From c1b79eb035fa158fb2ac3bc8e559809611070016 Mon Sep 17 00:00:00 2001 From: Yaniv Kamay Date: Sat, 19 Sep 2009 21:25:46 +0300 Subject: fresh start --- client/canvas.h | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 client/canvas.h (limited to 'client/canvas.h') diff --git a/client/canvas.h b/client/canvas.h new file mode 100644 index 00000000..55415e31 --- /dev/null +++ b/client/canvas.h @@ -0,0 +1,265 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _H_CANVAS +#define _H_CANVAS + +#include "common.h" +#include "debug.h" +#include "cairo.h" +#include "red.h" +#include "cache.hpp" +#include "shared_cache.hpp" +#include "canvas_utils.h" +#include "glz_decoded_image.h" +#include "glz_decoder.h" + +enum CanvasType { + CANVAS_TYPE_INVALID, + CANVAS_TYPE_CAIRO, + CANVAS_TYPE_GL, + CANVAS_TYPE_GDI, +}; + +struct QRegion; + +class PixmapCacheTreat { +public: + static inline cairo_surface_t *get(cairo_surface_t *surf) + { + return cairo_surface_reference(surf); + } + + static inline void release(cairo_surface_t *surf) + { + cairo_surface_destroy(surf); + } + + static const char* name() { return "pixmap";} +}; + +typedef SharedCache PixmapCache; + +class CachedPalette { +public: + CachedPalette(Palette* palette) + : _refs(1) + { + int size = sizeof(Palette) + palette->num_ents * sizeof(uint32_t); + CachedPalette **ptr = (CachedPalette **)new uint8_t[size + sizeof(CachedPalette *)]; + *ptr = this; + _palette = (Palette*)(ptr + 1); + memcpy(_palette, palette, size); + } + + CachedPalette* ref() + { + _refs++; + return this; + } + + void unref() + { + if (--_refs == 0) { + delete this; + } + } + + static void unref(Palette *pal) + { + CachedPalette **ptr = (CachedPalette **)pal; + (*(ptr - 1))->unref(); + } + + Palette* palette() { return _palette;} + +private: + ~CachedPalette() + { + delete[] (uint8_t *)((CachedPalette **)_palette - 1); + } + +private: + int _refs; + Palette* _palette; +}; + +class PaletteCacheTreat { +public: + static inline CachedPalette* get(CachedPalette* palette) + { + return palette->ref(); + } + + static inline void release(CachedPalette* palette) + { + palette->unref(); + } + + static const char* name() { return "palette";} +}; + +typedef Cache PaletteCache; + +/* Lz decoder related classes */ + +class GlzDecodedSurface: public GlzDecodedImage { +public: + GlzDecodedSurface(uint64_t id, uint64_t win_head_id, uint8_t *data, int size, + int bytes_per_pixel, cairo_surface_t *surface) + : GlzDecodedImage(id, win_head_id, data, size, bytes_per_pixel) + , _surface (surface) + { + cairo_surface_reference(_surface); + } + + virtual ~GlzDecodedSurface() + { + cairo_surface_destroy(_surface); + } + +private: + cairo_surface_t *_surface; +}; + +class GlzDecodeSurfaceHandler: public GlzDecodeHandler { +public: + virtual GlzDecodedImage *alloc_image(void *opaque_usr_info, uint64_t image_id, + uint64_t image_win_head_id, LzImageType type, + int width, int height, int gross_pixels, + int n_bytes_per_pixel, bool top_down) + { + cairo_surface_t *surface = alloc_lz_image_surface((LzDecodeUsrData *)opaque_usr_info, + type, width, height, gross_pixels, + top_down); + uint8_t *data = cairo_image_surface_get_data(surface); + if (!top_down) { + data = data - (gross_pixels / height) * n_bytes_per_pixel * (height - 1); + } + + return (new GlzDecodedSurface(image_id, image_win_head_id, data, + gross_pixels, n_bytes_per_pixel, surface)); + } +}; + +/* TODO: unite with the window debug callbacks? */ +class GlzDecoderCanvasDebug: public GlzDecoderDebug { +public: + virtual void error(const std::string& str) + { + throw Exception(str); + } + + virtual void warn(const std::string& str) + { + LOG_WARN("%s", str.c_str()); + } + + virtual void info(const std::string& str) + { + LOG_INFO("%s", str.c_str()); + } +}; + +class Canvas { +public: + Canvas(PixmapCache& bits_cache, PaletteCache& palette_cache, + GlzDecoderWindow &glz_decoder_window); + virtual ~Canvas(); + + virtual void copy_pixels(const QRegion& region, RedDrawable* dc, + const PixmapHeader* pixmap) = 0; + virtual void copy_pixels(const QRegion& region, RedDrawable& dc) = 0; + virtual void thread_touch() = 0; + + virtual void clear() = 0; + + void draw_fill(RedFill& fill, int size); + void draw_text(RedText& text, int size); + void draw_opaque(RedOpaque& opaque, int size); + void draw_copy(RedCopy& copy, int size); + void draw_transparent(RedTransparent& transparent, int size); + void draw_alpha_blend(RedAlphaBlend& alpha_blend, int size); + void copy_bits(RedCopyBits& copy_bits, int size); + void draw_blend(RedBlend& blend, int size); + void draw_blackness(RedBlackness& blackness, int size); + void draw_whiteness(RedWhiteness& whiteness, int size); + void draw_invers(RedInvers& invers, int size); + void draw_rop3(RedRop3& rop3, int size); + void draw_stroke(RedStroke& stroke, int size); + +#ifdef WIN32 + virtual void put_image(HDC dc, const PixmapHeader& image, + const Rect& dest, const QRegion* clip) = 0; +#else + virtual void put_image(const PixmapHeader& image, const Rect& dest, + const QRegion* clip) = 0; +#endif + + virtual CanvasType get_pixmap_type() { return CANVAS_TYPE_INVALID; } + +protected: + virtual void set_access_params(ADDRESS delta, unsigned long base, unsigned long max) = 0; + virtual void draw_fill(Rect *bbox, Clip *clip, Fill *fill) = 0; + virtual void draw_copy(Rect *bbox, Clip *clip, Copy *copy) = 0; + virtual void draw_opaque(Rect *bbox, Clip *clip, Opaque *opaque) = 0; + virtual void copy_bits(Rect *bbox, Clip *clip, Point *src_pos) = 0; + virtual void draw_text(Rect *bbox, Clip *clip, Text *text) = 0; + virtual void draw_stroke(Rect *bbox, Clip *clip, Stroke *stroke) = 0; + virtual void draw_rop3(Rect *bbox, Clip *clip, Rop3 *rop3) = 0; + virtual void draw_blend(Rect *bbox, Clip *clip, Blend *blend) = 0; + virtual void draw_blackness(Rect *bbox, Clip *clip, Blackness *blackness) = 0; + virtual void draw_whiteness(Rect *bbox, Clip *clip, Whiteness *whiteness) = 0; + virtual void draw_invers(Rect *bbox, Clip *clip, Invers *invers) = 0; + virtual void draw_transparent(Rect *bbox, Clip *clip, Transparent* transparent) = 0; + virtual void draw_alpha_blend(Rect *bbox, Clip *clip, AlphaBlnd* alpha_blend) = 0; + + PixmapCache& pixmap_cache() { return _pixmap_cache;} + PaletteCache& palette_cache() { return _palette_cache;} + static void bits_cache_put(void *opaque, uint64_t id, cairo_surface_t *surface); + static cairo_surface_t* bits_cache_get(void *opaque, uint64_t id); + static void palette_cache_put(void *opaque, Palette *palette); + static Palette* palette_cache_get(void *opaque, uint64_t id); + static void palette_cache_release(Palette* palette); + + GlzDecoder& glz_decoder() {return _glz_decoder;} + static void glz_decode(void *opaque, uint8_t *data, Palette *plt, void *usr_data); + +private: + void access_test(void* ptr, size_t size); + void localalize_ptr(ADDRESS* data); + void localalize_image(ADDRESS* in_bitmap); + void localalize_brush(Brush& brush); + void localalize_attr(LineAttr& attr); + void localalize_mask(QMask& mask); + void begin_draw(RedDrawBase& base, int size, size_t min_size); + +private: + PixmapCache& _pixmap_cache; + PaletteCache& _palette_cache; + + GlzDecodeSurfaceHandler _glz_handler; + GlzDecoderCanvasDebug _glz_debug; + GlzDecoder _glz_decoder; + + unsigned long _base; + unsigned long _max; +}; + + +#endif + -- cgit