summaryrefslogtreecommitdiff
path: root/src/egl/drivers/dri2/platform_wayland.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/drivers/dri2/platform_wayland.c')
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c71
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;
}