Exemplo n.º 1
0
void
exaGlyphsInit(ScreenPtr pScreen)
{
    ExaScreenPriv(pScreen);
    int i = 0;

    memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches));

    pExaScr->glyphCaches[i].format = PICT_a8;
    pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
        16;
    i++;
    pExaScr->glyphCaches[i].format = PICT_a8;
    pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
        32;
    i++;
    pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
    pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
        16;
    i++;
    pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
    pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
        32;
    i++;

    assert(i == EXA_NUM_GLYPH_CACHES);

    for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
        pExaScr->glyphCaches[i].columns =
            CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth;
        pExaScr->glyphCaches[i].size = 256;
        pExaScr->glyphCaches[i].hashSize = 557;
    }
}
Exemplo n.º 2
0
/**
 * Ejects all offscreen areas, and uninitializes the offscreen memory manager.
 */
void
ExaOffscreenSwapOut (ScreenPtr pScreen)
{
    ExaScreenPriv (pScreen);

    ExaOffscreenValidate (pScreen);
    /* loop until a single free area spans the space */
    for (;;)
    {
	ExaOffscreenArea *area = pExaScr->info->offScreenAreas;

	if (!area)
	    break;
	if (area->state == ExaOffscreenAvail)
	{
	    area = area->next;
	    if (!area)
		break;
	}
	assert (area->state != ExaOffscreenAvail);
	(void) ExaOffscreenKickOut (pScreen, area);
	ExaOffscreenValidate (pScreen);
    }
    ExaOffscreenValidate (pScreen);
    ExaOffscreenFini (pScreen);
}
Exemplo n.º 3
0
/** Ejects all pixmaps managed by EXA. */
static void
ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
{
    ExaScreenPriv (pScreen);

    ExaOffscreenValidate (pScreen);
    /* loop until a single free area spans the space */
    for (;;)
    {
	ExaOffscreenArea *area;

	for (area = pExaScr->info->offScreenAreas; area != NULL;
	     area = area->next)
	{
	    if (area->state == ExaOffscreenRemovable &&
		area->save == exaPixmapSave)
	    {
		(void) ExaOffscreenKickOut (pScreen, area);
		ExaOffscreenValidate (pScreen);
		break;
	    }
	}
	if (area == NULL)
	    break;
    }
    ExaOffscreenValidate (pScreen);
}
Exemplo n.º 4
0
static void
exaUnrealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
{
    ExaScreenPriv(pScreen);
    int i;

    for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
        ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];

        if (cache->format != format)
            continue;

        if (cache->picture) {
            FreePicture((pointer) cache->picture, (XID) 0);
            cache->picture = NULL;
        }

        free(cache->hashEntries);
        cache->hashEntries = NULL;

        free(cache->glyphs);
        cache->glyphs = NULL;
        cache->glyphCount = 0;
    }
}
Exemplo n.º 5
0
void
exaCopyNtoN(DrawablePtr pSrcDrawable,
            DrawablePtr pDstDrawable,
            GCPtr pGC,
            BoxPtr pbox,
            int nbox,
            int dx,
            int dy,
            Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
{
    ExaScreenPriv(pDstDrawable->pScreen);

    if (pExaScr->fallback_counter ||
        (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
        return;

    if (exaHWCopyNtoN
        (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
         upsidedown))
        return;

    /* This is a CopyWindow, it's cleaner to fallback at the original call. */
    if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) {
        pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
        return;
    }

    /* fallback */
    ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy,
                     reverse, upsidedown, bitplane, closure);
}
Exemplo n.º 6
0
/**
 * 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.
 */
static PixmapPtr
exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
    PixmapPtr		pPixmap;
    ExaPixmapPrivPtr	pExaPixmap;
    int			bpp;
    ExaScreenPriv(pScreen);

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

    pPixmap = fbCreatePixmap (pScreen, w, h, depth);
    if (!pPixmap)
	return NULL;
    pExaPixmap = ExaGetPixmapPriv(pPixmap);

    bpp = pPixmap->drawable.bitsPerPixel;

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

    pExaPixmap->area = NULL;

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

    pExaPixmap->fb_ptr = NULL;
    if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
	pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
    else
	pExaPixmap->fb_pitch = w * bpp / 8;
    pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
				     pExaScr->info->pixmapPitchAlign);
    pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;

    if (pExaPixmap->fb_pitch > 131071) {
	fbDestroyPixmap(pPixmap);
	return NULL;
    }

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

    if (pExaPixmap->pDamage == NULL) {
	fbDestroyPixmap (pPixmap);
	return NULL;
    }

    DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
    DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);

    /* None of the pixmap bits are valid initially */
    REGION_NULL(pScreen, &pExaPixmap->validReg);

    return pPixmap;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
static void
exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
             DDXPointPtr ppt)
{
    ExaScreenPriv(pDrawable->pScreen);
    int i;
    xRectangle *prect;

    /* If we can't reuse the current GC as is, don't bother accelerating the
     * points.
     */
    if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) {
        ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
        return;
    }

    prect = malloc(sizeof(xRectangle) * npt);
    for (i = 0; i < npt; i++) {
        prect[i].x = ppt[i].x;
        prect[i].y = ppt[i].y;
        if (i > 0 && mode == CoordModePrevious) {
            prect[i].x += prect[i - 1].x;
            prect[i].y += prect[i - 1].y;
        }
        prect[i].width = 1;
        prect[i].height = 1;
    }
    pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect);
    free(prect);
}
Exemplo n.º 9
0
/**
 * exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
 *
 * It deals with calling the driver's FinishAccess() only if necessary.
 */
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
    ScreenPtr	    pScreen = pDrawable->pScreen;
    ExaScreenPriv  (pScreen);
    PixmapPtr	    pPixmap;
    ExaPixmapPrivPtr pExaPixmap;

    pPixmap = exaGetDrawablePixmap (pDrawable);

    pExaPixmap = ExaGetPixmapPriv(pPixmap);

    /* Rehide pixmap pointer if we're doing that. */
    if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
	pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
    {
	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    }

    if (pExaScr->info->FinishAccess == NULL)
	return;

    if (!exaPixmapIsOffscreen (pPixmap))
	return;

    (*pExaScr->info->FinishAccess) (pPixmap, index);
}
Exemplo n.º 10
0
/**
 * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
 *
 * It deals with waiting for synchronization with the card, determining if
 * PrepareAccess() is necessary, and working around PrepareAccess() failure.
 */
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
    ScreenPtr	    pScreen = pDrawable->pScreen;
    ExaScreenPriv  (pScreen);
    PixmapPtr	    pPixmap;

    pPixmap = exaGetDrawablePixmap (pDrawable);

    if (exaPixmapIsOffscreen (pPixmap))
	exaWaitSync (pDrawable->pScreen);
    else
	return;

    /* Unhide pixmap pointer */
    if (pPixmap->devPrivate.ptr == NULL) {
	ExaPixmapPriv (pPixmap);

	pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    }

    if (pExaScr->info->PrepareAccess == NULL)
	return;

    if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
	ExaPixmapPriv (pPixmap);
	if (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED)
	    FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
	exaMoveOutPixmap (pPixmap);
    }
}
Exemplo n.º 11
0
static void
ExaSrcValidate(DrawablePtr pDrawable,
	       int x,
	       int y,
	       int width,
	       int height)
{
    ScreenPtr pScreen = pDrawable->pScreen;
    ExaScreenPriv(pScreen);
    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
    BoxRec box;
    RegionRec reg;
    RegionPtr dst;
    int xoff, yoff;

    exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);

    box.x1 = x + xoff;
    box.y1 = y + yoff;
    box.x2 = box.x1 + width;
    box.y2 = box.y1 + height;

    dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
	&pExaScr->maskReg;

    REGION_INIT(pScreen, &reg, &box, 1);
    REGION_UNION(pScreen, dst, dst, &reg);
    REGION_UNINIT(pScreen, &reg);

    if (pExaScr->SavedSourceValidate) {
        swap(pExaScr, pScreen, SourceValidate);
        pScreen->SourceValidate(pDrawable, x, y, width, height);
        swap(pExaScr, pScreen, SourceValidate);
    }
}
Exemplo n.º 12
0
/**
 * exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's
 * screen private, before calling down to the next CloseSccreen.
 */
