summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/egl/x11/native_ximage.c
diff options
context:
space:
mode:
authorChia-I Wu <olv@lunarg.com>2010-02-19 22:36:16 +0800
committerChia-I Wu <olv@lunarg.com>2010-02-21 10:22:07 +0800
commitd6b348ddd182999e4f3514e990e0bfb4f871805b (patch)
tree80549706834f1bd381450d6d39efa04d270e47a9 /src/gallium/state_trackers/egl/x11/native_ximage.c
parent71e3abc014cf8a1c18dcfd87517546a47ba41b6d (diff)
st/egl: Clean up ximage surface.
Mainly to move buffer allocation code from ximage_surface_validate to the new ximage_surface_update_buffers.
Diffstat (limited to 'src/gallium/state_trackers/egl/x11/native_ximage.c')
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c170
1 files changed, 109 insertions, 61 deletions
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 92a62f230e..78675a1998 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -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);
+ if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
+ return FALSE;
- 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 (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];
- if (textures) {
- textures[att] = NULL;
- pipe_texture_reference(&textures[att], xbuf->texture);
+ 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 (seq_num)
- *seq_num = xsurf->sequence_number;
if (width)
*width = xsurf->width;
if (height)