summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c23
-rw-r--r--src/gallium/state_trackers/egl/common/native.h27
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c13
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h2
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c20
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c7
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h8
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c20
8 files changed, 106 insertions, 14 deletions
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 04268c71c5a..ddb1ef1bf1f 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -531,6 +531,24 @@ egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
}
+static void
+egl_g3d_invalid_surface(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num)
+{
+ /* XXX not thread safe? */
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
+ struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
+
+ /* set force_validate to skip an unnecessary check */
+ if (gctx)
+ gctx->force_validate = TRUE;
+}
+
+static struct native_event_handler egl_g3d_native_event_handler = {
+ .invalid_surface = egl_g3d_invalid_surface
+};
+
static EGLBoolean
egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
@@ -575,12 +593,14 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
dpy->DriverData = gdpy;
- gdpy->native = native_create_display(dpy->NativeDisplay);
+ gdpy->native = native_create_display(dpy->NativeDisplay,
+ &egl_g3d_native_event_handler);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
+ gdpy->native->user_data = (void *) dpy;
gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
@@ -776,6 +796,7 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
+ nsurf->user_data = &gsurf->base;
gsurf->native = nsurf;
gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 4f9758545ab..1bf2804db5d 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -69,6 +69,11 @@ struct native_probe {
};
struct native_surface {
+ /**
+ * Available for caller's use.
+ */
+ void *user_data;
+
void (*destroy)(struct native_surface *nsurf);
/**
@@ -143,6 +148,11 @@ struct native_display {
*/
struct pipe_screen *screen;
+ /**
+ * Available for caller's use.
+ */
+ void *user_data;
+
void (*destroy)(struct native_display *ndpy);
/**
@@ -239,6 +249,20 @@ struct native_display_modeset {
};
/**
+ * The handler for events that a native display may generate. The events are
+ * generated asynchronously and the handler may be called by any thread at any
+ * time.
+ */
+struct native_event_handler {
+ /**
+ * This function is called when a surface needs to be validated.
+ */
+ void (*invalid_surface)(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num);
+};
+
+/**
* Test whether an attachment is set in the mask.
*/
static INLINE boolean
@@ -267,6 +291,7 @@ const char *
native_get_name(void);
struct native_display *
-native_create_display(EGLNativeDisplayType dpy);
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *handler);
#endif /* _NATIVE_H_ */
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index aedf3d430ca..90c82eaf6ce 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -201,6 +201,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
/* the front/back textures are swapped */
ksurf->sequence_number++;
+ kdpy->event_handler->invalid_surface(&kdpy->base,
+ &ksurf->base, ksurf->sequence_number);
return TRUE;
}
@@ -762,7 +764,9 @@ static struct native_display_modeset kms_display_modeset = {
};
static struct native_display *
-kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
+kms_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api)
{
struct kms_display *kdpy;
@@ -770,6 +774,8 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
if (!kdpy)
return NULL;
+ kdpy->event_handler = event_handler;
+
kdpy->api = api;
if (!kdpy->api) {
_eglLog(_EGL_WARNING, "failed to create DRM API");
@@ -845,7 +851,8 @@ native_get_name(void)
}
struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
@@ -853,7 +860,7 @@ native_create_display(EGLNativeDisplayType dpy)
drm_api = drm_api_create();
if (drm_api)
- ndpy = kms_create_display(dpy, drm_api);
+ ndpy = kms_create_display(dpy, event_handler, drm_api);
return ndpy;
}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
index 095186e3cf3..f9cbcb158b5 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -53,6 +53,8 @@ struct kms_crtc {
struct kms_display {
struct native_display base;
+ struct native_event_handler *event_handler;
+
int fd;
struct drm_api *api;
drmModeResPtr resources;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 74d3d104b94..858033e1c10 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -48,6 +48,8 @@ struct dri2_display {
Display *dpy;
boolean own_dpy;
+ struct native_event_handler *event_handler;
+
struct drm_api *api;
struct x11_screen *xscr;
int xscr_number;
@@ -324,8 +326,11 @@ dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
/* force buffers to be updated in next validation call */
- if (!dri2_surface_receive_events(&dri2surf->base))
+ if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
+ }
return TRUE;
}
@@ -353,8 +358,11 @@ dri2_surface_swap_buffers(struct native_surface *nsurf)
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
/* force buffers to be updated in next validation call */
- if (!dri2_surface_receive_events(&dri2surf->base))
+ if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
+ }
return TRUE;
}
@@ -737,7 +745,10 @@ dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
return;
dri2surf = dri2_surface(nsurf);
+
dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
}
/**
@@ -796,7 +807,9 @@ dri2_display_hash_table_compare(void *key1, void *key2)
}
struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api)
{
struct dri2_display *dri2dpy;
@@ -804,6 +817,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
if (!dri2dpy)
return NULL;
+ dri2dpy->event_handler = event_handler;
dri2dpy->api = api;
dri2dpy->dpy = dpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 3add95d0aca..7b4fe63fa07 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -126,7 +126,8 @@ native_get_name(void)
}
struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
boolean force_sw;
@@ -136,7 +137,7 @@ native_create_display(EGLNativeDisplayType dpy)
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
if (api && !force_sw) {
- ndpy = x11_create_dri2_display(dpy, api);
+ ndpy = x11_create_dri2_display(dpy, event_handler, api);
}
if (!ndpy) {
@@ -150,7 +151,7 @@ native_create_display(EGLNativeDisplayType dpy)
*/
use_shm = FALSE;
_eglLog(level, "use software%s fallback", (use_shm) ? " (SHM)" : "");
- ndpy = x11_create_ximage_display(dpy, use_shm);
+ ndpy = x11_create_ximage_display(dpy, event_handler, use_shm);
}
return ndpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 622ddac5df6..8c6a7d93497 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -29,9 +29,13 @@
#include "common/native.h"
struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm);
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ boolean use_xshm);
struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api);
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api);
#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index a8633b1501e..5e0270c2963 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -56,6 +56,8 @@ struct ximage_display {
struct x11_screen *xscr;
int xscr_number;
+ struct native_event_handler *event_handler;
+
boolean use_xshm;
struct pipe_winsys *winsys;
@@ -228,6 +230,16 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
return updated;
}
+static void
+ximage_surface_notify_invalid(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ struct ximage_display *xdpy = xsurf->xdpy;
+
+ xdpy->event_handler->invalid_surface(&xdpy->base,
+ &xsurf->base, xsurf->server_stamp);
+}
+
/**
* Update the buffers of the surface. It is a slow function due to the
* round-trip to the server.
@@ -339,6 +351,7 @@ ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
NATIVE_ATTACHMENT_FRONT_LEFT);
/* force buffers to be updated in next validation call */
xsurf->server_stamp++;
+ ximage_surface_notify_invalid(&xsurf->base);
return ret;
}
@@ -354,6 +367,7 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
/* force buffers to be updated in next validation call */
xsurf->server_stamp++;
+ ximage_surface_notify_invalid(&xsurf->base);
xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
@@ -703,7 +717,9 @@ ximage_display_destroy(struct native_display *ndpy)
}
struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ boolean use_xshm)
{
struct ximage_display *xdpy;
@@ -728,6 +744,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
return NULL;
}
+ xdpy->event_handler = event_handler;
+
xdpy->use_xshm =
(use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));