コード例 #1
0
ファイル: s_span.c プロジェクト: hoangduit/reactos
/** Put row of colors into renderbuffer */
void
_swrast_put_row(struct gl_context *ctx, struct gl_renderbuffer *rb,
                GLenum datatype,
                GLuint count, GLint x, GLint y,
                const void *values, const GLubyte *mask)
{
   GLubyte *dst = _swrast_pixel_address(rb, x, y);

   if (!mask) {
      if (datatype == GL_UNSIGNED_BYTE) {
         _mesa_pack_ubyte_rgba_row(rb->Format, count,
                                   (const GLubyte (*)[4]) values, dst);
      }
      else {
         assert(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 = runStart = 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 (datatype == GL_UNSIGNED_BYTE) {
                  _mesa_pack_ubyte_rgba_row(rb->Format, runLen,
                                     (const GLubyte (*)[4]) values + runStart,
                                     dst + runStart * bpp);
               }
               else {
                  assert(datatype == GL_FLOAT);
                  _mesa_pack_float_rgba_row(rb->Format, runLen,
                                   (const GLfloat (*)[4]) values + runStart,
                                   dst + runStart * bpp);
               }
               runLen = 0;
            }
         }
      }
   }
}
コード例 #2
0
ファイル: s_blit.c プロジェクト: venkatarajasekhar/Qt
/**
 * Bilinear filtered blit (color only, non-integer values).
 */
static void
blit_linear(struct gl_context *ctx,
            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
{
   struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer;
   struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0];

   const GLint srcWidth = ABS(srcX1 - srcX0);
   const GLint dstWidth = ABS(dstX1 - dstX0);
   const GLint srcHeight = ABS(srcY1 - srcY0);
   const GLint dstHeight = ABS(dstY1 - dstY0);
   const GLfloat dstHeightF = (GLfloat) dstHeight;

   const GLint srcXpos = MIN2(srcX0, srcX1);
   const GLint srcYpos = MIN2(srcY0, srcY1);
   const GLint dstXpos = MIN2(dstX0, dstX1);
   const GLint dstYpos = MIN2(dstY0, dstY1);

   const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0);
   const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0);

   GLint dstRow;

   GLint pixelSize;
   GLvoid *srcBuffer0, *srcBuffer1;
   GLint srcBufferY0 = -1, srcBufferY1 = -1;
   GLvoid *dstBuffer;

   gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format);
   gl_format drawFormat = _mesa_get_srgb_format_linear(drawRb->Format);
   GLuint bpp = _mesa_get_format_bytes(readFormat);

   GLenum pixelType;

   GLubyte *srcMap, *dstMap;
   GLint srcRowStride, dstRowStride;


   /* Determine datatype for resampling */
   if (_mesa_get_format_max_bits(readFormat) == 8 &&
       _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) {
      pixelType = GL_UNSIGNED_BYTE;
      pixelSize = 4 * sizeof(GLubyte);
   }
   else {
      pixelType = GL_FLOAT;
      pixelSize = 4 * sizeof(GLfloat);
   }

   /* Allocate the src/dst row buffers.
    * Keep two adjacent src rows around for bilinear sampling.
    */
   srcBuffer0 = malloc(pixelSize * srcWidth);
   if (!srcBuffer0) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   srcBuffer1 = malloc(pixelSize * srcWidth);
   if (!srcBuffer1) {
      free(srcBuffer0);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }
   dstBuffer = malloc(pixelSize * dstWidth);
   if (!dstBuffer) {
      free(srcBuffer0);
      free(srcBuffer1);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT");
      return;
   }

   /*
    * Map src / dst renderbuffers
    */
   if (readRb == drawRb) {
      /* map whole buffer for read/write */
      ctx->Driver.MapRenderbuffer(ctx, readRb,
                                  0, 0, readRb->Width, readRb->Height,
                                  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
                                  &srcMap, &srcRowStride);
      if (!srcMap) {
         free(srcBuffer0);
         free(srcBuffer1);
         free(dstBuffer);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }

      dstMap = srcMap;
      dstRowStride = srcRowStride;
   }
   else {
      /* different src/dst buffers */
      /* XXX with a bit of work we could just map the regions to be
       * read/written instead of the whole buffers.
       */
      ctx->Driver.MapRenderbuffer(ctx, readRb,
				  0, 0, readRb->Width, readRb->Height,
                                  GL_MAP_READ_BIT, &srcMap, &srcRowStride);
      if (!srcMap) {
         free(srcBuffer0);
         free(srcBuffer1);
         free(dstBuffer);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }
      ctx->Driver.MapRenderbuffer(ctx, drawRb,
                                  0, 0, drawRb->Width, drawRb->Height,
                                  GL_MAP_WRITE_BIT, &dstMap, &dstRowStride);
      if (!dstMap) {
         ctx->Driver.UnmapRenderbuffer(ctx, readRb);
         free(srcBuffer0);
         free(srcBuffer1);
         free(dstBuffer);
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer");
         return;
      }
   }

   for (dstRow = 0; dstRow < dstHeight; dstRow++) {
      const GLint dstY = dstYpos + dstRow;
      const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF;
      GLint srcRow0 = IFLOOR(srcRow);
      GLint srcRow1 = srcRow0 + 1;
      GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */

      ASSERT(srcRow >= 0);
      ASSERT(srcRow < srcHeight);

      if (srcRow1 == srcHeight) {
         /* last row fudge */
         srcRow1 = srcRow0;
         rowWeight = 0.0;
      }

      if (invertY) {
         srcRow0 = srcHeight - 1 - srcRow0;
         srcRow1 = srcHeight - 1 - srcRow1;
      }

      srcY0 = srcYpos + srcRow0;
      srcY1 = srcYpos + srcRow1;

      /* get the two source rows */
      if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) {
         /* use same source row buffers again */
      }
      else if (srcY0 == srcBufferY1) {
         /* move buffer1 into buffer0 by swapping pointers */
         GLvoid *tmp = srcBuffer0;
         srcBuffer0 = srcBuffer1;
         srcBuffer1 = tmp;
         /* get y1 row */
         {
            GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
            if (pixelType == GL_UNSIGNED_BYTE) {
               _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
                                           src, srcBuffer1);
            }
            else {
               _mesa_unpack_rgba_row(readFormat, srcWidth,
                                     src, srcBuffer1);
            }
         }            
         srcBufferY0 = srcY0;
         srcBufferY1 = srcY1;
      }
      else {
         /* get both new rows */
         {
            GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp;
            GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp;
            if (pixelType == GL_UNSIGNED_BYTE) {
               _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
                                           src0, srcBuffer0);
               _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth,
                                           src1, srcBuffer1);
            }
            else {
               _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0);
               _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1);
            }
         }
         srcBufferY0 = srcY0;
         srcBufferY1 = srcY1;
      }

      if (pixelType == GL_UNSIGNED_BYTE) {
         resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
                                dstBuffer, invertX, rowWeight);
      }
      else {
         resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1,
                                   dstBuffer, invertX, rowWeight);
      }

      /* store pixel row in destination */
      {
         GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp;
         if (pixelType == GL_UNSIGNED_BYTE) {
            _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
         }
         else {
            _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst);
         }
      }
   }

   free(srcBuffer0);
   free(srcBuffer1);
   free(dstBuffer);

   ctx->Driver.UnmapRenderbuffer(ctx, readRb);
   if (drawRb != readRb) {
      ctx->Driver.UnmapRenderbuffer(ctx, drawRb);
   }
}