void uxa_check_composite(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 screen = pDst->pDrawable->pScreen; UXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst)); if (uxa_picture_prepare_access(pDst, UXA_ACCESS_RW)) { if (uxa_picture_prepare_access(pSrc, UXA_ACCESS_RO)) { if (!pMask || uxa_picture_prepare_access(pMask, UXA_ACCESS_RO)) { fbComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (pMask) uxa_picture_finish_access(pMask, UXA_ACCESS_RO); } uxa_picture_finish_access(pSrc, UXA_ACCESS_RO); } uxa_picture_finish_access(pDst, UXA_ACCESS_RW); } }
void KdCheckComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { KdCheckSync (pDst->pDrawable->pScreen); fbComposite (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); }
/** * Does an fbComposite to complete the requested drawing operation. */ static void ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { KdScreenPriv(pDst->drawable.pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; EphyrFakexaPriv *fakexa = scrpriv->fakexa; fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture, fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY, w, h); }
void fbCompositeGeneral (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { fbComposite (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); }
fastcall static void sna_tiling_composite_spans_done(struct sna *sna, const struct sna_composite_spans_op *op) { struct sna_tile_state *tile = op->base.priv; struct sna_composite_spans_op tmp; int x, y, n, step; bool force_fallback = false; /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) || tile->dst_y & 63) step /= 2; while (step * step * 4 > sna->kgem.max_copy_tile_size) step /= 2; DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__, tile->width, tile->height, tile->rect_count, step)); if (tile->rect_count == 0) goto done; for (y = 0; y < tile->height; y += step) { int height = step; if (y + height > tile->height) height = tile->height - y; for (x = 0; x < tile->width; x += step) { const struct sna_tile_span *r = (void *)tile->rects; int width = step; if (x + width > tile->width) width = tile->width - x; if (!force_fallback && sna->render.composite_spans(sna, tile->op, tile->src, tile->dst, tile->src_x + x, tile->src_y + y, tile->dst_x + x, tile->dst_y + y, width, height, tile->flags, memset(&tmp, 0, sizeof(tmp)))) { for (n = 0; n < tile->rect_count; n++) { BoxRec b; b.x1 = r->box.x1 - tile->dst_x; if (b.x1 < x) b.x1 = x; b.y1 = r->box.y1 - tile->dst_y; if (b.y1 < y) b.y1 = y; b.x2 = r->box.x2 - tile->dst_x; if (b.x2 > x + width) b.x2 = x + width; b.y2 = r->box.y2 - tile->dst_y; if (b.y2 > y + height) b.y2 = y + height; DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d)\n", __FUNCTION__, n, r->box.x1, r->box.y1, r->box.x2-r->box.x1, r->box.y2-r->box.y1, x, y, width, height, b.x1, b.y1, b.x2, b.y2)); if (b.y2 > b.y1 && b.x2 > b.x1) tmp.box(sna, &tmp, &b, r->opacity); r++; } tmp.done(sna, &tmp); } else { unsigned int flags; DBG(("%s -- falback\n", __FUNCTION__)); if (tile->op <= PictOpSrc) flags = MOVE_WRITE; else flags = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_to_cpu(tile->dst->pDrawable, flags)) goto done; if (tile->dst->alphaMap && !sna_drawable_move_to_cpu(tile->dst->alphaMap->pDrawable, flags)) goto done; if (tile->src->pDrawable && !sna_drawable_move_to_cpu(tile->src->pDrawable, MOVE_READ)) goto done; if (tile->src->alphaMap && !sna_drawable_move_to_cpu(tile->src->alphaMap->pDrawable, MOVE_READ)) goto done; for (n = 0; n < tile->rect_count; n++) { BoxRec b; b.x1 = r->box.x1 - tile->dst_x; if (b.x1 < x) b.x1 = x; b.y1 = r->box.y1 - tile->dst_y; if (b.y1 < y) b.y1 = y; b.x2 = r->box.x2 - tile->dst_x; if (b.x2 > x + width) b.x2 = x + width; b.y2 = r->box.y2 - tile->dst_y; if (b.y2 > y + height) b.y2 = y + height; DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d)\n", __FUNCTION__, n, r->box.x1, r->box.y1, r->box.x2-r->box.x1, r->box.y2-r->box.y1, x, y, width, height, b.x1, b.y1, b.x2, b.y2)); if (b.y2 > b.y1 && b.x2 > b.x1) { xRenderColor alpha; PicturePtr mask; int error; alpha.red = alpha.green = alpha.blue = 0; alpha.alpha = r->opacity * 0xffff; mask = CreateSolidPicture(0, &alpha, &error); if (!mask) goto done; if (sigtrap_get() == 0) { fbComposite(tile->op, tile->src, mask, tile->dst, tile->src_x + x, tile->src_y + y, 0, 0, tile->dst_x + x, tile->dst_y + y, width, height); sigtrap_put(); } FreePicture(mask, 0); } r++; } force_fallback = true; } } } done: if (tile->rects != tile->rects_embedded) free(tile->rects); free(tile); }
static void sna_tiling_composite_done(struct sna *sna, const struct sna_composite_op *op) { struct sna_tile_state *tile = op->priv; struct sna_composite_op tmp; int x, y, n, step; /* Use a small step to accommodate enlargement through tile alignment */ step = sna->render.max_3d_size; if (tile->dst_x & (8*512 / tile->dst->pDrawable->bitsPerPixel - 1) || tile->dst_y & 63) step /= 2; while (step * step * 4 > sna->kgem.max_copy_tile_size) step /= 2; DBG(("%s -- %dx%d, count=%d, step size=%d\n", __FUNCTION__, tile->width, tile->height, tile->rect_count, step)); if (tile->rect_count == 0) goto done; for (y = 0; y < tile->height; y += step) { int height = step; if (y + height > tile->height) height = tile->height - y; for (x = 0; x < tile->width; x += step) { int width = step; if (x + width > tile->width) width = tile->width - x; if (sna->render.composite(sna, tile->op, tile->src, tile->mask, tile->dst, tile->src_x + x, tile->src_y + y, tile->mask_x + x, tile->mask_y + y, tile->dst_x + x, tile->dst_y + y, width, height, COMPOSITE_PARTIAL, memset(&tmp, 0, sizeof(tmp)))) { for (n = 0; n < tile->rect_count; n++) { const struct sna_composite_rectangles *r = &tile->rects[n]; int x1, x2, dx, y1, y2, dy; x1 = r->dst.x - tile->dst_x, dx = 0; if (x1 < x) dx = x - x1, x1 = x; y1 = r->dst.y - tile->dst_y, dy = 0; if (y1 < y) dy = y - y1, y1 = y; x2 = r->dst.x + r->width - tile->dst_x; if (x2 > x + width) x2 = x + width; y2 = r->dst.y + r->height - tile->dst_y; if (y2 > y + height) y2 = y + height; DBG(("%s: rect[%d] = (%d, %d)x(%d,%d), tile=(%d,%d)x(%d, %d), blt=(%d,%d),(%d,%d), delta=(%d,%d)\n", __FUNCTION__, n, r->dst.x, r->dst.y, r->width, r->height, x, y, width, height, x1, y1, x2, y2, dx, dy)); if (y2 > y1 && x2 > x1) { struct sna_composite_rectangles rr; rr.src.x = dx + r->src.x; rr.src.y = dy + r->src.y; rr.mask.x = dx + r->mask.x; rr.mask.y = dy + r->mask.y; rr.dst.x = dx + r->dst.x; rr.dst.y = dy + r->dst.y; rr.width = x2 - x1; rr.height = y2 - y1; tmp.blt(sna, &tmp, &rr); } } tmp.done(sna, &tmp); } else { unsigned int flags; DBG(("%s -- falback\n", __FUNCTION__)); if (tile->op <= PictOpSrc) flags = MOVE_WRITE; else flags = MOVE_WRITE | MOVE_READ; if (!sna_drawable_move_to_cpu(tile->dst->pDrawable, flags)) goto done; if (tile->dst->alphaMap && !sna_drawable_move_to_cpu(tile->dst->alphaMap->pDrawable, flags)) goto done; if (tile->src->pDrawable && !sna_drawable_move_to_cpu(tile->src->pDrawable, MOVE_READ)) goto done; if (tile->src->alphaMap && !sna_drawable_move_to_cpu(tile->src->alphaMap->pDrawable, MOVE_READ)) goto done; if (tile->mask && tile->mask->pDrawable && !sna_drawable_move_to_cpu(tile->mask->pDrawable, MOVE_READ)) goto done; if (tile->mask && tile->mask->alphaMap && !sna_drawable_move_to_cpu(tile->mask->alphaMap->pDrawable, MOVE_READ)) goto done; if (sigtrap_get() == 0) { fbComposite(tile->op, tile->src, tile->mask, tile->dst, tile->src_x + x, tile->src_y + y, tile->mask_x + x, tile->mask_y + y, tile->dst_x + x, tile->dst_y + y, width, height); sigtrap_put(); } } } } done: if (tile->rects != tile->rects_embedded) free(tile->rects); free(tile); }
static void radeon_glamor_composite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) { ScrnInfoPtr scrn = xf86ScreenToScrn(pDst->pDrawable->pScreen); RADEONInfoPtr info; PixmapPtr pixmap; struct radeon_pixmap *dst_priv, *src_priv = NULL, *mask_priv = NULL; Bool gpu_done = FALSE; if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap)) goto fallback; pixmap = get_drawable_pixmap(pDst->pDrawable); if (&pixmap->drawable != pDst->pDrawable || pixmap->usage_hint != RADEON_CREATE_PIXMAP_SCANOUT) goto fallback; dst_priv = radeon_get_pixmap_private(pixmap); if (!radeon_glamor_prepare_access_gpu(dst_priv)) goto fallback; info = RADEONPTR(scrn); if (!pSrc->pDrawable || ((pixmap = get_drawable_pixmap(pSrc->pDrawable)) && (src_priv = radeon_get_pixmap_private(pixmap)) && radeon_glamor_prepare_access_gpu(src_priv))) { if (!pMask || !pMask->pDrawable || ((pixmap = get_drawable_pixmap(pMask->pDrawable)) && (mask_priv = radeon_get_pixmap_private(pixmap)) && radeon_glamor_prepare_access_gpu(mask_priv))) { info->glamor.SavedComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); gpu_done = TRUE; if (mask_priv) radeon_glamor_finish_access_gpu_ro(info, mask_priv); } if (src_priv) radeon_glamor_finish_access_gpu_ro(info, src_priv); } radeon_glamor_finish_access_gpu_rw(info, dst_priv); if (gpu_done) return; fallback: if (radeon_glamor_picture_prepare_access_cpu_rw(scrn, pDst)) { if (radeon_glamor_picture_prepare_access_cpu_ro(scrn, pSrc)) { if (!pMask || radeon_glamor_picture_prepare_access_cpu_ro(scrn, pMask)) { fbComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); if (pMask) radeon_glamor_picture_finish_access_cpu(pMask); } radeon_glamor_picture_finish_access_cpu(pSrc); } radeon_glamor_picture_finish_access_cpu(pDst); } }