[Mesa-dev] [PATCH 7/7] EGL/Wayland: use blitImage when requested and on a different device

Axel Davy axel.davy at ens.fr
Fri Mar 7 08:26:07 PST 2014


When the client use a different graphic device than the server,
we want for better performance to render to a tiled buffer,
and copy to a linear buffer which we share with the server.

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         | 81 +++++++++++++++++++++----
 src/mesa/drivers/dri/common/xmlpool/t_options.h |  5 ++
 3 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 941690f..c790b30 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 0bee4d2..a3cc5c8 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -53,6 +53,7 @@ PUBLIC const char __driConfigOptionsWayland[] =
 DRI_CONF_BEGIN
     DRI_CONF_SECTION_MISCELLANEOUS
         DRI_CONF_WANTED_DEVICE_ID_PATH_TAG()
+        DRI_CONF_BLIT_IF_DIFFERENT_DEVICE("true")
     DRI_CONF_SECTION_END
 DRI_CONF_END;
 
@@ -231,8 +232,12 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
    for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
       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)
+      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++)
@@ -265,11 +270,16 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf)
       if (dri2_surf->color_buffers[i].wl_buffer &&
           !dri2_surf->color_buffers[i].locked)
          wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
-      if (dri2_surf->color_buffers[i].dri_image)
+      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;
    }
 
@@ -317,13 +327,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
       if (!dri2_dpy->enable_tiling)
          use_flags |= __DRI_IMAGE_USE_LINEAR;
 
-      dri2_surf->back->dri_image = 
+      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,
                                       use_flags,
                                       NULL);
+      if (dri2_dpy->blit_front)
+         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);
+      else
+         dri2_surf->back->dri_image = dri2_surf->back->front_image;
       dri2_surf->back->age = 0;
    }
    if (dri2_surf->back->dri_image == NULL)
@@ -410,8 +430,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;
       }
    }
 
@@ -547,9 +571,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 =
@@ -563,9 +587,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 =
@@ -648,9 +672,21 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv,
       }
    }
 
-   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->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);
+
+   if (dri2_dpy->flush->base.version >= 4) {
       (*dri2_dpy->flush->flush_with_flags)(dri2_ctx->dri_context,
                                            dri2_surf->dri_drawable,
                                            __DRI2_FLUSH_DRAWABLE,
@@ -1078,7 +1114,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
    struct dri2_egl_display *dri2_dpy;
    const __DRIconfig *config;
    uint32_t types;
-   int i, is_render_node, device_fd, is_different_device;
+   int i, is_render_node, device_fd, is_different_device, want_blit;
    drm_magic_t magic;
    static const unsigned int argb_masks[4] =
       { 0xff0000, 0xff00, 0xff, 0xff000000 };
@@ -1090,20 +1126,33 @@ 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");
+
+   driParseOptionInfo(&defaultInitOptions, __driConfigOptionsWayland);
+   driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0, "init");
 
    if (dri_prime)
       prime = strdup(dri_prime);
    else {
-      driParseOptionInfo(&defaultInitOptions, __driConfigOptionsWayland);
-      driParseConfigFiles(&userInitOptions, &defaultInitOptions, 0, "init");
       if (driCheckOption(&userInitOptions, "wanted_device_id_path_tag",
                          DRI_STRING))
          prime = strdup(driQueryOptionstr(&userInitOptions,
                                           "wanted_device_id_path_tag"));
-      driDestroyOptionCache(&userInitOptions);
-      driDestroyOptionInfo(&defaultInitOptions);
    }
 
+   errno = 0;
+   if (dri_blit)
+      want_blit = strtoul(dri_blit, NULL, 0);
+   if (errno || !dri_blit) {
+      if (driCheckOption(&userInitOptions,
+                         "blit_if_different_device",
+                         DRI_BOOL))
+         want_blit = driQueryOptionb(&userInitOptions, "blit_if_different_device");
+   }
+
+   driDestroyOptionCache(&userInitOptions);
+   driDestroyOptionInfo(&defaultInitOptions);
+
    loader_set_logger(_eglLog);
 
    drv->API.CreateWindowSurface = dri2_create_window_surface;
@@ -1275,6 +1324,12 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
       goto cleanup_screen;
    }
 
+   if (is_different_device && dri2_dpy->image->base.version >= 9 &&
+                              want_blit) {
+      dri2_dpy->blit_front = 1;
+      _eglLog(_EGL_DEBUG, "wayland-egl: blit mode activated");
+   }
+
    types = EGL_WINDOW_BIT;
    for (i = 0; dri2_dpy->driver_configs[i]; i++) {
       config = dri2_dpy->driver_configs[i];
diff --git a/src/mesa/drivers/dri/common/xmlpool/t_options.h b/src/mesa/drivers/dri/common/xmlpool/t_options.h
index ac72e3b..fc59d77 100644
--- a/src/mesa/drivers/dri/common/xmlpool/t_options.h
+++ b/src/mesa/drivers/dri/common/xmlpool/t_options.h
@@ -326,3 +326,8 @@ DRI_CONF_OPT_END
 DRI_CONF_OPT_BEGIN(wanted_device_id_path_tag, string, def) \
         DRI_CONF_DESC(en,gettext("Define the graphic device to use if possible")) \
 DRI_CONF_OPT_END
+
+#define DRI_CONF_BLIT_IF_DIFFERENT_DEVICE(def) \
+DRI_CONF_OPT_BEGIN_B(blit_if_different_device, def) \
+        DRI_CONF_DESC(en,gettext("Render to a separate buffer and copy to a shared buffer. Apply only if using a different device than the server")) \
+DRI_CONF_OPT_END
-- 
1.8.3.2



More information about the mesa-dev mailing list