summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-02-19 07:14:13 -0800
committerEric Anholt <eric@anholt.net>2013-08-17 12:20:40 +0200
commitf22d3fb8f7f9a605e037c1e11391954dcb4ddede (patch)
tree1e1216708247625b8bfdc7f24b0c55da4104707b
parent52a9d6bfe44e9f893f3d3df7e272207d44bc9f7c (diff)
glamor: Add support for using EXT_framebuffer_blit to do CopyArea.old-glamor
-rw-r--r--glamor/glamor_copyarea.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 172b9593c..297a1fbc5 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -33,6 +33,88 @@
*/
static Bool
+glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
+ DrawablePtr dst,
+ GCPtr gc,
+ BoxPtr box,
+ int nbox,
+ int dx,
+ int dy)
+{
+ ScreenPtr screen = dst->pScreen;
+ PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+ PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+ glamor_pixmap_private *src_pixmap_priv;
+ int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
+
+ if (src == dst) {
+ glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+ "src == dest\n");
+ return FALSE;
+ }
+
+ if (!GLEW_EXT_framebuffer_blit) {
+ glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+ "no EXT_framebuffer_blit\n");
+ return FALSE;
+ }
+
+ src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
+
+ if (src_pixmap_priv->fb == 0) {
+ PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+ if (src_pixmap != screen_pixmap) {
+ glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+ "no src fbo\n");
+ return FALSE;
+ }
+ }
+
+ if (gc) {
+ if (gc->alu != GXcopy) {
+ glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+ "non-copy ALU\n");
+ return FALSE;
+ }
+ if (!glamor_pm_is_solid(dst, gc->planemask)) {
+ glamor_delayed_fallback(screen, "glamor_copy_n_to_n_fbo_blit(): "
+ "non-solid planemask\n");
+ return FALSE;
+ }
+ }
+
+ if (!glamor_set_destination_pixmap(dst_pixmap))
+ return FALSE;
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->fb);
+
+ glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
+ glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
+ src_y_off += dy;
+
+ for (i = 0; i < nbox; i++) {
+ int flip_dst_y1 = dst_pixmap->drawable.height - (box[i].y2 + dst_y_off);
+ int flip_dst_y2 = dst_pixmap->drawable.height - (box[i].y1 + dst_y_off);
+ int flip_src_y1 = src_pixmap->drawable.height - (box[i].y2 + src_y_off);
+ int flip_src_y2 = src_pixmap->drawable.height - (box[i].y1 + src_y_off);
+
+ glBlitFramebufferEXT(box[i].x1 + dx + src_x_off,
+ flip_src_y1,
+ box[i].x2 + dx + src_x_off,
+ flip_src_y2,
+ box[i].x1 + dst_x_off,
+ flip_dst_y1,
+ box[i].x2 + dst_x_off,
+ flip_dst_y2,
+ GL_COLOR_BUFFER_BIT,
+ GL_NEAREST);
+ }
+
+ return TRUE;
+}
+
+static Bool
glamor_copy_n_to_n_copypixels(DrawablePtr src,
DrawablePtr dst,
GCPtr gc,
@@ -199,6 +281,11 @@ glamor_copy_n_to_n(DrawablePtr src,
Pixel bitplane,
void *closure)
{
+ if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
+ glamor_clear_delayed_fallbacks(dst->pScreen);
+ return;
+ }
+
if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)) {
glamor_clear_delayed_fallbacks(dst->pScreen);
return;