コード例 #1
0
/**
 * For the "greedy" migration scheme, pushes the pixmap toward being located in
 * system memory.
 */
static void
exaMigrateTowardSys(ExaMigrationPtr migrate)
{
    PixmapPtr pPixmap = migrate->pPix;

    ExaPixmapPriv(pPixmap);

    DBG_MIGRATE(("UseMem: %p score %d\n", (pointer) pPixmap,
                 pExaPixmap->score));

    if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
        return;

    if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT)
        pExaPixmap->score = 0;

    if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN)
        pExaPixmap->score--;

    if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
        exaDoMoveOutPixmap(migrate);

    if (exaPixmapHasGpuCopy(pPixmap)) {
        exaCopyDirtyToFb(migrate);
        ExaOffscreenMarkUsed(pPixmap);
    }
    else
        exaCopyDirtyToSys(migrate);
}
コード例 #2
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;
}
コード例 #3
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);
    }
}
コード例 #4
0
/**
 * For the "greedy" migration scheme, pushes the pixmap toward being located in
 * framebuffer memory.
 */
static void
exaMigrateTowardFb(ExaMigrationPtr migrate)
{
    PixmapPtr pPixmap = migrate->pPix;

    ExaPixmapPriv(pPixmap);

    if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
        DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
                     (pointer) pPixmap));
        return;
    }

    DBG_MIGRATE(("UseScreen %p score %d\n",
                 (pointer) pPixmap, pExaPixmap->score));

    if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
        exaDoMoveInPixmap(migrate);
        pExaPixmap->score = 0;
    }

    if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
        pExaPixmap->score++;

    if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
            !exaPixmapHasGpuCopy(pPixmap)) {
        exaDoMoveInPixmap(migrate);
    }

    if (exaPixmapHasGpuCopy(pPixmap)) {
        exaCopyDirtyToFb(migrate);
        ExaOffscreenMarkUsed(pPixmap);
    }
    else
        exaCopyDirtyToSys(migrate);
}