static void image_cache_put(SpiceImageCache *spice_cache, uint64_t id, pixman_image_t *image) { ImageCache *cache = SPICE_UPCAST(ImageCache, spice_cache); ImageCacheItem *item; #ifndef IMAGE_CACHE_AGE if (cache->num_items == IMAGE_CACHE_MAX_ITEMS) { SPICE_VERIFY(SPICE_OFFSETOF(ImageCacheItem, lru_link) == 0); ImageCacheItem *tail = (ImageCacheItem *)ring_get_tail(&cache->lru); spice_assert(tail); image_cache_remove(cache, tail); } #endif item = spice_new(ImageCacheItem, 1); item->id = id; #ifdef IMAGE_CACHE_AGE item->age = cache->age; #else cache->num_items++; #endif item->image = pixman_image_ref(image); ring_item_init(&item->lru_link); item->next = cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE]; cache->hash_table[item->id % IMAGE_CACHE_HASH_SIZE] = item; ring_add(&cache->lru, &item->lru_link); }
static pixman_image_t *image_cache_get(SpiceImageCache *spice_cache, uint64_t id) { ImageCache *cache = SPICE_UPCAST(ImageCache, spice_cache); ImageCacheItem *item = image_cache_find(cache, id); if (!item) { spice_error("not found"); } return pixman_image_ref(item->image); }
static void qemu_spice_create_update(SimpleSpiceDisplay *ssd) { static const int blksize = 32; int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize; int dirty_top[blocks]; int y, yoff, x, xoff, blk, bw; int bpp = surface_bytes_per_pixel(ssd->ds); uint8_t *guest, *mirror; if (qemu_spice_rect_is_empty(&ssd->dirty)) { return; }; if (ssd->surface == NULL) { ssd->surface = pixman_image_ref(ssd->ds->image); ssd->mirror = qemu_pixman_mirror_create(ssd->ds->format, ssd->ds->image); } for (blk = 0; blk < blocks; blk++) { dirty_top[blk] = -1; } guest = surface_data(ssd->ds); mirror = (void *)pixman_image_get_data(ssd->mirror); for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) { yoff = y * surface_stride(ssd->ds); for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) { xoff = x * bpp; blk = x / blksize; bw = MIN(blksize, ssd->dirty.right - x); if (memcmp(guest + yoff + xoff, mirror + yoff + xoff, bw * bpp) == 0) { if (dirty_top[blk] != -1) { QXLRect update = { .top = dirty_top[blk], .bottom = y, .left = x, .right = x + bw, }; qemu_spice_create_one_update(ssd, &update); dirty_top[blk] = -1; } } else { if (dirty_top[blk] == -1) { dirty_top[blk] = y; } } } }
WL_EXPORT void pixman_renderer_output_set_buffer(struct weston_output *output, pixman_image_t *buffer) { struct pixman_output_state *po = get_output_state(output); if (po->hw_buffer) pixman_image_unref(po->hw_buffer); po->hw_buffer = buffer; if (po->hw_buffer) { output->compositor->read_format = pixman_image_get_format(po->hw_buffer); pixman_image_ref(po->hw_buffer); } }
static cairo_status_t fixup_unbounded (const cairo_composite_rectangles_t *extents) { cairo_image_surface_t *dst = (cairo_image_surface_t *)extents->surface; pixman_image_t *mask; int mask_x, mask_y; if (! _cairo_clip_is_region (extents->clip)) { cairo_image_surface_t *clip; clip = get_clip_surface (dst, extents, &mask_x, &mask_y); if (unlikely (clip->base.status)) return clip->base.status; mask = pixman_image_ref (clip->pixman_image); cairo_surface_destroy (&clip->base); } else { mask_x = mask_y = 0; mask = _pixman_image_for_color (CAIRO_COLOR_WHITE); if (unlikely (mask == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } /* top */ if (extents->bounded.y != extents->unbounded.y) { int x = extents->unbounded.x; int y = extents->unbounded.y; int width = extents->unbounded.width; int height = extents->bounded.y - y; pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, mask, NULL, dst->pixman_image, x - mask_x, y - mask_y, 0, 0, x, y, width, height); } /* left */ if (extents->bounded.x != extents->unbounded.x) { int x = extents->unbounded.x; int y = extents->bounded.y; int width = extents->bounded.x - x; int height = extents->bounded.height; pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, mask, NULL, dst->pixman_image, x - mask_x, y - mask_y, 0, 0, x, y, width, height); } /* right */ if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) { int x = extents->bounded.x + extents->bounded.width; int y = extents->bounded.y; int width = extents->unbounded.x + extents->unbounded.width - x; int height = extents->bounded.height; pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, mask, NULL, dst->pixman_image, x - mask_x, y - mask_y, 0, 0, x, y, width, height); } /* bottom */ if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) { int x = extents->unbounded.x; int y = extents->bounded.y + extents->bounded.height; int width = extents->unbounded.width; int height = extents->unbounded.y + extents->unbounded.height - y; pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, mask, NULL, dst->pixman_image, x - mask_x, y - mask_y, 0, 0, x, y, width, height); } pixman_image_unref (mask); return CAIRO_STATUS_SUCCESS; }