diff options
Diffstat (limited to 'src/gallium/state_trackers')
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 741e5b46593..9d5734d46f9 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 33894b614f9..4c8b8dfe9e0 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 5ddcf673607..4714e24b5c6 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 0e0babdb14f..a44b9b9ae5c 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 3f869b25acf..095186e3cf3 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 0dda786bbdb..2192a1366d2 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 e02faa9b7ba..1a1844ec49a 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) |