[Spice-devel] [PATCH 02/30] Add pixman utilities
Alexander Larsson
alexl at redhat.com
Thu Feb 18 12:58:28 PST 2010
This includes:
* pixman region from SpiceRects
* pixman region from bitmask
* rop2 enum
* solid fill
* solid fill with rop
* tiled fill
* tiled fill with rop
* blit
* blit with rop
* copy rect
---
client/Makefile.am | 1 +
client/pixman_utils.cpp | 25 +
client/x11/Makefile.am | 1 +
common/Makefile.am | 2 +
common/pixman_utils.c | 1286 +++++++++++++++++++++++++++++++++++++++++++++++
common/pixman_utils.h | 112 ++++
server/Makefile.am | 1 +
7 files changed, 1428 insertions(+), 0 deletions(-)
create mode 100644 client/pixman_utils.cpp
create mode 100644 common/pixman_utils.c
create mode 100644 common/pixman_utils.h
diff --git a/client/Makefile.am b/client/Makefile.am
index b453e94..c59b6f3 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -10,6 +10,7 @@ RED_COMMON_SRCS = \
audio_devices.h \
cache.hpp \
cairo_canvas.cpp \
+ pixman_utils.cpp \
canvas.cpp \
canvas.h \
canvas_utils.cpp \
diff --git a/client/pixman_utils.cpp b/client/pixman_utils.cpp
new file mode 100644
index 0000000..337e07c
--- /dev/null
+++ b/client/pixman_utils.cpp
@@ -0,0 +1,25 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "common.h"
+#include "utils.h"
+
+
+#define CANVAS_ERROR(format, ...) THROW(format, ## __VA_ARGS__)
+
+#include "../common/pixman_utils.c"
+
diff --git a/client/x11/Makefile.am b/client/x11/Makefile.am
index c5efd86..e50c4ae 100644
--- a/client/x11/Makefile.am
+++ b/client/x11/Makefile.am
@@ -71,6 +71,7 @@ RED_COMMON_SRCS = \
$(top_srcdir)/client/menu.cpp \
$(top_srcdir)/client/menu.h \
$(top_srcdir)/client/pixels_source.h \
+ $(top_srcdir)/client/pixman_utils.cpp \
$(top_srcdir)/client/platform.h \
$(top_srcdir)/client/playback_channel.cpp \
$(top_srcdir)/client/process_loop.cpp \
diff --git a/common/Makefile.am b/common/Makefile.am
index 7fcdfe9..2d18440 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -3,6 +3,8 @@ NULL =
COMMON_SRCS = \
cairo_canvas.h \
cairo_canvas.c \
+ pixman_utils.h \
+ pixman_utils.c \
canvas_base.h \
canvas_base.c \
canvas_utils.h \
diff --git a/common/pixman_utils.c b/common/pixman_utils.c
new file mode 100644
index 0000000..84df957
--- /dev/null
+++ b/common/pixman_utils.c
@@ -0,0 +1,1286 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "pixman_utils.h"
+#include <stdlib.h>
+#include <string.h>
+
+/*************************************************************
+ *********** Copied from pixman-region.c ************
+ *************************************************************/
+
+/* We're doing 32bit only atm, but keep this to be generically useful */
+
+typedef pixman_box32_t box_type_t;
+typedef pixman_region32_data_t region_data_type_t;
+typedef pixman_region32_t region_type_t;
+
+typedef struct {
+ int x, y;
+} point_type_t;
+
+#define pixman_region32_init_from_bitmap spice_pixman_region32_init_from_bitmap
+
+#define PREFIX(x) pixman_region32##x
+
+/* Below this is 16/32bit intependent */
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef UINT32_MAX
+# define UINT32_MAX (4294967295U)
+#endif
+
+/* from pixman-edge-imp.h */
+#ifdef WORDS_BIGENDIAN
+# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
+# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
+#else
+# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
+# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
+#endif
+
+#define PIXREGION_BOXPTR(reg) ((box_type_t *)((reg)->data + 1))
+#define PIXREGION_BOX(reg, i) (&PIXREGION_BOXPTR (reg)[i])
+#define PIXREGION_TOP(reg) PIXREGION_BOX (reg, (reg)->data->numRects)
+#define PIXREGION_END(reg) PIXREGION_BOX (reg, (reg)->data->numRects - 1)
+
+static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 };
+static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
+
+static box_type_t *pixman_region_empty_box =
+ (box_type_t *)&PREFIX (_empty_box_);
+static region_data_type_t *pixman_broken_data =
+ (region_data_type_t *)&PREFIX (_broken_data_);
+
+static size_t
+PIXREGION_SZOF (size_t n)
+{
+ size_t size = n * sizeof(box_type_t);
+
+ if (n > UINT32_MAX / sizeof(box_type_t))
+ return 0;
+
+ if (sizeof(region_data_type_t) > UINT32_MAX - size)
+ return 0;
+
+ return size + sizeof(region_data_type_t);
+}
+
+static void *
+alloc_data (size_t n)
+{
+ size_t sz = PIXREGION_SZOF (n);
+
+ if (!sz)
+ return NULL;
+
+ return malloc (sz);
+}
+
+#define FREE_DATA(reg) if ((reg)->data && (reg)->data->size) free ((reg)->data)
+
+static pixman_bool_t
+pixman_break (region_type_t *region)
+{
+ FREE_DATA (region);
+
+ region->extents = *pixman_region_empty_box;
+ region->data = pixman_broken_data;
+
+ return FALSE;
+}
+
+static pixman_bool_t
+pixman_rect_alloc (region_type_t * region,
+ int n)
+{
+ region_data_type_t *data;
+
+ if (!region->data)
+ {
+ n++;
+ region->data = (region_data_type_t *)alloc_data (n);
+
+ if (!region->data)
+ return pixman_break (region);
+
+ region->data->numRects = 1;
+ *PIXREGION_BOXPTR (region) = region->extents;
+ }
+ else if (!region->data->size)
+ {
+ region->data = (region_data_type_t *)alloc_data (n);
+
+ if (!region->data)
+ return pixman_break (region);
+
+ region->data->numRects = 0;
+ }
+ else
+ {
+ size_t data_size;
+
+ if (n == 1)
+ {
+ n = region->data->numRects;
+ if (n > 500) /* XXX pick numbers out of a hat */
+ n = 250;
+ }
+
+ n += region->data->numRects;
+ data_size = PIXREGION_SZOF (n);
+
+ if (!data_size)
+ {
+ data = NULL;
+ }
+ else
+ {
+ data = (region_data_type_t *)
+ realloc (region->data, PIXREGION_SZOF (n));
+ }
+
+ if (!data)
+ return pixman_break (region);
+
+ region->data = data;
+ }
+
+ region->data->size = n;
+
+ return TRUE;
+}
+
+/*************************************************************
+ ********** copied from X, fbpixmap.c and fb.h **********
+ *************************************************************/
+
+/* We only use uint32_t for bits and little endian bitmasks */
+#define READ(_ptr) (*(_ptr))
+
+/* This is the code from fbpixmap.c */
+
+#define BM_ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
+if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
+ (!((reg)->data->numRects && \
+ ((r-1)->y1 == (ry1)) && \
+ ((r-1)->y2 == (ry2)) && \
+ ((r-1)->x1 <= (rx1)) && \
+ ((r-1)->x2 >= (rx2))))) \
+{ \
+ if (!(reg)->data || \
+ (reg)->data->numRects == (reg)->data->size) \
+ { \
+ if (!pixman_rect_alloc (reg, 1)) \
+ goto error; \
+ fr = PIXREGION_BOXPTR(reg); \
+ r = fr + (reg)->data->numRects; \
+ } \
+ r->x1 = (rx1); \
+ r->y1 = (ry1); \
+ r->x2 = (rx2); \
+ r->y2 = (ry2); \
+ (reg)->data->numRects++; \
+ if(r->x1 < (reg)->extents.x1) \
+ (reg)->extents.x1 = r->x1; \
+ if(r->x2 > (reg)->extents.x2) \
+ (reg)->extents.x2 = r->x2; \
+ r++; \
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+void
+PREFIX (_init_from_bitmap) (region_type_t *region,
+ uint32_t *data,
+ int width, int height, int stride)
+{
+ uint32_t mask0 = 0xffffffff & ~SCREEN_SHIFT_RIGHT(0xffffffff, 1);
+ box_type_t *first_rect, *rects, *prect_line_start;
+ box_type_t *old_rect, *new_rect;
+ uint32_t *pw, w, *pw_line, *pw_line_end;
+ int irect_prev_start, irect_line_start;
+ int h, base, rx1 = 0, crects;
+ int ib;
+ pixman_bool_t in_box, same;
+
+ PREFIX(_init) (region);
+
+ first_rect = PIXREGION_BOXPTR(region);
+ rects = first_rect;
+
+ pw_line = data;
+
+ region->extents.x1 = width - 1;
+ region->extents.x2 = 0;
+ irect_prev_start = -1;
+ for (h = 0; h < height; h++)
+ {
+ pw = pw_line;
+ pw_line += stride;
+ irect_line_start = rects - first_rect;
+
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if (READ(pw) & mask0)
+ {
+ in_box = TRUE;
+ rx1 = 0;
+ }
+ else
+ in_box = FALSE;
+
+ /* Process all words which are fully in the pixmap */
+ pw_line_end = pw + (width >> 5);
+ for (base = 0; pw < pw_line_end; base += 32)
+ {
+ w = READ(pw++);
+ if (in_box)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for (ib = 0; ib < 32; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0)
+ {
+ if (!in_box)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ in_box = TRUE;
+ }
+ }
+ else
+ {
+ if (in_box)
+ {
+ /* end box */
+ BM_ADDRECT(region, rects, first_rect,
+ rx1, h, base + ib, h + 1);
+ in_box = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCREEN_SHIFT_LEFT(w, 1);
+ }
+ }
+
+ if (width & 31)
+ {
+ /* Process final partial word on line */
+ w = READ(pw++);
+ for (ib = 0; ib < (width & 31); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0)
+ {
+ if (!in_box)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ in_box = TRUE;
+ }
+ }
+ else
+ {
+ if (in_box)
+ {
+ /* end box */
+ BM_ADDRECT(region, rects, first_rect,
+ rx1, h, base + ib, h + 1);
+ in_box = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCREEN_SHIFT_LEFT(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if (in_box)
+ {
+ BM_ADDRECT(region, rects, first_rect,
+ rx1, h, base + (width & 31), h + 1);
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ same = FALSE;
+ if (irect_prev_start != -1)
+ {
+ crects = irect_line_start - irect_prev_start;
+ if (crects != 0 &&
+ crects == ((rects - first_rect) - irect_line_start))
+ {
+ old_rect = first_rect + irect_prev_start;
+ new_rect = prect_line_start = first_rect + irect_line_start;
+ same = TRUE;
+ while (old_rect < prect_line_start)
+ {
+ if ((old_rect->x1 != new_rect->x1) ||
+ (old_rect->x2 != new_rect->x2))
+ {
+ same = FALSE;
+ break;
+ }
+ old_rect++;
+ new_rect++;
+ }
+ if (same)
+ {
+ old_rect = first_rect + irect_prev_start;
+ while (old_rect < prect_line_start)
+ {
+ old_rect->y2 += 1;
+ old_rect++;
+ }
+ rects -= crects;
+ region->data->numRects -= crects;
+ }
+ }
+ }
+ if(!same)
+ irect_prev_start = irect_line_start;
+ }
+ if (!region->data->numRects)
+ region->extents.x1 = region->extents.x2 = 0;
+ else
+ {
+ region->extents.y1 = PIXREGION_BOXPTR(region)->y1;
+ region->extents.y2 = PIXREGION_END(region)->y2;
+ if (region->data->numRects == 1)
+ {
+ free (region->data);
+ region->data = NULL;
+ }
+ }
+
+ error:
+ return;
+}
+
+#include <stdio.h>
+
+#ifndef ASSERT
+#define ASSERT(x) if (!(x)) { \
+ printf("%s: ASSERT %s failed\n", __FUNCTION__, #x); \
+ abort(); \
+}
+#endif
+
+#define SOLID_RASTER_OP(_name, _size, _type, _equation) \
+static void \
+solid_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type src) \
+{ \
+ while (len--) { \
+ _type dst = *ptr; \
+ if (dst) /* avoid unused warning */; \
+ *ptr = (_type)(_equation); \
+ ptr++; \
+ } \
+} \
+
+#define TILED_RASTER_OP(_name, _size, _type, _equation) \
+static void \
+tiled_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) \
+{ \
+ while (len--) { \
+ _type src = *tile; \
+ _type dst = *ptr; \
+ if (src) /* avoid unused warning */; \
+ if (dst) /* avoid unused warning */; \
+ *ptr = (_type)(_equation); \
+ ptr++; \
+ tile++; \
+ if (tile == tile_end) \
+ tile -= tile_width; \
+ } \
+} \
+
+#define COPY_RASTER_OP(_name, _size, _type, _equation) \
+static void \
+ copy_rop_ ## _name ## _ ## _size (_type *ptr, _type *src_line, int len) \
+{ \
+ while (len--) { \
+ _type src = *src_line; \
+ _type dst = *ptr; \
+ if (src) /* avoid unused warning */; \
+ if (dst) /* avoid unused warning */; \
+ *ptr = (_type)(_equation); \
+ ptr++; \
+ src_line++; \
+ } \
+} \
+
+#define RASTER_OP(name, equation) \
+ SOLID_RASTER_OP(name, 8, uint8_t, equation) \
+ SOLID_RASTER_OP(name, 16, uint16_t, equation) \
+ SOLID_RASTER_OP(name, 32, uint32_t, equation) \
+ TILED_RASTER_OP(name, 8, uint8_t, equation) \
+ TILED_RASTER_OP(name, 16, uint16_t, equation) \
+ TILED_RASTER_OP(name, 32, uint32_t, equation) \
+ COPY_RASTER_OP(name, 8, uint8_t, equation) \
+ COPY_RASTER_OP(name, 16, uint16_t, equation) \
+ COPY_RASTER_OP(name, 32, uint32_t, equation)
+
+RASTER_OP(clear, 0x0)
+RASTER_OP(and, src & dst)
+RASTER_OP(and_reverse, src & ~dst)
+RASTER_OP(copy, src)
+RASTER_OP(and_inverted, ~src & dst)
+RASTER_OP(noop, dst)
+RASTER_OP(xor, src ^ dst)
+RASTER_OP(or, src | dst)
+RASTER_OP(nor, ~src & ~dst)
+RASTER_OP(equiv, ~src ^ dst)
+RASTER_OP(invert, ~dst)
+RASTER_OP(or_reverse, src | ~dst)
+RASTER_OP(copy_inverted, ~src)
+RASTER_OP(or_inverted, ~src | dst)
+RASTER_OP(nand, ~src | ~dst)
+RASTER_OP(set, 0xffffffff)
+
+typedef void (*solid_rop_8_func_t)(uint8_t *ptr, int len, uint8_t src);
+typedef void (*solid_rop_16_func_t)(uint16_t *ptr, int len, uint16_t src);
+typedef void (*solid_rop_32_func_t)(uint32_t *ptr, int len, uint32_t src);
+typedef void (*tiled_rop_8_func_t)(uint8_t *ptr, int len, uint8_t *tile, uint8_t *tile_end, int tile_width);
+typedef void (*tiled_rop_16_func_t)(uint16_t *ptr, int len, uint16_t *tile, uint16_t *tile_end, int tile_width);
+typedef void (*tiled_rop_32_func_t)(uint32_t *ptr, int len, uint32_t *tile, uint32_t *tile_end, int tile_width);
+typedef void (*copy_rop_8_func_t)(uint8_t *ptr, uint8_t *src, int len);
+typedef void (*copy_rop_16_func_t)(uint16_t *ptr, uint16_t *src, int len);
+typedef void (*copy_rop_32_func_t)(uint32_t *ptr, uint32_t *src, int len);
+
+#define ROP_TABLE(_type, _size) \
+static void (*solid_rops_ ## _size[16]) (_type *ptr, int len, _type src) = { \
+ solid_rop_clear_ ## _size, \
+ solid_rop_and_ ## _size, \
+ solid_rop_and_reverse_ ## _size, \
+ solid_rop_copy_ ## _size, \
+ solid_rop_and_inverted_ ## _size, \
+ solid_rop_noop_ ## _size, \
+ solid_rop_xor_ ## _size, \
+ solid_rop_or_ ## _size, \
+ solid_rop_nor_ ## _size, \
+ solid_rop_equiv_ ## _size, \
+ solid_rop_invert_ ## _size, \
+ solid_rop_or_reverse_ ## _size, \
+ solid_rop_copy_inverted_ ## _size, \
+ solid_rop_or_inverted_ ## _size, \
+ solid_rop_nand_ ## _size, \
+ solid_rop_set_ ## _size \
+}; \
+static void (*tiled_rops_ ## _size[16]) (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) = { \
+ tiled_rop_clear_ ## _size, \
+ tiled_rop_and_ ## _size, \
+ tiled_rop_and_reverse_ ## _size, \
+ tiled_rop_copy_ ## _size, \
+ tiled_rop_and_inverted_ ## _size, \
+ tiled_rop_noop_ ## _size, \
+ tiled_rop_xor_ ## _size, \
+ tiled_rop_or_ ## _size, \
+ tiled_rop_nor_ ## _size, \
+ tiled_rop_equiv_ ## _size, \
+ tiled_rop_invert_ ## _size, \
+ tiled_rop_or_reverse_ ## _size, \
+ tiled_rop_copy_inverted_ ## _size, \
+ tiled_rop_or_inverted_ ## _size, \
+ tiled_rop_nand_ ## _size, \
+ tiled_rop_set_ ## _size \
+}; \
+static void (*copy_rops_ ## _size[16]) (_type *ptr, _type *tile, int len) = { \
+ copy_rop_clear_ ## _size, \
+ copy_rop_and_ ## _size, \
+ copy_rop_and_reverse_ ## _size, \
+ copy_rop_copy_ ## _size, \
+ copy_rop_and_inverted_ ## _size, \
+ copy_rop_noop_ ## _size, \
+ copy_rop_xor_ ## _size, \
+ copy_rop_or_ ## _size, \
+ copy_rop_nor_ ## _size, \
+ copy_rop_equiv_ ## _size, \
+ copy_rop_invert_ ## _size, \
+ copy_rop_or_reverse_ ## _size, \
+ copy_rop_copy_inverted_ ## _size, \
+ copy_rop_or_inverted_ ## _size, \
+ copy_rop_nand_ ## _size, \
+ copy_rop_set_ ## _size \
+};
+
+ROP_TABLE(uint8_t, 8)
+ROP_TABLE(uint16_t, 16)
+ROP_TABLE(uint32_t, 32)
+
+void
+spice_pixman_fill_rect (pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ uint32_t value)
+{
+ uint32_t *bits;
+ int stride, depth;
+ uint32_t byte_width;
+ uint8_t *byte_line;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ ASSERT(x >= 0);
+ ASSERT(y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(x + width <= pixman_image_get_width (dest));
+ ASSERT(y + height <= pixman_image_get_height (dest));
+
+ if (depth == 24)
+ depth = 32; /* Needed for pixman_fill */
+
+ if (pixman_fill (bits,
+ stride / 4,
+ depth,
+ x, y,
+ width, height,
+ value))
+ return;
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ byte_width = width;
+ value = (value & 0xff) * 0x01010101;
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ byte_width = 2 * width;
+ value = (value & 0xffff) * 0x00010001;
+ } else {
+ ASSERT (depth == 32 || depth == 24)
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ byte_width = 4 * width;
+ }
+
+ while (height--) {
+ int w;
+ uint8_t *d = byte_line;
+
+ byte_line += stride;
+ w = byte_width;
+
+ while (w >= 1 && ((unsigned long)d & 1)) {
+ *(uint8_t *)d = (value & 0xff);
+ w--;
+ d++;
+ }
+
+ while (w >= 2 && ((unsigned long)d & 3)) {
+ *(uint16_t *)d = value;
+ w -= 2;
+ d += 2;
+ }
+
+ while (w >= 4 && ((unsigned long)d & 7)) {
+ *(uint32_t *)d = value;
+
+ w -= 4;
+ d += 4;
+ }
+
+ while (w >= 4) {
+ *(uint32_t *)d = value;
+
+ w -= 4;
+ d += 4;
+ }
+
+ while (w >= 2) {
+ *(uint16_t *)d = value;
+ w -= 2;
+ d += 2;
+ }
+
+ while (w >= 1) {
+ *(uint8_t *)d = (value & 0xff);
+ w--;
+ d++;
+ }
+ }
+}
+
+void
+spice_pixman_fill_rect_rop (pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ uint32_t value,
+ SpiceROP rop)
+{
+ uint32_t *bits;
+ int stride, depth;
+ uint8_t *byte_line;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ ASSERT(x >= 0);
+ ASSERT(y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(x + width <= pixman_image_get_width (dest));
+ ASSERT(y + height <= pixman_image_get_height (dest));
+ ASSERT(rop >= 0 && rop < 16);
+
+ if (depth == 8) {
+ solid_rop_8_func_t rop_func = solid_rops_8[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ while (height--) {
+ rop_func ((uint8_t *)byte_line, width, (uint8_t)value);
+ byte_line += stride;
+ }
+
+ } else if (depth == 16) {
+ solid_rop_16_func_t rop_func = solid_rops_16[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ while (height--) {
+ rop_func ((uint16_t *)byte_line, width, (uint16_t)value);
+ byte_line += stride;
+ }
+ } else {
+ solid_rop_32_func_t rop_func = solid_rops_32[rop];
+
+ ASSERT (depth == 32 || depth == 24);
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ while (height--) {
+ rop_func ((uint32_t *)byte_line, width, (uint32_t)value);
+ byte_line += stride;
+ }
+ }
+}
+
+void
+spice_pixman_tile_rect (pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y)
+{
+ uint32_t *bits, *tile_bits;
+ int stride, depth;
+ int tile_width, tile_height, tile_stride;
+ uint8_t *byte_line;
+ uint8_t *tile_line;
+ int tile_start_x, tile_start_y, tile_end_dx;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ tile_bits = pixman_image_get_data (tile);
+ tile_stride = pixman_image_get_stride (tile);
+ tile_width = pixman_image_get_width (tile);
+ tile_height = pixman_image_get_height (tile);
+
+ ASSERT(x >= 0);
+ ASSERT(y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(x + width <= pixman_image_get_width (dest));
+ ASSERT(y + height <= pixman_image_get_height (dest));
+ ASSERT(depth == pixman_image_get_depth (tile));
+
+ tile_start_x = (x - offset_x) % tile_width;
+ if (tile_start_x < 0)
+ tile_start_x += tile_width;
+ tile_start_y = (y - offset_y) % tile_height;
+ if (tile_start_y < 0)
+ tile_start_y += tile_height;
+ tile_end_dx = tile_width - tile_start_x;
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
+ while (height--) {
+ tiled_rop_copy_8 ((uint8_t *)byte_line, width, (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx, tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
+ while (height--) {
+ tiled_rop_copy_16 ((uint16_t *)byte_line, width, (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx, tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ } else {
+ ASSERT (depth == 32 || depth == 24);
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
+ while (height--) {
+ tiled_rop_copy_32 ((uint32_t *)byte_line, width, (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx, tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ }
+}
+
+void
+spice_pixman_tile_rect_rop (pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y,
+ SpiceROP rop)
+{
+ uint32_t *bits, *tile_bits;
+ int stride, depth;
+ int tile_width, tile_height, tile_stride;
+ uint8_t *byte_line;
+ uint8_t *tile_line;
+ int tile_start_x, tile_start_y, tile_end_dx;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ tile_bits = pixman_image_get_data (tile);
+ tile_stride = pixman_image_get_stride (tile);
+ tile_width = pixman_image_get_width (tile);
+ tile_height = pixman_image_get_height (tile);
+
+ ASSERT(x >= 0);
+ ASSERT(y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(x + width <= pixman_image_get_width (dest));
+ ASSERT(y + height <= pixman_image_get_height (dest));
+ ASSERT(rop >= 0 && rop < 16);
+ ASSERT(depth == pixman_image_get_depth (tile));
+
+ tile_start_x = (x - offset_x) % tile_width;
+ if (tile_start_x < 0)
+ tile_start_x += tile_width;
+ tile_start_y = (y - offset_y) % tile_height;
+ if (tile_start_y < 0)
+ tile_start_y += tile_height;
+ tile_end_dx = tile_width - tile_start_x;
+
+ if (depth == 8) {
+ tiled_rop_8_func_t rop_func = tiled_rops_8[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
+ while (height--) {
+ rop_func ((uint8_t *)byte_line, width, (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx, tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+
+ } else if (depth == 16) {
+ tiled_rop_16_func_t rop_func = tiled_rops_16[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
+ while (height--) {
+ rop_func ((uint16_t *)byte_line, width, (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx, tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ } else {
+ tiled_rop_32_func_t rop_func = tiled_rops_32[rop];
+
+ ASSERT (depth == 32 || depth == 24);
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
+ while (height--) {
+ rop_func ((uint32_t *)byte_line, width, (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx, tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ }
+}
+
+
+void
+spice_pixman_blit (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height)
+{
+ uint32_t *bits, *src_bits;
+ int stride, depth;
+ int src_width, src_height, src_stride;
+ uint8_t *byte_line;
+ uint8_t *src_line;
+ int byte_width;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ src_bits = pixman_image_get_data (src);
+ src_stride = pixman_image_get_stride (src);
+ src_width = pixman_image_get_width (src);
+ src_height = pixman_image_get_height (src);
+
+ /* Clip source */
+ if (src_x < 0) {
+ width += src_x;
+ dest_x -= src_x;
+ src_x = 0;
+ }
+ if (src_y < 0) {
+ height += src_y;
+ dest_y -= src_y;
+ src_y = 0;
+ }
+ if (src_x + width > src_width) {
+ width = src_width - src_x;
+ }
+ if (src_y + height > src_height) {
+ height = src_height - src_y;
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ ASSERT(src_x >= 0);
+ ASSERT(src_y >= 0);
+ ASSERT(dest_x >= 0);
+ ASSERT(dest_y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(dest_x + width <= pixman_image_get_width (dest));
+ ASSERT(dest_y + height <= pixman_image_get_height (dest));
+ ASSERT(src_x + width <= pixman_image_get_width (src));
+ ASSERT(src_y + height <= pixman_image_get_height (src));
+ ASSERT(depth == pixman_image_get_depth (src));
+
+ if (depth == 24)
+ depth = 32; /* Needed for pixman_blt */
+
+ if (pixman_blt (src_bits,
+ bits,
+ src_stride / 4,
+ stride / 4,
+ depth, depth,
+ src_x, src_y,
+ dest_x, dest_y,
+ width, height))
+ return;
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
+ byte_width = width;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
+ byte_width = width * 2;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
+ } else {
+ ASSERT (depth == 32 || depth == 24);
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
+ byte_width = width * 4;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
+ }
+
+ while (height--) {
+ memcpy (byte_line, src_line, byte_width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+}
+
+void
+spice_pixman_blit_rop (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ SpiceROP rop)
+{
+ uint32_t *bits, *src_bits;
+ int stride, depth;
+ int src_width, src_height, src_stride;
+ uint8_t *byte_line;
+ uint8_t *src_line;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ src_bits = pixman_image_get_data (src);
+ src_stride = pixman_image_get_stride (src);
+ src_width = pixman_image_get_width (src);
+ src_height = pixman_image_get_height (src);
+
+ /* Clip source */
+ if (src_x < 0) {
+ width += src_x;
+ dest_x -= src_x;
+ src_x = 0;
+ }
+ if (src_y < 0) {
+ height += src_y;
+ dest_y -= src_y;
+ src_y = 0;
+ }
+ if (src_x + width > src_width) {
+ width = src_width - src_x;
+ }
+ if (src_y + height > src_height) {
+ height = src_height - src_y;
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ ASSERT(src_x >= 0);
+ ASSERT(src_y >= 0);
+ ASSERT(dest_x >= 0);
+ ASSERT(dest_y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(dest_x + width <= pixman_image_get_width (dest));
+ ASSERT(dest_y + height <= pixman_image_get_height (dest));
+ ASSERT(src_x + width <= pixman_image_get_width (src));
+ ASSERT(src_y + height <= pixman_image_get_height (src));
+ ASSERT(depth == pixman_image_get_depth (src));
+
+ if (depth == 8) {
+ copy_rop_8_func_t rop_func = copy_rops_8[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
+
+ while (height--) {
+ rop_func ((uint8_t *)byte_line, (uint8_t *)src_line, width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else if (depth == 16) {
+ copy_rop_16_func_t rop_func = copy_rops_16[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
+
+ while (height--) {
+ rop_func ((uint16_t *)byte_line, (uint16_t *)src_line, width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else {
+ copy_rop_32_func_t rop_func = copy_rops_32[rop];
+
+ ASSERT (depth == 32 || depth == 24);
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
+
+ while (height--) {
+ rop_func ((uint32_t *)byte_line, (uint32_t *)src_line, width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ }
+
+}
+
+void
+spice_pixman_blit_colorkey (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ uint32_t transparent_color)
+{
+ uint32_t *bits, *src_bits;
+ int stride, depth;
+ int src_width, src_height, src_stride;
+ uint8_t *byte_line;
+ uint8_t *src_line;
+ int x;
+
+ bits = pixman_image_get_data (dest);
+ stride = pixman_image_get_stride (dest);
+ depth = pixman_image_get_depth (dest);
+ /* stride is in bytes, depth in bits */
+
+ src_bits = pixman_image_get_data (src);
+ src_stride = pixman_image_get_stride (src);
+ src_width = pixman_image_get_width (src);
+ src_height = pixman_image_get_height (src);
+
+ /* Clip source */
+ if (src_x < 0) {
+ width += src_x;
+ dest_x -= src_x;
+ src_x = 0;
+ }
+ if (src_y < 0) {
+ height += src_y;
+ dest_y -= src_y;
+ src_y = 0;
+ }
+ if (src_x + width > src_width) {
+ width = src_width - src_x;
+ }
+ if (src_y + height > src_height) {
+ height = src_height - src_y;
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ ASSERT(src_x >= 0);
+ ASSERT(src_y >= 0);
+ ASSERT(dest_x >= 0);
+ ASSERT(dest_y >= 0);
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ ASSERT(dest_x + width <= pixman_image_get_width (dest));
+ ASSERT(dest_y + height <= pixman_image_get_height (dest));
+ ASSERT(src_x + width <= pixman_image_get_width (src));
+ ASSERT(src_y + height <= pixman_image_get_height (src));
+ ASSERT(depth == pixman_image_get_depth (src));
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
+
+ while (height--) {
+ uint8_t *d = (uint8_t *)byte_line;
+ uint8_t *s = (uint8_t *)byte_line;
+
+ s = (uint8_t *)src_line;
+ for (x = 0; x < width; x++) {
+ uint8_t val = *s;
+ if (val != (uint8_t)transparent_color) {
+ *d = val;
+ }
+ s++; d++;
+ }
+
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
+
+ while (height--) {
+ uint16_t *d = (uint16_t *)byte_line;
+ uint16_t *s = (uint16_t *)byte_line;
+
+ s = (uint16_t *)src_line;
+ for (x = 0; x < width; x++) {
+ uint16_t val = *s;
+ if (val != (uint16_t)transparent_color) {
+ *d = val;
+ }
+ s++; d++;
+ }
+
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else {
+ ASSERT (depth == 32 || depth == 24);
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
+
+ while (height--) {
+ uint32_t *d = (uint32_t *)byte_line;
+ uint32_t *s = (uint32_t *)byte_line;
+
+ s = (uint32_t *)src_line;
+ for (x = 0; x < width; x++) {
+ uint32_t val = *s;
+ if (val != (0xffffff & transparent_color)) {
+ *d = val;
+ }
+ s++; d++;
+ }
+
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ }
+}
+
+static void copy_bits_up(uint8_t *data, const int stride,
+ const int src_x, const int src_y,
+ const int width, const int height,
+ const int dest_x, const int dest_y)
+{
+ uint8_t *src = data + src_y * stride + src_x * sizeof(uint32_t);
+ uint8_t *dest = data + dest_y * stride + dest_x * sizeof(uint32_t);
+ uint8_t *end = dest + height * stride;
+ for (; dest != end; dest += stride, src += stride) {
+ memcpy(dest, src, width * sizeof(uint32_t));
+ }
+}
+
+static void copy_bits_down(uint8_t *data, const int stride,
+ const int src_x, const int src_y,
+ const int width, const int height,
+ const int dest_x, const int dest_y)
+{
+ uint8_t *src = data + (src_y + height - 1) * stride + src_x * sizeof(uint32_t);
+ uint8_t *end = data + (dest_y - 1) * stride + dest_x * sizeof(uint32_t);
+ uint8_t *dest = end + height * stride;
+
+ for (; dest != end; dest -= stride, src -= stride) {
+ memcpy(dest, src, width * sizeof(uint32_t));
+ }
+}
+
+static void copy_bits_same_line(uint8_t *data, const int stride,
+ const int src_x, const int src_y,
+ const int width, const int height,
+ const int dest_x, const int dest_y)
+{
+ uint8_t *src = data + src_y * stride + src_x * sizeof(uint32_t);
+ uint8_t *dest = data + dest_y * stride + dest_x * sizeof(uint32_t);
+ uint8_t *end = dest + height * stride;
+ for (; dest != end; dest += stride, src += stride) {
+ memmove(dest, src, width * sizeof(uint32_t));
+ }
+}
+
+void spice_pixman_copy_rect (pixman_image_t *image,
+ int src_x, int src_y,
+ int width, int height,
+ int dest_x, int dest_y)
+{
+ uint8_t *data;
+ int stride;
+
+ data = (uint8_t *)pixman_image_get_data(image);
+ stride = pixman_image_get_stride(image);
+
+ ASSERT(pixman_image_get_depth (image) == 24 ||
+ pixman_image_get_depth (image) == 32);
+
+ if (dest_y > src_y) {
+ copy_bits_down(data, stride,
+ src_x, src_y,
+ width, height,
+ dest_x, dest_y);
+ } else if (dest_y < src_y) {
+ copy_bits_up(data, stride,
+ src_x, src_y,
+ width, height,
+ dest_x, dest_y);
+ } else {
+ copy_bits_same_line(data, stride,
+ src_x, src_y,
+ width, height,
+ dest_x, dest_y);
+ }
+}
+
+pixman_bool_t
+spice_pixman_region32_init_rects (pixman_region32_t *region,
+ const SpiceRect *rects,
+ int count)
+{
+ pixman_box32_t boxes_array[10];
+ pixman_box32_t *boxes;
+ pixman_bool_t res;
+ int i;
+
+ if (count < 10)
+ boxes = boxes_array;
+ else {
+ boxes = (pixman_box32_t *)malloc (sizeof(pixman_box32_t) * count);
+ if (boxes == NULL)
+ return FALSE;
+ }
+
+ for (i = 0; i < count; i++) {
+ boxes[i].x1 = rects[i].left;
+ boxes[i].y1 = rects[i].top;
+ boxes[i].x2 = rects[i].right;
+ boxes[i].y2 = rects[i].bottom;
+ }
+
+ res = pixman_region32_init_rects (region,
+ boxes,
+ count);
+
+ if (count >= 10)
+ free (boxes);
+
+ return res;
+}
diff --git a/common/pixman_utils.h b/common/pixman_utils.h
new file mode 100644
index 0000000..933cd8f
--- /dev/null
+++ b/common/pixman_utils.h
@@ -0,0 +1,112 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H__PIXMAN_UTILS
+#define _H__PIXMAN_UTILS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <pixman.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <spice/draw.h>
+
+/* This lists all possible 2 argument binary raster ops.
+ * This enum has the same values as the X11 GXcopy type
+ * and same as the GL constants (GL_AND etc) if you
+ * or it with 0x1500. However it is not exactly the
+ * same as the win32 ROP2 type (they use another order).
+ */
+typedef enum {
+ SPICE_ROP_CLEAR, /* 0x0 0 */
+ SPICE_ROP_AND, /* 0x1 src AND dst */
+ SPICE_ROP_AND_REVERSE, /* 0x2 src AND NOT dst */
+ SPICE_ROP_COPY, /* 0x3 src */
+ SPICE_ROP_AND_INVERTED, /* 0x4 (NOT src) AND dst */
+ SPICE_ROP_NOOP, /* 0x5 dst */
+ SPICE_ROP_XOR, /* 0x6 src XOR dst */
+ SPICE_ROP_OR, /* 0x7 src OR dst */
+ SPICE_ROP_NOR, /* 0x8 (NOT src) AND (NOT dst) */
+ SPICE_ROP_EQUIV, /* 0x9 (NOT src) XOR dst */
+ SPICE_ROP_INVERT, /* 0xa NOT dst */
+ SPICE_ROP_OR_REVERSE, /* 0xb src OR (NOT dst) */
+ SPICE_ROP_COPY_INVERTED, /* 0xc NOT src */
+ SPICE_ROP_OR_INVERTED, /* 0xd (NOT src) OR dst */
+ SPICE_ROP_NAND, /* 0xe (NOT src) OR (NOT dst) */
+ SPICE_ROP_SET /* 0xf 1 */
+} SpiceROP;
+
+
+void spice_pixman_region32_init_from_bitmap (pixman_region32_t *region,
+ uint32_t *data,
+ int width, int height,
+ int stride);
+pixman_bool_t spice_pixman_region32_init_rects (pixman_region32_t *region,
+ const SpiceRect *rects,
+ int count);
+
+void spice_pixman_fill_rect (pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ uint32_t value);
+void spice_pixman_fill_rect_rop (pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ uint32_t value,
+ SpiceROP rop);
+void spice_pixman_tile_rect (pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y);
+void spice_pixman_tile_rect_rop (pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y,
+ SpiceROP rop);
+void spice_pixman_blit (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int w, int h);
+void spice_pixman_blit_rop (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int w, int h,
+ SpiceROP rop);
+void spice_pixman_blit_colorkey (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ uint32_t transparent_color);
+void spice_pixman_copy_rect (pixman_image_t *image,
+ int src_x, int src_y,
+ int w, int h,
+ int dest_x, int dest_y);
+
+#endif /* _H__PIXMAN_UTILS */
diff --git a/server/Makefile.am b/server/Makefile.am
index 03f15a3..b2bea00 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -20,6 +20,7 @@ INCLUDES = \
COMMON_SRCS = \
$(top_srcdir)/common/cairo_canvas.c \
+ $(top_srcdir)/common/pixman_utils.c \
$(top_srcdir)/common/gl_canvas.c \
$(top_srcdir)/common/region.c \
$(top_srcdir)/common/glc.c \
--
1.6.6
More information about the Spice-devel
mailing list