ecore-drm: Delay destroy of output if there is a pending flip
authorChris Michael <cp.michael@samsung.com>
Tue, 7 Apr 2015 17:03:28 +0000 (13:03 -0400)
committerStefan Schmidt <s.schmidt@samsung.com>
Fri, 10 Apr 2015 09:09:50 +0000 (11:09 +0200)
Summary: If an output has a pending page flip, we cannot destroy it
until the page flip has completed. This commit adds support to delay
destroying an output until the page flip is completed.

@fix

Signed-off-by: Chris Michael <cp.michael@samsung.com>
src/lib/ecore_drm/ecore_drm_device.c
src/lib/ecore_drm/ecore_drm_output.c
src/lib/ecore_drm/ecore_drm_private.h

index 69a8e1c..1ba4a26 100644 (file)
@@ -24,7 +24,13 @@ _ecore_drm_device_cb_page_flip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSE
      }
 
    output->pending_flip = EINA_FALSE;
-   if (!output->pending_vblank) ecore_drm_output_repaint(output);
+   if (output->pending_destroy)
+     {
+        output->pending_destroy = EINA_FALSE;
+        ecore_drm_output_free(output);
+     }
+   else if (!output->pending_vblank)
+     ecore_drm_output_repaint(output);
 }
 
 static void 
@@ -79,7 +85,7 @@ _ecore_drm_device_cb_idle(void *data)
 
    EINA_LIST_FOREACH(dev->outputs, l, output)
      {
-        output->need_repaint = EINA_TRUE;
+        if ((!output->enabled) || (!output->need_repaint)) continue;
         if (output->repaint_scheduled) continue;
         _ecore_drm_output_repaint_start(output);
      }
index 5876141..7bced0c 100644 (file)
@@ -594,6 +594,12 @@ _ecore_drm_output_free(Ecore_Drm_Output *output)
    /* check for valid output */
    if (!output) return;
 
+   if (output->pending_flip)
+     {
+        output->pending_destroy = EINA_TRUE;
+        return;
+     }
+
    /* delete the backlight struct */
    if (output->backlight) 
      _ecore_drm_output_backlight_shutdown(output->backlight);
@@ -649,6 +655,7 @@ _ecore_drm_output_repaint_start(Ecore_Drm_Output *output)
    /* DBG("Output Repaint Start"); */
 
    if (!output) return;
+   if (output->pending_destroy) return;
 
    if (!output->current)
      {
@@ -902,7 +909,8 @@ ecore_drm_output_repaint(Ecore_Drm_Output *output)
    Ecore_Drm_Sprite *sprite;
    int ret = 0;
 
-   if (!output) return;
+   EINA_SAFETY_ON_NULL_RETURN(output);
+   EINA_SAFETY_ON_TRUE_RETURN(output->pending_destroy);
 
    /* DBG("Output Repaint: %d %d", output->crtc_id, output->conn_id); */
 
index beea203..4460064 100644 (file)
@@ -117,15 +117,10 @@ struct _Ecore_Drm_Output
 
    int x, y, phys_width, phys_height;
 
-   Eina_Bool need_repaint : 1;
-   Eina_Bool repaint_scheduled : 1;
-
-   Eina_Bool pending_flip : 1;
-   Eina_Bool pending_vblank : 1;
-
    int pipe;
    const char *make, *model, *name;
    unsigned int subpixel;
+   uint16_t gamma;
 
    Ecore_Drm_Output_Mode *current_mode;
    Eina_List *modes;
@@ -142,10 +137,13 @@ struct _Ecore_Drm_Output
    Ecore_Drm_Fb *dumb[NUM_FRAME_BUFFERS];
    Ecore_Drm_Backlight *backlight;   
 
-   uint16_t gamma;
-
    Eina_Bool enabled : 1;
    Eina_Bool cloned : 1;
+   Eina_Bool need_repaint : 1;
+   Eina_Bool repaint_scheduled : 1;
+   Eina_Bool pending_destroy : 1;
+   Eina_Bool pending_flip : 1;
+   Eina_Bool pending_vblank : 1;
 };
 
 struct _Ecore_Drm_Seat