diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c index 4cbb3c66b..c8ccaaef1 100644 --- a/glamor/glamor_copyarea.c +++ b/glamor/glamor_copyarea.c @@ -47,15 +47,10 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int dst_x_off, dst_y_off, src_x_off, src_y_off, i; - if (src == dst) { - glamor_delayed_fallback(screen,"src == dest\n"); - return FALSE; - } - if (!GLEW_EXT_framebuffer_blit) { glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n"); return FALSE; - } + } src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); @@ -121,78 +116,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src, return TRUE; } -static Bool -glamor_copy_n_to_n_copypixels(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); - glamor_screen_private *glamor_priv = - glamor_get_screen_private(screen); - glamor_pixmap_private *pixmap_priv; - int x_off, y_off, i; - if (src != dst) { - glamor_delayed_fallback(screen, "src != dest\n"); - return FALSE; - } - - if (gc) { - if (gc->alu != GXcopy) { - glamor_delayed_fallback(screen,"non-copy ALU\n"); - return FALSE; - } - if (!glamor_pm_is_solid(dst, gc->planemask)) { - glamor_delayed_fallback(screen,"non-solid planemask\n"); - return FALSE; - } - } - - pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL) - return TRUE; - if (glamor_set_destination_pixmap(dst_pixmap)) { - glamor_delayed_fallback(screen, "dst has no fbo.\n"); - return FALSE; - } - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glOrtho(0, dst_pixmap->drawable.width, - 0, dst_pixmap->drawable.height, - -1, 1); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off); - - for (i = 0; i < nbox; i++) { - if(glamor_priv->yInverted) { - glRasterPos2i(box[i].x1 + x_off, - box[i].y1 + y_off); - glCopyPixels(box[i].x1 + dx + x_off, - box[i].y1 + dy + y_off, - box[i].x2 - box[i].x1, - box[i].y2 - box[i].y1, - GL_COLOR); - } else { - int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off; - glRasterPos2i(box[i].x1 + x_off, - flip_y1); - glCopyPixels(box[i].x1 + dx + x_off, - flip_y1 - dy, - box[i].x2 - box[i].x1, - box[i].y2 - box[i].y1, - GL_COLOR); - } - } - return TRUE; -} - static Bool glamor_copy_n_to_n_textured(DrawablePtr src, DrawablePtr dst, @@ -213,21 +136,17 @@ glamor_copy_n_to_n_textured(DrawablePtr src, int src_x_off, src_y_off, dst_x_off, dst_y_off; enum glamor_pixmap_status src_status = GLAMOR_NONE; GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; + int flush_needed = 0; src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - if (src == dst) { - glamor_delayed_fallback(dst->pScreen, "same src/dst\n"); - goto fail; - } - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n"); goto fail; } - if (!src_pixmap_priv->gl_tex) { + if (!src_pixmap_priv->gl_fbo) { #ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n"); goto fail; @@ -237,6 +156,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src, goto fail; #endif } + else + flush_needed = 1; if (gc) { glamor_set_alu(gc->alu); @@ -246,7 +167,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glamor_set_destination_pixmap_priv_nc(src_pixmap_priv); glamor_validate_pixmap(src_pixmap); } - } glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); @@ -283,6 +203,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src, } for (i = 0; i < nbox; i++) { + glamor_set_normalize_vcoords(dst_xscale, dst_yscale, box[i].x1 + dst_x_off, box[i].y1 + dst_y_off, @@ -308,6 +229,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src, glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); } + /* The source texture is bound to a fbo, we have to flush it here. */ + if (flush_needed) + glFlush(); return TRUE; fail: @@ -337,8 +261,14 @@ glamor_copy_n_to_n(DrawablePtr src, ScreenPtr screen; int temp_dx = dx; int temp_dy = dy; + int src_x_off, src_y_off, dst_x_off, dst_y_off; + int i; + int overlaped = 0; + dst_pixmap = glamor_get_drawable_pixmap(dst); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); + src_pixmap = glamor_get_drawable_pixmap(src); + src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); screen = dst_pixmap->drawable.pScreen; if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) { @@ -346,19 +276,29 @@ glamor_copy_n_to_n(DrawablePtr src, goto fail; } - if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { + glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); + glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); + + if (src_pixmap_priv->fb == dst_pixmap_priv->fb) { + int x_shift = abs(src_x_off - dx - dst_x_off); + int y_shift = abs(src_y_off - dy - dst_y_off); + for ( i = 0; i < nbox; i++) + { + if (x_shift < abs(box[i].x2 - box[i].x1) + && y_shift < abs(box[i].y2 - box[i].y1)) { + overlaped = 1; + break; + } + } + } + /* XXX need revisit to handle overlapped area copying. */ + + if ( overlaped + && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { goto done; return; } - if (glamor_copy_n_to_n_copypixels(src, dst, gc, box, nbox, dx, dy)){ - goto done; - return; - } - - src_pixmap = glamor_get_drawable_pixmap(src); - src_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - glamor_calculate_boxes_bound(&bound, box, nbox); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) @@ -370,7 +310,7 @@ glamor_copy_n_to_n(DrawablePtr src, bound.y2 - bound.y1, src_pixmap->drawable.depth, GLAMOR_CREATE_PIXMAP_CPU); - if (!temp_src) + if (!temp_pixmap) goto fail; glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1); temp_src = &temp_pixmap->drawable; @@ -391,6 +331,7 @@ glamor_copy_n_to_n(DrawablePtr src, if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { goto done; } + fail: glamor_report_delayed_fallbacks(src->pScreen); @@ -406,7 +347,8 @@ glamor_copy_n_to_n(DrawablePtr src, dst_access = GLAMOR_ACCESS_WO; if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { - if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { + if (dst == src + || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); @@ -428,34 +370,10 @@ RegionPtr glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc, int srcx, int srcy, int width, int height, int dstx, int dsty) { -#if 0 - ScreenPtr screen = dst->pScreen; - PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); - PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); - glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap); -#endif RegionPtr region; - region = miDoCopy(src, dst, gc, srcx, srcy, width, height, dstx, dsty, glamor_copy_n_to_n, 0, NULL); return region; - -#if 0 -fail: - glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst, - glamor_get_drawable_location(src), - glamor_get_drawable_location(dst)); - region = NULL; - if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) { - if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) { - region = fbCopyArea(src, dst, gc, srcx, srcy, width, height, - dstx, dsty); - glamor_finish_access(src); - } - glamor_finish_access(dst); - } - return region; -#endif }