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