mesa: make _mesa_clip_blit() a shared function
authorBrian Paul <brianp@vmware.com>
Wed, 5 Aug 2009 19:21:59 +0000 (13:21 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 5 Aug 2009 19:21:59 +0000 (13:21 -0600)
src/mesa/main/image.c
src/mesa/main/image.h
src/mesa/swrast/s_blit.c

index 01fbe40a03b418f72ef98f9d1f81246dfaf0b9b7..1a4d22256f4510ff80f0adfcf07cf00816452c98 100644 (file)
@@ -5333,3 +5333,181 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
 
    return GL_TRUE;
 }
+
+
+/**
+ * Clip dst coords against Xmax (or Ymax).
+ */
+static INLINE void
+clip_right_or_top(GLint *srcX0, GLint *srcX1,
+                  GLint *dstX0, GLint *dstX1,
+                  GLint maxValue)
+{
+   GLfloat t, bias;
+
+   if (*dstX1 > maxValue) {
+      /* X1 outside right edge */
+      ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
+      t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+      /* chop off [t, 1] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX1 = maxValue;
+      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+      *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+   }
+   else if (*dstX0 > maxValue) {
+      /* X0 outside right edge */
+      ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
+      t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+      /* chop off [t, 1] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX0 = maxValue;
+      bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
+      *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+   }
+}
+
+
+/**
+ * Clip dst coords against Xmin (or Ymin).
+ */
+static INLINE void
+clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
+                    GLint *dstX0, GLint *dstX1,
+                    GLint minValue)
+{
+   GLfloat t, bias;
+
+   if (*dstX0 < minValue) {
+      /* X0 outside left edge */
+      ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
+      t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+      /* chop off [0, t] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX0 = minValue;
+      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
+      *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+   }
+   else if (*dstX1 < minValue) {
+      /* X1 outside left edge */
+      ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
+      t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+      /* chop off [0, t] part */
+      ASSERT(t >= 0.0 && t <= 1.0);
+      *dstX1 = minValue;
+      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+      *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+   }
+}
+
+
+/**
+ * Do clipping of blit src/dest rectangles.
+ * The dest rect is clipped against both the buffer bounds and scissor bounds.
+ * The src rect is just clipped against the buffer bounds.
+ *
+ * When either the src or dest rect is clipped, the other is also clipped
+ * proportionately!
+ *
+ * Note that X0 need not be less than X1 (same for Y) for either the source
+ * and dest rects.  That makes the clipping a little trickier.
+ *
+ * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
+ */
+GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+                GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+                GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
+{
+   const GLint srcXmin = 0;
+   const GLint srcXmax = ctx->ReadBuffer->Width;
+   const GLint srcYmin = 0;
+   const GLint srcYmax = ctx->ReadBuffer->Height;
+
+   /* these include scissor bounds */
+   const GLint dstXmin = ctx->DrawBuffer->_Xmin;
+   const GLint dstXmax = ctx->DrawBuffer->_Xmax;
+   const GLint dstYmin = ctx->DrawBuffer->_Ymin;
+   const GLint dstYmax = ctx->DrawBuffer->_Ymax;
+
+   /*
+   printf("PreClipX:  src: %d .. %d  dst: %d .. %d\n",
+          *srcX0, *srcX1, *dstX0, *dstX1);
+   printf("PreClipY:  src: %d .. %d  dst: %d .. %d\n",
+          *srcY0, *srcY1, *dstY0, *dstY1);
+   */
+
+   /* trivial rejection tests */
+   if (*dstX0 == *dstX1)
+      return GL_FALSE; /* no width */
+   if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
+      return GL_FALSE; /* totally out (left) of bounds */
+   if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
+      return GL_FALSE; /* totally out (right) of bounds */
+
+   if (*dstY0 == *dstY1)
+      return GL_FALSE;
+   if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
+      return GL_FALSE;
+   if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
+      return GL_FALSE;
+
+   if (*srcX0 == *srcX1)
+      return GL_FALSE;
+   if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
+      return GL_FALSE;
+   if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
+      return GL_FALSE;
+
+   if (*srcY0 == *srcY1)
+      return GL_FALSE;
+   if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
+      return GL_FALSE;
+   if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
+      return GL_FALSE;
+
+   /*
+    * dest clip
+    */
+   clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
+   clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
+   clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
+   clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
+
+   /*
+    * src clip (just swap src/dst values from above)
+    */
+   clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
+   clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
+   clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
+   clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
+
+   /*
+   printf("PostClipX: src: %d .. %d  dst: %d .. %d\n",
+          *srcX0, *srcX1, *dstX0, *dstX1);
+   printf("PostClipY: src: %d .. %d  dst: %d .. %d\n",
+          *srcY0, *srcY1, *dstY0, *dstY1);
+   */
+
+   ASSERT(*dstX0 >= dstXmin);
+   ASSERT(*dstX0 <= dstXmax);
+   ASSERT(*dstX1 >= dstXmin);
+   ASSERT(*dstX1 <= dstXmax);
+
+   ASSERT(*dstY0 >= dstYmin);
+   ASSERT(*dstY0 <= dstYmax);
+   ASSERT(*dstY1 >= dstYmin);
+   ASSERT(*dstY1 <= dstYmax);
+
+   ASSERT(*srcX0 >= srcXmin);
+   ASSERT(*srcX0 <= srcXmax);
+   ASSERT(*srcX1 >= srcXmin);
+   ASSERT(*srcX1 <= srcXmax);
+
+   ASSERT(*srcY0 >= srcYmin);
+   ASSERT(*srcY0 <= srcYmax);
+   ASSERT(*srcY1 >= srcYmin);
+   ASSERT(*srcY1 <= srcYmax);
+
+   return GL_TRUE;
+}
index b26c27e5a8ac7976781a076440e00b8ba66267cb..ee17accb80c71ee22ad997fd4451a2fa512e3d89 100644 (file)
@@ -291,4 +291,10 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
                      GLint *x, GLint *y,
                      GLsizei *width, GLsizei *height );
 
