[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