[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