static Bool
exaCloseScreen(int i, ScreenPtr pScreen)
{
    ExaScreenPriv(pScreen);
#ifdef RENDER
    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
#endif

    pScreen->CreateGC = pExaScr->SavedCreateGC;
    pScreen->CloseScreen = pExaScr->SavedCloseScreen;
    pScreen->GetImage = pExaScr->SavedGetImage;
    pScreen->GetSpans = pExaScr->SavedGetSpans;
    pScreen->PaintWindowBackground = pExaScr->SavedPaintWindowBackground;
    pScreen->PaintWindowBorder = pExaScr->SavedPaintWindowBorder;
    pScreen->CreatePixmap = pExaScr->SavedCreatePixmap;
    pScreen->DestroyPixmap = pExaScr->SavedDestroyPixmap;
    pScreen->CopyWindow = pExaScr->SavedCopyWindow;
#ifdef RENDER
    if (ps) {
	ps->Composite = pExaScr->SavedComposite;
	ps->Glyphs = pExaScr->SavedGlyphs;
	ps->Trapezoids = pExaScr->SavedTrapezoids;
    }
#endif

    xfree (pExaScr);

    return (*pScreen->CloseScreen) (i, pScreen);
}
Exemplo n.º 13
0
/**
 * exaOffscreenInit initializes the offscreen memory manager.
 *
 * @param pScreen current screen
 *
 * exaOffscreenInit is called by exaDriverInit to set up the memory manager for
 * the screen, if any offscreen memory is available.
 */
Bool
exaOffscreenInit (ScreenPtr pScreen)
{
    ExaScreenPriv (pScreen);
    ExaOffscreenArea *area;

    /* Allocate a big free area */
    area = xalloc (sizeof (ExaOffscreenArea));

    if (!area)
	return FALSE;

    area->state = ExaOffscreenAvail;
    area->base_offset = pExaScr->info->offScreenBase;
    area->offset = area->base_offset;
    area->size = pExaScr->info->memorySize - area->base_offset;
    area->save = NULL;
    area->next = NULL;
    area->score = 0;

    /* Add it to the free areas */
    pExaScr->info->offScreenAreas = area;

    ExaOffscreenValidate (pScreen);

    return TRUE;
}
Exemplo n.º 14
0
Bool
exaDestroyPixmap_classic(PixmapPtr pPixmap)
{
    ScreenPtr pScreen = pPixmap->drawable.pScreen;

    ExaScreenPriv(pScreen);
    Bool ret;

    if (pPixmap->refcnt == 1) {
        ExaPixmapPriv(pPixmap);

        exaDestroyPixmap(pPixmap);

        if (pExaPixmap->area) {
            DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
                        (void *) pPixmap->drawable.id,
                        ExaGetPixmapPriv(pPixmap)->area->offset,
                        pPixmap->drawable.width, pPixmap->drawable.height));
            /* Free the offscreen area */
            exaOffscreenFree(pPixmap->drawable.pScreen, pExaPixmap->area);
            pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
            pPixmap->devKind = pExaPixmap->sys_pitch;
        }
        RegionUninit(&pExaPixmap->validSys);
        RegionUninit(&pExaPixmap->validFB);
    }

    swap(pExaScr, pScreen, DestroyPixmap);
    ret = pScreen->DestroyPixmap(pPixmap);
    swap(pExaScr, pScreen, DestroyPixmap);

    return ret;
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
0
/**
 * exaDDXDriverInit is required by the top-level EXA module, and is used by
 * the xorg DDX to hook in its EnableDisableFB wrapper.  We don't need it, since
 * we won't be enabling/disabling the FB.
 */
void
exaDDXDriverInit(ScreenPtr pScreen)
{
    ExaScreenPriv(pScreen);

    pExaScr->migration = ExaMigrationSmart;
    pExaScr->checkDirtyCorrectness = TRUE;
}
Exemplo n.º 17
0
/**
 * exaWaitSync() ensures that all drawing has been completed.
 *
 * @param pScreen screen being synchronized.
 *
 * Calls down into the driver to ensure that all previous drawing has completed.
 * It should always be called before relying on the framebuffer contents
 * reflecting previous drawing, from a CPU perspective.
 */
void exaWaitSync(ScreenPtr pScreen)
{
    ExaScreenPriv(pScreen);

    if (pExaScr->info->needsSync && !pExaScr->swappedOut) {
        (*pExaScr->info->WaitMarker)(pScreen, pExaScr->info->lastMarker);
        pExaScr->info->needsSync = FALSE;
    }
}
Exemplo n.º 18
0
/**
 * exaMarkSync() should be called after any asynchronous drawing by the hardware.
 *
 * @param pScreen screen which drawing occurred on
 *
 * exaMarkSync() sets a flag to indicate that some asynchronous drawing has
 * happened and a WaitSync() will be necessary before relying on the contents of
 * offscreen memory from the CPU's perspective.  It also calls an optional
 * driver MarkSync() callback, the return value of which may be used to do partial
 * synchronization with the hardware in the future.
 */
void exaMarkSync(ScreenPtr pScreen)
{
    ExaScreenPriv(pScreen);

    pExaScr->info->needsSync = TRUE;
    if (pExaScr->info->MarkSync != NULL) {
        pExaScr->info->lastMarker = (*pExaScr->info->MarkSync)(pScreen);
    }
}
Exemplo n.º 19
0
/**
 * Allocates a framebuffer copy of the pixmap if necessary, and then copies
 * any necessary pixmap data into the framebuffer copy and points the pixmap at
 * it.
 *
 * Note that when first allocated, a pixmap will have FALSE dirty flag.
 * This is intentional because pixmap data starts out undefined.  So if we move
 * it in due to the first operation against it being accelerated, it will have
 * undefined framebuffer contents that we didn't have to upload.  If we do
 * moveouts (and moveins) after the first movein, then we will only have to copy
 * back and forth if the pixmap was written to after the last synchronization of
 * the two copies.  Then, at exaPixmapSave (when the framebuffer copy goes away)
 * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
 * all the data, since it's almost surely all valid now.
 */
static void
exaDoMoveInPixmap(ExaMigrationPtr migrate)
{
    PixmapPtr pPixmap = migrate->pPix;
    ScreenPtr pScreen = pPixmap->drawable.pScreen;

    ExaScreenPriv(pScreen);
    ExaPixmapPriv(pPixmap);

    /* If we're VT-switched away, no touching card memory allowed. */
    if (pExaScr->swappedOut)
        return;

    /* If we're not allowed to move, then fail. */
    if (exaPixmapIsPinned(pPixmap))
        return;

    /* Don't migrate in pixmaps which are less than 8bpp.  This avoids a lot of
     * fragility in EXA, and <8bpp is probably not used enough any more to care
     * (at least, not in acceleratd paths).
     */
    if (pPixmap->drawable.bitsPerPixel < 8)
        return;

    if (pExaPixmap->accel_blocked)
        return;

    if (pExaPixmap->area == NULL) {
        pExaPixmap->area =
            exaOffscreenAlloc(pScreen, pExaPixmap->fb_size,
                              pExaScr->info->pixmapOffsetAlign, FALSE,
                              exaPixmapSave, (pointer) pPixmap);
        if (pExaPixmap->area == NULL)
            return;

        pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase +
                             pExaPixmap->area->offset;
    }

    exaCopyDirtyToFb(migrate);

    if (exaPixmapHasGpuCopy(pPixmap))
        return;

    DBG_MIGRATE(("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
                 (ExaGetPixmapPriv(pPixmap)->area ?
                  ExaGetPixmapPriv(pPixmap)->area->offset : 0),
                 pPixmap->drawable.width,
                 pPixmap->drawable.height,
                 exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));

    pExaPixmap->use_gpu_copy = TRUE;

    pPixmap->devKind = pExaPixmap->fb_pitch;
    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
Exemplo n.º 20
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.
 */
void
exaCopyDirtyToFb(ExaMigrationPtr migrate)
{
    PixmapPtr pPixmap = migrate->pPix;

    ExaScreenPriv(pPixmap->drawable.pScreen);
    ExaPixmapPriv(pPixmap);

    exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
                 pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL);
}
Exemplo n.º 21
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.
 */
