コード例 #1
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
/**
 * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
 * current fill style.
 *
 * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
 * 1bpp and never in fb, so we don't worry about them.
 * We should worry about them for completeness sake and going forward.
 */
void
exaPrepareAccessGC(GCPtr pGC)
{
    if (pGC->stipple)
        exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
    if (pGC->fillStyle == FillTiled)
        exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
}
コード例 #2
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
                 BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
                 Bool upsidedown, Pixel bitplane, void *closure)
{
    RegionRec reg;
    int xoff, yoff;

    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
                  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));

    if (pExaScr->prepare_access_reg && RegionInitBoxes(&reg, pbox, nbox)) {
        PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);

        exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
        RegionTranslate(&reg, xoff + dx, yoff + dy);
        pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
        RegionUninit(&reg);
    }
    else
        exaPrepareAccess(pSrc, EXA_PREPARE_SRC);

    if (pExaScr->prepare_access_reg &&
        !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
                               pGC->alu, pGC->clientClipType) &&
        RegionInitBoxes(&reg, pbox, nbox)) {
        PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);

        exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
        RegionTranslate(&reg, xoff, yoff);
        pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
        RegionUninit(&reg);
    }
    else
        exaPrepareAccess(pDst, EXA_PREPARE_DEST);

    /* This will eventually call fbCopyNtoN, with some calculation overhead. */
    while (nbox--) {
        pGC->ops->CopyArea(pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx,
                           pbox->y1 - pSrc->y + dy, pbox->x2 - pbox->x1,
                           pbox->y2 - pbox->y1, pbox->x1 - pDst->x,
                           pbox->y1 - pDst->y);
        pbox++;
    }
    exaFinishAccess(pSrc, EXA_PREPARE_SRC);
    exaFinishAccess(pDst, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #3
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    DrawablePtr pDrawable = &pWin->drawable;
    ScreenPtr pScreen = pDrawable->pScreen;

    EXA_PRE_FALLBACK(pScreen);
    EXA_FALLBACK(("from %p\n", pWin));

    /* Only need the source bits, the destination region will be overwritten */
    if (pExaScr->prepare_access_reg) {
        PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
        int xoff, yoff;

        exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
        RegionTranslate(prgnSrc, xoff, yoff);
        pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
        RegionTranslate(prgnSrc, -xoff, -yoff);
    }
    else
        exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);

    swap(pExaScr, pScreen, CopyWindow);
    pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
    swap(pExaScr, pScreen, CopyWindow);
    exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
    EXA_POST_FALLBACK(pScreen);
}
コード例 #4
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
static void
ExaFallbackPrepareReg(DrawablePtr pDrawable,
                      GCPtr pGC,
                      int x, int y, int width, int height,
                      int index, Bool checkReads)
{
    ScreenPtr pScreen = pDrawable->pScreen;

    ExaScreenPriv(pScreen);

    if (pExaScr->prepare_access_reg &&
        !(checkReads && exaGCReadsDestination(pDrawable,
                                              pGC->planemask,
                                              pGC->fillStyle,
                                              pGC->alu, pGC->clientClipType))) {
        BoxRec box;
        RegionRec reg;
        int xoff, yoff;
        PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);

        exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
        box.x1 = pDrawable->x + x + xoff;
        box.y1 = pDrawable->y + y + yoff;
        box.x2 = box.x1 + width;
        box.y2 = box.y1 + height;

        RegionInit(&reg, &box, 1);
        pExaScr->prepare_access_reg(pPixmap, index, &reg);
        RegionUninit(&reg);
    }
    else
        exaPrepareAccess(pDrawable, index);
}
コード例 #5
0
/**
 * If the pixmap is currently dirty, this copies at least the dirty area from
 * the system memory copy to the framebuffer memory copy.  Both areas must be
 * allocated.
 */
static void
exaCopyDirtyToFb (PixmapPtr pPixmap)
{
    ExaScreenPriv (pPixmap->drawable.pScreen);
    ExaPixmapPriv (pPixmap);
    RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
    CARD8 *save_ptr;
    int save_pitch;
    BoxPtr pBox = REGION_RECTS(pRegion);
    int nbox = REGION_NUM_RECTS(pRegion);
    Bool do_sync = FALSE;

    save_ptr = pPixmap->devPrivate.ptr;
    save_pitch = pPixmap->devKind;
    pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    pPixmap->devKind = pExaPixmap->fb_pitch;

    while (nbox--) {
	pBox->x1 = max(pBox->x1, 0);
	pBox->y1 = max(pBox->y1, 0);
	pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
	pBox->y2 = min(pBox->y2, pPixmap->drawable.height);

	if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
	    continue;

	if (pExaScr->info->UploadToScreen == NULL ||
	    !pExaScr->info->UploadToScreen (pPixmap,
					    pBox->x1, pBox->y1,
					    pBox->x2 - pBox->x1,
					    pBox->y2 - pBox->y1,
					    pExaPixmap->sys_ptr
					    + pBox->y1 * pExaPixmap->sys_pitch
					    + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
					    pExaPixmap->sys_pitch))
	{
	    exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
	    exaMemcpyBox (pPixmap, pBox,
			  pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
			  pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
	    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
	}
	else
	    do_sync = TRUE;

	pBox++;
    }

    if (do_sync)
	exaMarkSync (pPixmap->drawable.pScreen);

    pPixmap->devPrivate.ptr = save_ptr;
    pPixmap->devKind = save_pitch;

    /* The previously damaged bits are now no longer damaged but valid */
    REGION_UNION(pPixmap->drawable.pScreen,
		 &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
    DamageEmpty (pExaPixmap->pDamage);
}
コード例 #6
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
                  DDXPointPtr pptInit)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, pptInit);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #7
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
                 DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #8
0
/**
 * If the pixmap has both a framebuffer and system memory copy, this function
 * asserts that both of them are the same.
 */
static Bool
exaAssertNotDirty (PixmapPtr pPixmap)
{
    ExaPixmapPriv (pPixmap);
    CARD8 *dst, *src;
    RegionPtr pValidReg = &pExaPixmap->validReg;
    int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
    BoxPtr pBox = REGION_RECTS(pValidReg);
    Bool ret = TRUE;

    if (pExaPixmap == NULL || pExaPixmap->fb_ptr == NULL)
	return ret;

    dst = pExaPixmap->sys_ptr;
    dst_pitch = pExaPixmap->sys_pitch;
    src = pExaPixmap->fb_ptr;
    src_pitch = pExaPixmap->fb_pitch;
    cpp = pPixmap->drawable.bitsPerPixel / 8;

    exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
    while (nbox--) {
	    int rowbytes;

	    pBox->x1 = max(pBox->x1, 0);
	    pBox->y1 = max(pBox->y1, 0);
	    pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
	    pBox->y2 = min(pBox->y2, pPixmap->drawable.height);

	    if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
		continue;

	    rowbytes = (pBox->x2 - pBox->x1) * cpp;
	    src += pBox->y1 * src_pitch + pBox->x1 * cpp;
	    dst += pBox->y1 * dst_pitch + pBox->x1 * cpp;

	    for (y = pBox->y2 - pBox->y1; y; y--) {
		if (memcmp(dst + pBox->y1 * dst_pitch + pBox->x1 * cpp,
			   src + pBox->y1 * src_pitch + pBox->x1 * cpp,
			   (pBox->x2 - pBox->x1) * cpp) != 0) {
		    ret = FALSE;
		    break;
		}
		src += src_pitch;
		dst += dst_pitch;
	    }
	    src -= pBox->y1 * src_pitch + pBox->x1 * cpp;
	    dst -= pBox->y1 * dst_pitch + pBox->x1 * cpp;
    }
    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);

    return ret;
}
コード例 #9
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));

    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    exaPrepareAccessGC(pGC);
    pGC->ops->PolyArc(pDrawable, pGC, narcs, pArcs);
    exaFinishAccessGC(pGC);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #10
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
                     int nrect, xRectangle *prect)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));

    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    exaPrepareAccessGC(pGC);
    pGC->ops->PolyFillRect(pDrawable, pGC, nrect, prect);
    exaFinishAccessGC(pGC);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #11
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
                      int x, int y, unsigned int nglyph,
                      CharInfoPtr * ppci, void *pglyphBase)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    exaPrepareAccessGC(pGC);
    pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
    exaFinishAccessGC(pGC);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #12
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
                    int nsegInit, xSegment * pSegInit)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
                  exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));

    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    exaPrepareAccessGC(pGC);
    pGC->ops->PolySegment(pDrawable, pGC, nsegInit, pSegInit);
    exaFinishAccessGC(pGC);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #13
