[Mesa-dev] [PATCH 6/6][RFC] EGL/Wayland: Use the DRIImage blit function (when available) for Prime

Axel Davy axel.davy at ens.fr
Sun Jan 5 13:26:42 PST 2014


Signed-off-by: Axel Davy <axel.davy at ens.fr>
---
 src/egl/drivers/dri2/egl_dri2.h         |  2 +
 src/egl/drivers/dri2/platform_wayland.c | 98 ++++++++++++++++++++++++++-------
 2 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 5f49cc5..6f89cba 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -134,6 +134,7 @@ struct dri2_egl_display
    int			     formats;
    uint32_t                  capabilities;
    int			     enable_tiling;
+   int			     blit_front;
 #endif
 
    int (*authenticate) (_EGLDisplay *disp, uint32_t id);
@@ -189,6 +190,7 @@ struct dri2_egl_surface
 #ifdef HAVE_WAYLAND_PLATFORM
       struct wl_buffer   *wl_buffer;
       __DRIimage         *dri_image;
+      __DRIimage         *front_image;
 #endif
 #ifdef HAVE_DRM_PLATFORM
       struct gbm_bo       *bo;
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 7c8e076..6abd4d1 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -235,7 +235,12 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
       if (dri2_surf->color_buffers[i].wl_buffer)
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
       if (dri2_surf->color_buffers[i].dri_image)
+      {
          dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
+         if (dri2_dpy->blit_front)
+            dri2_dpy->image->destroyImage
+               (dri2_surf->color_buffers[i].front_image);
+      }
    }
 
    for (i = 0; i < __DRI_BUFFER_COUNT; i++)
@@ -269,10 +274,16 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf)
           !dri2_surf->color_buffers[i].locked)
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
       if (dri2_surf->color_buffers[i].dri_image)
+      {
          dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
+         if (dri2_dpy->blit_front)
+            dri2_dpy->image->destroyImage
+               (dri2_surf->color_buffers[i].front_image);
+      }
 
       dri2_surf->color_buffers[i].wl_buffer = NULL;
       dri2_surf->color_buffers[i].dri_image = NULL;
+      dri2_surf->color_buffers[i].front_image = NULL;
       dri2_surf->color_buffers[i].locked = 0;
    }
 
@@ -315,18 +326,39 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
    if (dri2_surf->back == NULL)
       return -1;
    if (dri2_surf->back->dri_image == NULL) {
-      unsigned int use_flags = __DRI_IMAGE_USE_SHARE;
-
-      if (!dri2_dpy->enable_tiling)
-         use_flags |= __DRI_IMAGE_USE_LINEAR;
-
-      dri2_surf->back->dri_image = 
-         dri2_dpy->image->createImage(dri2_dpy->dri_screen,
-                                      dri2_surf->base.Width,
-                                      dri2_surf->base.Height,
-                                      __DRI_IMAGE_FORMAT_ARGB8888,
-                                      use_flags,
-                                      NULL);
+      if (dri2_dpy->blit_front) {
+         unsigned int front_use_flags = __DRI_IMAGE_USE_SHARE
+                                       | __DRI_IMAGE_USE_LINEAR;
+
+         dri2_surf->back->dri_image =
+            dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+                                         dri2_surf->base.Width,
+                                         dri2_surf->base.Height,
+                                         __DRI_IMAGE_FORMAT_ARGB8888,
+                                         0,
+                                         NULL);
+         dri2_surf->back->front_image =
+            dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+                                         dri2_surf->base.Width,
+                                         dri2_surf->base.Height,
+                                         __DRI_IMAGE_FORMAT_ARGB8888,
+                                         front_use_flags,
+                                         NULL);
+      } else {
+         unsigned int use_flags = __DRI_IMAGE_USE_SHARE;
+
+         if (!dri2_dpy->enable_tiling)
+            use_flags |= __DRI_IMAGE_USE_LINEAR;
+
+         dri2_surf->back->dri_image =
+            dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+                                         dri2_surf->base.Width,
+                                         dri2_surf->base.Height,
+                                         __DRI_IMAGE_FORMAT_ARGB8888,
+                                         use_flags,
+                                         NULL);
+         dri2_surf->back->front_image = dri2_surf->back->dri_image;
+      }
       dri2_surf->back->age = 0;
    }
    if (dri2_surf->back->dri_image == NULL)
