[PATCH] Adding partial impedance layer code by airlied

check.nyah at gmail.com check.nyah at gmail.com
Wed Jul 30 11:52:47 PDT 2014


From: Ch3ck <Ch3ck at localhost.localdomain>

---
 drv/Makefile.am     |   11 +
 drv/imped.h         |  110 +++++++
 drv/imped_gc.c      |  872 +++++++++++++++++++++++++++++++++++++++++++++++++++
 drv/imped_pict.c    |  576 ++++++++++++++++++++++++++++++++++
 drv/imped_plug.c    |  169 ++++++++++
 drv/imped_scrn.c    |  535 +++++++++++++++++++++++++++++++
 include/pixmapstr.h |    2 +-
 7 files changed, 2274 insertions(+), 1 deletions(-)
 create mode 100644 drv/Makefile.am
 create mode 100644 drv/imped.h
 create mode 100644 drv/imped_gc.c
 create mode 100644 drv/imped_pict.c
 create mode 100644 drv/imped_plug.c
 create mode 100644 drv/imped_scrn.c

diff --git a/drv/Makefile.am b/drv/Makefile.am
new file mode 100644
index 0000000..cc7672c
--- /dev/null
+++ b/drv/Makefile.am
@@ -0,0 +1,11 @@
+noinst_LTLIBRARIES = libdrv.la
+
+SUBDIRS =
+
+AM_CFLAGS = $(DIX_CFLAGS)
+
+libdrv_la_SOURCES =     \
+	imped_scrn.c    \
+	imped_gc.c	\
+	imped_pict.c    \
+	imped_plug.c
diff --git a/drv/imped.h b/drv/imped.h
new file mode 100644
index 0000000..36ebaee
--- /dev/null
+++ b/drv/imped.h
@@ -0,0 +1,110 @@
+#ifndef IMPED_H
+#define IMPED_H
+
+#include "randrstr.h"
+#include "picturestr.h"
+
+extern _X_EXPORT Bool impedSetupScreen(ScreenPtr pScreen);
+
+extern _X_EXPORT Bool impedFinishScreenInit(ScreenPtr pScreen,
+                                            pointer pbits,
+                                            int         xsize,
+                                            int         ysize,
+                                            int         dpix,
+                                            int         dpiy,
+                                            int         width,
+                                            int         bpp);
+
+#define impedGetScreenPixmap(s)	((PixmapPtr) (s)->devPrivate)
+
+extern _X_EXPORT PixmapPtr
+ _impedGetWindowPixmap(WindowPtr pWindow);
+
+extern _X_EXPORT void
+ _impedSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap);
+
+extern _X_EXPORT Bool
+impedCreateGC(GCPtr pGC);
+
+extern _X_EXPORT void
+impedAttachUnboundScreen(ScreenPtr pScreen, ScreenPtr new);
+extern _X_EXPORT void
+impedDetachUnboundScreen(ScreenPtr pScreen, ScreenPtr slave);
+
+extern _X_EXPORT void
+impedAttachScreen(ScreenPtr pScreen, ScreenPtr slave);
+
+extern _X_EXPORT void
+impedAttachOutputSlave(ScreenPtr pScreen, ScreenPtr slave, int index);
+
+extern _X_EXPORT void
+impedAttachOffloadSlave(ScreenPtr pScreen, ScreenPtr slave, int index);
+
+extern _X_EXPORT void
+impedDetachOutputSlave(ScreenPtr pScreen, ScreenPtr slave);
+
+extern _X_EXPORT void
+impedDetachOffloadSlave(ScreenPtr pScreen, ScreenPtr slave);
+
+extern _X_EXPORT void
+impedMigrateOutputSlaves(ScreenPtr pOldMaster, ScreenPtr pNewMaster);
+
+extern _X_EXPORT void
+impedCopyNtoN (DrawablePtr	pSrcDrawable,
+	       DrawablePtr	pDstDrawable,
+	       GCPtr	pGC,
+	       BoxPtr	pbox,
+	       int		nbox,
+	       int		dx,
+	       int		dy,
+	       Bool	reverse,
+	       Bool	upsidedown,
+	       Pixel	bitplane,
+	       void	*closure);
+
+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
+}
+
+/* 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
+}
+
+extern _X_EXPORT Bool
+impedPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+extern _X_EXPORT void
+impedPictureDuplicate(PicturePtr pPicture, int new_gpu_index);
+
+extern _X_EXPORT int
+impedAddScreen(ScreenPtr protocol_master, ScreenPtr new);
+
+extern _X_EXPORT Bool
+impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave);
+
+extern _X_EXPORT Bool
+impedRandR12Init(ScreenPtr pScreen);
+
+Bool impedCheckPixmapBounding(ScreenPtr pScreen,
+			      RRCrtcPtr rr_crtc, int x, int y, int w, int h);
+#endif
diff --git a/drv/imped_gc.c b/drv/imped_gc.c
new file mode 100644
index 0000000..c7f34b8
--- /dev/null
+++ b/drv/imped_gc.c
@@ -0,0 +1,872 @@
+
+/* Impedance layer for GC ops
+   This provides an impedance layer between drawables and pixmaps
+   it reworks the operations
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "gcstruct.h"
+#include "migc.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "imped.h"
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "fb.h"
+
+static void setup_shatter_clip(RegionPtr orig_region, GCPtr pGC, PixmapPtr pPixmap)
+{
+    RegionRec pixclip;
+
+    /* adjust the composite clip */
+    PixmapRegionInit(&pixclip, pPixmap);
+
+    RegionNull(orig_region);
+    RegionCopy(orig_region, pGC->pCompositeClip);
+    RegionIntersect(pGC->pCompositeClip, orig_region, &pixclip);
+}
+
+static void finish_shatter_clip(RegionPtr orig_region, GCPtr pGC)
+{
+    RegionCopy(pGC->pCompositeClip, orig_region);
+    RegionUninit(orig_region);
+}
+
+#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) {						\
+            if (pPixmap->shattered) setup_shatter_clip(&orig_region, _pDrvGC, _pDrvPixmap); \
+            op;								\
+            opcpy;                                                      \
+            if (pPixmap->shattered) finish_shatter_clip(&orig_region, _pDrvGC); \
+            _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;
+    ScreenPtr iter;
+    xorg_list_del(&pGC->member);
+    i = 0;
+    xorg_list_for_each_entry(iter, &pGC->pScreen->gpu_screen_list, gpu_screen_head) {
+        FreeGC(pGC->gpu[i], 0);
+        pGC->gpu[i] = NULL;
+        i++;
+    }
+
+    // TODO destroy driver GC
+    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], pDstPixmap->gpu[i],
+	     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,
+};
+
+Bool
+impedCreateGC(GCPtr pGC)
+{
+    GCPtr gpugc;
+    ScreenPtr iter;
+    int i = 0;
+    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);
+
+    xorg_list_for_each_entry(iter, &pGC->pScreen->gpu_screen_list, gpu_screen_head) {
+        gpugc = NewGCObject(iter, pGC->depth);
+        pGC->gpu[i] = gpugc;
+        gpugc->parent = pGC;
+        ret = gpugc->pScreen->CreateGC(gpugc);
+        if (ret == FALSE)
+            return FALSE;
+        i++;
+    }
+
+    return TRUE;
+
+}
diff --git a/drv/imped_pict.c b/drv/imped_pict.c
new file mode 100644
index 0000000..396a167
--- /dev/null
+++ b/drv/imped_pict.c
@@ -0,0 +1,576 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "fb.h"
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "imped.h"
+
+static void setup_shatter_clip(RegionPtr orig_region, PicturePtr pDrvPicture)
+{
+    RegionRec pixclip;
+
+    /* adjust the composite clip */
+    PixmapRegionInit(&pixclip, pDrvPicture->pDrawable);
+
+    RegionNull(orig_region);
+    RegionCopy(orig_region, pDrvPicture->pCompositeClip);
+    RegionIntersect(pDrvPicture->pCompositeClip, orig_region, &pixclip);
+}
+
+static void finish_shatter_clip(RegionPtr orig_region, PicturePtr pDrvPicture)
+{
+    RegionCopy(pDrvPicture->pCompositeClip, orig_region);
+}
+
+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;
+
+#if 0
+	if (pSrcPixmap && imped_src_pixmap->shattered)
+	    setup_shatter_clip(&orig_src_region, pDrvSrc);
+	if (pDrvMask && imped_mask_pixmap->shattered)
+	    setup_shatter_clip(&orig_mask_region, pDrvMask);
+	if (imped_dst_pixmap->shattered)
+	    setup_shatter_clip(&orig_dst_region, pDrvDst);
+#endif
+	drv_ps = GetPictureScreen(pScreen->gpu[i]);
+	drv_ps->Composite(op, pDrvSrc, pDrvMask, pDrvDst,
+			  xSrc, ySrc, xMask, yMask,
+			  xDst, yDst, width, height);
+
+#if 0
+	if (imped_dst_pixmap->shattered)
+	    finish_shatter_clip(&orig_dst_region, pDrvDst);
+	if (pDrvMask && imped_mask_pixmap->shattered)
+	    finish_shatter_clip(&orig_mask_region, pDrvMask);
+	if (pSrcPixmap && imped_src_pixmap->shattered)
+	    finish_shatter_clip(&orig_src_region, pDrvSrc);
+#endif
+    }
+}
+
+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;
+
+//	if (imped_pixmap->shattered) ErrorF("%s: shattered picture\n", __func__);
+	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;
+
+//	if (imped_pixmap->shattered) ErrorF("%s: shattered picture\n", __func__);
+	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);
+	    //if (imped_src_pixmap->shattered) ErrorF("%s: shattered src picture\n", __func__);
+	    impedGetDrawableDeltas(pSrc->pDrawable, pSrcPixmap, &x_off, &y_off);
+	    xSrc += x_off;
+	    ySrc += y_off;
+	}
+    }
+    
+    pDstPixmap = GetDrawablePixmap(pDst->pDrawable);
+    //if (imped_dst_pixmap->shattered) ErrorF("%s: shattered dst picture\n", __func__);
+    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;
+	//if (imped_pixmap->shattered) ErrorF("%s: shattered picture\n", __func__);
+	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;
+	}
+    }
+    //if (imped_src_pixmap->shattered) ErrorF("%s: shattered src picture\n", __func__);
+    //if (imped_dst_pixmap->shattered) ErrorF("%s: shattered dst picture\n", __func__);
+
+    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);
+
+    //if (imped_src_pixmap->shattered) ErrorF("%s: shattered src picture\n", __func__);
+    //if (imped_dst_pixmap->shattered) ErrorF("%s: shattered dst picture\n", __func__);
+
+    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);
+        pPicture->gpu[i]->parent = pPicture;
+        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/drv/imped_plug.c b/drv/imped_plug.c
new file mode 100644
index 0000000..c443609
--- /dev/null
+++ b/drv/imped_plug.c
@@ -0,0 +1,169 @@
+/* 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 "gcstruct.h"
+#include "pixmapstr.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "imped.h"
+#include "randrstr.h"
+#include "mi.h"
+#include "micmap.h"
+
+static Bool
+dup_pixmap_contents(PixmapPtr pDst, PixmapPtr pSrc)
+{
+    char *image_ptr;
+    int size;
+    GCPtr pGC;
+
+    size = PixmapBytePad(pSrc->drawable.width, pSrc->drawable.depth) * pSrc->drawable.height;
+    image_ptr = malloc(size);
+
+    pSrc->drawable.pScreen->GetImage(&pSrc->drawable, 0, 0, pSrc->drawable.width,
+				     pSrc->drawable.height, ZPixmap, ~0,
+				     image_ptr);
+
+    pGC = GetScratchGC(pSrc->drawable.depth, pDst->drawable.pScreen);
+    pGC->stateChanges &= ~GCTile;
+
+    ValidateGC(&pDst->drawable, pGC);
+
+    pGC->ops->PutImage(&pDst->drawable, pGC, pDst->drawable.depth, 0, 0,
+		       pSrc->drawable.width, pSrc->drawable.height, 0,
+		       ZPixmap, image_ptr);
+
+    FreeScratchGC(pGC);
+    free(image_ptr);
+    return TRUE;
+}
+
+static void dup_pixmap(PixmapPtr pPixmap, ScreenPtr new, int new_gpu_idx)
+{
+    pPixmap->gpu[new_gpu_idx] = new->CreatePixmap(new, pPixmap->drawable.width,
+						  pPixmap->drawable.height,
+						  pPixmap->drawable.depth,
+						  pPixmap->usage_hint);
+
+    dup_pixmap_contents(pPixmap->gpu[new_gpu_idx], pPixmap->gpu[0]);
+}
+
+int
+impedAddScreen(ScreenPtr protocol_master, ScreenPtr new)
+{
+    int new_gpu_index;
+    int ret;
+
+    impedAttachScreen(protocol_master, new);
+
+    new_gpu_index = protocol_master->num_gpu - 1;
+    ErrorF("hot adding GPU %d\n", new_gpu_index);
+
+    {
+	GCPtr pGC;
+	xorg_list_for_each_entry(pGC, &protocol_master->gc_list, member) {
+	    pGC->gpu[new_gpu_index] = NewGCObject(new, pGC->depth);
+	    pGC->gpu[new_gpu_index]->parent = pGC;
+	    ret = new->CreateGC(pGC->gpu[new_gpu_index]);
+	    if (ret == FALSE)
+		ErrorF("failed to create GC\n");
+   	}
+    }
+
+    {
+	PixmapPtr pPixmap;
+	xorg_list_for_each_entry(pPixmap, &protocol_master->pixmap_list, member) {
+	    dup_pixmap(pPixmap, new, new_gpu_index);
+   	}
+    }
+
+    {
+	PicturePtr pPicture;
+	xorg_list_for_each_entry(pPicture, &protocol_master->picture_list, member) {
+	    impedPictureDuplicate(pPicture, new_gpu_index);
+   	}
+    }
+
+    /* set the screen pixmap up correctly */
+    {
+        PixmapPtr pPixmap;
+
+        pPixmap = protocol_master->GetScreenPixmap(protocol_master);
+
+        protocol_master->gpu[new_gpu_index]->SetScreenPixmap(pPixmap->gpu[new_gpu_index]);
+    }
+
+    return 0;
+}
+
+Bool
+impedRemoveScreen(ScreenPtr protocol_master, ScreenPtr slave)
+{
+    int remove_index = -1;
+    int i;
+
+    for (i = 0; i < protocol_master->num_gpu; i++) {
+	if (protocol_master->gpu[i] == slave){
+	    remove_index = i;
+	    break;
+	}
+    }
+    
+    if (remove_index == -1)
+	return FALSE;
+
+    ErrorF("ot removing GPU %d\n", remove_index);
+
+    {
+	PicturePtr pPicture;
+	xorg_list_for_each_entry(pPicture, &protocol_master->picture_list, member) {
+	    PicturePtr tofree = pPicture->gpu[remove_index];
+	    pPicture->gpu[remove_index] = NULL;
+	    for (i = remove_index ; i < protocol_master->num_gpu - 1; i++)
+		pPicture->gpu[i] = pPicture->gpu[i + 1];
+	    FreePicture(tofree, (XID)0);
+	}
+    }
+    {
+	GCPtr pGC;
+	xorg_list_for_each_entry(pGC, &protocol_master->gc_list, member) {
+	    GCPtr tofree = pGC->gpu[remove_index];
+	    pGC->serialNumber = NEXT_SERIAL_NUMBER;
+	    pGC->gpu[remove_index] = NULL;
+	    for (i = remove_index ; i < protocol_master->num_gpu - 1; i++)
+		pGC->gpu[i] = pGC->gpu[i + 1];
+	    FreeGC(tofree, 0);
+	}
+    }
+
+    {
+	PixmapPtr pPixmap;
+	xorg_list_for_each_entry(pPixmap, &protocol_master->pixmap_list, member) {
+	    PixmapPtr tofree = pPixmap->gpu[remove_index];
+	    pPixmap->gpu[remove_index] = NULL;
+	    for (i = remove_index ; i < protocol_master->num_gpu - 1; i++)
+		pPixmap->gpu[i] = pPixmap->gpu[i + 1];
+	    (*slave->DestroyPixmap)(tofree);
+	}
+    }
+
+    xorg_list_del(&slave->gpu_screen_head);
+    protocol_master->gpu[remove_index] = NULL;
+    for (i = remove_index; i < protocol_master->num_gpu - 1; i++)
+	protocol_master->gpu[i] = protocol_master->gpu[i + 1];
+
+    protocol_master->num_gpu--;
+
+    return TRUE;
+}
+
diff --git a/drv/imped_scrn.c b/drv/imped_scrn.c
new file mode 100644
index 0000000..83082ac
--- /dev/null
+++ b/drv/imped_scrn.c
@@ -0,0 +1,535 @@
+/* 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 "imped.h"
+#include "randrstr.h"
+#include "mi.h"
+#include "micmap.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()))
+
+static Bool
+impedAllocatePrivates(ScreenPtr pScreen)
+{
+    if (!dixRegisterPrivateKey(&impedWinPrivateKeyRec, PRIVATE_WINDOW, 0))
+        return FALSE;
+
+    return TRUE;
+}
+
+static Bool
+impedCreateScreenResources(ScreenPtr pScreen)
+{
+    ScreenPtr iter;
+    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);
+    i = 0;
+    xorg_list_for_each_entry(iter, &pScreen->gpu_screen_list, gpu_screen_head) {
+	iter->omghack = pPixmap->gpu[i];
+	i++;
+    }
+
+    xorg_list_for_each_entry(iter, &pScreen->gpu_screen_list, gpu_screen_head) {
+	ret = iter->CreateScreenResources(iter);
+    }
+
+
+    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);
+
+    {
+	ScreenPtr iter;
+        int i = 0;
+        xorg_list_for_each_entry(iter, &pScreen->gpu_screen_list, gpu_screen_head) {
+            pPixmap->gpu[i] = iter->CreatePixmap(iter, width, height, depth, usage_hint);
+            i++;
+        }
+    }
+    return pPixmap;
+}
+
+static Bool
+impedModifyPixmapHeader(PixmapPtr pPixmap, int w, int h, int d,
+                        int bpp, int devKind, pointer pPixData)
+{
+    ScreenPtr iter;
+    int i;
+    if (!pPixmap)
+	return FALSE;
+
+    miModifyPixmapHeader(pPixmap, w, h, d, bpp, devKind, pPixData);
+
+    i = 0;
+    xorg_list_for_each_entry(iter, &pPixmap->drawable.pScreen->gpu_screen_list, gpu_screen_head) {
+	iter->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;
+}
+
+static void 
+impedBlockHandler(ScreenPtr pScreen, pointer blockData, pointer pTimeout,
+                  pointer pReadmask)
+{
+    int i;
+    ScreenPtr master, slave;
+
+    for (i = 0; i < pScreen->num_gpu; i++) {
+	master = pScreen->gpu[i];
+
+	master->BlockHandler(master, blockData, pTimeout, pReadmask);
+	xorg_list_for_each_entry(slave, &master->offload_slave_list, offload_head) {
+	    slave->BlockHandler(slave, blockData, pTimeout, pReadmask);
+	}
+	xorg_list_for_each_entry(slave, &master->output_slave_list, output_head) {
+	    slave->BlockHandler(slave, blockData, pTimeout, pReadmask);
+	}
+    }
+}
+
+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);
+
+    xorg_list_init(&pScreen->gpu_screen_list);
+    /* protocol screen should have no offload/output slaves attached directly
+       to it they are attached to the respective masters - don't
+       init the lists so we spot failure */
+    xorg_list_init(&pScreen->unattached_list);
+    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;
+
+    //    imped_screen = impedGetScreen(pScreen); 
+    pScreen->ModifyPixmapHeader = impedModifyPixmapHeader;
+    pScreen->CreateScreenResources = impedCreateScreenResources;
+    pScreen->BlockHandler = impedBlockHandler;
+    //    imped_screen->SavedCloseScreen = pScreen->CloseScreen;
+    //    pScreen->CloseScreen = impedCloseScreen;
+
+    return TRUE;
+}
+
+/* attach a gpu screen to a list on the protocol screen of unbound screens */
+void
+impedAttachUnboundScreen(ScreenPtr pScreen, ScreenPtr new)
+{
+    assert(!pScreen->isGPU);
+    assert(new->isGPU);
+    xorg_list_add(&new->unattached_head, &pScreen->unattached_list);
+    new->protocol_master = pScreen;
+}
+
+void
+impedDetachUnboundScreen(ScreenPtr pScreen, ScreenPtr slave)
+{
+    xorg_list_del(&slave->unattached_head);
+    slave->protocol_master = NULL;
+}
+
+/* attach a gpu screen to a protocol screen */
+void
+impedAttachScreen(ScreenPtr pScreen, ScreenPtr slave)
+{
+    assert(!pScreen->isGPU);
+    assert(slave->isGPU);
+    xorg_list_add(&slave->gpu_screen_head, &pScreen->gpu_screen_list);
+    slave->protocol_master = pScreen;
+    pScreen->gpu[pScreen->num_gpu] = slave;
+    pScreen->num_gpu++;
+}
+
+/* attach a gpu screen as an output slave to another gpu screen */
+void
+impedAttachOutputSlave(ScreenPtr master, ScreenPtr slave, int index)
+{
+    assert(master->isGPU);
+    assert(slave->isGPU);
+    xorg_list_add(&slave->output_head, &master->output_slave_list);
+    slave->protocol_master = master->protocol_master;
+    slave->output_master = master;
+}
+
+/* attach a gpu screen as an offload slave to another gpu screen */
+void
+impedAttachOffloadSlave(ScreenPtr master, ScreenPtr slave, int index)
+{
+    assert(master->isGPU);
+    assert(slave->isGPU);
+    xorg_list_add(&slave->offload_head, &master->offload_slave_list);
+    slave->protocol_master = master->protocol_master;
+    slave->offload_master = master;
+}
+
+void
+impedDetachOutputSlave(ScreenPtr master, ScreenPtr slave)
+{
+    assert(master->isGPU);
+    assert(slave->isGPU);
+    xorg_list_del(&slave->output_head);
+    slave->output_master = NULL;
+    slave->protocol_master = NULL;
+}
+
+void
+impedDetachOffloadSlave(ScreenPtr master, ScreenPtr slave)
+{
+    assert(master->isGPU);
+    assert(slave->isGPU);
+    xorg_list_del(&slave->offload_head);
+    slave->offload_master = NULL;
+    slave->protocol_master = NULL;
+}
+
+void
+impedMigrateOutputSlaves(ScreenPtr pOldMaster, ScreenPtr pNewMaster)
+{
+    ScreenPtr iter, safe;
+
+    assert(pOldMaster->isGPU);
+    assert(pNewMaster->isGPU);
+
+    xorg_list_for_each_entry_safe(iter, safe, &pOldMaster->output_slave_list, output_head) {
+        if (iter == pNewMaster)
+            continue;
+        iter->output_master = pNewMaster;
+        xorg_list_del(&iter->output_head);
+        xorg_list_add(&iter->output_head, &pNewMaster->output_slave_list);
+    }
+}
+
+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;
+}
+
+Bool
+impedRandR12Init(ScreenPtr pScreen)
+{
+    rrScrPrivPtr rp;
+    if (!RRScreenInit(pScreen))
+        return FALSE;
+
+    rp = rrGetScrPriv(pScreen);
+    rp->rrScreenSetSize = impedScreenSetSize;
+
+    return TRUE;
+}
diff --git a/include/pixmapstr.h b/include/pixmapstr.h
index 702faf0..4149df2 100644
--- a/include/pixmapstr.h
+++ b/include/pixmapstr.h
@@ -1,4 +1,4 @@
-/***********************************************************
+a/***********************************************************
 
 Copyright 1987, 1998  The Open Group
 
-- 
1.7.1



More information about the xorg-devel mailing list