0
ファイル: exa_unaccel.c プロジェクト: geekmaster/fread-ink
void
ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
		     int x, int y, unsigned int nglyph,
		     CharInfoPtr *ppci, pointer pglyphBase)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
		  exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
    exaPrepareAccessGC (pGC);
    pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
    exaFinishAccessGC (pGC);
    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #14
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckGetSpans(DrawablePtr pDrawable,
                 int wMax,
                 DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
{
    ScreenPtr pScreen = pDrawable->pScreen;

    EXA_PRE_FALLBACK(pScreen);
    EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
    swap(pExaScr, pScreen, GetSpans);
    pScreen->GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
    swap(pExaScr, pScreen, GetSpans);
    exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
    EXA_POST_FALLBACK(pScreen);
}
コード例 #15
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
                  int mode, int npt, DDXPointPtr ppt)
{
    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
                  pDrawable, exaDrawableLocation(pDrawable),
                  pGC->lineWidth, mode, npt));

    exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
    exaPrepareAccessGC(pGC);
    pGC->ops->Polylines(pDrawable, pGC, mode, npt, ppt);
    exaFinishAccessGC(pGC);
    exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #16
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckAddTraps(PicturePtr pPicture,
                 INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
{
    ScreenPtr pScreen = pPicture->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);

    EXA_PRE_FALLBACK(pScreen);

    EXA_FALLBACK(("to pict %p (%c)\n",
                  exaDrawableLocation(pPicture->pDrawable)));
    exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
    swap(pExaScr, ps, AddTraps);
    ps->AddTraps(pPicture, x_off, y_off, ntrap, traps);
    swap(pExaScr, ps, AddTraps);
    exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK(pScreen);
}
コード例 #17
0
ファイル: exa_unaccel.c プロジェクト: geekmaster/fread-ink
void
ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
		 int x, int y, int w, int h, int leftPad, int format,
		 char *bits)
{
    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
    ExaPixmapPriv(pPixmap);

    EXA_PRE_FALLBACK_GC(pGC);
    EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
    if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
	exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
			      pGC->alu, pGC->clientClipType))
	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
    else
	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
				    DamagePendingRegion(pExaPixmap->pDamage));
    pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
    exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
    EXA_POST_FALLBACK_GC(pGC);
}
コード例 #18
0
ファイル: exa.c プロジェクト: miettal/armadillo420_standard
/**
 * exaValidateGC() sets the ops to EXA's implementations, which may be
 * accelerated or may sync the card and fall back to fb.
 */
static void
exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    /* fbValidateGC will do direct access to pixmaps if the tiling has changed.
     * Preempt fbValidateGC by doing its work and masking the change out, so
     * that we can do the Prepare/FinishAccess.
     */
