From: Ander Conselvan de Oliveira <ander.conselvan.de.olive...@intel.com>
--- src/egl/drivers/dri2/egl_dri2.h | 11 +++++ src/egl/drivers/dri2/platform_drm.c | 79 ++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 206902b..f75c278 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -143,6 +143,15 @@ enum wayland_buffer_type { }; #endif +#ifdef HAVE_DRM_PLATFORM +enum drm_buffer_type { + DRM_BUFFER_FRONT, + DRM_BUFFER_BACK, + DRM_BUFFER_THIRD, + DRM_BUFFER_COUNT +}; +#endif + struct dri2_egl_surface { _EGLSurface base; @@ -177,8 +186,10 @@ struct dri2_egl_surface #ifdef HAVE_DRM_PLATFORM struct gbm_dri_surface *gbm_surf; + int drm_buffer_lock[DRM_BUFFER_COUNT]; #ifndef HAVE_WAYLAND_PLATFORM __DRIbuffer *dri_buffers[__DRI_BUFFER_COUNT]; + __DRIbuffer *third_buffer; #endif #endif diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 06fdd85..4212cea 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -44,7 +44,22 @@ get_front_buffer(struct gbm_dri_surface *surf, void *data) (void) surf; - return &dri2_surf->buffers[__DRI_BUFFER_FRONT_LEFT]; + dri2_surf->drm_buffer_lock[DRM_BUFFER_FRONT] = 1; + return dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]; +} + +static void +release_buffer(struct gbm_dri_surface *surf, __DRIbuffer *buffer, void *data) +{ + struct dri2_egl_surface *dri2_surf = data; + + if (buffer == dri2_surf->third_buffer) + dri2_surf->drm_buffer_lock[DRM_BUFFER_THIRD] = 0; + else if (buffer->attachment == __DRI_BUFFER_FRONT_LEFT) + dri2_surf->drm_buffer_lock[DRM_BUFFER_FRONT] = 0; + else if (buffer->attachment == __DRI_BUFFER_BACK_LEFT) + dri2_surf->drm_buffer_lock[DRM_BUFFER_BACK] = 0; + } static _EGLSurface * @@ -73,6 +88,8 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, for (i = 0; i < __DRI_BUFFER_COUNT; ++i) dri2_surf->dri_buffers[i] = NULL; + dri2_surf->third_buffer = NULL; + switch (type) { case EGL_WINDOW_BIT: surf = gbm_dri_surface((struct gbm_surface *) window); @@ -82,6 +99,7 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, dri2_surf->base.Height = surf->base.height; surf->get_front_buffer = get_front_buffer; + surf->release_buffer = release_buffer; surf->dri_private = dri2_surf; break; @@ -169,6 +187,61 @@ pointer_swap(const void **p1, const void **p2) *p2 = tmp; } +static void +destroy_third_buffer(struct dri2_egl_surface *dri2_surf) +{ + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + + if (dri2_surf->third_buffer == NULL) + return; + + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, + dri2_surf->third_buffer); + dri2_surf->third_buffer = NULL; + dri2_surf->drm_buffer_lock[DRM_BUFFER_THIRD] = 0; +} + +static void +swap_drm_buffers(struct dri2_egl_surface *dri2_surf, + enum drm_buffer_type a, enum drm_buffer_type b) +{ + int tmp; + + tmp = dri2_surf->drm_buffer_lock[a]; + dri2_surf->drm_buffer_lock[a] = dri2_surf->drm_buffer_lock[b]; + dri2_surf->drm_buffer_lock[b] = tmp; +} + +static void +swap_back_and_third(struct dri2_egl_surface *dri2_surf) +{ + if (dri2_surf->drm_buffer_lock[DRM_BUFFER_THIRD]) + destroy_third_buffer(dri2_surf); + + pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT], + (const void **) &dri2_surf->third_buffer); + + swap_drm_buffers(dri2_surf, DRM_BUFFER_BACK, DRM_BUFFER_THIRD); +} + +static void +dri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf, + unsigned int type) +{ + switch (type) { + case __DRI_BUFFER_BACK_LEFT: + if (dri2_surf->drm_buffer_lock[DRM_BUFFER_BACK]) + swap_back_and_third(dri2_surf); + else if (dri2_surf->third_buffer) + destroy_third_buffer(dri2_surf); + break; + default: + break; + + } +} + static __DRIbuffer * dri2_get_buffers_with_format(__DRIdrawable * driDrawable, int *width, int *height, @@ -185,6 +258,8 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable, assert(attachments[i] < __DRI_BUFFER_COUNT); assert(dri2_surf->buffer_count < 5); + dri2_prior_buffer_creation(dri2_surf, attachments[i]); + if (dri2_surf->dri_buffers[attachments[i]] == NULL) { dri2_surf->dri_buffers[attachments[i]] = @@ -274,6 +349,8 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) __DRI_BUFFER_FRONT_LEFT; dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment = __DRI_BUFFER_BACK_LEFT; + + swap_drm_buffers(dri2_surf, DRM_BUFFER_FRONT, DRM_BUFFER_BACK); } _EGLContext *ctx; -- 1.7.4.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel