From: Chia-I Wu Date: Thu, 25 Feb 2010 13:16:56 +0000 (+0800) Subject: st/egl: Reduce validation round-trips in ximage backend. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=33b92471a7b97c4f3ebf722e8551f37e167a445c;p=mesa.git 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. --- 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];