/** * 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); } }
static void GLAMOBlockHandler(pointer blockData, OSTimePtr timeout, pointer readmask) { ScreenPtr pScreen = (ScreenPtr) blockData; exaWaitSync(pScreen); }
/** * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. * * This is probably the only case we actually care about. The rest fall through * to migration and fbGetImage, which hopefully will result in migration pushing * the pixmap out of framebuffer. */ void exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ExaScreenPriv(pDrawable->pScreen); PixmapPtr pPix = exaGetDrawablePixmap(pDrawable); ExaPixmapPriv(pPix); int xoff, yoff; Bool ok; if (pExaScr->fallback_counter || pExaScr->swappedOut) goto fallback; /* If there's a system copy, we want to save the result there */ if (pExaPixmap->pDamage) goto fallback; pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff); if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL) goto fallback; /* Only cover the ZPixmap, solid copy case. */ if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) goto fallback; /* Only try to handle the 8bpp and up cases, since we don't want to think * about <8bpp. */ if (pDrawable->bitsPerPixel < 8) goto fallback; ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff, pDrawable->y + y + yoff, w, h, d, PixmapBytePad(w, pDrawable->depth)); if (ok) { exaWaitSync(pDrawable->pScreen); return; } fallback: ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d); }
/** * 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); }
/** * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. * * This is probably the only case we actually care about. The rest fall through * to migration and fbGetImage, which hopefully will result in migration pushing * the pixmap out of framebuffer. */ void exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ExaScreenPriv (pDrawable->pScreen); PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); int xoff, yoff; Bool ok; if (pExaScr->fallback_counter || pExaScr->swappedOut) goto fallback; exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff); if (pExaScr->do_migration) { BoxRec Box; RegionRec Reg; ExaMigrationRec pixmaps[1]; Box.x1 = pDrawable->y + x + xoff; Box.y1 = pDrawable->y + y + yoff; Box.x2 = Box.x1 + w; Box.y2 = Box.y1 + h; REGION_INIT(pScreen, &Reg, &Box, 1); pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; pixmaps[0].pPix = pPix; pixmaps[0].pReg = &Reg; exaDoMigration(pixmaps, 1, FALSE); REGION_UNINIT(pScreen, &Reg); } pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL) goto fallback; /* Only cover the ZPixmap, solid copy case. */ if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) goto fallback; /* Only try to handle the 8bpp and up cases, since we don't want to think * about <8bpp. */ if (pDrawable->bitsPerPixel < 8) goto fallback; ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff, pDrawable->y + y + yoff, w, h, d, PixmapBytePad(w, pDrawable->depth)); if (ok) { exaWaitSync(pDrawable->pScreen); return; } fallback: ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d); }