summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2010-06-11 11:30:42 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-09-14 06:38:50 -0400
commit6ec925515fdaf403d85534283eb981be6aaf05fc (patch)
tree356b1002293eb6edd1a38c02b0bb4e1cbdb0a264
parenta10cb2087168dd068ffea666ea4aab2d076f4c12 (diff)
Add a region argument to prepare access.
Download individual boxes.
-rw-r--r--src/qxl.h1
-rw-r--r--src/qxl_driver.c108
-rw-r--r--src/uxa/uxa-accel.c8
-rw-r--r--src/uxa/uxa-priv.h2
-rw-r--r--src/uxa/uxa-render.c16
-rw-r--r--src/uxa/uxa-unaccel.c46
-rw-r--r--src/uxa/uxa.c41
-rw-r--r--src/uxa/uxa.h2
8 files changed, 133 insertions, 91 deletions
diff --git a/src/qxl.h b/src/qxl.h
index bebeea5..58b5a66 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -634,6 +634,7 @@ struct _qxl_screen_t
{
PixmapPtr copy_source;
Pixel solid_pixel;
+ RegionPtr access_region;
} u;
};
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 6e2763c..ffb0185 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -830,60 +830,86 @@ unaccel (void)
return FALSE;
}
-static Bool
-qxl_prepare_access(PixmapPtr pixmap, uxa_access_t access)
+static void
+download_box (qxl_screen_t *qxl, uint8_t *host,
+ int x1, int y1, int x2, int y2)
{
- ScreenPtr pScreen = pixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- qxl_screen_t *qxl = pScrn->driverPrivate;
struct qxl_ram_header *ram_header = (void *)((unsigned long)qxl->ram +
qxl->rom->ram_header_offset);
- int n_bytes;
- uint8_t *copy;
- int w, h, stride;
-
- ErrorF ("preparing access to %p\n", pixmap);
-
- w = pixmap->drawable.width;
- h = pixmap->drawable.height;
- stride = - qxl->current_mode->stride;
-
- ErrorF ("Width, stride: %d %d, real stride: %d, display wid: %d\n", w, stride, pixmap->devKind, pScrn->displayWidth);
-
- /* Rather than go out of memory, we simply tell the
- * device to dump everything
- */
- ram_header->update_area.top = 0;
- ram_header->update_area.bottom = w;
- ram_header->update_area.left = 0;
- ram_header->update_area.right = h;
+ int stride = - qxl->current_mode->stride;
+ int Bpp = qxl->current_mode->bits / 8;
+ uint8_t *host_line;
+ uint8_t *dev_line;
+ int height = y2 - y1;
+
+ ram_header->update_area.top = y1;
+ ram_header->update_area.bottom = y2;
+ ram_header->update_area.left = x1;
+ ram_header->update_area.right = x2;
ram_header->update_surface = 0; /* Only primary for now */
outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
- usleep (10000);
+ dev_line = (uint8_t *)qxl->ram + y1 * stride + x1 * Bpp;
+ host_line = host + y1 * stride + x1 * Bpp;
- n_bytes = ((stride < 0)? -stride : stride) * pixmap->drawable.height;
+ ErrorF ("stride: %d\n", stride);
+
+ while (height--)
+ {
+ uint8_t *h = host_line;
+ uint8_t *d = dev_line;
+ int w = x2 - x1;
+
+ host_line += stride;
+ dev_line += stride;
+
+ while (w--)
+ *h++ = *d++;
+ }
+}
- ErrorF ("allocated %d bytes\n", n_bytes);
+static Bool
+qxl_prepare_access(PixmapPtr pixmap, RegionPtr region, uxa_access_t access)
+{
+ ScreenPtr pScreen = pixmap->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+ uint8_t *copy;
+ int n_bytes;
+ BoxPtr boxes;
+ int n_boxes;
+ int stride;
+
+ stride = qxl->current_mode->stride;
+ n_bytes = stride * pixmap->drawable.height;
+
copy = malloc (n_bytes);
if (!copy)
return FALSE;
- memcpy (copy, qxl->ram, n_bytes);
-
- if (stride < 0)
- copy += - stride * (h - 1);
+ /* QXL's framebuffer has a negative stride */
+ copy += stride * (pixmap->drawable.height - 1);
+ n_boxes = REGION_NUM_RECTS (region);
+ boxes = REGION_RECTS (region);
+ while (n_boxes--)
+ {
+ download_box (qxl, copy, boxes->x1, boxes->y1, boxes->x2, boxes->y2);
+ boxes++;
+ }
+
pScreen->ModifyPixmapHeader(
- pixmap, w, h, -1, -1, -1, copy);
+ pixmap, -1, -1, -1, -1, -1, copy);
/* miModifyPixmapHeader() doesn't seem to actually set a negative
* stride, so just set it here.
*/
- pixmap->devKind = stride;
+ pixmap->devKind = - stride;
+
+ qxl->u.access_region = region;
return TRUE;
}
@@ -901,18 +927,13 @@ qxl_finish_access (PixmapPtr pixmap)
struct qxl_rect rect;
ErrorF ("Finishing access to %p (stride: %d)\n", pixmap, stride);
-
- rect.left = 0;
- rect.right = w;
- rect.top = 0;
- rect.bottom = h;
drawable = make_drawable (qxl, QXL_DRAW_COPY, &rect);
-
+
drawable->u.copy.src_bitmap = physical_address (
qxl, qxl_image_create (qxl, pixmap->devPrivate.ptr,
0, 0, w, h, stride), qxl->main_mem_slot);
-
+
drawable->u.copy.src_area = rect;
drawable->u.copy.rop_descriptor = ROPD_OP_PUT;
drawable->u.copy.scale_mode = 0;
@@ -920,9 +941,9 @@ qxl_finish_access (PixmapPtr pixmap)
drawable->u.copy.mask.pos.x = 0;
drawable->u.copy.mask.pos.y = 0;
drawable->u.copy.mask.bitmap = 0;
-
+
push_drawable (qxl, drawable);
-
+
pScreen->ModifyPixmapHeader(
pixmap, w, h, -1, -1, 0, NULL);
}
@@ -1021,8 +1042,7 @@ qxl_check_copy (PixmapPtr source, PixmapPtr dest,
return FALSE;
}
- if (source->drawable.bitsPerPixel != 16 &&
- source->drawable.bitsPerPixel != 32)
+ if (source->drawable.bitsPerPixel != 16 && source->drawable.bitsPerPixel != 32)
{
ErrorF ("bad bpp\n");
return FALSE;
diff --git a/src/uxa/uxa-accel.c b/src/uxa/uxa-accel.c
index e4dbfcc..73d1059 100644
--- a/src/uxa/uxa-accel.c
+++ b/src/uxa/uxa-accel.c
@@ -338,7 +338,7 @@ uxa_do_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int dstBpp;
int dstXoff, dstYoff;
- if (!uxa_prepare_access(pDrawable, UXA_ACCESS_RW))
+ if (!uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW))
return FALSE;
fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
@@ -600,8 +600,8 @@ fallback:
UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
uxa_drawable_location(pSrcDrawable),
uxa_drawable_location(pDstDrawable)));
- if (uxa_prepare_access(pDstDrawable, UXA_ACCESS_RW)) {
- if (uxa_prepare_access(pSrcDrawable, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(pDstDrawable, NULL, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pSrcDrawable, NULL, UXA_ACCESS_RO)) {
fbCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
dx, dy, reverse, upsidedown, bitplane,
closure);
@@ -1248,7 +1248,7 @@ fallback:
UXA_FALLBACK(("from %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RO)) {
fbGetImage(pDrawable, x, y, w, h, format, planeMask, d);
uxa_finish_access(pDrawable);
}
diff --git a/src/uxa/uxa-priv.h b/src/uxa/uxa-priv.h
index 6492ca7..3ea6810 100644
--- a/src/uxa/uxa-priv.h
+++ b/src/uxa/uxa-priv.h
@@ -316,7 +316,7 @@ uxa_check_composite(CARD8 op,
#endif
/* uxa.c */
-Bool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access);
+Bool uxa_prepare_access(DrawablePtr pDrawable, RegionPtr region, uxa_access_t access);
void uxa_finish_access(DrawablePtr pDrawable);
diff --git a/src/uxa/uxa-render.c b/src/uxa/uxa-render.c
index 0e4fa91..beb7f7c 100644
--- a/src/uxa/uxa-render.c
+++ b/src/uxa/uxa-render.c
@@ -555,7 +555,7 @@ uxa_picture_from_pixman_image(ScreenPtr screen,
}
ValidatePicture(src);
- if (uxa_prepare_access(picture->pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(picture->pDrawable, NULL, UXA_ACCESS_RW)) {
fbComposite(PictOpSrc, src, NULL, picture,
0, 0, 0, 0, 0, 0, width, height);
uxa_finish_access(picture->pDrawable);
@@ -581,7 +581,7 @@ uxa_create_solid(ScreenPtr screen, uint32_t color)
if (!pixmap)
return 0;
- if (!uxa_prepare_access((DrawablePtr)pixmap, UXA_ACCESS_RW)) {
+ if (!uxa_prepare_access((DrawablePtr)pixmap, NULL, UXA_ACCESS_RW)) {
(*screen->DestroyPixmap)(pixmap);
return 0;
}
@@ -686,7 +686,7 @@ uxa_acquire_pattern(ScreenPtr pScreen,
if (!pDst)
return 0;
- if (uxa_prepare_access(pDst->pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDst->pDrawable, NULL, UXA_ACCESS_RW)) {
fbComposite(PictOpSrc, pSrc, NULL, pDst,
x, y, 0, 0, 0, 0, width, height);
uxa_finish_access(pDst->pDrawable);
@@ -743,8 +743,8 @@ uxa_render_picture(ScreenPtr screen,
if (!picture)
return 0;
- if (uxa_prepare_access(picture->pDrawable, UXA_ACCESS_RW)) {
- if (uxa_prepare_access(src->pDrawable, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(picture->pDrawable, NULL, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(src->pDrawable, NULL, UXA_ACCESS_RO)) {
ret = 1;
fbComposite(PictOpSrc, src, NULL, picture,
x, y, 0, 0, 0, 0, width, height);
@@ -1783,7 +1783,7 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
xoff += pDraw->x;
yoff += pDraw->y;
- if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDraw, NULL, UXA_ACCESS_RW)) {
PictureScreenPtr ps = GetPictureScreen(screen);
for (; ntrap; ntrap--, traps++)
@@ -1897,7 +1897,7 @@ uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
*/
if (direct) {
DrawablePtr pDraw = pDst->pDrawable;
- if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDraw, NULL, UXA_ACCESS_RW)) {
(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
uxa_finish_access(pDraw);
}
@@ -1932,7 +1932,7 @@ uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
uxa_check_poly_fill_rect(pPicture->pDrawable, pGC, 1, &rect);
FreeScratchGC(pGC);
- if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pPicture->pDrawable, NULL, UXA_ACCESS_RW)) {
(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1,
ntri, tris);
uxa_finish_access(pPicture->pDrawable);
diff --git a/src/uxa/uxa-unaccel.c b/src/uxa/uxa-unaccel.c
index 15be821..df5fbed 100644
--- a/src/uxa/uxa-unaccel.c
+++ b/src/uxa/uxa-unaccel.c
@@ -44,11 +44,11 @@
Bool uxa_prepare_access_gc(GCPtr pGC)
{
if (pGC->stipple)
- if (!uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RO))
+ if (!uxa_prepare_access(&pGC->stipple->drawable, NULL, UXA_ACCESS_RO))
return FALSE;
if (pGC->fillStyle == FillTiled)
if (!uxa_prepare_access
- (&pGC->tile.pixmap->drawable, UXA_ACCESS_RO)) {
+ (&pGC->tile.pixmap->drawable, NULL, UXA_ACCESS_RO)) {
if (pGC->stipple)
uxa_finish_access(&pGC->stipple->drawable);
return FALSE;
@@ -80,7 +80,7 @@ uxa_check_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
UXA_FALLBACK(("to %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
if (uxa_prepare_access_gc(pGC)) {
fbFillSpans(pDrawable, pGC, nspans, ppt, pwidth,
fSorted);
@@ -98,7 +98,7 @@ uxa_check_set_spans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
UXA_FALLBACK(("to %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
fbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
uxa_finish_access(pDrawable);
}
@@ -113,7 +113,7 @@ uxa_check_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth,
UXA_FALLBACK(("to %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
fbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
bits);
uxa_finish_access(pDrawable);
@@ -130,8 +130,8 @@ uxa_check_copy_area(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
uxa_drawable_location(pSrc),
uxa_drawable_location(pDst)));
- if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) {
- if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(pDst, NULL, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pSrc, NULL, UXA_ACCESS_RO)) {
ret =
fbCopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx,
dsty);
@@ -153,8 +153,8 @@ uxa_check_copy_plane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
UXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
uxa_drawable_location(pSrc),
uxa_drawable_location(pDst)));
- if (uxa_prepare_access(pDst, UXA_ACCESS_RW)) {
- if (uxa_prepare_access(pSrc, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(pDst, NULL, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pSrc, NULL, UXA_ACCESS_RO)) {
ret =
fbCopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx,
dsty, bitPlane);
@@ -173,7 +173,7 @@ uxa_check_poly_point(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
UXA_FALLBACK(("to %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
fbPolyPoint(pDrawable, pGC, mode, npt, pptInit);
uxa_finish_access(pDrawable);
}
@@ -190,7 +190,7 @@ uxa_check_poly_lines(DrawablePtr pDrawable, GCPtr pGC,
pGC->lineWidth, mode, npt));
if (pGC->lineWidth == 0) {
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
if (uxa_prepare_access_gc(pGC)) {
fbPolyLine(pDrawable, pGC, mode, npt, ppt);
uxa_finish_access_gc(pGC);
@@ -213,7 +213,7 @@ uxa_check_poly_segment(DrawablePtr pDrawable, GCPtr pGC,
uxa_drawable_location(pDrawable), pGC->lineWidth,
nsegInit));
if (pGC->lineWidth == 0) {
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
if (uxa_prepare_access_gc(pGC)) {
fbPolySegment(pDrawable, pGC, nsegInit,
pSegInit);
@@ -263,7 +263,7 @@ uxa_check_poly_fill_rect(DrawablePtr pDrawable, GCPtr pGC,
UXA_FALLBACK(("to %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
if (uxa_prepare_access_gc(pGC)) {
fbPolyFillRect(pDrawable, pGC, nrect, prect);
uxa_finish_access_gc(pGC);
@@ -281,7 +281,7 @@ uxa_check_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
UXA_FALLBACK(("to %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
if (uxa_prepare_access_gc(pGC)) {
fbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
@@ -301,7 +301,7 @@ uxa_check_poly_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
UXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
uxa_drawable_location(pDrawable), pGC->fillStyle,
pGC->alu));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
if (uxa_prepare_access_gc(pGC)) {
fbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
@@ -320,8 +320,8 @@ uxa_check_push_pixels(GCPtr pGC, PixmapPtr pBitmap,
UXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
uxa_drawable_location(&pBitmap->drawable),
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RW)) {
- if (uxa_prepare_access(&pBitmap->drawable, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(&pBitmap->drawable, NULL, UXA_ACCESS_RO)) {
if (uxa_prepare_access_gc(pGC)) {
fbPushPixels(pGC, pBitmap, pDrawable, w, h, x,
y);
@@ -342,7 +342,7 @@ uxa_check_get_spans(DrawablePtr pDrawable,
UXA_FALLBACK(("from %p (%c)\n", pDrawable,
uxa_drawable_location(pDrawable)));
- if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) {
+ if (uxa_prepare_access(pDrawable, NULL, UXA_ACCESS_RO)) {
fbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
uxa_finish_access(pDrawable);
}
@@ -362,11 +362,11 @@ uxa_check_composite(CARD8 op,
UXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));
- if (uxa_prepare_access(pDst->pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pDst->pDrawable, NULL, UXA_ACCESS_RW)) {
if (pSrc->pDrawable == NULL ||
- uxa_prepare_access(pSrc->pDrawable, UXA_ACCESS_RO)) {
+ uxa_prepare_access(pSrc->pDrawable, NULL, UXA_ACCESS_RO)) {
if (!pMask || pMask->pDrawable == NULL ||
- uxa_prepare_access(pMask->pDrawable, UXA_ACCESS_RO))
+ uxa_prepare_access(pMask->pDrawable, NULL, UXA_ACCESS_RO))
{
fbComposite(op, pSrc, pMask, pDst,
xSrc, ySrc,
@@ -391,7 +391,7 @@ uxa_check_add_traps(PicturePtr pPicture,
UXA_FALLBACK(("to pict %p (%c)\n", pPicture,
uxa_drawable_location(pPicture->pDrawable)));
- if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(pPicture->pDrawable, NULL, UXA_ACCESS_RW)) {
fbAddTraps(pPicture, x_off, y_off, ntrap, traps);
uxa_finish_access(pPicture->pDrawable);
}
@@ -408,7 +408,7 @@ CARD32 uxa_get_pixmap_first_pixel(PixmapPtr pPixmap)
CARD32 pixel;
void *fb;
- if (!uxa_prepare_access(&pPixmap->drawable, UXA_ACCESS_RO))
+ if (!uxa_prepare_access(&pPixmap->drawable, NULL, UXA_ACCESS_RO))
return 0;
fb = pPixmap->devPrivate.ptr;
diff --git a/src/uxa/uxa.c b/src/uxa/uxa.c
index b661bb8..71fe482 100644
--- a/src/uxa/uxa.c
+++ b/src/uxa/uxa.c
@@ -136,19 +136,40 @@ PixmapPtr uxa_get_offscreen_pixmap(DrawablePtr drawable, int *xp, int *yp)
* It deals with waiting for synchronization with the card, determining if
* PrepareAccess() is necessary, and working around PrepareAccess() failure.
*/
-Bool uxa_prepare_access(DrawablePtr pDrawable, uxa_access_t access)
+Bool uxa_prepare_access(DrawablePtr pDrawable, RegionPtr region, uxa_access_t access)
{
ScreenPtr pScreen = pDrawable->pScreen;
uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
PixmapPtr pPixmap = uxa_get_drawable_pixmap(pDrawable);
Bool offscreen = uxa_pixmap_is_offscreen(pPixmap);
+ BoxRec box;
+ RegionRec region_rec;
+ Bool result;
if (!offscreen)
- return TRUE;
+ return TRUE;
+
+ if (!region)
+ {
+ region = &region_rec;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pPixmap->drawable.width;
+ box.y2 = pPixmap->drawable.height;
+
+ REGION_INIT (pScreen, &region_rec, &box, 1);
+ }
+
+ result = TRUE;
if (uxa_screen->info->prepare_access)
- return (*uxa_screen->info->prepare_access) (pPixmap, access);
- return TRUE;
+ result = (*uxa_screen->info->prepare_access) (pPixmap, region, access);
+
+ if (region == &region_rec)
+ REGION_UNINIT (pScreen, &region_rec);
+
+ return result;
}
/**
@@ -207,7 +228,7 @@ uxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
* FB until at least one accelerated UXA op.
*/
if (uxa_prepare_access
- (&pOldTile->drawable, UXA_ACCESS_RO)) {
+ (&pOldTile->drawable, NULL, UXA_ACCESS_RO)) {
pNewTile =
fb24_32ReformatTile(pOldTile,
pDrawable->
@@ -228,7 +249,7 @@ uxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
&& FbEvenTile(pGC->tile.pixmap->drawable.width *
pDrawable->bitsPerPixel)) {
if (uxa_prepare_access
- (&pGC->tile.pixmap->drawable, UXA_ACCESS_RW)) {
+ (&pGC->tile.pixmap->drawable, NULL, UXA_ACCESS_RW)) {
fbPadPixmap(pGC->tile.pixmap);
uxa_finish_access(&pGC->tile.pixmap->drawable);
}
@@ -243,7 +264,7 @@ uxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
/* We can't inline stipple handling like we do for GCTile
* because it sets fbgc privates.
*/
- if (uxa_prepare_access(&pGC->stipple->drawable, UXA_ACCESS_RW)) {
+ if (uxa_prepare_access(&pGC->stipple->drawable, NULL, UXA_ACCESS_RW)) {
fbValidateGC(pGC, changes, pDrawable);
uxa_finish_access(&pGC->stipple->drawable);
}
@@ -282,13 +303,13 @@ Bool uxa_prepare_access_window(WindowPtr pWin)
{
if (pWin->backgroundState == BackgroundPixmap) {
if (!uxa_prepare_access
- (&pWin->background.pixmap->drawable, UXA_ACCESS_RO))
+ (&pWin->background.pixmap->drawable, NULL, UXA_ACCESS_RO))
return FALSE;
}
if (pWin->borderIsPixel == FALSE) {
if (!uxa_prepare_access
- (&pWin->border.pixmap->drawable, UXA_ACCESS_RO)) {
+ (&pWin->border.pixmap->drawable, NULL, UXA_ACCESS_RO)) {
if (pWin->backgroundState == BackgroundPixmap)
uxa_finish_access(&pWin->background.pixmap->
drawable);
@@ -321,7 +342,7 @@ static Bool uxa_change_window_attributes(WindowPtr pWin, unsigned long mask)
static RegionPtr uxa_bitmap_to_region(PixmapPtr pPix)
{
RegionPtr ret;
- if (!uxa_prepare_access(&pPix->drawable, UXA_ACCESS_RO))
+ if (!uxa_prepare_access(&pPix->drawable, NULL, UXA_ACCESS_RO))
return NULL;
ret = fbPixmapToRegion(pPix);
uxa_finish_access(&pPix->drawable);
diff --git a/src/uxa/uxa.h b/src/uxa/uxa.h
index cb08665..90e9c58 100644
--- a/src/uxa/uxa.h
+++ b/src/uxa/uxa.h
@@ -501,7 +501,7 @@ typedef struct _UxaDriver {
* @return FALSE if prepare_access() is unsuccessful and UXA should use
* get_image() to migate the pixmap out.
*/
- Bool(*prepare_access) (PixmapPtr pPix, uxa_access_t access);
+ Bool(*prepare_access) (PixmapPtr pPix, RegionPtr region, uxa_access_t access);
/**
* finish_access() is called after CPU access to an offscreen pixmap.