diff options
author | Chia-I Wu <[email protected]> | 2010-02-25 21:16:56 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2010-02-25 21:29:37 +0800 |
commit | 33b92471a7b97c4f3ebf722e8551f37e167a445c (patch) | |
tree | 7c1a19b1c8554c5cfbdb4203f0ec45f2df8a8e20 /src/gallium/state_trackers/egl | |
parent | 29ec53d8439eab85f39de02bd18539c26410d2bf (diff) |
st/egl: Reduce validation round-trips in ximage backend.
ximage_surface_validate is called several times per frame. This commit
adds the client and server stamps to reduce the round-trips to the
server. The idea is to bump the server stamp when flush_frontbuffer or
swap_buffers is called, and to skip the round-trip when the client stamp
is equal to the server stamp. This makes sure the client APIs get the
new buffers when a new frame is started while skipping all round-trips
during the drawing. To make this work, egl_g3d_validate_context is no
longer called after swap_buffers.
Diffstat (limited to 'src/gallium/state_trackers/egl')
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d.c | 20 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/x11/native_ximage.c | 62 |
2 files changed, 39 insertions, 43 deletions
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 13a7487ea83..086e644e211 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -931,25 +931,7 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) if (gctx) gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb); - /* - * We drew on the back buffer, unless there was no back buffer. - * In that case, we drew on the front buffer. Either case, we call - * swap_buffers. - */ - if (!gsurf->native->swap_buffers(gsurf->native)) - return EGL_FALSE; - - if (gctx) { - struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); - - /* force validation if the swap method is not copy */ - if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) { - gctx->force_validate = EGL_TRUE; - egl_g3d_validate_context(dpy, &gctx->base); - } - } - - return EGL_TRUE; + return gsurf->native->swap_buffers(gsurf->native); } /** diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 78675a19985..8ba73f289dd 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -81,7 +81,8 @@ struct ximage_surface { GC gc; - unsigned int sequence_number; + unsigned int server_stamp; + unsigned int client_stamp; int width, height; struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS]; uint valid_mask; @@ -216,18 +217,11 @@ ximage_surface_update_geometry(struct native_surface *nsurf) 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) { + if (ok && (xsurf->width != w || xsurf->height != h)) { xsurf->width = w; xsurf->height = h; - xsurf->valid_mask = 0x0; - xsurf->sequence_number++; + xsurf->server_stamp++; updated = TRUE; } @@ -247,10 +241,18 @@ ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask) int att; updated = ximage_surface_update_geometry(&xsurf->base); - buffer_mask &= ~xsurf->valid_mask; - /* all requested buffers are valid */ - if (!buffer_mask) - return TRUE; + if (updated) { + /* all buffers become invalid */ + xsurf->valid_mask = 0x0; + } + else { + buffer_mask &= ~xsurf->valid_mask; + /* all requested buffers are valid */ + if (!buffer_mask) { + xsurf->client_stamp = xsurf->server_stamp; + return TRUE; + } + } new_valid = 0x0; for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { @@ -273,11 +275,8 @@ ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask) } } - if (new_valid) { - xsurf->valid_mask |= new_valid; - if (updated) - xsurf->sequence_number++; - } + xsurf->valid_mask |= new_valid; + xsurf->client_stamp = xsurf->server_stamp; return (new_valid == buffer_mask); } @@ -333,7 +332,15 @@ ximage_surface_draw_buffer(struct native_surface *nsurf, static boolean ximage_surface_flush_frontbuffer(struct native_surface *nsurf) { - return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); + struct ximage_surface *xsurf = ximage_surface(nsurf); + boolean ret; + + ret = ximage_surface_draw_buffer(&xsurf->base, + NATIVE_ATTACHMENT_FRONT_LEFT); + /* force buffers to be updated in next validation call */ + xsurf->server_stamp++; + + return ret; } static boolean @@ -345,6 +352,8 @@ ximage_surface_swap_buffers(struct native_surface *nsurf) /* display the back buffer first */ ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT); + /* force buffers to be updated in next validation call */ + xsurf->server_stamp++; xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT]; xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT]; @@ -356,7 +365,6 @@ ximage_surface_swap_buffers(struct native_surface *nsurf) xtmp = *xfront; *xfront = *xback; *xback = xtmp; - xsurf->sequence_number++; return ret; } @@ -368,11 +376,14 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, { struct ximage_surface *xsurf = ximage_surface(nsurf); - if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask)) - return FALSE; + if (xsurf->client_stamp != xsurf->server_stamp || + (xsurf->valid_mask & attachment_mask) != attachment_mask) { + if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask)) + return FALSE; + } if (seq_num) - *seq_num = xsurf->sequence_number; + *seq_num = xsurf->client_stamp; if (textures) { int att; @@ -453,6 +464,9 @@ ximage_display_create_surface(struct native_display *ndpy, return NULL; } + /* initialize the geometry */ + ximage_surface_update_buffers(&xsurf->base, 0x0); + for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) { struct ximage_buffer *xbuf = &xsurf->buffers[i]; |