diff options
-rw-r--r-- | client/canvas.cpp | 68 | ||||
-rw-r--r-- | client/canvas.h | 29 | ||||
-rw-r--r-- | client/red_cairo_canvas.cpp | 96 | ||||
-rw-r--r-- | client/red_cairo_canvas.h | 25 | ||||
-rw-r--r-- | client/red_gdi_canvas.cpp | 84 | ||||
-rw-r--r-- | client/red_gdi_canvas.h | 20 | ||||
-rw-r--r-- | client/red_gl_canvas.cpp | 101 | ||||
-rw-r--r-- | client/red_gl_canvas.h | 20 | ||||
-rw-r--r-- | common/cairo_canvas.c | 127 | ||||
-rw-r--r-- | common/cairo_canvas.h | 45 | ||||
-rw-r--r-- | common/canvas_base.c | 67 | ||||
-rw-r--r-- | common/canvas_base.h | 39 | ||||
-rw-r--r-- | common/gdi_canvas.c | 107 | ||||
-rw-r--r-- | common/gdi_canvas.h | 36 | ||||
-rw-r--r-- | common/gl_canvas.c | 136 | ||||
-rw-r--r-- | common/gl_canvas.h | 47 | ||||
-rw-r--r-- | server/red_worker.c | 284 |
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(©.data.src_bitmap); localalize_mask(copy.data.mask); - draw_copy(©.base.box, ©.base.clip, ©.data); + _canvas->ops->draw_copy(_canvas, ©.base.box, ©.base.clip, ©.data); + touched_bbox(©.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(©.base.box, ©.base.clip, ©.src_pos); + _canvas->ops->copy_bits(_canvas, ©.base.box, ©.base.clip, ©.src_pos); + touched_bbox(©.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, ©.src_bitmap, drawable->group_id); localize_mask(worker, ©.mask, drawable->group_id); - worker->draw_funcs.draw_copy(worker->surface.context.canvas, &drawable->qxl_drawable->bbox, - &clip, ©); + canvas->ops->draw_copy(canvas, &drawable->qxl_drawable->bbox, + &clip, ©); unlocalize_mask(©.mask); unlocalize_bitmap(©.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; } } |