summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/canvas.cpp68
-rw-r--r--client/canvas.h29
-rw-r--r--client/red_cairo_canvas.cpp96
-rw-r--r--client/red_cairo_canvas.h25
-rw-r--r--client/red_gdi_canvas.cpp84
-rw-r--r--client/red_gdi_canvas.h20
-rw-r--r--client/red_gl_canvas.cpp101
-rw-r--r--client/red_gl_canvas.h20
-rw-r--r--common/cairo_canvas.c127
-rw-r--r--common/cairo_canvas.h45
-rw-r--r--common/canvas_base.c67
-rw-r--r--common/canvas_base.h39
-rw-r--r--common/gdi_canvas.c107
-rw-r--r--common/gdi_canvas.h36
-rw-r--r--common/gl_canvas.c136
-rw-r--r--common/gl_canvas.h47
-rw-r--r--server/red_worker.c284
17 files changed, 501 insertions, 830 deletions
diff --git a/client/canvas.cpp b/client/canvas.cpp
index 516a874c..ba446c9a 100644
--- a/client/canvas.cpp
+++ b/client/canvas.cpp
@@ -23,7 +23,8 @@
Canvas::Canvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window)
- : _pixmap_cache (pixmap_cache)
+ : _canvas (NULL)
+ , _pixmap_cache (pixmap_cache)
, _palette_cache (palette_cache)
, _glz_decoder(glz_decoder_window, _glz_handler, _glz_debug)
{
@@ -31,8 +32,17 @@ Canvas::Canvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
Canvas::~Canvas()
{
+ /* _canvas is both set and destroyed by derived class */
}
+void Canvas::clear()
+{
+ if (_canvas) {
+ _canvas->ops->clear(_canvas);
+ }
+}
+
+
inline void Canvas::access_test(void *ptr, size_t size)
{
if ((unsigned long)ptr < _base || (unsigned long)ptr + size > _max) {
@@ -107,7 +117,7 @@ void Canvas::begin_draw(SpiceMsgDisplayBase& base, int size, size_t min_size)
{
_base = (unsigned long)&base;
_max = _base + size;
- set_access_params(_base, _max);
+ _canvas->ops->set_access_params(_canvas, _base, _max);
access_test(&base, min_size);
localalize_ptr(&base.clip.data);
}
@@ -117,7 +127,8 @@ void Canvas::draw_fill(SpiceMsgDisplayDrawFill& fill, int size)
begin_draw(fill.base, size, sizeof(SpiceMsgDisplayDrawFill));
localalize_brush(fill.data.brush);
localalize_mask(fill.data.mask);
- draw_fill(&fill.base.box, &fill.base.clip, &fill.data);
+ _canvas->ops->draw_fill(_canvas, &fill.base.box, &fill.base.clip, &fill.data);
+ touched_bbox(&fill.base.box);
}
void Canvas::draw_text(SpiceMsgDisplayDrawText& text, int size)
@@ -126,7 +137,8 @@ void Canvas::draw_text(SpiceMsgDisplayDrawText& text, int size)
localalize_brush(text.data.fore_brush);
localalize_brush(text.data.back_brush);
localalize_ptr(&text.data.str);
- draw_text(&text.base.box, &text.base.clip, &text.data);
+ _canvas->ops->draw_text(_canvas, &text.base.box, &text.base.clip, &text.data);
+ touched_bbox(&text.base.box);
}
void Canvas::draw_opaque(SpiceMsgDisplayDrawOpaque& opaque, int size)
@@ -135,7 +147,8 @@ void Canvas::draw_opaque(SpiceMsgDisplayDrawOpaque& opaque, int size)
localalize_brush(opaque.data.brush);
localalize_image(&opaque.data.src_bitmap);
localalize_mask(opaque.data.mask);
- draw_opaque(&opaque.base.box, &opaque.base.clip, &opaque.data);
+ _canvas->ops->draw_opaque(_canvas, &opaque.base.box, &opaque.base.clip, &opaque.data);
+ touched_bbox(&opaque.base.box);
}
void Canvas::draw_copy(SpiceMsgDisplayDrawCopy& copy, int size)
@@ -143,27 +156,31 @@ void Canvas::draw_copy(SpiceMsgDisplayDrawCopy& copy, int size)
begin_draw(copy.base, size, sizeof(SpiceMsgDisplayDrawCopy));
localalize_image(&copy.data.src_bitmap);
localalize_mask(copy.data.mask);
- draw_copy(&copy.base.box, &copy.base.clip, &copy.data);
+ _canvas->ops->draw_copy(_canvas, &copy.base.box, &copy.base.clip, &copy.data);
+ touched_bbox(&copy.base.box);
}
void Canvas::draw_transparent(SpiceMsgDisplayDrawTransparent& transparent, int size)
{
begin_draw(transparent.base, size, sizeof(SpiceMsgDisplayDrawTransparent));
localalize_image(&transparent.data.src_bitmap);
- draw_transparent(&transparent.base.box, &transparent.base.clip, &transparent.data);
+ _canvas->ops->draw_transparent(_canvas, &transparent.base.box, &transparent.base.clip, &transparent.data);
+ touched_bbox(&transparent.base.box);
}
void Canvas::draw_alpha_blend(SpiceMsgDisplayDrawAlphaBlend& alpha_blend, int size)
{
begin_draw(alpha_blend.base, size, sizeof(SpiceMsgDisplayDrawAlphaBlend));
localalize_image(&alpha_blend.data.src_bitmap);
- draw_alpha_blend(&alpha_blend.base.box, &alpha_blend.base.clip, &alpha_blend.data);
+ _canvas->ops->draw_alpha_blend(_canvas, &alpha_blend.base.box, &alpha_blend.base.clip, &alpha_blend.data);
+ touched_bbox(&alpha_blend.base.box);
}
void Canvas::copy_bits(SpiceMsgDisplayCopyBits& copy, int size)
{
begin_draw(copy.base, size, sizeof(SpiceMsgDisplayCopyBits));
- copy_bits(&copy.base.box, &copy.base.clip, &copy.src_pos);
+ _canvas->ops->copy_bits(_canvas, &copy.base.box, &copy.base.clip, &copy.src_pos);
+ touched_bbox(&copy.base.box);
}
void Canvas::draw_blend(SpiceMsgDisplayDrawBlend& blend, int size)
@@ -171,28 +188,32 @@ void Canvas::draw_blend(SpiceMsgDisplayDrawBlend& blend, int size)
begin_draw(blend.base, size, sizeof(SpiceMsgDisplayDrawBlend));
localalize_image(&blend.data.src_bitmap);
localalize_mask(blend.data.mask);
- draw_blend(&blend.base.box, &blend.base.clip, &blend.data);
+ _canvas->ops->draw_blend(_canvas, &blend.base.box, &blend.base.clip, &blend.data);
+ touched_bbox(&blend.base.box);
}
void Canvas::draw_blackness(SpiceMsgDisplayDrawBlackness& blackness, int size)
{
begin_draw(blackness.base, size, sizeof(SpiceMsgDisplayDrawBlackness));
localalize_mask(blackness.data.mask);
- draw_blackness(&blackness.base.box, &blackness.base.clip, &blackness.data);
+ _canvas->ops->draw_blackness(_canvas, &blackness.base.box, &blackness.base.clip, &blackness.data);
+ touched_bbox(&blackness.base.box);
}
void Canvas::draw_whiteness(SpiceMsgDisplayDrawWhiteness& whiteness, int size)
{
begin_draw(whiteness.base, size, sizeof(SpiceMsgDisplayDrawWhiteness));
localalize_mask(whiteness.data.mask);
- draw_whiteness(&whiteness.base.box, &whiteness.base.clip, &whiteness.data);
+ _canvas->ops->draw_whiteness(_canvas, &whiteness.base.box, &whiteness.base.clip, &whiteness.data);
+ touched_bbox(&whiteness.base.box);
}
void Canvas::draw_invers(SpiceMsgDisplayDrawInvers& invers, int size)
{
begin_draw(invers.base, size, sizeof(SpiceMsgDisplayDrawInvers));
localalize_mask(invers.data.mask);
- draw_invers(&invers.base.box, &invers.base.clip, &invers.data);
+ _canvas->ops->draw_invers(_canvas, &invers.base.box, &invers.base.clip, &invers.data);
+ touched_bbox(&invers.base.box);
}
void Canvas::draw_rop3(SpiceMsgDisplayDrawRop3& rop3, int size)
@@ -201,7 +222,8 @@ void Canvas::draw_rop3(SpiceMsgDisplayDrawRop3& rop3, int size)
localalize_brush(rop3.data.brush);
localalize_image(&rop3.data.src_bitmap);
localalize_mask(rop3.data.mask);
- draw_rop3(&rop3.base.box, &rop3.base.clip, &rop3.data);
+ _canvas->ops->draw_rop3(_canvas, &rop3.base.box, &rop3.base.clip, &rop3.data);
+ touched_bbox(&rop3.base.box);
}
void Canvas::draw_stroke(SpiceMsgDisplayDrawStroke& stroke, int size)
@@ -210,5 +232,21 @@ void Canvas::draw_stroke(SpiceMsgDisplayDrawStroke& stroke, int size)
localalize_brush(stroke.data.brush);
localalize_ptr(&stroke.data.path);
localalize_attr(stroke.data.attr);
- draw_stroke(&stroke.base.box, &stroke.base.clip, &stroke.data);
+ _canvas->ops->draw_stroke(_canvas, &stroke.base.box, &stroke.base.clip, &stroke.data);
+ touched_bbox(&stroke.base.box);
+}
+
+void Canvas::put_image(
+#ifdef WIN32
+ HDC dc,
+#endif
+ const PixmapHeader& image, const SpiceRect& dest, const QRegion* clip)
+{
+ _canvas->ops->put_image(_canvas,
+#ifdef WIN32
+ dc,
+#endif
+ &dest, image.data, image.width, image.height, image.stride,
+ clip);
+ touched_bbox(&dest);
}
diff --git a/client/canvas.h b/client/canvas.h
index 2f122638..8e3a8f1b 100644
--- a/client/canvas.h
+++ b/client/canvas.h
@@ -249,7 +249,7 @@ public:
virtual void copy_pixels(const QRegion& region, RedDrawable& dc) = 0;
virtual void thread_touch() = 0;
- virtual void clear() = 0;
+ void clear();
void draw_fill(SpiceMsgDisplayDrawFill& fill, int size);
void draw_text(SpiceMsgDisplayDrawText& text, int size);
@@ -265,31 +265,17 @@ public:
void draw_rop3(SpiceMsgDisplayDrawRop3& rop3, int size);
void draw_stroke(SpiceMsgDisplayDrawStroke& stroke, int size);
+ void put_image(
#ifdef WIN32
- virtual void put_image(HDC dc, const PixmapHeader& image,
- const SpiceRect& dest, const QRegion* clip) = 0;
-#else
- virtual void put_image(const PixmapHeader& image, const SpiceRect& dest,
- const QRegion* clip) = 0;
+ HDC dc,
#endif
+ const PixmapHeader& image,
+ const SpiceRect& dest, const QRegion* clip);
virtual CanvasType get_pixmap_type() { return CANVAS_TYPE_INVALID; }
protected:
- virtual void set_access_params(unsigned long base, unsigned long max) = 0;
- virtual void draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill) = 0;
- virtual void draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy) = 0;
- virtual void draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque) = 0;
- virtual void copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos) = 0;
- virtual void draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text) = 0;
- virtual void draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke) = 0;
- virtual void draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3) = 0;
- virtual void draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend) = 0;
- virtual void draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness) = 0;
- virtual void draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness) = 0;
- virtual void draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers) = 0;
- virtual void draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent) = 0;
- virtual void draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend) = 0;
+ virtual void touched_bbox(const SpiceRect *bbox) {};
PixmapCache& pixmap_cache() { return _pixmap_cache;}
PaletteCache& palette_cache() { return _palette_cache;}
@@ -305,6 +291,9 @@ private:
void localalize_mask(SpiceQMask& mask);
void begin_draw(SpiceMsgDisplayBase& base, int size, size_t min_size);
+protected:
+ SpiceCanvas* _canvas;
+
private:
PixmapCache& _pixmap_cache;
PaletteCache& _palette_cache;
diff --git a/client/red_cairo_canvas.cpp b/client/red_cairo_canvas.cpp
index 97277fb3..02c105a6 100644
--- a/client/red_cairo_canvas.cpp
+++ b/client/red_cairo_canvas.cpp
@@ -27,7 +27,6 @@
CCanvas::CCanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window)
: Canvas (pixmap_cache, palette_cache, glz_decoder_window)
- , _canvas (NULL)
, _pixmap (0)
{
}
@@ -40,19 +39,12 @@ CCanvas::~CCanvas()
void CCanvas::destroy()
{
if (_canvas) {
- canvas_destroy(_canvas);
+ _canvas->ops->destroy(_canvas);
_canvas = NULL;
}
destroy_pixmap();
}
-void CCanvas::clear()
-{
- if (_canvas) {
- canvas_clear(_canvas);
- }
-}
-
void CCanvas::destroy_pixmap()
{
delete _pixmap;
@@ -108,92 +100,6 @@ void CCanvas::set_mode(int width, int height, int depth, RedWindow *win)
pixman_image_unref (surface);
}
-void CCanvas::set_access_params(unsigned long base, unsigned long max)
-{
- canvas_set_access_params(_canvas, base, max);
-}
-
-void CCanvas::draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
-{
- canvas_draw_fill(_canvas, bbox, clip, fill);
-}
-
-void CCanvas::draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
-{
- canvas_draw_text(_canvas, bbox, clip, text);
-}
-
-void CCanvas::draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
-{
- canvas_draw_opaque(_canvas, bbox, clip, opaque);
-}
-
-void CCanvas::draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
-{
- canvas_draw_copy(_canvas, bbox, clip, copy);
-}
-
-void CCanvas::draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
-{
- canvas_draw_transparent(_canvas, bbox, clip, transparent);
-}
-
-void CCanvas::draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
-{
- canvas_draw_alpha_blend(_canvas, bbox, clip, alpha_blend);
-}
-
-void CCanvas::copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
-{
- canvas_copy_bits(_canvas, bbox, clip, src_pos);
-}
-
-void CCanvas::draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
-{
- canvas_draw_blend(_canvas, bbox, clip, blend);
-}
-
-void CCanvas::draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
-{
- canvas_draw_blackness(_canvas, bbox, clip, blackness);
-}
-
-void CCanvas::draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
-{
- canvas_draw_whiteness(_canvas, bbox, clip, whiteness);
-}
-
-void CCanvas::draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
-{
- canvas_draw_invers(_canvas, bbox, clip, invers);
-}
-
-void CCanvas::draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
-{
- canvas_draw_rop3(_canvas, bbox, clip, rop3);
-}
-
-void CCanvas::draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
-{
- canvas_draw_stroke(_canvas, bbox, clip, stroke);
-}
-
-#ifdef WIN32
-void CCanvas::put_image(HDC dc, const PixmapHeader& image, const SpiceRect& dest, const QRegion* clip)
-{
- canvas_put_image(_canvas, dc, &dest, image.data, image.width, image.height, image.stride,
- clip);
-}
-
-#else
-void CCanvas::put_image(const PixmapHeader& image, const SpiceRect& dest, const QRegion* clip)
-{
- canvas_put_image(_canvas, &dest, image.data, image.width, image.height, image.stride,
- clip);
-}
-
-#endif
-
CanvasType CCanvas::get_pixmap_type()
{
return CANVAS_TYPE_CAIRO;
diff --git a/client/red_cairo_canvas.h b/client/red_cairo_canvas.h
index 2bcb3a89..51c6c5ad 100644
--- a/client/red_cairo_canvas.h
+++ b/client/red_cairo_canvas.h
@@ -30,44 +30,19 @@ public:
virtual ~CCanvas();
virtual void set_mode(int x, int y, int bits, RedWindow *win);
- virtual void clear();
virtual void thread_touch() {}
virtual void copy_pixels(const QRegion& region, RedDrawable* dc,
const PixmapHeader* pixmap);
virtual void copy_pixels(const QRegion& region, RedDrawable& dc);
-#ifdef WIN32
- virtual void put_image(HDC dc, const PixmapHeader& image,
- const SpiceRect& dest, const QRegion* clip);
-#else
- virtual void put_image(const PixmapHeader& image, const SpiceRect& dest,
- const QRegion* clip);
-#endif
virtual CanvasType get_pixmap_type();
-protected:
- virtual void set_access_params(unsigned long base, unsigned long max);
- virtual void draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
- virtual void draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
- virtual void draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
- virtual void copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
- virtual void draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
- virtual void draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
- virtual void draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
- virtual void draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
- virtual void draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
- virtual void draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
- virtual void draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
- virtual void draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
- virtual void draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
-
private:
void create_pixmap(int width, int height, RedWindow *win);
void destroy_pixmap();
void destroy();
private:
- CairoCanvas* _canvas;
RedPixmap *_pixmap;
unsigned long _base;
unsigned long _max;
diff --git a/client/red_gdi_canvas.cpp b/client/red_gdi_canvas.cpp
index efdf5d4d..a623e64c 100644
--- a/client/red_gdi_canvas.cpp
+++ b/client/red_gdi_canvas.cpp
@@ -26,7 +26,6 @@
GDICanvas::GDICanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window)
: Canvas (pixmap_cache, palette_cache, glz_decoder_window)
- , _canvas (NULL)
, _pixmap (0)
{
}
@@ -44,13 +43,6 @@ void GDICanvas::destroy()
destroy_pixmap();
}
-void GDICanvas::clear()
-{
- if (_canvas) {
- gdi_canvas_clear(_canvas);
- }
-}
-
void GDICanvas::destroy_pixmap()
{
delete _pixmap;
@@ -97,82 +89,6 @@ void GDICanvas::set_mode(int width, int height, int depth)
}
}
-void GDICanvas::set_access_params(unsigned long base, unsigned long max)
-{
- gdi_canvas_set_access_params(_canvas, base, max);
-}
-
-void GDICanvas::draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
-{
- gdi_canvas_draw_fill(_canvas, bbox, clip, fill);
-}
-
-void GDICanvas::draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
-{
- gdi_canvas_draw_text(_canvas, bbox, clip, text);
-}
-
-void GDICanvas::draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
-{
- gdi_canvas_draw_opaque(_canvas, bbox, clip, opaque);
-}
-
-void GDICanvas::draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
-{
- gdi_canvas_draw_copy(_canvas, bbox, clip, copy);
-}
-
-void GDICanvas::draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
-{
- gdi_canvas_draw_transparent(_canvas, bbox, clip, transparent);
-}
-
-void GDICanvas::draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
-{
- gdi_canvas_draw_alpha_blend(_canvas, bbox, clip, alpha_blend);
-}
-
-void GDICanvas::copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
-{
- gdi_canvas_copy_bits(_canvas, bbox, clip, src_pos);
-}
-
-void GDICanvas::draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
-{
- gdi_canvas_draw_blend(_canvas, bbox, clip, blend);
-}
-
-void GDICanvas::draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
-{
- gdi_canvas_draw_blackness(_canvas, bbox, clip, blackness);
-}
-
-void GDICanvas::draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
-{
- gdi_canvas_draw_whiteness(_canvas, bbox, clip, whiteness);
-}
-
-void GDICanvas::draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
-{
- gdi_canvas_draw_invers(_canvas, bbox, clip, invers);
-}
-
-void GDICanvas::draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
-{
- gdi_canvas_draw_rop3(_canvas, bbox, clip, rop3);
-}
-
-void GDICanvas::draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
-{
- gdi_canvas_draw_stroke(_canvas, bbox, clip, stroke);
-}
-
-void GDICanvas::put_image(HDC dc, const PixmapHeader& image, const SpiceRect& dest, const QRegion* clip)
-{
- gdi_canvas_put_image(_canvas, dc, &dest, image.data, image.width, image.height, image.stride,
- clip);
-}
-
CanvasType GDICanvas::get_pixmap_type()
{
return CANVAS_TYPE_GDI;
diff --git a/client/red_gdi_canvas.h b/client/red_gdi_canvas.h
index 6f494340..83fc1205 100644
--- a/client/red_gdi_canvas.h
+++ b/client/red_gdi_canvas.h
@@ -32,39 +32,19 @@ public:
virtual ~GDICanvas();
virtual void set_mode(int x, int y, int bits);
- virtual void clear();
virtual void thread_touch() {}
virtual void copy_pixels(const QRegion& region, RedDrawable* dc,
const PixmapHeader* pixmap);
virtual void copy_pixels(const QRegion& region, RedDrawable& dc);
- virtual void put_image(HDC dc, const PixmapHeader& image, const SpiceRect& dest,
- const QRegion* clip);
virtual CanvasType get_pixmap_type();
-protected:
- virtual void set_access_params(unsigned long base, unsigned long max);
- virtual void draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
- virtual void draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
- virtual void draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
- virtual void copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
- virtual void draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
- virtual void draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
- virtual void draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
- virtual void draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
- virtual void draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
- virtual void draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
- virtual void draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
- virtual void draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
- virtual void draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
-
private:
void create_pixmap(int width, int height);
void destroy_pixmap();
void destroy();
private:
- GdiCanvas* _canvas;
RedPixmapGdi *_pixmap;
RedPixmapGdi *_helper_pixmap;
HDC _dc;
diff --git a/client/red_gl_canvas.cpp b/client/red_gl_canvas.cpp
index 76dabc71..c6bb1137 100644
--- a/client/red_gl_canvas.cpp
+++ b/client/red_gl_canvas.cpp
@@ -27,7 +27,6 @@
GCanvas::GCanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window)
: Canvas(pixmap_cache, palette_cache, glz_decoder_window)
- , _canvas (NULL)
, _pixmap (0)
, _textures_lost (false)
{
@@ -41,19 +40,13 @@ GCanvas::~GCanvas()
void GCanvas::destroy()
{
if (_canvas) {
- gl_canvas_destroy(_canvas, _textures_lost);
+ gl_canvas_set_textures_lost (_canvas, (int)_textures_lost);
+ _canvas->ops->destroy(_canvas);
_canvas = NULL;
}
destroy_pixmap();
}
-void GCanvas::clear()
-{
- if (_canvas) {
- gl_canvas_clear(_canvas);
- }
-}
-
void GCanvas::destroy_pixmap()
{
delete _pixmap;
@@ -96,7 +89,7 @@ void GCanvas::set_mode(int width, int height, int depth, RedWindow *win,
destroy();
create_pixmap(width, height, win, rendertype);
- if (!(_canvas = gl_canvas_create(NULL, width, height, depth,
+ if (!(_canvas = gl_canvas_create(width, height, depth,
&pixmap_cache().base,
&palette_cache().base,
&glz_decoder()))) {
@@ -104,97 +97,11 @@ void GCanvas::set_mode(int width, int height, int depth, RedWindow *win,
}
}
-void GCanvas::set_access_params(unsigned long base, unsigned long max)
-{
- gl_canvas_set_access_params(_canvas, base, max);
-}
-
-void GCanvas::draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
-{
- gl_canvas_draw_fill(_canvas, bbox, clip, fill);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
-{
- gl_canvas_draw_text(_canvas, bbox, clip, text);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
-{
- gl_canvas_draw_opaque(_canvas, bbox, clip, opaque);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
+void GCanvas::touched_bbox(const SpiceRect *bbox)
{
- gl_canvas_draw_copy(_canvas, bbox, clip, copy);
_pixmap->update_texture(bbox);
}
-void GCanvas::draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
-{
- gl_canvas_draw_transparent(_canvas, bbox, clip, transparent);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
-{
- gl_canvas_draw_alpha_blend(_canvas, bbox, clip, alpha_blend);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
-{
- gl_canvas_copy_pixels(_canvas, bbox, clip, src_pos);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
-{
- gl_canvas_draw_blend(_canvas, bbox, clip, blend);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
-{
- gl_canvas_draw_blackness(_canvas, bbox, clip, blackness);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
-{
- gl_canvas_draw_whiteness(_canvas, bbox, clip, whiteness);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
-{
- gl_canvas_draw_invers(_canvas, bbox, clip, invers);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
-{
- gl_canvas_draw_rop3(_canvas, bbox, clip, rop3);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
-{
- gl_canvas_draw_stroke(_canvas, bbox, clip, stroke);
- _pixmap->update_texture(bbox);
-}
-
-void GCanvas::put_image(const PixmapHeader& image, const SpiceRect& dest,
- const QRegion* clip)
-{
- gl_canvas_put_image(_canvas, &dest, image.data, image.width, image.height,
- image.stride, clip);
- _pixmap->update_texture(&dest);
-}
-
CanvasType GCanvas::get_pixmap_type()
{
return CANVAS_TYPE_GL;
diff --git a/client/red_gl_canvas.h b/client/red_gl_canvas.h
index 918aa6c6..983f7729 100644
--- a/client/red_gl_canvas.h
+++ b/client/red_gl_canvas.h
@@ -39,29 +39,12 @@ public:
void copy_pixels(const QRegion& region, RedDrawable* dc,
const PixmapHeader* pixmap);
void copy_pixels(const QRegion& region, RedDrawable& dc);
- void put_image(const PixmapHeader& image, const SpiceRect& dest,
- const QRegion* clip);
-
- void set_access_params(unsigned long base, unsigned long max);
- void draw_fill(SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
- void draw_copy(SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
- void draw_opaque(SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
- void copy_bits(SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
- void draw_text(SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
- void draw_stroke(SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
- void draw_rop3(SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
- void draw_blend(SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
- void draw_blackness(SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
- void draw_whiteness(SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
- void draw_invers(SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
- void draw_transparent(SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
- void draw_alpha_blend(SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
-
virtual void textures_lost();
virtual CanvasType get_pixmap_type();
virtual void touch_context();
virtual void pre_gl_copy();
virtual void post_gl_copy();
+ void touched_bbox(const SpiceRect *bbox);
private:
void create_pixmap(int width, int height, RedWindow *win,
@@ -70,7 +53,6 @@ private:
void destroy();
private:
- GLCanvas* _canvas;
RedPixmapGL *_pixmap;
bool _textures_lost;
};
diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c
index 8dcb12dd..426643e5 100644
--- a/common/cairo_canvas.c
+++ b/common/cairo_canvas.c
@@ -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);
}
-#ifdef CAIRO_CANVAS_ACCESS_TEST
-void canvas_set_access_params(CairoCanvas *canvas, unsigned long base, unsigned long max)
+static void canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
+#ifdef CAIRO_CANVAS_ACCESS_TEST
+ 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();
}
diff --git a/common/cairo_canvas.h b/common/cairo_canvas.h
index c0102aee..3f6fbbc6 100644
--- a/common/cairo_canvas.h
+++ b/common/cairo_canvas.h
@@ -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();
diff --git a/common/canvas_base.c b/common/canvas_base.c
index 01945ec9..2a946076 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -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;
}
-
diff --git a/common/canvas_base.h b/common/canvas_base.h
index 4c286547..48e921e6 100644
--- a/common/canvas_base.h
+++ b/common/canvas_base.h
@@ -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
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
index 40305df8..4d5bc9db 100644
--- a/common/gdi_canvas.c
+++ b/common/gdi_canvas.c
@@ -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)
{
}
-#ifdef CAIRO_CANVAS_ACCESS_TEST
-void gdi_canvas_set_access_params(GdiCanvas *canvas, unsigned long base, unsigned long max)
+static void gdi_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
+#ifdef CAIRO_CANVAS_ACCESS_TEST
+ 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();
}
diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h
index 12082d83..b3dc6057 100644
--- a/common/gdi_canvas.h
+++ b/common/gdi_canvas.h
@@ -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();
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
index e7a7bfff..99f14f5d 100644
--- a/common/gl_canvas.c
+++ b/common/gl_canvas.c
@@ -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);
}
-#ifdef CAIRO_CANVAS_ACCESS_TEST
-void gl_canvas_set_access_params(GLCanvas *canvas, unsigned long base, unsigned long max)
+static void gl_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long base, unsigned long max)
{
+#ifdef CAIRO_CANVAS_ACCESS_TEST
+ 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();
}
diff --git a/common/gl_canvas.h b/common/gl_canvas.h
index ee272a8a..29737ec8 100644
--- a/common/gl_canvas.h
+++ b/common/gl_canvas.h
@@ -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();
diff --git a/server/red_worker.c b/server/red_worker.c
index 6eaf391f..e8c986f6 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -830,48 +830,9 @@ typedef struct UpgradeItem {
uint32_t n_rects;
} UpgradeItem;
-typedef void (*draw_fill_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
-typedef void (*draw_copy_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
-typedef void (*draw_opaque_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
-typedef void (*copy_bits_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
-typedef void (*draw_text_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
-typedef void (*draw_stroke_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
-typedef void (*draw_rop3_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
-typedef void (*draw_blend_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
-typedef void (*draw_blackness_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
-typedef void (*draw_whiteness_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
-typedef void (*draw_invers_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
-typedef void (*draw_transparent_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
-typedef void (*draw_alpha_blend_t)(void *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend);
-typedef void (*read_pixels_t)(void *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
-typedef void (*set_top_mask_t)(void *canvas, QRegion *region);
-typedef void (*clear_top_mask_t)(void *canvas);
-typedef void (*validate_area_t)(void *canvas, int32_t stride, uint8_t *line_0, const SpiceRect *area);
-typedef void (*destroy_t)(void *canvas);
-
-typedef struct DrawFuncs {
- draw_fill_t draw_fill;
- draw_copy_t draw_copy;
- draw_opaque_t draw_opaque;
- copy_bits_t copy_bits;
- draw_text_t draw_text;
- draw_stroke_t draw_stroke;
- draw_rop3_t draw_rop3;
- draw_blend_t draw_blend;
- draw_blackness_t draw_blackness;
- draw_whiteness_t draw_whiteness;
- draw_invers_t draw_invers;
- draw_transparent_t draw_transparent;
- draw_alpha_blend_t draw_alpha_blend;
- read_pixels_t read_pixels;
- set_top_mask_t set_top_mask;
- clear_top_mask_t clear_top_mask;
- validate_area_t validate_area;
- destroy_t destroy;
-} DrawFuncs;
-
typedef struct DrawContext {
- void *canvas;
+ SpiceCanvas *canvas;
+ int canvas_draws_on_surface;
int top_down;
uint32_t width;
uint32_t height;
@@ -929,7 +890,6 @@ typedef struct RedWorker {
uint32_t renderers[RED_MAX_RENDERERS];
uint32_t renderer;
- DrawFuncs draw_funcs;
Surface surface;
Ring current_list;
@@ -1546,8 +1506,10 @@ static inline void __red_destroy_surface(RedWorker *worker)
#ifdef STREAM_TRACE
red_reset_stream_trace(worker);
#endif
- worker->draw_funcs.destroy(surface->context.canvas);
- surface->context.canvas = NULL;
+ if (surface->context.canvas) {
+ surface->context.canvas->ops->destroy(surface->context.canvas);
+ surface->context.canvas = NULL;
+ }
}
}
@@ -3574,11 +3536,12 @@ static inline int red_current_add_qxl(RedWorker *worker, Drawable *drawable,
static void red_get_area(RedWorker *worker, const SpiceRect *area, uint8_t *dest, int dest_stride,
int update)
{
+ SpiceCanvas *canvas = worker->surface.context.canvas;
if (update) {
red_update_area(worker, area);
}
- worker->draw_funcs.read_pixels(worker->surface.context.canvas, dest, dest_stride, area);
+ canvas->ops->read_bits(canvas, dest, dest_stride, area);
}
static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
@@ -4173,6 +4136,7 @@ static void unlocalize_attr(SpiceLineAttr *attr)
static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
{
SpiceClip clip = drawable->qxl_drawable->clip;
+ SpiceCanvas *canvas = worker->surface.context.canvas;
worker->local_images_pos = 0;
image_cache_eaging(&worker->image_cache);
@@ -4185,8 +4149,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
SpiceFill fill = drawable->qxl_drawable->u.fill;
localize_brush(worker, &fill.brush, drawable->group_id);
localize_mask(worker, &fill.mask, drawable->group_id);
- worker->draw_funcs.draw_fill(worker->surface.context.canvas, &drawable->qxl_drawable->bbox,
- &clip, &fill); unlocalize_mask(&fill.mask);
+ canvas->ops->draw_fill(canvas, &drawable->qxl_drawable->bbox,
+ &clip, &fill); unlocalize_mask(&fill.mask);
unlocalize_brush(&fill.brush);
break;
}
@@ -4195,8 +4159,7 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
localize_brush(worker, &opaque.brush, drawable->group_id);
localize_bitmap(worker, &opaque.src_bitmap, drawable->group_id);
localize_mask(worker, &opaque.mask, drawable->group_id);
- worker->draw_funcs.draw_opaque(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &opaque);
+ canvas->ops->draw_opaque(canvas, &drawable->qxl_drawable->bbox, &clip, &opaque);
unlocalize_mask(&opaque.mask);
unlocalize_bitmap(&opaque.src_bitmap);
unlocalize_brush(&opaque.brush);
@@ -4206,8 +4169,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
SpiceCopy copy = drawable->qxl_drawable->u.copy;
localize_bitmap(worker, &copy.src_bitmap, drawable->group_id);
localize_mask(worker, &copy.mask, drawable->group_id);
- worker->draw_funcs.draw_copy(worker->surface.context.canvas, &drawable->qxl_drawable->bbox,
- &clip, &copy);
+ canvas->ops->draw_copy(canvas, &drawable->qxl_drawable->bbox,
+ &clip, &copy);
unlocalize_mask(&copy.mask);
unlocalize_bitmap(&copy.src_bitmap);
break;
@@ -4215,30 +4178,30 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
case QXL_DRAW_TRANSPARENT: {
SpiceTransparent transparent = drawable->qxl_drawable->u.transparent;
localize_bitmap(worker, &transparent.src_bitmap, drawable->group_id);
- worker->draw_funcs.draw_transparent(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &transparent);
+ canvas->ops->draw_transparent(canvas,
+ &drawable->qxl_drawable->bbox, &clip, &transparent);
unlocalize_bitmap(&transparent.src_bitmap);
break;
}
case QXL_DRAW_ALPHA_BLEND: {
SpiceAlphaBlnd alpha_blend = drawable->qxl_drawable->u.alpha_blend;
localize_bitmap(worker, &alpha_blend.src_bitmap, drawable->group_id);
- worker->draw_funcs.draw_alpha_blend(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &alpha_blend);
+ canvas->ops->draw_alpha_blend(canvas,
+ &drawable->qxl_drawable->bbox, &clip, &alpha_blend);
unlocalize_bitmap(&alpha_blend.src_bitmap);
break;
}
case QXL_COPY_BITS: {
- worker->draw_funcs.copy_bits(worker->surface.context.canvas, &drawable->qxl_drawable->bbox,
- &clip, &drawable->qxl_drawable->u.copy_bits.src_pos);
+ canvas->ops->copy_bits(canvas, &drawable->qxl_drawable->bbox,
+ &clip, &drawable->qxl_drawable->u.copy_bits.src_pos);
break;
}
case QXL_DRAW_BLEND: {
SpiceBlend blend = drawable->qxl_drawable->u.blend;
localize_bitmap(worker, &blend.src_bitmap, drawable->group_id);
localize_mask(worker, &blend.mask, drawable->group_id);
- worker->draw_funcs.draw_blend(worker->surface.context.canvas, &drawable->qxl_drawable->bbox,
- &clip, &blend);
+ canvas->ops->draw_blend(canvas, &drawable->qxl_drawable->bbox,
+ &clip, &blend);
unlocalize_mask(&blend.mask);
unlocalize_bitmap(&blend.src_bitmap);
break;
@@ -4246,24 +4209,24 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
case QXL_DRAW_BLACKNESS: {
SpiceBlackness blackness = drawable->qxl_drawable->u.blackness;
localize_mask(worker, &blackness.mask, drawable->group_id);
- worker->draw_funcs.draw_blackness(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &blackness);
+ canvas->ops->draw_blackness(canvas,
+ &drawable->qxl_drawable->bbox, &clip, &blackness);
unlocalize_mask(&blackness.mask);
break;
}
case QXL_DRAW_WHITENESS: {
SpiceWhiteness whiteness = drawable->qxl_drawable->u.whiteness;
localize_mask(worker, &whiteness.mask, drawable->group_id);
- worker->draw_funcs.draw_whiteness(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &whiteness);
+ canvas->ops->draw_whiteness(canvas,
+ &drawable->qxl_drawable->bbox, &clip, &whiteness);
unlocalize_mask(&whiteness.mask);
break;
}
case QXL_DRAW_INVERS: {
SpiceInvers invers = drawable->qxl_drawable->u.invers;
localize_mask(worker, &invers.mask, drawable->group_id);
- worker->draw_funcs.draw_invers(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &invers);
+ canvas->ops->draw_invers(canvas,
+ &drawable->qxl_drawable->bbox, &clip, &invers);
unlocalize_mask(&invers.mask);
break;
}
@@ -4272,8 +4235,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
localize_brush(worker, &rop3.brush, drawable->group_id);
localize_bitmap(worker, &rop3.src_bitmap, drawable->group_id);
localize_mask(worker, &rop3.mask, drawable->group_id);
- worker->draw_funcs.draw_rop3(worker->surface.context.canvas, &drawable->qxl_drawable->bbox,
- &clip, &rop3); unlocalize_mask(&rop3.mask);
+ canvas->ops->draw_rop3(canvas, &drawable->qxl_drawable->bbox,
+ &clip, &rop3); unlocalize_mask(&rop3.mask);
unlocalize_bitmap(&rop3.src_bitmap);
unlocalize_brush(&rop3.brush);
break;
@@ -4283,8 +4246,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
localize_brush(worker, &stroke.brush, drawable->group_id);
localize_path(worker, &stroke.path, drawable->group_id);
localize_attr(worker, &stroke.attr, drawable->group_id);
- worker->draw_funcs.draw_stroke(worker->surface.context.canvas,
- &drawable->qxl_drawable->bbox, &clip, &stroke);
+ canvas->ops->draw_stroke(canvas,
+ &drawable->qxl_drawable->bbox, &clip, &stroke);
unlocalize_attr(&stroke.attr);
unlocalize_path(&stroke.path);
unlocalize_brush(&stroke.brush);
@@ -4295,8 +4258,8 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
localize_brush(worker, &text.fore_brush, drawable->group_id);
localize_brush(worker, &text.back_brush, drawable->group_id);
localize_str(worker, &text.str, drawable->group_id);
- worker->draw_funcs.draw_text(worker->surface.context.canvas, &drawable->qxl_drawable->bbox,
- &clip, &text);
+ canvas->ops->draw_text(canvas, &drawable->qxl_drawable->bbox,
+ &clip, &text);
unlocalize_str(&text.str);
unlocalize_brush(&text.back_brush);
unlocalize_brush(&text.fore_brush);
@@ -4313,16 +4276,36 @@ static void red_draw_qxl_drawable(RedWorker *worker, Drawable *drawable)
static void red_draw_drawable(RedWorker *worker, Drawable *drawable)
{
#ifdef UPDATE_AREA_BY_TREE
+ SpiceCanvas *canvas = worker->surface.context.canvas;
//todo: add need top mask flag
- worker->draw_funcs.set_top_mask(worker->surface.context.canvas,
- &drawable->tree_item.base.rgn);
+ canvas->ops->group_start(canvas,
+ &drawable->tree_item.base.rgn);
#endif
red_draw_qxl_drawable(worker, drawable);
#ifdef UPDATE_AREA_BY_TREE
- worker->draw_funcs.clear_top_mask(worker->surface.context.canvas);
+ canvas->ops->group_end(canvas);
#endif
}
+static void validate_area(RedWorker *worker, const SpiceRect *area)
+{
+ if (!worker->surface.context.canvas_draws_on_surface) {
+ SpiceCanvas *canvas = worker->surface.context.canvas;
+ int h;
+ int stride = worker->surface.context.stride;
+ uint8_t *line_0 = worker->surface.context.line_0;
+
+ if (!(h = area->bottom - area->top)) {
+ return;
+ }
+
+ ASSERT(stride < 0);
+ uint8_t *dest = line_0 + (area->top * stride) + area->left * sizeof(uint32_t);
+ dest += (h - 1) * stride;
+ canvas->ops->read_bits(canvas, dest, -stride, area);
+ }
+}
+
#ifdef UPDATE_AREA_BY_TREE
static inline void __red_collect_for_update(RedWorker *worker, Ring *ring, RingItem *ring_item,
@@ -4401,8 +4384,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area)
current_remove_drawable(worker, drawable);
container_cleanup(worker, container);
}
- worker->draw_funcs.validate_area(worker->surface.context.canvas, worker->surface.context.stride,
- worker->surface.context.line_0, area);
+ validate_area(worker, area);
}
#else
@@ -4427,9 +4409,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area)
region_destroy(&rgn);
if (!last) {
- worker->draw_funcs.validate_area(worker->surface.context.canvas,
- worker->surface.context.stride,
- worker->surface.context.line_0, area);
+ validate_area(worker, area);
return;
}
@@ -4443,8 +4423,7 @@ static void red_update_area(RedWorker *worker, const SpiceRect *area)
current_remove_drawable(worker, now);
container_cleanup(worker, container);
} while (now != last);
- worker->draw_funcs.validate_area(worker->surface.context.canvas, worker->surface.context.stride,
- worker->surface.context.line_0, area);
+ validate_area(worker, area);
}
#endif
@@ -4702,8 +4681,9 @@ static void red_add_screen_image(RedWorker *worker)
ImageItem *item;
int stride;
SpiceRect area;
+ SpiceCanvas *canvas = worker->surface.context.canvas;
- if (!worker->display_channel || !worker->surface.context.canvas) {
+ if (!worker->display_channel || !canvas) {
return;
}
@@ -4726,7 +4706,7 @@ static void red_add_screen_image(RedWorker *worker)
area.top = area.left = 0;
area.right = worker->surface.context.width;
area.bottom = worker->surface.context.height;
- worker->draw_funcs.read_pixels(worker->surface.context.canvas, item->data, stride, &area);
+ canvas->ops->read_bits(canvas, item->data, stride, &area);
red_pipe_add_image_item(worker, item);
release_image_item(item);
display_channel_push(worker);
@@ -7445,46 +7425,10 @@ static void red_migrate_display(RedWorker *worker)
}
}
-static void destroy_cairo_canvas(CairoCanvas *canvas)
-{
- if (!canvas) {
- return;
- }
-
- canvas_destroy(canvas);
-}
-
-static void validate_area_nop(void *canvas, int32_t stride, uint8_t *line_0, const SpiceRect *area)
-{
-}
-
-static void init_cairo_draw_funcs(RedWorker *worker)
-{
- worker->draw_funcs.draw_fill = (draw_fill_t)canvas_draw_fill;
- worker->draw_funcs.draw_copy = (draw_copy_t)canvas_draw_copy;
- worker->draw_funcs.draw_opaque = (draw_opaque_t)canvas_draw_opaque;
- worker->draw_funcs.copy_bits = (copy_bits_t)canvas_copy_bits;
- worker->draw_funcs.draw_text = (draw_text_t)canvas_draw_text;
- worker->draw_funcs.draw_stroke = (draw_stroke_t)canvas_draw_stroke;
- worker->draw_funcs.draw_rop3 = (draw_rop3_t)canvas_draw_rop3;
- worker->draw_funcs.draw_blend = (draw_blend_t)canvas_draw_blend;
- worker->draw_funcs.draw_blackness = (draw_blackness_t)canvas_draw_blackness;
- worker->draw_funcs.draw_whiteness = (draw_whiteness_t)canvas_draw_whiteness;
- worker->draw_funcs.draw_invers = (draw_invers_t)canvas_draw_invers;
- worker->draw_funcs.draw_transparent = (draw_transparent_t)canvas_draw_transparent;
- worker->draw_funcs.draw_alpha_blend = (draw_alpha_blend_t)canvas_draw_alpha_blend;
- worker->draw_funcs.read_pixels = (read_pixels_t)canvas_read_bits;
-
- worker->draw_funcs.set_top_mask = (set_top_mask_t)canvas_group_start;
- worker->draw_funcs.clear_top_mask = (clear_top_mask_t)canvas_group_end;
- worker->draw_funcs.validate_area = validate_area_nop;
- worker->draw_funcs.destroy = (destroy_t)destroy_cairo_canvas;
-}
-
-static CairoCanvas *create_cairo_context(RedWorker *worker, uint32_t width, uint32_t height,
+static SpiceCanvas *create_cairo_context(RedWorker *worker, uint32_t width, uint32_t height,
int32_t stride, uint8_t depth, void *line_0)
{
- CairoCanvas *canvas;
+ SpiceCanvas *canvas;
pixman_image_t *surface;
surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, height,
@@ -7499,78 +7443,29 @@ static CairoCanvas *create_cairo_context(RedWorker *worker, uint32_t width, uint
return canvas;
}
-static void destroy_gl_canvas(GLCanvas *canvas)
+static SpiceCanvas *create_ogl_context_common(RedWorker *worker, OGLCtx *ctx, uint32_t width,
+ uint32_t height, int32_t stride, uint8_t depth)
{
- OGLCtx *ctx;
-
- if (!canvas) {
- return;
- }
-
- ctx = gl_canvas_get_usr_data(canvas);
- ASSERT(ctx);
- gl_canvas_destroy(canvas, 0);
- oglctx_destroy(ctx);
-}
-
-static void gl_validate_area(GLCanvas *canvas, int32_t stride, uint8_t *line_0, const SpiceRect *area)
-{
- int h;
-
- if (!(h = area->bottom - area->top)) {
- return;
- }
-
- ASSERT(stride < 0);
- uint8_t *dest = line_0 + (area->top * stride) + area->left * sizeof(uint32_t);
- dest += (h - 1) * stride;
- gl_canvas_read_pixels(canvas, dest, -stride, area);
-}
-
-static void init_ogl_draw_funcs(RedWorker *worker)
-{
- worker->draw_funcs.draw_fill = (draw_fill_t)gl_canvas_draw_fill;
- worker->draw_funcs.draw_copy = (draw_copy_t)gl_canvas_draw_copy;
- worker->draw_funcs.draw_opaque = (draw_opaque_t)gl_canvas_draw_opaque;
- worker->draw_funcs.copy_bits = (copy_bits_t)gl_canvas_copy_pixels;
- worker->draw_funcs.draw_text = (draw_text_t)gl_canvas_draw_text;
- worker->draw_funcs.draw_stroke = (draw_stroke_t)gl_canvas_draw_stroke;
- worker->draw_funcs.draw_rop3 = (draw_rop3_t)gl_canvas_draw_rop3;
- worker->draw_funcs.draw_blend = (draw_blend_t)gl_canvas_draw_blend;
- worker->draw_funcs.draw_blackness = (draw_blackness_t)gl_canvas_draw_blackness;
- worker->draw_funcs.draw_whiteness = (draw_whiteness_t)gl_canvas_draw_whiteness;
- worker->draw_funcs.draw_invers = (draw_invers_t)gl_canvas_draw_invers;
- worker->draw_funcs.draw_transparent = (draw_transparent_t)gl_canvas_draw_transparent;
- worker->draw_funcs.draw_alpha_blend = (draw_alpha_blend_t)gl_canvas_draw_alpha_blend;
- worker->draw_funcs.read_pixels = (read_pixels_t)gl_canvas_read_pixels;
-
- worker->draw_funcs.set_top_mask = (set_top_mask_t)gl_canvas_set_top_mask;
- worker->draw_funcs.clear_top_mask = (clear_top_mask_t)gl_canvas_clear_top_mask;
- worker->draw_funcs.validate_area = (validate_area_t)gl_validate_area;
- worker->draw_funcs.destroy = (destroy_t)destroy_gl_canvas;
-}
-
-static GLCanvas *create_ogl_context_common(RedWorker *worker, OGLCtx *ctx, uint32_t width,
- uint32_t height, int32_t stride, uint8_t depth)
-{
- GLCanvas *canvas;
+ SpiceCanvas *canvas;
oglctx_make_current(ctx);
- if (!(canvas = gl_canvas_create(ctx, width, height, depth, &worker->image_cache.base, NULL,
+ if (!(canvas = gl_canvas_create(width, height, depth, &worker->image_cache.base, NULL,
&worker->preload_group_virt_mapping))) {
return NULL;
}
- gl_canvas_clear(canvas);
+ spice_canvas_set_usr_data(canvas, ctx, (spice_destroy_fn_t)oglctx_destroy);
+
+ canvas->ops->clear(canvas);
return canvas;
}
-static GLCanvas *create_ogl_pbuf_context(RedWorker *worker, uint32_t width, uint32_t height,
+static SpiceCanvas *create_ogl_pbuf_context(RedWorker *worker, uint32_t width, uint32_t height,
int32_t stride, uint8_t depth)
{
OGLCtx *ctx;
- GLCanvas *canvas;
+ SpiceCanvas *canvas;
if (!(ctx = pbuf_create(width, height))) {
return NULL;
@@ -7584,10 +7479,10 @@ static GLCanvas *create_ogl_pbuf_context(RedWorker *worker, uint32_t width, uint
return canvas;
}
-static GLCanvas *create_ogl_pixmap_context(RedWorker *worker, uint32_t width, uint32_t height,
- int32_t stride, uint8_t depth) {
+static SpiceCanvas *create_ogl_pixmap_context(RedWorker *worker, uint32_t width, uint32_t height,
+ int32_t stride, uint8_t depth) {
OGLCtx *ctx;
- GLCanvas *canvas;
+ SpiceCanvas *canvas;
if (!(ctx = pixmap_create(width, height))) {
return NULL;
@@ -7601,36 +7496,17 @@ static GLCanvas *create_ogl_pixmap_context(RedWorker *worker, uint32_t width, ui
return canvas;
}
-static inline void surface_init_draw_funcs(RedWorker *worker, uint32_t renderer)
-{
- switch (renderer) {
- case RED_RENDERER_CAIRO:
- init_cairo_draw_funcs(worker);
- red_printf("using cairo canvas");
- return;
- case RED_RENDERER_OGL_PBUF:
- init_ogl_draw_funcs(worker);
- red_printf("using opengl pbuff canvas");
- return;
- case RED_RENDERER_OGL_PIXMAP:
- init_ogl_draw_funcs(worker);
- red_printf("using opengl pixmap canvas");
- return;
- default:
- red_error("invalid renderer type");
- };
-}
-
static inline void *create_canvas_for_surface(RedWorker *worker, Surface *surface,
uint32_t renderer, uint32_t width, uint32_t height,
int32_t stride, uint8_t depth, void *line_0)
{
- void *canvas;
+ SpiceCanvas *canvas;
switch (renderer) {
case RED_RENDERER_CAIRO:
canvas = create_cairo_context(worker, width, height, stride, depth, line_0);
surface->context.top_down = TRUE;
+ surface->context.canvas_draws_on_surface = TRUE;
return canvas;
case RED_RENDERER_OGL_PBUF:
canvas = create_ogl_pbuf_context(worker, width, height, stride, depth);
@@ -7656,6 +7532,7 @@ static inline void red_create_surface(RedWorker *worker, uint32_t width, uint32_
}
PANIC_ON(surface->context.canvas);
+ surface->context.canvas_draws_on_surface = FALSE;
surface->context.width = width;
surface->context.height = height;
surface->context.depth = depth;
@@ -7679,7 +7556,6 @@ static inline void red_create_surface(RedWorker *worker, uint32_t width, uint32_
surface->context.depth, line_0);
if (surface->context.canvas) {
worker->renderer = worker->renderers[i];
- surface_init_draw_funcs(worker, worker->renderers[i]);
return;
}
}