mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-common
synced 2025-12-26 14:18:36 +00:00
Use pixman_image_t instead of cairo_surface_t as the generic pixman container
This allows us to use the simpler dependency of pixman outside of the cairo backend, and it later lets us move the cairo backend to using pixman only.
This commit is contained in:
parent
1d3ac0b931
commit
44de7fcff4
151
cairo_canvas.c
151
cairo_canvas.c
@ -297,7 +297,7 @@ static inline void canvas_invers_1bpp_be(uint8_t* dest, int dest_stride, uint8_t
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, SpiceBitmap* bitmap,
|
||||
static pixman_image_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, SpiceBitmap* bitmap,
|
||||
SpicePalette *palette)
|
||||
{
|
||||
uint8_t* src = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
|
||||
@ -305,21 +305,20 @@ static cairo_surface_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, Spi
|
||||
uint8_t* end;
|
||||
uint8_t* dest;
|
||||
int dest_stride;
|
||||
cairo_surface_t* cairo_surface;
|
||||
pixman_image_t* surface;
|
||||
|
||||
src_stride = bitmap->stride;
|
||||
end = src + (bitmap->y * src_stride);
|
||||
access_test(&canvas->base, src, bitmap->y * src_stride);
|
||||
|
||||
cairo_surface = cairo_image_surface_create((bitmap->format == SPICE_BITMAP_FMT_RGBA) ?
|
||||
CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
|
||||
bitmap->x, bitmap->y);
|
||||
if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(cairo_surface)));
|
||||
surface = pixman_image_create_bits((bitmap->format == SPICE_BITMAP_FMT_RGBA) ?
|
||||
PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
|
||||
bitmap->x, bitmap->y, NULL, 0);
|
||||
if (surface == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
dest = cairo_image_surface_get_data(cairo_surface);
|
||||
dest_stride = cairo_image_surface_get_stride(cairo_surface);
|
||||
dest = (uint8_t *)pixman_image_get_data(surface);
|
||||
dest_stride = pixman_image_get_stride(surface);
|
||||
|
||||
if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
|
||||
ASSERT(bitmap->y > 0);
|
||||
@ -347,7 +346,7 @@ static cairo_surface_t *canvas_bitmap_to_invers_surface(CairoCanvas *canvas, Spi
|
||||
canvas_invers_1bpp_be(dest, dest_stride, src, src_stride, bitmap->x, end, palette);
|
||||
break;
|
||||
}
|
||||
return cairo_surface;
|
||||
return surface;
|
||||
}
|
||||
|
||||
#if defined(CAIRO_CANVAS_CACHE) || defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
@ -386,11 +385,11 @@ static void free_palette(SpiceBitmap *bitmap, SpicePalette *palette)
|
||||
|
||||
#endif
|
||||
|
||||
static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
|
||||
static pixman_image_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *invers = NULL;
|
||||
pixman_image_t *surface;
|
||||
pixman_image_t *invers = NULL;
|
||||
|
||||
access_test(&canvas->base, descriptor, sizeof(SpiceImageDescriptor));
|
||||
|
||||
@ -469,13 +468,13 @@ static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRE
|
||||
}
|
||||
|
||||
invers = canvas_handle_inverse_user_data(surface);
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
return invers;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static cairo_surface_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitmap)
|
||||
static pixman_image_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitmap)
|
||||
{
|
||||
SpicePalette *palette;
|
||||
|
||||
@ -486,7 +485,7 @@ static cairo_surface_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitm
|
||||
if (canvas->color_shift == 5) {
|
||||
int size = sizeof(SpicePalette) + (palette->num_ents << 2);
|
||||
SpicePalette *local_palette = malloc(size);
|
||||
cairo_surface_t* surface;
|
||||
pixman_image_t* surface;
|
||||
|
||||
memcpy(local_palette, palette, size);
|
||||
canvas_localize_palette(canvas, palette);
|
||||
@ -498,7 +497,7 @@ static cairo_surface_t *canvas_get_invers(CairoCanvas *canvas, SpiceBitmap *bitm
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
|
||||
static pixman_image_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
|
||||
@ -522,28 +521,28 @@ static cairo_surface_t *canvas_get_invers_image(CairoCanvas *canvas, SPICE_ADDRE
|
||||
|
||||
#endif
|
||||
|
||||
static cairo_surface_t* canvas_surface_from_self(CairoCanvas *canvas, SpicePoint *pos,
|
||||
int32_t width, int32_t heigth)
|
||||
static pixman_image_t* canvas_surface_from_self(CairoCanvas *canvas, SpicePoint *pos,
|
||||
int32_t width, int32_t heigth)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *src_surface;
|
||||
pixman_image_t *surface;
|
||||
pixman_image_t *src_surface;
|
||||
uint8_t *dest;
|
||||
int dest_stride;
|
||||
uint8_t *src;
|
||||
int src_stride;
|
||||
int i;
|
||||
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, heigth);
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, heigth, NULL, 0);
|
||||
if (surface == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
dest = cairo_image_surface_get_data(surface);
|
||||
dest_stride = cairo_image_surface_get_stride(surface);
|
||||
|
||||
src_surface = cairo_get_target(canvas->cairo);
|
||||
src = cairo_image_surface_get_data(src_surface);
|
||||
src_stride = cairo_image_surface_get_stride(src_surface);
|
||||
dest = (uint8_t *)pixman_image_get_data(surface);
|
||||
dest_stride = pixman_image_get_stride(surface);
|
||||
|
||||
src_surface = canvas->image;
|
||||
src = (uint8_t *)pixman_image_get_data(src_surface);
|
||||
src_stride = pixman_image_get_stride(src_surface);
|
||||
src += pos->y * src_stride + (pos->x << 2);
|
||||
for (i = 0; i < heigth; i++, dest += dest_stride, src += src_stride) {
|
||||
memcpy(dest, src, width << 2);
|
||||
@ -566,7 +565,8 @@ static cairo_pattern_t *canvas_get_brush(CairoCanvas *canvas, SpiceBrush *brush,
|
||||
return cairo_pattern_create_rgb(r, g, b);
|
||||
}
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
cairo_surface_t* surface;
|
||||
pixman_image_t* surface;
|
||||
cairo_surface_t* cairo_surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
@ -575,13 +575,15 @@ static cairo_pattern_t *canvas_get_brush(CairoCanvas *canvas, SpiceBrush *brush,
|
||||
} else {
|
||||
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
|
||||
}
|
||||
pattern = cairo_pattern_create_for_surface(surface);
|
||||
cairo_surface = surface_from_pixman_image (surface);
|
||||
pixman_image_unref (surface);
|
||||
pattern = cairo_pattern_create_for_surface(cairo_surface);
|
||||
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_surface_destroy(cairo_surface);
|
||||
CANVAS_ERROR("create pattern failed, %s",
|
||||
cairo_status_to_string(cairo_pattern_status(pattern)));
|
||||
}
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_surface_destroy(cairo_surface);
|
||||
cairo_matrix_init_translate(&matrix, -brush->u.pattern.pos.x, -brush->u.pattern.pos.y);
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
|
||||
@ -666,20 +668,23 @@ static inline void canvas_draw(CairoCanvas *canvas, SpiceBrush *brush, uint16_t
|
||||
|
||||
static cairo_pattern_t *canvas_get_mask_pattern(CairoCanvas *canvas, SpiceQMask *mask, int x, int y)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
cairo_surface_t *cairo_surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
if (!(surface = canvas_get_mask(&canvas->base, mask))) {
|
||||
return NULL;
|
||||
}
|
||||
pattern = cairo_pattern_create_for_surface(surface);
|
||||
cairo_surface = surface_from_pixman_image (surface);
|
||||
pixman_image_unref (surface);
|
||||
pattern = cairo_pattern_create_for_surface(cairo_surface);
|
||||
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_surface_destroy(cairo_surface);
|
||||
CANVAS_ERROR("create pattern failed, %s",
|
||||
cairo_status_to_string(cairo_pattern_status(pattern)));
|
||||
}
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_surface_destroy(cairo_surface);
|
||||
|
||||
cairo_matrix_init_translate(&matrix, mask->pos.x - x, mask->pos.y - y);
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
@ -724,7 +729,8 @@ static cairo_pattern_t *canvas_src_image_to_pat(CairoCanvas *canvas, SPICE_ADDRE
|
||||
int scale_mode)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
cairo_surface_t *cairo_surface;
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
ASSERT(src_bitmap);
|
||||
@ -735,8 +741,10 @@ static cairo_pattern_t *canvas_src_image_to_pat(CairoCanvas *canvas, SPICE_ADDRE
|
||||
surface = canvas_get_image(&canvas->base, src_bitmap);
|
||||
}
|
||||
|
||||
pattern = cairo_pattern_create_for_surface(surface);
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_surface = surface_from_pixman_image (surface);
|
||||
pixman_image_unref (surface);
|
||||
pattern = cairo_pattern_create_for_surface(cairo_surface);
|
||||
cairo_surface_destroy(cairo_surface);
|
||||
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create pattern failed, %s",
|
||||
cairo_status_to_string(cairo_pattern_status(pattern)));
|
||||
@ -1124,8 +1132,9 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
{
|
||||
cairo_t *cairo = canvas->cairo;
|
||||
cairo_pattern_t *mask;
|
||||
pixman_image_t *dd;
|
||||
cairo_surface_t *d;
|
||||
cairo_surface_t *s;
|
||||
pixman_image_t *s;
|
||||
SpicePoint pos;
|
||||
int width;
|
||||
int heigth;
|
||||
@ -1142,13 +1151,13 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
cairo_user_to_device(cairo, &x_pos, &y_pos);
|
||||
pos.x = (int32_t)x_pos;
|
||||
pos.y = (int32_t)y_pos;
|
||||
d = canvas_surface_from_self(canvas, &pos, width, heigth);
|
||||
dd = canvas_surface_from_self(canvas, &pos, width, heigth);
|
||||
s = canvas_get_image(&canvas->base, rop3->src_bitmap);
|
||||
|
||||
if (!rect_is_same_size(bbox, &rop3->src_area)) {
|
||||
cairo_surface_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
|
||||
pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
|
||||
rop3->scale_mode);
|
||||
cairo_surface_destroy(s);
|
||||
pixman_image_unref(s);
|
||||
s = scaled_s;
|
||||
src_pos.x = 0;
|
||||
src_pos.y = 0;
|
||||
@ -1156,26 +1165,28 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
src_pos.x = rop3->src_area.left;
|
||||
src_pos.y = rop3->src_area.top;
|
||||
}
|
||||
if (cairo_image_surface_get_width(s) - src_pos.x < width ||
|
||||
cairo_image_surface_get_height(s) - src_pos.y < heigth) {
|
||||
if (pixman_image_get_width(s) - src_pos.x < width ||
|
||||
pixman_image_get_height(s) - src_pos.y < heigth) {
|
||||
CANVAS_ERROR("bad src bitmap size");
|
||||
}
|
||||
if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
|
||||
cairo_surface_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
|
||||
pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
|
||||
SpicePoint pat_pos;
|
||||
|
||||
pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % cairo_image_surface_get_width(p);
|
||||
pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % cairo_image_surface_get_height(p);
|
||||
do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
|
||||
cairo_surface_destroy(p);
|
||||
pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
|
||||
pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
|
||||
do_rop3_with_pattern(rop3->rop3, dd, s, &src_pos, p, &pat_pos);
|
||||
pixman_image_unref(p);
|
||||
} else {
|
||||
uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
|
||||
canvas_16bpp_to_32bpp(rop3->brush.u.color);
|
||||
do_rop3_with_color(rop3->rop3, d, s, &src_pos, color);
|
||||
do_rop3_with_color(rop3->rop3, dd, s, &src_pos, color);
|
||||
}
|
||||
cairo_surface_destroy(s);
|
||||
pixman_image_unref(s);
|
||||
d = surface_from_pixman_image (dd);
|
||||
cairo_set_source_surface(cairo, d, bbox->left, bbox->top);
|
||||
cairo_surface_destroy(d);
|
||||
pixman_image_unref (dd);
|
||||
if ((mask = canvas_get_mask_pattern(canvas, &rop3->mask, bbox->left, bbox->top))) {
|
||||
cairo_rectangle(cairo,
|
||||
bbox->left,
|
||||
@ -1360,7 +1371,8 @@ static inline void __canvas_copy_region_bits(uint8_t *data, int stride, SpiceRec
|
||||
void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
|
||||
{
|
||||
cairo_t *cairo = canvas->cairo;
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *cairo_surface;
|
||||
pixman_image_t *surface;
|
||||
int32_t width;
|
||||
int32_t heigth;
|
||||
|
||||
@ -1368,22 +1380,20 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
#ifdef FAST_COPY_BITS
|
||||
switch (clip->type) {
|
||||
case SPICE_CLIP_TYPE_NONE: {
|
||||
surface = cairo_get_target(cairo);
|
||||
__canvas_copy_rect_bits(cairo_image_surface_get_data(surface),
|
||||
cairo_image_surface_get_stride(surface),
|
||||
__canvas_copy_rect_bits((uint8_t *)pixman_image_get_data(canvas->image),
|
||||
pixman_image_get_stride(canvas->image),
|
||||
bbox, src_pos);
|
||||
break;
|
||||
}
|
||||
case SPICE_CLIP_TYPE_RECTS: {
|
||||
surface = cairo_get_target(cairo);
|
||||
uint32_t *n = (uint32_t *)SPICE_GET_ADDRESS(clip->data);
|
||||
access_test(&canvas->base, n, sizeof(uint32_t));
|
||||
|
||||
SpiceRect *now = (SpiceRect *)(n + 1);
|
||||
SpiceRect *end = now + *n;
|
||||
access_test(&canvas->base, now, (unsigned long)end - (unsigned long)now);
|
||||
uint8_t *data = cairo_image_surface_get_data(surface);
|
||||
int stride = cairo_image_surface_get_stride(surface);
|
||||
uint8_t *data = (uint8_t *)pixman_image_get_data(canvas->image);
|
||||
int stride = pixman_image_get_stride(canvas->image);
|
||||
|
||||
//using QRegion in order to sort and remove intersections
|
||||
QRegion region;
|
||||
@ -1402,11 +1412,13 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
width = bbox->right - bbox->left;
|
||||
heigth = bbox->bottom - bbox->top;
|
||||
surface = canvas_surface_from_self(canvas, src_pos, width, heigth);
|
||||
cairo_set_source_surface(cairo, surface, bbox->left, bbox->top);
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_surface = surface_from_pixman_image (surface);
|
||||
cairo_set_source_surface(cairo, cairo_surface, bbox->left, bbox->top);
|
||||
cairo_rectangle(cairo, bbox->left, bbox->top, width, heigth);
|
||||
cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY);
|
||||
cairo_fill(cairo);
|
||||
cairo_surface_destroy(cairo_surface);
|
||||
pixman_image_unref (surface);
|
||||
#ifdef FAST_COPY_BITS
|
||||
}
|
||||
|
||||
@ -1417,16 +1429,18 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
static void canvas_draw_raster_str(CairoCanvas *canvas, SpiceString *str, int bpp,
|
||||
SpiceBrush *brush, uint16_t rop_decriptor)
|
||||
{
|
||||
cairo_surface_t *str_mask;
|
||||
pixman_image_t *str_mask;
|
||||
cairo_surface_t *cairo_str_mask;
|
||||
DrawMaskData draw_data;
|
||||
cairo_matrix_t matrix;
|
||||
SpicePoint pos;
|
||||
|
||||
str_mask = canvas_get_str_mask(&canvas->base, str, bpp, &pos);
|
||||
cairo_str_mask = surface_from_pixman_image (str_mask);
|
||||
draw_data.cairo = canvas->cairo;
|
||||
draw_data.mask = cairo_pattern_create_for_surface(str_mask);
|
||||
draw_data.mask = cairo_pattern_create_for_surface(cairo_str_mask);
|
||||
if (cairo_pattern_status(draw_data.mask) != CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_destroy(str_mask);
|
||||
cairo_surface_destroy(cairo_str_mask);
|
||||
CANVAS_ERROR("create pattern failed, %s",
|
||||
cairo_status_to_string(cairo_pattern_status(draw_data.mask)));
|
||||
}
|
||||
@ -1434,7 +1448,8 @@ static void canvas_draw_raster_str(CairoCanvas *canvas, SpiceString *str, int bp
|
||||
cairo_pattern_set_matrix(draw_data.mask, &matrix);
|
||||
canvas_draw(canvas, brush, rop_decriptor, __draw_mask, &draw_data);
|
||||
cairo_pattern_destroy(draw_data.mask);
|
||||
cairo_surface_destroy(str_mask);
|
||||
pixman_image_unref(str_mask);
|
||||
cairo_surface_destroy(cairo_str_mask);
|
||||
}
|
||||
|
||||
static void canvas_draw_vector_str(CairoCanvas *canvas, SpiceString *str, SpiceBrush *brush,
|
||||
|
||||
323
canvas_base.c
323
canvas_base.c
@ -21,6 +21,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <spice/draw.h>
|
||||
#include "quic.h"
|
||||
@ -76,6 +77,8 @@
|
||||
#define MAX(x, y) (((x) >= (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define ROUND(_x) floor((_x) + 0.5)
|
||||
|
||||
#ifdef WIN32
|
||||
typedef struct __declspec (align(1)) LZImage {
|
||||
#else
|
||||
@ -88,12 +91,7 @@ typedef struct __attribute__ ((__packed__)) LZImage {
|
||||
};
|
||||
} LZImage;
|
||||
|
||||
static const cairo_user_data_key_t invers_data_type = {0};
|
||||
|
||||
#ifdef CAIRO_CANVAS_CACH_IS_SHARED
|
||||
/* should be defined and initialized once in application.cpp */
|
||||
extern mutex_t cairo_surface_user_data_mutex;
|
||||
#endif
|
||||
static const cairo_user_data_key_t pixman_data_type = {0};
|
||||
|
||||
static inline double fix_to_double(SPICE_FIXED28_4 fixed)
|
||||
{
|
||||
@ -234,9 +232,13 @@ pixman_image_from_surface (cairo_surface_t *surface)
|
||||
pixman_image_t *image;
|
||||
cairo_format_t format;
|
||||
|
||||
|
||||
format = cairo_image_surface_get_format (surface);
|
||||
|
||||
image = (pixman_image_t *)cairo_surface_get_user_data(surface, &pixman_data_type);
|
||||
|
||||
if (image)
|
||||
return pixman_image_ref (image);
|
||||
|
||||
image = pixman_image_create_bits (pixman_format_from_cairo_format (format),
|
||||
cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
@ -246,6 +248,44 @@ pixman_image_from_surface (cairo_surface_t *surface)
|
||||
return image;
|
||||
}
|
||||
|
||||
static cairo_format_t
|
||||
cairo_format_from_depth (int depth)
|
||||
{
|
||||
switch (depth) {
|
||||
case 1:
|
||||
return CAIRO_FORMAT_A1;
|
||||
case 8:
|
||||
return CAIRO_FORMAT_A8;
|
||||
case 24:
|
||||
return CAIRO_FORMAT_RGB24;
|
||||
case 32:
|
||||
default:
|
||||
return CAIRO_FORMAT_ARGB32;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
surface_from_pixman_image (pixman_image_t *image)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
int depth;
|
||||
|
||||
depth = pixman_image_get_depth (image);
|
||||
|
||||
surface = cairo_image_surface_create_for_data ((uint8_t *)pixman_image_get_data (image),
|
||||
cairo_format_from_depth (depth),
|
||||
pixman_image_get_width (image),
|
||||
pixman_image_get_height (image),
|
||||
pixman_image_get_stride (image));
|
||||
|
||||
|
||||
if (cairo_surface_set_user_data (surface, &pixman_data_type,
|
||||
image, (cairo_destroy_func_t) pixman_image_unref) == CAIRO_STATUS_SUCCESS)
|
||||
pixman_image_ref (image);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void canvas_localize_palette(CanvasBase *canvas, SpicePalette *palette)
|
||||
@ -261,11 +301,11 @@ static inline void canvas_localize_palette(CanvasBase *canvas, SpicePalette *pal
|
||||
|
||||
//#define DEBUG_DUMP_COMPRESS
|
||||
#ifdef DEBUG_DUMP_COMPRESS
|
||||
static void dump_surface(cairo_surface_t *surface, int cache);
|
||||
static void dump_surface(pixman_image_t *surface, int cache);
|
||||
#endif
|
||||
static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image, int invers)
|
||||
static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *image, int invers)
|
||||
{
|
||||
cairo_surface_t *surface = NULL;
|
||||
pixman_image_t *surface = NULL;
|
||||
QuicData *quic_data = &canvas->quic_data;
|
||||
QuicImageType type;
|
||||
uint8_t *dest;
|
||||
@ -279,7 +319,7 @@ static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *imag
|
||||
#endif
|
||||
|
||||
if (setjmp(quic_data->jmp_env)) {
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
CANVAS_ERROR("quic error, %s", quic_data->message_buf);
|
||||
}
|
||||
|
||||
@ -320,18 +360,18 @@ static cairo_surface_t *canvas_get_quic(CanvasBase *canvas, SpiceQUICImage *imag
|
||||
#ifdef WIN32
|
||||
canvas->dc,
|
||||
#endif
|
||||
alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
|
||||
alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
|
||||
width, height, FALSE);
|
||||
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
if (surface == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
dest = cairo_image_surface_get_data(surface);
|
||||
stride = cairo_image_surface_get_stride(surface);
|
||||
dest = (uint8_t *)pixman_image_get_data(surface);
|
||||
stride = pixman_image_get_stride(surface);
|
||||
if (quic_decode(quic_data->quic, alpha ? QUIC_IMAGE_TYPE_RGBA : QUIC_IMAGE_TYPE_RGB32,
|
||||
dest, stride) == QUIC_ERROR) {
|
||||
pixman_image_unref(surface);
|
||||
CANVAS_ERROR("quic decode failed");
|
||||
}
|
||||
|
||||
@ -463,33 +503,32 @@ static inline void canvas_copy_1bpp_be(uint8_t* dest, int dest_stride, uint8_t*
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
|
||||
SpicePalette *palette)
|
||||
static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
|
||||
SpicePalette *palette)
|
||||
{
|
||||
uint8_t* src = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
|
||||
int src_stride;
|
||||
uint8_t* end;
|
||||
uint8_t* dest;
|
||||
int dest_stride;
|
||||
cairo_surface_t* cairo_surface;
|
||||
pixman_image_t* image;
|
||||
|
||||
src_stride = bitmap->stride;
|
||||
end = src + (bitmap->y * src_stride);
|
||||
access_test(canvas, src, bitmap->y * src_stride);
|
||||
|
||||
cairo_surface = surface_create(
|
||||
image = surface_create(
|
||||
#ifdef WIN32
|
||||
canvas->dc,
|
||||
#endif
|
||||
(bitmap->format == SPICE_BITMAP_FMT_RGBA) ? CAIRO_FORMAT_ARGB32 :
|
||||
CAIRO_FORMAT_RGB24,
|
||||
(bitmap->format == SPICE_BITMAP_FMT_RGBA) ? PIXMAN_a8r8g8b8 :
|
||||
PIXMAN_x8r8g8b8,
|
||||
bitmap->x, bitmap->y, FALSE);
|
||||
if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(cairo_surface)));
|
||||
if (image == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
dest = cairo_image_surface_get_data(cairo_surface);
|
||||
dest_stride = cairo_image_surface_get_stride(cairo_surface);
|
||||
dest = (uint8_t *)pixman_image_get_data(image);
|
||||
dest_stride = pixman_image_get_stride(image);
|
||||
if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
|
||||
ASSERT(bitmap->y > 0);
|
||||
dest += dest_stride * ((int)bitmap->y - 1);
|
||||
@ -517,7 +556,7 @@ static cairo_surface_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap
|
||||
canvas_copy_1bpp_be(dest, dest_stride, src, src_stride, bitmap->x, end, palette);
|
||||
break;
|
||||
}
|
||||
return cairo_surface;
|
||||
return image;
|
||||
}
|
||||
|
||||
#ifdef CAIRO_CANVAS_CACHE
|
||||
@ -544,7 +583,7 @@ static inline SpicePalette *canvas_get_palett(CanvasBase *canvas, SPICE_ADDRESS
|
||||
return palette;
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int invers)
|
||||
static pixman_image_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int invers)
|
||||
{
|
||||
LzData *lz_data = &canvas->lz_data;
|
||||
uint8_t *comp_buf = NULL;
|
||||
@ -612,7 +651,7 @@ static cairo_surface_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int in
|
||||
alloc_lz_image_surface(&lz_data->decode_data, alpha ? LZ_IMAGE_TYPE_RGBA : LZ_IMAGE_TYPE_RGB32,
|
||||
width, height, n_comp_pixels, top_down);
|
||||
|
||||
src = cairo_image_surface_get_data(lz_data->decode_data.out_surface);
|
||||
src = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface);
|
||||
|
||||
stride = (n_comp_pixels / height) * 4;
|
||||
if (!top_down) {
|
||||
@ -644,7 +683,7 @@ static cairo_surface_t *canvas_get_lz(CanvasBase *canvas, LZImage *image, int in
|
||||
|
||||
// don't handle plts since bitmaps with plt can be decoded globaly to RGB32 (because
|
||||
// same byte sequence can be transformed to different RGB pixels by different plts)
|
||||
static cairo_surface_t *canvas_get_glz(CanvasBase *canvas, LZImage *image)
|
||||
static pixman_image_t *canvas_get_glz(CanvasBase *canvas, LZImage *image)
|
||||
{
|
||||
ASSERT(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB);
|
||||
#ifdef WIN32
|
||||
@ -696,9 +735,9 @@ static void dump_bitmap(SpiceBitmap *bitmap, SpicePalette *palette)
|
||||
|
||||
#endif
|
||||
|
||||
static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
{
|
||||
cairo_surface_t* surface;
|
||||
pixman_image_t* surface;
|
||||
SpicePalette *palette;
|
||||
|
||||
palette = canvas_get_palett(canvas, bitmap->palette, bitmap->flags);
|
||||
@ -720,7 +759,7 @@ static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
#else
|
||||
|
||||
|
||||
static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
{
|
||||
SpicePalette *palette;
|
||||
|
||||
@ -731,7 +770,7 @@ static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
if (canvas->color_shift == 5) {
|
||||
int size = sizeof(SpicePalette) + (palette->num_ents << 2);
|
||||
SpicePalette *local_palette = malloc(size);
|
||||
cairo_surface_t* surface;
|
||||
pixman_image_t* surface;
|
||||
|
||||
memcpy(local_palette, palette, size);
|
||||
canvas_localize_palette(canvas, local_palette);
|
||||
@ -754,21 +793,21 @@ static cairo_surface_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap)
|
||||
|
||||
#if defined(DEBUG_DUMP_SURFACE) || defined(DEBUG_DUMP_COMPRESS)
|
||||
|
||||
static void dump_surface(cairo_surface_t *surface, int cache)
|
||||
static void dump_surface(pixman_image_t *surface, int cache)
|
||||
{
|
||||
static uint32_t file_id = 0;
|
||||
int i, j;
|
||||
char file_str[200];
|
||||
cairo_format_t format = cairo_image_surface_get_format(surface);
|
||||
int depth = pixman_image_get_depth(surface);
|
||||
|
||||
if (format != CAIRO_FORMAT_RGB24 && format != CAIRO_FORMAT_ARGB32) {
|
||||
if (depth != 24 && depth != 32) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *data = cairo_image_surface_get_data(surface);
|
||||
int width = cairo_image_surface_get_width(surface);
|
||||
int height = cairo_image_surface_get_height(surface);
|
||||
int stride = cairo_image_surface_get_stride(surface);
|
||||
uint8_t *data = (uint8_t *)pixman_image_get_data(surface);
|
||||
int width = pixman_image_get_width(surface);
|
||||
int height = pixman_image_get_height(surface);
|
||||
int stride = pixman_image_surface_get_stride(surface);
|
||||
|
||||
uint32_t id = ++file_id;
|
||||
#ifdef WIN32
|
||||
@ -800,17 +839,12 @@ static void dump_surface(cairo_surface_t *surface, int cache)
|
||||
|
||||
#if defined(CAIRO_CANVAS_CACHE) || defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
|
||||
static void __release_surface(void *inv_surf)
|
||||
{
|
||||
cairo_surface_destroy((cairo_surface_t *)inv_surf);
|
||||
}
|
||||
|
||||
//#define DEBUG_LZ
|
||||
|
||||
static cairo_surface_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
static pixman_image_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
|
||||
#ifdef DEBUG_LZ
|
||||
LOG_DEBUG("canvas_get_image image type: " << (int)descriptor->type);
|
||||
@ -872,7 +906,7 @@ static cairo_surface_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
|
||||
#else
|
||||
|
||||
static cairo_surface_t *canvas_get_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
|
||||
static pixman_image_t *canvas_get_image(CairoCanvas *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
|
||||
@ -909,9 +943,9 @@ static inline uint8_t revers_bits(uint8_t byte)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
|
||||
static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
uint8_t *src_line;
|
||||
uint8_t *end_line;
|
||||
uint8_t *dest_line;
|
||||
@ -923,10 +957,9 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
|
||||
#ifdef WIN32
|
||||
canvas->dc,
|
||||
#endif
|
||||
CAIRO_FORMAT_A1, bitmap->x, bitmap->y, TRUE);
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
PIXMAN_a1, bitmap->x, bitmap->y, TRUE);
|
||||
if (surface == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
src_line = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
|
||||
@ -935,8 +968,8 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
|
||||
access_test(canvas, src_line, end_line - src_line);
|
||||
line_size = ALIGN(bitmap->x, 8) >> 3;
|
||||
|
||||
dest_stride = cairo_image_surface_get_stride(surface);
|
||||
dest_line = cairo_image_surface_get_data(surface);
|
||||
dest_stride = pixman_image_get_stride(surface);
|
||||
dest_line = (uint8_t *)pixman_image_get_data(surface);
|
||||
#if defined(GL_CANVAS)
|
||||
if ((bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
|
||||
#else
|
||||
@ -979,7 +1012,8 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
surface = NULL;
|
||||
CANVAS_ERROR("invalid bitmap format");
|
||||
}
|
||||
} else {
|
||||
@ -1009,26 +1043,27 @@ static cairo_surface_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap*
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
surface = NULL;
|
||||
CANVAS_ERROR("invalid bitmap format");
|
||||
}
|
||||
}
|
||||
return surface;
|
||||
}
|
||||
|
||||
static inline cairo_surface_t *canvas_A1_invers(cairo_surface_t *src_surf)
|
||||
static inline pixman_image_t *canvas_A1_invers(pixman_image_t *src_surf)
|
||||
{
|
||||
int width = cairo_image_surface_get_width(src_surf);
|
||||
int height = cairo_image_surface_get_height(src_surf);
|
||||
int width = pixman_image_get_width(src_surf);
|
||||
int height = pixman_image_get_height(src_surf);
|
||||
|
||||
cairo_surface_t * invers = cairo_image_surface_create(CAIRO_FORMAT_A1, width, height);
|
||||
if (cairo_surface_status(invers) == CAIRO_STATUS_SUCCESS) {
|
||||
uint8_t *src_line = cairo_image_surface_get_data(src_surf);
|
||||
int src_stride = cairo_image_surface_get_stride(src_surf);
|
||||
pixman_image_t * invers = pixman_image_create_bits(PIXMAN_a1, width, height, NULL, 0);
|
||||
if (invers != NULL) {
|
||||
uint8_t *src_line = (uint8_t *)pixman_image_get_data(src_surf);
|
||||
int src_stride = pixman_image_get_stride(src_surf);
|
||||
uint8_t *end_line = src_line + (height * src_stride);
|
||||
int line_size = ALIGN(width, 8) >> 3;
|
||||
uint8_t *dest_line = cairo_image_surface_get_data(invers);
|
||||
int dest_stride = cairo_image_surface_get_stride(invers);
|
||||
uint8_t *dest_line = (uint8_t *)pixman_image_get_data(invers);
|
||||
int dest_stride = pixman_image_get_stride(invers);
|
||||
|
||||
for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
|
||||
uint8_t *dest = dest_line;
|
||||
@ -1042,29 +1077,28 @@ static inline cairo_surface_t *canvas_A1_invers(cairo_surface_t *src_surf)
|
||||
return invers;
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_surf_to_invers(cairo_surface_t *surf)
|
||||
static pixman_image_t *canvas_surf_to_invers(pixman_image_t *surf)
|
||||
{
|
||||
int width = cairo_image_surface_get_width(surf);
|
||||
int height = cairo_image_surface_get_height(surf);
|
||||
int width = pixman_image_get_width(surf);
|
||||
int height = pixman_image_get_height(surf);
|
||||
uint8_t *dest_line;
|
||||
uint8_t *dest_line_end;
|
||||
uint8_t *src_line;
|
||||
int dest_stride;
|
||||
int src_stride;
|
||||
|
||||
ASSERT(cairo_image_surface_get_format(surf) == CAIRO_FORMAT_RGB24);
|
||||
cairo_surface_t *invers = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
||||
ASSERT(pixman_image_get_depth(surf) == 24);
|
||||
pixman_image_t *invers = pixman_image_create_bits (PIXMAN_x8r8g8b8, width, height, NULL, 0);
|
||||
|
||||
if (cairo_surface_status(invers) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(invers)));
|
||||
if (invers == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
dest_line = cairo_image_surface_get_data(invers);
|
||||
dest_stride = cairo_image_surface_get_stride(invers);
|
||||
dest_line = (uint8_t *)pixman_image_get_data(invers);
|
||||
dest_stride = pixman_image_get_stride(invers);
|
||||
dest_line_end = dest_line + dest_stride * height;
|
||||
src_line = cairo_image_surface_get_data(surf);
|
||||
src_stride = cairo_image_surface_get_stride(surf);
|
||||
src_line = (uint8_t *)pixman_image_get_data(surf);
|
||||
src_stride = pixman_image_get_stride(surf);
|
||||
|
||||
for (; dest_line != dest_line_end; dest_line += dest_stride, src_line += src_stride) {
|
||||
uint32_t *src = (uint32_t *)src_line;
|
||||
@ -1083,53 +1117,27 @@ static cairo_surface_t *canvas_surf_to_invers(cairo_surface_t *surf)
|
||||
* the returned reference, you must call cairo_surface_destroy.
|
||||
* Thread safe with respect to the user data.
|
||||
*/
|
||||
static inline cairo_surface_t* canvas_handle_inverse_user_data(cairo_surface_t* surface)
|
||||
static inline pixman_image_t* canvas_handle_inverse_user_data(pixman_image_t* surface)
|
||||
{
|
||||
cairo_surface_t *inv_surf = NULL;
|
||||
#ifdef CAIRO_CANVAS_CACH_IS_SHARED
|
||||
MUTEX_LOCK(cairo_surface_user_data_mutex);
|
||||
#endif
|
||||
inv_surf = (cairo_surface_t *)cairo_surface_get_user_data(surface, &invers_data_type);
|
||||
#ifdef CAIRO_CANVAS_CACH_IS_SHARED
|
||||
MUTEX_UNLOCK(cairo_surface_user_data_mutex);
|
||||
#endif
|
||||
if (!inv_surf) {
|
||||
if (cairo_image_surface_get_format(surface) == CAIRO_FORMAT_A1) {
|
||||
inv_surf = canvas_A1_invers(surface);
|
||||
} else {
|
||||
inv_surf = canvas_surf_to_invers(surface);
|
||||
}
|
||||
pixman_image_t *inv_surf = NULL;
|
||||
|
||||
if (cairo_surface_status(inv_surf) != CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_destroy(inv_surf);
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
}
|
||||
#ifdef CAIRO_CANVAS_CACH_IS_SHARED
|
||||
MUTEX_LOCK(cairo_surface_user_data_mutex);
|
||||
|
||||
// checking if other thread has already assigned the user data
|
||||
if (!cairo_surface_get_user_data(surface, &invers_data_type)) {
|
||||
#endif
|
||||
if (cairo_surface_set_user_data(surface, &invers_data_type, inv_surf,
|
||||
__release_surface) == CAIRO_STATUS_SUCCESS) {
|
||||
cairo_surface_reference(inv_surf);
|
||||
}
|
||||
#ifdef CAIRO_CANVAS_CACH_IS_SHARED
|
||||
}
|
||||
MUTEX_UNLOCK(cairo_surface_user_data_mutex);
|
||||
#endif
|
||||
if (pixman_image_get_depth(surface) == 1) {
|
||||
inv_surf = canvas_A1_invers(surface);
|
||||
} else {
|
||||
cairo_surface_reference(inv_surf);
|
||||
inv_surf = canvas_surf_to_invers(surface);
|
||||
}
|
||||
|
||||
if (inv_surf == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
return inv_surf;
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask)
|
||||
static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor;
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
int need_invers;
|
||||
int is_invers;
|
||||
int cache_me;
|
||||
@ -1172,11 +1180,11 @@ static cairo_surface_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask)
|
||||
}
|
||||
|
||||
if (need_invers && !is_invers) { // surface is in cache
|
||||
cairo_surface_t *inv_surf;
|
||||
pixman_image_t *inv_surf;
|
||||
|
||||
inv_surf = canvas_handle_inverse_user_data(surface);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
surface = inv_surf;
|
||||
}
|
||||
#endif
|
||||
@ -1332,12 +1340,12 @@ static void canvas_put_glyph_bits(SpiceRasterGlyph *glyph, int bpp, uint8_t *des
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
|
||||
static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
|
||||
{
|
||||
SpiceRasterGlyph *glyph = (SpiceRasterGlyph *)str->data;
|
||||
SpiceRasterGlyph *next_glyph;
|
||||
SpiceRect bounds;
|
||||
cairo_surface_t *str_mask;
|
||||
pixman_image_t *str_mask;
|
||||
uint8_t *dest;
|
||||
int dest_stride;
|
||||
int i;
|
||||
@ -1360,15 +1368,14 @@ static cairo_surface_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str
|
||||
rect_union(&bounds, &glyph_box);
|
||||
}
|
||||
|
||||
str_mask = cairo_image_surface_create((bpp == 1) ? CAIRO_FORMAT_A1 : CAIRO_FORMAT_A8,
|
||||
bounds.right - bounds.left,
|
||||
bounds.bottom - bounds.top);
|
||||
if (cairo_surface_status(str_mask) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(str_mask)));
|
||||
str_mask = pixman_image_create_bits((bpp == 1) ? PIXMAN_a1 : PIXMAN_a8,
|
||||
bounds.right - bounds.left,
|
||||
bounds.bottom - bounds.top, NULL, 0);
|
||||
if (str_mask == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
dest = cairo_image_surface_get_data(str_mask);
|
||||
dest_stride = cairo_image_surface_get_stride(str_mask);
|
||||
dest = (uint8_t *)pixman_image_get_data(str_mask);
|
||||
dest_stride = pixman_image_get_stride(str_mask);
|
||||
glyph = (SpiceRasterGlyph *)str->data;
|
||||
for (i = 0; i < str->length; i++) {
|
||||
#if defined(GL_CANVAS)
|
||||
@ -1390,47 +1397,39 @@ static inline SpiceVectorGlyph *canvas_next_vector_glyph(const SpiceVectorGlyph
|
||||
return (SpiceVectorGlyph *)((uint8_t *)(glyph + 1) + glyph->data_size);
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_scale_surface(cairo_surface_t *src, const SpiceRect *src_area, int width,
|
||||
int hight, int scale_mode)
|
||||
static pixman_image_t *canvas_scale_surface(pixman_image_t *src, const SpiceRect *src_area, int width,
|
||||
int height, int scale_mode)
|
||||
{
|
||||
cairo_t *cairo;
|
||||
cairo_surface_t *surface;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_matrix_t matrix;
|
||||
pixman_image_t *surface;
|
||||
pixman_transform_t transform;
|
||||
double sx, sy;
|
||||
|
||||
surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, hight);
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
}
|
||||
|
||||
cairo = cairo_create(surface);
|
||||
if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s", cairo_status_to_string(cairo_status(cairo)));
|
||||
}
|
||||
|
||||
pattern = cairo_pattern_create_for_surface(src);
|
||||
if (cairo_pattern_status(pattern) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create pattern failed, %s",
|
||||
cairo_status_to_string(cairo_pattern_status(pattern)));
|
||||
surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, height, NULL, 0);
|
||||
if (surface == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
sx = (double)(src_area->right - src_area->left) / width;
|
||||
sy = (double)(src_area->bottom - src_area->top) / hight;
|
||||
sy = (double)(src_area->bottom - src_area->top) / height;
|
||||
|
||||
cairo_matrix_init_translate(&matrix, src_area->left, src_area->top);
|
||||
cairo_matrix_scale(&matrix, sx, sy);
|
||||
pixman_transform_init_scale(&transform, pixman_double_to_fixed(sx), pixman_double_to_fixed(sy));
|
||||
|
||||
cairo_pattern_set_matrix(pattern, &matrix);
|
||||
pixman_image_set_transform (src, &transform);
|
||||
pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
|
||||
ASSERT(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE || scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
|
||||
cairo_pattern_set_filter(pattern, (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
|
||||
CAIRO_FILTER_NEAREST : CAIRO_FILTER_GOOD);
|
||||
pixman_image_set_filter(src,
|
||||
(scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
|
||||
NULL, 0);
|
||||
|
||||
pixman_image_composite32(PIXMAN_OP_SRC,
|
||||
src, NULL, surface,
|
||||
ROUND(src_area->left / sx), ROUND (src_area->top / sy),
|
||||
0, 0, /* mask */
|
||||
0, 0, /* dst */
|
||||
width, height);
|
||||
|
||||
pixman_image_set_transform(src, NULL);
|
||||
|
||||
cairo_set_source(cairo, pattern);
|
||||
cairo_pattern_destroy(pattern);
|
||||
cairo_paint(cairo);
|
||||
cairo_destroy(cairo);
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#define _H_CANVAS_BASE
|
||||
|
||||
|
||||
#include "cairo.h"
|
||||
#include "pixman_utils.h"
|
||||
#include "lz.h"
|
||||
#include <spice/draw.h>
|
||||
|
||||
@ -30,9 +30,9 @@ typedef struct _SpicePaletteCache SpicePaletteCache;
|
||||
typedef struct {
|
||||
void (*put)(SpiceImageCache *cache,
|
||||
uint64_t id,
|
||||
cairo_surface_t *surface);
|
||||
cairo_surface_t *(*get)(SpiceImageCache *cache,
|
||||
uint64_t id);
|
||||
pixman_image_t *surface);
|
||||
pixman_image_t *(*get)(SpiceImageCache *cache,
|
||||
uint64_t id);
|
||||
} SpiceImageCacheOps;
|
||||
|
||||
struct _SpiceImageCache {
|
||||
|
||||
152
canvas_utils.c
152
canvas_utils.c
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
Copyright (C) 2009 Red Hat, Inc.
|
||||
|
||||
@ -45,31 +46,50 @@ extern int gdi_handlers;
|
||||
#define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
|
||||
#endif
|
||||
|
||||
const cairo_user_data_key_t bitmap_data_type = {0};
|
||||
const cairo_user_data_key_t bitmap_withstride_data_type = {0};
|
||||
static void release_data(pixman_image_t *image, void *release_data)
|
||||
{
|
||||
PixmanData *data = (PixmanData *)release_data;
|
||||
|
||||
#ifdef WIN32
|
||||
static void release_bitmap(void *bitmap_cache)
|
||||
{
|
||||
DeleteObject((HBITMAP)((BitmapCache *)bitmap_cache)->bitmap);
|
||||
CloseHandle(((BitmapCache *)bitmap_cache)->mutex);
|
||||
free(bitmap_cache);
|
||||
gdi_handlers--;
|
||||
}
|
||||
|
||||
if (data->bitmap) {
|
||||
DeleteObject((HBITMAP)data->bitmap);
|
||||
CloseHandle(data->mutex);
|
||||
gdi_handlers--;
|
||||
}
|
||||
#endif
|
||||
if (data->data) {
|
||||
free(data->data);
|
||||
}
|
||||
|
||||
static void release_withstride_bitmap(void *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
static inline cairo_surface_t *__surface_create_stride(cairo_format_t format, int width, int height,
|
||||
int stride)
|
||||
static PixmanData *
|
||||
pixman_image_add_data(pixman_image_t *image)
|
||||
{
|
||||
PixmanData *data;
|
||||
|
||||
data = (PixmanData *)pixman_image_get_destroy_data(image);
|
||||
if (data == NULL) {
|
||||
data = (PixmanData *)calloc(1, sizeof(PixmanData));
|
||||
if (data == NULL) {
|
||||
CANVAS_ERROR("out of memory");
|
||||
}
|
||||
pixman_image_set_destroy_function(image,
|
||||
release_data,
|
||||
data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline pixman_image_t *__surface_create_stride(pixman_format_code_t format, int width, int height,
|
||||
int stride)
|
||||
{
|
||||
uint8_t *data;
|
||||
uint8_t *stride_data;
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
data = (uint8_t *)malloc(abs(stride) * height);
|
||||
if (stride < 0) {
|
||||
@ -78,30 +98,24 @@ static inline cairo_surface_t *__surface_create_stride(cairo_format_t format, in
|
||||
stride_data = data;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create_for_data(stride_data, format, width, height, stride);
|
||||
surface = pixman_image_create_bits(format, width, height, (uint32_t *)stride_data, stride);
|
||||
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
if (surface == NULL) {
|
||||
free(data);
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
CANVAS_ERROR("create surface failed, out of memory");
|
||||
}
|
||||
|
||||
if (cairo_surface_set_user_data(surface, &bitmap_withstride_data_type, data,
|
||||
release_withstride_bitmap) != CAIRO_STATUS_SUCCESS) {
|
||||
free(data);
|
||||
cairo_surface_destroy(surface);
|
||||
CANVAS_ERROR("set_user_data surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
}
|
||||
pixman_data = pixman_image_add_data(surface);
|
||||
pixman_data->data = data;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
cairo_surface_t *surface_create(HDC dc, cairo_format_t format,
|
||||
pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
|
||||
int width, int height, int top_down)
|
||||
#else
|
||||
cairo_surface_t * surface_create(cairo_format_t format, int width, int height, int top_down)
|
||||
pixman_image_t * surface_create(pixman_format_code_t format, int width, int height, int top_down)
|
||||
#endif
|
||||
{
|
||||
#ifdef WIN32
|
||||
@ -120,8 +134,10 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
|
||||
RGBQUAD palette[255];
|
||||
} bitmap_info;
|
||||
int nstride;
|
||||
cairo_surface_t *surface;
|
||||
BitmapCache *bitmap_cache;
|
||||
pixman_image_t *surface;
|
||||
PixmanData *pixman_data;
|
||||
HBITMAP bitmap;
|
||||
HANDLE mutex;
|
||||
|
||||
memset(&bitmap_info, 0, sizeof(bitmap_info));
|
||||
bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
|
||||
@ -131,16 +147,16 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
|
||||
|
||||
bitmap_info.inf.bmiHeader.biPlanes = 1;
|
||||
switch (format) {
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case PIXMAN_a8r8g8b8:
|
||||
case PIXMAN_x8r8g8b8:
|
||||
bitmap_info.inf.bmiHeader.biBitCount = 32;
|
||||
nstride = width * 4;
|
||||
break;
|
||||
case CAIRO_FORMAT_A8:
|
||||
case PIXMAN_a8:
|
||||
bitmap_info.inf.bmiHeader.biBitCount = 8;
|
||||
nstride = ALIGN(width, 4);
|
||||
break;
|
||||
case CAIRO_FORMAT_A1:
|
||||
case PIXMAN_a1:
|
||||
bitmap_info.inf.bmiHeader.biBitCount = 1;
|
||||
nstride = ALIGN(width, 32) / 8;
|
||||
break;
|
||||
@ -150,25 +166,15 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
|
||||
|
||||
bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
bitmap_cache = (BitmapCache *)malloc(sizeof(*bitmap_cache));
|
||||
if (!bitmap_cache) {
|
||||
CANVAS_ERROR("malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bitmap_cache->mutex = CreateMutex(NULL, 0, NULL);
|
||||
if (!bitmap_cache->mutex) {
|
||||
free(bitmap_cache);
|
||||
mutex = CreateMutex(NULL, 0, NULL);
|
||||
if (!mutex) {
|
||||
CANVAS_ERROR("Unable to CreateMutex");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bitmap_cache->bitmap = CreateDIBSection(dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
|
||||
if (!bitmap_cache->bitmap) {
|
||||
bitmap = CreateDIBSection(dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
|
||||
if (!bitmap) {
|
||||
CloseHandle(bitmap_cache->mutex);
|
||||
free(bitmap_cache);
|
||||
CANVAS_ERROR("Unable to CreateDIBSection");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (top_down) {
|
||||
@ -178,41 +184,33 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
|
||||
nstride = -nstride;
|
||||
}
|
||||
|
||||
surface = cairo_image_surface_create_for_data(src, format, width, height, nstride);
|
||||
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
CloseHandle(bitmap_cache->mutex);
|
||||
DeleteObject((HBITMAP)bitmap_cache->bitmap);
|
||||
free(bitmap_cache);
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
}
|
||||
if (cairo_surface_set_user_data(surface, &bitmap_data_type, bitmap_cache,
|
||||
release_bitmap) != CAIRO_STATUS_SUCCESS) {
|
||||
CloseHandle(bitmap_cache->mutex);
|
||||
cairo_surface_destroy(surface);
|
||||
DeleteObject((HBITMAP)bitmap_cache->bitmap);
|
||||
free(bitmap_cache);
|
||||
CANVAS_ERROR("set_user_data surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(surface)));
|
||||
surface = pixman_image_create_bits(format, width, height, (uint32_t *)src, stride);
|
||||
if (surface == NULL) {
|
||||
CloseHandle(mutex);
|
||||
DeleteObject(bitmap);
|
||||
CANVAS_ERROR("create surface failed, out of memory");
|
||||
}
|
||||
pixman_data = pixman_image_add_data(surface);
|
||||
pixman_data.bitmap = bitmap;
|
||||
pixman_data.mutex = mutex;
|
||||
gdi_handlers++;
|
||||
return surface;
|
||||
} else {
|
||||
#endif
|
||||
if (top_down) {
|
||||
return cairo_image_surface_create(format, width, height);
|
||||
return pixman_image_create_bits(format, width, height, NULL, 0);
|
||||
} else {
|
||||
// NOTE: we assume here that the lz decoders always decode to RGB32.
|
||||
int stride = 0;
|
||||
switch (format) {
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
case PIXMAN_a8r8g8b8:
|
||||
case PIXMAN_x8r8g8b8:
|
||||
stride = width * 4;
|
||||
break;
|
||||
case CAIRO_FORMAT_A8:
|
||||
case PIXMAN_a8:
|
||||
stride = ALIGN(width, 4);
|
||||
break;
|
||||
case CAIRO_FORMAT_A1:
|
||||
case PIXMAN_a1:
|
||||
stride = ALIGN(width, 32) / 8;
|
||||
break;
|
||||
default:
|
||||
@ -228,11 +226,11 @@ cairo_surface_t * surface_create(cairo_format_t format, int width, int height, i
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
cairo_surface_t *surface_create_stride(HDC dc, cairo_format_t format, int width, int height,
|
||||
int stride)
|
||||
pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
|
||||
int stride)
|
||||
#else
|
||||
cairo_surface_t *surface_create_stride(cairo_format_t format, int width, int height,
|
||||
int stride)
|
||||
pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
|
||||
int stride)
|
||||
#endif
|
||||
{
|
||||
#ifdef WIN32
|
||||
@ -246,12 +244,12 @@ cairo_surface_t *surface_create_stride(cairo_format_t format, int width, int hei
|
||||
return __surface_create_stride(format, width, height, stride);
|
||||
}
|
||||
|
||||
cairo_surface_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
|
||||
int height, int gross_pixels, int top_down)
|
||||
pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
|
||||
int height, int gross_pixels, int top_down)
|
||||
{
|
||||
int stride;
|
||||
int alpha;
|
||||
cairo_surface_t *surface = NULL;
|
||||
pixman_image_t *surface = NULL;
|
||||
|
||||
stride = (gross_pixels / height) * 4;
|
||||
|
||||
@ -270,7 +268,7 @@ cairo_surface_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageTyp
|
||||
#ifdef WIN32
|
||||
canvas_data->dc,
|
||||
#endif
|
||||
alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height, stride);
|
||||
alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, width, height, stride);
|
||||
canvas_data->out_surface = surface;
|
||||
return surface;
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
Copyright (C) 2009 Red Hat, Inc.
|
||||
|
||||
@ -20,31 +21,30 @@
|
||||
|
||||
#include <spice/types.h>
|
||||
|
||||
#include "cairo.h"
|
||||
#include "pixman_utils.h"
|
||||
#include "lz.h"
|
||||
|
||||
typedef struct PixmanData {
|
||||
#ifdef WIN32
|
||||
typedef struct BitmapCache {
|
||||
HBITMAP bitmap;
|
||||
HANDLE mutex;
|
||||
} BitmapCache;
|
||||
#endif
|
||||
|
||||
extern const cairo_user_data_key_t bitmap_data_type;
|
||||
uint8_t *data;
|
||||
} PixmanData;
|
||||
|
||||
#ifdef WIN32
|
||||
cairo_surface_t *surface_create(HDC dc, cairo_format_t format,
|
||||
int width, int height, int top_down);
|
||||
pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
|
||||
int width, int height, int top_down);
|
||||
#else
|
||||
cairo_surface_t *surface_create(cairo_format_t format, int width, int height, int top_down);
|
||||
pixman_image_t *surface_create(pixman_format_code_t format, int width, int height, int top_down);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
cairo_surface_t *surface_create_stride(HDC dc, cairo_format_t format, int width, int height,
|
||||
int stride);
|
||||
pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
|
||||
int stride);
|
||||
#else
|
||||
cairo_surface_t *surface_create_stride(cairo_format_t format, int width, int height,
|
||||
int stride);
|
||||
pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
|
||||
int stride);
|
||||
#endif
|
||||
|
||||
|
||||
@ -52,10 +52,10 @@ typedef struct LzDecodeUsrData {
|
||||
#ifdef WIN32
|
||||
HDC dc;
|
||||
#endif
|
||||
cairo_surface_t *out_surface;
|
||||
pixman_image_t *out_surface;
|
||||
} LzDecodeUsrData;
|
||||
|
||||
|
||||
cairo_surface_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
|
||||
int height, int gross_pixels, int top_down);
|
||||
pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data, LzImageType type, int width,
|
||||
int height, int gross_pixels, int top_down);
|
||||
#endif
|
||||
|
||||
156
gdi_canvas.c
156
gdi_canvas.c
@ -305,15 +305,15 @@ uint32_t raster_ops[] = {
|
||||
0x00FF0062 // 1 WHITENESS
|
||||
};
|
||||
|
||||
static inline void surface_to_image(cairo_surface_t *surface, GdiImage *image)
|
||||
static inline void surface_to_image(pixman_image_t *surface, GdiImage *image)
|
||||
{
|
||||
cairo_format_t format = cairo_image_surface_get_format(surface);
|
||||
int depth = pixman_image_surface_get_depth(surface);
|
||||
|
||||
ASSERT(format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24);
|
||||
image->width = cairo_image_surface_get_width(surface);
|
||||
image->height = cairo_image_surface_get_height(surface);
|
||||
image->stride = cairo_image_surface_get_stride(surface);
|
||||
image->pixels = cairo_image_surface_get_data(surface);
|
||||
ASSERT(depth == 32 || depth == 24);
|
||||
image->width = pixman_image_get_width(surface);
|
||||
image->height = pixman_image_get_height(surface);
|
||||
image->stride = pixman_image_get_stride(surface);
|
||||
image->pixels = pixman_image_get_data(surface);
|
||||
}
|
||||
|
||||
static void set_path(GdiCanvas *canvas, void *addr)
|
||||
@ -645,7 +645,7 @@ static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush)
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
GdiImage image;
|
||||
HBRUSH hbrush;
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
HDC dc;
|
||||
HBITMAP bitmap;
|
||||
HBITMAP prev_bitmap;
|
||||
@ -664,7 +664,7 @@ static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush)
|
||||
}
|
||||
|
||||
release_bitmap(dc, bitmap, prev_bitmap, 0);
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
return hbrush;
|
||||
}
|
||||
case SPICE_BRUSH_TYPE_NONE:
|
||||
@ -779,27 +779,27 @@ uint8_t calc_rop3_src_brush(uint16_t rop3_bits)
|
||||
|
||||
static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
struct BitmapData bitmap;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
bitmap.hbitmap = NULL;
|
||||
if (!(surface = canvas_get_mask(&canvas->base, mask))) {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
pixman_data = pixman_image_get_destroy_data (surface);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
bitmap.dc = create_compatible_dc();
|
||||
bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, bitmap_cache->bitmap);
|
||||
bitmap.hbitmap = bitmap_cache->bitmap;
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
|
||||
bitmap.hbitmap = pixman_data->bitmap;
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
bitmap.cache = 1;
|
||||
} else if (!create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc,
|
||||
cairo_image_surface_get_data(surface),
|
||||
cairo_image_surface_get_width(surface),
|
||||
cairo_image_surface_get_height(surface),
|
||||
cairo_image_surface_get_stride(surface), 1, 0)) {
|
||||
pixman_image_get_data(surface),
|
||||
pixman_image_get_width(surface),
|
||||
pixman_image_get_height(surface),
|
||||
pixman_image_get_stride(surface), 1, 0)) {
|
||||
bitmap.hbitmap = NULL;
|
||||
} else {
|
||||
bitmap.cache = 0;
|
||||
@ -865,7 +865,7 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
|
||||
SpiceString *str, int n, SpiceRect *dest,
|
||||
SpiceRect *src, SpiceBrush *brush)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
struct BitmapData bitmap;
|
||||
SpicePoint pos;
|
||||
int dest_stride;
|
||||
@ -882,9 +882,9 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
|
||||
bitmap.cache = 0;
|
||||
bitmap_data = create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap,
|
||||
&bitmap.dc, NULL,
|
||||
cairo_image_surface_get_width(surface),
|
||||
cairo_image_surface_get_height(surface),
|
||||
cairo_image_surface_get_stride(surface), 32, 0);
|
||||
pixman_image_get_width(surface),
|
||||
pixman_image_get_height(surface),
|
||||
pixman_image_get_stride(surface), 32, 0);
|
||||
|
||||
if (!bitmap_data) {
|
||||
return;
|
||||
@ -896,14 +896,14 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
|
||||
|
||||
dest->left = pos.x;
|
||||
dest->top = pos.y;
|
||||
dest->right = pos.x + cairo_image_surface_get_width(surface);
|
||||
dest->bottom = pos.y + cairo_image_surface_get_height(surface);
|
||||
dest->right = pos.x + pixman_image_get_width(surface);
|
||||
dest->bottom = pos.y + pixman_image_get_height(surface);
|
||||
src->left = 0;
|
||||
src->top = 0;
|
||||
src->right = cairo_image_surface_get_width(surface);
|
||||
src->bottom = cairo_image_surface_get_height(surface);
|
||||
src->right = pixman_image_get_width(surface);
|
||||
src->bottom = pixman_image_get_height(surface);
|
||||
|
||||
dest_stride = cairo_image_surface_get_width(surface);
|
||||
dest_stride = pixman_image_get_width(surface);
|
||||
switch (n) {
|
||||
case 1:
|
||||
dest_stride = dest_stride / 8;
|
||||
@ -926,10 +926,10 @@ static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
|
||||
|
||||
unset_brush(bitmap.dc, prev_hbrush);
|
||||
|
||||
copy_bitmap_alpha(cairo_image_surface_get_data(surface),
|
||||
cairo_image_surface_get_height(surface),
|
||||
cairo_image_surface_get_width(surface),
|
||||
cairo_image_surface_get_stride(surface),
|
||||
copy_bitmap_alpha(pixman_image_get_data(surface),
|
||||
pixman_image_get_height(surface),
|
||||
pixman_image_get_width(surface),
|
||||
pixman_image_get_stride(surface),
|
||||
bitmap_data, dest_stride, n);
|
||||
|
||||
BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
|
||||
@ -1000,30 +1000,30 @@ void gdi_canvas_draw_fill(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
|
||||
void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
struct BitmapData bitmapmask;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, ©->mask);
|
||||
surface = canvas_get_image(&canvas->base, copy->src_bitmap);
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_scale_mode(canvas, copy->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, dc,
|
||||
&bitmapmask, copy->rop_decriptor, 0);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image(canvas->dc, ©->src_area, bbox, image.pixels,
|
||||
@ -1033,7 +1033,7 @@ void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
void gdi_canvas_put_image(GdiCanvas *canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
|
||||
@ -1127,26 +1127,26 @@ static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const Spi
|
||||
void gdi_canvas_draw_transparent(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
|
||||
SpiceTransparent* transparent)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, transparent->src_bitmap);
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc,
|
||||
transparent->true_color);
|
||||
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, image.pixels,
|
||||
@ -1154,7 +1154,7 @@ void gdi_canvas_draw_transparent(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *
|
||||
transparent->true_color, 0);
|
||||
}
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
|
||||
@ -1198,28 +1198,28 @@ static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceR
|
||||
|
||||
void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
int use_bitmap_alpha;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap);
|
||||
use_bitmap_alpha = cairo_image_surface_get_format(surface) == CAIRO_FORMAT_ARGB32;
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
|
||||
use_bitmap_alpha);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, image.pixels,
|
||||
@ -1227,21 +1227,21 @@ void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *
|
||||
alpha_blend->alpha, 0, use_bitmap_alpha);
|
||||
}
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
struct BitmapData bitmapmask;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
HBRUSH prev_hbrush;
|
||||
HBRUSH hbrush;
|
||||
uint8_t rop3;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, opaque->src_bitmap);
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
|
||||
rop3 = calc_rop3_src_brush(opaque->rop_decriptor);
|
||||
hbrush = get_brush(canvas, &opaque->brush);
|
||||
@ -1252,16 +1252,16 @@ void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
|
||||
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, image.pixels,
|
||||
@ -1272,35 +1272,35 @@ void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
|
||||
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
struct BitmapData bitmapmask;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, &blend->mask);
|
||||
surface = canvas_get_image(&canvas->base, blend->src_bitmap);
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_scale_mode(canvas, blend->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc,
|
||||
&bitmapmask, blend->rop_decriptor, 0);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image(canvas->dc, &blend->src_area, bbox, image.pixels, image.stride, image.width,
|
||||
@ -1309,7 +1309,7 @@ void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
|
||||
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
void gdi_canvas_draw_blackness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
|
||||
@ -1353,16 +1353,16 @@ void gdi_canvas_draw_whiteness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
|
||||
|
||||
void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
struct BitmapData bitmapmask;
|
||||
HBRUSH prev_hbrush;
|
||||
HBRUSH hbrush;
|
||||
BitmapCache *bitmap_cache;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
hbrush = get_brush(canvas, &rop3->brush);
|
||||
surface = canvas_get_image(&canvas->base, rop3->src_bitmap);
|
||||
bitmap_cache = (BitmapCache *)cairo_surface_get_user_data(surface, &bitmap_data_type);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
@ -1370,17 +1370,17 @@ void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
|
||||
|
||||
if (bitmap_cache && (WaitForSingleObject(bitmap_cache->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, bitmap_cache->bitmap);
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
|
||||
&bitmapmask, rop3->rop3);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(bitmap_cache->mutex);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, image.pixels,
|
||||
@ -1390,7 +1390,7 @@ void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
void gdi_canvas_copy_bits(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
|
||||
@ -1517,7 +1517,7 @@ void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
|
||||
int ps_join = 0;
|
||||
int line_cap = 0;
|
||||
uint32_t *user_style = NULL;
|
||||
cairo_surface_t *surface = NULL;
|
||||
pixman_image_t *surface = NULL;
|
||||
|
||||
if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
|
||||
surface = canvas_get_image(&canvas->base, stroke->brush.u.pattern.pat);
|
||||
@ -1630,7 +1630,7 @@ void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
|
||||
logbrush.lbStyle = BS_DIBPATTERN | DIB_RGB_COLORS;
|
||||
logbrush.lbColor = 0;
|
||||
#endif
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <spice/draw.h>
|
||||
#include "cairo.h"
|
||||
#include "pixman_utils.h"
|
||||
#include "canvas_base.h"
|
||||
#include "region.h"
|
||||
|
||||
|
||||
171
gl_canvas.c
171
gl_canvas.c
@ -71,8 +71,8 @@ static inline uint8_t *copy_opposite_image(GLCanvas *canvas, void *data, int str
|
||||
return (uint8_t *)canvas->private_data;
|
||||
}
|
||||
|
||||
static cairo_surface_t *canvas_surf_to_trans_surf(GLCImage *image,
|
||||
uint32_t trans_color)
|
||||
static pixman_image_t *canvas_surf_to_trans_surf(GLCImage *image,
|
||||
uint32_t trans_color)
|
||||
{
|
||||
int width = image->width;
|
||||
int height = image->height;
|
||||
@ -81,21 +81,20 @@ static cairo_surface_t *canvas_surf_to_trans_surf(GLCImage *image,
|
||||
int src_stride;
|
||||
uint8_t *dest_line;
|
||||
int dest_stride;
|
||||
cairo_surface_t *ret;
|
||||
pixman_image_t *ret;
|
||||
int i;
|
||||
|
||||
ret = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
||||
if (cairo_surface_status(ret) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(ret)));
|
||||
ret = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
|
||||
if (ret == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
|
||||
src_line = image->pixels;
|
||||
src_stride = image->stride;
|
||||
end_src_line = src_line + src_stride * height;
|
||||
|
||||
dest_line = cairo_image_surface_get_data(ret);
|
||||
dest_stride = cairo_image_surface_get_stride(ret);
|
||||
dest_line = (uint8_t *)pixman_image_get_data(ret);
|
||||
dest_stride = pixman_image_get_stride(ret);
|
||||
|
||||
for (; src_line < end_src_line; src_line += src_stride, dest_line += dest_stride) {
|
||||
for (i = 0; i < width; i++) {
|
||||
@ -209,32 +208,32 @@ static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip)
|
||||
|
||||
static void set_mask(GLCanvas *canvas, SpiceQMask *mask, int x, int y)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *image;
|
||||
|
||||
if (!(surface = canvas_get_mask(&canvas->base, mask))) {
|
||||
if (!(image = canvas_get_mask(&canvas->base, mask))) {
|
||||
glc_clear_mask(canvas->glc, GLC_MASK_A);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
glc_set_mask(canvas->glc, x - mask->pos.x, y - mask->pos.y,
|
||||
cairo_image_surface_get_width(surface),
|
||||
cairo_image_surface_get_height(surface),
|
||||
cairo_image_surface_get_stride(surface),
|
||||
cairo_image_surface_get_data(surface), GLC_MASK_A);
|
||||
pixman_image_get_width(image),
|
||||
pixman_image_get_height(image),
|
||||
pixman_image_get_stride(image),
|
||||
(uint8_t *)pixman_image_get_data(image), GLC_MASK_A);
|
||||
}
|
||||
|
||||
static inline void surface_to_image(GLCanvas *canvas, cairo_surface_t *surface, GLCImage *image,
|
||||
static inline void surface_to_image(GLCanvas *canvas, pixman_image_t *surface, GLCImage *image,
|
||||
int ignore_stride)
|
||||
{
|
||||
cairo_format_t format = cairo_image_surface_get_format(surface);
|
||||
int depth = pixman_image_get_depth(surface);
|
||||
|
||||
ASSERT(format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24);
|
||||
image->format = (format == CAIRO_FORMAT_RGB24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
|
||||
image->width = cairo_image_surface_get_width(surface);
|
||||
image->height = cairo_image_surface_get_height(surface);
|
||||
image->stride = cairo_image_surface_get_stride(surface);
|
||||
image->pixels = cairo_image_surface_get_data(surface);
|
||||
ASSERT(depth == 32 || depth == 24);
|
||||
image->format = (depth == 24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32;
|
||||
image->width = pixman_image_get_width(surface);
|
||||
image->height = pixman_image_get_height(surface);
|
||||
image->stride = pixman_image_get_stride(surface);
|
||||
image->pixels = (uint8_t *)pixman_image_get_data(surface);
|
||||
image->pallet = NULL;
|
||||
if (ignore_stride) {
|
||||
return;
|
||||
@ -265,7 +264,7 @@ static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
GLCImage image;
|
||||
GLCPattern pattern;
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
|
||||
surface_to_image(canvas, surface, &image, 0);
|
||||
@ -275,6 +274,7 @@ static void set_brush(GLCanvas *canvas, SpiceBrush *brush)
|
||||
|
||||
glc_set_pattern(canvas->glc, pattern);
|
||||
glc_pattern_destroy(pattern);
|
||||
pixman_image_unref (surface);
|
||||
}
|
||||
case SPICE_BRUSH_TYPE_NONE:
|
||||
return;
|
||||
@ -358,7 +358,7 @@ void gl_canvas_draw_fill(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
|
||||
void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GLCRecti src;
|
||||
GLCRecti dest;
|
||||
GLCImage image;
|
||||
@ -374,13 +374,13 @@ void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
SET_GLC_RECT(&src, ©->src_area);
|
||||
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
glc_flush(canvas->glc);
|
||||
}
|
||||
|
||||
void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GLCRecti src;
|
||||
GLCRecti dest;
|
||||
GLCRect fill_rect;
|
||||
@ -396,7 +396,7 @@ void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
SET_GLC_RECT(&dest, bbox);
|
||||
SET_GLC_RECT(&src, &opaque->src_area);
|
||||
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
|
||||
set_brush(canvas, &opaque->brush);
|
||||
set_op(canvas, opaque->rop_decriptor & ~SPICE_ROPD_INVERS_SRC);
|
||||
@ -408,7 +408,7 @@ void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
|
||||
void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd *alpha_blend)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GLCRecti src;
|
||||
GLCRecti dest;
|
||||
GLCImage image;
|
||||
@ -423,13 +423,13 @@ void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
|
||||
SET_GLC_RECT(&src, &alpha_blend->src_area);
|
||||
glc_draw_image(canvas->glc, &dest, &src, &image, 0, (double)alpha_blend->alpha / 0xff);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
glc_flush(canvas->glc);
|
||||
}
|
||||
|
||||
void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
pixman_image_t *surface;
|
||||
GLCRecti src;
|
||||
GLCRecti dest;
|
||||
GLCImage image;
|
||||
@ -444,14 +444,14 @@ void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Sp
|
||||
surface_to_image(canvas, surface, &image, 0);
|
||||
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
|
||||
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
glc_flush(canvas->glc);
|
||||
}
|
||||
|
||||
void gl_canvas_draw_transparent(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *trans_surf;
|
||||
pixman_image_t *surface;
|
||||
pixman_image_t *trans_surf;
|
||||
GLCImage image;
|
||||
GLCRecti src;
|
||||
GLCRecti dest;
|
||||
@ -464,14 +464,14 @@ void gl_canvas_draw_transparent(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
|
||||
surface_to_image(canvas, surface, &image, 0);
|
||||
|
||||
trans_surf = canvas_surf_to_trans_surf(&image, transparent->true_color);
|
||||
cairo_surface_destroy(surface);
|
||||
pixman_image_unref(surface);
|
||||
|
||||
surface_to_image(canvas, trans_surf, &image, 1);
|
||||
SET_GLC_RECT(&dest, bbox);
|
||||
SET_GLC_RECT(&src, &transparent->src_area);
|
||||
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
|
||||
|
||||
cairo_surface_destroy(trans_surf);
|
||||
pixman_image_unref(trans_surf);
|
||||
glc_flush(canvas->glc);
|
||||
}
|
||||
|
||||
@ -503,8 +503,8 @@ void gl_canvas_draw_invers(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
|
||||
|
||||
void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
|
||||
{
|
||||
cairo_surface_t *d;
|
||||
cairo_surface_t *s;
|
||||
pixman_image_t *d;
|
||||
pixman_image_t *s;
|
||||
GLCImage image;
|
||||
SpicePoint src_pos;
|
||||
uint8_t *data_opp;
|
||||
@ -521,34 +521,33 @@ void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
|
||||
image.pallet = NULL;
|
||||
|
||||
d = cairo_image_surface_create(CAIRO_FORMAT_RGB24, image.width, image.height);
|
||||
if (cairo_surface_status(d) != CAIRO_STATUS_SUCCESS) {
|
||||
CANVAS_ERROR("create surface failed, %s",
|
||||
cairo_status_to_string(cairo_surface_status(d)));
|
||||
d = pixman_image_create_bits(PIXMAN_x8r8g8b8, image.width, image.height, NULL, 0);
|
||||
if (d == NULL) {
|
||||
CANVAS_ERROR("create surface failed");
|
||||
}
|
||||
image.pixels = cairo_image_surface_get_data(d);
|
||||
image.stride = cairo_image_surface_get_stride(d);
|
||||
image.pixels = (uint8_t *)pixman_image_get_data(d);
|
||||
image.stride = pixman_image_get_stride(d);
|
||||
|
||||
glc_read_pixels(canvas->glc, bbox->left, bbox->top, &image);
|
||||
data_opp = copy_opposite_image(canvas, image.pixels,
|
||||
cairo_image_surface_get_stride(d),
|
||||
cairo_image_surface_get_height(d));
|
||||
image.stride,
|
||||
pixman_image_get_height(d));
|
||||
memcpy(image.pixels, data_opp,
|
||||
cairo_image_surface_get_stride(d) * cairo_image_surface_get_height(d));
|
||||
image.stride * pixman_image_get_height(d));
|
||||
|
||||
s = canvas_get_image(&canvas->base, rop3->src_bitmap);
|
||||
src_stride = cairo_image_surface_get_stride(s);
|
||||
src_stride = pixman_image_get_stride(s);
|
||||
if (src_stride > 0) {
|
||||
data_opp = copy_opposite_image(canvas, cairo_image_surface_get_data(s),
|
||||
src_stride, cairo_image_surface_get_height(s));
|
||||
memcpy(cairo_image_surface_get_data(s), data_opp,
|
||||
src_stride * cairo_image_surface_get_height(s));
|
||||
data_opp = copy_opposite_image(canvas, (uint8_t *)pixman_image_get_data(s),
|
||||
src_stride, pixman_image_get_height(s));
|
||||
memcpy((uint8_t *)pixman_image_get_data(s), data_opp,
|
||||
src_stride * pixman_image_get_height(s));
|
||||
}
|
||||
|
||||
if (!rect_is_same_size(bbox, &rop3->src_area)) {
|
||||
cairo_surface_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width,
|
||||
image.height, rop3->scale_mode);
|
||||
cairo_surface_destroy(s);
|
||||
pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width,
|
||||
image.height, rop3->scale_mode);
|
||||
pixman_image_unref(s);
|
||||
s = scaled_s;
|
||||
src_pos.x = 0;
|
||||
src_pos.y = 0;
|
||||
@ -557,49 +556,49 @@ void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
src_pos.y = rop3->src_area.top;
|
||||
}
|
||||
|
||||
if (cairo_image_surface_get_width(s) - src_pos.x < image.width ||
|
||||
cairo_image_surface_get_height(s) - src_pos.y < image.height) {
|
||||
if (pixman_image_get_width(s) - src_pos.x < image.width ||
|
||||
pixman_image_get_height(s) - src_pos.y < image.height) {
|
||||
CANVAS_ERROR("bad src bitmap size");
|
||||
}
|
||||
|
||||
if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
|
||||
cairo_surface_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
|
||||
pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat);
|
||||
SpicePoint pat_pos;
|
||||
|
||||
pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % cairo_image_surface_get_width(p);
|
||||
pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
|
||||
|
||||
pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % cairo_image_surface_get_height(p);
|
||||
pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
|
||||
|
||||
//for now (bottom-top)
|
||||
if (pat_pos.y < 0) {
|
||||
pat_pos.y = cairo_image_surface_get_height(p) + pat_pos.y;
|
||||
pat_pos.y = pixman_image_get_height(p) + pat_pos.y;
|
||||
}
|
||||
pat_pos.y = (image.height + pat_pos.y) % cairo_image_surface_get_height(p);
|
||||
pat_pos.y = cairo_image_surface_get_height(p) - pat_pos.y;
|
||||
pat_pos.y = (image.height + pat_pos.y) % pixman_image_get_height(p);
|
||||
pat_pos.y = pixman_image_get_height(p) - pat_pos.y;
|
||||
|
||||
do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
|
||||
cairo_surface_destroy(p);
|
||||
pixman_image_unref(p);
|
||||
} else {
|
||||
uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color :
|
||||
canvas_16bpp_to_32bpp(rop3->brush.u.color);
|
||||
do_rop3_with_color(rop3->rop3, d, s, &src_pos, color);
|
||||
}
|
||||
|
||||
cairo_surface_destroy(s);
|
||||
pixman_image_unref(s);
|
||||
|
||||
GLCRecti dest;
|
||||
GLCRecti src;
|
||||
dest.x = bbox->left;
|
||||
dest.y = bbox->top;
|
||||
|
||||
image.pixels = copy_opposite_image(canvas, image.pixels, cairo_image_surface_get_stride(d),
|
||||
cairo_image_surface_get_height(d));
|
||||
image.pixels = copy_opposite_image(canvas, image.pixels, pixman_image_get_stride(d),
|
||||
pixman_image_get_height(d));
|
||||
|
||||
src.x = src.y = 0;
|
||||
dest.width = src.width = image.width;
|
||||
dest.height = src.height = image.height;
|
||||
glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1);
|
||||
cairo_surface_destroy(d);
|
||||
pixman_image_unref(d);
|
||||
}
|
||||
|
||||
void gl_canvas_draw_stroke(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
|
||||
@ -641,34 +640,34 @@ void gl_canvas_draw_text(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
|
||||
set_op(canvas, text->fore_mode);
|
||||
if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
|
||||
SpicePoint pos;
|
||||
cairo_surface_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos);
|
||||
pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos);
|
||||
_glc_fill_mask(canvas->glc, pos.x, pos.y,
|
||||
cairo_image_surface_get_width(mask),
|
||||
cairo_image_surface_get_height(mask),
|
||||
cairo_image_surface_get_stride(mask),
|
||||
cairo_image_surface_get_data(mask));
|
||||
cairo_surface_destroy(mask);
|
||||
pixman_image_get_width(mask),
|
||||
pixman_image_get_height(mask),
|
||||
pixman_image_get_stride(mask),
|
||||
(uint8_t *)pixman_image_get_data(mask));
|
||||
pixman_image_unref(mask);
|
||||
} else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
|
||||
SpicePoint pos;
|
||||
cairo_surface_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos);
|
||||
pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos);
|
||||
glc_fill_alpha(canvas->glc, pos.x, pos.y,
|
||||
cairo_image_surface_get_width(mask),
|
||||
cairo_image_surface_get_height(mask),
|
||||
cairo_image_surface_get_stride(mask),
|
||||
cairo_image_surface_get_data(mask));
|
||||
pixman_image_get_width(mask),
|
||||
pixman_image_get_height(mask),
|
||||
pixman_image_get_stride(mask),
|
||||
(uint8_t *)pixman_image_get_data(mask));
|
||||
|
||||
cairo_surface_destroy(mask);
|
||||
pixman_image_unref(mask);
|
||||
} else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
|
||||
WARN("untested path A8 glyphs, doing nothing");
|
||||
if (0) {
|
||||
SpicePoint pos;
|
||||
cairo_surface_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos);
|
||||
pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos);
|
||||
glc_fill_alpha(canvas->glc, pos.x, pos.y,
|
||||
cairo_image_surface_get_width(mask),
|
||||
cairo_image_surface_get_height(mask),
|
||||
cairo_image_surface_get_stride(mask),
|
||||
cairo_image_surface_get_data(mask));
|
||||
cairo_surface_destroy(mask);
|
||||
pixman_image_get_width(mask),
|
||||
pixman_image_get_height(mask),
|
||||
pixman_image_get_stride(mask),
|
||||
(uint8_t *)pixman_image_get_data(mask));
|
||||
pixman_image_unref(mask);
|
||||
}
|
||||
} else {
|
||||
WARN("untested path vector glyphs, doing nothing");
|
||||
|
||||
56
rop3.c
56
rop3.c
@ -24,11 +24,11 @@
|
||||
#define WARN(x) printf("warning: %s\n", x)
|
||||
#endif
|
||||
|
||||
typedef void (*rop3_with_pattern_handler_t)(cairo_surface_t *d, cairo_surface_t *s,
|
||||
SpicePoint *src_pos, cairo_surface_t *p,
|
||||
typedef void (*rop3_with_pattern_handler_t)(pixman_image_t *d, pixman_image_t *s,
|
||||
SpicePoint *src_pos, pixman_image_t *p,
|
||||
SpicePoint *pat_pos);
|
||||
|
||||
typedef void (*rop3_with_color_handler_t)(cairo_surface_t *d, cairo_surface_t *s,
|
||||
typedef void (*rop3_with_color_handler_t)(pixman_image_t *d, pixman_image_t *s,
|
||||
SpicePoint *src_pos, uint32_t rgb);
|
||||
|
||||
typedef void (*rop3_test_handler_t)();
|
||||
@ -40,14 +40,14 @@ static rop3_with_color_handler_t rop3_with_color_handlers[ROP3_NUM_OPS];
|
||||
static rop3_test_handler_t rop3_test_handlers[ROP3_NUM_OPS];
|
||||
|
||||
|
||||
static void default_rop3_with_pattern_handler(cairo_surface_t *d, cairo_surface_t *s,
|
||||
SpicePoint *src_pos, cairo_surface_t *p,
|
||||
static void default_rop3_with_pattern_handler(pixman_image_t *d, pixman_image_t *s,
|
||||
SpicePoint *src_pos, pixman_image_t *p,
|
||||
SpicePoint *pat_pos)
|
||||
{
|
||||
WARN("not implemented 0x%x");
|
||||
}
|
||||
|
||||
static void default_rop3_withe_color_handler(cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
|
||||
static void default_rop3_withe_color_handler(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
|
||||
uint32_t rgb)
|
||||
{
|
||||
WARN("not implemented 0x%x");
|
||||
@ -58,24 +58,24 @@ static void default_rop3_test_handler()
|
||||
}
|
||||
|
||||
#define ROP3_HANDLERS(name, formula, index) \
|
||||
static void rop3_handle_p_##name(cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos, \
|
||||
cairo_surface_t *p, SpicePoint *pat_pos) \
|
||||
static void rop3_handle_p_##name(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos, \
|
||||
pixman_image_t *p, SpicePoint *pat_pos) \
|
||||
{ \
|
||||
int width = cairo_image_surface_get_width(d); \
|
||||
int height = cairo_image_surface_get_height(d); \
|
||||
uint8_t *dest_line = cairo_image_surface_get_data(d); \
|
||||
int dest_stride = cairo_image_surface_get_stride(d); \
|
||||
int width = pixman_image_get_width(d); \
|
||||
int height = pixman_image_get_height(d); \
|
||||
uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
|
||||
int dest_stride = pixman_image_get_stride(d); \
|
||||
uint8_t *end_line = dest_line + height * dest_stride; \
|
||||
\
|
||||
int pat_width = cairo_image_surface_get_width(p); \
|
||||
int pat_height = cairo_image_surface_get_height(p); \
|
||||
uint8_t *pat_base = cairo_image_surface_get_data(p); \
|
||||
int pat_stride = cairo_image_surface_get_stride(p); \
|
||||
int pat_width = pixman_image_get_width(p); \
|
||||
int pat_height = pixman_image_get_height(p); \
|
||||
uint8_t *pat_base = (uint8_t *)pixman_image_get_data(p); \
|
||||
int pat_stride = pixman_image_get_stride(p); \
|
||||
int pat_v_offset = pat_pos->y; \
|
||||
\
|
||||
int src_stride = cairo_image_surface_get_stride(s); \
|
||||
int src_stride = pixman_image_get_stride(s); \
|
||||
uint8_t *src_line; \
|
||||
src_line = cairo_image_surface_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
|
||||
src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
|
||||
\
|
||||
for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) { \
|
||||
uint32_t *dest = (uint32_t *)dest_line; \
|
||||
@ -95,19 +95,19 @@ static void rop3_handle_p_##name(cairo_surface_t *d, cairo_surface_t *s, SpicePo
|
||||
} \
|
||||
} \
|
||||
\
|
||||
static void rop3_handle_c_##name(cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos, \
|
||||
static void rop3_handle_c_##name(pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos, \
|
||||
uint32_t rgb) \
|
||||
{ \
|
||||
int width = cairo_image_surface_get_width(d); \
|
||||
int height = cairo_image_surface_get_height(d); \
|
||||
uint8_t *dest_line = cairo_image_surface_get_data(d); \
|
||||
int dest_stride = cairo_image_surface_get_stride(d); \
|
||||
int width = pixman_image_get_width(d); \
|
||||
int height = pixman_image_get_height(d); \
|
||||
uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
|
||||
int dest_stride = pixman_image_get_stride(d); \
|
||||
uint8_t *end_line = dest_line + height * dest_stride; \
|
||||
uint32_t *pat = &rgb; \
|
||||
\
|
||||
int src_stride = cairo_image_surface_get_stride(s); \
|
||||
int src_stride = pixman_image_get_stride(s); \
|
||||
uint8_t *src_line; \
|
||||
src_line = cairo_image_surface_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
|
||||
src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x << 2); \
|
||||
\
|
||||
for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) { \
|
||||
uint32_t *dest = (uint32_t *)dest_line; \
|
||||
@ -600,13 +600,13 @@ void rop3_init()
|
||||
}
|
||||
}
|
||||
|
||||
void do_rop3_with_pattern(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
|
||||
cairo_surface_t *p, SpicePoint *pat_pos)
|
||||
void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
|
||||
pixman_image_t *p, SpicePoint *pat_pos)
|
||||
{
|
||||
rop3_with_pattern_handlers[rop3](d, s, src_pos, p, pat_pos);
|
||||
}
|
||||
|
||||
void do_rop3_with_color(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
|
||||
void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
|
||||
uint32_t rgb)
|
||||
{
|
||||
rop3_with_color_handlers[rop3](d, s, src_pos, rgb);
|
||||
|
||||
8
rop3.h
8
rop3.h
@ -22,11 +22,11 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <spice/draw.h>
|
||||
#include "cairo.h"
|
||||
#include "pixman_utils.h"
|
||||
|
||||
void do_rop3_with_pattern(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
|
||||
cairo_surface_t *p, SpicePoint *pat_pos);
|
||||
void do_rop3_with_color(uint8_t rop3, cairo_surface_t *d, cairo_surface_t *s, SpicePoint *src_pos,
|
||||
void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
|
||||
pixman_image_t *p, SpicePoint *pat_pos);
|
||||
void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
|
||||
uint32_t rgb);
|
||||
|
||||
void rop3_init();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user