/** * 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); }
/** * 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); }