mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 09:30:11 +01:00
st/egl: Add event support to the native display interface.
There is only invalid_surface event right now. When EGL receives the event, it sets the force_validate flag of the context binding to the surface. This helps skip an unnecessary check.
This commit is contained in:
parent
45df4bad9f
commit
e38f28dded
8 changed files with 106 additions and 14 deletions
|
|
@ -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) ?
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
@ -238,6 +248,20 @@ struct native_display_modeset {
|
|||
const struct native_mode *nmode);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue