Move virtualization of canvas drawing into common/canvas_base

Instead of having two virtualizations of the canvas we push the
virtualization into the canvas code itself. This not only avoids
the duplication of this code, it also makes the exposed API for the
canvas much smaller (in terms of exported API).

It also lets us use the virtualization to implement basic support
for operations in canvas_base which is then overridden by each canvas
implementation.
This commit is contained in:
Alexander Larsson 2010-03-03 15:08:58 +01:00 committed by Marc-André Lureau
parent 981270d38a
commit 3b73f93cf2
8 changed files with 353 additions and 251 deletions

View File

@ -19,6 +19,7 @@
#include <math.h>
#include "cairo_canvas.h"
#define CANVAS_USE_PIXMAN
#define CANVAS_SINGLE_INSTANCE
#include "canvas_base.c"
#include "rop3.h"
#include "rect.h"
@ -26,6 +27,8 @@
#include "lines.h"
#include "pixman_utils.h"
typedef struct CairoCanvas CairoCanvas;
struct CairoCanvas {
CanvasBase base;
uint32_t *private_data;
@ -1007,8 +1010,9 @@ static void touch_brush(CairoCanvas *canvas, SpiceBrush *brush)
}
}
void canvas_draw_fill(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
static void canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
SpiceROP rop;
@ -1037,8 +1041,9 @@ void canvas_draw_fill(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
pixman_region32_fini(&dest_region);
}
void canvas_draw_copy(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
SpiceROP rop;
@ -1106,16 +1111,15 @@ void canvas_draw_copy(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
pixman_region32_fini(&dest_region);
}
static void canvas_put_image(SpiceCanvas *spice_canvas,
#ifdef WIN32
void canvas_put_image(CairoCanvas *canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip)
#else
void canvas_put_image(CairoCanvas *canvas, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip)
HDC dc,
#endif
const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_image_t *src;
int dest_width;
int dest_height;
@ -1165,8 +1169,9 @@ void canvas_put_image(CairoCanvas *canvas, const SpiceRect *dest, const uint8_t
pixman_image_unref(src);
}
void canvas_draw_transparent(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
static void canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_region32_init_rect(&dest_region,
@ -1205,8 +1210,9 @@ void canvas_draw_transparent(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
pixman_region32_fini(&dest_region);
}
void canvas_draw_alpha_blend(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
static void canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_region32_init_rect(&dest_region,
@ -1251,8 +1257,9 @@ void canvas_draw_alpha_blend(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
pixman_region32_fini(&dest_region);
}
void canvas_draw_opaque(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
SpiceROP rop;
@ -1300,8 +1307,9 @@ void canvas_draw_opaque(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
pixman_region32_fini(&dest_region);
}
void canvas_draw_blend(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
SpiceROP rop;
@ -1372,8 +1380,9 @@ void canvas_draw_blend(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Sp
pixman_region32_fini(&dest_region);
}
void canvas_draw_blackness(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
static void canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_region32_init_rect(&dest_region,
@ -1396,8 +1405,9 @@ void canvas_draw_blackness(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip
pixman_region32_fini(&dest_region);
}
void canvas_draw_whiteness(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
static void canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_region32_init_rect(&dest_region,
@ -1420,8 +1430,9 @@ void canvas_draw_whiteness(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip
pixman_region32_fini(&dest_region);
}
void canvas_draw_invers(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
static void canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_region32_init_rect(&dest_region,
@ -1445,8 +1456,9 @@ void canvas_draw_invers(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
pixman_region32_fini(&dest_region);
}
void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_image_t *d;
pixman_image_t *s;
@ -1509,8 +1521,9 @@ void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
pixman_region32_fini(&dest_region);
}
void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
static void canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
int dx, dy;
@ -1541,8 +1554,9 @@ void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
pixman_region32_fini(&dest_region);
}
void canvas_draw_text(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
static void canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_t dest_region;
pixman_image_t *str_mask, *brush;
SpiceString *str;
@ -1909,8 +1923,9 @@ static void stroke_lines_draw(StrokeLines *lines,
}
void canvas_draw_stroke(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
StrokeGC gc = { {0} };
lineGCOps ops = {
stroke_fill_spans,
@ -2074,8 +2089,9 @@ void canvas_draw_stroke(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
pixman_region32_fini(&gc.dest_region);
}
void canvas_read_bits(CairoCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
static void canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_image_t* surface;
uint8_t *src;
int src_stride;
@ -2093,8 +2109,9 @@ void canvas_read_bits(CairoCanvas *canvas, uint8_t *dest, int dest_stride, const
}
}
void canvas_group_start(CairoCanvas *canvas, QRegion *region)
static void canvas_group_start(SpiceCanvas *spice_canvas, QRegion *region)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_fini(&canvas->canvas_region);
/* Make sure we always clip to canvas size */
pixman_region32_init_rect(&canvas->canvas_region,
@ -2105,8 +2122,9 @@ void canvas_group_start(CairoCanvas *canvas, QRegion *region)
pixman_region32_intersect(&canvas->canvas_region, &canvas->canvas_region, region);
}
void canvas_group_end(CairoCanvas *canvas)
static void canvas_group_end(SpiceCanvas *spice_canvas)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
pixman_region32_fini(&canvas->canvas_region);
pixman_region32_init_rect(&canvas->canvas_region,
0, 0,
@ -2114,8 +2132,9 @@ void canvas_group_end(CairoCanvas *canvas)
pixman_image_get_height(canvas->image));
}
void canvas_clear(CairoCanvas *canvas)
static void canvas_clear(SpiceCanvas *spice_canvas)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
spice_pixman_fill_rect(canvas->image,
0, 0,
pixman_image_get_width(canvas->image),
@ -2123,15 +2142,17 @@ void canvas_clear(CairoCanvas *canvas)
0);
}
static void canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
#ifdef CAIRO_CANVAS_ACCESS_TEST
void canvas_set_access_params(CairoCanvas *canvas, unsigned long base, unsigned long max)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
__canvas_set_access_params(&canvas->base, base, max);
}
#endif
}
void canvas_destroy(CairoCanvas *canvas)
static void canvas_destroy(SpiceCanvas *spice_canvas)
{
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
if (!canvas) {
return;
}
@ -2144,18 +2165,16 @@ void canvas_destroy(CairoCanvas *canvas)
}
static int need_init = 1;
static SpiceCanvasOps cairo_canvas_ops;
SpiceCanvas *canvas_create(pixman_image_t *image, int bits
#ifdef CAIRO_CANVAS_CACHE
CairoCanvas *canvas_create(pixman_image_t *image, int bits,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
CairoCanvas *canvas_create(pixman_image_t *image, int bits,
SpiceImageCache *bits_cache
#else
CairoCanvas *canvas_create(pixman_image_t *image, int bits
, SpiceImageCache *bits_cache
#endif
, SpiceGlzDecoder *glz_decoder
, SpiceGlzDecoder *glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
@ -2168,15 +2187,12 @@ CairoCanvas *canvas_create(pixman_image_t *image, int bits
return NULL;
}
memset(canvas, 0, sizeof(CairoCanvas));
init_ok = canvas_base_init(&canvas->base, &cairo_canvas_ops, bits
#ifdef CAIRO_CANVAS_CACHE
init_ok = canvas_base_init(&canvas->base, bits,
bits_cache,
palette_cache
, bits_cache
, palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
init_ok = canvas_base_init(&canvas->base, bits,
bits_cache
#else
init_ok = canvas_base_init(&canvas->base, bits
, bits_cache
#endif
, glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
@ -2192,7 +2208,7 @@ CairoCanvas *canvas_create(pixman_image_t *image, int bits
pixman_image_get_width (canvas->image),
pixman_image_get_height (canvas->image));
return canvas;
return (SpiceCanvas *)canvas;
}
void cairo_canvas_init() //unsafe global function
@ -2201,6 +2217,29 @@ void cairo_canvas_init() //unsafe global function
return;
}
need_init = 0;
canvas_base_init_ops(&cairo_canvas_ops);
cairo_canvas_ops.draw_fill = canvas_draw_fill;
cairo_canvas_ops.draw_copy = canvas_draw_copy;
cairo_canvas_ops.draw_opaque = canvas_draw_opaque;
cairo_canvas_ops.copy_bits = canvas_copy_bits;
cairo_canvas_ops.draw_text = canvas_draw_text;
cairo_canvas_ops.draw_stroke = canvas_draw_stroke;
cairo_canvas_ops.draw_rop3 = canvas_draw_rop3;
cairo_canvas_ops.draw_blend = canvas_draw_blend;
cairo_canvas_ops.draw_blackness = canvas_draw_blackness;
cairo_canvas_ops.draw_whiteness = canvas_draw_whiteness;
cairo_canvas_ops.draw_invers = canvas_draw_invers;
cairo_canvas_ops.draw_transparent = canvas_draw_transparent;
cairo_canvas_ops.draw_alpha_blend = canvas_draw_alpha_blend;
cairo_canvas_ops.put_image = canvas_put_image;
cairo_canvas_ops.clear = canvas_clear;
cairo_canvas_ops.read_bits = canvas_read_bits;
cairo_canvas_ops.group_start = canvas_group_start;
cairo_canvas_ops.group_end = canvas_group_end;
cairo_canvas_ops.set_access_params = canvas_set_access_params;
cairo_canvas_ops.destroy = canvas_destroy;
rop3_init();
}

View File

@ -26,55 +26,18 @@
#include "canvas_base.h"
#include "region.h"
typedef struct CairoCanvas CairoCanvas;
void canvas_draw_fill(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
void canvas_draw_copy(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
void canvas_draw_opaque(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
void canvas_copy_bits(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
void canvas_draw_text(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
void canvas_draw_stroke(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
void canvas_draw_rop3(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
void canvas_draw_blend(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
void canvas_draw_blackness(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
void canvas_draw_whiteness(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
void canvas_draw_invers(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
void canvas_draw_transparent(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
void canvas_draw_alpha_blend(CairoCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
#ifdef WIN32
void canvas_put_image(CairoCanvas *canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip);
#else
void canvas_put_image(CairoCanvas *canvas, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip);
#endif
void canvas_clear(CairoCanvas *canvas);
void canvas_read_bits(CairoCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
void canvas_group_start(CairoCanvas *canvas, QRegion *region);
void canvas_group_end(CairoCanvas *canvas);
void canvas_set_addr_delta(CairoCanvas *canvas, SPICE_ADDRESS delta);
#ifdef CAIRO_CANVAS_ACCESS_TEST
void canvas_set_access_params(CairoCanvas *canvas, unsigned long base, unsigned long max);
#endif
SpiceCanvas *canvas_create(pixman_image_t *image, int bits
#ifdef CAIRO_CANVAS_CACHE
CairoCanvas *canvas_create(pixman_image_t *image, int bits,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
CairoCanvas *canvas_create(pixman_image_t *image, int bits,
SpiceImageCache *bits_cache
#else
CairoCanvas *canvas_create(pixman_image_t *image, int bits
, SpiceImageCache *bits_cache
#endif
, SpiceGlzDecoder *glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
);
void canvas_destroy(CairoCanvas *canvas);
void cairo_canvas_init();

View File

@ -60,6 +60,11 @@
#define WARN(x) printf("warning: %s\n", x)
#endif
#define PANIC(str) { \
printf("%s: panic: %s", __FUNCTION__, str); \
abort(); \
}
#ifndef DBG
#define DBG(level, format, ...) printf("%s: debug: " format "\n", __FUNCTION__, ## __VA_ARGS__);
#endif
@ -170,6 +175,7 @@ typedef struct QuicData {
} QuicData;
typedef struct CanvasBase {
SpiceCanvas parent;
uint32_t color_shift;
uint32_t color_mask;
QuicData quic_data;
@ -190,6 +196,9 @@ typedef struct CanvasBase {
LzData lz_data;
GlzData glz_data;
void *usr_data;
spice_destroy_fn_t usr_data_destroy;
} CanvasBase;
@ -1538,17 +1547,59 @@ static void canvas_base_destroy(CanvasBase *canvas)
#ifdef GDI_CANVAS
DeleteDC(canvas->dc);
#endif
if (canvas->usr_data && canvas->usr_data_destroy) {
canvas->usr_data_destroy (canvas->usr_data);
canvas->usr_data = NULL;
}
}
/* This is kind of lame, but it protects against muliple
instances of these functions. We really should stop including
canvas_base.c and build it separately instead */
#ifdef CANVAS_SINGLE_INSTANCE
void spice_canvas_set_usr_data(SpiceCanvas *spice_canvas,
void *data,
spice_destroy_fn_t destroy_fn)
{
CanvasBase *canvas = (CanvasBase *)spice_canvas;
if (canvas->usr_data && canvas->usr_data_destroy) {
canvas->usr_data_destroy (canvas->usr_data);
}
canvas->usr_data = data;
canvas->usr_data_destroy = destroy_fn;
}
void *spice_canvas_get_usr_data(SpiceCanvas *spice_canvas)
{
CanvasBase *canvas = (CanvasBase *)spice_canvas;
return canvas->usr_data;
}
#endif
static void unimplemented_op(SpiceCanvas *canvas)
{
PANIC("unimplemented canvas operation");
}
inline static void canvas_base_init_ops(SpiceCanvasOps *ops)
{
void **ops_cast;
int i;
ops_cast = (void **)ops;
for (i = 0; i < sizeof(SpiceCanvasOps) / sizeof(void *); i++) {
ops_cast[i] = (void *) unimplemented_op;
}
}
static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops, int depth
#ifdef CAIRO_CANVAS_CACHE
static int canvas_base_init(CanvasBase *canvas, int depth,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
static int canvas_base_init(CanvasBase *canvas, int depth,
SpiceImageCache *bits_cache
#else
static int canvas_base_init(CanvasBase *canvas, int depth
, SpiceImageCache *bits_cache
#endif
, SpiceGlzDecoder *glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
@ -1556,6 +1607,7 @@ static int canvas_base_init(CanvasBase *canvas, int depth
#endif
)
{
canvas->parent.ops = ops;
canvas->quic_data.usr.error = quic_usr_error;
canvas->quic_data.usr.warn = quic_usr_warn;
canvas->quic_data.usr.info = quic_usr_warn;
@ -1612,4 +1664,3 @@ static int canvas_base_init(CanvasBase *canvas, int depth
#endif
return 1;
}

View File

@ -22,12 +22,16 @@
#include "pixman_utils.h"
#include "lz.h"
#include "region.h"
#include <spice/draw.h>
typedef void (*spice_destroy_fn_t)(void *data);
typedef struct _SpiceImageCache SpiceImageCache;
typedef struct _SpicePaletteCache SpicePaletteCache;
typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
typedef struct _SpiceVirtMapping SpiceVirtMapping;
typedef struct _SpiceCanvas SpiceCanvas;
typedef struct {
void (*put)(SpiceImageCache *cache,
@ -75,5 +79,40 @@ struct _SpiceVirtMapping {
SpiceVirtMappingOps *ops;
};
typedef struct {
void (*draw_fill)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
void (*draw_copy)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
void (*draw_opaque)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
void (*copy_bits)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
void (*draw_text)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
void (*draw_stroke)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
void (*draw_rop3)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
void (*draw_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
void (*draw_blackness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
void (*draw_whiteness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
void (*draw_invers)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
void (*draw_transparent)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
void (*draw_alpha_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
void (*put_image)(SpiceCanvas *canvas,
#ifdef WIN32
HDC dc,
#endif
const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip);
void (*clear)(SpiceCanvas *canvas);
void (*read_bits)(SpiceCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
void (*group_start)(SpiceCanvas *canvas, QRegion *region);
void (*group_end)(SpiceCanvas *canvas);
void (*set_access_params)(SpiceCanvas *canvas, unsigned long base, unsigned long max);
void (*destroy)(SpiceCanvas *canvas);
} SpiceCanvasOps;
void spice_canvas_set_usr_data(SpiceCanvas *canvas, void *data, spice_destroy_fn_t destroy_fn);
void *spice_canvas_get_usr_data(SpiceCanvas *canvas);
struct _SpiceCanvas {
SpiceCanvasOps *ops;
};
#endif

View File

@ -26,6 +26,8 @@
#include "region.h"
#include "threads.h"
typedef struct GdiCanvas GdiCanvas;
struct GdiCanvas {
CanvasBase base;
HDC dc;
@ -976,8 +978,9 @@ static void gdi_draw_image_rop3(HDC dest_dc, const SpiceRect *src, const SpiceRe
release_bitmap(dc, bitmap, prev_bitmap, 0);
}
void gdi_canvas_draw_fill(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
HBRUSH prev_hbrush;
HBRUSH brush;
struct BitmapData bitmapmask;
@ -998,8 +1001,9 @@ void gdi_canvas_draw_fill(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
unset_brush(canvas->dc, prev_hbrush);
}
void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
static void gdi_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
@ -1036,10 +1040,11 @@ void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
pixman_image_unref(surface);
}
void gdi_canvas_put_image(GdiCanvas *canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip)
static void gdi_canvas_put_image(SpiceCanvas *spice_canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
SpiceRect src;
src.top = 0;
src.bottom = src_height;
@ -1127,9 +1132,10 @@ static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const Spi
release_bitmap(dc, bitmap, prev_bitmap, 0);
}
void gdi_canvas_draw_transparent(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
SpiceTransparent* transparent)
static void gdi_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip,
SpiceTransparent* transparent)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
pixman_image_t *surface;
GdiImage image;
PixmanData *pixman_data;
@ -1199,8 +1205,9 @@ static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceR
release_bitmap(dc, bitmap, prev_bitmap, 0);
}
void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
static void gdi_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
pixman_image_t *surface;
GdiImage image;
PixmanData *pixman_data;
@ -1233,8 +1240,9 @@ void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *
pixman_image_unref(surface);
}
void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
@ -1278,8 +1286,9 @@ void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
pixman_image_unref(surface);
}
void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
static void gdi_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
@ -1315,8 +1324,9 @@ void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
pixman_image_unref(surface);
}
void gdi_canvas_draw_blackness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
struct BitmapData bitmapmask;
bitmapmask = get_mask_bitmap(canvas, &blackness->mask);
@ -1328,8 +1338,9 @@ void gdi_canvas_draw_blackness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
free_mask(&bitmapmask);
}
void gdi_canvas_draw_invers(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
static void gdi_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
struct BitmapData bitmapmask;
bitmapmask = get_mask_bitmap(canvas, &invers->mask);
@ -1341,8 +1352,9 @@ void gdi_canvas_draw_invers(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
free_mask(&bitmapmask);
}
void gdi_canvas_draw_whiteness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
struct BitmapData bitmapmask;
bitmapmask = get_mask_bitmap(canvas, &whiteness->mask);
@ -1354,8 +1366,9 @@ void gdi_canvas_draw_whiteness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
free_mask(&bitmapmask);
}
void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
pixman_image_t *surface;
GdiImage image;
struct BitmapData bitmapmask;
@ -1396,8 +1409,9 @@ void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
pixman_image_unref(surface);
}
void gdi_canvas_copy_bits(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
static void gdi_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
Lock lock(*canvas->lock);
set_clip(canvas, clip);
@ -1406,8 +1420,9 @@ void gdi_canvas_copy_bits(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
bbox->bottom - bbox->top, canvas->dc, src_pos->x, src_pos->y, SRCCOPY);
}
void gdi_canvas_draw_text(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
static void gdi_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
SpiceString *str;
Lock lock(*canvas->lock);
@ -1512,8 +1527,9 @@ static uint32_t *gdi_get_userstyle(GdiCanvas *canvas, uint8_t nseg, SPICE_ADDRES
return local_style;
}
void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
static void gdi_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
HPEN hpen;
HPEN prev_hpen;
LOGBRUSH logbrush;
@ -1675,19 +1691,21 @@ void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
}
}
void gdi_canvas_clear(GdiCanvas *canvas)
static void gdi_canvas_clear(SpiceCanvas *spice_canvas)
{
}
static void gdi_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gdi_canvas_set_access_params(GdiCanvas *canvas, unsigned long base, unsigned long max)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
__canvas_set_access_params(&canvas->base, base, max);
}
#endif
}
void gdi_canvas_destroy(GdiCanvas *canvas)
static void gdi_canvas_destroy(SpiceCanvas *spice_canvas)
{
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
if (!canvas) {
return;
}
@ -1696,16 +1714,14 @@ void gdi_canvas_destroy(GdiCanvas *canvas)
}
static int need_init = 1;
static SpiceCanvasOps gdi_canvas_ops;
SpiceCanvas *gdi_canvas_create(HDC dc, Mutex* lock, int bits
#ifdef CAIRO_CANVAS_CACHE
GdiCanvas *gdi_canvas_create(HDC dc, Mutex* lock, int bits,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
GdiCanvas *gdi_canvas_create(HDC dc, int bits,
SpiceImageCache *bits_cache
#else
GdiCanvas *gdi_canvas_create(HDC dc, int bits
, SpiceImageCache *bits_cache
#endif
, SpiceGlzDecoder *glz_decoder
)
@ -1717,20 +1733,17 @@ GdiCanvas *gdi_canvas_create(HDC dc, int bits
return NULL;
}
memset(canvas, 0, sizeof(GdiCanvas));
init_ok = canvas_base_init(&canvas->base, &gdi_canvas_ops, bits
#ifdef CAIRO_CANVAS_CACHE
init_ok = canvas_base_init(&canvas->base, bits,
bits_cache,
palette_cache
,bits_cache
,palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
init_ok = gdi_canvas_base_init(&canvas->base, bits,
bits_cache
#else
init_ok = gdi_canvas_base_init(&canvas->base, bits
, bits_cache
#endif
, glz_decoder);
canvas->dc = dc;
canvas->lock = lock;
return canvas;
return (SpiceCanvas *)canvas;
}
void gdi_canvas_init() //unsafe global function
@ -1739,6 +1752,26 @@ void gdi_canvas_init() //unsafe global function
return;
}
need_init = 0;
canvas_base_init_ops(&gdi_canvas_ops);
gdi_canvas_ops.draw_fill = gdi_canvas_draw_fill;
gdi_canvas_ops.draw_copy = gdi_canvas_draw_copy;
gdi_canvas_ops.draw_opaque = gdi_canvas_draw_opaque;
gdi_canvas_ops.copy_bits = gdi_canvas_copy_bits;
gdi_canvas_ops.draw_text = gdi_canvas_draw_text;
gdi_canvas_ops.draw_stroke = gdi_canvas_draw_stroke;
gdi_canvas_ops.draw_rop3 = gdi_canvas_draw_rop3;
gdi_canvas_ops.draw_blend = gdi_canvas_draw_blend;
gdi_canvas_ops.draw_blackness = gdi_canvas_draw_blackness;
gdi_canvas_ops.draw_whiteness = gdi_canvas_draw_whiteness;
gdi_canvas_ops.draw_invers = gdi_canvas_draw_invers;
gdi_canvas_ops.draw_transparent = gdi_canvas_draw_transparent;
gdi_canvas_ops.draw_alpha_blend = gdi_canvas_draw_alpha_blend;
gdi_canvas_ops.put_image = gdi_canvas_put_image;
gdi_canvas_ops.clear = gdi_canvas_clear;
gdi_canvas_ops.set_access_params = gdi_canvas_set_access_params;
gdi_canvas_ops.destroy = gdi_canvas_destroy;
rop3_init();
}

View File

@ -26,8 +26,6 @@
#include "canvas_base.h"
#include "region.h"
typedef struct GdiCanvas GdiCanvas;
typedef struct {
int width;
int height;
@ -35,36 +33,10 @@ typedef struct {
uint8_t *pixels;
} GdiImage;
void gdi_canvas_draw_fill(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
void gdi_canvas_draw_copy(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
void gdi_canvas_draw_opaque(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
void gdi_canvas_copy_bits(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
void gdi_canvas_draw_text(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
void gdi_canvas_draw_stroke(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
void gdi_canvas_draw_rop3(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
void gdi_canvas_draw_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
void gdi_canvas_draw_blackness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
void gdi_canvas_draw_whiteness(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
void gdi_canvas_draw_invers(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
void gdi_canvas_draw_transparent(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip,
SpiceTransparent* transparent);
void gdi_canvas_draw_alpha_blend(GdiCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
void gdi_canvas_put_image(GdiCanvas *canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip);
void gdi_canvas_clear(GdiCanvas *canvas);
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gdi_canvas_set_access_params(GdiCanvas *canvas, unsigned long base, unsigned long max);
#endif
GdiCanvas *gdi_canvas_create(HDC dc, class Mutex *lock, int bits,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache,
SpiceGlzDecoder *glz_decoder);
void gdi_canvas_destroy(GdiCanvas *canvas);
SpiceCanvas *gdi_canvas_create(HDC dc, class Mutex *lock, int bits,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache,
SpiceGlzDecoder *glz_decoder);
void gdi_canvas_init();

View File

@ -28,12 +28,14 @@
#define GL_CANVAS
#include "canvas_base.c"
typedef struct GLCanvas GLCanvas;
struct GLCanvas {
CanvasBase base;
GLCCtx glc;
void *usr_data;
void *private_data;
int private_data_size;
int textures_lost;
};
static inline uint8_t *copy_opposite_image(GLCanvas *canvas, void *data, int stride, int height)
@ -350,8 +352,9 @@ static void set_op(GLCanvas *canvas, uint16_t rop_decriptor)
glc_set_op(canvas->glc, op);
}
void gl_canvas_draw_fill(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
static void gl_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
GLCRect rect;
set_clip(canvas, bbox, clip);
set_mask(canvas, &fill->mask, bbox->left, bbox->top);
@ -363,8 +366,9 @@ void gl_canvas_draw_fill(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
glc_flush(canvas->glc);
}
void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
static void gl_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
@ -385,8 +389,9 @@ void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
glc_flush(canvas->glc);
}
void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
static void gl_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
@ -413,8 +418,9 @@ void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
glc_flush(canvas->glc);
}
void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd *alpha_blend)
static void gl_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd *alpha_blend)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
@ -434,8 +440,9 @@ void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *cl
glc_flush(canvas->glc);
}
void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
static void gl_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
pixman_image_t *surface;
GLCRecti src;
GLCRecti dest;
@ -455,8 +462,9 @@ void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Sp
glc_flush(canvas->glc);
}
void gl_canvas_draw_transparent(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
static void gl_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
pixman_image_t *surface;
pixman_image_t *trans_surf;
GLCImage image;
@ -493,23 +501,27 @@ static inline void fill_common(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *cli
glc_fill_rect(canvas->glc, &rect);
}
void gl_canvas_draw_whiteness(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
static void gl_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
fill_common(canvas, bbox, clip, &whiteness->mask, GLC_OP_SET);
}
void gl_canvas_draw_blackness(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
static void gl_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
fill_common(canvas, bbox, clip, &blackness->mask, GLC_OP_CLEAR);
}
void gl_canvas_draw_invers(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
static void gl_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
fill_common(canvas, bbox, clip, &invers->mask, GLC_OP_INVERT);
}
void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
static void gl_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
pixman_image_t *d;
pixman_image_t *s;
GLCImage image;
@ -608,8 +620,9 @@ void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
pixman_image_unref(d);
}
void gl_canvas_draw_stroke(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
static void gl_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
GLCPath path;
set_clip(canvas, bbox, clip);
@ -627,8 +640,9 @@ void gl_canvas_draw_stroke(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
glc_path_destroy(path);
}
void gl_canvas_draw_text(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
static void gl_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
GLCRect rect;
SpiceString *str;
@ -685,14 +699,16 @@ void gl_canvas_draw_text(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, Spi
glc_flush(canvas->glc);
}
void gl_canvas_clear(GLCanvas *canvas)
static void gl_canvas_clear(SpiceCanvas *spice_canvas)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
glc_clear(canvas->glc);
glc_flush(canvas->glc);
}
void gl_canvas_copy_pixels(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
static void gl_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
set_clip(canvas, bbox, clip);
glc_clear_mask(canvas->glc, GLC_MASK_A);
glc_set_op(canvas->glc, GLC_OP_COPY);
@ -700,8 +716,9 @@ void gl_canvas_copy_pixels(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, S
bbox->right - bbox->left, bbox->bottom - bbox->top);
}
void gl_canvas_read_pixels(GLCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
static void gl_canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest, int dest_stride, const SpiceRect *area)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
GLCImage image;
ASSERT(dest_stride > 0);
@ -713,8 +730,9 @@ void gl_canvas_read_pixels(GLCanvas *canvas, uint8_t *dest, int dest_stride, con
glc_read_pixels(canvas->glc, area->left, area->top, &image);
}
void gl_canvas_set_top_mask(GLCanvas *canvas, QRegion *region)
static void gl_canvas_group_start(SpiceCanvas *spice_canvas, QRegion *region)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
GLCRect *glc_rects;
GLCRect *now, *end;
int num_rect;
@ -734,10 +752,11 @@ void gl_canvas_set_top_mask(GLCanvas *canvas, QRegion *region)
free(glc_rects);
}
void gl_canvas_put_image(GLCanvas *canvas, const SpiceRect *dest, const uint8_t *src_data,
static void gl_canvas_put_image(SpiceCanvas *spice_canvas, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
GLCRecti src;
GLCRecti gldest;
GLCImage image;
@ -781,39 +800,33 @@ void gl_canvas_put_image(GLCanvas *canvas, const SpiceRect *dest, const uint8_t
glc_flush(canvas->glc);
}
void gl_canvas_clear_top_mask(GLCanvas *canvas)
static void gl_canvas_group_end(SpiceCanvas *spice_canvas)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
glc_clear_mask(canvas->glc, GLC_MASK_B);
}
static void gl_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gl_canvas_set_access_params(GLCanvas *canvas, unsigned long base, unsigned long max)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
__canvas_set_access_params(&canvas->base, base, max);
}
#endif
void *gl_canvas_get_usr_data(GLCanvas *canvas)
{
return canvas->usr_data;
}
static int need_init = 1;
static SpiceCanvasOps gl_canvas_ops;
SpiceCanvas *gl_canvas_create(int width, int height, int depth
#ifdef CAIRO_CANVAS_CACHE
GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth,
SpiceImageCache *bits_cache
#else
GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
, SpiceImageCache *bits_cache
#endif
, SpiceGlzDecoder *glz_decoder
, SpiceGlzDecoder *glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
, SpiceVirtMapping *virt_mapping
#endif
)
{
@ -828,17 +841,13 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
if (!(canvas->glc = glc_create(width, height))) {
goto error_1;
}
canvas->usr_data = usr_data;
canvas->private_data = NULL;
init_ok = canvas_base_init(&canvas->base, &gl_canvas_ops, depth
#ifdef CAIRO_CANVAS_CACHE
init_ok = canvas_base_init(&canvas->base, depth,
bits_cache,
palette_cache
, bits_cache
, palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
init_ok = canvas_base_init(&canvas->base, depth,
bits_cache
#else
init_ok = canvas_base_init(&canvas->base, depth
, bits_cache
#endif
, glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
@ -849,7 +858,7 @@ GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
goto error_2;
}
return canvas;
return (SpiceCanvas *)canvas;
error_2:
glc_destroy(canvas->glc, 0);
@ -859,13 +868,23 @@ error_1:
return NULL;
}
void gl_canvas_destroy(GLCanvas *canvas, int textures_lost)
void gl_canvas_set_textures_lost(SpiceCanvas *spice_canvas,
int textures_lost)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
canvas->textures_lost = textures_lost;
}
static void gl_canvas_destroy(SpiceCanvas *spice_canvas)
{
GLCanvas *canvas = (GLCanvas *)spice_canvas;
if (!canvas) {
return;
}
canvas_base_destroy(&canvas->base);
glc_destroy(canvas->glc, textures_lost);
glc_destroy(canvas->glc, canvas->textures_lost);
if (canvas->private_data) {
free(canvas->private_data);
}
@ -878,5 +897,28 @@ void gl_canvas_init() //unsafe global function
return;
}
need_init = 0;
canvas_base_init_ops(&gl_canvas_ops);
gl_canvas_ops.draw_fill = gl_canvas_draw_fill;
gl_canvas_ops.draw_copy = gl_canvas_draw_copy;
gl_canvas_ops.draw_opaque = gl_canvas_draw_opaque;
gl_canvas_ops.copy_bits = gl_canvas_copy_bits;
gl_canvas_ops.draw_text = gl_canvas_draw_text;
gl_canvas_ops.draw_stroke = gl_canvas_draw_stroke;
gl_canvas_ops.draw_rop3 = gl_canvas_draw_rop3;
gl_canvas_ops.draw_blend = gl_canvas_draw_blend;
gl_canvas_ops.draw_blackness = gl_canvas_draw_blackness;
gl_canvas_ops.draw_whiteness = gl_canvas_draw_whiteness;
gl_canvas_ops.draw_invers = gl_canvas_draw_invers;
gl_canvas_ops.draw_transparent = gl_canvas_draw_transparent;
gl_canvas_ops.draw_alpha_blend = gl_canvas_draw_alpha_blend;
gl_canvas_ops.put_image = gl_canvas_put_image;
gl_canvas_ops.clear = gl_canvas_clear;
gl_canvas_ops.read_bits = gl_canvas_read_bits;
gl_canvas_ops.group_start = gl_canvas_group_start;
gl_canvas_ops.group_end = gl_canvas_group_end;
gl_canvas_ops.set_access_params = gl_canvas_set_access_params;
gl_canvas_ops.destroy = gl_canvas_destroy;
rop3_init();
}

View File

@ -21,55 +21,18 @@
#include "canvas_base.h"
#include "region.h"
typedef struct GLCanvas GLCanvas;
void gl_canvas_draw_fill(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
void gl_canvas_draw_copy(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
void gl_canvas_draw_opaque(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
void gl_canvas_draw_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
void gl_canvas_draw_alpha_blend(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd *alpha_blend);
void gl_canvas_draw_transparent(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent *transparent);
void gl_canvas_draw_whiteness(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
void gl_canvas_draw_blackness(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
void gl_canvas_draw_invers(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
void gl_canvas_draw_rop3(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
void gl_canvas_draw_stroke(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
void gl_canvas_draw_text(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
void gl_canvas_copy_pixels(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
void gl_canvas_read_pixels(GLCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
void gl_canvas_put_image(GLCanvas *canvas, const SpiceRect *dest, const uint8_t *src_data,
uint32_t src_width, uint32_t src_height, int src_stride,
const QRegion *clip);
void gl_canvas_clear(GLCanvas *canvas);
void gl_canvas_set_top_mask(GLCanvas *canvas, QRegion *region);
void gl_canvas_clear_top_mask(GLCanvas *canvas);
#ifdef CAIRO_CANVAS_ACCESS_TEST
void gl_canvas_set_access_params(GLCanvas *canvas, unsigned long base, unsigned long max);
#endif
void *gl_canvas_get_usr_data(GLCanvas *canvas);
SpiceCanvas *gl_canvas_create(int width, int height, int depth
#ifdef CAIRO_CANVAS_CACHE
GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth,
SpiceImageCache *bits_cache
#else
GLCanvas *gl_canvas_create(void *usr_data, int width, int height, int depth
, SpiceImageCache *bits_cache
#endif
, SpiceGlzDecoder *glz_decoder
#ifndef CAIRO_CANVAS_NO_CHUNKS
, SpiceVirtMapping *virt_mapping
#endif
);
void gl_canvas_destroy(GLCanvas *, int);
void gl_canvas_set_textures_lost(SpiceCanvas *canvas, int textures_lost);
void gl_canvas_init();