summaryrefslogtreecommitdiff
path: root/drv
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-11-22 16:04:42 +0000
committerDave Airlie <airlied@redhat.com>2012-01-11 09:42:52 +0000
commit8178d23142d039674e5d6dc59b21e107b1ac1340 (patch)
tree4f2ea8b868ea7b82e8451da0563bc289c6bb3195 /drv
parent92aaa6d28aa056b16a3bf8a2c000e075504aecf3 (diff)
add drvcopy
Diffstat (limited to 'drv')
-rw-r--r--drv/Makefile.am3
-rw-r--r--drv/drv_screenint.h30
-rw-r--r--drv/drvcopy.c268
-rw-r--r--drv/fb/drvfb.h12
-rw-r--r--drv/fb/fbcopy.c21
-rw-r--r--drv/fb/fbgc.c2
6 files changed, 334 insertions, 2 deletions
diff --git a/drv/Makefile.am b/drv/Makefile.am
index 3e8d0c67a..7c4475ef5 100644
--- a/drv/Makefile.am
+++ b/drv/Makefile.am
@@ -38,4 +38,5 @@ libdrv_la_SOURCES = \
impedgc.c \
impedpict.c \
impedplug.c \
- impedrandr.c
+ impedrandr.c\
+ drvcopy.c
diff --git a/drv/drv_screenint.h b/drv/drv_screenint.h
index 99e0ffa77..a257ce21b 100644
--- a/drv/drv_screenint.h
+++ b/drv/drv_screenint.h
@@ -2,6 +2,7 @@
#define DRV_SCREENINT_H
#include "drv_types.h"
+#include "pixmap.h"
DrvScreenPtr DrvScreenAllocate(void);
extern _X_EXPORT Bool
@@ -9,4 +10,33 @@ drvScreenInit(DrvScreenPtr pDrvScreen);
void
drvSetScreenPixmap(DrvScreenPtr pDrvScreen, DrvPixmapPtr drvPixmap);
+
+extern _X_EXPORT void
+DrvPixmapSetGPUPixmap(PixmapPtr parent, DrvPixmapPtr new);
+
+
+extern _X_EXPORT void
+drvCopyRegion (DrvPixmapPtr pSrcPixmap,
+ DrvPixmapPtr pDstPixmap,
+ DrvGCPtr pGC,
+ RegionPtr pDstRegion,
+ int dx,
+ int dy,
+ drvCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure);
+
+extern _X_EXPORT RegionPtr
+drvDoCopy (DrvPixmapPtr pSrcPixmap,
+ DrvPixmapPtr pDstPixmap,
+ DrvGCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ drvCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure);
#endif
diff --git a/drv/drvcopy.c b/drv/drvcopy.c
new file mode 100644
index 000000000..8460ea36f
--- /dev/null
+++ b/drv/drvcopy.c
@@ -0,0 +1,268 @@
+
+/*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "drv_screenint.h"
+#include "drv_pixmapstr.h"
+#include "drv_gcstruct.h"
+
+void
+drvCopyRegion (DrvPixmapPtr pSrcPixmap,
+ DrvPixmapPtr pDstPixmap,
+ DrvGCPtr pGC,
+ RegionPtr pDstRegion,
+ int dx,
+ int dy,
+ drvCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure)
+{
+ int careful;
+ Bool reverse;
+ Bool upsidedown;
+ BoxPtr pbox;
+ int nbox;
+ BoxPtr pboxNew1, pboxNew2, pboxBase, pboxNext, pboxTmp;
+
+ pbox = RegionRects(pDstRegion);
+ nbox = RegionNumRects(pDstRegion);
+
+ careful = (pSrcPixmap == pDstPixmap);
+
+ pboxNew1 = NULL;
+ pboxNew2 = NULL;
+ if (careful && dy < 0)
+ {
+ upsidedown = TRUE;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ upsidedown = FALSE;
+ }
+
+ if (careful && dx < 0)
+ {
+ /* walk source right to left */
+ if (dy <= 0)
+ reverse = TRUE;
+ else
+ reverse = FALSE;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ if(!pboxNew2)
+ {
+ free(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ reverse = FALSE;
+ }
+
+ (*copyProc) (pSrcPixmap,
+ pDstPixmap,
+ pGC,
+ pbox,
+ nbox,
+ dx, dy,
+ reverse, upsidedown, bitPlane, closure);
+
+ free(pboxNew1);
+ free(pboxNew2);
+}
+
+
+RegionPtr
+drvDoCopy (DrvPixmapPtr pSrcPixmap,
+ DrvPixmapPtr pDstPixmap,
+ DrvGCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ drvCopyProc copyProc,
+ Pixel bitPlane,
+ void *closure)
+{
+ RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+ RegionPtr prgnExposed = NULL;
+ RegionRec rgnDst;
+ int dx;
+ int dy;
+ int numRects;
+ int box_x1;
+ int box_y1;
+ int box_x2;
+ int box_y2;
+ Bool fastSrc = FALSE; /* for fast clipping with pixmap source */
+ Bool fastDst = FALSE; /* for fast clipping with one rect dest */
+ Bool fastExpose = FALSE; /* for fast exposures with pixmap source */
+
+ if ((pSrcPixmap == pDstPixmap) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;//GetCompositeClip(pGC);
+ else
+ fastSrc = TRUE;
+
+ box_x1 = xIn;
+ box_y1 = yIn;
+ box_x2 = xIn + widthSrc;
+ box_y2 = yIn + heightSrc;
+
+ dx = xIn - xOut;
+ dy = yIn - yOut;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastSrc)
+ {
+ RegionPtr cclip;
+
+ fastExpose = TRUE;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (box_x2 > (int) pSrcPixmap->width)
+ {
+ box_x2 = (int) pSrcPixmap->width;
+ fastExpose = FALSE;
+ }
+ if (box_y2 > (int) pSrcPixmap->height)
+ {
+ box_y2 = (int) pSrcPixmap->height;
+ fastExpose = FALSE;
+ }
+
+ /* Translate and clip the dst to the destination composite clip */
+ box_x1 -= dx;
+ box_x2 -= dx;
+ box_y1 -= dy;
+ box_y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ cclip = pGC->pCompositeClip;//miGetCompositeClip(pGC);
+ if (RegionNumRects(cclip) == 1)
+ {
+ BoxPtr pBox = RegionRects(cclip);
+
+ if (box_x1 < pBox->x1) box_x1 = pBox->x1;
+ if (box_x2 > pBox->x2) box_x2 = pBox->x2;
+ if (box_y1 < pBox->y1) box_y1 = pBox->y1;
+ if (box_y2 > pBox->y2) box_y2 = pBox->y2;
+ fastDst = TRUE;
+ }
+ }
+
+ /* Check to see if the region is empty */
+ if (box_x1 >= box_x2 || box_y1 >= box_y2)
+ {
+ RegionNull(&rgnDst);
+ }
+ else
+ {
+ BoxRec box;
+ box.x1 = box_x1;
+ box.y1 = box_y1;
+ box.x2 = box_x2;
+ box.y2 = box_y2;
+ RegionInit(&rgnDst, &box, 1);
+ }
+
+ /* Clip against complex source if needed */
+ if (!fastSrc)
+ {
+ RegionIntersect(&rgnDst, &rgnDst, prgnSrcClip);
+ RegionTranslate(&rgnDst, -dx, -dy);
+ }
+
+ /* Clip against complex dest if needed */
+ if (!fastDst)
+ {
+ RegionIntersect(&rgnDst, &rgnDst,
+ pGC->pCompositeClip);// miGetCompositeClip(pGC));
+ }
+
+ /* Do bit blitting */
+ numRects = RegionNumRects(&rgnDst);
+ if (numRects && widthSrc && heightSrc)
+ drvCopyRegion (pSrcPixmap, pDstPixmap, pGC,
+ &rgnDst, dx, dy, copyProc, bitPlane, closure);
+
+ RegionUninit(&rgnDst);
+ if (freeSrcClip)
+ RegionDestroy(prgnSrcClip);
+ return prgnExposed;
+}
diff --git a/drv/fb/drvfb.h b/drv/fb/drvfb.h
index 1c4e0718d..05347f858 100644
--- a/drv/fb/drvfb.h
+++ b/drv/fb/drvfb.h
@@ -1271,6 +1271,18 @@ drvCopyProc
fbGetCopyPlaneFunction(DrvPixmapPtr pSrc,
DrvPixmapPtr pDst, int bitplane);
+
+RegionPtr
+drvfbCopyArea(DrvPixmapPtr pSrc,
+ DrvPixmapPtr pDst,
+ DrvGCPtr pGC,
+ int srcx,
+ int srcy,
+ int w,
+ int h,
+ int dstx,
+ int dsty);
+
/*
* fbfill.c
*/
diff --git a/drv/fb/fbcopy.c b/drv/fb/fbcopy.c
index d4484d989..10b72f435 100644
--- a/drv/fb/fbcopy.c
+++ b/drv/fb/fbcopy.c
@@ -310,3 +310,24 @@ fbGetCopyPlaneFunction(DrvPixmapPtr pSrc,
else
return NULL;
}
+
+RegionPtr
+drvfbCopyArea(DrvPixmapPtr pSrc,
+ DrvPixmapPtr pDst,
+ DrvGCPtr pGC,
+ int srcx,
+ int srcy,
+ int w,
+ int h,
+ int dstx,
+ int dsty)
+{
+ drvCopyProc copy;
+
+ if (pSrc->bitsPerPixel != pDst->bitsPerPixel)
+ copy = drvfb24_32CopyMtoN;
+ else
+ copy = drvfbCopyNtoN;
+ return drvDoCopy (pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, copy, 0, 0);
+}
diff --git a/drv/fb/fbgc.c b/drv/fb/fbgc.c
index 4b88bb4bd..5c352d691 100644
--- a/drv/fb/fbgc.c
+++ b/drv/fb/fbgc.c
@@ -34,7 +34,7 @@ const DrvGCOps drvfbGCOps = {
drvfbFillSpans,
drvfbSetSpans,
drvfbPutImage,
- NULL,
+ drvfbCopyArea,
NULL,
drvfbPolyPoint,
drvfbPolyLine,