forked from enlightenment/efl
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.
This commit is contained in:
parent
0584fc81a2
commit
2b16fc4278
|
@ -54,6 +54,7 @@ typedef struct _Ecore_Evas_Engine_Drm_Data
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
int depth, bpp;
|
int depth, bpp;
|
||||||
unsigned int format;
|
unsigned int format;
|
||||||
|
double offset;
|
||||||
Ecore_Drm2_Context ctx;
|
Ecore_Drm2_Context ctx;
|
||||||
Ecore_Fd_Handler *hdlr;
|
Ecore_Fd_Handler *hdlr;
|
||||||
Ecore_Drm2_Device *dev;
|
Ecore_Drm2_Device *dev;
|
||||||
|
@ -61,6 +62,7 @@ typedef struct _Ecore_Evas_Engine_Drm_Data
|
||||||
Evas_Device *seat;
|
Evas_Device *seat;
|
||||||
Eina_Bool pending : 1;
|
Eina_Bool pending : 1;
|
||||||
Eina_Bool ticking : 1;
|
Eina_Bool ticking : 1;
|
||||||
|
Eina_Bool once : 1;
|
||||||
} Ecore_Evas_Engine_Drm_Data;
|
} Ecore_Evas_Engine_Drm_Data;
|
||||||
|
|
||||||
static int _drm_init_count = 0;
|
static int _drm_init_count = 0;
|
||||||
|
@ -623,7 +625,8 @@ _cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int se
|
||||||
{
|
{
|
||||||
double t = (double)sec + ((double)usec / 1000000);
|
double t = (double)sec + ((double)usec / 1000000);
|
||||||
|
|
||||||
ecore_evas_animator_tick(ee, NULL, t);
|
if (!edata->once) t = ecore_time_get();
|
||||||
|
ecore_evas_animator_tick(ee, NULL, t - edata->offset);
|
||||||
}
|
}
|
||||||
else if (ret)
|
else if (ret)
|
||||||
{
|
{
|
||||||
|
@ -650,13 +653,43 @@ _drm_evas_changed(Ecore_Evas *ee, Eina_Bool changed)
|
||||||
static void
|
static void
|
||||||
_drm_animator_register(Ecore_Evas *ee)
|
_drm_animator_register(Ecore_Evas *ee)
|
||||||
{
|
{
|
||||||
|
double t;
|
||||||
|
long sec, usec;
|
||||||
Ecore_Evas_Engine_Drm_Data *edata;
|
Ecore_Evas_Engine_Drm_Data *edata;
|
||||||
|
Eina_Bool r;
|
||||||
|
|
||||||
if (ee->manual_render)
|
if (ee->manual_render)
|
||||||
ERR("Attempt to schedule tick for manually rendered canvas");
|
ERR("Attempt to schedule tick for manually rendered canvas");
|
||||||
|
|
||||||
edata = ee->engine.data;
|
edata = ee->engine.data;
|
||||||
edata->ticking = EINA_TRUE;
|
edata->ticking = EINA_TRUE;
|
||||||
|
|
||||||
|
/* Some graphics stacks appear to lie about their clock sources
|
||||||
|
* so attempt to measure the difference between our clock and the
|
||||||
|
* GPU's source of timestamps once at startup and apply that.
|
||||||
|
* If it's tiny, just assume they're the same clock and it's
|
||||||
|
* measurement error.
|
||||||
|
*
|
||||||
|
* <cedric> what happen when you suspend ?
|
||||||
|
* <cedric> what about drift ?
|
||||||
|
*
|
||||||
|
* If someone could relay the message to cedric that I'm not
|
||||||
|
* talking to him anymore, that would be helpful.
|
||||||
|
*/
|
||||||
|
if (!edata->once)
|
||||||
|
{
|
||||||
|
r = ecore_drm2_output_blanktime_get(edata->output, 1, &sec, &usec);
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
t = (double)sec + ((double)usec / 1000000.0);
|
||||||
|
edata->offset = t - ecore_time_get();
|
||||||
|
if (fabs(edata->offset) < 0.010)
|
||||||
|
edata->offset = 0.0;
|
||||||
|
|
||||||
|
edata->once = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!edata->pending && !ee->in_async_render)
|
if (!edata->pending && !ee->in_async_render)
|
||||||
{
|
{
|
||||||
edata->pending = EINA_TRUE;
|
edata->pending = EINA_TRUE;
|
||||||
|
|
Loading…
Reference in New Issue