ecore-drm: Update drm device & output code to remove per-output dumb buffers
authorChris Michael <cp.michael@samsung.com>
Tue, 7 Apr 2015 18:07:12 +0000 (14:07 -0400)
committerStefan Schmidt <s.schmidt@samsung.com>
Fri, 10 Apr 2015 09:09:50 +0000 (11:09 +0200)
Summary: Since we now create the dumb buffers in the ecore_drm_device
structure, we don't need them on a per-output basis. This commit fixes
the output & device code to adjust to this.

@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

index 1ba4a26..0eeb7c5 100644 (file)
@@ -18,9 +18,10 @@ _ecore_drm_device_cb_page_flip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSE
 
    if (output->pending_flip)
      {
-        ecore_drm_output_fb_release(output, output->current);
-        output->current = output->next;
-        output->next = NULL;
+        if (output->dev->current)
+          ecore_drm_output_fb_release(output, output->dev->current);
+        output->dev->current = output->dev->next;
+        output->dev->next = NULL;
      }
 
    output->pending_flip = EINA_FALSE;
@@ -83,6 +84,8 @@ _ecore_drm_device_cb_idle(void *data)
 
    if (!(dev = data)) return ECORE_CALLBACK_CANCEL;
 
+   /* TODO: skip repaints if we are VT-switched away */
+
    EINA_LIST_FOREACH(dev->outputs, l, output)
      {
         if ((!output->enabled) || (!output->need_repaint)) continue;
@@ -232,10 +235,19 @@ EAPI void
 ecore_drm_device_free(Ecore_Drm_Device *dev)
 {
    Ecore_Drm_Output *output;
+   unsigned int i = 0;
 
    /* check for valid device */
    if (!dev) return;
 
+   for (; i < ALEN(dev->dumb); i++)
+     {
+        if (dev->dumb[i]) ecore_drm_fb_destroy(dev->dumb[i]);
+        dev->dumb[i] = NULL;
+     }
+
+   ecore_drm_inputs_destroy(dev);
+
    /* free outputs */
    EINA_LIST_FREE(dev->outputs, output)
      ecore_drm_output_free(output);
@@ -537,3 +549,49 @@ ecore_drm_device_pointer_xy_get(Ecore_Drm_Device *dev, int *x, int *y)
           }
      }
 }
+
+EAPI Eina_Bool
+ecore_drm_device_software_setup(Ecore_Drm_Device *dev)
+{
+   unsigned int i = 0;
+   int w = 0, h = 0;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dev, EINA_FALSE);
+
+   /* destroy any old buffers */
+   for (; i < ALEN(dev->dumb); i++)
+     {
+        if (dev->dumb[i]) ecore_drm_fb_destroy(dev->dumb[i]);
+        dev->dumb[i] = NULL;
+     }
+
+   /* get screen size */
+   ecore_drm_outputs_geometry_get(dev, NULL, NULL, &w, &h);
+
+   /* create new buffers */
+   for (i = 0; i < ALEN(dev->dumb); i++)
+     {
+        if (!(dev->dumb[i] = ecore_drm_fb_create(dev, w, h)))
+          {
+             ERR("Could not create dumb framebuffer: %m");
+             goto err;
+          }
+
+        DBG("Ecore_Drm_Device Created Dumb Buffer");
+        DBG("\tFb: %d", dev->dumb[i]->id);
+        DBG("\tHandle: %d", dev->dumb[i]->hdl);
+        DBG("\tStride: %d", dev->dumb[i]->stride);
+        DBG("\tSize: %d", dev->dumb[i]->size);
+        DBG("\tW: %d\tH: %d", dev->dumb[i]->w, dev->dumb[i]->h);
+     }
+
+   return EINA_TRUE;
+
+err:
+   for (i = 0; i < ALEN(dev->dumb); i++)
+     {
+        if (dev->dumb[i]) ecore_drm_fb_destroy(dev->dumb[i]);
+        dev->dumb[i] = NULL;
+     }
+   return EINA_FALSE;
+}
index 988ddf0..1c1514f 100644 (file)
@@ -5,8 +5,6 @@
 #include "ecore_drm_private.h"
 #include <ctype.h>
 
-#define ALEN(array) (sizeof(array) / sizeof(array)[0])
-
 #define EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING 0xfe
 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME 0xfc
 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER 0xff
