summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-07-28 15:24:30 -0500
committerDerek Foreman <derekf@osg.samsung.com>2017-07-28 15:35:03 -0500
commit2b16fc4278adfdf471c5ea488c08daeb96400a9a (patch)
treed8182457e15a5380f6987678630f92a921ef223a
parent0584fc81a2960c47426560fa52bab675b10527b5 (diff)
ecore_evas_drm: Calculate gpu blank time offset once at startup
So vmware's graphics driver reports the MONOTONIC drm cap, yet uses CLOCK_REALTIME instead. This leaves us with a gigantic offset between the gpu timestamp and the times ecore_time_get() gets from CLOCK_MONOTONIC. Since ticking screws directly with loop time this results in some long distance clock jumping. This commit fixes drm/gl_drm operation under vmware.
-rw-r--r--src/modules/ecore_evas/engines/drm/ecore_evas_drm.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
index 302048c3b9..ac70498e20 100644
--- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
+++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
@@ -54,6 +54,7 @@ typedef struct _Ecore_Evas_Engine_Drm_Data
54 int x, y, w, h; 54 int x, y, w, h;
55 int depth, bpp; 55 int depth, bpp;
56 unsigned int format; 56 unsigned int format;
57 double offset;
57 Ecore_Drm2_Context ctx; 58 Ecore_Drm2_Context ctx;
58 Ecore_Fd_Handler *hdlr; 59 Ecore_Fd_Handler *hdlr;
59 Ecore_Drm2_Device *dev; 60 Ecore_Drm2_Device *dev;
@@ -61,6 +62,7 @@ typedef struct _Ecore_Evas_Engine_Drm_Data
61 Evas_Device *seat; 62 Evas_Device *seat;
62 Eina_Bool pending : 1; 63 Eina_Bool pending : 1;
63 Eina_Bool ticking : 1; 64 Eina_Bool ticking : 1;
65 Eina_Bool once : 1;
64} Ecore_Evas_Engine_Drm_Data; 66} Ecore_Evas_Engine_Drm_Data;
65 67
66static int _drm_init_count = 0; 68static int _drm_init_count = 0;
@@ -623,7 +625,8 @@ _cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int se
623 { 625 {
624 double t = (double)sec + ((double)usec / 1000000); 626 double t = (double)sec + ((double)usec / 1000000);
625 627
626 ecore_evas_animator_tick(ee, NULL, t); 628 if (!edata->once) t = ecore_time_get();
629 ecore_evas_animator_tick(ee, NULL, t - edata->offset);
627 } 630 }
628 else if (ret) 631 else if (ret)
629 { 632 {
@@ -650,13 +653,43 @@ _drm_evas_changed(Ecore_Evas *ee, Eina_Bool changed)
650static void 653static void
651_drm_animator_register(Ecore_Evas *ee) 654_drm_animator_register(Ecore_Evas *ee)
652{ 655{
656 double t;
657 long sec, usec;
653 Ecore_Evas_Engine_Drm_Data *edata; 658 Ecore_Evas_Engine_Drm_Data *edata;
659 Eina_Bool r;
654 660
655 if (ee->manual_render) 661 if (ee->manual_render)
656 ERR("Attempt to schedule tick for manually rendered canvas"); 662 ERR("Attempt to schedule tick for manually rendered canvas");
657 663
658 edata = ee->engine.data; 664 edata = ee->engine.data;
659 edata->ticking = EINA_TRUE; 665 edata->ticking = EINA_TRUE;
666
667 /* Some graphics stacks appear to lie about their clock sources
668 * so attempt to measure the difference between our clock and the
669 * GPU's source of timestamps once at startup and apply that.
670 * If it's tiny, just assume they're the same clock and it's
671 * measurement error.
672 *
673 * <cedric> what happen when you suspend ?
674 * <cedric> what about drift ?
675 *
676 * If someone could relay the message to cedric that I'm not
677 * talking to him anymore, that would be helpful.
678 */
679 if (!edata->once)
680 {
681 r = ecore_drm2_output_blanktime_get(edata->output, 1, &sec, &usec);
682 if (r)
683 {
684 t = (double)sec + ((double)usec / 1000000.0);
685 edata->offset = t - ecore_time_get();
686 if (fabs(edata->offset) < 0.010)
687 edata->offset = 0.0;
688
689 edata->once = EINA_TRUE;
690 }
691 }
692
660 if (!edata->pending && !ee->in_async_render) 693 if (!edata->pending && !ee->in_async_render)
661 { 694 {
662 edata->pending = EINA_TRUE; 695 edata->pending = EINA_TRUE;