st/egl: Clean up ximage surface.

Mainly to move buffer allocation code from ximage_surface_validate to
the new ximage_surface_update_buffers.
This commit is contained in:
Chia-I Wu
2010-02-19 22:36:16 +08:00
parent 71e3abc014
commit d6b348ddd1
@@ -79,11 +79,12 @@ struct ximage_surface {
XVisualInfo visual;
struct ximage_display *xdpy;
int width, height;
GC gc;
struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
unsigned int sequence_number;
int width, height;
struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
uint valid_mask;
};
struct ximage_config {
@@ -195,6 +196,92 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
return (xbuf->texture != NULL);
}
/**
* Update the geometry of the surface. Return TRUE if the geometry has changed
* since last call.
*/
static boolean
ximage_surface_update_geometry(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
Status ok;
Window root;
int x, y;
unsigned int w, h, border, depth;
boolean updated = FALSE;
/* pbuffer has fixed geometry */
if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
return FALSE;
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
if (!ok) {
w = xsurf->width;
h = xsurf->height;
}
/* all buffers become invalid */
if (xsurf->width != w || xsurf->height != h) {
xsurf->width = w;
xsurf->height = h;
xsurf->valid_mask = 0x0;
xsurf->sequence_number++;
updated = TRUE;
}
return updated;
}
/**
* Update the buffers of the surface. It is a slow function due to the
* round-trip to the server.
*/
static boolean
ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean updated;
uint new_valid;
int att;
updated = ximage_surface_update_geometry(&xsurf->base);
buffer_mask &= ~xsurf->valid_mask;
/* all requested buffers are valid */
if (!buffer_mask)
return TRUE;
new_valid = 0x0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(buffer_mask, att)) {
struct ximage_buffer *xbuf = &xsurf->buffers[att];
/* reallocate the texture */
if (!ximage_surface_alloc_buffer(&xsurf->base, att))
break;
/* update ximage */
if (xbuf->ximage) {
xbuf->ximage->width = xsurf->width;
xbuf->ximage->height = xsurf->height;
}
new_valid |= (1 << att);
if (buffer_mask == new_valid)
break;
}
}
if (new_valid) {
xsurf->valid_mask |= new_valid;
if (updated)
xsurf->sequence_number++;
}
return (new_valid == buffer_mask);
}
static boolean
ximage_surface_draw_buffer(struct native_surface *nsurf,
enum native_attachment which)
@@ -254,44 +341,24 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_buffer *xfront, *xback, xtmp;
boolean ret;
/* display the back buffer first */
ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
/* draw the back buffer directly if there is no front buffer */
/* skip swapping so that the front buffer is allocated only when needed */
if (!xfront->texture)
return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
return ret;
/* swap the buffers */
xtmp = *xfront;
*xfront = *xback;
*xback = xtmp;
/* the front/back textures are swapped */
xsurf->sequence_number++;
return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
}
static void
ximage_surface_update_geometry(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
Status ok;
Window root;
int x, y;
unsigned int w, h, border, depth;
/* pbuffer has fixed geometry */
if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
return;
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
if (ok) {
xsurf->width = w;
xsurf->height = h;
}
return ret;
}
static boolean
@@ -300,44 +367,25 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean new_buffers = FALSE;
int att;
ximage_surface_update_geometry(&xsurf->base);
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
struct ximage_buffer *xbuf = &xsurf->buffers[att];
/* delay the allocation */
if (!native_attachment_mask_test(attachment_mask, att))
continue;
/* reallocate the texture */
if (!xbuf->texture ||
xsurf->width != xbuf->texture->width0 ||
xsurf->height != xbuf->texture->height0) {
new_buffers = TRUE;
if (ximage_surface_alloc_buffer(&xsurf->base, att)) {
/* update ximage */
if (xbuf->ximage) {
xbuf->ximage->width = xsurf->width;
xbuf->ximage->height = xsurf->height;
}
}
}
if (textures) {
textures[att] = NULL;
pipe_texture_reference(&textures[att], xbuf->texture);
}
}
/* increase the sequence number so that caller knows */
if (new_buffers)
xsurf->sequence_number++;
if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
return FALSE;
if (seq_num)
*seq_num = xsurf->sequence_number;
if (textures) {
int att;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(attachment_mask, att)) {
struct ximage_buffer *xbuf = &xsurf->buffers[att];
textures[att] = NULL;
pipe_texture_reference(&textures[att], xbuf->texture);
}
}
}
if (width)
*width = xsurf->width;
if (height)