This consists of Dave airlied's current work on impedance layer; with imped_pict, imped_gc, imped_plug, imped_screen files.
I've not completely tested patch since i'm facing still facing dependencies probelems with compiling mesa hence X server.
From 8b50e535801d84cca23293d6f137fa6a95f496ec Mon Sep 17 00:00:00 2001 From: Ch3ck <[email protected]> Date: Wed, 30 Jul 2014 12:32:06 +0100 Subject: [PATCH] Adding partial impedance layer code by airlied --- 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
_______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
