summaryrefslogtreecommitdiff
path: root/hw/kdrive
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2006-03-30 05:15:58 +0000
committerEric Anholt <anholt@freebsd.org>2006-03-30 05:15:58 +0000
commit3cf46cc1e32efc0e4be1d88be111ba0438e0f021 (patch)
tree1acc958472195ae32ad4a6f48753e88ff679526c /hw/kdrive
parente799dd68e2bd0fa8ac3c344111fb12e1f32d4c10 (diff)
Add an UploadToScreen implementation, for testing PutImage support, and
make the DownloadFromScreen more robust.
Diffstat (limited to 'hw/kdrive')
-rw-r--r--hw/kdrive/ephyr/ephyr_draw.c59
1 files changed, 53 insertions, 6 deletions
diff --git a/hw/kdrive/ephyr/ephyr_draw.c b/hw/kdrive/ephyr/ephyr_draw.c
index 93cb23b3c..f4bb2a1b0 100644
--- a/hw/kdrive/ephyr/ephyr_draw.c
+++ b/hw/kdrive/ephyr/ephyr_draw.c
@@ -227,19 +227,32 @@ ephyrDoneComposite(PixmapPtr pDst)
}
/**
- * Does an fbGetImage to pull image data from a pixmap.
+ * Does fake acceleration of DownloadFromScren using memcpy.
*/
static Bool
ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
int dst_pitch)
{
- /* Only "accelerate" it if we can hand it off to fbGetImage, which expects
- * the dst pitch to match the width of the image.
- */
- if (dst_pitch != PixmapBytePad(&pSrc->drawable, w))
+ KdScreenPriv(pSrc->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ char *src;
+ int src_pitch, cpp;
+
+ if (pSrc->drawable.bitsPerPixel < 8)
return FALSE;
- fbGetImage(&pSrc->drawable, x, y, w, h, ZPixmap, FB_ALLONES, dst);
+ cpp = pSrc->drawable.bitsPerPixel / 8;
+ src_pitch = exaGetPixmapPitch(pSrc);
+ src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
+ src += y * src_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
exaMarkSync(pSrc->drawable.pScreen);
@@ -247,6 +260,39 @@ ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
}
/**
+ * Does fake acceleration of DownloadFromScren using memcpy.
+ */
+static Bool
+ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ char *dst;
+ int dst_pitch, cpp;
+
+ if (pDst->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ cpp = pDst->drawable.bitsPerPixel / 8;
+ dst_pitch = exaGetPixmapPitch(pDst);
+ dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
+ dst += y * dst_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pDst->drawable.pScreen);
+
+ return TRUE;
+}
+
+/**
* In fakexa, we currently only track whether we have synced to the latest
* "accelerated" drawing that has happened or not. This will be used by an
* ephyrPrepareAccess for the purpose of reliably providing garbage when
@@ -331,6 +377,7 @@ ephyrDrawInit(ScreenPtr pScreen)
fakexa->exa->DoneComposite = ephyrDoneComposite;
fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen;
+ fakexa->exa->UploadToScreen = ephyrUploadToScreen;
fakexa->exa->MarkSync = ephyrMarkSync;
fakexa->exa->WaitMarker = ephyrWaitMarker;