summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/cursor_channel.cpp10
-rw-r--r--client/display_channel.cpp29
-rw-r--r--client/display_channel.h6
-rw-r--r--client/gui/gui.cpp3
-rw-r--r--client/red_cairo_canvas.cpp75
-rw-r--r--client/red_cairo_canvas.h10
-rw-r--r--client/red_gdi_canvas.cpp44
-rw-r--r--client/red_gdi_canvas.h9
-rw-r--r--client/red_gl_canvas.cpp55
-rw-r--r--client/red_gl_canvas.h7
-rw-r--r--client/red_pixmap.h49
-rw-r--r--client/red_pixmap_cairo.h3
-rw-r--r--client/red_pixmap_gdi.h3
-rw-r--r--client/red_pixmap_gl.h2
-rw-r--r--client/screen.cpp2
-rw-r--r--client/windows/red_pixmap.cpp4
-rw-r--r--client/windows/red_pixmap_cairo.cpp24
-rw-r--r--client/windows/red_pixmap_gdi.cpp21
-rw-r--r--client/x11/red_pixmap.cpp4
-rw-r--r--client/x11/red_pixmap_cairo.cpp26
-rw-r--r--client/x11/red_pixmap_gl.cpp4
-rw-r--r--common/cairo_canvas.c76
-rw-r--r--common/cairo_canvas.h17
-rw-r--r--common/canvas_base.c8
-rw-r--r--common/canvas_utils.c9
-rw-r--r--common/gdi_canvas.c4
-rw-r--r--common/gdi_canvas.h2
-rw-r--r--common/gl_canvas.c4
-rw-r--r--common/gl_canvas.h2
-rw-r--r--server/red_worker.c33
30 files changed, 296 insertions, 249 deletions
diff --git a/client/cursor_channel.cpp b/client/cursor_channel.cpp
index 0dd9dcb6..289c059f 100644
--- a/client/cursor_channel.cpp
+++ b/client/cursor_channel.cpp
@@ -112,7 +112,7 @@ void UnsupportedCursor::draw(RedDrawable& dest, int x, int y, const SpiceRect& a
AlphaCursor::AlphaCursor(const SpiceCursorHeader& header, const uint8_t* data)
: _pixmap (new RedPixmapCairo(header.width, header.height,
- RedPixmap::ARGB32, true, NULL, NULL))
+ RedPixmap::ARGB32, true, NULL))
{
int stride = _pixmap->get_stride();
uint8_t* dest = _pixmap->get_data();
@@ -131,9 +131,8 @@ MonoCursor::MonoCursor(const SpiceCursorHeader& header, const uint8_t* data)
: _pixmap (NULL)
, _height (header.height)
{
- rgb32_t pallete[2] = { rgb32_make(0x00, 0x00, 0x00), rgb32_make(0xff, 0xff, 0xff)};
_pixmap.reset(new RedPixmapCairo(header.width, _height * 2, RedPixmap::A1,
- true, pallete, NULL));
+ true, NULL));
int dest_stride = _pixmap->get_stride();
uint8_t *dest_line = _pixmap->get_data();
@@ -177,12 +176,11 @@ private:
ColorCursor::ColorCursor(const SpiceCursorHeader& header)
: _pixmap (new RedPixmapCairo(header.width, header.height,
- RedPixmap::ARGB32, true, NULL, NULL))
+ RedPixmap::ARGB32, true, NULL))
, _invers (NULL)
{
- rgb32_t pallete[2] = { rgb32_make(0x00, 0x00, 0x00), rgb32_make(0xff, 0xff, 0xff)};
_invers.reset(new RedPixmapCairo(header.width, header.height, RedPixmap::A1,
- true, pallete, NULL));
+ true, NULL));
}
void ColorCursor::init_pixels(const SpiceCursorHeader& header, const uint8_t* pixels,
diff --git a/client/display_channel.cpp b/client/display_channel.cpp
index 719e7dfd..acbf5da7 100644
--- a/client/display_channel.cpp
+++ b/client/display_channel.cpp
@@ -1079,12 +1079,13 @@ void DisplayChannel::on_disconnect()
(*sync_event)->wait();
}
-bool DisplayChannel::create_cairo_canvas(int surface_id, int width, int height, int depth)
+bool DisplayChannel::create_cairo_canvas(int surface_id, int width, int height, uint32_t format)
{
try {
- CCanvas *canvas = new CCanvas(_pixmap_cache, _palette_cache, _glz_window,
+ CCanvas *canvas = new CCanvas(surface_id == 0, width, height, format,
+ screen()->get_window(),
+ _pixmap_cache, _palette_cache, _glz_window,
surfaces_mngr.get_surfaces());
- canvas->set_mode(width, height, depth, screen()->get_window());
surfaces_mngr.add_canvas(surface_id, canvas);
surfaces_mngr.add_surface(surface_id, canvas->get_internal_canvas());
if (surface_id == 0) {
@@ -1097,21 +1098,19 @@ bool DisplayChannel::create_cairo_canvas(int surface_id, int width, int height,
}
#ifdef USE_OGL
-bool DisplayChannel::create_ogl_canvas(int surface_id, int width, int height, int depth,
+bool DisplayChannel::create_ogl_canvas(int surface_id, int width, int height, uint32_t format,
bool recreate, RenderType rendertype)
{
try {
RedWindow *win;
- GCanvas *canvas = new GCanvas(_pixmap_cache,
+ win = screen()->get_window();
+ GCanvas *canvas = new GCanvas(width, height, format, win, rendertype,
+ _pixmap_cache,
_palette_cache,
_glz_window,
surfaces_mngr.get_surfaces());
- win = screen()->get_window();
-
- canvas->set_mode(width, height, depth, win, rendertype);
-
screen()->untouch_context();
surfaces_mngr.add_canvas(surface_id, canvas);
@@ -1129,12 +1128,12 @@ bool DisplayChannel::create_ogl_canvas(int surface_id, int width, int height, in
#endif
#ifdef WIN32
-bool DisplayChannel::create_gdi_canvas(int surface_id, int width, int height, int depth)
+bool DisplayChannel::create_gdi_canvas(int surface_id, int width, int height, uint32_t format)
{
try {
- GDICanvas *canvas = new GDICanvas(_pixmap_cache, _palette_cache, _glz_window,
+ GDICanvas *canvas = new GDICanvas(width, height, format,
+ _pixmap_cache, _palette_cache, _glz_window,
surfaces_mngr.get_surfaces());
- canvas->set_mode(width, height, depth);
surfaces_mngr.add_canvas(surface_id, canvas);
surfaces_mngr.add_surface(surface_id, canvas->get_internal_canvas());
if (surface_id == 0) {
@@ -1155,7 +1154,7 @@ void DisplayChannel::destroy_canvas(int surface_id)
if (!surfaces_mngr.is_present_canvas(surface_id)) {
return;
}
-
+
canvas = surfaces_mngr.get_canvas(surface_id);
#ifdef USE_OGL
@@ -1171,7 +1170,7 @@ void DisplayChannel::destroy_canvas(int surface_id)
}
void DisplayChannel::create_canvas(int surface_id, const std::vector<int>& canvas_types, int width,
- int height, int depth)
+ int height, uint32_t format)
{
#ifdef USE_OGL
bool recreate = true;
@@ -1417,7 +1416,7 @@ void DisplayChannel::handle_stream_destroy_all(RedPeer::InMessage* message)
destroy_strams();
}
-void DisplayChannel::create_primary_surface(int width, int height, int depth)
+void DisplayChannel::create_primary_surface(int width, int height, uint32_t format)
{
Canvas *canvas;
_mark = false;
diff --git a/client/display_channel.h b/client/display_channel.h
index 2bb697c5..a5761b35 100644
--- a/client/display_channel.h
+++ b/client/display_channel.h
@@ -133,13 +133,13 @@ protected:
private:
void set_draw_handlers();
void clear_draw_handlers();
- bool create_cairo_canvas(int surface_id, int width, int height, int depth);
+ bool create_cairo_canvas(int surface_id, int width, int height, uint32_t format);
#ifdef USE_OGL
- bool create_ogl_canvas(int surface_id, int width, int height, int depth, bool recreate,
+ bool create_ogl_canvas(int surface_id, int width, int height, uint32_t format, bool recreate,
RenderType rendertype);
#endif
#ifdef WIN32
- bool create_gdi_canvas(int surface_id, int width, int height, int depth);
+ bool create_gdi_canvas(int surface_id, int width, int height, uint32_t format);
#endif
void destroy_canvas(int surface_id);
void create_canvas(int surface_id, const std::vector<int>& canvas_type, int width, int height,
diff --git a/client/gui/gui.cpp b/client/gui/gui.cpp
index 0ff442e5..6debdd1b 100644
--- a/client/gui/gui.cpp
+++ b/client/gui/gui.cpp
@@ -888,8 +888,7 @@ GUI::GUI(Application& app, Application::State state)
: ScreenLayer (SCREEN_LAYER_GUI, false)
, _app (app)
, _state (state)
- , _pixmap (new RedPixmapCairo(MAIN_GUI_WIDTH, MAIN_GUI_HEIGHT, RedPixmap::RGB32, true, NULL,
- NULL))
+ , _pixmap (new RedPixmapCairo(MAIN_GUI_WIDTH, MAIN_GUI_HEIGHT, RedPixmap::RGB32, true, NULL))
, _renderer (new CEGUI::SoftRenderer(_pixmap->get_data(), MAIN_GUI_WIDTH, MAIN_GUI_HEIGHT,
_pixmap->get_stride()))
, _gui_system (new CEGUI::System(_renderer, new CEGUIResourceProvider()))
diff --git a/client/red_cairo_canvas.cpp b/client/red_cairo_canvas.cpp
index 96f76375..9338d9ff 100644
--- a/client/red_cairo_canvas.cpp
+++ b/client/red_cairo_canvas.cpp
@@ -25,36 +25,44 @@
#include "region.h"
#include "red_pixmap_cairo.h"
-CCanvas::CCanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
+CCanvas::CCanvas(bool onscreen,
+ int width, int height, uint32_t format, RedWindow *win,
+ PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window, CSurfaces& csurfaces)
: Canvas (pixmap_cache, palette_cache, glz_decoder_window, csurfaces)
, _pixmap (0)
{
+ if (onscreen) {
+ _pixmap = new RedPixmapCairo(width, height,
+ RedPixmap::format_from_surface(format),
+ true, win);
+ _canvas = canvas_create_for_data(width, height, format,
+ _pixmap->get_data(),
+ _pixmap->get_stride(),
+ &pixmap_cache.base,
+ &palette_cache.base,
+ &csurfaces.base,
+ &glz_decoder());
+ } else {
+ _canvas = canvas_create(width, height, format,
+ &pixmap_cache.base,
+ &palette_cache.base,
+ &csurfaces.base,
+ &glz_decoder());
+ }
+ if (_canvas == NULL) {
+ THROW("create canvas failed");
+ }
}
CCanvas::~CCanvas()
{
- destroy();
-}
-
-void CCanvas::destroy()
-{
- if (_canvas) {
- _canvas->ops->destroy(_canvas);
- _canvas = NULL;
+ _canvas->ops->destroy(_canvas);
+ _canvas = NULL;
+ if (_pixmap) {
+ delete _pixmap;
+ _pixmap = NULL;
}
- destroy_pixmap();
-}
-
-void CCanvas::destroy_pixmap()
-{
- delete _pixmap;
- _pixmap = NULL;
-}
-
-void CCanvas::create_pixmap(int width, int height, RedWindow *win)
-{
- _pixmap = new RedPixmapCairo(width, height, RedPixmap::RGB32, true, NULL, win);
}
void CCanvas::copy_pixels(const QRegion& region, RedDrawable& dest_dc)
@@ -62,6 +70,8 @@ void CCanvas::copy_pixels(const QRegion& region, RedDrawable& dest_dc)
pixman_box32_t *rects;
int num_rects;
+ ASSERT(_pixmap != NULL);
+
rects = pixman_region32_rectangles((pixman_region32_t *)&region, &num_rects);
for (int i = 0; i < num_rects; i++) {
SpiceRect r;
@@ -79,29 +89,6 @@ void CCanvas::copy_pixels(const QRegion& region, RedDrawable* dest_dc, const Pix
copy_pixels(region, *dest_dc);
}
-void CCanvas::set_mode(int width, int height, int depth, RedWindow *win)
-{
- pixman_image_t *surface;
-
- destroy();
- create_pixmap(width, height, win);
- surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, height,
- (uint32_t *)_pixmap->get_data(),
- _pixmap->get_stride());
- if (surface == NULL) {
- THROW("create surface failed, out of memory");
- }
-
- if (!(_canvas = canvas_create(surface, depth,
- &pixmap_cache().base,
- &palette_cache().base,
- &csurfaces().base,
- &glz_decoder()))) {
- THROW("create canvas failed");
- }
- pixman_image_unref (surface);
-}
-
CanvasType CCanvas::get_pixmap_type()
{
return CANVAS_TYPE_CAIRO;
diff --git a/client/red_cairo_canvas.h b/client/red_cairo_canvas.h
index 8d039bfb..9f4911bb 100644
--- a/client/red_cairo_canvas.h
+++ b/client/red_cairo_canvas.h
@@ -26,11 +26,12 @@ class RedPixmap;
class CCanvas: public Canvas {
public:
- CCanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
+ CCanvas(bool onscreen,
+ int width, int height, uint32_t format, RedWindow *win,
+ PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window, CSurfaces &csurfaces);
virtual ~CCanvas();
- virtual void set_mode(int x, int y, int bits, RedWindow *win);
virtual void thread_touch() {}
virtual void copy_pixels(const QRegion& region, RedDrawable* dc,
const PixmapHeader* pixmap);
@@ -39,11 +40,6 @@ public:
virtual CanvasType get_pixmap_type();
private:
- void create_pixmap(int width, int height, RedWindow *win);
- void destroy_pixmap();
- void destroy();
-
-private:
RedPixmap *_pixmap;
unsigned long _base;
unsigned long _max;
diff --git a/client/red_gdi_canvas.cpp b/client/red_gdi_canvas.cpp
index be7992c1..ae73ea2c 100644
--- a/client/red_gdi_canvas.cpp
+++ b/client/red_gdi_canvas.cpp
@@ -23,38 +23,33 @@
#include "region.h"
#include "red_pixmap_gdi.h"
-GDICanvas::GDICanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
+GDICanvas::GDICanvas(int width, int height, uint32_t format,
+ PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window, CSurfaces &csurfaces)
: Canvas (pixmap_cache, palette_cache, glz_decoder_window, csurfaces)
, _pixmap (0)
{
-}
-
-GDICanvas::~GDICanvas()
-{
- destroy();
-}
-
-void GDICanvas::destroy()
-{
- if (_canvas) {
- _canvas->ops->destroy(_canvas);
- _canvas = NULL;
+ _pixmap = new RedPixmapGdi(width, height,
+ RedPixmap::format_from_surface(format),
+ true, NULL);
+ if (!(_canvas = gdi_canvas_create(width, height, _pixmap->get_dc(),
+ &_pixmap->get_mutex(),
+ depth, &pixmap_cache().base,
+ &palette_cache().base,
+ &csurfaces().base,
+ &glz_decoder()))) {
+ THROW("create canvas failed");
}
- destroy_pixmap();
}
-void GDICanvas::destroy_pixmap()
+GDICanvas::~GDICanvas()
{
+ _canvas->ops->destroy(_canvas);
+ _canvas = NULL;
delete _pixmap;
_pixmap = NULL;
}
-void GDICanvas::create_pixmap(int width, int height)
-{
- _pixmap = new RedPixmapGdi(width, height, RedPixmap::RGB32, true, NULL);
-}
-
void GDICanvas::copy_pixels(const QRegion& region, RedDrawable& dest_dc)
{
pixman_box32_t *rects;
@@ -80,15 +75,6 @@ void GDICanvas::copy_pixels(const QRegion& region, RedDrawable* dest_dc, const P
void GDICanvas::set_mode(int width, int height, int depth)
{
destroy();
- create_pixmap(width, height);
- if (!(_canvas = gdi_canvas_create(width, height, _pixmap->get_dc(),
- &_pixmap->get_mutex(),
- depth, &pixmap_cache().base,
- &palette_cache().base,
- &csurfaces().base,
- &glz_decoder()))) {
- THROW("create canvas failed");
- }
}
CanvasType GDICanvas::get_pixmap_type()
diff --git a/client/red_gdi_canvas.h b/client/red_gdi_canvas.h
index d117282b..643f3c6c 100644
--- a/client/red_gdi_canvas.h
+++ b/client/red_gdi_canvas.h
@@ -27,11 +27,11 @@ class RedPixmap;
class GDICanvas: public Canvas {
public:
- GDICanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
+ GDICanvas(int width, int height, uint32_t format,
+ PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window, CSurfaces &csurfaces);
virtual ~GDICanvas();
- virtual void set_mode(int x, int y, int bits);
virtual void thread_touch() {}
virtual void copy_pixels(const QRegion& region, RedDrawable* dc,
const PixmapHeader* pixmap);
@@ -40,11 +40,6 @@ public:
virtual CanvasType get_pixmap_type();
private:
- void create_pixmap(int width, int height);
- void destroy_pixmap();
- void destroy();
-
-private:
RedPixmapGdi *_pixmap;
RedPixmapGdi *_helper_pixmap;
HDC _dc;
diff --git a/client/red_gl_canvas.cpp b/client/red_gl_canvas.cpp
index 2d285a50..dc743cfb 100644
--- a/client/red_gl_canvas.cpp
+++ b/client/red_gl_canvas.cpp
@@ -24,42 +24,36 @@
#include "red_pixmap_gl.h"
#include <GL/glx.h>
-GCanvas::GCanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
+GCanvas::GCanvas(int width, int height, uint32_t format, RedWindow *win,
+ RenderType rendertype,
+ PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window, CSurfaces &csurfaces)
: Canvas(pixmap_cache, palette_cache, glz_decoder_window, csurfaces)
, _pixmap (0)
, _textures_lost (false)
{
-}
-
-GCanvas::~GCanvas()
-{
- destroy();
-}
-
-void GCanvas::destroy()
-{
- if (_canvas) {
- gl_canvas_set_textures_lost (_canvas, (int)_textures_lost);
- _canvas->ops->destroy(_canvas);
- _canvas = NULL;
+ _pixmap = new RedPixmapGL(width, height,
+ RedPixmap::format_from_surface(format),
+ true, win, rendertype);
+ if (!(_canvas = gl_canvas_create(width, height,
+ SPICE_SURFACE_FMT_DEPTH(format),
+ &pixmap_cache.base,
+ &palette_cache.base,
+ &csurfaces.base,
+ &glz_decoder()))) {
+ THROW("create canvas failed");
}
- destroy_pixmap();
}
-void GCanvas::destroy_pixmap()
+GCanvas::~GCanvas()
{
+ gl_canvas_set_textures_lost (_canvas, (int)_textures_lost);
+ _canvas->ops->destroy(_canvas);
+ _canvas = NULL;
delete _pixmap;
_pixmap = NULL;
}
-void GCanvas::create_pixmap(int width, int height, RedWindow *win,
- RenderType rendertype)
-{
- _pixmap = new RedPixmapGL(width, height, RedPixmap::RGB32, true, NULL,
- win, rendertype);
-}
-
void GCanvas::copy_pixels(const QRegion& region, RedDrawable& dest_dc)
{
pixman_box32_t *rects;
@@ -83,21 +77,6 @@ void GCanvas::copy_pixels(const QRegion& region, RedDrawable* dest_dc, const Pix
copy_pixels(region, *dest_dc);
}
-void GCanvas::set_mode(int width, int height, int depth, RedWindow *win,
- RenderType rendertype)
-{
- destroy();
-
- create_pixmap(width, height, win, rendertype);
- if (!(_canvas = gl_canvas_create(width, height, depth,
- &pixmap_cache().base,
- &palette_cache().base,
- &csurfaces().base,
- &glz_decoder()))) {
- THROW("create canvas failed");
- }
-}
-
void GCanvas::touched_bbox(const SpiceRect *bbox)
{
_pixmap->update_texture(bbox);
diff --git a/client/red_gl_canvas.h b/client/red_gl_canvas.h
index 22491c49..dfe53d61 100644
--- a/client/red_gl_canvas.h
+++ b/client/red_gl_canvas.h
@@ -28,12 +28,13 @@ class RedPixmapGL;
class GCanvas: public Canvas {
public:
- GCanvas(PixmapCache& pixmap_cache, PaletteCache& palette_cache,
+ GCanvas(int width, int height, uint32_t format, RedWindow *win,
+ RenderType rendertype,
+ PixmapCache& pixmap_cache, PaletteCache& palette_cache,
GlzDecoderWindow &glz_decoder_window, CSurfaces &csurfaces);
virtual ~GCanvas();
- void set_mode(int width, int height, int depth, RedWindow *win,
- RenderType rendertype);
+ void set_mode();
void clear();
void thread_touch() {}
void copy_pixels(const QRegion& region, RedDrawable* dc,
diff --git a/client/red_pixmap.h b/client/red_pixmap.h
index 1b469bdf..c81c2f77 100644
--- a/client/red_pixmap.h
+++ b/client/red_pixmap.h
@@ -20,17 +20,62 @@
#define _H_RED_PIXMAP
#include "red_drawable.h"
+#include "utils.h"
+#include <pixman_utils.h>
class RedPixmap: public RedDrawable {
public:
enum Format {
ARGB32,
RGB32,
+ RGB16_555,
+ RGB16_565,
A1,
};
- RedPixmap(int width, int height, Format format, bool top_bottom,
- rgb32_t* pallete);
+ static int format_to_bpp(Format format) {
+ if (format == RedPixmap::A1) {
+ return 1;
+ } else if (format == RGB16_555 || format == RGB16_565) {
+ return 16;
+ } else {
+ return 32;
+ }
+ }
+
+ static pixman_format_code_t format_to_pixman(Format format) {
+ switch (format) {
+ case RedPixmap::ARGB32:
+ return PIXMAN_a8r8g8b8;
+ case RedPixmap::RGB32:
+ return PIXMAN_x8r8g8b8;
+ case RedPixmap::RGB16_555:
+ return PIXMAN_x1r5g5b5;
+ case RedPixmap::RGB16_565:
+ return PIXMAN_r5g6b5;
+ case RedPixmap::A1:
+ return PIXMAN_a1;
+ default:
+ THROW("unsupported format %d", format);
+ }
+ }
+
+ static Format format_from_surface(uint32_t format) {
+ switch (format) {
+ case SPICE_SURFACE_FMT_16_555:
+ return RedPixmap::RGB16_555;
+ case SPICE_SURFACE_FMT_16_565:
+ return RedPixmap::RGB16_565;
+ case SPICE_SURFACE_FMT_32_xRGB:
+ return RedPixmap::RGB32;
+ case SPICE_SURFACE_FMT_32_ARGB:
+ return RedPixmap::ARGB32;
+ default:
+ THROW("Unsupported RedPixman format");
+ }
+ }
+
+ RedPixmap(int width, int height, Format format, bool top_bottom);
virtual ~RedPixmap();
virtual SpicePoint get_size() { SpicePoint pt = {_width, _height}; return pt;}
diff --git a/client/red_pixmap_cairo.h b/client/red_pixmap_cairo.h
index 3f89db8f..7f9523e8 100644
--- a/client/red_pixmap_cairo.h
+++ b/client/red_pixmap_cairo.h
@@ -23,8 +23,7 @@
class RedPixmapCairo: public RedPixmap {
public:
- RedPixmapCairo(int width, int height, Format format, bool top_bottom,
- rgb32_t *pallete, RedWindow *win);
+ RedPixmapCairo(int width, int height, Format format, bool top_bottom, RedWindow *win);
~RedPixmapCairo();
};
diff --git a/client/red_pixmap_gdi.h b/client/red_pixmap_gdi.h
index 9e10adc1..524e6f31 100644
--- a/client/red_pixmap_gdi.h
+++ b/client/red_pixmap_gdi.h
@@ -25,8 +25,7 @@ class RecurciveMutex;
class RedPixmapGdi: public RedPixmap {
public:
- RedPixmapGdi(int width, int height, Format format, bool top_bottom,
- rgb32_t *pallete);
+ RedPixmapGdi(int width, int height, Format format, bool top_bottom);
HDC get_dc();
void *get_memptr();
~RedPixmapGdi();
diff --git a/client/red_pixmap_gl.h b/client/red_pixmap_gl.h
index f322d52c..f7a14af9 100644
--- a/client/red_pixmap_gl.h
+++ b/client/red_pixmap_gl.h
@@ -29,7 +29,7 @@ enum RenderType {
class RedPixmapGL: public RedPixmap {
public:
RedPixmapGL(int width, int height, Format format, bool top_bottom,
- rgb32_t *pallete, RedWindow *win, RenderType rendertype);
+ RedWindow *win, RenderType rendertype);
void textures_lost();
void touch_context();
diff --git a/client/screen.cpp b/client/screen.cpp
index f31a9a60..7edca121 100644
--- a/client/screen.cpp
+++ b/client/screen.cpp
@@ -172,7 +172,7 @@ void RedScreen::create_composit_area()
{
destroy_composit_area();
_composit_area = new RedPixmapCairo(_size.x, _size.y, RedPixmap::RGB32,
- false, NULL, NULL);
+ false, NULL);
}
void RedScreen::adjust_window_rect(int x, int y)
diff --git a/client/windows/red_pixmap.cpp b/client/windows/red_pixmap.cpp
index 1ec41faf..574d2851 100644
--- a/client/windows/red_pixmap.cpp
+++ b/client/windows/red_pixmap.cpp
@@ -21,11 +21,11 @@
#include "utils.h"
RedPixmap::RedPixmap(int width, int height, RedPixmap::Format format,
- bool top_bottom, rgb32_t* pallet)
+ bool top_bottom)
: _format (format)
, _width (width)
, _height (height)
- , _stride (SPICE_ALIGN(width * (_format == RedPixmap::A1 ? 1: 32), 32) / 8)
+ , _stride (SPICE_ALIGN(width * format_to_bpp(format), 32) / 8)
, _top_bottom (top_bottom)
, _data (NULL)
{
diff --git a/client/windows/red_pixmap_cairo.cpp b/client/windows/red_pixmap_cairo.cpp
index 6ed58068..793d21ed 100644
--- a/client/windows/red_pixmap_cairo.cpp
+++ b/client/windows/red_pixmap_cairo.cpp
@@ -29,14 +29,9 @@ struct RedPixmap_p {
HBITMAP prev_bitmap;
};
-static inline int format_to_bpp(RedPixmap::Format format)
-{
- return ((format == RedPixmap::A1) ? 1 : 32);
-}
-
-RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format, bool top_bottom,
- rgb32_t* pallet, RedWindow *win)
- : RedPixmap(width, height, format, top_bottom, pallet)
+RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
+ bool top_bottom, RedWindow *win)
+ : RedPixmap(width, height, format, top_bottom)
{
ASSERT(format == RedPixmap::ARGB32 || format == RedPixmap::RGB32 || format == RedPixmap::A1);
ASSERT(sizeof(RedPixmap_p) <= PIXELES_SOURCE_OPAQUE_SIZE);
@@ -65,15 +60,16 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
#endif*/
bitmap_info.inf.bmiHeader.biPlanes = 1;
- bitmap_info.inf.bmiHeader.biBitCount = format_to_bpp(format);
+ bitmap_info.inf.bmiHeader.biBitCount = RedPixmap::format_to_bpp(format);
bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
switch (format) {
case RedPixmap::A1:
- for (int i = 0; i < (1 << format_to_bpp(format)); i++) {
- bitmap_info.inf.bmiColors[i].rgbRed = rgb32_get_red(pallet[i]);
- bitmap_info.inf.bmiColors[i].rgbGreen = rgb32_get_green(pallet[i]);
- bitmap_info.inf.bmiColors[i].rgbBlue = rgb32_get_blue(pallet[i]);
- }
+ bitmap_info.inf.bmiColors[0].rgbRed = 0;
+ bitmap_info.inf.bmiColors[0].rgbGreen = 0;
+ bitmap_info.inf.bmiColors[0].rgbBlue = 0;
+ bitmap_info.inf.bmiColors[1].rgbRed = 0xff;
+ bitmap_info.inf.bmiColors[1].rgbGreen = 0xff;
+ bitmap_info.inf.bmiColors[1].rgbBlue = 0xff;
break;
}
AutoDC dc(create_compatible_dc());
diff --git a/client/windows/red_pixmap_gdi.cpp b/client/windows/red_pixmap_gdi.cpp
index d4913c49..1c90f3d5 100644
--- a/client/windows/red_pixmap_gdi.cpp
+++ b/client/windows/red_pixmap_gdi.cpp
@@ -29,13 +29,7 @@ struct RedPixmap_p {
HBITMAP prev_bitmap;
};
-static inline int format_to_bpp(RedPixmap::Format format)
-{
- return ((format == RedPixmap::A1) ? 1 : 32);
-}
-
-RedPixmapGdi::RedPixmapGdi(int width, int height, RedPixmap::Format format, bool top_bottom,
- rgb32_t* pallet)
+RedPixmapGdi::RedPixmapGdi(int width, int height, RedPixmap::Format format, bool top_bottom)
: RedPixmap(width, height, format, top_bottom, pallet)
{
ASSERT(format == RedPixmap::ARGB32 || format == RedPixmap::RGB32 || format == RedPixmap::A1);
@@ -52,15 +46,16 @@ RedPixmapGdi::RedPixmapGdi(int width, int height, RedPixmap::Format format, bool
bitmap_info.inf.bmiHeader.biHeight = top_bottom ? -_height : _height;
bitmap_info.inf.bmiHeader.biPlanes = 1;
- bitmap_info.inf.bmiHeader.biBitCount = format_to_bpp(format);
+ bitmap_info.inf.bmiHeader.biBitCount = RedPixmap::format_to_bpp(format);
bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
switch (format) {
case RedPixmap::A1:
- for (int i = 0; i < (1 << format_to_bpp(format)); i++) {
- bitmap_info.inf.bmiColors[i].rgbRed = rgb32_get_red(pallet[i]);
- bitmap_info.inf.bmiColors[i].rgbGreen = rgb32_get_green(pallet[i]);
- bitmap_info.inf.bmiColors[i].rgbBlue = rgb32_get_blue(pallet[i]);
- }
+ bitmap_info.inf.bmiColors[0].rgbRed = 0;
+ bitmap_info.inf.bmiColors[0].rgbGreen = 0;
+ bitmap_info.inf.bmiColors[0].rgbBlue = 0;
+ bitmap_info.inf.bmiColors[1].rgbRed = 0xff;
+ bitmap_info.inf.bmiColors[1].rgbGreen = 0xff;
+ bitmap_info.inf.bmiColors[1].rgbBlue = 0xff;
break;
}
AutoDC dc(create_compatible_dc());
diff --git a/client/x11/red_pixmap.cpp b/client/x11/red_pixmap.cpp
index 09455dd3..2a0eb99b 100644
--- a/client/x11/red_pixmap.cpp
+++ b/client/x11/red_pixmap.cpp
@@ -21,11 +21,11 @@
#include "utils.h"
RedPixmap::RedPixmap(int width, int height, RedPixmap::Format format,
- bool top_bottom, rgb32_t* pallet)
+ bool top_bottom)
: _format (format)
, _width (width)
, _height (height)
- , _stride (SPICE_ALIGN(width * (_format == RedPixmap::A1 ? 1 : 32), 32) / 8)
+ , _stride (SPICE_ALIGN(width * format_to_bpp(format), 32) / 8)
, _top_bottom (top_bottom)
, _data (NULL)
{
diff --git a/client/x11/red_pixmap_cairo.cpp b/client/x11/red_pixmap_cairo.cpp
index e73b8b41..1974ebc4 100644
--- a/client/x11/red_pixmap_cairo.cpp
+++ b/client/x11/red_pixmap_cairo.cpp
@@ -26,10 +26,12 @@
RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
- bool top_bottom, rgb32_t* pallet, RedWindow *win)
- : RedPixmap(width, height, format, top_bottom, pallet)
+ bool top_bottom, RedWindow *win)
+ : RedPixmap(width, height, format, top_bottom)
{
- ASSERT(format == RedPixmap::ARGB32 || format == RedPixmap::RGB32 || format == RedPixmap::A1);
+ ASSERT(format == RedPixmap::ARGB32 || format == RedPixmap::RGB32 ||
+ format == RedPixmap::RGB16_555 || format == RedPixmap::RGB16_565 ||
+ format == RedPixmap::A1);
ASSERT(sizeof(RedDrawable_p) <= PIXELES_SOURCE_OPAQUE_SIZE);
pixman_image_t *pixman_image;
XImage *image = NULL;
@@ -49,22 +51,8 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
using_shm = vinfo && XPlatform::is_x_shm_avail();
if (using_shm) {
- int depth;
-
- switch (format) {
- case RedPixmap::ARGB32:
- case RedPixmap::RGB32:
- depth = XPlatform::get_vinfo()[0]->depth;
- pixman_format = format == RedPixmap::ARGB32 ? PIXMAN_a8r8g8b8 :
- PIXMAN_x8r8g8b8;
- break;
- case RedPixmap::A1:
- depth = 1;
- pixman_format = PIXMAN_a1;
- break;
- default:
- THROW("unsupported format %d", format);
- }
+ int depth = RedPixmap::format_to_bpp(format);
+ pixman_format = RedPixmap::format_to_pixman(format);
shminfo = new XShmSegmentInfo;
shminfo->shmid = -1;
diff --git a/client/x11/red_pixmap_gl.cpp b/client/x11/red_pixmap_gl.cpp
index 2722476d..a3096517 100644
--- a/client/x11/red_pixmap_gl.cpp
+++ b/client/x11/red_pixmap_gl.cpp
@@ -31,9 +31,9 @@
RedPixmapGL::RedPixmapGL(int width, int height, RedPixmap::Format format,
- bool top_bottom, rgb32_t* pallet, RedWindow *win,
+ bool top_bottom, RedWindow *win,
RenderType rendertype)
- : RedPixmap(width, height, format, top_bottom, pallet)
+ : RedPixmap(width, height, format, top_bottom)
{
GLuint fbo;
GLuint tex;
diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c
index 38a7081e..fde43d7f 100644
--- a/common/cairo_canvas.c
+++ b/common/cairo_canvas.c
@@ -1074,7 +1074,8 @@ static void canvas_destroy(SpiceCanvas *spice_canvas)
static int need_init = 1;
static SpiceCanvasOps cairo_canvas_ops;
-SpiceCanvas *canvas_create(pixman_image_t *image, int bits
+static SpiceCanvas *canvas_create_common(pixman_image_t *image,
+ uint32_t format
#ifdef CAIRO_CANVAS_CACHE
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
@@ -1098,7 +1099,7 @@ SpiceCanvas *canvas_create(pixman_image_t *image, int bits
init_ok = canvas_base_init(&canvas->base, &cairo_canvas_ops,
pixman_image_get_width (image),
pixman_image_get_height (image),
- bits
+ format
#ifdef CAIRO_CANVAS_CACHE
, bits_cache
, palette_cache
@@ -1114,11 +1115,80 @@ SpiceCanvas *canvas_create(pixman_image_t *image, int bits
canvas->private_data = NULL;
canvas->private_data_size = 0;
- canvas->image = pixman_image_ref(image);
+ canvas->image = image;
return (SpiceCanvas *)canvas;
}
+SpiceCanvas *canvas_create(int width, int height, uint32_t format
+#ifdef CAIRO_CANVAS_CACHE
+ , SpiceImageCache *bits_cache
+ , SpicePaletteCache *palette_cache
+#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
+ , SpiceImageCache *bits_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+#ifndef CAIRO_CANVAS_NO_CHUNKS
+ , SpiceVirtMapping *virt_mapping
+#endif
+ )
+{
+ pixman_image_t *image;
+
+ image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
+ width, height, NULL, 0);
+
+ return canvas_create_common(image, format
+#ifdef CAIRO_CANVAS_CACHE
+ , bits_cache
+ , palette_cache
+#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
+ , bits_cache
+#endif
+ , surfaces
+ , glz_decoder
+#ifndef CAIRO_CANVAS_NO_CHUNKS
+ , virt_mapping
+#endif
+ );
+}
+
+SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
+ uint8_t *data, size_t stride
+#ifdef CAIRO_CANVAS_CACHE
+ , SpiceImageCache *bits_cache
+ , SpicePaletteCache *palette_cache
+#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
+ , SpiceImageCache *bits_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+#ifndef CAIRO_CANVAS_NO_CHUNKS
+ , SpiceVirtMapping *virt_mapping
+#endif
+ )
+{
+ pixman_image_t *image;
+
+ image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
+ width, height, (uint32_t *)data, stride);
+
+ return canvas_create_common(image, format
+#ifdef CAIRO_CANVAS_CACHE
+ , bits_cache
+ , palette_cache
+#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
+ , bits_cache
+#endif
+ , surfaces
+ , glz_decoder
+#ifndef CAIRO_CANVAS_NO_CHUNKS
+ , virt_mapping
+#endif
+ );
+}
+
void cairo_canvas_init() //unsafe global function
{
if (!need_init) {
diff --git a/common/cairo_canvas.h b/common/cairo_canvas.h
index 7f882b2a..c97380e2 100644
--- a/common/cairo_canvas.h
+++ b/common/cairo_canvas.h
@@ -26,7 +26,7 @@
#include "canvas_base.h"
#include "region.h"
-SpiceCanvas *canvas_create(pixman_image_t *image, int bits
+SpiceCanvas *canvas_create(int width, int height, uint32_t format
#ifdef CAIRO_CANVAS_CACHE
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
@@ -40,6 +40,21 @@ SpiceCanvas *canvas_create(pixman_image_t *image, int bits
#endif
);
+SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint8_t *data, size_t stride
+#ifdef CAIRO_CANVAS_CACHE
+ , SpiceImageCache *bits_cache
+ , SpicePaletteCache *palette_cache
+#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
+ , SpiceImageCache *bits_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+#ifndef CAIRO_CANVAS_NO_CHUNKS
+ , SpiceVirtMapping *virt_mapping
+#endif
+ );
+
+
void cairo_canvas_init();
#endif
diff --git a/common/canvas_base.c b/common/canvas_base.c
index 9852da9e..fb101fda 100644
--- a/common/canvas_base.c
+++ b/common/canvas_base.c
@@ -176,6 +176,7 @@ typedef struct CanvasBase {
unsigned long max;
#endif
+ uint32_t format;
int width;
int height;
pixman_region32_t canvas_region;
@@ -3175,7 +3176,7 @@ inline static void canvas_base_init_ops(SpiceCanvasOps *ops)
}
static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
- int width, int height, int depth
+ int width, int height, uint32_t format
#ifdef CAIRO_CANVAS_CACHE
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
@@ -3218,7 +3219,10 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
canvas->surfaces = surfaces;
canvas->glz_data.decoder = glz_decoder;
- if (depth == 16) {
+ canvas->format = format;
+
+ /* TODO: This is all wrong now */
+ if (SPICE_SURFACE_FMT_DEPTH(format) == 16) {
canvas->color_shift = 5;
canvas->color_mask = 0x1f;
} else {
diff --git a/common/canvas_utils.c b/common/canvas_utils.c
index 1e97e872..4f2456d6 100644
--- a/common/canvas_utils.c
+++ b/common/canvas_utils.c
@@ -175,6 +175,11 @@ pixman_image_t * surface_create(pixman_format_code_t format, int width, int heig
bitmap_info.inf.bmiHeader.biBitCount = 32;
nstride = width * 4;
break;
+ case PIXMAN_x1r5g5b5:
+ case PIXMAN_r5g6b5:
+ bitmap_info.inf.bmiHeader.biBitCount = 16;
+ nstride = SPICE_ALIGN(width * 2, 4);
+ break;
case PIXMAN_a8:
bitmap_info.inf.bmiHeader.biBitCount = 8;
nstride = SPICE_ALIGN(width, 4);
@@ -237,6 +242,10 @@ pixman_image_t * surface_create(pixman_format_code_t format, int width, int heig
case PIXMAN_x8r8g8b8:
stride = width * 4;
break;
+ case PIXMAN_x1r5g5b5:
+ case PIXMAN_r5g6b5:
+ stride = SPICE_ALIGN(width * 2, 4);
+ break;
case PIXMAN_a8:
stride = SPICE_ALIGN(width, 4);
break;
diff --git a/common/gdi_canvas.c b/common/gdi_canvas.c
index ead94af0..c600419d 100644
--- a/common/gdi_canvas.c
+++ b/common/gdi_canvas.c
@@ -1884,7 +1884,7 @@ static int need_init = 1;
static SpiceCanvasOps gdi_canvas_ops;
SpiceCanvas *gdi_canvas_create(int width, int height,
- HDC dc, RecurciveMutex* lock, int bits
+ HDC dc, RecurciveMutex* lock, uint32_t format
#ifdef CAIRO_CANVAS_CACHE
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
@@ -1903,7 +1903,7 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
}
canvas = spice_new0(GdiCanvas, 1);
init_ok = canvas_base_init(&canvas->base, &gdi_canvas_ops,
- width, height, bits
+ width, height, format
#ifdef CAIRO_CANVAS_CACHE
,bits_cache
,palette_cache
diff --git a/common/gdi_canvas.h b/common/gdi_canvas.h
index 43da189c..13d82efa 100644
--- a/common/gdi_canvas.h
+++ b/common/gdi_canvas.h
@@ -34,7 +34,7 @@ typedef struct {
} GdiImage;
SpiceCanvas *gdi_canvas_create(int width, int height,
- HDC dc, class RecurciveMutex *lock, int bits,
+ HDC dc, class RecurciveMutex *lock, uint32_t format,
SpiceImageCache *bits_cache,
SpicePaletteCache *palette_cache,
SpiceImageSurfaces *surfaces,
diff --git a/common/gl_canvas.c b/common/gl_canvas.c
index dd470bc5..9b017fa2 100644
--- a/common/gl_canvas.c
+++ b/common/gl_canvas.c
@@ -821,7 +821,7 @@ static void gl_canvas_set_access_params(SpiceCanvas *spice_canvas, unsigned long
static int need_init = 1;
static SpiceCanvasOps gl_canvas_ops;
-SpiceCanvas *gl_canvas_create(int width, int height, int depth
+SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
#ifdef CAIRO_CANVAS_CACHE
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
@@ -848,7 +848,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, int depth
}
canvas->private_data = NULL;
init_ok = canvas_base_init(&canvas->base, &gl_canvas_ops,
- width, height, depth
+ width, height, format
#ifdef CAIRO_CANVAS_CACHE
, bits_cache
, palette_cache
diff --git a/common/gl_canvas.h b/common/gl_canvas.h
index 7c54cbfb..615ca895 100644
--- a/common/gl_canvas.h
+++ b/common/gl_canvas.h
@@ -21,7 +21,7 @@
#include "canvas_base.h"
#include "region.h"
-SpiceCanvas *gl_canvas_create(int width, int height, int depth
+SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format
#ifdef CAIRO_CANVAS_CACHE
, SpiceImageCache *bits_cache
, SpicePaletteCache *palette_cache
diff --git a/server/red_worker.c b/server/red_worker.c
index 28927285..af3a8883 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -7795,25 +7795,6 @@ static void red_migrate_display(RedWorker *worker)
}
}
-static SpiceCanvas *create_cairo_context(RedWorker *worker, uint32_t width, uint32_t height,
- int32_t stride, uint8_t depth, void *line_0)
-{
- SpiceCanvas *canvas;
- pixman_image_t *surface;
-
- surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, width, height,
- (uint32_t *)line_0,
- stride);
- if (surface == NULL) {
- red_error("create cairo surface failed");
- }
- canvas = canvas_create(surface, depth, &worker->image_cache.base,
- &worker->image_surfaces, NULL,
- &worker->preload_group_virt_mapping);
- pixman_image_unref (surface);
- return canvas;
-}
-
static SpiceCanvas *create_ogl_context_common(RedWorker *worker, OGLCtx *ctx, uint32_t width,
uint32_t height, int32_t stride, uint8_t depth)
{
@@ -7870,22 +7851,28 @@ static SpiceCanvas *create_ogl_pixmap_context(RedWorker *worker, uint32_t width,
static inline void *create_canvas_for_surface(RedWorker *worker, RedSurface *surface,
uint32_t renderer, uint32_t width, uint32_t height,
- int32_t stride, uint8_t depth, void *line_0)
+ int32_t stride, uint32_t format, void *line_0)
{
SpiceCanvas *canvas;
switch (renderer) {
case RED_RENDERER_CAIRO:
- canvas = create_cairo_context(worker, width, height, stride, depth, line_0);
+ canvas = canvas_create_for_data(width, height, format,
+ line_0, stride,
+ &worker->image_cache.base,
+ &worker->image_surfaces, NULL,
+ &worker->preload_group_virt_mapping);
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);
+ canvas = create_ogl_pbuf_context(worker, width, height, stride,
+ SPICE_SURFACE_FMT_DEPTH(format));
surface->context.top_down = FALSE;
return canvas;
case RED_RENDERER_OGL_PIXMAP:
- canvas = create_ogl_pixmap_context(worker, width, height, stride, depth);
+ canvas = create_ogl_pixmap_context(worker, width, height, stride,
+ SPICE_SURFACE_FMT_DEPTH(format));
surface->context.top_down = FALSE;
return canvas;
default: