mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 13:10:10 +01:00
mesa: make _mesa_clip_blit() a shared function
This commit is contained in:
parent
4f36164024
commit
727b2d747e
3 changed files with 187 additions and 180 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue