static PicturePtr create_white_solid(ScreenPtr screen) { PicturePtr white, ret = NULL; xRenderColor color; int error; color.red = color.green = color.blue = color.alpha = 0xffff; white = CreateSolidPicture(0, &color, &error); if (white) { ret = uxa_acquire_solid(screen, white->pSourcePict); FreePicture(white, 0); } return ret; }
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 uxa_check_glyphs(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs) { pixman_image_t *image; PixmapPtr scratch; PicturePtr mask, mask_src = NULL, mask_dst = NULL, white = NULL; int width = 0, height = 0; int x, y, n; int xDst = list->xOff, yDst = list->yOff; BoxRec extents = { 0, 0, 0, 0 }; CARD8 mask_op = 0; if (maskFormat) { pixman_format_code_t format; CARD32 component_alpha; xRenderColor color; int error; uxa_glyph_extents(nlist, list, glyphs, &extents); if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) return; width = extents.x2 - extents.x1; height = extents.y2 - extents.y1; format = maskFormat->format | (BitsPerPixel(maskFormat->depth) << 24); image = pixman_image_create_bits(format, width, height, NULL, 0); if (!image) return; scratch = GetScratchPixmapHeader(dst->pDrawable->pScreen, width, height, PIXMAN_FORMAT_DEPTH(format), PIXMAN_FORMAT_BPP(format), pixman_image_get_stride(image), pixman_image_get_data(image)); if (!scratch) { pixman_image_unref(image); return; } component_alpha = NeedsComponent(maskFormat->format); mask = CreatePicture(0, &scratch->drawable, maskFormat, CPComponentAlpha, &component_alpha, serverClient, &error); if (!mask) { FreeScratchPixmapHeader(scratch); pixman_image_unref(image); return; } ValidatePicture(mask); x = -extents.x1; y = -extents.y1; color.red = color.green = color.blue = color.alpha = 0xffff; white = CreateSolidPicture(0, &color, &error); mask_op = op; op = PictOpAdd; mask_src = src; src = white; mask_dst = dst; dst = mask; } else { mask = dst; x = 0; y = 0; } while (nlist--) { x += list->xOff; y += list->yOff; n = list->len; while (n--) { GlyphPtr glyph = *glyphs++; PicturePtr g = GetGlyphPicture(glyph, dst->pDrawable->pScreen); if (g) { CompositePicture(op, src, g, dst, xSrc + (x - glyph->info.x) - xDst, ySrc + (y - glyph->info.y) - yDst, 0, 0, x - glyph->info.x, y - glyph->info.y, glyph->info.width, glyph->info.height); } x += glyph->info.xOff; y += glyph->info.yOff; } list++; } if (white) FreePicture(white, 0); if (maskFormat) { x = extents.x1; y = extents.y1; CompositePicture(mask_op, mask_src, mask, mask_dst, xSrc + x - xDst, ySrc + y - yDst, 0, 0, x, y, width, height); FreePicture(mask, 0); FreeScratchPixmapHeader(scratch); pixman_image_unref(image); } }