summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/egl_g3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/egl_g3d')
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/egl_g3d.c35
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/egl_g3d.h1
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/native.h7
-rw-r--r--src/gallium/state_trackers/egl_g3d/kms/native_kms.c9
-rw-r--r--src/gallium/state_trackers/egl_g3d/kms/native_kms.h1
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/native_dri2.c20
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/native_ximage.c14
7 files changed, 66 insertions, 21 deletions
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
index 741e5b4659..9d5734d46f 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
@@ -63,22 +63,19 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
}
if (!gctx->force_validate) {
- EGLint cur_w, cur_h;
+ unsigned int seq_num;
- cur_w = gsurf->base.Width;
- cur_h = gsurf->base.Height;
gsurf->native->validate(gsurf->native,
gbuf->native_atts, gbuf->num_atts,
- NULL,
- &gsurf->base.Width, &gsurf->base.Height);
- /* validate only when the geometry changed */
- if (gsurf->base.Width == cur_w && gsurf->base.Height == cur_h)
+ &seq_num, NULL, NULL, NULL);
+ /* skip validation */
+ if (gsurf->sequence_number == seq_num)
continue;
}
gsurf->native->validate(gsurf->native,
gbuf->native_atts, gbuf->num_atts,
- (struct pipe_texture **) textures,
+ &gsurf->sequence_number, textures,
&gsurf->base.Width, &gsurf->base.Height);
for (i = 0; i < gbuf->num_atts; i++) {
struct pipe_texture *pt = textures[i];
@@ -599,6 +596,16 @@ egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
return EGL_TRUE;
}
+static EGLBoolean
+init_surface_geometry(_EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ return gsurf->native->validate(gsurf->native, NULL, 0,
+ &gsurf->sequence_number, NULL,
+ &gsurf->base.Width, &gsurf->base.Height);
+}
+
static _EGLSurface *
egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, EGLNativeWindowType win,
@@ -626,8 +633,7 @@ egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return NULL;
}
- if (!gsurf->native->validate(gsurf->native, NULL, 0, NULL,
- &gsurf->base.Width, &gsurf->base.Height)) {
+ if (!init_surface_geometry(&gsurf->base)) {
gsurf->native->destroy(gsurf->native);
free(gsurf);
return NULL;
@@ -667,8 +673,7 @@ egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return NULL;
}
- if (!gsurf->native->validate(gsurf->native, NULL, 0, NULL,
- &gsurf->base.Width, &gsurf->base.Height)) {
+ if (!init_surface_geometry(&gsurf->base)) {
gsurf->native->destroy(gsurf->native);
free(gsurf);
return NULL;
@@ -706,6 +711,12 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return NULL;
}
+ if (!init_surface_geometry(&gsurf->base)) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
index 33894b614f..4c8b8dfe9e 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
@@ -73,6 +73,7 @@ struct egl_g3d_surface {
struct native_surface *native;
enum native_attachment render_att;
struct pipe_surface *render_surface;
+ unsigned int sequence_number;
};
struct egl_g3d_config {
diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h
index 5ddcf67360..4714e24b5c 100644
--- a/src/gallium/state_trackers/egl_g3d/common/native.h
+++ b/src/gallium/state_trackers/egl_g3d/common/native.h
@@ -65,8 +65,9 @@ struct native_surface {
/**
* Validate the buffers of the surface. The returned textures are owned by
- * the caller. It is possible that this function is called with textures,
- * width, or height being NULL.
+ * the caller. A sequence number is also returned. The caller can use it
+ * to check if anything has changed since the last call. Any of the pointers
+ * may be NULL and it indicates the caller has no interest in those values.
*
* If this function is called multiple times with different attachments,
* those not listed in the latest call might be destroyed. This behavior
@@ -75,7 +76,7 @@ struct native_surface {
boolean (*validate)(struct native_surface *nsurf,
const enum native_attachment *natts,
unsigned num_natts,
- struct pipe_texture **textures,
+ unsigned int *seq_num, struct pipe_texture **textures,
int *width, int *height);
/**
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
index 0e0babdb14..a44b9b9ae5 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
@@ -36,7 +36,7 @@ static boolean
kms_surface_validate(struct native_surface *nsurf,
const enum native_attachment *natts,
unsigned num_natts,
- struct pipe_texture **textures,
+ unsigned int *seq_num, struct pipe_texture **textures,
int *width, int *height)
{
struct kms_surface *ksurf = kms_surface(nsurf);
@@ -75,6 +75,8 @@ kms_surface_validate(struct native_surface *nsurf,
pipe_texture_reference(&textures[i], ptex);
}
+ if (seq_num)
+ *seq_num = ksurf->sequence_number;
if (width)
*width = ksurf->width;
if (height)
@@ -111,7 +113,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
if (!fb->texture) {
/* make sure the texture has been allocated */
- kms_surface_validate(&ksurf->base, &natt, 1, NULL, NULL, NULL);
+ kms_surface_validate(&ksurf->base, &natt, 1, NULL, NULL, NULL, NULL);
if (!ksurf->textures[natt])
return FALSE;
@@ -196,6 +198,9 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT];
ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture;
+ /* the front/back textures are swapped */
+ ksurf->sequence_number++;
+
return TRUE;
}
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h b/src/gallium/state_trackers/egl_g3d/kms/native_kms.h
index 3f869b25ac..095186e3cf 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.h
@@ -81,6 +81,7 @@ struct kms_surface {
int width, height;
struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ unsigned int sequence_number;
struct kms_framebuffer front_fb, back_fb;
boolean is_shown;
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
index 0dda786bbd..2192a1366d 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
@@ -64,6 +64,7 @@ struct dri2_surface {
struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS];
boolean have_back, have_fake;
int width, height;
+ unsigned int sequence_number;
};
struct dri2_config {
@@ -136,6 +137,7 @@ static boolean
dri2_surface_validate(struct native_surface *nsurf,
const enum native_attachment *natts,
unsigned num_natts,
+ unsigned int *seq_num,
struct pipe_texture **textures,
int *width, int *height)
{
@@ -178,6 +180,8 @@ dri2_surface_validate(struct native_surface *nsurf,
pipe_texture_reference(&textures[i], ptex);
}
+ if (seq_num)
+ *seq_num = dri2surf->sequence_number;
if (width)
*width = dri2surf->width;
if (height)
@@ -219,15 +223,23 @@ dri2_surface_validate(struct native_surface *nsurf,
dri2surf->have_back = FALSE;
dri2surf->have_fake = FALSE;
+ /* remember old geometry */
+ templ.width0 = dri2surf->width;
+ templ.height0 = dri2surf->height;
+
xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
&dri2surf->width, &dri2surf->height,
dri2atts, FALSE, num_ins, &num_outs);
if (!xbufs)
return FALSE;
- /* update width and height */
- templ.width0 = dri2surf->width;
- templ.height0 = dri2surf->height;
+ if (templ.width0 != dri2surf->width || templ.height0 != dri2surf->height) {
+ /* are there cases where the buffers change and the geometry doesn't? */
+ dri2surf->sequence_number++;
+
+ templ.width0 = dri2surf->width;
+ templ.height0 = dri2surf->height;
+ }
for (i = 0; i < num_outs; i++) {
struct x11_drawable_buffer *xbuf = &xbufs[i];
@@ -279,6 +291,8 @@ dri2_surface_validate(struct native_surface *nsurf,
free(xbufs);
+ if (seq_num)
+ *seq_num = dri2surf->sequence_number;
if (width)
*width = dri2surf->width;
if (height)
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
index e02faa9b7b..1a1844ec49 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
@@ -83,6 +83,7 @@ struct ximage_surface {
GC gc;
struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
+ unsigned int sequence_number;
};
struct ximage_config {
@@ -260,6 +261,9 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
*xfront = *xback;
*xback = xtmp;
+ /* the front/back textures are swapped */
+ xsurf->sequence_number++;
+
return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
}
@@ -288,11 +292,12 @@ static boolean
ximage_surface_validate(struct native_surface *nsurf,
const enum native_attachment *natts,
unsigned num_natts,
+ unsigned int *seq_num,
struct pipe_texture **textures,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- boolean error = FALSE;
+ boolean new_buffers = FALSE, error = FALSE;
unsigned i;
ximage_surface_update_geometry(&xsurf->base);
@@ -311,6 +316,7 @@ ximage_surface_validate(struct native_surface *nsurf,
if (!xbuf->texture ||
xsurf->width != xbuf->texture->width0 ||
xsurf->height != xbuf->texture->height0) {
+ new_buffers = TRUE;
if (ximage_surface_alloc_buffer(&xsurf->base, natt)) {
/* update ximage */
if (xbuf->ximage) {
@@ -336,6 +342,12 @@ ximage_surface_validate(struct native_surface *nsurf,
pipe_texture_reference(&textures[i], xbuf->texture);
}
+ /* increase the sequence number so that caller knows */
+ if (new_buffers)
+ xsurf->sequence_number++;
+
+ if (seq_num)
+ *seq_num = xsurf->sequence_number;
if (width)
*width = xsurf->width;
if (height)