@@ -413,8 +445,12 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
           dri2_surf->color_buffers[i].wl_buffer) {
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
          dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
+         if(dri2_dpy->blit_front)
+            dri2_dpy->image->destroyImage
+               (dri2_surf->color_buffers[i].front_image);
          dri2_surf->color_buffers[i].wl_buffer = NULL;
          dri2_surf->color_buffers[i].dri_image = NULL;
+         dri2_surf->color_buffers[i].front_image = NULL;
       }
    }
 
@@ -549,9 +585,9 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
       return;
 
    if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
+      dri2_dpy->image->queryImage(dri2_surf->current->front_image,
                                   __DRI_IMAGE_ATTRIB_FD, &fd);
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
+      dri2_dpy->image->queryImage(dri2_surf->current->front_image,
                                   __DRI_IMAGE_ATTRIB_STRIDE, &stride);
 
       dri2_surf->current->wl_buffer =
@@ -565,9 +601,9 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
                                     0, 0);
       close(fd);
    } else {
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
+      dri2_dpy->image->queryImage(dri2_surf->current->front_image,
                                   __DRI_IMAGE_ATTRIB_NAME, &name);
-      dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
+      dri2_dpy->image->queryImage(dri2_surf->current->front_image,
                                   __DRI_IMAGE_ATTRIB_STRIDE, &stride);
 
       dri2_surf->current->wl_buffer =
@@ -649,20 +685,32 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv,
                            rect[2], rect[3]);
       }
    }
-
-   if (dri2_dpy->flush->base.version >= 4) {
+   if (dri2_dpy->flush->base.version >= 4 || dri2_dpy->blit_front)
+   {
       ctx = _eglGetCurrentContext();
       dri2_ctx = dri2_egl_context(ctx);
+   }
+
+   if (dri2_dpy->flush->base.version >= 4)
       (*dri2_dpy->flush->flush_with_flags)(dri2_ctx->dri_context,
                                            dri2_surf->dri_drawable,
                                            __DRI2_FLUSH_DRAWABLE,
                                            __DRI2_THROTTLE_SWAPBUFFER);
-   } else {
+   else
       (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
-   }
 
    (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
 
+   if (dri2_dpy->blit_front)
+      dri2_dpy->image->blitImage(dri2_ctx->dri_context,
+                                 dri2_surf->current->front_image,
+                                 dri2_surf->current->dri_image,
+                                 0, 0, dri2_surf->base.Width,
+                                 dri2_surf->base.Height,
+                                 0, 0, dri2_surf->base.Width,
+                                 dri2_surf->base.Height,
+                                 __BLIT_FLAG_FINISH);
+
    wl_surface_commit(dri2_surf->wl_win->surface);
 
    /* If we're not waiting for a frame callback then we'll at least throttle
@@ -912,7 +960,7 @@ is_render_node_capable(struct dri2_egl_display *dri2_dpy)
    if (!(dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME))
       return EGL_FALSE;
 
-   extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
+   extensions = dri2_dpy->driver_extensions;
    for (i = 0; extensions[i]; i++) {
       if (strcmp(extensions[i]->name, __DRI_IMAGE_DRIVER) == 0)
          return EGL_TRUE;
@@ -1081,6 +1129,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
    char* prime_device_name = NULL;
    char* prime = NULL;
    const char *dri_prime = getenv("DRI_PRIME");
+   const char *dri_blit = getenv("DRI_BLIT");
 
    if (dri_prime)
       prime = strdup(dri_prime);
@@ -1267,6 +1316,13 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
       goto cleanup_screen;
    }
 
+   if (is_different_device && dri2_dpy->image->base.version >= 9) {
+      if (dri_blit)
+         dri2_dpy->blit_front = strtoul(prime, NULL, 0);
+      else
+         dri2_dpy->blit_front = 1; /* default when available */
+   }
+
    types = EGL_WINDOW_BIT;
    for (i = 0; dri2_dpy->driver_configs[i]; i++) {
       config = dri2_dpy->driver_configs[i];
-- 
1.8.3.2



More information about the mesa-dev mailing list