Remove existing broken maxX/maxY code for composite (results in infinite

loops, doesn't deal with failure, doesn't present the interface to
    drivers that I expected) and instead replace it with a simple fallback
    to software when coordinate limits could be violated. Act similarly in
    other acceleration cases as well.
The solution I want to see (and intend to do soon) is to (when necessary)
    create temporary pictures/pixmaps pointing towards the real ones' bits,
    with the offsets adjusted, then render from/to those using adjusted
    coordinates.
This commit is contained in:
Eric Anholt 2005-08-30 04:41:04 +00:00
parent f20e845b04
commit 0c74799af4
9 changed files with 201 additions and 174 deletions

View File

@ -517,6 +517,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
STRACE; STRACE;
if (pGC->fillStyle != FillSolid || if (pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -605,6 +607,25 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
STRACE; STRACE;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
* adjusted so that the drawing happened within limits.
*/
if (pSrcDrawable->width > pExaScr->info->card.maxX ||
pSrcDrawable->height > pExaScr->info->card.maxY ||
pDstDrawable->width > pExaScr->info->card.maxX ||
pDstDrawable->height > pExaScr->info->card.maxY)
{
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
/* If either drawable is already in framebuffer, try to get both of them /* If either drawable is already in framebuffer, try to get both of them
* there. Otherwise, be happy with where they are. * there. Otherwise, be happy with where they are.
*/ */
@ -691,6 +712,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pGC->fillStyle != FillSolid || pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -794,6 +817,8 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
@ -1079,7 +1104,9 @@ exaFillRegionSolid (DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
STRACE; STRACE;
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if (pDrawable->width <= pExaScr->info->card.maxX &&
pDrawable->height <= pExaScr->info->card.maxY &&
(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
{ {
int nbox = REGION_NUM_RECTS (pRegion); int nbox = REGION_NUM_RECTS (pRegion);

View File

@ -517,6 +517,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
STRACE; STRACE;
if (pGC->fillStyle != FillSolid || if (pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -605,6 +607,25 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
STRACE; STRACE;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
* adjusted so that the drawing happened within limits.
*/
if (pSrcDrawable->width > pExaScr->info->card.maxX ||
pSrcDrawable->height > pExaScr->info->card.maxY ||
pDstDrawable->width > pExaScr->info->card.maxX ||
pDstDrawable->height > pExaScr->info->card.maxY)
{
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
/* If either drawable is already in framebuffer, try to get both of them /* If either drawable is already in framebuffer, try to get both of them
* there. Otherwise, be happy with where they are. * there. Otherwise, be happy with where they are.
*/ */
@ -691,6 +712,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pGC->fillStyle != FillSolid || pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -794,6 +817,8 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
@ -1079,7 +1104,9 @@ exaFillRegionSolid (DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
STRACE; STRACE;
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if (pDrawable->width <= pExaScr->info->card.maxX &&
pDrawable->height <= pExaScr->info->card.maxY &&
(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
{ {
int nbox = REGION_NUM_RECTS (pRegion); int nbox = REGION_NUM_RECTS (pRegion);

View File

@ -517,6 +517,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
STRACE; STRACE;
if (pGC->fillStyle != FillSolid || if (pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -605,6 +607,25 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
STRACE; STRACE;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
* adjusted so that the drawing happened within limits.
*/
if (pSrcDrawable->width > pExaScr->info->card.maxX ||
pSrcDrawable->height > pExaScr->info->card.maxY ||
pDstDrawable->width > pExaScr->info->card.maxX ||
pDstDrawable->height > pExaScr->info->card.maxY)
{
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
/* If either drawable is already in framebuffer, try to get both of them /* If either drawable is already in framebuffer, try to get both of them
* there. Otherwise, be happy with where they are. * there. Otherwise, be happy with where they are.
*/ */
@ -691,6 +712,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pGC->fillStyle != FillSolid || pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -794,6 +817,8 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
@ -1079,7 +1104,9 @@ exaFillRegionSolid (DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
STRACE; STRACE;
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if (pDrawable->width <= pExaScr->info->card.maxX &&
pDrawable->height <= pExaScr->info->card.maxY &&
(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
{ {
int nbox = REGION_NUM_RECTS (pRegion); int nbox = REGION_NUM_RECTS (pRegion);

View File

@ -327,65 +327,20 @@ exaTryDriverComposite(CARD8 op,
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
struct _Pixmap scratch; struct _Pixmap scratch;
if (pExaScr->info->card.maxX < width || /* Bail if we might exceed coord limits by rendering from/to these. We
pExaScr->info->card.maxY < height) * should really be making some scratch pixmaps with offsets and coords
* adjusted to deal with this, but it hasn't been done yet.
*/
if (pSrc->pDrawable->width > pExaScr->info->card.maxX ||
pSrc->pDrawable->height > pExaScr->info->card.maxY ||
pDst->pDrawable->width > pExaScr->info->card.maxX ||
pDst->pDrawable->height > pExaScr->info->card.maxY ||
(pMask && (pMask->pDrawable->width > pExaScr->info->card.maxX ||
pMask->pDrawable->height > pExaScr->info->card.maxY)))
{ {
int total_width = width;
int total_height = height;
int xOff = 0;
int yOff = 0;
while (total_width > pExaScr->info->card.maxX) {
while (total_height > pExaScr->info->card.maxY) {
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
pExaScr->info->card.maxX,
pExaScr->info->card.maxY);
total_width -= pExaScr->info->card.maxX;
xOff += pExaScr->info->card.maxX;
yOff = 0;
}
if (total_height)
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
pExaScr->info->card.maxX,
total_height);
total_height -= pExaScr->info->card.maxY;
yOff += pExaScr->info->card.maxY;
}
if (total_width && total_height)
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
total_width,
total_height);
return -1; return -1;
} }
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;

View File

@ -517,6 +517,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
STRACE; STRACE;
if (pGC->fillStyle != FillSolid || if (pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -605,6 +607,25 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
STRACE; STRACE;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
* adjusted so that the drawing happened within limits.
*/
if (pSrcDrawable->width > pExaScr->info->card.maxX ||
pSrcDrawable->height > pExaScr->info->card.maxY ||
pDstDrawable->width > pExaScr->info->card.maxX ||
pDstDrawable->height > pExaScr->info->card.maxY)
{
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
/* If either drawable is already in framebuffer, try to get both of them /* If either drawable is already in framebuffer, try to get both of them
* there. Otherwise, be happy with where they are. * there. Otherwise, be happy with where they are.
*/ */
@ -691,6 +712,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pGC->fillStyle != FillSolid || pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -794,6 +817,8 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
@ -1079,7 +1104,9 @@ exaFillRegionSolid (DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
STRACE; STRACE;
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if (pDrawable->width <= pExaScr->info->card.maxX &&
pDrawable->height <= pExaScr->info->card.maxY &&
(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
{ {
int nbox = REGION_NUM_RECTS (pRegion); int nbox = REGION_NUM_RECTS (pRegion);

View File

@ -517,6 +517,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
STRACE; STRACE;
if (pGC->fillStyle != FillSolid || if (pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -605,6 +607,25 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
STRACE; STRACE;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
* adjusted so that the drawing happened within limits.
*/
if (pSrcDrawable->width > pExaScr->info->card.maxX ||
pSrcDrawable->height > pExaScr->info->card.maxY ||
pDstDrawable->width > pExaScr->info->card.maxX ||
pDstDrawable->height > pExaScr->info->card.maxY)
{
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
/* If either drawable is already in framebuffer, try to get both of them /* If either drawable is already in framebuffer, try to get both of them
* there. Otherwise, be happy with where they are. * there. Otherwise, be happy with where they are.
*/ */
@ -691,6 +712,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pGC->fillStyle != FillSolid || pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -794,6 +817,8 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
@ -1079,7 +1104,9 @@ exaFillRegionSolid (DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
STRACE; STRACE;
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if (pDrawable->width <= pExaScr->info->card.maxX &&
pDrawable->height <= pExaScr->info->card.maxY &&
(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
{ {
int nbox = REGION_NUM_RECTS (pRegion); int nbox = REGION_NUM_RECTS (pRegion);

View File

@ -517,6 +517,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
STRACE; STRACE;
if (pGC->fillStyle != FillSolid || if (pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -605,6 +607,25 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
STRACE; STRACE;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
* adjusted so that the drawing happened within limits.
*/
if (pSrcDrawable->width > pExaScr->info->card.maxX ||
pSrcDrawable->height > pExaScr->info->card.maxY ||
pDstDrawable->width > pExaScr->info->card.maxX ||
pDstDrawable->height > pExaScr->info->card.maxY)
{
if (pSrcDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
/* If either drawable is already in framebuffer, try to get both of them /* If either drawable is already in framebuffer, try to get both of them
* there. Otherwise, be happy with where they are. * there. Otherwise, be happy with where they are.
*/ */
@ -691,6 +712,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pGC->fillStyle != FillSolid || pGC->fillStyle != FillSolid ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, !(*pExaScr->info->accel.PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
@ -794,6 +817,8 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
STRACE; STRACE;
if (!pScrn->vtSema || if (!pScrn->vtSema ||
pDrawable->width > pExaScr->info->card.maxX ||
pDrawable->height > pExaScr->info->card.maxY ||
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || !(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
@ -1079,7 +1104,9 @@ exaFillRegionSolid (DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
STRACE; STRACE;
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if (pDrawable->width <= pExaScr->info->card.maxX &&
pDrawable->height <= pExaScr->info->card.maxY &&
(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
{ {
int nbox = REGION_NUM_RECTS (pRegion); int nbox = REGION_NUM_RECTS (pRegion);

View File

@ -327,65 +327,20 @@ exaTryDriverComposite(CARD8 op,
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
struct _Pixmap scratch; struct _Pixmap scratch;
if (pExaScr->info->card.maxX < width || /* Bail if we might exceed coord limits by rendering from/to these. We
pExaScr->info->card.maxY < height) * should really be making some scratch pixmaps with offsets and coords
* adjusted to deal with this, but it hasn't been done yet.
*/
if (pSrc->pDrawable->width > pExaScr->info->card.maxX ||
pSrc->pDrawable->height > pExaScr->info->card.maxY ||
pDst->pDrawable->width > pExaScr->info->card.maxX ||
pDst->pDrawable->height > pExaScr->info->card.maxY ||
(pMask && (pMask->pDrawable->width > pExaScr->info->card.maxX ||
pMask->pDrawable->height > pExaScr->info->card.maxY)))
{ {
int total_width = width;
int total_height = height;
int xOff = 0;
int yOff = 0;
while (total_width > pExaScr->info->card.maxX) {
while (total_height > pExaScr->info->card.maxY) {
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
pExaScr->info->card.maxX,
pExaScr->info->card.maxY);
total_width -= pExaScr->info->card.maxX;
xOff += pExaScr->info->card.maxX;
yOff = 0;
}
if (total_height)
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
pExaScr->info->card.maxX,
total_height);
total_height -= pExaScr->info->card.maxY;
yOff += pExaScr->info->card.maxY;
}
if (total_width && total_height)
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
total_width,
total_height);
return -1; return -1;
} }
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;

View File

@ -327,65 +327,20 @@ exaTryDriverComposite(CARD8 op,
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix; PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
struct _Pixmap scratch; struct _Pixmap scratch;
if (pExaScr->info->card.maxX < width || /* Bail if we might exceed coord limits by rendering from/to these. We
pExaScr->info->card.maxY < height) * should really be making some scratch pixmaps with offsets and coords
* adjusted to deal with this, but it hasn't been done yet.
*/
if (pSrc->pDrawable->width > pExaScr->info->card.maxX ||
pSrc->pDrawable->height > pExaScr->info->card.maxY ||
pDst->pDrawable->width > pExaScr->info->card.maxX ||
pDst->pDrawable->height > pExaScr->info->card.maxY ||
(pMask && (pMask->pDrawable->width > pExaScr->info->card.maxX ||
pMask->pDrawable->height > pExaScr->info->card.maxY)))
{ {
int total_width = width;
int total_height = height;
int xOff = 0;
int yOff = 0;
while (total_width > pExaScr->info->card.maxX) {
while (total_height > pExaScr->info->card.maxY) {
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
pExaScr->info->card.maxX,
pExaScr->info->card.maxY);
total_width -= pExaScr->info->card.maxX;
xOff += pExaScr->info->card.maxX;
yOff = 0;
}
if (total_height)
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
pExaScr->info->card.maxX,
total_height);
total_height -= pExaScr->info->card.maxY;
yOff += pExaScr->info->card.maxY;
}
if (total_width && total_height)
exaTryDriverComposite(op,
pSrc,
pMask,
pDst,
xSrc + xOff,
ySrc + yOff,
xMask + xOff,
yMask + yOff,
xDst + xOff,
yDst + yOff,
total_width,
total_height);
return -1; return -1;
} }
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;