swrast: stop using Put/GetRow/Values() in swrast code
authorBrian Paul <brianp@vmware.com>
Mon, 16 Jan 2012 17:55:39 +0000 (10:55 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 24 Jan 2012 21:12:15 +0000 (14:12 -0700)
All color buffer rendering is now done by accessing mapped renderbuffer
memory.  We're now able to get rid of all the GetRow/PutRow stuff.

src/mesa/swrast/s_copypix.c
src/mesa/swrast/s_span.c
src/mesa/swrast/s_span.h
src/mesa/swrast/s_texture.c
src/mesa/swrast/s_triangle.c

index 13fc36cf9edcefcc6683451c98ccb2f12c214139..91541d2c93c85030b94b7adc85dd9af4afdde8f9 100644 (file)
@@ -557,6 +557,46 @@ swrast_fast_copy_pixels(struct gl_context *ctx,
 }
 
 
+/**
+ * Find/map the renderbuffer that we'll be reading from.
+ * The swrast_render_start() function only maps the drawing buffers,
+ * not the read buffer.
+ */
+static struct gl_renderbuffer *
+map_readbuffer(struct gl_context *ctx, GLenum type)
+{
+   struct gl_framebuffer *fb = ctx->ReadBuffer;
+   struct gl_renderbuffer *rb;
+
+   switch (type) {
+   case GL_COLOR:
+      rb = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;
+      break;
+   case GL_DEPTH:
+   case GL_DEPTH_STENCIL:
+      rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+      break;
+   case GL_STENCIL:
+      rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+      break;
+   default:
+      return NULL;
+   }
+
+   if (!rb || rb->Map) {
+      /* no buffer, or buffer is mapped already, we're done */
+      return NULL;
+   }
+
+   ctx->Driver.MapRenderbuffer(ctx, rb,
+                               0, 0, rb->Width, rb->Height,
+                               GL_MAP_READ_BIT,
+                               &rb->Map, &rb->RowStrideBytes);
+
+   return rb;
+}
+
+
 /**
  * Do software-based glCopyPixels.
  * By time we get here, all parameters will have been error-checked.
@@ -567,6 +607,7 @@ _swrast_CopyPixels( struct gl_context *ctx,
                    GLint destx, GLint desty, GLenum type )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   struct gl_renderbuffer *rb;
       
    if (!_mesa_check_conditional_render(ctx))
       return; /* don't copy */
@@ -585,6 +626,7 @@ _swrast_CopyPixels( struct gl_context *ctx,
    }
 
    swrast_render_start(ctx);
+   rb = map_readbuffer(ctx, type);
 
    switch (type) {
    case GL_COLOR:
@@ -606,4 +648,9 @@ _swrast_CopyPixels( struct gl_context *ctx,
    }
 
    swrast_render_finish(ctx);
+
+   if (rb) {
+      ctx->Driver.UnmapRenderbuffer(ctx, rb);
+      rb->Map = NULL;
+   }
 }
index beadbeb7fcdce6702abb152d4fb2166fedc0f6eb..157392a619ab41d4b4aec31d8acdd4169825f8be 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "main/glheader.h"
 #include "main/colormac.h"
+#include "main/format_pack.h"
+#include "main/format_unpack.h"
 #include "main/macros.h"
 #include "main/imports.h"
 #include "main/image.h"
@@ -1043,6 +1045,87 @@ shade_texture_span(struct gl_context *ctx, SWspan *span)
 }
 
 