@@ -180,46 +178,6 @@ _ecore_drm_output_edid_find(Ecore_Drm_Output *output, drmModeConnector *conn)
    drmModeFreePropertyBlob(blob);
 }
 
-static Eina_Bool 
-_ecore_drm_output_software_setup(Ecore_Drm_Device *dev, Ecore_Drm_Output *output)
-{
-   unsigned int i = 0;
-   int w = 0, h = 0;
-
-   if ((!dev) || (!output)) return EINA_FALSE;
-
-   if (output->current_mode)
-     {
-        w = output->current_mode->width;
-        h = output->current_mode->height;
-     }
-   else
-     {
-        w = 1024;
-        h = 768;
-     }
-
-   for (i = 0; i < NUM_FRAME_BUFFERS; i++)
-     {
-        if (!(output->dumb[i] = ecore_drm_fb_create(dev, w, h)))
-          {
-             ERR("Could not create dumb framebuffer %d", i);
-             goto err;
-          }
-     }
-
-   return EINA_TRUE;
-
-err:
-   for (i = 0; i < NUM_FRAME_BUFFERS; i++)
-     {
-        if (output->dumb[i]) ecore_drm_fb_destroy(output->dumb[i]);
-        output->dumb[i] = NULL;
-     }
-
-   return EINA_FALSE;
-}
-
 static void 
 _ecore_drm_output_software_render(Ecore_Drm_Output *output)
 {
@@ -545,9 +503,6 @@ _ecore_drm_output_create(Ecore_Drm_Device *dev, drmModeRes *res, drmModeConnecto
    /* TODO: implement support for LCMS ? */
    output->gamma = output->crtc->gamma_size;
 
-   if (!_ecore_drm_output_software_setup(dev, output))
-     goto err;
-
    dev->outputs = eina_list_append(dev->outputs, output);
 
    DBG("Created New Output At %d,%d", output->x, output->y);
@@ -643,7 +598,8 @@ _ecore_drm_output_fb_release(Ecore_Drm_Output *output, Ecore_Drm_Fb *fb)
 {
    if ((!output) || (!fb)) return;
 
-   if ((fb->mmap) && (fb != output->dumb[0]) && (fb != output->dumb[1]))
+   if ((fb->mmap) &&
+       (fb != output->dev->dumb[0]) && (fb != output->dev->dumb[1]))
      ecore_drm_fb_destroy(fb);
 }
 
@@ -657,14 +613,13 @@ _ecore_drm_output_repaint_start(Ecore_Drm_Output *output)
    if (!output) return;
    if (output->pending_destroy) return;
 
-   if (!output->current)
+   if (!output->dev->current)
      {
         /* DBG("\tNo Current FB"); */
         goto finish;
      }
 
-   fb = output->current->id;
-
+   fb = output->dev->current->id;
    if (drmModePageFlip(output->dev->drm.fd, output->crtc_id, fb, 
                        DRM_MODE_PAGE_FLIP_EVENT, output) < 0)
      {
@@ -876,17 +831,38 @@ ecore_drm_output_cursor_size_set(Ecore_Drm_Output *output, int handle, int w, in
 EAPI Eina_Bool 
 ecore_drm_output_enable(Ecore_Drm_Output *output)
 {
+   Ecore_Drm_Device *dev;
    Ecore_Drm_Output_Mode *mode;
+   int x = 0, y = 0;
 
-   if ((!output) || (!output->current)) return EINA_FALSE;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(output->current_mode, EINA_FALSE);
+
+   if (!(dev = output->dev)) return EINA_FALSE;
+
+   output->enabled = EINA_TRUE;
+   if (!dev->current)
+     {
+        /* schedule repaint */
+        /* NB: this will trigger a redraw at next idle */
+        output->need_repaint = EINA_TRUE;
+        return EINA_TRUE;
+     }
 
    ecore_drm_output_dpms_set(output, DRM_MODE_DPMS_ON);
 
+   if (!output->cloned)
+     {
+        x = output->x;
+        y = output->y;
+     }
+
    mode = output->current_mode;
-   if (drmModeSetCrtc(output->dev->drm.fd, output->crtc_id, output->current->id
-                      0, 0, &output->conn_id, 1, &mode->info) < 0)
+   if (drmModeSetCrtc(dev->drm.fd, output->crtc_id, dev->current->id, x, y
+                      &output->conn_id, 1, &mode->info) < 0)
      {
-        ERR("Could not set output crtc: %m");
+        ERR("Failed to set Mode %dx%d for Output %s: %m",
+            mode->width, mode->height, output->name);
         return EINA_FALSE;
      }
 
@@ -896,57 +872,59 @@ ecore_drm_output_enable(Ecore_Drm_Output *output)
 EAPI void 
 ecore_drm_output_fb_release(Ecore_Drm_Output *output, Ecore_Drm_Fb *fb)
 {
-   if ((!output) || (!fb)) return;
-
-   if ((fb->mmap) && (fb != output->dumb[0]) && (fb != output->dumb[1]))
-     ecore_drm_fb_destroy(fb);
+   _ecore_drm_output_fb_release(output, fb);
 }
 
 EAPI void 
 ecore_drm_output_repaint(Ecore_Drm_Output *output)
 {
-   Eina_List *l;
+   Ecore_Drm_Device *dev;
    Ecore_Drm_Sprite *sprite;
+   Eina_List *l;
    int ret = 0;
 
    EINA_SAFETY_ON_NULL_RETURN(output);
    EINA_SAFETY_ON_TRUE_RETURN(output->pending_destroy);
 
+   if (!(dev = output->dev)) return;
+
    /* DBG("Output Repaint: %d %d", output->crtc_id, output->conn_id); */
 
    /* TODO: assign planes ? */
 
-   if (!output->next)
+   if (!dev->next)
      _ecore_drm_output_software_render(output);
-
-   if (!output->next) return;
+   if (!dev->next) return;
 
    output->need_repaint = EINA_FALSE;
 
-   if (!output->current)
+   if ((!dev->current) || 
+       (dev->current->stride != dev->next->stride))
      {
         Ecore_Drm_Output_Mode *mode;
 
         mode = output->current_mode;
-
-        ret = drmModeSetCrtc(output->dev->drm.fd, output->crtc_id, 
-                             output->next->id, 0, 0, &output->conn_id, 1, 
-                             &mode->info);
+        ret = drmModeSetCrtc(dev->drm.fd, output->crtc_id, dev->next->id,
+                             0, 0, &output->conn_id, 1, &mode->info);
         if (ret) goto err;
-     }
 
-   /* TODO: set dpms to on */
+        ecore_drm_output_dpms_set(output, DRM_MODE_DPMS_ON);
+     }
 
-   if (drmModePageFlip(output->dev->drm.fd, output->crtc_id, output->next->id,
+   if (drmModePageFlip(dev->drm.fd, output->crtc_id, dev->next->id,
                        DRM_MODE_PAGE_FLIP_EVENT, output) < 0)
      {
-        /* ERR("Scheduling pageflip failed"); */
+        ERR("Could not schedule pageflip: %m");
+        DBG("\tCrtc: %d\tConn: %d\tFB: %d",
+            output->crtc_id, output->conn_id, dev->next->id);
         goto err;
      }
 
    output->pending_flip = EINA_TRUE;
 
-   EINA_LIST_FOREACH(output->dev->sprites, l, sprite)
+   /* TODO: output_cursor_set */
+
+   EINA_LIST_FOREACH(dev->sprites, l, sprite)
      {
         unsigned int flags = 0, id = 0;
         drmVBlank vbl = 
@@ -959,13 +937,13 @@ ecore_drm_output_repaint(Ecore_Drm_Output *output)
             (!ecore_drm_sprites_crtc_supported(output, sprite->crtcs)))
           continue;
 
-        if ((sprite->next_fb) && (!output->dev->cursors_broken))
+        if ((sprite->next_fb) && (!dev->cursors_broken))
           id = sprite->next_fb->id;
 
         ecore_drm_sprites_fb_set(sprite, id, flags);
 
         vbl.request.signal = (unsigned long)sprite;
-        ret = drmWaitVBlank(output->dev->drm.fd, &vbl);
+        ret = drmWaitVBlank(dev->drm.fd, &vbl);
         if (ret) ERR("Error Wait VBlank: %m");
 
         sprite->output = output;
@@ -975,10 +953,10 @@ ecore_drm_output_repaint(Ecore_Drm_Output *output)
    return;
 
 err:
-   if (output->next)
+   if (dev->next)
      {
-        ecore_drm_output_fb_release(output, output->next);
-        output->next = NULL;
+        _ecore_drm_output_fb_release(output, dev->next);
+        dev->next = NULL;
      }
 }