예제 #1
0
파일: image-cache.c 프로젝트: fgouget/spice
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);
}
예제 #2
0
파일: image-cache.c 프로젝트: fgouget/spice
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);
}
예제 #3
0
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;
                }
            }
        }
    }
예제 #4
0
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;
}