#ifdef FB_24_32BIT
    if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) {
	(*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
	fbGetRotatedPixmap(pGC) = 0;
    }
	
    if (pGC->fillStyle == FillTiled) {
	PixmapPtr	pOldTile, pNewTile;

	pOldTile = pGC->tile.pixmap;
	if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
	{
	    pNewTile = fbGetRotatedPixmap(pGC);
	    if (!pNewTile ||
		pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel)
	    {
		if (pNewTile)
		    (*pGC->pScreen->DestroyPixmap) (pNewTile);
		/* fb24_32ReformatTile will do direct access of a newly-
		 * allocated pixmap.  This isn't a problem yet, since we don't
		 * put pixmaps in FB until at least one accelerated EXA op.
		 */
		exaPrepareAccess(&pOldTile->drawable, EXA_PREPARE_SRC);
		pNewTile = fb24_32ReformatTile (pOldTile,
						pDrawable->bitsPerPixel);
		exaPixmapDirty(pNewTile, 0, 0, pNewTile->drawable.width, pNewTile->drawable.height);
		exaFinishAccess(&pOldTile->drawable, EXA_PREPARE_SRC);
	    }
	    if (pNewTile)
	    {
		fbGetRotatedPixmap(pGC) = pOldTile;
		pGC->tile.pixmap = pNewTile;
		changes |= GCTile;
	    }
	}
    }
#endif
    if (changes & GCTile) {
	if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
					     pDrawable->bitsPerPixel))
	{
	    /* XXX This fixes corruption with tiled pixmaps, but may just be a
	     * workaround for broken drivers
	     */
	    exaMoveOutPixmap(pGC->tile.pixmap);
	    fbPadPixmap (pGC->tile.pixmap);
	    exaPixmapDirty(pGC->tile.pixmap, 0, 0,
			   pGC->tile.pixmap->drawable.width,
			   pGC->tile.pixmap->drawable.height);
	}
	/* Mask out the GCTile change notification, now that we've done FB's
	 * job for it.
	 */
	changes &= ~GCTile;
    }

    fbValidateGC (pGC, changes, pDrawable);

    pGC->ops = (GCOps *) &exaOps;
}
コード例 #19
0
ファイル: exa_classic.c プロジェクト: AmesianX/xorg-server
/**
 * exaCreatePixmap() creates a new pixmap.
 *
 * If width and height are 0, this won't be a full-fledged pixmap and it will
 * get ModifyPixmapHeader() called on it later.  So, we mark it as pinned, because
 * ModifyPixmapHeader() would break migration.  These types of pixmaps are used
 * for scratch pixmaps, or to represent the visible screen.
 */
PixmapPtr
exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
                        unsigned usage_hint)
{
    PixmapPtr pPixmap;
    ExaPixmapPrivPtr pExaPixmap;
    BoxRec box;
    int bpp;

    ExaScreenPriv(pScreen);

    if (w > 32767 || h > 32767)
        return NullPixmap;

    swap(pExaScr, pScreen, CreatePixmap);
    pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
    swap(pExaScr, pScreen, CreatePixmap);

    if (!pPixmap)
        return NULL;

    pExaPixmap = ExaGetPixmapPriv(pPixmap);
    pExaPixmap->driverPriv = NULL;

    bpp = pPixmap->drawable.bitsPerPixel;

    pExaPixmap->driverPriv = NULL;
    /* Scratch pixmaps may have w/h equal to zero, and may not be
     * migrated.
     */
    if (!w || !h)
        pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
    else
        pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;

    pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
    pExaPixmap->sys_pitch = pPixmap->devKind;

    pPixmap->devPrivate.ptr = NULL;
    pExaPixmap->use_gpu_copy = FALSE;

    pExaPixmap->fb_ptr = NULL;
    exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
    pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;

    if (pExaPixmap->fb_pitch > 131071) {
        swap(pExaScr, pScreen, DestroyPixmap);
        pScreen->DestroyPixmap(pPixmap);
        swap(pExaScr, pScreen, DestroyPixmap);
        return NULL;
    }

    /* Set up damage tracking */
    pExaPixmap->pDamage = DamageCreate(NULL, NULL,
                                       DamageReportNone, TRUE,
                                       pScreen, pPixmap);

    if (pExaPixmap->pDamage == NULL) {
        swap(pExaScr, pScreen, DestroyPixmap);
        pScreen->DestroyPixmap(pPixmap);
        swap(pExaScr, pScreen, DestroyPixmap);
        return NULL;
    }

    DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
    /* This ensures that pending damage reflects the current operation. */
    /* This is used by exa to optimize migration. */
    DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);

    pExaPixmap->area = NULL;

    /* We set the initial pixmap as completely valid for a simple reason.
     * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which
     * could form single pixel rects as part of a region. Setting the complete region
     * as valid is a natural defragmentation of the region.
     */
    box.x1 = 0;
    box.y1 = 0;
    box.x2 = w;
    box.y2 = h;
    RegionInit(&pExaPixmap->validSys, &box, 0);
    RegionInit(&pExaPixmap->validFB, &box, 0);

    exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);

    /* During a fallback we must prepare access. */
    if (pExaScr->fallback_counter)
        exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);

    return pPixmap;
}
コード例 #20
0
/**
 * If the pixmap is currently dirty, this copies at least the dirty area from
 * the framebuffer  memory copy to the system memory copy.  Both areas must be
 * allocated.
 */
