mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
Fix clipping for copypixel
This commit is contained in:
parent
008ddf628a
commit
4aea628194
3 changed files with 201 additions and 53 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "swrast/swrast.h"
|
||||
#include "intel_context.h"
|
||||
#include "intel_pixel.h"
|
||||
#include "intel_regions.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -115,23 +116,84 @@ GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
|
|||
|
||||
|
||||
|
||||
GLboolean intel_clip_to_drawable( GLcontext *ctx,
|
||||
const __DRIdrawablePrivate *dPriv,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height )
|
||||
{
|
||||
/* left clipping */
|
||||
if (*x < dPriv->x) {
|
||||
*width -= (dPriv->x - *x);
|
||||
*x = dPriv->x;
|
||||
}
|
||||
|
||||
/* right clipping */
|
||||
if (*x + *width > dPriv->x + dPriv->w)
|
||||
*width -= (*x + *width) - (dPriv->x + dPriv->w);
|
||||
|
||||
if (*width <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
/* bottom clipping */
|
||||
if (*y < dPriv->y) {
|
||||
*height -= (dPriv->y - *y);
|
||||
*y = dPriv->y;
|
||||
}
|
||||
|
||||
/* top clipping */
|
||||
if (*y + *height > dPriv->y + dPriv->h)
|
||||
*height -= (*y + *height) - (dPriv->y + dPriv->w);
|
||||
|
||||
if (*height <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
GLboolean intel_clip_to_region( GLcontext *ctx,
|
||||
const struct intel_region *region,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height )
|
||||
{
|
||||
/* left clipping */
|
||||
if (*x < 0) {
|
||||
*width -= (0 - *x);
|
||||
*x = 0;
|
||||
}
|
||||
|
||||
/* right clipping */
|
||||
if (*x + *width > region->pitch)
|
||||
*width -= (*x + *width) - region->pitch;
|
||||
|
||||
if (*width <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
/* bottom clipping */
|
||||
if (*y < 0) {
|
||||
*height -= (0 - *y);
|
||||
*y = 0;
|
||||
}
|
||||
|
||||
/* top clipping */
|
||||
if (*y + *height > region->height)
|
||||
*height -= (*y + *height) - region->height;
|
||||
|
||||
if (*height <= 0)
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void intelInitPixelFuncs( struct dd_function_table *functions )
|
||||
{
|
||||
/* Pixel path fallbacks.
|
||||
*/
|
||||
functions->Accum = _swrast_Accum;
|
||||
functions->Bitmap = _swrast_Bitmap;
|
||||
|
||||
if (getenv("INTEL_NO_BLITS") == 0) {
|
||||
functions->CopyPixels = intelCopyPixels;
|
||||
functions->ReadPixels = intelReadPixels;
|
||||
functions->DrawPixels = intelDrawPixels;
|
||||
}
|
||||
else {
|
||||
functions->CopyPixels = _swrast_CopyPixels;
|
||||
functions->ReadPixels = _swrast_ReadPixels;
|
||||
functions->DrawPixels = _swrast_DrawPixels;
|
||||
}
|
||||
functions->CopyPixels = intelCopyPixels;
|
||||
functions->ReadPixels = intelReadPixels;
|
||||
functions->DrawPixels = intelDrawPixels;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,17 @@ GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
|
|||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height );
|
||||
|
||||
GLboolean intel_clip_to_drawable( GLcontext *ctx,
|
||||
const __DRIdrawablePrivate *dPriv,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height );
|
||||
|
||||
GLboolean intel_clip_to_region( GLcontext *ctx,
|
||||
const struct intel_region *region,
|
||||
GLint *x, GLint *y,
|
||||
GLsizei *width, GLsizei *height );
|
||||
|
||||
|
||||
void intelReadPixels( GLcontext *ctx,
|
||||
GLint x, GLint y,
|
||||
GLsizei width, GLsizei height,
|
||||
|
|
|
|||
|
|
@ -41,49 +41,17 @@
|
|||
#include "bufmgr.h"
|
||||
|
||||
|
||||
|
||||
|
||||
static GLboolean do_texture_copypixels( GLcontext *ctx,
|
||||
GLint srcx, GLint srcy,
|
||||
GLsizei width, GLsizei height,
|
||||
GLint dstx, GLint dsty,
|
||||
GLenum type )
|
||||
static struct intel_region *copypix_src_region( struct intel_context *intel,
|
||||
GLenum type )
|
||||
{
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
|
||||
*/
|
||||
static GLboolean do_blit_copypixels( GLcontext *ctx,
|
||||
GLint srcx, GLint srcy,
|
||||
GLsizei width, GLsizei height,
|
||||
GLint dstx, GLint dsty,
|
||||
GLenum type )
|
||||
{
|
||||
struct intel_context *intel = intel_context( ctx );
|
||||
struct intel_region *dst = intel_drawbuf_region( intel );
|
||||
struct intel_region *src = NULL;
|
||||
|
||||
/* Copypixels can be more than a straight copy. Ensure all the
|
||||
* extra operations are disabled:
|
||||
*/
|
||||
if (!intel_check_color_per_fragment_ops(ctx) ||
|
||||
ctx->Pixel.ZoomX != 1.0F ||
|
||||
ctx->Pixel.ZoomY != 1.0F)
|
||||
return GL_FALSE;
|
||||
|
||||
switch (type) {
|
||||
case GL_COLOR:
|
||||
src = intel_readbuf_region( intel );
|
||||
break;
|
||||
return intel_readbuf_region( intel );
|
||||
case GL_DEPTH:
|
||||
/* Don't think this is really possible execpt at 16bpp, when we have no stencil.
|
||||
*/
|
||||
if (intel->intelScreen->cpp == 2)
|
||||
src = intel->depth_region;
|
||||
break;
|
||||
return intel->depth_region;
|
||||
case GL_STENCIL:
|
||||
/* Don't think this is really possible.
|
||||
*/
|
||||
|
|
@ -91,15 +59,24 @@ static GLboolean do_blit_copypixels( GLcontext *ctx,
|
|||
case GL_DEPTH_STENCIL_EXT:
|
||||
/* Does it matter whether it is stencil/depth or depth/stencil?
|
||||
*/
|
||||
src = intel->depth_region;
|
||||
break;
|
||||
return intel->depth_region;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!src || !dst)
|
||||
return GL_FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GLboolean do_texture_copypixels( GLcontext *ctx,
|
||||
GLint srcx, GLint srcy,
|
||||
GLsizei width, GLsizei height,
|
||||
GLint dstx, GLint dsty,
|
||||
GLenum type )
|
||||
{
|
||||
#if 0
|
||||
struct intel_context *intel = intel_context( ctx );
|
||||
struct intel_region *dst = intel_drawbuf_region( intel );
|
||||
struct intel_region *src = copypix_src_region(intel);
|
||||
|
||||
|
||||
intelFlush( &intel->ctx );
|
||||
|
|
@ -171,6 +148,104 @@ static GLboolean do_blit_copypixels( GLcontext *ctx,
|
|||
intel_batchbuffer_flush( intel->batch );
|
||||
UNLOCK_HARDWARE( intel );
|
||||
return GL_TRUE;
|
||||
#endif
|
||||
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
|
||||
*/
|
||||
static GLboolean do_blit_copypixels( GLcontext *ctx,
|
||||
GLint srcx, GLint srcy,
|
||||
GLsizei width, GLsizei height,
|
||||
GLint dstx, GLint dsty,
|
||||
GLenum type )
|
||||
{
|
||||
struct intel_context *intel = intel_context( ctx );
|
||||
struct intel_region *dst = intel_drawbuf_region( intel );
|
||||
struct intel_region *src = copypix_src_region( intel, type );
|
||||
|
||||
/* Copypixels can be more than a straight copy. Ensure all the
|
||||
* extra operations are disabled:
|
||||
*/
|
||||
if (!intel_check_color_per_fragment_ops(ctx) ||
|
||||
ctx->Pixel.ZoomX != 1.0F ||
|
||||
ctx->Pixel.ZoomY != 1.0F)
|
||||
return GL_FALSE;
|
||||
|
||||
if (!src || !dst)
|
||||
return GL_FALSE;
|
||||
|
||||
|
||||
|
||||
intelFlush( &intel->ctx );
|
||||
LOCK_HARDWARE( intel );
|
||||
{
|
||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||
GLint nbox = dPriv->numClipRects;
|
||||
GLint delta_x = srcx - dstx;
|
||||
GLint delta_y = srcy - dsty;
|
||||
GLuint i;
|
||||
|
||||
|
||||
dsty = dPriv->h - dsty - height; /* convert from gl to hardware coords */
|
||||
srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */
|
||||
dstx += dPriv->x;
|
||||
dsty += dPriv->y;
|
||||
srcx += dPriv->x;
|
||||
srcy += dPriv->y;
|
||||
|
||||
/* Clip against the source region. This is the only source
|
||||
* clipping we do. Dst is clipped with cliprects below.
|
||||
*
|
||||
* TODO: Scissor?
|
||||
*/
|
||||
if (!intel_clip_to_region(ctx, src, &srcx, &srcy, &width, &height))
|
||||
goto out;
|
||||
|
||||
dstx = srcx - delta_x;
|
||||
dsty = srcy - delta_y;
|
||||
|
||||
/* Could do slightly more clipping: Eg, take the intersection of
|
||||
* the existing set of cliprects and those cliprects translated
|
||||
* by delta_x, delta_y:
|
||||
*
|
||||
* This code will not overwrite other windows, but will
|
||||
* introduce garbage when copying from obscured window regions.
|
||||
*/
|
||||
for (i = 0 ; i < nbox ; i++ )
|
||||
{
|
||||
GLint bx = box[i].x1;
|
||||
GLint by = box[i].y1;
|
||||
GLint bw = box[i].x2 - bx;
|
||||
GLint bh = box[i].y2 - by;
|
||||
|
||||
if (bx < dstx) bw -= dstx - bx, bx = dstx;
|
||||
if (by < dsty) bh -= dsty - by, by = dsty;
|
||||
if (bx + bw > dstx + width) bw = dstx + width - bx;
|
||||
if (by + bh > dsty + height) bh = dsty + height - by;
|
||||
if (bw <= 0) continue;
|
||||
if (bh <= 0) continue;
|
||||
|
||||
intelEmitCopyBlit( intel,
|
||||
dst->cpp,
|
||||
src->pitch, src->buffer, 0,
|
||||
dst->pitch, dst->buffer, 0,
|
||||
bx + delta_x, by + delta_y, /* srcx, srcy */
|
||||
bx, by, /* dstx, dsty */
|
||||
bw, bh );
|
||||
}
|
||||
}
|
||||
out:
|
||||
intel_batchbuffer_flush( intel->batch );
|
||||
UNLOCK_HARDWARE( intel );
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue