st/egl: Cache the pipe surface used in flush_frontbuffer.
authorChia-I Wu <olv@lunarg.com>
Fri, 12 Mar 2010 16:48:23 +0000 (00:48 +0800)
committerChia-I Wu <olv@lunarg.com>
Sat, 13 Mar 2010 05:05:21 +0000 (13:05 +0800)
It is very likely that the same surface will be flushed again and again.
Caching the surface should reduce the overhead of surface creation.

src/gallium/state_trackers/egl/x11/native_ximage.c

index e0d12acabe83d5e6e1cb4b5b1a2e9f122edeb71d..c6b16354f9bb67efbae05e63567d4baf5319d77b 100644 (file)
@@ -82,6 +82,8 @@ struct ximage_surface {
    int width, height;
    struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
    uint valid_mask;
+
+   struct pipe_surface *draw_surface;
 };
 
 struct ximage_config {
@@ -266,15 +268,19 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
 
    assert(xsurf->drawable && xbuf->texture);
 
-   /* what's the cost of surface creation? */
-   psurf = screen->get_tex_surface(screen,
-         xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
-   if (!psurf)
-      return FALSE;
+   psurf = xsurf->draw_surface;
+   if (!psurf || psurf->texture != xbuf->texture) {
+      pipe_surface_reference(&xsurf->draw_surface, NULL);
 
-   screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
+      psurf = screen->get_tex_surface(screen,
+            xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+      if (!psurf)
+         return FALSE;
 
-   pipe_surface_reference(&psurf, NULL);
+      xsurf->draw_surface = psurf;
+   }
+
+   screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
 
    return TRUE;
 }
@@ -371,6 +377,8 @@ ximage_surface_destroy(struct native_surface *nsurf)
    struct ximage_surface *xsurf = ximage_surface(nsurf);
    int i;
 
+   pipe_surface_reference(&xsurf->draw_surface, NULL);
+
    for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
       ximage_surface_free_buffer(&xsurf->base, i);