summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-06-27 13:15:09 +0100
committerDave Airlie <airlied@redhat.com>2012-09-20 14:33:48 +1000
commitb84d88857faee06897b4541b70b81df7e8fd0540 (patch)
tree693ae0c504d80e93fb6dc4698272e177258369ea
parente8b2000e5f6e19f1da23bfef8ed9e833c7643e54 (diff)
initial gpu switching layer code
-rw-r--r--dix/Makefile.am1
-rw-r--r--dix/dispatch.c4
-rw-r--r--dix/gc.c2
-rw-r--r--dix/impedance.c1245
-rw-r--r--include/gc.h3
-rw-r--r--include/gcstruct.h3
-rw-r--r--include/impedance.h46
-rw-r--r--include/misc.h1
-rw-r--r--include/pixmapstr.h2
-rw-r--r--include/scrnintstr.h10
-rw-r--r--render/Makefile.am3
-rw-r--r--render/impedpict.c531
-rw-r--r--render/picturestr.h4
13 files changed, 1853 insertions, 2 deletions
diff --git a/dix/Makefile.am b/dix/Makefile.am
index b7358aa72..26bad204e 100644
--- a/dix/Makefile.am
+++ b/dix/Makefile.am
@@ -26,6 +26,7 @@ libdix_la_SOURCES = \
globals.c \
glyphcurs.c \
grabs.c \
+ impedance.c \
initatoms.c \
inpututils.c \
pixmap.c \
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 0ce10c2f7..d20a5f39d 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3760,6 +3760,10 @@ static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
xorg_list_init(&pScreen->output_slave_list);
xorg_list_init(&pScreen->offload_slave_list);
+ xorg_list_init(&pScreen->gc_list);
+ xorg_list_init(&pScreen->pixmap_list);
+ xorg_list_init(&pScreen->picture_list);
+
/*
* This loop gets run once for every Screen that gets added,
* but thats ok. If the ddx layer initializes the formats
diff --git a/dix/gc.c b/dix/gc.c
index f46e0ddc4..3197674a2 100644
--- a/dix/gc.c
+++ b/dix/gc.c
@@ -458,7 +458,7 @@ ChangeGCXIDs(ClientPtr client, GC * pGC, BITS32 mask, CARD32 *pC32)
return ChangeGC(client, pGC, mask, vals);
}
-static GCPtr
+GCPtr
NewGCObject(ScreenPtr pScreen, int depth)
{
GCPtr pGC;
diff --git a/dix/impedance.c b/dix/impedance.c
new file mode 100644
index 000000000..add8e89b5
--- /dev/null
+++ b/dix/impedance.c
@@ -0,0 +1,1245 @@
+/* impedance layer screen functions - replaces
+ *
+ * fb/mi as the bottom layer of wrapping for protocol level screens
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "windowstr.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "randrstr.h"
+#include "mi.h"
+#include "micmap.h"
+#include "impedance.h"
+#include "dixfontstr.h"
+#include "fb.h"
+#include "gcstruct.h"
+
+#define impedWindowEnabled(pWin) \
+ RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip)
+
+#define impedDrawableEnabled(pDrawable) \
+ ((pDrawable)->type == DRAWABLE_PIXMAP ? \
+ TRUE : impedWindowEnabled((WindowPtr) pDrawable))
+
+static DevPrivateKeyRec impedWinPrivateKeyRec;
+static DevPrivateKey
+impedGetWinPrivateKey (void)
+{
+ return &impedWinPrivateKeyRec;
+}
+
+#define impedGetWindowPixmap(pWin) ((PixmapPtr) \
+ dixLookupPrivate(&((WindowPtr)(pWin))->devPrivates, impedGetWinPrivateKey()))
+
+#define FOR_EACH_PIXMAP_MEMCPY(op, opcpy) \
+ for (int _i = 0; _i < pDrawable->pScreen->num_gpu; _i++) { \
+ GCPtr _pDrvGC = pGC->gpu[_i]; \
+ PixmapPtr _pDrvPixmap = pPixmap->gpu[_i]; \
+ RegionRec orig_region; \
+ while (_pDrvPixmap) { \
+ op; \
+ opcpy; \
+ _pDrvPixmap = NULL;/* _pDrvPixmap->shatter_next; */ \
+ } \
+ }
+
+#define FOR_EACH_PIXMAP(op) FOR_EACH_PIXMAP_MEMCPY(op, do {} while(0))
+
+void
+impedValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ PixmapPtr pPixmap = GetDrawablePixmap(pDrawable);
+ GCPtr pDrvGC;
+ int i;
+ int x_off = 0, y_off = 0;
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+ }
+
+ if (pGC->pCompositeClip)
+ ErrorF("clip %d %d %d %d\n",
+ pGC->pCompositeClip->extents.x1,
+ pGC->pCompositeClip->extents.y1,
+ pGC->pCompositeClip->extents.x2,
+ pGC->pCompositeClip->extents.y2);
+ /* have to translate the composite clip before syncing it */
+#ifdef COMPOSITE
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ x_off = -pPixmap->screen_x;
+ y_off = -pPixmap->screen_y;
+ RegionTranslate(pGC->pCompositeClip, x_off, y_off);
+ }
+#endif
+ for (i = 0; i < pGC->pScreen->num_gpu; i++) {
+ pDrvGC = pGC->gpu[i];
+
+ /* check tile pixmap */
+ if (pGC->fillStyle == FillTiled && !pGC->tileIsPixel) {
+ if (pDrvGC->tile.pixmap != pGC->tile.pixmap->gpu[i]) {
+ pDrvGC->tile.pixmap = pGC->tile.pixmap->gpu[i];
+ pDrvGC->tile.pixmap->refcnt++;
+ }
+ }
+ if (!pDrvGC->pCompositeClip) {
+ pDrvGC->freeCompClip = TRUE;
+ pDrvGC->pCompositeClip = RegionCreate(NULL, 0);
+ }
+ pDrvGC->funcs->ValidateGC(pDrvGC, changes, &pPixmap->gpu[i]->drawable);
+ /* overwrite the composite clip with the toplevel one -
+ probably could just avoid clipping down in fbgc.c
+ fixes rendering with twm + xlogo in top corner */
+ RegionCopy(pDrvGC->pCompositeClip, pGC->pCompositeClip);
+ }
+#ifdef COMPOSITE
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ RegionTranslate(pGC->pCompositeClip, -x_off, -y_off);
+ }
+#endif
+}
+
+static void impedDestroyGC(GCPtr pGC)
+{
+ int i;
+
+ xorg_list_del(&pGC->member);
+ for (i = 0; i < pGC->pScreen->num_gpu; i++) {
+ FreeGC(pGC->gpu[i], 0);
+ pGC->gpu[i] = NULL;
+ }
+
+ miDestroyGC(pGC);
+}
+
+static void impedModChildGC(GCPtr pGC, GCPtr pChild, int index, unsigned long mask)
+{
+ PixmapPtr pPixmap;
+ BITS32 index2, maskQ;
+ maskQ = mask;
+ while (mask) {
+ index2 = (BITS32)lowbit(mask);
+ mask &= ~index2;
+ switch (index2) {
+ case GCFunction:
+ pChild->alu = pGC->alu;
+ break;
+ case GCPlaneMask:
+ pChild->planemask = pGC->planemask;
+ break;
+ case GCForeground:
+ pChild->fgPixel = pGC->fgPixel;
+ break;
+ case GCBackground:
+ pChild->bgPixel = pGC->bgPixel;
+ break;
+ case GCLineWidth:
+ pChild->lineWidth = pGC->lineWidth;
+ break;
+ case GCLineStyle:
+ pChild->lineStyle = pGC->lineStyle;
+ break;
+ case GCCapStyle:
+ pChild->capStyle = pGC->capStyle;
+ break;
+ case GCJoinStyle:
+ pChild->joinStyle = pGC->joinStyle;
+ break;
+ case GCFillStyle:
+ pChild->fillStyle = pGC->fillStyle;
+ break;
+ case GCFillRule:
+ pChild->fillRule = pGC->fillRule;
+ break;
+ case GCTile:
+ if (!pChild->tileIsPixel)
+ pChild->pScreen->DestroyPixmap(pChild->tile.pixmap);
+ pChild->tileIsPixel = pGC->tileIsPixel;
+ if (pGC->tileIsPixel == FALSE) {
+ pPixmap = pGC->tile.pixmap->gpu[index];
+ pChild->tile.pixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+ break;
+ case GCStipple:
+ pPixmap = pGC->stipple->gpu[index];
+ if (pChild->stipple)
+ pChild->pScreen->DestroyPixmap(pChild->stipple);
+ pChild->stipple = pPixmap;
+ break;
+ case GCTileStipXOrigin:
+ pChild->patOrg.x = pGC->patOrg.x;
+ break;
+ case GCTileStipYOrigin:
+ pChild->patOrg.y = pGC->patOrg.y;
+ break;
+ case GCFont:
+ if (pChild->font)
+ CloseFont(pChild->font, (Font)0);
+ pGC->font->refcnt++;
+ pChild->font = pGC->font;
+ break;
+ case GCSubwindowMode:
+ pChild->subWindowMode = pGC->subWindowMode;
+ break;
+ case GCGraphicsExposures:
+ pChild->graphicsExposures = pGC->graphicsExposures;
+ break;
+ case GCClipXOrigin:
+ pChild->clipOrg.x = pGC->clipOrg.x;
+ break;
+ case GCClipYOrigin:
+ pChild->clipOrg.y = pGC->clipOrg.y;
+ break;
+ case GCDashOffset:
+ pChild->dashOffset = pGC->dashOffset;
+ break;
+ case GCArcMode:
+ pChild->arcMode = pGC->arcMode;
+ break;
+ case GCClipMask:
+ default:
+ ErrorF("unhandled GC bit %lx\n", index2);
+ }
+ }
+}
+
+static void impedChangeGC(GCPtr pGC, unsigned long mask)
+{
+ unsigned long maskQ;
+ int i;
+ ErrorF("imped change GC %08x\n", mask);
+ maskQ = mask;
+ /* have to execute GC change on the lower layers
+ however for have to also do pixmap lookups etc */
+
+ for (i = 0; i < pGC->pScreen->num_gpu; i++) {
+ impedModChildGC(pGC, pGC->gpu[i], i, mask);
+ }
+ miChangeGC(pGC, maskQ);
+}
+
+const GCFuncs impedGCFuncs = {
+ impedValidateGC,
+ impedChangeGC,
+ miCopyGC,
+ impedDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+static void
+impedFillSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted)
+{
+ int i;
+ int x_off, y_off;
+ PixmapPtr pPixmap = GetDrawablePixmap(pDrawable);
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ for (i = 0; i < nInit; i++) {
+ pptInit[i].x += x_off;
+ pptInit[i].y += y_off;
+ }
+
+ FOR_EACH_PIXMAP(_pDrvGC->ops->FillSpans(&_pDrvPixmap->drawable,
+ _pDrvGC,
+ nInit,
+ pptInit,
+ pwidthInit,
+ fSorted));
+}
+
+static void
+impedSetSpans (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *src,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted)
+{
+ int i;
+ int x_off, y_off;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ for (i = 0; i < nspans; i++) {
+ ppt[i].x += x_off;
+ ppt[i].y += y_off;
+ }
+
+
+ FOR_EACH_PIXMAP(_pDrvGC->ops->SetSpans(&_pDrvPixmap->drawable,
+ _pDrvGC,
+ src,
+ ppt,
+ pwidth,
+ nspans,
+ fSorted));
+}
+
+static void
+impedPutImage (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ int x_off, y_off;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ x += x_off;
+ y += y_off;
+
+ FOR_EACH_PIXMAP(_pDrvGC->ops->PutImage(&_pDrvPixmap->drawable,
+ _pDrvGC,
+ depth, x, y, w, h,
+ leftPad, format, pImage));
+
+}
+
+static void
+impedPolyPoint (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ xPoint *origPts;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ if (mode == CoordModePrevious) {
+ pptInit[0].x += x_off;
+ pptInit[0].y += y_off;
+ } else {
+ for (i = 0; i < npt; i++) {
+ pptInit[i].x += x_off;
+ pptInit[i].y += y_off;
+ }
+ }
+
+ origPts = malloc(npt * sizeof(*pptInit));
+ memcpy(origPts, pptInit, npt * sizeof(xPoint));
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->PolyPoint(&_pDrvPixmap->drawable,
+ _pDrvGC, mode, npt, pptInit),
+ memcpy(pptInit, origPts, npt * sizeof(xPoint)));
+ free(origPts);
+}
+
+static void
+impedPolyLines (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DDXPointPtr ppt_orig;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ fprintf(stderr,"poly lines %d %d %d\n", mode, x_off, y_off);
+ if (mode == CoordModePrevious) {
+ ppt[0].x += x_off;
+ ppt[0].y += y_off;
+ } else {
+ for (i = 0; i < npt; i++) {
+ ppt[i].x += x_off;
+ ppt[i].y += y_off;
+ }
+ }
+ ppt_orig = malloc(sizeof(*ppt_orig) * npt);
+ if (!ppt_orig)
+ return;
+
+ memcpy(ppt_orig, ppt, npt * sizeof(*ppt_orig));
+
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->Polylines(&_pDrvPixmap->drawable,
+ _pDrvGC, mode, npt, ppt),
+ memcpy(ppt, ppt_orig, npt*sizeof(*ppt_orig)));
+ free(ppt_orig);
+}
+
+static void
+impedPolySegment (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSegs)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ xSegment *pSegs_orig;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < nseg; i++) {
+ pSegs[i].x1 += x_off;
+ pSegs[i].x2 += x_off;
+ pSegs[i].y1 += y_off;
+ pSegs[i].y2 += y_off;
+ }
+
+ pSegs_orig = malloc(nseg * sizeof(*pSegs));
+ if (!pSegs_orig)
+ return;
+
+ memcpy(pSegs_orig, pSegs, nseg * sizeof(*pSegs));
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->PolySegment(&_pDrvPixmap->drawable,
+ _pDrvGC, nseg, pSegs),
+ memcpy(pSegs, pSegs_orig, nseg * sizeof(*pSegs)));
+ free(pSegs_orig);
+}
+
+static void
+impedPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects, xRectangle *pRects)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ xRectangle *orig_pRects;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < nrects; i++) {
+ pRects[i].x += x_off;
+ pRects[i].y += y_off;
+ }
+
+ orig_pRects = malloc(nrects * sizeof(xRectangle));
+ memcpy(orig_pRects, pRects, nrects * sizeof(xRectangle));
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->PolyRectangle(&_pDrvPixmap->drawable, _pDrvGC, nrects, pRects),
+ memcpy(pRects, orig_pRects, nrects * sizeof(xRectangle)));
+
+ free(orig_pRects);
+}
+
+static void impedPolyArc (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ xArc *orig_arcs;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ /* impedance match with fb layer */
+ for (i = 0; i < narcs; i++) {
+ parcs[i].x += x_off;
+ parcs[i].y += y_off;
+ }
+
+ orig_arcs = malloc(narcs * sizeof(xArc));
+ if (!orig_arcs)
+ return;
+
+ memcpy(orig_arcs, parcs, narcs * sizeof(xArc));
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->PolyArc(&_pDrvPixmap->drawable, _pDrvGC, narcs, parcs),
+ memcpy(parcs, orig_arcs, narcs * sizeof(xArc)));
+ free(orig_arcs);
+}
+
+static void impedFillPolygon( DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode,
+ int count, DDXPointPtr pPts)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ DDXPointPtr orig_pts;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < count; i++) {
+ pPts[i].x += x_off;
+ pPts[i].y += y_off;
+ }
+
+ orig_pts = malloc(count * sizeof(DDXPointRec));
+ if (!orig_pts)
+ return;
+
+ memcpy(orig_pts, pPts, count * sizeof(DDXPointRec));
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->FillPolygon(&_pDrvPixmap->drawable, _pDrvGC, shape,
+ mode, count, pPts),
+ memcpy(pPts, orig_pts, count * sizeof(DDXPointRec)));
+ free(orig_pts);
+}
+
+static void impedPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ xRectangle *orig_prect;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ for (i = 0; i < nrectFill; i++) {
+ prectInit[i].x += x_off;
+ prectInit[i].y += y_off;
+ }
+
+ orig_prect = malloc(nrectFill * sizeof(xRectangle));
+ if (!orig_prect)
+ return;
+
+ memcpy(orig_prect, prectInit, nrectFill * sizeof(xRectangle));
+
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->PolyFillRect(&_pDrvPixmap->drawable, _pDrvGC, nrectFill, prectInit),
+ memcpy(prectInit, orig_prect, nrectFill * sizeof(xRectangle)));
+ free(orig_prect);
+}
+
+static void impedPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc *parcs)
+{
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ xArc *orig_arcs;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < narcs; i++) {
+ parcs[i].x += x_off;
+ parcs[i].y += y_off;
+ }
+
+ orig_arcs = malloc(narcs * sizeof(xArc));
+ if (!orig_arcs)
+ return;
+
+ memcpy(orig_arcs, parcs, narcs * sizeof(xArc));
+ FOR_EACH_PIXMAP_MEMCPY(_pDrvGC->ops->PolyFillArc(&_pDrvPixmap->drawable, _pDrvGC, narcs, parcs),
+ memcpy(orig_arcs, parcs, sizeof(narcs * sizeof(xArc))));
+ free(orig_arcs);
+}
+
+static int
+impedPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ int i, ret = 0;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ GCPtr pDrvGC;
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < pDrawable->pScreen->num_gpu; i++) {
+ pDrvGC = pGC->gpu[i];
+ ret = pDrvGC->ops->PolyText8(&pPixmap->gpu[i]->drawable, pDrvGC, x, y, count, chars);
+ }
+ return ret;
+}
+
+static int
+impedPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
+{
+ int ret = 0;
+ int i;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+ GCPtr pDrvGC;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ for (i = 0; i < pDrawable->pScreen->num_gpu; i++) {
+ pDrvGC = pGC->gpu[i];
+ ret = pDrvGC->ops->PolyText16(&pPixmap->gpu[i]->drawable, pDrvGC, x, y, count, chars);
+ if (ret)
+ return ret;
+ }
+ return ret;
+}
+
+static void
+impedImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *chars)
+{
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+
+ FOR_EACH_PIXMAP(_pDrvGC->ops->ImageText8(&_pDrvPixmap->drawable, _pDrvGC, x, y, count, chars));
+}
+
+static void
+impedImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *chars)
+{
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ FOR_EACH_PIXMAP(_pDrvGC->ops->ImageText16(&_pDrvPixmap->drawable, _pDrvGC, x, y, count, chars));
+}
+
+static void
+impedPolyGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ int x_off, y_off;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ x += x_off;
+ y += y_off;
+
+ FOR_EACH_PIXMAP(_pDrvGC->ops->PolyGlyphBlt(&_pDrvPixmap->drawable, _pDrvGC,
+ x, y, nglyph,
+ ppci, pglyphBase));
+}
+
+static void
+impedImageGlyphBlt (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ int x_off, y_off;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ x += x_off;
+ y += y_off;
+ FOR_EACH_PIXMAP(_pDrvGC->ops->ImageGlyphBlt(&_pDrvPixmap->drawable, _pDrvGC,
+ x, y, nglyph,
+ ppciInit, pglyphBase));
+}
+
+void
+impedCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ miCopyProc copy;
+ int src_x_off, src_y_off;
+ int dst_x_off, dst_y_off;
+ PixmapPtr pSrcPixmap = (PixmapPtr)GetDrawablePixmap(pSrcDrawable);
+ PixmapPtr pDstPixmap = (PixmapPtr)GetDrawablePixmap(pDstDrawable);
+ int i;
+ GCPtr pDrvGC = NULL;
+
+ impedGetCompositeDeltas(pSrcDrawable, pSrcPixmap, &src_x_off, &src_y_off);
+ impedGetCompositeDeltas(pDstDrawable, pDstPixmap, &dst_x_off, &dst_y_off);
+
+ /* copy already takes care of the pixmap clipping */
+ dx += -dst_x_off + src_x_off;//pDstPixmap->screen_x - pSrcPixmap->screen_x;
+ dy += -dst_y_off + src_y_off;//pDstPixmap->screen_y - pSrcPixmap->screen_y;
+
+ if (dst_x_off || dst_y_off) {
+ for (i = 0; i < nbox; i++) {
+ pbox[i].x1 += dst_x_off;
+ pbox[i].x2 += dst_x_off;
+
+ pbox[i].y1 += dst_y_off;
+ pbox[i].y2 += dst_y_off;
+ }
+ }
+
+ for (i = 0; i < pSrcDrawable->pScreen->num_gpu; i++) {
+ // copy = pSrcDrawable->pScreen->gpu[i]->GetCopyAreaFunction(&pSrcPixmap->gpu[i]->drawable, &pDstPixmap->gpu[i]->drawable);
+
+ if (pGC) {
+ pDrvGC = pGC->gpu[i];
+ }
+
+ copy(&pSrcPixmap->gpu[i]->drawable,
+ &pDstPixmap->gpu[i]->drawable,
+ pDrvGC, pbox, nbox, dx, dy, reverse,
+ upsidedown, bitplane, closure);
+ }
+
+}
+
+static RegionPtr
+impedCopyArea (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut)
+{
+ return miDoCopy(pSrcDrawable,
+ pDstDrawable,
+ pGC, xIn, yIn,
+ widthSrc,
+ heightSrc,
+ xOut,
+ yOut,
+ impedCopyNtoN, 0, 0);
+}
+
+#if 0
+static void
+impedCopyPlaneNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ drvCopyProc copy;
+ PixmapPtr pSrcPixmap, pDstPixmap;
+ DrvGCPtr pDrvGC = NULL;
+ impedGCPrivPtr imped_gc;
+
+ int i;
+ pSrcPixmap = GetDrawablePixmap(pSrcDrawable);
+ pDstPixmap = GetDrawablePixmap(pDstDrawable);
+
+ for (i = 0; i < pSrcDrawable->pScreen->num_gpu; i++) {
+ copy = imped_src_screen->gpu[i]->GetCopyPlaneFunction(imped_src_pixmap->gpu[i],
+ imped_dst_pixmap->gpu[i], bitplane);
+
+ if (pGC) {
+ imped_gc = impedGetGC(pGC);
+ pDrvGC = imped_gc->gpu[i];
+ }
+ copy(imped_src_pixmap->gpu[i],
+ imped_dst_pixmap->gpu[i],
+ pDrvGC, pbox, nbox, dx, dy, reverse,
+ upsidedown, bitplane, closure);
+ }
+
+}
+#endif
+
+static RegionPtr
+impedCopyPlane (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ int xIn,
+ int yIn,
+ int widthSrc,
+ int heightSrc,
+ int xOut,
+ int yOut,
+ unsigned long bitplane)
+{
+ // drvCopyProc copy;
+ PixmapPtr pSrcPixmap, pDstPixmap;
+
+ pSrcPixmap = GetDrawablePixmap(pSrcDrawable);
+ pDstPixmap = GetDrawablePixmap(pDstDrawable);
+
+#if 0
+ copy = imped_src_screen->gpu[0]->GetCopyPlaneFunction(imped_src_pixmap->gpu[0],
+ imped_dst_pixmap->gpu[0], bitplane);
+
+ if (copy)
+ return miDoCopy(pSrcDrawable,
+ pDstDrawable,
+ pGC, xIn, yIn,
+ widthSrc,
+ heightSrc,
+ xOut,
+ yOut,
+ impedCopyPlaneNtoN, (Pixel)bitplane, 0);
+ else
+#endif
+ return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ xIn, yIn,
+ widthSrc,
+ heightSrc,
+ xOut, yOut, bitplane);
+}
+
+static void
+impedPushPixels (GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg)
+{
+ int x_off, y_off;
+ PixmapPtr pPixmap = (PixmapPtr)GetDrawablePixmap(pDrawable);
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ xOrg += x_off;
+ yOrg += y_off;
+
+ FOR_EACH_PIXMAP(_pDrvGC->ops->PushPixels(_pDrvGC, pBitmap->gpu[_i], &_pDrvPixmap->drawable,
+ dx, dy, xOrg, yOrg));
+
+}
+
+const GCOps impedGCOps = {
+ impedFillSpans,
+ impedSetSpans,
+ impedPutImage,
+ impedCopyArea,
+ impedCopyPlane,
+ impedPolyPoint,
+ impedPolyLines,
+ impedPolySegment,
+ impedPolyRectangle,
+ impedPolyArc,
+ impedFillPolygon,
+ impedPolyFillRect,
+ impedPolyFillArc,
+ impedPolyText8,
+ impedPolyText16,
+ impedImageText8,
+ impedImageText16,
+ impedImageGlyphBlt,
+ impedPolyGlyphBlt,
+ impedPushPixels,
+};
+
+static Bool
+impedCreateGC(GCPtr pGC)
+{
+ GCPtr gpugc;
+ int i;
+ Bool ret;
+ pGC->ops = (GCOps *)&impedGCOps;
+ pGC->funcs = &impedGCFuncs;
+
+ /* imped wants to translate before scan conversion */
+ pGC->miTranslate = 1;
+ pGC->fExpose = 1;
+
+ xorg_list_add(&pGC->member, &pGC->pScreen->gc_list);
+
+ for (i = 0; i < pGC->pScreen->num_gpu; i++) {
+ gpugc = NewGCObject(pGC->pScreen->gpu[i], pGC->depth);
+ pGC->gpu[i] = gpugc;
+ // gpugc->parent = pGC;
+ ret = gpugc->pScreen->CreateGC(gpugc);
+ if (ret == FALSE)
+ return FALSE;
+ i++;
+ }
+
+ return TRUE;
+
+}
+
+
+static Bool
+impedAllocatePrivates(ScreenPtr pScreen)
+{
+ if (!dixRegisterPrivateKey(&impedWinPrivateKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+impedCreateScreenResources(ScreenPtr pScreen)
+{
+ Bool ret = TRUE;
+ int i;
+ PixmapPtr pPixmap;
+ xorg_list_init(&pScreen->gc_list);
+ xorg_list_init(&pScreen->pixmap_list);
+ xorg_list_init(&pScreen->picture_list);
+
+ ret = miCreateScreenResources(pScreen);
+ if (!ret)
+ return ret;
+
+
+ /* have to fixup the screen pixmap linkages */
+ pPixmap = pScreen->GetScreenPixmap(pScreen);
+ for (i = 0; i < pScreen->num_gpu; i++)
+ pScreen->gpu[i]->omghack = pPixmap->gpu[i];
+
+ for (i = 0; i < pScreen->num_gpu; i++)
+ pScreen->gpu[i]->CreateScreenResources(pScreen->gpu[i]);
+
+ return ret;
+}
+
+static Bool
+impedCreateWindow(WindowPtr pWin)
+{
+ dixSetPrivate(&pWin->devPrivates, impedGetWinPrivateKey(),
+ impedGetScreenPixmap(pWin->drawable.pScreen));
+ return TRUE;
+}
+
+static Bool
+impedPositionWindow(WindowPtr pWin, int x, int y)
+{
+ return TRUE;
+}
+
+static Bool
+impedDestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+static Bool
+impedMapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+
+static Bool
+impedUnmapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+static void
+impedCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+ RegionRec rgnDst;
+ int dx, dy;
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ RegionTranslate(prgnSrc, -dx, -dy);
+ RegionNull(&rgnDst);
+ RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
+#ifdef COMPOSITE
+ if (pPixmap->screen_x || pPixmap->screen_y) {
+ int xoff = 0, yoff = 0;
+
+ xoff = -pPixmap->screen_x;
+ yoff = -pPixmap->screen_y;
+ RegionTranslate(&rgnDst, xoff, yoff);
+ }
+#endif
+
+ // miCopyRegion(&pWin->drawable, &pWin->drawable, NULL,
+ // &rgnDst, dx, dy, impedCopyNtoN, 0, 0);
+
+ RegionUninit(&rgnDst);
+}
+
+static Bool
+impedChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
+{
+ return FALSE;
+}
+
+static Bool
+impedRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ return TRUE;
+}
+
+static Bool
+impedUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ return TRUE;
+}
+
+static void
+impedGetImage (DrawablePtr pDrawable,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *d)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ RegionRec img_region;
+ PixmapPtr pPixmap = GetDrawablePixmap(pDrawable);
+ int x_off, y_off;
+
+ if (!impedDrawableEnabled(pDrawable))
+ return;
+
+ impedGetDrawableDeltas(pDrawable, pPixmap, &x_off, &y_off);
+ x += x_off;
+ y += y_off;
+
+ pScreen->gpu[0]->GetImage(&pPixmap->gpu[0]->drawable, x, y, w, h,
+ format, planeMask, d);
+ /* TODO shatter*/
+}
+
+static void
+impedGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart)
+{
+}
+
+static PixmapPtr
+impedCreatePixmap (ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint)
+{
+ PixmapPtr pPixmap;
+ pPixmap = AllocatePixmap(pScreen, 0);
+ if (!pPixmap)
+ return NULL;
+
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = BitsPerPixel (depth);
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = (width * (BitsPerPixel(depth)/8));
+ pPixmap->refcnt = 1;
+
+#ifdef COMPOSITE
+ pPixmap->screen_x = 0;
+ pPixmap->screen_y = 0;
+#endif
+ pPixmap->usage_hint = usage_hint;
+
+ xorg_list_add(&pPixmap->member, &pScreen->pixmap_list);
+
+ {
+ int i = 0;
+ for (i = 0; i < pScreen->num_gpu; i++)
+ pPixmap->gpu[i] = pScreen->gpu[i]->CreatePixmap(pScreen->gpu[i],
+ width, height,
+ depth, usage_hint);
+ }
+ return pPixmap;
+}
+
+static Bool
+impedModifyPixmapHeader(PixmapPtr pPixmap, int w, int h, int d,
+ int bpp, int devKind, pointer pPixData)
+{
+ ScreenPtr screen;
+ int i;
+ if (!pPixmap)
+ return FALSE;
+
+ miModifyPixmapHeader(pPixmap, w, h, d, bpp, devKind, pPixData);
+
+ screen = pPixmap->drawable.pScreen;
+ for (i = 0; i < screen->num_gpu; i++)
+ screen->gpu[i]->ModifyPixmapHeader(pPixmap->gpu[i], w, h, d, bpp, devKind, pPixData);
+
+ return TRUE;
+}
+
+static void
+impedQueryBestSize (int class,
+ unsigned short *width, unsigned short *height,
+ ScreenPtr pScreen)
+{
+ pScreen->gpu[0]->QueryBestSize(class, width, height, pScreen->gpu[0]);
+}
+
+static RegionPtr
+impedBitmapToRegion(PixmapPtr pPix)
+{
+ return pPix->drawable.pScreen->gpu[0]->BitmapToRegion(pPix->gpu[0]);
+}
+
+static Bool
+impedDestroyPixmap(PixmapPtr pPixmap)
+{
+ int i;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ if (--pPixmap->refcnt)
+ return TRUE;
+
+ xorg_list_del(&pPixmap->member);
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ pScreen->gpu[i]->DestroyPixmap(pPixmap->gpu[i]);
+ }
+ FreePixmap(pPixmap);
+ return TRUE;
+}
+
+Bool
+impedCloseScreen (ScreenPtr pScreen)
+{
+ return FALSE;
+}
+
+PixmapPtr
+_impedGetWindowPixmap (WindowPtr pWindow)
+{
+ return impedGetWindowPixmap (pWindow);
+}
+
+void
+_impedSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+ dixSetPrivate(&pWindow->devPrivates, impedGetWinPrivateKey(), pPixmap);
+}
+
+
+Bool
+impedSetupScreen(ScreenPtr pScreen)
+{
+
+ if (!impedAllocatePrivates(pScreen))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+
+ pScreen->ChangeWindowAttributes = impedChangeWindowAttributes;
+ pScreen->CreateWindow = impedCreateWindow;
+ pScreen->CopyWindow = impedCopyWindow;
+ pScreen->PositionWindow = impedPositionWindow;
+ pScreen->RealizeWindow = impedMapWindow;
+ pScreen->UnrealizeWindow = impedUnmapWindow;
+ pScreen->DestroyWindow = impedDestroyWindow;
+ pScreen->GetImage = impedGetImage;
+ pScreen->GetSpans = impedGetSpans;
+ pScreen->GetWindowPixmap = _impedGetWindowPixmap;
+ pScreen->SetWindowPixmap = _impedSetWindowPixmap;
+
+ pScreen->RealizeFont = impedRealizeFont;
+ pScreen->UnrealizeFont = impedUnrealizeFont;
+
+ pScreen->CreateColormap = miInitializeColormap;
+ pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
+ pScreen->InstallColormap = miInstallColormap;
+ pScreen->UninstallColormap = miUninstallColormap;
+ pScreen->ListInstalledColormaps = miListInstalledColormaps;
+ pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA;
+ pScreen->ResolveColor = miResolveColor;
+
+ pScreen->CreatePixmap = impedCreatePixmap;
+ pScreen->DestroyPixmap = impedDestroyPixmap;
+
+ pScreen->CreateGC = impedCreateGC;
+
+ pScreen->QueryBestSize = impedQueryBestSize;
+
+ pScreen->BitmapToRegion = impedBitmapToRegion;
+
+ /* replace miCloseScreen */
+
+ // drvmiSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
+ return TRUE;
+}
+
+Bool impedFinishScreenInit(ScreenPtr pScreen,
+ pointer pbits,
+ int xsize,
+ int ysize,
+ int dpix,
+ int dpiy,
+ int width,
+ int bpp)
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+ int imagebpp = bpp;
+ // impedScreenPrivPtr imped_screen;
+ rootdepth = 0;
+
+ if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual, 8, ((unsigned long)1<<(imagebpp - 1)), -1))
+ return FALSE;
+ if (!miScreenInit(pScreen, NULL, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths, defaultVisual,
+ nvisuals, visuals))
+ return FALSE;
+
+ pScreen->ModifyPixmapHeader = impedModifyPixmapHeader;
+ pScreen->CreateScreenResources = impedCreateScreenResources;
+
+ return TRUE;
+}
+
+static Bool
+impedScreenSetSize(ScreenPtr pScreen,
+ CARD16 width, CARD16 height,
+ CARD32 mmWidth, CARD32 mmHeight)
+{
+ PixmapPtr pScrnPix;
+
+ SetRootClip(pScreen, FALSE);
+
+ pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
+ pScreen->width = pScrnPix->drawable.width = width;
+ pScreen->height = pScrnPix->drawable.width = height;
+
+ update_desktop_dimensions();
+
+ SetRootClip(pScreen, TRUE);
+
+ // if (pScreen->root)
+ // RRScreenSizeNotify(pScreen);
+ return TRUE;
+}
+
+#if 0
+Bool
+impedRandR12Init(ScreenPtr pScreen)
+{
+ rrScrPrivPtr rp;
+ if (!RRScreenInit(pScreen))
+ return FALSE;
+
+ rp = rrGetScrPriv(pScreen);
+ rp->rrScreenSetSize = impedScreenSetSize;
+
+ return TRUE;
+}
+#endif
diff --git a/include/gc.h b/include/gc.h
index 6e5b92da2..6aa4fd0ed 100644
--- a/include/gc.h
+++ b/include/gc.h
@@ -101,6 +101,9 @@ extern _X_EXPORT int ChangeGC(ClientPtr /*client */ ,
BITS32 /*mask */ ,
ChangeGCValPtr /*pCGCV */ );
+/* create a bare GC object */
+extern _X_EXPORT GCPtr NewGCObject(ScreenPtr pScreen, int depth);
+
extern _X_EXPORT GCPtr CreateGC(DrawablePtr /*pDrawable */ ,
BITS32 /*mask */ ,
XID * /*pval */ ,
diff --git a/include/gcstruct.h b/include/gcstruct.h
index 7621ceb11..908941c92 100644
--- a/include/gcstruct.h
+++ b/include/gcstruct.h
@@ -287,6 +287,9 @@ typedef struct _GC {
PixmapPtr pRotatedPixmap; /* tile/stipple rotated for alignment */
RegionPtr pCompositeClip;
/* fExpose & freeCompClip defined above */
+
+ struct xorg_list member;
+ GCPtr gpu[MAXGPU];
} GC;
#endif /* GCSTRUCT_H */
diff --git a/include/impedance.h b/include/impedance.h
new file mode 100644
index 000000000..95c587212
--- /dev/null
+++ b/include/impedance.h
@@ -0,0 +1,46 @@
+#ifndef IMPEDANCE_H
+#define IMPEDANCE_H
+
+#define impedGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate)
+
+static inline void impedGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap,
+ int *x_off, int *y_off)
+{
+ *x_off = pDrawable->x;
+ *y_off = pDrawable->y;
+
+#ifdef COMPOSITE
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ *x_off -= pPixmap->screen_x;
+ *y_off -= pPixmap->screen_y;
+ }
+#endif
+}
+
+static inline PixmapPtr GetDrawablePixmap(DrawablePtr drawable)
+{
+ if (drawable->type == DRAWABLE_PIXMAP)
+ return (PixmapPtr)drawable;
+ else {
+ struct _Window *pWin = (struct _Window *)drawable;
+ return drawable->pScreen->GetWindowPixmap(pWin);
+ }
+}
+
+/* only used for CopyNtoN */
+static inline void impedGetCompositeDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap,
+ int *x_off, int *y_off)
+{
+ *x_off = 0;
+ *y_off = 0;
+
+#ifdef COMPOSITE
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ *x_off -= pPixmap->screen_x;
+ *y_off -= pPixmap->screen_y;
+ }
+#endif
+}
+
+
+#endif
diff --git a/include/misc.h b/include/misc.h
index 348717676..f478455b3 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -86,6 +86,7 @@ OF THIS SOFTWARE.
#ifndef MAXGPUSCREENS
#define MAXGPUSCREENS 16
#endif
+#define MAXGPU 2 /* only have space for 2 per protocol screen now */
#define MAXCLIENTS 256
#define MAXEXTENSIONS 128
#define MAXFORMATS 8
diff --git a/include/pixmapstr.h b/include/pixmapstr.h
index 2a1ef9b85..98963ca47 100644
--- a/include/pixmapstr.h
+++ b/include/pixmapstr.h
@@ -83,6 +83,8 @@ typedef struct _Pixmap {
unsigned usage_hint; /* see CREATE_PIXMAP_USAGE_* */
PixmapPtr master_pixmap; /* pointer to master copy of pixmap for pixmap sharing */
+ PixmapPtr gpu[MAXGPU];
+ struct xorg_list member;
} PixmapRec;
typedef struct _PixmapDirtyUpdate {
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index df7407391..c91f0130c 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -513,6 +513,16 @@ typedef struct _Screen {
struct xorg_list offload_head;
ReplaceScanoutPixmapProcPtr ReplaceScanoutPixmap;
+
+ ScreenPtr gpu[MAXGPU];
+ int num_gpu;
+ int primary_gpu_index;
+
+ struct xorg_list gc_list;
+ struct xorg_list pixmap_list;
+ struct xorg_list picture_list;
+ PixmapPtr omghack;
+
} ScreenRec;
static inline RegionPtr
diff --git a/render/Makefile.am b/render/Makefile.am
index d02028b3b..32a1a42ca 100644
--- a/render/Makefile.am
+++ b/render/Makefile.am
@@ -13,7 +13,8 @@ librender_la_SOURCES = \
mitrap.c \
mitri.c \
picture.c \
- render.c
+ render.c \
+ impedpict.c
if XORG
sdk_HEADERS = picture.h mipict.h glyphstr.h picturestr.h
diff --git a/render/impedpict.c b/render/impedpict.c
new file mode 100644
index 000000000..69c1cef01
--- /dev/null
+++ b/render/impedpict.c
@@ -0,0 +1,531 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "fb.h"
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "impedance.h"
+
+static void
+impedComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ int x_off, y_off;
+ PixmapPtr pSrcPixmap = NULL, pDstPixmap, pMaskPixmap = NULL;
+ PicturePtr pDrvSrc, pDrvMask = NULL, pDrvDst;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int i;
+
+ if (pSrc->pDrawable) {
+ pSrcPixmap = GetDrawablePixmap(pSrc->pDrawable);
+ }
+
+ if (pMask) {
+ pMaskPixmap = GetDrawablePixmap(pMask->pDrawable);
+ }
+ pDstPixmap = GetDrawablePixmap(pDst->pDrawable);
+
+ miCompositeSourceValidate (pSrc);
+ if (pMask)
+ miCompositeSourceValidate (pMask);
+
+ if (pSrc->pDrawable) {
+ impedGetDrawableDeltas(pSrc->pDrawable, pSrcPixmap, &x_off, &y_off);
+ xSrc += x_off;
+ ySrc += y_off;
+ }
+
+ if (pMask) {
+ impedGetDrawableDeltas(pMask->pDrawable, pMaskPixmap, &x_off, &y_off);
+ xMask += x_off;
+ yMask += y_off;
+ }
+
+ impedGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &x_off, &y_off);
+ xDst += x_off;
+ yDst += y_off;
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PictureScreenPtr drv_ps;
+ RegionRec orig_src_region, orig_mask_region, orig_dst_region;
+
+ if (pSrc->pDrawable)
+ pDrvSrc = pSrc->gpu[i];
+ else
+ pDrvSrc = pSrc; /* solid/gradient pics */
+ if (pMask) {
+ pDrvMask = pMask->gpu[i];
+ }
+ pDrvDst = pDst->gpu[i];
+ if (pSrcPixmap)
+ pDrvSrc->pDrawable = &pSrcPixmap->gpu[i]->drawable;
+ if (pDrvMask)
+ pDrvMask->pDrawable = &pMaskPixmap->gpu[i]->drawable;
+ pDrvDst->pDrawable = &pDstPixmap->gpu[i]->drawable;
+
+ drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ drv_ps->Composite(op, pDrvSrc, pDrvMask, pDrvDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+
+ }
+}
+
+static void
+impedRasterizeTrapezoid (PicturePtr pPicture,
+ xTrapezoid *trap,
+ int x_off,
+ int y_off)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PixmapPtr pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+ PicturePtr pDrvPicture;
+ PictureScreenPtr drv_ps;
+ int i;
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ pDrvPicture = pPicture->gpu[i];
+ pDrvPicture->pDrawable = &pPixmap->gpu[i]->drawable;
+
+ drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ drv_ps->RasterizeTrapezoid(pDrvPicture, trap, x_off, y_off);
+ }
+}
+
+static void
+impedAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps)
+{
+ PictureScreenPtr drv_ps;
+ PixmapPtr pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PicturePtr pDrvPicture;
+ int i;
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ pDrvPicture = pPicture->gpu[i];
+ pDrvPicture->pDrawable = &pPixmap->gpu[i]->drawable;
+
+ drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ drv_ps->AddTraps(pDrvPicture, x_off, y_off, ntrap, traps);
+ }
+}
+
+static void
+impedTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntrap,
+ xTrapezoid *traps)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
+ PixmapPtr pSrcPixmap = NULL, pDstPixmap;
+ int i;
+ int x_off, y_off;
+ Bool ret;
+ xTrapezoid *orig_traps;
+
+ miCompositeSourceValidate (pSrc);
+ if (pSrc) {
+ if (pSrc->pDrawable) {
+ pSrcPixmap = GetDrawablePixmap(pSrc->pDrawable);
+ impedGetDrawableDeltas(pSrc->pDrawable, pSrcPixmap, &x_off, &y_off);
+ xSrc += x_off;
+ ySrc += y_off;
+ }
+ }
+
+ pDstPixmap = GetDrawablePixmap(pDst->pDrawable);
+ impedGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &x_off, &y_off);
+ if (x_off || y_off) {
+ for (i = 0; i < ntrap; i++) {
+ traps[i].top += y_off << 16;
+ traps[i].bottom += y_off << 16;
+ traps[i].left.p1.x += x_off << 16;
+ traps[i].left.p1.y += y_off << 16;
+ traps[i].left.p2.x += x_off << 16;
+ traps[i].left.p2.y += y_off << 16;
+ traps[i].right.p1.x += x_off << 16;
+ traps[i].right.p1.y += y_off << 16;
+ traps[i].right.p2.x += x_off << 16;
+ traps[i].right.p2.y += y_off << 16;
+ }
+ }
+ orig_traps = malloc(ntrap * sizeof(xTrapezoid));
+ if (!orig_traps)
+ return;
+
+ memcpy(orig_traps, traps, ntrap * sizeof(xTrapezoid));
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PictureScreenPtr drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ PicturePtr pDrvSrc = NULL, pDrvDst;
+
+ if (pSrc) {
+ if (pSrc->pDrawable)
+ pDrvSrc = pSrc->gpu[i];
+ else
+ pDrvSrc = pSrc; /* source pict */
+ if (pSrcPixmap)
+ pDrvSrc->pDrawable = &pSrcPixmap->gpu[i]->drawable;
+ if (pDrvSrc) {
+ }
+ }
+ pDrvDst = pDst->gpu[i];
+ pDrvDst->pDrawable = &pDstPixmap->gpu[i]->drawable;
+ memcpy(traps, orig_traps, ntrap * sizeof(xTrapezoid));
+ drv_ps->Trapezoids(op, pDrvSrc, pDrvDst, maskFormat, xSrc, ySrc, ntrap, traps);
+ }
+ free(orig_traps);
+}
+
+static void
+impedAddTriangles (PicturePtr pPicture,
+ INT16 x_off_orig,
+ INT16 y_off_orig,
+ int ntri,
+ xTriangle *tris)
+{
+ int x_off, y_off;
+ PixmapPtr pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ int i;
+
+ impedGetDrawableDeltas(pPicture->pDrawable, pPixmap, &x_off, &y_off);
+ x_off_orig += x_off;
+ y_off_orig += y_off;
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PictureScreenPtr drv_ps;
+ PicturePtr pDrvPicture;
+
+ pDrvPicture = pPicture->gpu[i];
+ pDrvPicture->pDrawable = &pPixmap->gpu[i]->drawable;
+ drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ drv_ps->AddTriangles(pDrvPicture, x_off_orig, y_off_orig, ntri, tris);
+ }
+}
+
+static void
+impedTriangles (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int ntris,
+ xTriangle *tris)
+{
+ int x_off, y_off, i;
+ PixmapPtr pSrcPixmap, pDstPixmap;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ xTriangle *orig_tris;
+
+ miCompositeSourceValidate (pSrc);
+
+ pSrcPixmap = GetDrawablePixmap(pSrc->pDrawable);
+ impedGetDrawableDeltas(pSrc->pDrawable, pSrcPixmap, &x_off, &y_off);
+ xSrc += x_off;
+ ySrc += y_off;
+
+ pDstPixmap = GetDrawablePixmap(pDst->pDrawable);
+ impedGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &x_off, &y_off);
+ if (x_off || y_off) {
+ for (i = 0; i < ntris; i++) {
+ tris[i].p1.x += x_off << 16;
+ tris[i].p1.y += y_off << 16;
+ tris[i].p2.x += x_off << 16;
+ tris[i].p2.y += y_off << 16;
+ tris[i].p3.x += x_off << 16;
+ tris[i].p3.y += y_off << 16;
+ }
+ }
+ orig_tris = malloc(ntris * sizeof(xTriangle));
+ if (!orig_tris)
+ return;
+
+ memcpy(orig_tris, tris, ntris * sizeof(xTriangle));
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PictureScreenPtr drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ PicturePtr pDrvSrc = NULL, pDrvDst;
+
+ pDrvSrc = pSrc->gpu[i];
+ pDrvSrc->pDrawable = &pSrcPixmap->gpu[i]->drawable;
+ pDrvDst = pDst->gpu[i];
+ pDrvDst->pDrawable = &pDstPixmap->gpu[i]->drawable;
+
+ memcpy(tris, orig_tris, ntris * sizeof(xTriangle));
+ drv_ps->Triangles(op, pDrvSrc, pDrvDst, maskFormat, xSrc, ySrc, ntris, tris);
+ }
+ free(orig_tris);
+}
+
+static void
+impedGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlists,
+ GlyphListPtr lists,
+ GlyphPtr *glyphs)
+{
+ PixmapPtr pSrcPixmap, pDstPixmap;
+ int x_off, y_off;
+ int i;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ pSrcPixmap = GetDrawablePixmap(pSrc->pDrawable);
+ impedGetDrawableDeltas(pSrc->pDrawable, pSrcPixmap, &x_off, &y_off);
+ xSrc += x_off;
+ ySrc += y_off;
+
+ pDstPixmap = GetDrawablePixmap(pDst->pDrawable);
+ impedGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &x_off, &y_off);
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PictureScreenPtr drv_ps = GetPictureScreen(pScreen->gpu[i]);
+ PicturePtr pDrvSrc = NULL, pDrvDst;
+ pDrvSrc = pSrc->gpu[i];
+ pDrvSrc->pDrawable = &pSrcPixmap->gpu[i]->drawable;
+ pDrvDst = pDst->gpu[i];
+ pDrvDst->pDrawable = &pDstPixmap->gpu[i]->drawable;
+
+ drv_ps->Glyphs(op, pDrvSrc, pDrvDst, maskFormat, xSrc, ySrc, nlists, lists, glyphs);
+ }
+}
+
+static void
+impedChangeOnePicture(PicturePtr pPicture, PicturePtr pChild, int index, Mask mask)
+{
+ Mask maskQ;
+ BITS32 index2;
+
+ maskQ = mask;
+ while (mask) {
+ index2 = (BITS32) lowbit(mask);
+ mask &= ~index2;
+ pChild->stateChanges |= index2;
+ switch (index2) {
+ case CPRepeat:
+ pChild->repeat = pPicture->repeat;
+ pChild->repeatType = pPicture->repeatType;
+ break;
+ case CPAlphaMap:
+ if (pPicture->alphaMap)
+ pChild->alphaMap = pPicture->alphaMap->gpu[index];
+ else
+ pChild->alphaMap = NULL;
+ break;
+ case CPAlphaXOrigin:
+ pChild->alphaOrigin.x = pPicture->alphaOrigin.x;
+ break;
+ case CPAlphaYOrigin:
+ pChild->alphaOrigin.y = pPicture->alphaOrigin.y;
+ break;
+ case CPClipXOrigin:
+ pChild->clipOrigin.x = pPicture->clipOrigin.x;
+ break;
+ case CPClipYOrigin:
+ pChild->clipOrigin.y = pPicture->clipOrigin.y;
+ break;
+ case CPClipMask:
+ /* TODO */
+ break;
+ case CPGraphicsExposure:
+ pChild->graphicsExposures = pPicture->graphicsExposures;
+ break;
+ case CPSubwindowMode:
+ pChild->subWindowMode = pPicture->subWindowMode;
+ break;
+ case CPPolyEdge:
+ pChild->polyEdge = pPicture->polyEdge;
+ break;
+ case CPPolyMode:
+ pChild->polyMode = pPicture->polyMode;
+ break;
+ case CPDither:
+ break;
+ case CPComponentAlpha:
+ pChild->componentAlpha = pPicture->componentAlpha;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+impedChangePicture(PicturePtr pPicture, Mask mask)
+{
+ ScreenPtr pScreen;
+ int i;
+
+ if (!pPicture->pDrawable)
+ return;
+ if (!pPicture->gpu[i])
+ return;
+ pScreen = pPicture->pDrawable->pScreen;
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ impedChangeOnePicture(pPicture, pPicture->gpu[i], i, mask);
+ }
+}
+
+static int
+impedCreatePicture (PicturePtr pPicture)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ PictureScreenPtr ps;
+ int i;
+ PixmapPtr pPixmap;
+ int x_off = 0, y_off = 0;
+ int error;
+
+ ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+ pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+
+ xorg_list_add(&pPicture->member, &pScreen->picture_list);
+
+ /* have to translate the composite clip before syncing it */
+#ifdef COMPOSITE
+ if (pPicture->pCompositeClip && pPicture->pDrawable->type == DRAWABLE_WINDOW) {
+ x_off = -pPixmap->screen_x;
+ y_off = -pPixmap->screen_y;
+ RegionTranslate(pPicture->pCompositeClip, x_off, y_off);
+ }
+#endif
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ pPicture->gpu[i] = CreatePicture(0, &pPixmap->gpu[i]->drawable, pPicture->pFormat,
+ 0, 0, serverClient, &error);
+ if (!pPicture->gpu[i])
+ ErrorF("no gpu %d picture\n", i);
+ impedChangeOnePicture(pPicture, pPicture->gpu[i], i, 0xffffffff);
+ }
+#ifdef COMPOSITE
+ if (x_off || y_off) {
+ RegionTranslate(pPicture->pCompositeClip, -x_off, -y_off);
+ }
+#endif
+ return 0;
+}
+
+static void
+impedDestroyPicture(PicturePtr pPicture)
+{
+ int i;
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ xorg_list_del(&pPicture->member);
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ FreePicture(pPicture->gpu[i], 0);
+ pPicture->gpu[i] = NULL;
+ }
+ miDestroyPicture(pPicture);
+}
+
+static void
+impedValidatePicture(PicturePtr pPicture, Mask mask)
+{
+ int x_off, y_off;
+ int i;
+ ScreenPtr pScreen;
+ miValidatePicture(pPicture, mask);
+ /**/
+ if (!pPicture->pDrawable)
+ return;
+
+ pScreen = pPicture->pDrawable->pScreen;
+#ifdef COMPOSITE
+ if (pPicture->pCompositeClip && pPicture->pDrawable->type == DRAWABLE_WINDOW) {
+ PixmapPtr pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+ x_off = -pPixmap->screen_x;
+ y_off = -pPixmap->screen_y;
+ RegionTranslate(pPicture->pCompositeClip, x_off, y_off);
+ }
+#endif
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PicturePtr pDrvPicture = pPicture->gpu[i];
+ pDrvPicture->freeCompClip = TRUE;
+ if (!pDrvPicture->pCompositeClip)
+ pDrvPicture->pCompositeClip = RegionCreate(NullBox, 0);
+
+ if (pPicture->pCompositeClip)
+ RegionCopy(pDrvPicture->pCompositeClip, pPicture->pCompositeClip);
+ else
+ RegionNull(pDrvPicture->pCompositeClip);
+ }
+
+
+#ifdef COMPOSITE
+ if (x_off || y_off) {
+ RegionTranslate(pPicture->pCompositeClip, -x_off, -y_off);
+ }
+#endif
+}
+
+Bool
+impedPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+ PictureScreenPtr ps;
+ int i;
+
+ if (!miPictureInit (pScreen, formats, nformats))
+ return FALSE;
+
+ /* must get after pictureinit as privates could get reallocated. */
+ ps = GetPictureScreen(pScreen);
+
+ ps->CreatePicture = impedCreatePicture;
+ ps->ChangePicture = impedChangePicture;
+ ps->ValidatePicture = impedValidatePicture;
+ ps->Composite = impedComposite;
+ ps->RasterizeTrapezoid = impedRasterizeTrapezoid;
+ ps->AddTraps = impedAddTraps;
+ ps->Trapezoids = impedTrapezoids;
+ ps->AddTriangles = impedAddTriangles;
+ ps->Triangles = impedTriangles;
+ ps->Glyphs = impedGlyphs;
+ ps->DestroyPicture = impedDestroyPicture;
+
+ for (i = 0; i < pScreen->num_gpu; i++) {
+ PictureScreenPtr drvps = GetPictureScreenIfSet(pScreen->gpu[i]);
+ // if (drvps)
+ // drvps->parent = ps;
+ }
+
+ return TRUE;
+}
+
+void
+impedPictureDuplicate(PicturePtr pPicture, int new_gpu_index)
+{
+ PixmapPtr pPixmap;
+ int error;
+
+ pPixmap = GetDrawablePixmap(pPicture->pDrawable);
+ pPicture->gpu[new_gpu_index] = CreatePicture(0, &pPixmap->gpu[new_gpu_index]->drawable, pPicture->pFormat, 0, 0, serverClient, &error);
+}
+
diff --git a/render/picturestr.h b/render/picturestr.h
index dc00f41ff..98fc3b829 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -158,6 +158,10 @@ typedef struct _Picture {
SourcePictPtr pSourcePict;
xFixed *filter_params;
int filter_nparams;
+
+ struct xorg_list member;
+ PicturePtr gpu[4];
+
} PictureRec;
typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,