diff options
Diffstat (limited to 'src/egl/drivers/dri2/platform_wayland.c')
-rw-r--r-- | src/egl/drivers/dri2/platform_wayland.c | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index e96c2486a0..f20293fea4 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -90,13 +90,14 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } - + if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; for (i = 0; i < WL_BUFFER_COUNT; ++i) { dri2_surf->wl_drm_buffer[i] = NULL; dri2_surf->wl_buffer_lock[i] = 0; + dri2_surf->buffer_age[i] = 0; } for (i = 0; i < __DRI_BUFFER_COUNT; ++i) @@ -129,14 +130,14 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_buf->dri_buffer; } break; - default: + default: goto cleanup_surf; } - dri2_surf->dri_drawable = + dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, type == EGL_WINDOW_BIT ? - dri2_conf->dri_double_config : + dri2_conf->dri_double_config : dri2_conf->dri_single_config, dri2_surf); if (dri2_surf->dri_drawable == NULL) { @@ -175,6 +176,21 @@ dri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp, pixmap, attrib_list); } +static EGLBoolean +dri2_query_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, + EGLint attribute, EGLint *value) +{ + struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); + + switch (attribute) { + case EGL_BUFFER_AGE_EXT: + *value = dri2_surf->buffer_age[WL_BUFFER_BACK]; + return EGL_TRUE; + default: + return _eglQuerySurface (drv, dpy, surface, attribute, value); + } +} + /** * Called via eglDestroySurface(), drv->API.DestroySurface(). */ @@ -223,7 +239,7 @@ dri2_wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap) dri2_buf->dri_buffer); free(dri2_buf); - + egl_pixmap->driver_private = NULL; egl_pixmap->destroy = NULL; } @@ -257,7 +273,7 @@ dri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format) /* allocate a front buffer for our double-buffered window*/ if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL) break; - dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = + dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen, __DRI_BUFFER_FRONT_LEFT, format, dri2_surf->base.Width, dri2_surf->base.Height); @@ -302,7 +318,7 @@ dri2_release_pending_buffer(void *data, /* FIXME: print internal error */ if (!dri2_surf->pending_buffer) return; - + dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->pending_buffer); dri2_surf->pending_buffer = NULL; @@ -326,6 +342,7 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf) dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->third_buffer); dri2_surf->third_buffer = NULL; + dri2_surf->buffer_age[WL_BUFFER_THIRD] = 0; } for (i = 0; i < __DRI_BUFFER_COUNT; ++i) { @@ -338,7 +355,11 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf) callback = wl_display_sync(dri2_dpy->wl_dpy); wl_callback_add_listener(callback, &release_buffer_listener, dri2_surf); + dri2_surf->buffer_age[WL_BUFFER_FRONT] = 0; break; + case __DRI_BUFFER_BACK_LEFT: + dri2_surf->buffer_age[WL_BUFFER_BACK] = 0; + /* fall through */ default: dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->dri_buffers[i]); @@ -357,6 +378,14 @@ pointer_swap(const void **p1, const void **p2) *p2 = tmp; } +static inline void +int_swap(int *i1, int *i2) +{ + int tmp = *i1; + *i1 = *i2; + *i2 = tmp; +} + static void destroy_third_buffer(struct dri2_egl_surface *dri2_surf) { @@ -369,6 +398,7 @@ destroy_third_buffer(struct dri2_egl_surface *dri2_surf) dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen, dri2_surf->third_buffer); dri2_surf->third_buffer = NULL; + dri2_surf->buffer_age[WL_BUFFER_THIRD] = 0; if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]) wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]); @@ -380,12 +410,9 @@ static void swap_wl_buffers(struct dri2_egl_surface *dri2_surf, enum wayland_buffer_type a, enum wayland_buffer_type b) { - int tmp; + int_swap(&dri2_surf->wl_buffer_lock[a], &dri2_surf->wl_buffer_lock[b]); + int_swap(&dri2_surf->buffer_age[a], &dri2_surf->buffer_age[b]); - tmp = dri2_surf->wl_buffer_lock[a]; - dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b]; - dri2_surf->wl_buffer_lock[b] = tmp; - pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a], (const void **) &dri2_surf->wl_drm_buffer[b]); } @@ -431,7 +458,7 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable, int i; if (dri2_surf->base.Type == EGL_WINDOW_BIT && - (dri2_surf->base.Width != dri2_surf->wl_win->width || + (dri2_surf->base.Width != dri2_surf->wl_win->width || dri2_surf->base.Height != dri2_surf->wl_win->height)) { dri2_release_buffers(dri2_surf); @@ -463,7 +490,7 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable, attachments[i], attachments[i+1], dri2_surf->base.Width, dri2_surf->base.Height); - if (!dri2_surf->dri_buffers[attachments[i]]) + if (!dri2_surf->dri_buffers[attachments[i]]) continue; if (attachments[i] == __DRI_BUFFER_FRONT_LEFT) @@ -591,9 +618,9 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT], (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]); - dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment = + dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment = __DRI_BUFFER_FRONT_LEFT; - dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment = + dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment = __DRI_BUFFER_BACK_LEFT; swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK); @@ -621,6 +648,11 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv, wl_surface_damage(dri2_surf->wl_win->surface, rect[0], rect[1], rect[2], rect[3]); } + + for (i = 0; i < WL_BUFFER_COUNT; i++) + if (dri2_surf->buffer_age[i] != 0) + dri2_surf->buffer_age[i]++; + dri2_surf->buffer_age[WL_BUFFER_FRONT] = 1; } _EGLContext *ctx; @@ -818,6 +850,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) drv->API.CreateWindowSurface = dri2_create_window_surface; drv->API.CreatePixmapSurface = dri2_create_pixmap_surface; + drv->API.QuerySurface = dri2_query_surface; drv->API.DestroySurface = dri2_destroy_surface; drv->API.SwapBuffers = dri2_swap_buffers; drv->API.SwapBuffersWithDamageEXT = dri2_swap_buffers_with_damage; @@ -873,7 +906,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer; dri2_dpy->dri2_loader_extension.getBuffersWithFormat = dri2_get_buffers_with_format; - + dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; dri2_dpy->extensions[1] = &image_lookup_extension.base; dri2_dpy->extensions[2] = &use_invalidate.base; @@ -898,6 +931,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) disp->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE; + disp->Extensions.EXT_buffer_age = EGL_TRUE; + /* we're supporting EGL 1.4 */ disp->VersionMajor = 1; disp->VersionMinor = 4; @@ -915,6 +950,6 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) wl_drm_destroy(dri2_dpy->wl_drm); cleanup_dpy: free(dri2_dpy); - + return EGL_FALSE; } |