static void
exaCopyDirtyToSys (PixmapPtr pPixmap)
{
    ExaScreenPriv (pPixmap->drawable.pScreen);
    ExaPixmapPriv (pPixmap);
    RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
    CARD8 *save_ptr;
    int save_pitch;
    BoxPtr pBox = REGION_RECTS(pRegion);
    int nbox = REGION_NUM_RECTS(pRegion);
    Bool do_sync = FALSE;

    save_ptr = pPixmap->devPrivate.ptr;
    save_pitch = pPixmap->devKind;
    pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    pPixmap->devKind = pExaPixmap->fb_pitch;

    while (nbox--) {
	pBox->x1 = max(pBox->x1, 0);
	pBox->y1 = max(pBox->y1, 0);
	pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
	pBox->y2 = min(pBox->y2, pPixmap->drawable.height);

	if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
	    continue;

	if (pExaScr->info->DownloadFromScreen == NULL ||
	    !pExaScr->info->DownloadFromScreen (pPixmap,
						pBox->x1, pBox->y1,
						pBox->x2 - pBox->x1,
						pBox->y2 - pBox->y1,
						pExaPixmap->sys_ptr
						+ pBox->y1 * pExaPixmap->sys_pitch
						+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
						pExaPixmap->sys_pitch))
	{
	    exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
	    exaMemcpyBox (pPixmap, pBox,
			  pExaPixmap->fb_ptr, pExaPixmap->fb_pitch,
			  pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
	    exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
	}
	else
	    do_sync = TRUE;

	pBox++;
    }

    /* Make sure the bits have actually landed, since we don't necessarily sync
     * when accessing pixmaps in system memory.
     */
    if (do_sync)
	exaWaitSync (pPixmap->drawable.pScreen);

    pPixmap->devPrivate.ptr = save_ptr;
    pPixmap->devKind = save_pitch;

    /* The previously damaged bits are now no longer damaged but valid */
    REGION_UNION(pPixmap->drawable.pScreen,
		 &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
    DamageEmpty (pExaPixmap->pDamage);
}
コード例 #21
0
ファイル: exa_unaccel.c プロジェクト: MrKepzie/xserver
void
ExaCheckComposite(CARD8 op,
                  PicturePtr pSrc,
                  PicturePtr pMask,
                  PicturePtr pDst,
                  INT16 xSrc,
                  INT16 ySrc,
                  INT16 xMask,
                  INT16 yMask,
                  INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
    ScreenPtr pScreen = pDst->pDrawable->pScreen;
    PictureScreenPtr ps = GetPictureScreen(pScreen);

    EXA_PRE_FALLBACK(pScreen);

    if (pExaScr->prepare_access_reg) {
        if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
                                    ySrc, xMask, yMask, xDst, yDst, width,
                                    height))
            goto out_no_clip;
    }
    else {

        /* We need to prepare access to any separate alpha maps first,
         * in case the driver doesn't support EXA_PREPARE_AUX*,
         * in which case EXA_PREPARE_SRC may be used for moving them out.
         */

        if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
            exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
        if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
            exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
        if (pDst->alphaMap && pDst->alphaMap->pDrawable)
            exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);

        exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST);

        EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));

        if (pSrc->pDrawable != NULL)
            exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
        if (pMask && pMask->pDrawable != NULL)
            exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK);
    }

    swap(pExaScr, ps, Composite);
    ps->Composite(op,
                  pSrc,
                  pMask,
                  pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
    swap(pExaScr, ps, Composite);
    if (pMask && pMask->pDrawable != NULL)
        exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK);
    if (pSrc->pDrawable != NULL)
        exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
    exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST);
    if (pDst->alphaMap && pDst->alphaMap->pDrawable)
        exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
        exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
        exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);

 out_no_clip:
    EXA_POST_FALLBACK(pScreen);
}