Alternate CopyPixels path based on get/put_tile().
authorBrian <brian.paul@tungstengraphics.com>
Thu, 18 Oct 2007 21:18:55 +0000 (15:18 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 18 Oct 2007 21:18:55 +0000 (15:18 -0600)
For some drivers (like Xlib) it's not possible to treat the front/back color
buffers as pipe_regions.  So pipe->region_copy() won't work.  Added a new
state tracker field indicating if we can use regions for colorbuffer accesses.
This should probably be re-considered someday...

src/mesa/drivers/x11/xm_api.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h

index 1d3f799f3688048eb9949cddc5b0244ecb6fd228..ff83dab075237e26344858b8359fda07f6408ebf 100644 (file)
@@ -1603,6 +1603,8 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
    mesaCtx->st->pipe->surface_alloc = xmesa_surface_alloc;
    mesaCtx->st->pipe->supported_formats = xmesa_supported_formats;
 
+   mesaCtx->st->haveFramebufferRegions = GL_FALSE;
+
    /* special pipe->clear function */
    mesaCtx->st->pipe->clear = xmesa_clear;
 
index b88b96e3b2f1b9829629c5ead17bbb7c7fa3db92..90f91c39b5d0b82484decbee2d33dc5d87b63be3 100644 (file)
@@ -1219,14 +1219,40 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
       srcy = ctx->DrawBuffer->Height - srcy - height;
    }
 
-   /* copy source framebuffer region into mipmap/texture */
-   pipe->region_copy(pipe,
-                     mt->region, /* dest */
-                     0, /* dest_offset */
-                     0, 0, /* destx/y */
-                     psRead->region,
-                     0, /* src_offset */
-                     srcx, srcy, width, height);
+   /* For some drivers (like Xlib) it's not possible to treat the
+    * front/back color buffers as regions (they're XImages and Pixmaps).
+    * So, this var tells us if we can use region_copy here...
+    */
+   if (st->haveFramebufferRegions) {
+      /* copy source framebuffer region into mipmap/texture */
+      pipe->region_copy(pipe,
+                        mt->region, /* dest */
+                        0, /* dest_offset */
+                        0, 0, /* destx/y */
+                        psRead->region,
+                        0, /* src_offset */
+                        srcx, srcy, width, height);
+   }
+   else {
+      /* alternate path using get/put_tile() */
+      struct pipe_surface *psTex;
+      GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
+
+      psTex = pipe->get_tex_surface(pipe, mt, 0, 0, 0);
+
+      (void) pipe->region_map(pipe, psRead->region);
+      (void) pipe->region_map(pipe, psTex->region);
+
+      psRead->get_tile(psRead, srcx, srcy, width, height, buf);
+      psTex->put_tile(psTex, 0, 0, width, height, buf);
+
+      pipe->region_unmap(pipe, psRead->region);
+      pipe->region_unmap(pipe, psTex->region);
+
+      pipe_surface_reference(&psTex, NULL);
+
+      free(buf);
+   }
 
 
    /* draw textured quad */
index 09d9b1ea3b442f1ad44104e6220afb0de262c21b..8ced3f504c2abfbe1863918d45902ba6e3ac0ba1 100644 (file)
@@ -90,6 +90,7 @@ struct st_context *st_create_context( GLcontext *ctx,
 
    st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
 
+   st->haveFramebufferRegions = GL_TRUE;
 
 #if 0
    st_init_cb_clear( st );
index b4ae041d36c1d2c482b8cce25e7e322730964f88..bacc0b9b3ff2cf3f871db6ee9368e1b57f60a41b 100644 (file)
@@ -111,6 +111,12 @@ struct st_context
    char vendor[100];
    char renderer[100];
 
+   /** Can we access the front/back color buffers as pipe_regions?
+    * We can't with the Xlib driver...
+    * This is a hack that should be fixed someday.
+    */
+   GLboolean haveFramebufferRegions;
+
    /* State to be validated:
     */
    struct st_tracked_state **atoms;