void
exaCopyDirtyToSys(ExaMigrationPtr migrate)
{
    PixmapPtr pPixmap = migrate->pPix;

    ExaScreenPriv(pPixmap->drawable.pScreen);
    ExaPixmapPriv(pPixmap);

    exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
                 pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC,
                 exaWaitSync);
}
Exemplo n.º 22
0
/**
 * exaPolySegment() checks if it can accelerate the lines as a group of
 * horizontal or vertical lines (rectangles), and uses existing rectangle fill
 * acceleration if so.
 */
static void
exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
{
    ExaScreenPriv(pDrawable->pScreen);
    xRectangle *prect;
    int i;

    /* Don't try to do wide lines or non-solid fill style. */
    if (pExaScr->fallback_counter || pGC->lineWidth != 0 ||
        pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) {
        ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
        return;
    }

    /* If we have any non-horizontal/vertical, fall back. */
    for (i = 0; i < nseg; i++) {
        if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
            ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
            return;
        }
    }

    prect = malloc(sizeof(xRectangle) * nseg);
    for (i = 0; i < nseg; i++) {
        if (pSeg[i].x1 < pSeg[i].x2) {
            prect[i].x = pSeg[i].x1;
            prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
        }
        else {
            prect[i].x = pSeg[i].x2;
            prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
        }
        if (pSeg[i].y1 < pSeg[i].y2) {
            prect[i].y = pSeg[i].y1;
            prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
        }
        else {
            prect[i].y = pSeg[i].y2;
            prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
        }

        /* don't paint last pixel */
        if (pGC->capStyle == CapNotLast) {
            if (prect[i].width == 1)
                prect[i].height--;
            else
                prect[i].width--;
        }
    }
    pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
    free(prect);
}
Exemplo n.º 23
0
void
ExaOffscreenFini (ScreenPtr pScreen)
{
    ExaScreenPriv (pScreen);
    ExaOffscreenArea *area;

    /* just free all of the area records */
    while ((area = pExaScr->info->offScreenAreas))
    {
	pExaScr->info->offScreenAreas = area->next;
	xfree (area);
    }
}
Exemplo n.º 24
0
void
exaGlyphsFini(ScreenPtr pScreen)
{
    ExaScreenPriv(pScreen);
    int i;

    for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
        ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];

        if (cache->picture)
            exaUnrealizeGlyphCaches(pScreen, cache->format);
    }
}
Exemplo n.º 25
0
void
exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
{
    int i;

    /* If anything is pinned in system memory, we won't be able to
     * accelerate.
     */
    for (i = 0; i < npixmaps; i++) {
        if (exaPixmapIsPinned(pixmaps[i].pPix) &&
            !exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
            can_accel = FALSE;
            break;
        }
    }

    /* We can do nothing. */
    if (!can_accel)
        return;

    for (i = 0; i < npixmaps; i++) {
        PixmapPtr pPixmap = pixmaps[i].pPix;

        ExaPixmapPriv(pPixmap);

        if (!pExaPixmap->driverPriv)
            exaCreateDriverPixmap_mixed(pPixmap);

        if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
            ExaScreenPriv(pPixmap->drawable.pScreen);

            /* This pitch is needed for proper acceleration. For some reason
             * there are pixmaps without pDamage and a bad fb_pitch value.
             * So setting devKind when only exaPixmapHasGpuCopy() is true
             * causes corruption. Pixmaps without pDamage are not migrated
             * and should have a valid devKind at all times, so that's why this
             * isn't causing problems. Pixmaps have their gpu pitch set the
             * first time in the MPH call from exaCreateDriverPixmap_mixed().
             */
            pPixmap->devKind = pExaPixmap->fb_pitch;
            exaCopyDirtyToFb(pixmaps + i);

            if (pExaScr->deferred_mixed_pixmap == pPixmap &&
                !pixmaps[i].as_dst && !pixmaps[i].pReg)
                pExaScr->deferred_mixed_pixmap = NULL;
        }

        pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
    }
}
Exemplo n.º 26
0
/**
 * exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
 * the beginning of the given pixmap.
 *
 * Note that drivers are free to, and often do, munge this offset as necessary
 * for handing to the hardware -- for example, translating it into a different
 * aperture.  This function may need to be extended in the future if we grow
 * support for having multiple card-accessible offscreen, such as an AGP memory
 * pool alongside the framebuffer pool.
 */
unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
    ExaScreenPriv (pPix->drawable.pScreen);
    ExaPixmapPriv (pPix);
    void *ptr;

    /* Return the offscreen pointer if we've hidden the data. */
    if (pPix->devPrivate.ptr == NULL)
	ptr = pExaPixmap->fb_ptr;
    else
	ptr = pPix->devPrivate.ptr;

    return ((unsigned long)ptr - (unsigned long)pExaScr->info->memoryBase);
}
Exemplo n.º 27
0
RegionPtr
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
            int srcx, int srcy, int width, int height, int dstx, int dsty)
{
    ExaScreenPriv(pDstDrawable->pScreen);

    if (pExaScr->fallback_counter || pExaScr->swappedOut) {
        return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
                                srcx, srcy, width, height, dstx, dsty);
    }

    return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
                    srcx, srcy, width, height,
                    dstx, dsty, exaCopyNtoN, 0, NULL);
}
Exemplo n.º 28
0
/**
 * Prepares EXA for disabling of FB access, or restoring it.
 *
 * In version 2.1, the disabling results in pixmaps being ejected, while other
 * allocations remain.  With this plus the prevention of migration while
 * swappedOut is set, EXA by itself should not cause any access of the
 * framebuffer to occur while swapped out.  Any remaining issues are the
 * responsibility of the driver.
 *
 * Prior to version 2.1, all allocations, including locked ones, are ejected
 * when access is disabled, and the allocator is torn down while swappedOut
 * is set.  This is more drastic, and caused implementation difficulties for
 * many drivers that could otherwise handle the lack of FB access while
 * swapped out.
 */
void
exaEnableDisableFBAccess (int index, Bool enable)
{
    ScreenPtr pScreen = screenInfo.screens[index];
    ExaScreenPriv (pScreen);

    if (!enable) {
	if (pExaScr->info->exa_minor < 1)
	    ExaOffscreenSwapOut (pScreen);
	else
	    ExaOffscreenEjectPixmaps (pScreen);
	pExaScr->swappedOut = TRUE;
    } else {
	if (pExaScr->info->exa_minor < 1)
	    ExaOffscreenSwapIn (pScreen);
	pExaScr->swappedOut = FALSE;
    }
}
Exemplo n.º 29
0
/**
 * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
 * memory, meaning that acceleration could probably be done to it, and that it
 * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
 * with the CPU.
 *
 * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly
 * deal with moving pixmaps in and out of system memory), EXA will give drivers
 * pixmaps as arguments for which exaPixmapIsOffscreen() is TRUE.
 *
 * @return TRUE if the given drawable is in framebuffer memory.
 */
Bool
exaPixmapIsOffscreen(PixmapPtr p)
{
    ScreenPtr	pScreen = p->drawable.pScreen;
    ExaScreenPriv(pScreen);

    /* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
     */
    if (p->devPrivate.ptr == NULL)
	return TRUE;

    if (pExaScr->info->PixmapIsOffscreen)
	return pExaScr->info->PixmapIsOffscreen(p);

    return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
			     (CARD8 *) pExaScr->info->memoryBase) <
	    pExaScr->info->memorySize);
}
Exemplo n.º 30
0
static void
ExaOffscreenValidate (ScreenPtr pScreen)
{
    ExaScreenPriv (pScreen);
    ExaOffscreenArea *prev = 0, *area;

    assert (pExaScr->info->offScreenAreas->base_offset == 
	    pExaScr->info->offScreenBase);
    for (area = pExaScr->info->offScreenAreas; area; area = area->next)
    {
	assert (area->offset >= area->base_offset &&
		area->offset < (area->base_offset + area->size));
	if (prev)
	    assert (prev->base_offset + prev->area.size == area->base_offset);
	prev = area;
    }
    assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
}