static void glamor_copy_bail(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { if (bitplane) { if (src->bitsPerPixel > 1) fbCopyNto1(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); else fbCopy1toN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } else { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } } glamor_finish_access(dst); glamor_finish_access(src); }
/** * Implements CopyPlane and CopyArea from the GPU to the GPU by using * the source as a texture and painting that into the destination. * * This requires that source and dest are different textures, or that * (if the copy area doesn't overlap), GL_NV_texture_barrier is used * to ensure that the caches are flushed at the right times. */ static Bool glamor_copy_cpu_fbo(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); FbBits *src_bits; FbStride src_stride; int src_bpp; int src_xoff, src_yoff; int dst_xoff, dst_yoff; if (gc && gc->alu != GXcopy) goto bail; if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_make_current(glamor_priv); glamor_prepare_access(src, GLAMOR_ACCESS_RO); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff); if (bitplane) { PixmapPtr src_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width, dst_pixmap->drawable.height, dst->depth, 0); if (!src_pix) { glamor_finish_access(src); goto bail; } src_pix->drawable.x = -dst->x; src_pix->drawable.y = -dst->y; fbGetDrawable(&src_pix->drawable, src_bits, src_stride, src_bpp, src_xoff, src_yoff); if (src->bitsPerPixel > 1) fbCopyNto1(src, &src_pix->drawable, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); else fbCopy1toN(src, &src_pix->drawable, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff, src_yoff, dst_xoff, dst_yoff, (uint8_t *) src_bits, src_stride * sizeof(FbBits)); fbDestroyPixmap(src_pix); } else { fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff); glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy, dst_xoff, dst_yoff, (uint8_t *) src_bits, src_stride * sizeof (FbBits)); } glamor_finish_access(src); return TRUE; bail: return FALSE; }