+extern GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+                GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+                GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
+
+
 #endif
index 0e32cb8f653e3ba7743979413a9787a990093317..4a95c222d5681e21a19b819e1f974ad5a7122ce3 100644 (file)
@@ -24,6 +24,7 @@
 
 
 #include "main/glheader.h"
+#include "main/image.h"
 #include "main/macros.h"
 #include "s_context.h"
 
@@ -550,184 +551,6 @@ simple_blit(GLcontext *ctx,
 }
 
 
-/**
- * Clip dst coords against Xmax (or Ymax).
- */
-static INLINE void
-clip_right_or_top(GLint *srcX0, GLint *srcX1,
-                  GLint *dstX0, GLint *dstX1,
-                  GLint maxValue)
-{
-   GLfloat t, bias;
-
-   if (*dstX1 > maxValue) {
-      /* X1 outside right edge */
-      ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
-      t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
-      /* chop off [t, 1] part */
-      ASSERT(t >= 0.0 && t <= 1.0);
-      *dstX1 = maxValue;
-      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
-      *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
-   }
-   else if (*dstX0 > maxValue) {
-      /* X0 outside right edge */
-      ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
-      t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
-      /* chop off [t, 1] part */
-      ASSERT(t >= 0.0 && t <= 1.0);
-      *dstX0 = maxValue;
-      bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
-      *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
-   }
-}
-
-
-/**
- * Clip dst coords against Xmin (or Ymin).
- */
-static INLINE void
-clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
-                    GLint *dstX0, GLint *dstX1,
-                    GLint minValue)
-{
-   GLfloat t, bias;
-
-   if (*dstX0 < minValue) {
-      /* X0 outside left edge */
-      ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
-      t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
-      /* chop off [0, t] part */
-      ASSERT(t >= 0.0 && t <= 1.0);
-      *dstX0 = minValue;
-      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
-      *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
-   }
-   else if (*dstX1 < minValue) {
-      /* X1 outside left edge */
-      ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
-      t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
-      /* chop off [0, t] part */
-      ASSERT(t >= 0.0 && t <= 1.0);
-      *dstX1 = minValue;
-      bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
-      *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
-   }
-}
-
-
-/**
- * Do clipping of blit src/dest rectangles.
- * The dest rect is clipped against both the buffer bounds and scissor bounds.
- * The src rect is just clipped against the buffer bounds.
- *
- * When either the src or dest rect is clipped, the other is also clipped
- * proportionately!
- *
- * Note that X0 need not be less than X1 (same for Y) for either the source
- * and dest rects.  That makes the clipping a little trickier.
- *
- * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
- */
-static GLboolean
-clip_blit(GLcontext *ctx,
-          GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
-          GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
-{
-   const GLint srcXmin = 0;
-   const GLint srcXmax = ctx->ReadBuffer->Width;
-   const GLint srcYmin = 0;
-   const GLint srcYmax = ctx->ReadBuffer->Height;
-
-   /* these include scissor bounds */
-   const GLint dstXmin = ctx->DrawBuffer->_Xmin;
-   const GLint dstXmax = ctx->DrawBuffer->_Xmax;
-   const GLint dstYmin = ctx->DrawBuffer->_Ymin;
-   const GLint dstYmax = ctx->DrawBuffer->_Ymax;
-
-   /*
-   printf("PreClipX:  src: %d .. %d  dst: %d .. %d\n",
-          *srcX0, *srcX1, *dstX0, *dstX1);
-   printf("PreClipY:  src: %d .. %d  dst: %d .. %d\n",
-          *srcY0, *srcY1, *dstY0, *dstY1);
-   */
-
-   /* trivial rejection tests */
-   if (*dstX0 == *dstX1)
-      return GL_FALSE; /* no width */
-   if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
-      return GL_FALSE; /* totally out (left) of bounds */
-   if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
-      return GL_FALSE; /* totally out (right) of bounds */
-
-   if (*dstY0 == *dstY1)
-      return GL_FALSE;
-   if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
-      return GL_FALSE;
-   if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
-      return GL_FALSE;
-
-   if (*srcX0 == *srcX1)
-      return GL_FALSE;
-   if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
-      return GL_FALSE;
-   if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
-      return GL_FALSE;
-
-   if (*srcY0 == *srcY1)
-      return GL_FALSE;
-   if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
-      return GL_FALSE;
-   if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
-      return GL_FALSE;
-
-   /*
-    * dest clip
-    */
-   clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
-   clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
-   clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
-   clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
-
-   /*
-    * src clip (just swap src/dst values from above)
-    */
-   clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
-   clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
-   clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
-   clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
-
-   /*
-   printf("PostClipX: src: %d .. %d  dst: %d .. %d\n",
-          *srcX0, *srcX1, *dstX0, *dstX1);
-   printf("PostClipY: src: %d .. %d  dst: %d .. %d\n",
-          *srcY0, *srcY1, *dstY0, *dstY1);
-   */
-
-   ASSERT(*dstX0 >= dstXmin);
-   ASSERT(*dstX0 <= dstXmax);
-   ASSERT(*dstX1 >= dstXmin);
-   ASSERT(*dstX1 <= dstXmax);
-
-   ASSERT(*dstY0 >= dstYmin);
-   ASSERT(*dstY0 <= dstYmax);
-   ASSERT(*dstY1 >= dstYmin);
-   ASSERT(*dstY1 <= dstYmax);
-
-   ASSERT(*srcX0 >= srcXmin);
-   ASSERT(*srcX0 <= srcXmax);
-   ASSERT(*srcX1 >= srcXmin);
-   ASSERT(*srcX1 <= srcXmax);
-
-   ASSERT(*srcY0 >= srcYmin);
-   ASSERT(*srcY0 <= srcYmax);
-   ASSERT(*srcY1 >= srcYmin);
-   ASSERT(*srcY1 <= srcYmax);
-
-   return GL_TRUE;
-}
-
-
 /**
  * Software fallback for glBlitFramebufferEXT().
  */
@@ -747,8 +570,8 @@ _swrast_BlitFramebuffer(GLcontext *ctx,
    if (!ctx->DrawBuffer->_NumColorDrawBuffers)
       return;
 
-   if (!clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
-                  &dstX0, &dstY0, &dstX1, &dstY1)) {
+   if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
+                        &dstX0, &dstY0, &dstX1, &dstY1)) {
       return;
    }