}
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];
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,
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;
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;
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;
struct native_surface *native;
enum native_attachment render_att;
struct pipe_surface *render_surface;
+ unsigned int sequence_number;
};
struct egl_g3d_config {
/**
* 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
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);
/**
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);
pipe_texture_reference(&textures[i], ptex);
}
+ if (seq_num)
+ *seq_num = ksurf->sequence_number;
if (width)
*width = ksurf->width;
if (height)
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;
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;
}
int width, height;
struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ unsigned int sequence_number;
struct kms_framebuffer front_fb, back_fb;
boolean is_shown;
struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS];
boolean have_back, have_fake;
int width, height;
+ unsigned int sequence_number;
};
struct dri2_config {
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)
{
pipe_texture_reference(&textures[i], ptex);
}
+ if (seq_num)
+ *seq_num = dri2surf->sequence_number;
if (width)
*width = dri2surf->width;
if (height)
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];
free(xbufs);
+ if (seq_num)
+ *seq_num = dri2surf->sequence_number;
if (width)
*width = dri2surf->width;
if (height)
GC gc;
struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
+ unsigned int sequence_number;
};
struct ximage_config {
*xfront = *xback;
*xback = xtmp;
+ /* the front/back textures are swapped */
+ xsurf->sequence_number++;
+
return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
}
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);
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) {
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)