+/** Put colors at x/y locations into a renderbuffer */
+static void
+put_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
+           GLuint count, const GLint x[], const GLint y[],
+           const void *values, const GLubyte *mask)
+{
+   GLuint i;
+
+   for (i = 0; i < count; i++) {
+      if (mask[i]) {
+         GLubyte *dst = _swrast_pixel_address(rb, x[i], y[i]);
+
+         if (rb->DataType == GL_UNSIGNED_BYTE) {
+            _mesa_pack_ubyte_rgba_row(rb->Format, 1,
+                                      (const GLubyte (*)[4]) values + i, dst);
+         }
+         else {
+            assert(rb->DataType == GL_FLOAT);
+            _mesa_pack_float_rgba_row(rb->Format, count,
+                                      (const GLfloat (*)[4]) values + i, dst);
+         }
+      }
+   }
+}
+
+
+/** Put row of colors into renderbuffer */
+void
+_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
+                GLuint count, GLint x, GLint y,
+                const void *values, const GLubyte *mask)
+{
+   GLubyte *dst = _swrast_pixel_address(rb, x, y);
+
+   if (!mask) {
+      if (rb->DataType == GL_UNSIGNED_BYTE) {
+         _mesa_pack_ubyte_rgba_row(rb->Format, count,
+                                   (const GLubyte (*)[4]) values, dst);
+      }
+      else {
+         assert(rb->DataType == GL_FLOAT);
+         _mesa_pack_float_rgba_row(rb->Format, count,
+                                   (const GLfloat (*)[4]) values, dst);
+      }
+   }
+   else {
+      const GLuint bpp = _mesa_get_format_bytes(rb->Format);
+      GLuint i, runLen, runStart;
+      /* We can't pass a 'mask' array to the _mesa_pack_rgba_row() functions
+       * so look for runs where mask=1...
+       */
+      runLen = 0;
+      for (i = 0; i < count; i++) {
+         if (mask[i]) {
+            if (runLen == 0)
+               runStart = i;
+            runLen++;
+         }
+
+         if (!mask[i] || i == count - 1) {
+            /* might be the end of a run of pixels */
+            if (runLen > 0) {
+               if (rb->DataType == GL_UNSIGNED_BYTE) {
+                  _mesa_pack_ubyte_rgba_row(rb->Format, runLen,
+                                     (const GLubyte (*)[4]) values + runStart,
+                                     dst + runStart * bpp);
+               }
+               else {
+                  assert(rb->DataType == GL_FLOAT);
+                  _mesa_pack_float_rgba_row(rb->Format, runLen,
+                                   (const GLfloat (*)[4]) values + runStart,
+                                   dst + runStart * bpp);
+               }
+               runLen = 0;
+            }
+         }
+      }
+   }
+}
+
+
 
 /**
  * Apply all the per-fragment operations to a span.
@@ -1290,17 +1373,15 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
 
             if (span->arrayMask & SPAN_XY) {
                /* array of pixel coords */
-               ASSERT(rb->PutValues);
-               rb->PutValues(ctx, rb, span->end,
-                             span->array->x, span->array->y,
-                             span->array->rgba, span->array->mask);
+               put_values(ctx, rb, span->end,
+                          span->array->x, span->array->y,
+                          span->array->rgba, span->array->mask);
             }
             else {
                /* horizontal run of pixels */
-               ASSERT(rb->PutRow);
-               rb->PutRow(ctx, rb, span->end, span->x, span->y,
-                          span->array->rgba,
-                          span->writeAll ? NULL: span->array->mask);
+               _swrast_put_row(ctx, rb, span->end, span->x, span->y,
+                               span->array->rgba,
+                               span->writeAll ? NULL: span->array->mask);
             }
 
             if (!multiFragOutputs && numBuffers > 1) {
@@ -1344,6 +1425,8 @@ _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
    }
    else {
       GLint skip, length;
+      GLubyte *src;
+
       if (x < 0) {
          /* left edge clipping */
          skip = -x;
@@ -1372,7 +1455,6 @@ _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
       }
 
       ASSERT(rb);
-      ASSERT(rb->GetRow);
       ASSERT(rb->_BaseFormat == GL_RGBA ||
             rb->_BaseFormat == GL_RGB ||
             rb->_BaseFormat == GL_RG ||
@@ -1382,70 +1464,69 @@ _swrast_read_rgba_span( struct gl_context *ctx, struct gl_renderbuffer *rb,
             rb->_BaseFormat == GL_LUMINANCE_ALPHA ||
             rb->_BaseFormat == GL_ALPHA);
 
-      if (rb->DataType == dstType) {
-         rb->GetRow(ctx, rb, length, x + skip, y,
-                    (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType));
+      assert(rb->Map);
+
+      src = _swrast_pixel_address(rb, x + skip, y);
+
+      if (dstType == GL_UNSIGNED_BYTE) {
+         _mesa_unpack_ubyte_rgba_row(rb->Format, length, src,
+                                     (GLubyte (*)[4]) rgba + skip);
+      }
+      else if (dstType == GL_FLOAT) {
+         _mesa_unpack_rgba_row(rb->Format, length, src,
+                               (GLfloat (*)[4]) rgba + skip);
       }
       else {
-         GLuint temp[MAX_WIDTH * 4];
-         rb->GetRow(ctx, rb, length, x + skip, y, temp);
-         _mesa_convert_colors(rb->DataType, temp,
-                   dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType),
-                   length, NULL);
+         _mesa_problem(ctx, "unexpected type in _swrast_read_rgba_span()");
       }
    }
 }
 
 
 /**
- * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid
- * reading values outside the buffer bounds.
- * We can use this for reading any format/type of renderbuffer.
- * \param valueSize is the size in bytes of each value (pixel) put into the
- *                  values array.
+ * Get colors at x/y positions with clipping.
+ * \param type  type of values to return
  */
 static void
 get_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
            GLuint count, const GLint x[], const GLint y[],
-           void *values, GLuint valueSize)
+           void *values, GLenum type)
 {
-   GLuint i, inCount = 0, inStart = 0;
+   GLuint i;
 
    for (i = 0; i < count; i++) {
       if (x[i] >= 0 && y[i] >= 0 &&
          x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) {
          /* inside */
-         if (inCount == 0)
-            inStart = i;
-         inCount++;
-      }
-      else {
-         if (inCount > 0) {
-            /* read [inStart, inStart + inCount) */
-            rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
-                          (GLubyte *) values + inStart * valueSize);
-            inCount = 0;
+         const GLubyte *src = _swrast_pixel_address(rb, x[i], y[i]);
+
+         if (type == GL_UNSIGNED_BYTE) {
+            _mesa_unpack_ubyte_rgba_row(rb->Format, 1, src,
+                                        (GLubyte (*)[4]) values + i);
+         }
+         else if (type == GL_FLOAT) {
+            _mesa_unpack_rgba_row(rb->Format, 1, src,
+                                  (GLfloat (*)[4]) values + i);
+         }
+         else {
+            _mesa_problem(ctx, "unexpected type in get_values()");
          }
       }
    }
-   if (inCount > 0) {
-      /* read last values */
-      rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart,
-                    (GLubyte *) values + inStart * valueSize);
-   }
 }
 
 
 /**
- * Wrapper for gl_renderbuffer::GetRow() which does clipping.
- * \param valueSize  size of each value (pixel) in bytes
+ * Get row of colors with clipping.
+ * \param type  type of values to return
  */
 static void
 get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
         GLuint count, GLint x, GLint y,
-        GLvoid *values, GLuint valueSize)
+        GLvoid *values, GLenum type)
 {
    GLint skip = 0;
+   GLubyte *src;
 
    if (y < 0 || y >= (GLint) rb->Height)
       return; /* above or below */
@@ -1466,7 +1547,19 @@ get_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
       count -= skip;
    }
 
-   rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);
+   src = _swrast_pixel_address(rb, x, y);
+
+   if (type == GL_UNSIGNED_BYTE) {
+      _mesa_unpack_ubyte_rgba_row(rb->Format, count, src,
+                                  (GLubyte (*)[4]) values + skip);
+   }
+   else if (type == GL_FLOAT) {
+      _mesa_unpack_rgba_row(rb->Format, count, src,
+                            (GLfloat (*)[4]) values + skip);
+   }
+   else {
+      _mesa_problem(ctx, "unexpected type in get_row()");
+   }
 }
 
 
@@ -1479,7 +1572,6 @@ void *
 _swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
                       SWspan *span)
 {
-   const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType);
    void *rbPixels;
 
    /* Point rbPixels to a temporary space */
@@ -1488,11 +1580,11 @@ _swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
    /* Get destination values from renderbuffer */
    if (span->arrayMask & SPAN_XY) {
       get_values(ctx, rb, span->end, span->array->x, span->array->y,
-                 rbPixels, pixelSize);
+                 rbPixels, span->array->ChanType);
    }
    else {
       get_row(ctx, rb, span->end, span->x, span->y,
-              rbPixels, pixelSize);
+              rbPixels, span->array->ChanType);
    }
 
    return rbPixels;
index e39ae85382b009710600db8852975c4d9bab5c87..4d6eb7ec1635c16de296f55790f3e85312e2cf7e 100644 (file)
@@ -203,6 +203,11 @@ extern void
 _swrast_read_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
                        GLuint n, GLint x, GLint y, GLvoid *rgba);
 
+extern void
+_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
+                GLuint count, GLint x, GLint y,
+                const void *values, const GLubyte *mask);
+
 extern void *
 _swrast_get_dest_rgba(struct gl_context *ctx, struct gl_renderbuffer *rb,
                       SWspan *span);
index f945a6b0fa8dd2766923f345cd576a1b2fe27472..b98195e7489cef6cd96ef6aff2a9296f1afb9e21 100644 (file)
@@ -342,14 +342,11 @@ map_attachment(struct gl_context *ctx,
    }
    else if (rb) {
       /* Map ordinary renderbuffer */
-      /* XXX don't map color buffers yet */
-      if (buffer == BUFFER_DEPTH || buffer == BUFFER_STENCIL) {
          ctx->Driver.MapRenderbuffer(ctx, rb,
                                      0, 0, rb->Width, rb->Height,
                                      GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
                                      &rb->Map, &rb->RowStrideBytes);
          assert(rb->Map);
-      }
    }
 }
  
@@ -373,10 +370,7 @@ unmap_attachment(struct gl_context *ctx,
     }
    else if (rb) {
       /* unmap ordinary renderbuffer */
-      /* XXX don't map color buffers yet */
-      if (buffer == BUFFER_DEPTH || buffer == BUFFER_STENCIL) {
-         ctx->Driver.UnmapRenderbuffer(ctx, rb);
-      }
+      ctx->Driver.UnmapRenderbuffer(ctx, rb);
    }
 
    rb->Map = NULL;
index 4d815c5d6758077e8fe20805db0a1d1c17901987..2b54cd13153e048c6b148c727730e4e965cf6a91 100644 (file)
@@ -157,7 +157,7 @@ _swrast_culltriangle( struct gl_context *ctx,
       span.intTex[0] += span.intTexStep[0];                            \
       span.intTex[1] += span.intTexStep[1];                            \
    }                                                                   \
-   rb->PutRow(ctx, rb, span.end, span.x, span.y, rgba, NULL);
+   _swrast_put_row(ctx, rb, span.end, span.x, span.y, rgba, NULL);
 
 #include "s_tritemp.h"
 
@@ -223,7 +223,7 @@ _swrast_culltriangle( struct gl_context *ctx,
       span.intTex[1] += span.intTexStep[1];                            \
       span.z += span.zStep;                                            \
    }                                                                   \
-   rb->PutRow(ctx, rb, span.end, span.x, span.y, rgba, span.array->mask);
+   _swrast_put_row(ctx, rb, span.end, span.x, span.y, rgba, span.array->mask);
 
 #include "s_tritemp.h"