/** * Creates an appropriate picture for temp mask use. */ static PicturePtr glamor_create_mask_picture(ScreenPtr screen, PicturePtr dst, PictFormatPtr pict_format, CARD16 width, CARD16 height) { PixmapPtr pixmap; PicturePtr picture; int error; if (!pict_format) { if (dst->polyEdge == PolyEdgeSharp) pict_format = PictureMatchFormat(screen, 1, PICT_a1); else pict_format = PictureMatchFormat(screen, 8, PICT_a8); if (!pict_format) return 0; } pixmap = glamor_create_pixmap(screen, 0, 0, pict_format->depth, GLAMOR_CREATE_PIXMAP_CPU); if (!pixmap) return 0; picture = CreatePicture(0, &pixmap->drawable, pict_format, 0, 0, serverClient, &error); glamor_destroy_pixmap(pixmap); return picture; }
static PixmapPtr glamor_get_stipple_pixmap(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); ScreenPtr screen = gc->pScreen; PixmapPtr bitmap; PixmapPtr pixmap; GCPtr scratch_gc; ChangeGCVal changes[2]; if (gc_priv->stipple) return gc_priv->stipple; bitmap = gc->stipple; if (!bitmap) goto bail; pixmap = glamor_create_pixmap(screen, bitmap->drawable.width, bitmap->drawable.height, 8, GLAMOR_CREATE_NO_LARGE); if (!pixmap) goto bail; scratch_gc = GetScratchGC(8, screen); if (!scratch_gc) goto bail_pixmap; changes[0].val = 0xff; changes[1].val = 0x00; if (ChangeGC(NullClient, scratch_gc, GCForeground|GCBackground, changes) != Success) goto bail_gc; ValidateGC(&pixmap->drawable, scratch_gc); (*scratch_gc->ops->CopyPlane)(&bitmap->drawable, &pixmap->drawable, scratch_gc, 0, 0, bitmap->drawable.width, bitmap->drawable.height, 0, 0, 0x1); FreeScratchGC(scratch_gc); gc_priv->stipple = pixmap; glamor_track_stipple(gc); return pixmap; bail_gc: FreeScratchGC(scratch_gc); bail_pixmap: glamor_destroy_pixmap(pixmap); bail: return NULL; }
/* XXX LARGE pixmap? */ Bool glamor_fixup_pixmap_priv(ScreenPtr screen, glamor_pixmap_private *pixmap_priv) { glamor_pixmap_fbo *old_fbo; glamor_pixmap_fbo *new_fbo = NULL; PixmapPtr scratch = NULL; glamor_pixmap_private *scratch_priv; DrawablePtr drawable; GCPtr gc = NULL; int ret = FALSE; drawable = &pixmap_priv->base.pixmap->drawable; if (!GLAMOR_PIXMAP_FBO_NOT_EXACT_SIZE(pixmap_priv)) return TRUE; old_fbo = pixmap_priv->base.fbo; if (!old_fbo) return FALSE; gc = GetScratchGC(drawable->depth, screen); if (!gc) goto fail; scratch = glamor_create_pixmap(screen, drawable->width, drawable->height, drawable->depth, GLAMOR_CREATE_PIXMAP_FIXUP); scratch_priv = glamor_get_pixmap_private(scratch); if (!scratch_priv->base.fbo) goto fail; ValidateGC(&scratch->drawable, gc); glamor_copy_area(drawable, &scratch->drawable, gc, 0, 0, drawable->width, drawable->height, 0, 0); old_fbo = glamor_pixmap_detach_fbo(pixmap_priv); new_fbo = glamor_pixmap_detach_fbo(scratch_priv); glamor_pixmap_attach_fbo(pixmap_priv->base.pixmap, new_fbo); glamor_pixmap_attach_fbo(scratch, old_fbo); DEBUGF("old %dx%d type %d\n", drawable->width, drawable->height, pixmap_priv->type); DEBUGF("copy tex %d %dx%d to tex %d %dx%d \n", old_fbo->tex, old_fbo->width, old_fbo->height, new_fbo->tex, new_fbo->width, new_fbo->height); ret = TRUE; fail: if (gc) FreeScratchGC(gc); if (scratch) glamor_destroy_pixmap(scratch); return ret; }
static PixmapPtr glamor_get_dash_pixmap(GCPtr gc) { glamor_gc_private *gc_priv = glamor_get_gc_private(gc); ScreenPtr screen = gc->pScreen; PixmapPtr pixmap; int offset; int d; uint32_t pixel; GCPtr scratch_gc; if (gc_priv->dash) return gc_priv->dash; offset = 0; for (d = 0; d < gc->numInDashList; d++) offset += gc->dash[d]; pixmap = glamor_create_pixmap(screen, offset, 1, 8, 0); if (!pixmap) goto bail; scratch_gc = GetScratchGC(8, screen); if (!scratch_gc) goto bail_pixmap; pixel = 0xffffffff; offset = 0; for (d = 0; d < gc->numInDashList; d++) { xRectangle rect; ChangeGCVal changes; changes.val = pixel; (void) ChangeGC(NullClient, scratch_gc, GCForeground, &changes); ValidateGC(&pixmap->drawable, scratch_gc); rect.x = offset; rect.y = 0; rect.width = gc->dash[d]; rect.height = 1; scratch_gc->ops->PolyFillRect (&pixmap->drawable, scratch_gc, 1, &rect); offset += gc->dash[d]; pixel = ~pixel; } FreeScratchGC(scratch_gc); gc_priv->dash = pixmap; return pixmap; bail_pixmap: glamor_destroy_pixmap(pixmap); bail: return NULL; }
static Bool xwl_glamor_destroy_pixmap(PixmapPtr pixmap) { struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); if (xwl_pixmap && pixmap->refcnt == 1) { if (xwl_pixmap->buffer) wl_buffer_destroy(xwl_pixmap->buffer); eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image); gbm_bo_destroy(xwl_pixmap->bo); free(xwl_pixmap); } return glamor_destroy_pixmap(pixmap); }
static Bool _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int left_pad, int image_format, char *bits, Bool fallback) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); RegionPtr clip; int x_off, y_off; Bool ret = FALSE; PixmapPtr temp_pixmap, sub_pixmap; glamor_pixmap_private *temp_pixmap_priv; BoxRec box; int stride; glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); clip = fbGetCompositeClip(gc); if (image_format == XYBitmap) { assert(depth == 1); goto fail; } if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("has no fbo.\n"); goto fail; } if (image_format != ZPixmap) { glamor_fallback("non-ZPixmap\n"); goto fail; } if (!glamor_set_planemask(pixmap, gc->planemask)) { goto fail; } /* create a temporary pixmap and upload the bits to that * pixmap, then apply clip copy it to the destination pixmap.*/ stride = PixmapBytePad(w, depth); box.x1 = x + drawable->x; box.y1 = y + drawable->y; box.x2 = x + w + drawable->x; box.y2 = y + h + drawable->y; if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN) || gc->alu != GXcopy) { temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0); if (temp_pixmap == NULL) goto fail; temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) { temp_pixmap_priv->base.picture = pixmap_priv->base.picture; temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; } glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h, stride, bits, 0); glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y); glamor_destroy_pixmap(temp_pixmap); } else { glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off, w, h, stride, bits, 0); } ret = TRUE; goto done; fail: glamor_set_planemask(pixmap, ~0); if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable)) goto done; glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW); if (sub_pixmap) { if (clip != NULL) pixman_region_translate (clip, -x - drawable->x, -y - drawable->y); fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h, left_pad, image_format, bits); glamor_put_sub_pixmap(sub_pixmap, pixmap, x + x_off + drawable->x, y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW); if (clip != NULL) pixman_region_translate (clip, x + drawable->x, y + drawable->y); } else fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, bits); ret = TRUE; done: return ret; }
static inline void glamor_copy_glyph(PixmapPtr glyph_pixmap, DrawablePtr atlas_draw, int16_t x, int16_t y) { DrawablePtr glyph_draw = &glyph_pixmap->drawable; BoxRec box = { .x1 = 0, .y1 = 0, .x2 = glyph_draw->width, .y2 = glyph_draw->height, }; PixmapPtr upload_pixmap = glyph_pixmap; if (glyph_pixmap->drawable.bitsPerPixel != atlas_draw->bitsPerPixel) { /* If we're dealing with 1-bit glyphs, we copy them to a * temporary 8-bit pixmap and upload them from there, since * that's what GL can handle. */ ScreenPtr screen = atlas_draw->pScreen; GCPtr scratch_gc; ChangeGCVal changes[2]; upload_pixmap = glamor_create_pixmap(screen, glyph_draw->width, glyph_draw->height, atlas_draw->depth, GLAMOR_CREATE_PIXMAP_CPU); if (!upload_pixmap) return; scratch_gc = GetScratchGC(upload_pixmap->drawable.depth, screen); if (!scratch_gc) { glamor_destroy_pixmap(upload_pixmap); return; } changes[0].val = 0xff; changes[1].val = 0x00; if (ChangeGC(NullClient, scratch_gc, GCForeground|GCBackground, changes) != Success) { glamor_destroy_pixmap(upload_pixmap); FreeScratchGC(scratch_gc); return; } ValidateGC(&upload_pixmap->drawable, scratch_gc); (*scratch_gc->ops->CopyPlane)(glyph_draw, &upload_pixmap->drawable, scratch_gc, 0, 0, glyph_draw->width, glyph_draw->height, 0, 0, 0x1); } glamor_upload_boxes((PixmapPtr) atlas_draw, &box, 1, 0, 0, x, y, upload_pixmap->devPrivate.ptr, upload_pixmap->devKind); if (upload_pixmap != glyph_pixmap) glamor_destroy_pixmap(upload_pixmap); } static Bool glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PictFormatPtr format = atlas->format; atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim, glamor_priv->glyph_atlas_dim, format->depth, GLAMOR_CREATE_FBO_NO_FBO); if (!glamor_pixmap_has_fbo(atlas->atlas)) { glamor_destroy_pixmap(atlas->atlas); atlas->atlas = NULL; } atlas->x = 0; atlas->y = 0; atlas->row_height = 0; atlas->serial++; atlas->nglyph = 0; return TRUE; }
static Bool _glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure, Bool fallback) { PixmapPtr dst_pixmap, src_pixmap; glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; glamor_screen_private *glamor_priv; glamor_gl_dispatch *dispatch; BoxPtr extent; RegionRec region; int src_x_off, src_y_off, dst_x_off, dst_y_off; Bool ok = FALSE; int force_clip = 0; if (nbox == 0) return TRUE; 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); glamor_priv = glamor_get_screen_private(dst->pScreen); DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", box[0].x1, box[0].y1, box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, dx, dy, src_pixmap, dst_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) goto fall_back; if (gc) { if (!glamor_set_planemask(dst_pixmap, gc->planemask)) goto fall_back; dispatch = glamor_get_dispatch(glamor_priv); if (!glamor_set_alu(dispatch, gc->alu)) { glamor_put_dispatch(glamor_priv); goto fail_noregion; } glamor_put_dispatch(glamor_priv); } if (!src_pixmap_priv) { glamor_set_pixmap_type(src_pixmap, GLAMOR_MEMORY); src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); } 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); RegionInitBoxes(®ion, box, nbox); extent = RegionExtents(®ion); if (!glamor_check_fbo_size(glamor_priv, extent->x2 - extent->x1, extent->y2 - extent->y1) && (src_pixmap_priv->type == GLAMOR_MEMORY || (src_pixmap_priv == dst_pixmap_priv))) { force_clip = 1; } if (force_clip || dst_pixmap_priv->type == GLAMOR_TEXTURE_LARGE || src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { glamor_pixmap_clipped_regions *clipped_dst_regions; int n_dst_region, i, j; PixmapPtr temp_source_pixmap; glamor_pixmap_private *temp_source_priv = NULL; RegionTranslate(®ion, dst_x_off, dst_y_off); if (!force_clip) clipped_dst_regions = glamor_compute_clipped_regions(dst_pixmap_priv, ®ion, &n_dst_region, 0, reverse, upsidedown); else clipped_dst_regions = glamor_compute_clipped_regions_ext(dst_pixmap_priv, ®ion, &n_dst_region, glamor_priv->max_fbo_size, glamor_priv->max_fbo_size, reverse, upsidedown); for(i = 0; i < n_dst_region; i++) { int n_src_region; glamor_pixmap_clipped_regions *clipped_src_regions; BoxPtr current_boxes; int n_current_boxes; SET_PIXMAP_FBO_CURRENT(dst_pixmap_priv, clipped_dst_regions[i].block_idx); temp_source_pixmap = NULL; if (src_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { RegionTranslate(clipped_dst_regions[i].region, -dst_x_off + src_x_off + dx, -dst_y_off + src_y_off + dy); clipped_src_regions = glamor_compute_clipped_regions(src_pixmap_priv, clipped_dst_regions[i].region, &n_src_region, 0, reverse, upsidedown); DEBUGF("Source is large pixmap.\n"); for (j = 0; j < n_src_region; j++) { if (src_pixmap_priv != dst_pixmap_priv) SET_PIXMAP_FBO_CURRENT(src_pixmap_priv, clipped_src_regions[j].block_idx); else if (src_pixmap_priv == dst_pixmap_priv && clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx) { /* source and the dest are the same, but need different block_idx. * we create a empty pixmap and fill the required source fbo and box to * it. It's a little hacky, but avoid extra copy. */ temp_source_pixmap = glamor_create_pixmap(src->pScreen, 0, 0, src->depth, 0); if (!temp_source_pixmap) { ok = FALSE; goto fail; } src->pScreen->ModifyPixmapHeader(temp_source_pixmap, src_pixmap->drawable.width, src_pixmap->drawable.height, 0, 0, src_pixmap->devKind, NULL); temp_source_priv = glamor_get_pixmap_private(temp_source_pixmap); *temp_source_priv = *src_pixmap_priv; temp_source_priv->large.box = src_pixmap_priv->large.box_array[clipped_src_regions[j].block_idx]; temp_source_priv->base.fbo = src_pixmap_priv->large.fbo_array[clipped_src_regions[j].block_idx]; temp_source_priv->base.pixmap = temp_source_pixmap; } assert(temp_source_pixmap || !(src_pixmap_priv == dst_pixmap_priv && (clipped_src_regions[j].block_idx != clipped_dst_regions[i].block_idx))); RegionTranslate(clipped_src_regions[j].region, -src_x_off - dx, -src_y_off - dy); current_boxes = RegionRects(clipped_src_regions[j].region); n_current_boxes = RegionNumRects(clipped_src_regions[j].region); DEBUGF("dst pixmap fbo idx %d src pixmap fbo idx %d \n", clipped_dst_regions[i].block_idx, clipped_src_regions[j].block_idx); DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", current_boxes[0].x1, current_boxes[0].y1, current_boxes[0].x2, current_boxes[0].y2, dx, dy, src_pixmap, dst_pixmap); if (!temp_source_pixmap) ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, n_current_boxes, dx, dy, reverse, upsidedown, bitplane, closure); else { ok = __glamor_copy_n_to_n(&temp_source_pixmap->drawable, dst, gc, current_boxes, n_current_boxes, dx, dy, reverse, upsidedown, bitplane, closure); temp_source_priv->type = GLAMOR_MEMORY; temp_source_priv->base.fbo = NULL; glamor_destroy_pixmap(temp_source_pixmap); temp_source_pixmap = NULL; } RegionDestroy(clipped_src_regions[j].region); if (!ok) { assert(0); goto fail; } } if (n_src_region == 0) ok = TRUE; free(clipped_src_regions); } else { RegionTranslate(clipped_dst_regions[i].region, - dst_x_off, - dst_y_off); current_boxes = RegionRects(clipped_dst_regions[i].region); n_current_boxes = RegionNumRects(clipped_dst_regions[i].region); DEBUGF("dest pixmap fbo idx %d \n", clipped_dst_regions[i].block_idx); DEBUGF("Copy %d %d %d %d dx %d dy %d from %p to %p \n", current_boxes[0].x1, current_boxes[0].y1, current_boxes[0].x2, current_boxes[0].y2, dx, dy, src_pixmap, dst_pixmap); ok = __glamor_copy_n_to_n(src, dst, gc, current_boxes, n_current_boxes, dx, dy, reverse, upsidedown, bitplane, closure); } RegionDestroy(clipped_dst_regions[i].region); } if (n_dst_region == 0) ok = TRUE; free(clipped_dst_regions); } else { ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } fail: RegionUninit(®ion); fail_noregion: dispatch = glamor_get_dispatch(glamor_priv); glamor_set_alu(dispatch, GXcopy); glamor_put_dispatch(glamor_priv); if (ok) return TRUE; fall_back: if (!fallback && glamor_ddx_fallback_check_pixmap(src) && glamor_ddx_fallback_check_pixmap(dst)) goto done; if (src_pixmap_priv->type == GLAMOR_DRM_ONLY || dst_pixmap_priv->type == GLAMOR_DRM_ONLY) { LogMessage(X_WARNING, "Access a DRM only pixmap is not allowed within glamor.\n"); return TRUE; } glamor_report_delayed_fallbacks(src->pScreen); glamor_report_delayed_fallbacks(dst->pScreen); glamor_fallback("from %p to %p (%c,%c)\n", src, dst, glamor_get_drawable_location(src), glamor_get_drawable_location(dst)); if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW) && glamor_prepare_access(src, GLAMOR_ACCESS_RO) && glamor_prepare_access_gc(gc)) { fbCopyNtoN(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure); } glamor_finish_access_gc(gc); glamor_finish_access(src); glamor_finish_access(dst); ok = TRUE; done: glamor_clear_delayed_fallbacks(src->pScreen); glamor_clear_delayed_fallbacks(dst->pScreen); return ok; }
static Bool __glamor_copy_n_to_n(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy, Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) { PixmapPtr dst_pixmap, src_pixmap, temp_pixmap = NULL; DrawablePtr temp_src = src; glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv; glamor_screen_private *glamor_priv; BoxRec bound; 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; Bool ret = FALSE; 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; glamor_priv = glamor_get_screen_private(dst->pScreen); 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->base.fbo && src_pixmap_priv->base.fbo->fb == dst_pixmap_priv->base.fbo->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; } } } DEBUGF("Copy %d %d %dx%d dx %d dy %d from %p to %p \n", box[0].x1, box[0].y1, box[0].x2 - box[0].x1, box[0].y2 - box[0].y1, dx, dy, src_pixmap, dst_pixmap); #ifndef GLAMOR_GLES2 if (!overlaped && (glamor_priv->state != RENDER_STATE || !src_pixmap_priv->base.gl_tex || !dst_pixmap_priv->base.gl_tex) && glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) { ret = TRUE; goto done; } #endif glamor_calculate_boxes_bound(&bound, box, nbox); /* Overlaped indicate the src and dst are the same pixmap. */ if (overlaped || (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv) && (((bound.x2 - bound.x1) * (bound.y2 - bound.y1) * 4 > src_pixmap->drawable.width * src_pixmap->drawable.height) || !(glamor_check_fbo_size(glamor_priv, src_pixmap->drawable.width, src_pixmap->drawable.height))))) { temp_pixmap = glamor_create_pixmap(screen, bound.x2 - bound.x1, bound.y2 - bound.y1, src_pixmap-> drawable.depth, overlaped ? 0 : GLAMOR_CREATE_PIXMAP_CPU); assert(bound.x2 - bound.x1 <= glamor_priv->max_fbo_size); assert(bound.y2 - bound.y1 <= glamor_priv->max_fbo_size); if (!temp_pixmap) goto done; glamor_translate_boxes(box, nbox, -bound.x1, -bound.y1); temp_src = &temp_pixmap->drawable; if (overlaped) glamor_copy_n_to_n_textured(src, temp_src, gc, box, nbox, temp_dx + bound.x1, temp_dy + bound.y1); else fbCopyNtoN(src, temp_src, gc, box, nbox, temp_dx + bound.x1, temp_dy + bound.y1, reverse, upsidedown, bitplane, closure); glamor_translate_boxes(box, nbox, bound.x1, bound.y1); temp_dx = -bound.x1; temp_dy = -bound.y1; } else { temp_dx = dx; temp_dy = dy; temp_src = src; } if (glamor_copy_n_to_n_textured (temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) { ret = TRUE; } done: if (temp_src != src) glamor_destroy_pixmap(temp_pixmap); return ret; }