Acked-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> On Wed, May 11, 2016 at 03:47:56PM +0200, Pavel Grunt wrote: > It is not needed since spice-server commit > c5c176a5c7718177f23b07981556b5d460627498 > --- > v2: removed usage of GL_CANVAS > --- > common/Makefile.am | 12 - > common/canvas_base.c | 41 +- > common/gl_canvas.c | 911 ------------------------------ > common/gl_canvas.h | 45 -- > common/gl_utils.h | 59 -- > common/glc.c | 1510 -------------------------------------------------- > common/glc.h | 164 ------ > common/ogl_ctx.c | 249 --------- > common/ogl_ctx.h | 36 -- > configure.ac | 5 +- > m4/spice-deps.m4 | 31 -- > 11 files changed, 6 insertions(+), 3057 deletions(-) > delete mode 100644 common/gl_canvas.c > delete mode 100644 common/gl_canvas.h > delete mode 100644 common/gl_utils.h > delete mode 100644 common/glc.c > delete mode 100644 common/glc.h > delete mode 100644 common/ogl_ctx.c > delete mode 100644 common/ogl_ctx.h > > diff --git a/common/Makefile.am b/common/Makefile.am > index 89809ac..2dd56f3 100644 > --- a/common/Makefile.am > +++ b/common/Makefile.am > @@ -79,16 +79,6 @@ libspice_common_server_la_SOURCES = \ > > libspice_common_server_la_CFLAGS = -DFIXME_SERVER_SMARTCARD > > -if HAVE_GL > -libspice_common_la_SOURCES += \ > - gl_utils.h \ > - glc.c \ > - glc.h \ > - ogl_ctx.c \ > - ogl_ctx.h \ > - $(NULL) > -endif > - > AM_CPPFLAGS = \ > -I$(top_srcdir) \ > $(SPICE_COMMON_CFLAGS) \ > @@ -140,8 +130,6 @@ EXTRA_DIST = \ > canvas_base.h \ > gdi_canvas.c \ > gdi_canvas.h \ > - gl_canvas.c \ > - gl_canvas.h \ > lz_compress_tmpl.c \ > lz_decompress_tmpl.c \ > quic_family_tmpl.c \ > diff --git a/common/canvas_base.c b/common/canvas_base.c > index cf36257..3f9e055 100644 > --- a/common/canvas_base.c > +++ b/common/canvas_base.c > @@ -1443,11 +1443,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b > > dest_stride = pixman_image_get_stride(surface); > dest_line = (uint8_t *)pixman_image_get_data(surface); > -#if defined(GL_CANVAS) > - if ((bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) { > -#else > if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) { > -#endif > spice_return_val_if_fail(bitmap->y > 0, NULL); > dest_line += dest_stride * ((int)bitmap->y - 1); > dest_stride = -dest_stride; > @@ -1455,7 +1451,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b > > if (invers) { > switch (bitmap->format) { > -#if defined(GL_CANVAS) || defined(GDI_CANVAS) > +#if defined(GDI_CANVAS) > case SPICE_BITMAP_FMT_1BIT_BE: > #else > case SPICE_BITMAP_FMT_1BIT_LE: > @@ -1469,7 +1465,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b > } > } > break; > -#if defined(GL_CANVAS) || defined(GDI_CANVAS) > +#if defined(GDI_CANVAS) > case SPICE_BITMAP_FMT_1BIT_LE: > #else > case SPICE_BITMAP_FMT_1BIT_BE: > @@ -1492,7 +1488,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b > } > } else { > switch (bitmap->format) { > -#if defined(GL_CANVAS) || defined(GDI_CANVAS) > +#if defined(GDI_CANVAS) > case SPICE_BITMAP_FMT_1BIT_BE: > #else > case SPICE_BITMAP_FMT_1BIT_LE: > @@ -1501,7 +1497,7 @@ static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* b > memcpy(dest_line, src_line, line_size); > } > break; > -#if defined(GL_CANVAS) || defined(GDI_CANVAS) > +#if defined(GDI_CANVAS) > case SPICE_BITMAP_FMT_1BIT_LE: > #else > case SPICE_BITMAP_FMT_1BIT_BE: > @@ -1627,28 +1623,6 @@ static inline void canvas_raster_glyph_box(const SpiceRasterGlyph *glyph, SpiceR > r->right = r->left + glyph->width; > } > > -#ifdef GL_CANVAS > -static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n) > -{ > - uint8_t mask; > - int now; > - > - dest = dest + (offset >> 3); > - offset &= 0x07; > - now = MIN(8 - offset, n); > - > - mask = ~((1 << (8 - now)) - 1); > - mask >>= offset; > - *dest = ((val >> offset) & mask) | *dest; > - > - if ((n = n - now)) { > - mask = ~((1 << (8 - n)) - 1); > - dest++; > - *dest = ((val << now) & mask) | *dest; > - } > -} > - > -#else > static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n) > { > uint8_t mask; > @@ -1671,8 +1645,6 @@ static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int > } > } > > -#endif > - > static inline void canvas_put_bits(uint8_t *dest, int dest_offset, uint8_t *src, int n) > { > while (n) { > @@ -1792,12 +1764,7 @@ static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, > dest_stride = pixman_image_get_stride(str_mask); > for (i = 0; i < str->length; i++) { > glyph = str->glyphs[i]; > -#if defined(GL_CANVAS) > - canvas_put_glyph_bits(glyph, bpp, dest + (bounds.bottom - bounds.top - 1) * dest_stride, > - -dest_stride, &bounds); > -#else > canvas_put_glyph_bits(glyph, bpp, dest, dest_stride, &bounds); > -#endif > } > > pos->x = bounds.left; > diff --git a/common/gl_canvas.c b/common/gl_canvas.c > deleted file mode 100644 > index 5ffb47b..0000000 > --- a/common/gl_canvas.c > +++ /dev/null > @@ -1,911 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, see <http://www.gnu.org/licenses/>. > -*/ > -#ifdef HAVE_CONFIG_H > -#include <config.h> > -#endif > - > -#include <stdio.h> > -#include <stdlib.h> > -#include <string.h> > - > -#include "gl_canvas.h" > -#include "quic.h" > -#include "rop3.h" > -#include "region.h" > -#include "glc.h" > - > -#define GL_CANVAS > -#include "canvas_base.c" > - > -typedef struct GLCanvas GLCanvas; > - > -struct GLCanvas { > - CanvasBase base; > - GLCCtx glc; > - 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) > -{ > - uint8_t *ret_data = (uint8_t *)data; > - uint8_t *dest; > - uint8_t *src; > - int i; > - > - if (!canvas->private_data) { > - canvas->private_data = spice_malloc_n(height, stride); > - if (!canvas->private_data) { > - return ret_data; > - } > - canvas->private_data_size = stride * height; > - } > - > - if (canvas->private_data_size < (stride * height)) { > - free(canvas->private_data); > - canvas->private_data = spice_malloc_n(height, stride); > - if (!canvas->private_data) { > - return ret_data; > - } > - canvas->private_data_size = stride * height; > - } > - > - dest = (uint8_t *)canvas->private_data; > - src = (uint8_t *)data + (height - 1) * stride; > - > - for (i = 0; i < height; ++i) { > - memcpy(dest, src, stride); > - dest += stride; > - src -= stride; > - } > - return (uint8_t *)canvas->private_data; > -} > - > -static pixman_image_t *canvas_surf_to_trans_surf(GLCImage *image, > - uint32_t trans_color) > -{ > - int width = image->width; > - int height = image->height; > - uint8_t *src_line; > - uint8_t *end_src_line; > - int src_stride; > - uint8_t *dest_line; > - int dest_stride; > - pixman_image_t *ret; > - int i; > - > - ret = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0); > - if (ret == NULL) { > - spice_critical("create surface failed"); > - return NULL; > - } > - > - src_line = image->pixels; > - src_stride = image->stride; > - end_src_line = src_line + src_stride * height; > - > - dest_line = (uint8_t *)pixman_image_get_data(ret); > - dest_stride = pixman_image_get_stride(ret); > - > - for (; src_line < end_src_line; src_line += src_stride, dest_line += dest_stride) { > - for (i = 0; i < width; i++) { > - if ((((uint32_t*)src_line)[i] & 0x00ffffff) == trans_color) { > - ((uint32_t*)dest_line)[i] = 0; > - } else { > - ((uint32_t*)dest_line)[i] = (((uint32_t*)src_line)[i]) | 0xff000000; > - } > - } > - } > - > - return ret; > -} > - > -static GLCPath get_path(GLCanvas *canvas, SpicePath *s) > -{ > - GLCPath path = glc_path_create(canvas->glc); > - int i; > - > - for (i = 0; i < s->num_segments; i++) { > - SpicePathSeg* seg = s->segments[i]; > - SpicePointFix* point = seg->points; > - SpicePointFix* end_point = point + seg->count; > - > - if (seg->flags & SPICE_PATH_BEGIN) { > - glc_path_move_to(path, fix_to_double(point->x), fix_to_double(point->y)); > - point++; > - } > - > - if (seg->flags & SPICE_PATH_BEZIER) { > - spice_return_val_if_fail((point - end_point) % 3 == 0, path); > - for (; point + 2 < end_point; point += 3) { > - glc_path_curve_to(path, > - fix_to_double(point[0].x), fix_to_double(point[0].y), > - fix_to_double(point[1].x), fix_to_double(point[1].y), > - fix_to_double(point[2].x), fix_to_double(point[2].y)); > - } > - } else { > - for (; point < end_point; point++) { > - glc_path_line_to(path, fix_to_double(point->x), fix_to_double(point->y)); > - } > - } > - if (seg->flags & SPICE_PATH_END) { > - if (seg->flags & SPICE_PATH_CLOSE) { > - glc_path_close(path); > - } > - } > - } > - > - return path; > -} > - > -#define SET_GLC_RECT(dest, src) { \ > - (dest)->x = (src)->left; \ > - (dest)->y = (src)->top; \ > - (dest)->width = (src)->right - (src)->left; \ > - (dest)->height = (src)->bottom - (src)->top; \ > -} > - > -#define SET_GLC_BOX(dest, src) { \ > - (dest)->x = (src)->x1; \ > - (dest)->y = (src)->y1; \ > - (dest)->width = (src)->x2 - (src)->x1; \ > - (dest)->height = (src)->y2 - (src)->y1; \ > -} > - > -static void set_clip(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip) > -{ > - GLCRect rect; > - glc_clip_reset(canvas->glc); > - > - switch (clip->type) { > - case SPICE_CLIP_TYPE_NONE: > - break; > - case SPICE_CLIP_TYPE_RECTS: { > - uint32_t n = clip->rects->num_rects; > - SpiceRect *now = clip->rects->rects; > - SpiceRect *end = now + n; > - > - if (n == 0) { > - rect.x = rect.y = 0; > - rect.width = rect.height = 0; > - glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET); > - break; > - } else { > - SET_GLC_RECT(&rect, now); > - glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET); > - } > - > - for (now++; now < end; now++) { > - SET_GLC_RECT(&rect, now); > - glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR); > - } > - break; > - } > - default: > - spice_warn_if_reached(); > - return; > - } > -} > - > -static void set_mask(GLCanvas *canvas, SpiceQMask *mask, int x, int y) > -{ > - pixman_image_t *image; > - > - if (!mask->bitmap || > - !(image = canvas_get_mask(&canvas->base, mask, NULL))) { > - glc_clear_mask(canvas->glc, GLC_MASK_A); > - return; > - } > - > - > - glc_set_mask(canvas->glc, x - mask->pos.x, y - mask->pos.y, > - pixman_image_get_width(image), > - pixman_image_get_height(image), > - pixman_image_get_stride(image), > - (uint8_t *)pixman_image_get_data(image), GLC_MASK_A); > -} > - > -static inline void surface_to_image(GLCanvas *canvas, pixman_image_t *surface, GLCImage *image, > - int ignore_stride) > -{ > - int depth = pixman_image_get_depth(surface); > - > - spice_return_if_fail(depth == 32 || depth == 24); > - image->format = (depth == 24) ? GLC_IMAGE_RGB32 : GLC_IMAGE_ARGB32; > - image->width = pixman_image_get_width(surface); > - image->height = pixman_image_get_height(surface); > - image->stride = pixman_image_get_stride(surface); > - image->pixels = (uint8_t *)pixman_image_get_data(surface); > - image->pallet = NULL; > - if (ignore_stride) { > - return; > - } > - if (image->stride < 0) { > - image->stride = -image->stride; > - image->pixels = image->pixels - (image->height - 1) * image->stride; > - } else { > - image->pixels = copy_opposite_image(canvas, image->pixels, image->stride, image->height); > - } > -} > - > -static void set_brush(GLCanvas *canvas, SpiceBrush *brush) > -{ > - switch (brush->type) { > - case SPICE_BRUSH_TYPE_SOLID: { > - uint32_t color = brush->u.color; > - double r, g, b; > - > - b = (double)(color & canvas->base.color_mask) / canvas->base.color_mask; > - color >>= canvas->base.color_shift; > - g = (double)(color & canvas->base.color_mask) / canvas->base.color_mask; > - color >>= canvas->base.color_shift; > - r = (double)(color & canvas->base.color_mask) / canvas->base.color_mask; > - glc_set_rgb(canvas->glc, r, g, b); > - break; > - } > - case SPICE_BRUSH_TYPE_PATTERN: { > - GLCImage image; > - GLCPattern pattern; > - pixman_image_t *surface; > - > - surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE); > - surface_to_image(canvas, surface, &image, 0); > - > - pattern = glc_pattern_create(canvas->glc, -brush->u.pattern.pos.x, > - -brush->u.pattern.pos.y, &image); > - > - glc_set_pattern(canvas->glc, pattern); > - glc_pattern_destroy(pattern); > - pixman_image_unref (surface); > - } > - case SPICE_BRUSH_TYPE_NONE: > - return; > - default: > - spice_warn_if_reached(); > - return; > - } > -} > - > -static void set_op(GLCanvas *canvas, uint16_t rop_decriptor) > -{ > - GLCOp op; > - > - switch (rop_decriptor) { > - case SPICE_ROPD_OP_PUT: > - op = GLC_OP_COPY; > - break; > - case SPICE_ROPD_OP_XOR: > - op = GLC_OP_XOR; > - break; > - case SPICE_ROPD_OP_BLACKNESS: > - op = GLC_OP_CLEAR; > - break; > - case SPICE_ROPD_OP_WHITENESS: > - op = GLC_OP_SET; > - break; > - case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_BRUSH: > - case SPICE_ROPD_OP_PUT | SPICE_ROPD_INVERS_SRC: > - op = GLC_OP_COPY_INVERTED; > - break; > - case SPICE_ROPD_OP_INVERS: > - op = GLC_OP_INVERT; > - break; > - case SPICE_ROPD_OP_AND: > - op = GLC_OP_AND; > - break; > - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES: > - op = GLC_OP_NAND; > - break; > - case SPICE_ROPD_OP_OR: > - op = GLC_OP_OR; > - break; > - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES: > - op = GLC_OP_NOR; > - break; > - case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES: > - op = GLC_OP_EQUIV; > - break; > - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_DEST: > - op = GLC_OP_AND_REVERSE; > - break; > - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_BRUSH: > - case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_SRC: > - op = GLC_OP_AND_INVERTED; > - break; > - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST: > - op = GLC_OP_OR_REVERSE; > - break; > - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH: > - case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_SRC: > - op = GLC_OP_OR_INVERTED; > - break; > - default: > - spice_warning("GLC_OP_NOOP"); > - op = GLC_OP_NOOP; > - } > - glc_set_op(canvas->glc, op); > -} > - > -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); > - set_brush(canvas, &fill->brush); > - set_op(canvas, fill->rop_descriptor); > - SET_GLC_RECT(&rect, bbox); > - > - glc_fill_rect(canvas->glc, &rect); > - glc_flush(canvas->glc); > -} > - > -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; > - GLCImage image; > - > - set_clip(canvas, bbox, clip); > - set_mask(canvas, ©->mask, bbox->left, bbox->top); > - set_op(canvas, copy->rop_descriptor); > - > - //todo: optimize get_image (use ogl conversion + remove unnecessary copy of 32bpp) > - surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE); > - surface_to_image(canvas, surface, &image, 0); > - SET_GLC_RECT(&dest, bbox); > - SET_GLC_RECT(&src, ©->src_area); > - image.format = GLC_IMAGE_RGB32; > - glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1); > - > - pixman_image_unref(surface); > - glc_flush(canvas->glc); > -} > - > -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; > - GLCRect fill_rect; > - GLCImage image; > - > - set_clip(canvas, bbox, clip); > - set_mask(canvas, &opaque->mask, bbox->left, bbox->top); > - > - glc_set_op(canvas->glc, (opaque->rop_descriptor & SPICE_ROPD_INVERS_SRC) ? GLC_OP_COPY_INVERTED : > - GLC_OP_COPY); > - surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE); > - surface_to_image(canvas, surface, &image, 0); > - SET_GLC_RECT(&dest, bbox); > - SET_GLC_RECT(&src, &opaque->src_area); > - glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1); > - pixman_image_unref(surface); > - > - set_brush(canvas, &opaque->brush); > - set_op(canvas, opaque->rop_descriptor & ~SPICE_ROPD_INVERS_SRC); > - SET_GLC_RECT(&fill_rect, bbox); > - glc_fill_rect(canvas->glc, &fill_rect); > - > - glc_flush(canvas->glc); > -} > - > -static void gl_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend *alpha_blend) > -{ > - GLCanvas *canvas = (GLCanvas *)spice_canvas; > - pixman_image_t *surface; > - GLCRecti src; > - GLCRecti dest; > - GLCImage image; > - > - set_clip(canvas, bbox, clip); > - glc_clear_mask(canvas->glc, GLC_MASK_A); > - glc_set_op(canvas->glc, GLC_OP_COPY); > - > - surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, FALSE); > - surface_to_image(canvas, surface, &image, 0); > - SET_GLC_RECT(&dest, bbox); > - SET_GLC_RECT(&src, &alpha_blend->src_area); > - glc_draw_image(canvas->glc, &dest, &src, &image, 0, (double)alpha_blend->alpha / 0xff); > - > - pixman_image_unref(surface); > - glc_flush(canvas->glc); > -} > - > -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; > - GLCImage image; > - > - set_clip(canvas, bbox, clip); > - set_mask(canvas, &blend->mask, bbox->left, bbox->top); > - set_op(canvas, blend->rop_descriptor); > - > - surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE); > - SET_GLC_RECT(&dest, bbox); > - SET_GLC_RECT(&src, &blend->src_area); > - surface_to_image(canvas, surface, &image, 0); > - glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1); > - > - pixman_image_unref(surface); > - glc_flush(canvas->glc); > -} > - > -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; > - GLCRecti src; > - GLCRecti dest; > - > - set_clip(canvas, bbox, clip); > - glc_clear_mask(canvas->glc, GLC_MASK_A); > - glc_set_op(canvas->glc, GLC_OP_COPY); > - > - surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE); > - surface_to_image(canvas, surface, &image, 0); > - > - trans_surf = canvas_surf_to_trans_surf(&image, transparent->true_color); > - pixman_image_unref(surface); > - > - surface_to_image(canvas, trans_surf, &image, 1); > - SET_GLC_RECT(&dest, bbox); > - SET_GLC_RECT(&src, &transparent->src_area); > - glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1); > - > - pixman_image_unref(trans_surf); > - glc_flush(canvas->glc); > -} > - > -static inline void fill_common(GLCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceQMask * mask, GLCOp op) > -{ > - GLCRect rect; > - > - set_clip(canvas, bbox, clip); > - set_mask(canvas, mask, bbox->left, bbox->top); > - glc_set_op(canvas->glc, op); > - SET_GLC_RECT(&rect, bbox); > - glc_fill_rect(canvas->glc, &rect); > -} > - > -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); > -} > - > -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); > -} > - > -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); > -} > - > -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; > - SpicePoint src_pos; > - uint8_t *data_opp; > - int src_stride; > - > - set_clip(canvas, bbox, clip); > - set_mask(canvas, &rop3->mask, bbox->left, bbox->top); > - > - glc_set_op(canvas->glc, GLC_OP_COPY); > - > - image.format = GLC_IMAGE_RGB32; > - image.width = bbox->right - bbox->left; > - image.height = bbox->bottom - bbox->top; > - > - image.pallet = NULL; > - > - d = pixman_image_create_bits(PIXMAN_x8r8g8b8, image.width, image.height, NULL, 0); > - if (d == NULL) { > - spice_critical("create surface failed"); > - return; > - } > - image.pixels = (uint8_t *)pixman_image_get_data(d); > - image.stride = pixman_image_get_stride(d); > - > - glc_read_pixels(canvas->glc, bbox->left, bbox->top, &image); > - data_opp = copy_opposite_image(canvas, image.pixels, > - image.stride, > - pixman_image_get_height(d)); > - memcpy(image.pixels, data_opp, > - image.stride * pixman_image_get_height(d)); > - > - s = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE); > - src_stride = pixman_image_get_stride(s); > - if (src_stride > 0) { > - data_opp = copy_opposite_image(canvas, (uint8_t *)pixman_image_get_data(s), > - src_stride, pixman_image_get_height(s)); > - memcpy((uint8_t *)pixman_image_get_data(s), data_opp, > - src_stride * pixman_image_get_height(s)); > - } > - > - if (!rect_is_same_size(bbox, &rop3->src_area)) { > - pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, image.width, > - image.height, rop3->scale_mode); > - pixman_image_unref(s); > - s = scaled_s; > - src_pos.x = 0; > - src_pos.y = 0; > - } else { > - src_pos.x = rop3->src_area.left; > - src_pos.y = rop3->src_area.top; > - } > - > - if (pixman_image_get_width(s) - src_pos.x < image.width || > - pixman_image_get_height(s) - src_pos.y < image.height) { > - spice_critical("bad src bitmap size"); > - return; > - } > - > - if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) { > - pixman_image_t *p = canvas_get_image(&canvas->base, rop3->brush.u.pattern.pat, FALSE); > - SpicePoint pat_pos; > - > - pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p); > - > - pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p); > - > - //for now (bottom-top) > - if (pat_pos.y < 0) { > - pat_pos.y = pixman_image_get_height(p) + pat_pos.y; > - } > - pat_pos.y = (image.height + pat_pos.y) % pixman_image_get_height(p); > - pat_pos.y = pixman_image_get_height(p) - pat_pos.y; > - > - do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos); > - pixman_image_unref(p); > - } else { > - uint32_t color = (canvas->base.color_shift) == 8 ? rop3->brush.u.color : > - canvas_16bpp_to_32bpp(rop3->brush.u.color); > - do_rop3_with_color(rop3->rop3, d, s, &src_pos, color); > - } > - > - pixman_image_unref(s); > - > - GLCRecti dest; > - GLCRecti src; > - dest.x = bbox->left; > - dest.y = bbox->top; > - > - image.pixels = copy_opposite_image(canvas, image.pixels, pixman_image_get_stride(d), > - pixman_image_get_height(d)); > - > - src.x = src.y = 0; > - dest.width = src.width = image.width; > - dest.height = src.height = image.height; > - glc_draw_image(canvas->glc, &dest, &src, &image, 0, 1); > - pixman_image_unref(d); > -} > - > -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); > - glc_clear_mask(canvas->glc, GLC_MASK_A); > - set_op(canvas, stroke->fore_mode); > - set_brush(canvas, &stroke->brush); > - > - if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) { > - spice_warning("SPICE_LINE_FLAGS_STYLED"); > - } > - glc_set_line_width(canvas->glc, 1.0); > - > - path = get_path(canvas, stroke->path); > - glc_stroke_path(canvas->glc, path); > - glc_path_destroy(path); > -} > - > -static void gl_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text) > -{ > - GLCanvas *canvas = (GLCanvas *)spice_canvas; > - GLCRect rect; > - SpiceString *str; > - > - set_clip(canvas, bbox, clip); > - glc_clear_mask(canvas->glc, GLC_MASK_A); > - > - if (!rect_is_empty(&text->back_area)) { > - set_brush(canvas, &text->back_brush); > - set_op(canvas, text->back_mode); > - SET_GLC_RECT(&rect, bbox); > - glc_fill_rect(canvas->glc, &rect); > - } > - > - str = (SpiceString *)SPICE_GET_ADDRESS(text->str); > - set_brush(canvas, &text->fore_brush); > - set_op(canvas, text->fore_mode); > - if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) { > - SpicePoint pos; > - pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 1, &pos); > - _glc_fill_mask(canvas->glc, pos.x, pos.y, > - pixman_image_get_width(mask), > - pixman_image_get_height(mask), > - pixman_image_get_stride(mask), > - (uint8_t *)pixman_image_get_data(mask)); > - pixman_image_unref(mask); > - } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) { > - SpicePoint pos; > - pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 4, &pos); > - glc_fill_alpha(canvas->glc, pos.x, pos.y, > - pixman_image_get_width(mask), > - pixman_image_get_height(mask), > - pixman_image_get_stride(mask), > - (uint8_t *)pixman_image_get_data(mask)); > - > - pixman_image_unref(mask); > - } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) { > - spice_warning("untested path A8 glyphs, doing nothing"); > - if (0) { > - SpicePoint pos; > - pixman_image_t *mask = canvas_get_str_mask(&canvas->base, str, 8, &pos); > - glc_fill_alpha(canvas->glc, pos.x, pos.y, > - pixman_image_get_width(mask), > - pixman_image_get_height(mask), > - pixman_image_get_stride(mask), > - (uint8_t *)pixman_image_get_data(mask)); > - pixman_image_unref(mask); > - } > - } else { > - spice_warning("untested path vector glyphs, doing nothing"); > - if (0) { > - //draw_vector_str(canvas, str, &text->fore_brush, text->fore_mode); > - } > - } > - glc_flush(canvas->glc); > -} > - > -static void gl_canvas_clear(SpiceCanvas *spice_canvas) > -{ > - GLCanvas *canvas = (GLCanvas *)spice_canvas; > - glc_clear(canvas->glc); > - glc_flush(canvas->glc); > -} > - > -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); > - glc_copy_pixels(canvas->glc, bbox->left, bbox->top, src_pos->x, src_pos->y, > - bbox->right - bbox->left, bbox->bottom - bbox->top); > -} > - > -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; > - > - spice_return_if_fail(dest_stride > 0); > - > - image.format = GLC_IMAGE_RGB32; > - image.height = area->bottom - area->top; > - image.width = area->right - area->left; > - image.pixels = dest; > - image.stride = dest_stride; > - glc_read_pixels(canvas->glc, area->left, area->top, &image); > -} > - > -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; > - pixman_box32_t *rects; > - > - canvas_base_group_start(spice_canvas, region); > - > - rects = pixman_region32_rectangles(region, &num_rect); > - > - glc_rects = spice_new(GLCRect, num_rect); > - now = glc_rects; > - end = glc_rects + num_rect; > - > - for (; now < end; now++, rects++) { > - SET_GLC_BOX(now, rects); > - } > - glc_mask_rects(canvas->glc, num_rect, glc_rects, GLC_MASK_B); > - > - free(glc_rects); > -} > - > -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; > - uint32_t i; > - > - spice_warn_if_fail(src_stride <= 0); > - > - glc_clip_reset(canvas->glc); > - > - if (clip) { > - int num_rects; > - pixman_box32_t *rects = pixman_region32_rectangles((pixman_region32_t *)clip, > - &num_rects); > - GLCRect rect; > - if (num_rects == 0) { > - rect.x = rect.y = rect.width = rect.height = 0; > - glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET); > - } else { > - SET_GLC_BOX(&rect, rects); > - glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_SET); > - for (i = 1; i < num_rects; i++) { > - SET_GLC_BOX(&rect, rects + i); > - glc_clip_rect(canvas->glc, &rect, GLC_CLIP_OP_OR); > - } > - } > - } > - > - SET_GLC_RECT(&gldest, dest); > - src.x = src.y = 0; > - src.width = src_width; > - src.height = src_height; > - > - image.format = GLC_IMAGE_RGB32; > - image.width = src_width; > - image.height = src_height; > - if (src_stride < 0) { > - src_stride = -src_stride; > - image.pixels = (uint8_t *)src_data - (src_height - 1) * src_stride; > - } else { > - image.pixels = (uint8_t *)src_data; > - } > - image.stride = src_stride; > - image.pallet = NULL; > - glc_draw_image(canvas->glc, &gldest, &src, &image, 0, 1); > - > - glc_flush(canvas->glc); > -} > - > -static void gl_canvas_group_end(SpiceCanvas *spice_canvas) > -{ > - GLCanvas *canvas = (GLCanvas *)spice_canvas; > - > - canvas_base_group_end(spice_canvas); > - glc_clear_mask(canvas->glc, GLC_MASK_B); > -} > - > -static int need_init = 1; > -static SpiceCanvasOps gl_canvas_ops; > - > -SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format > - , SpiceImageCache *bits_cache > -#ifdef SW_CANVAS_CACHE > - , SpicePaletteCache *palette_cache > -#endif > - , SpiceImageSurfaces *surfaces > - , SpiceGlzDecoder *glz_decoder > - , SpiceJpegDecoder *jpeg_decoder > - , SpiceZlibDecoder *zlib_decoder > - ) > -{ > - GLCanvas *canvas; > - int init_ok; > - > - if (need_init) { > - return NULL; > - } > - canvas = spice_new0(GLCanvas, 1); > - > - if (!(canvas->glc = glc_create(width, height))) { > - goto error_1; > - } > - canvas->private_data = NULL; > - init_ok = canvas_base_init(&canvas->base, &gl_canvas_ops, > - width, height, format > - , bits_cache > -#ifdef SW_CANVAS_CACHE > - , palette_cache > -#endif > - , surfaces > - , glz_decoder > - , jpeg_decoder > - , zlib_decoder > - ); > - if (!init_ok) { > - goto error_2; > - } > - > - return (SpiceCanvas *)canvas; > - > -error_2: > - glc_destroy(canvas->glc, 0); > -error_1: > - free(canvas); > - > - return NULL; > -} > - > -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, canvas->textures_lost); > - free(canvas->private_data); > - free(canvas); > -} > - > -void gl_canvas_init(void) //unsafe global function > -{ > - if (!need_init) { > - 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.destroy = gl_canvas_destroy; > -} > diff --git a/common/gl_canvas.h b/common/gl_canvas.h > deleted file mode 100644 > index 42c9e5a..0000000 > --- a/common/gl_canvas.h > +++ /dev/null > @@ -1,45 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, see <http://www.gnu.org/licenses/>. > -*/ > - > -#ifndef _H__GL_CANVAS > -#define _H__GL_CANVAS > - > -#include <spice/macros.h> > - > -#include "glc.h" > -#include "canvas_base.h" > -#include "region.h" > - > -SPICE_BEGIN_DECLS > - > -SpiceCanvas *gl_canvas_create(int width, int height, uint32_t format > - , SpiceImageCache *bits_cache > -#ifdef SW_CANVAS_CACHE > - , SpicePaletteCache *palette_cache > -#endif > - , SpiceImageSurfaces *surfaces > - , SpiceGlzDecoder *glz_decoder > - , SpiceJpegDecoder *jpeg_decoder > - , SpiceZlibDecoder *zlib_decoder > - ); > -void gl_canvas_set_textures_lost(SpiceCanvas *canvas, int textures_lost); > -void gl_canvas_init(void); > - > -SPICE_END_DECLS > - > -#endif > diff --git a/common/gl_utils.h b/common/gl_utils.h > deleted file mode 100644 > index b6cc6ce..0000000 > --- a/common/gl_utils.h > +++ /dev/null > @@ -1,59 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, write to the Free Software > - > - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > -*/ > - > -#ifndef GL_UTILS_H > -#define GL_UTILS_H > - > -#include "spice_common.h" > - > -SPICE_BEGIN_DECLS > - > -#ifdef RED_DEBUG > -#define GLC_ERROR_TEST_FLUSH { \ > - GLenum gl_err; glFlush(); \ > - if ((gl_err = glGetError()) != GL_NO_ERROR) { \ > - printf("%s[%d]: opengl error: %s\n", __FUNCTION__, __LINE__, \ > - gluErrorString(gl_err)); \ > - spice_abort(); \ > - } \ > -} > - > -#define GLC_ERROR_TEST_FINISH { \ > - GLenum gl_err; glFinish(); \ > - if ((gl_err = glGetError()) != GL_NO_ERROR) { \ > - printf("%s[%d]: opengl error: %s\n", __FUNCTION__, __LINE__, \ > - gluErrorString(gl_err)); \ > - spice_abort(); \ > - } \ > -} > -#else > -#define GLC_ERROR_TEST_FLUSH ; > - > -#define GLC_ERROR_TEST_FINISH ; > -#endif > - > -#include "bitops.h" > - > -#define find_msb spice_bit_find_msb > -#define gl_get_to_power_two spice_bit_next_pow2 > - > -SPICE_END_DECLS > - > -#endif > diff --git a/common/glc.c b/common/glc.c > deleted file mode 100644 > index a792e55..0000000 > --- a/common/glc.c > +++ /dev/null > @@ -1,1510 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, write to the Free Software > - > - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > -*/ > -#ifdef HAVE_CONFIG_H > -#include <config.h> > -#endif > -#include "spice_common.h" > - > -#include <string.h> > -#include <math.h> > - > -#include <GL/gl.h> > -#include <GL/glu.h> > -#include <GL/glext.h> > - > -#ifdef WIN32 > -#include "glext.h" > -#include "wglext.h" > -#endif > - > -#include "mem.h" > -#include "glc.h" > -#include "gl_utils.h" > - > -#define TESS_VERTEX_ALLOC_BUNCH 20 > - > -typedef struct InternaCtx InternaCtx; > -typedef struct InternalPat { > - InternaCtx *owner; > - int refs; > - GLuint texture; > - int x_orign; > - int y_orign; > - int width; > - int height; > -} InternalPat; > - > -typedef struct Pathpath { > - int start_point; > - int num_segments; > -} Path; > - > -enum { > - GLC_PATH_SEG_LINES, > - GLC_PATH_SEG_BEIZER, > -}; > - > -//todo: flatten cache > -typedef struct PathSegment { > - int type; > - int count; > -} PathSegment; > - > -typedef struct PathPoint { > - double x; > - double y; > - double z; > -} PathPoint; > - > -typedef GLdouble Vertex[3]; > - > -typedef struct InternalPath { > - InternaCtx *owner; > - > - Path *paths; > - int paths_size; > - int paths_pos; > - > - PathSegment *segments; > - int segments_size; > - int segments_pos; > - > - PathPoint *points; > - int points_size; > - int points_pos; > - > - Path *current_path; > - PathSegment *current_segment; > -} InternalPath; > - > -typedef struct TassVertex TassVertex; > -struct TassVertex { > - PathPoint point; > - TassVertex *list_link; > - TassVertex *next; > -}; > - > -typedef struct TassVertexBuf TassVertexBuf; > -struct TassVertexBuf { > - TassVertexBuf *next; > - TassVertex vertexs[0]; > -}; > - > -#define USE_LINE_ANTIALIAS 0 > - > -typedef struct LineDash { > - double *dashes; > - int num_dashes; > - double offset; > - int cur_dash; > - double dash_pos; > -} LineDash; > - > -enum { > - GLC_STROKE_NONACTIVE, > - GLC_STROKE_FIRST, > - GLC_STROKE_ACTIVE, > -}; > - > -typedef struct PathStroke { > - double x; > - double y; > - int state; > -} PathStroke; > - > -struct InternaCtx { > - int draw_mode; > - int stencil_refs; > - int stencil_mask; > - int width; > - int height; > - GLfloat line_width; > - LineDash line_dash; > - PathStroke path_stroke; > - InternalPat *pat; > - int max_texture_size; > - GLUtesselator* tesselator; > - TassVertex *free_tess_vertex; > - TassVertex *used_tess_vertex; > - TassVertexBuf *vertex_bufs; > - int private_tex_width; > - int private_tex_height; > - GLuint private_tex; > -#ifdef WIN32 > - PFNGLBLENDEQUATIONPROC glBlendEquation; > -#endif > -}; > - > -#define Y(y) -(y) > -#define VERTEX2(x, y) glVertex2d(x, Y(y)) > - > -static void fill_rect(InternaCtx *ctx, void *rect); > -static void fill_path(InternaCtx *ctx, void *path); > -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, int stride, > - const uint8_t *bitmap); > -static void set_pat(InternaCtx *ctx, InternalPat *pat); > - > -static inline void set_raster_pos(InternaCtx *ctx, int x, int y) > -{ > - if (x >= 0 && y >= 0 && x < ctx->width && y < ctx->height) { > - glRasterPos2i(x, Y(y)); > - return; > - } > - glRasterPos2i(0, 0); > - glBitmap(0, 0, 0, 0, (GLfloat)x, (GLfloat)Y(y), NULL); > -} > - > -static TassVertex *alloc_tess_vertex(InternaCtx *ctx) > -{ > - TassVertex *vertex; > - > - if (!ctx->free_tess_vertex) { > - TassVertexBuf *buf; > - int i; > - > - buf = (TassVertexBuf *)spice_malloc(sizeof(TassVertexBuf) + > - sizeof(TassVertex) * TESS_VERTEX_ALLOC_BUNCH); > - buf->next = ctx->vertex_bufs; > - ctx->vertex_bufs = buf; > - for (i = 0; i < TESS_VERTEX_ALLOC_BUNCH; i++) { > - buf->vertexs[i].point.z = 0; > - buf->vertexs[i].next = ctx->free_tess_vertex; > - ctx->free_tess_vertex = &buf->vertexs[i]; > - } > - } > - > - vertex = ctx->free_tess_vertex; > - ctx->free_tess_vertex = vertex->next; > - vertex->next = ctx->used_tess_vertex; > - ctx->used_tess_vertex = vertex; > - return vertex; > -} > - > -static void reset_tass_vertex(InternaCtx *ctx) > -{ > - TassVertex *vertex; > - while ((vertex = ctx->used_tess_vertex)) { > - ctx->used_tess_vertex = vertex->next; > - vertex->next = ctx->free_tess_vertex; > - ctx->free_tess_vertex = vertex; > - } > -} > - > -static void free_tass_vertex_bufs(InternaCtx *ctx) > -{ > - TassVertexBuf *buf; > - > - ctx->used_tess_vertex = NULL; > - ctx->free_tess_vertex = NULL; > - while ((buf = ctx->vertex_bufs)) { > - ctx->vertex_bufs = buf->next; > - free(buf); > - } > -} > - > -//naive bezier flattener > -static TassVertex *bezier_flattener(InternaCtx *ctx, PathPoint *points) > -{ > - double ax, bx, cx; > - double ay, by, cy; > - const int num_points = 30; > - double dt; > - int i; > - > - TassVertex *vertex_list = NULL; > - TassVertex *curr_vertex; > - > - for (i = 0; i < num_points - 2; i++) { > - TassVertex *vertex; > - > - vertex = alloc_tess_vertex(ctx); > - vertex->list_link = vertex_list; > - vertex_list = vertex; > - } > - > - curr_vertex = vertex_list; > - > - cx = 3.0 * (points[1].x - points[0].x); > - bx = 3.0 * (points[2].x - points[1].x) - cx; > - ax = points[3].x - points[0].x - cx - bx; > - > - cy = 3.0 * (points[1].y - points[0].y); > - by = 3.0 * (points[2].y - points[1].y) - cy; > - ay = points[3].y - points[0].y - cy - by; > - > - dt = 1.0 / (num_points - 1); > - > - for (i = 1; i < num_points - 1; i++, curr_vertex = curr_vertex->list_link) { > - double tSquared, tCubed; > - double t; > - t = i * dt; > - > - tSquared = t * t; > - tCubed = tSquared * t; > - > - curr_vertex->point.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + points[0].x; > - curr_vertex->point.y = (ay * tCubed) + (by * tSquared) + (cy * t) + points[0].y; > - } > - > - return vertex_list; > -} > - > -#define MORE_X(path, Type, name) { \ > - Type *name; \ > - \ > - name = spice_new0(Type, path->name##_size * 2); \ > - memcpy(name, path->name, sizeof(*name) * path->name##_size); \ > - free(path->name); \ > - path->name = name; \ > - path->name##_size *= 2; \ > -} > - > -static void more_points(InternalPath *path) > -{ > - MORE_X(path, PathPoint, points); > -} > - > -static void more_segments(InternalPath *path) > -{ > - MORE_X(path, PathSegment, segments); > -} > - > -static void more_paths(InternalPath *path) > -{ > - MORE_X(path, Path, paths); > -} > - > -static inline void put_point(InternalPath *path, double x, double y) > -{ > - path->points[path->points_pos].x = x; > - path->points[path->points_pos].y = Y(y + 0.5); > - path->points[path->points_pos++].z = 0; > -} > - > -void glc_path_move_to(GLCPath path, double x, double y) > -{ > - InternalPath *internal = (InternalPath *)path; > - > - spice_assert(internal); > - > - if (internal->current_segment) { > - internal->current_segment = NULL; > - internal->current_path = NULL; > - if (internal->points_pos == internal->points_size) { > - more_points(internal); > - } > - internal->points_pos++; > - } > - internal->points[internal->points_pos - 1].x = x; > - internal->points[internal->points_pos - 1].y = Y(y + 0.5); > - internal->points[internal->points_pos - 1].z = 0; > -} > - > -static void add_segment_common(InternalPath *internal, int type, int num_points) > -{ > - if (internal->points_size - internal->points_pos < num_points) { > - more_points(internal); > - } > - > - if (internal->current_segment) { > - if (internal->current_segment->type == type) { > - internal->current_segment->count++; > - return; > - } > - if (internal->segments_pos == internal->segments_size) { > - more_segments(internal); > - } > - internal->current_segment = &internal->segments[internal->segments_pos++]; > - internal->current_segment->type = type; > - internal->current_segment->count = 1; > - internal->current_path->num_segments++; > - return; > - } > - > - if (internal->paths_pos == internal->paths_size) { > - more_paths(internal); > - } > - > - if (internal->segments_pos == internal->segments_size) { > - more_segments(internal); > - } > - > - internal->current_path = &internal->paths[internal->paths_pos++]; > - internal->current_path->start_point = internal->points_pos - 1; > - internal->current_path->num_segments = 1; > - internal->current_segment = &internal->segments[internal->segments_pos++]; > - internal->current_segment->type = type; > - internal->current_segment->count = 1; > -} > - > -void glc_path_line_to(GLCPath path, double x, double y) > -{ > - InternalPath *internal = (InternalPath *)path; > - > - spice_assert(internal); > - > - add_segment_common(internal, GLC_PATH_SEG_LINES, 1); > - put_point(internal, x, y); > -} > - > -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y, > - double p3_x, double p3_y) > -{ > - InternalPath *internal = (InternalPath *)path; > - > - spice_assert(internal); > - > - add_segment_common(internal, GLC_PATH_SEG_BEIZER, 3); > - put_point(internal, p1_x, p1_y); > - put_point(internal, p2_x, p2_y); > - put_point(internal, p3_x, p3_y); > -} > - > -void glc_path_close(GLCPath path) > -{ > - InternalPath *internal = (InternalPath *)path; > - > - spice_assert(internal); > - if (!internal->current_path) { > - return; > - } > - PathPoint *end_point = &internal->points[internal->current_path->start_point]; > - glc_path_line_to(path, end_point->x, Y(end_point->y)); > - glc_path_move_to(path, end_point->x, Y(end_point->y)); > -} > - > -void glc_path_cleare(GLCPath path) > -{ > - InternalPath *internal = (InternalPath *)path; > - > - spice_assert(internal); > - internal->paths_pos = internal->segments_pos = 0; > - internal->current_segment = NULL; > - internal->current_path = NULL; > - > - internal->points[0].x = 0; > - internal->points[0].y = 0; > - internal->points_pos = 1; > -} > - > -GLCPath glc_path_create(GLCCtx glc) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - InternalPath *path; > - > - spice_assert(ctx); > - path = spice_new0(InternalPath, 1); > - path->paths_size = 2; > - path->paths = spice_new(Path, path->paths_size); > - > - path->segments_size = 4; > - path->segments = spice_new(PathSegment, path->segments_size); > - > - path->points_size = 20; > - path->points = spice_new(PathPoint, path->points_size); > - > - path->owner = ctx; > - path->points_pos = 1; > - return path; > -} > - > -void glc_path_destroy(GLCPath path) > -{ > - InternalPath *internal = (InternalPath *)path; > - > - if (!path) { > - return; > - } > - > - free(internal->points); > - free(internal->segments); > - free(internal->paths); > - free(internal); > -} > - > -static inline void unref_pat(InternalPat *pat) > -{ > - if (!pat) { > - return; > - } > - spice_assert(pat->refs > 0); > - if (--pat->refs == 0) { > - glFinish(); > - glDeleteTextures(1, &pat->texture); > - free(pat); > - } > - GLC_ERROR_TEST_FLUSH; > -} > - > -static inline InternalPat *ref_pat(InternalPat *pat) > -{ > - pat->refs++; > - return pat; > -} > - > -static void scale(uint32_t *dest, uint32_t dest_width, uint32_t dest_height, > - uint32_t *src, uint32_t src_width, uint32_t src_height, int src_stride) > -{ > - double x_scale = (double)src_width / dest_width; > - double y_scale = (double)src_height / dest_height; > - uint32_t i; > - uint32_t j; > - int prev_row = -1; > - > - for (i = 0; i < dest_height; i++) { > - int row = (int)(y_scale * i); > - if (row == prev_row) { > - memcpy(dest, dest - dest_width, dest_width * sizeof(uint32_t)); > - dest += dest_width; > - continue; > - } > - for (j = 0; j < dest_width; j++) { > - int col = (int)(x_scale * j); > - *(dest++) = *(src + col); > - } > - prev_row = row; > - src = (uint32_t *)((uint8_t *)src + src_stride); > - } > -} > - > -static inline void init_pattern(InternalPat *pat, int x_orign, int y_orign, const GLCImage *image) > -{ > - InternaCtx *ctx = pat->owner; > - uint32_t *tmp_pixmap = NULL; > - int width; > - int height; > - int width2; > - int height2; > - > - const int pix_bytes = 4; > - > - spice_assert(image->format == GLC_IMAGE_RGB32); //for now > - > - width = image->width; > - height = image->height; > - width2 = gl_get_to_power_two(width); > - height2 = gl_get_to_power_two(height); > - > - spice_assert(width > 0 && height > 0); > - spice_assert(width > 0 && width <= pat->owner->max_texture_size); > - spice_assert(height > 0 && height <= pat->owner->max_texture_size); > - > - if (width2 != width || height2 != height) { > - tmp_pixmap = (uint32_t *)spice_malloc(width2 * height2 * sizeof(uint32_t)); > - scale(tmp_pixmap, width2, height2, (uint32_t *)image->pixels, width, height, image->stride); > - } > - > - glBindTexture(GL_TEXTURE_2D, pat->texture); > - > - //glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); > - > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); > - > - if (tmp_pixmap) { > - glPixelStorei(GL_UNPACK_ROW_LENGTH, width2); > - glTexImage2D(GL_TEXTURE_2D, 0, 4, width2, height2, 0, GL_BGRA, GL_UNSIGNED_BYTE, > - tmp_pixmap); > - free(tmp_pixmap); > - } else { > - spice_assert(image->stride % pix_bytes == 0); > - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes); > - glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, > - image->pixels); > - } > - > - GLC_ERROR_TEST_FLUSH; > - pat->x_orign = x_orign % width; > - pat->y_orign = y_orign % height; > - pat->width = width; > - pat->height = height; > - > - if (ctx->pat == pat) { > - set_pat(pat->owner, pat); > - } else if (ctx->pat) { > - glBindTexture(GL_TEXTURE_2D, ctx->pat->texture); > - } > -} > - > -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - InternalPat *pat; > - > - spice_assert(ctx && image); > - > - pat = spice_new0(InternalPat, 1); > - pat->refs = 1; > - pat->owner = ctx; > - glGenTextures(1, &pat->texture); > - init_pattern(pat, x_orign, y_orign, image); > - return pat; > -} > - > -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image) > -{ > - InternalPat *pat = (InternalPat *)pattern; > - spice_assert(pat && pat->owner); > - > - glFinish(); > - init_pattern(pat, x_orign, y_orign, image); > -} > - > -void glc_pattern_destroy(GLCPattern pat) > -{ > - unref_pat((InternalPat *)pat); > - GLC_ERROR_TEST_FLUSH; > -} > - > -static void set_pat(InternaCtx *ctx, InternalPat *pat) > -{ > - pat = ref_pat(pat); > - unref_pat(ctx->pat); > - ctx->pat = pat; > - > - glEnable(GL_TEXTURE_2D); > - glBindTexture(GL_TEXTURE_2D, pat->texture); > - > - GLfloat s_gen_params[] = { (GLfloat)1.0 / pat->width, 0, 0, 0 }; > - GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / (GLfloat)pat->height, 0, 0 }; > - glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params); > - glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params); > - > - glMatrixMode(GL_TEXTURE); > - glLoadIdentity(); > - glTranslatef((float)pat->x_orign / pat->width, (float)Y(pat->y_orign) / pat->height, 0); > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_set_pattern(GLCCtx glc, GLCPattern pattern) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - InternalPat *pat = (InternalPat *)pattern; > - > - spice_assert(ctx && pat && pat->owner == ctx); > - set_pat(ctx, pat); > -} > - > -void glc_set_rgb(GLCCtx glc, double red, double green, double blue) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > - > - glDisable(GL_TEXTURE_2D); > - unref_pat(ctx->pat); > - ctx->pat = NULL; > - glColor4d(red, green, blue, 1); > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_set_op(GLCCtx glc, GLCOp op) > -{ > - if (op == GL_COPY) { > - glDisable(GL_COLOR_LOGIC_OP); > - return; > - } > - glLogicOp(op); > - glEnable(GL_COLOR_LOGIC_OP); > -} > - > -void glc_set_line_width(GLCCtx glc, double width) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > - ctx->line_width = (GLfloat)width; > - if (ctx->line_width > 0) { > - glLineWidth(ctx->line_width); > - } else { > - ctx->line_width = 0; > - } > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > - if (dashes && num_dashes >= 0 && offset >= 0) { > - ctx->line_dash.dashes = spice_new(double, num_dashes); > - memcpy(ctx->line_dash.dashes, dashes, sizeof(double) * num_dashes); > - ctx->line_dash.num_dashes = num_dashes; > - ctx->line_dash.offset = offset; > - ctx->line_dash.cur_dash = offset ? -1 : 0; > - ctx->line_dash.dash_pos = 0; > - } else { > - free(ctx->line_dash.dashes); > - memset(&ctx->line_dash, 0, sizeof(ctx->line_dash)); > - } > -} > - > -void glc_set_fill_mode(GLCCtx glc, GLCFillMode fill_mode) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > - int mode; > - switch (fill_mode) { > - case GLC_FILL_MODE_WINDING_ODD: > - mode = GLU_TESS_WINDING_ODD; > - break; > - case GLC_FILL_MODE_WINDING_NONZERO: > - mode = GLU_TESS_WINDING_NONZERO; > - break; > - default: > - //warn > - return; > - } > - gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, mode); > -} > - > -static inline void add_stencil_client(InternaCtx *ctx) > -{ > - if (!ctx->stencil_refs) { > - glEnable(GL_STENCIL_TEST); > - } > - ctx->stencil_refs++; > -} > - > -static inline void remove_stencil_client(InternaCtx *ctx) > -{ > - ctx->stencil_refs--; > - if (!ctx->stencil_refs) { > - glDisable(GL_STENCIL_TEST); > - } > -} > - > -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, > - int stride, const uint8_t *bitmap, GLCMaskID id) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08; > - spice_assert(ctx && bitmap); > - spice_assert(id == GLC_MASK_A || id == GLC_MASK_B); > - > - if (ctx->pat) { > - glDisable(GL_TEXTURE_2D); > - } > - > - glDisable(GL_BLEND); > - > - if (!(ctx->stencil_mask & mask)) { > - add_stencil_client(ctx); > - ctx->stencil_mask |= mask; > - } > - > - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); > - ctx->draw_mode = FALSE; > - glStencilMask(mask); > - glClear(GL_STENCIL_BUFFER_BIT); > - > - glStencilFunc(GL_ALWAYS, mask, mask); > - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); > - fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap); > -} > - > -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08; > - GLCRect *end; > - spice_assert(ctx && rects); > - spice_assert(id == GLC_MASK_A || id == GLC_MASK_B); > - > - if (ctx->pat) { > - glDisable(GL_TEXTURE_2D); > - } > - > - glDisable(GL_BLEND); > - > - if (!(ctx->stencil_mask & mask)) { > - add_stencil_client(ctx); > - ctx->stencil_mask |= mask; > - } > - > - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); > - ctx->draw_mode = FALSE; > - glStencilMask(mask); > - glClear(GL_STENCIL_BUFFER_BIT); > - > - glStencilFunc(GL_ALWAYS, mask, mask); > - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); > - end = rects + num_rect; > - for (; rects < end; rects++) { > - fill_rect(ctx, rects); > - } > -} > - > -void glc_clear_mask(GLCCtx glc, GLCMaskID id) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - uint32_t mask = (id == GLC_MASK_A) ? 0x04 : 0x08; > - spice_assert(ctx); > - spice_assert(id == GLC_MASK_A || id == GLC_MASK_B); > - > - if ((ctx->stencil_mask & mask)) { > - ctx->stencil_mask &= ~mask; > - remove_stencil_client(ctx); > - } > -} > - > -void glc_clip_reset(GLCCtx glc) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - if (!(ctx->stencil_mask & 0x03)) { > - return; > - } > - remove_stencil_client(ctx); > - ctx->stencil_mask &= ~0x03; > - glStencilMask(0x03); > - glClear(GL_STENCIL_BUFFER_BIT); > - GLC_ERROR_TEST_FLUSH; > -} > - > -static void clip_common(InternaCtx *ctx, GLCClipOp op, void (*fill_func)(InternaCtx *, void *), > - void *data) > -{ > - int stencil_val; > - > - if (ctx->pat) { > - glDisable(GL_TEXTURE_2D); > - } > - glDisable(GL_BLEND); > - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); > - ctx->draw_mode = FALSE; > - > - if (op == GLC_CLIP_OP_SET) { > - glc_clip_reset(ctx); > - add_stencil_client(ctx); > - ctx->stencil_mask |= 0x01; > - } else if (!(ctx->stencil_mask & 0x03)) { > - GLCRect area; > - if (op == GLC_CLIP_OP_OR) { > - return; > - } > - area.x = area.y = 0; > - area.width = ctx->width; > - area.height = ctx->height; > - clip_common(ctx, GLC_CLIP_OP_SET, fill_rect, &area); > - } > - glStencilMask(0x03); > - switch (op) { > - case GLC_CLIP_OP_SET: > - case GLC_CLIP_OP_OR: > - stencil_val = ctx->stencil_mask & 0x03; > - glStencilFunc(GL_ALWAYS, stencil_val, stencil_val); > - glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); > - fill_func(ctx, data); > - break; > - case GLC_CLIP_OP_AND: { > - int clear_mask; > - stencil_val = ctx->stencil_mask & 0x03; > - glStencilFunc(GL_EQUAL, stencil_val, stencil_val); > - if (stencil_val == 0x01) { > - glStencilOp(GL_ZERO, GL_INCR, GL_INCR); > - stencil_val = 0x02; > - clear_mask = 0x01; > - } else { > - glStencilOp(GL_ZERO, GL_DECR, GL_DECR); > - stencil_val = 0x01; > - clear_mask = 0x02; > - } > - fill_func(ctx, data); > - > - glStencilMask(clear_mask); > - glClear(GL_STENCIL_BUFFER_BIT); > - ctx->stencil_mask = (ctx->stencil_mask & ~clear_mask) | stencil_val; > - break; > - } > - case GLC_CLIP_OP_EXCLUDE: > - stencil_val = ctx->stencil_mask & 0x03; > - glStencilFunc(GL_EQUAL, stencil_val, stencil_val); > - glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO); > - fill_func(ctx, data); > - break; > - } > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx && rect); > - clip_common(ctx, op, fill_rect, (void *)rect); > -} > - > -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx && path); > - clip_common(ctx, op, fill_path, path); > -} > - > -typedef struct FillMaskInfo { > - int x_dest; > - int y_dest; > - int width; > - int height; > - int stride; > - const uint8_t *bitmap; > -} FillMaskInfo; > - > -static void __fill_mask(InternaCtx *ctx, void *data) > -{ > - FillMaskInfo *info = (FillMaskInfo *)data; > - fill_mask(ctx, info->x_dest, info->y_dest, info->width, info->height, info->stride, > - info->bitmap); > -} > - > -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, > - int stride, const uint8_t *bitmap, GLCClipOp op) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - FillMaskInfo mask_info; > - > - spice_assert(ctx && bitmap); > - mask_info.x_dest = x_dest; > - mask_info.y_dest = y_dest; > - mask_info.width = width; > - mask_info.height = height; > - mask_info.stride = stride; > - mask_info.bitmap = bitmap; > - clip_common(ctx, op, __fill_mask, &mask_info); > -} > - > -static inline void start_draw(InternaCtx *ctx) > -{ > - if (ctx->draw_mode) { > - return; > - } > - ctx->draw_mode = TRUE; > - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); > - glStencilFunc(GL_EQUAL, ctx->stencil_mask, ctx->stencil_mask); > - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); > - if (ctx->pat) { > - glEnable(GL_TEXTURE_2D); > - } else { > - glDisable(GL_TEXTURE_2D); > - } > - GLC_ERROR_TEST_FLUSH; > -} > - > -static void fill_rect(InternaCtx *ctx, void *r) > -{ > - GLCRect *rect = (GLCRect *)r; > - glRectd(rect->x, Y(rect->y), rect->x + rect->width, Y(rect->y + rect->height)); > - /*glBegin(GL_POLYGON); > - VERTEX2(rect->x, rect->y); > - VERTEX2 (rect->x + rect->width, rect->y); > - VERTEX2 (rect->x + rect->width, rect->y + rect->height); > - VERTEX2 (rect->x , rect->y + rect->height); > - glEnd();*/ > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_fill_rect(GLCCtx glc, const GLCRect *rect) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - GLCRect *r = (GLCRect *)rect; // to avoid bugs in gcc older than 4.3 > - > - spice_assert(ctx); > - start_draw(ctx); > - fill_rect(ctx, (void *)r); > - GLC_ERROR_TEST_FLUSH; > -} > - > -static void fill_path(InternaCtx *ctx, void *p) > -{ > - InternalPath *path = (InternalPath *)p; > - > - PathPoint *current_point = path->points; > - PathSegment *current_segment = path->segments; > - Path *current_path = path->paths; > - Path *end_path = current_path + path->paths_pos; > - reset_tass_vertex(ctx); > - gluTessBeginPolygon(ctx->tesselator, ctx); > - for (; current_path < end_path; current_path++) { > - gluTessBeginContour(ctx->tesselator); > - PathSegment *end_segment = current_segment + current_path->num_segments; > - gluTessVertex(ctx->tesselator, (GLdouble *)current_point, current_point); > - current_point++; > - for (; current_segment < end_segment; current_segment++) { > - PathPoint *end_point; > - if (current_segment->type == GLC_PATH_SEG_BEIZER) { > - end_point = current_point + current_segment->count * 3; > - for (; current_point < end_point; current_point += 3) { > - TassVertex *vertex = bezier_flattener(ctx, current_point - 1); > - while (vertex) { > - gluTessVertex(ctx->tesselator, (GLdouble *)&vertex->point, > - (GLdouble *)&vertex->point); > - vertex = vertex->list_link; > - } > - gluTessVertex(ctx->tesselator, (GLdouble *)¤t_point[2], > - (GLdouble *)¤t_point[2]); > - } > - } else { > - spice_assert(current_segment->type == GLC_PATH_SEG_LINES); > - end_point = current_point + current_segment->count; > - for (; current_point < end_point; current_point++) { > - gluTessVertex(ctx->tesselator, (GLdouble *)current_point, > - (GLdouble *)current_point); > - } > - } > - } > - gluTessEndContour(ctx->tesselator); > - } > - gluTessEndPolygon(ctx->tesselator); > -} > - > -void glc_fill_path(GLCCtx glc, GLCPath path_ref) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx && path_ref); > - start_draw(ctx); > - fill_path(ctx, path_ref); > -} > - > -static void fill_mask(InternaCtx *ctx, int x_dest, int y_dest, int width, int height, > - int stride, const uint8_t *bitmap) > -{ > - set_raster_pos(ctx, x_dest, y_dest + height); > - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); > - glBitmap(width, height, 0, 0, 0, 0, bitmap); > -} > - > -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride, > - const uint8_t *bitmap) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx && bitmap); > - start_draw(ctx); > - if (ctx->pat) { > - spice_critical("unimplemented fill mask with pattern"); > - } > - fill_mask(ctx, x_dest, y_dest, width, height, stride, bitmap); > -} > - > -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride, > - const uint8_t *alpha_mask) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - GLCRect r; > - > - spice_assert(ctx); > - start_draw(ctx); > - > - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); > - set_raster_pos(ctx, x_dest, y_dest + height); > - glPixelStorei(GL_UNPACK_ROW_LENGTH, stride); > - glPixelZoom(1, 1); > - glDrawPixels(width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_mask); > - > - r.x = x_dest; > - r.y = y_dest; > - r.width = width; > - r.height = height; > - > - //todo: support color/texture alpah vals (GL_MODULATE) > - glEnable(GL_BLEND); > - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); > - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); > - fill_rect(ctx, &r); > - glDisable(GL_BLEND); > -} > - > -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > - if (ctx->line_width == 0) { > - return; > - } > - > - start_draw(ctx); > - > - glBegin(GL_LINES); > - VERTEX2(rect->x, rect->y + 0.5); > - VERTEX2(rect->x + rect->width, rect->y + 0.5); > - VERTEX2(rect->x + rect->width - 0.5, rect->y); > - VERTEX2(rect->x + rect->width - 0.5, rect->y + rect->height); > - VERTEX2(rect->x + rect->width, rect->y + rect->height - 0.5); > - VERTEX2(rect->x, rect->y + rect->height - 0.5); > - VERTEX2(rect->x + 0.5, rect->y + rect->height); > - VERTEX2(rect->x + 0.5, rect->y); > - glEnd(); > - GLC_ERROR_TEST_FLUSH; > -} > - > -static void glc_stroke_line(double x1, double y1, double x2, double y2, double width) > -{ > - double ax, ay, bx, by, cx, cy, dx, dy; > - double norm, tx; > - > - if (width == 1 || y1 == y2 || x1 == x2) { > - glBegin(GL_LINES); > - glVertex2d(x1, y1); > - glVertex2d(x2, y2); > - glEnd(); > - return; > - } > - norm = (x1 - x2) / (y2 - y1); > - tx = width / (2 * sqrt(1 + norm * norm)); > - ax = x1 + tx; > - ay = y1 + norm * (ax - x1); > - bx = x2 + tx; > - by = y2 + norm * (bx - x2); > - cx = x2 - tx; > - cy = y2 + norm * (cx - x2); > - dx = x1 - tx; > - dy = y1 + norm * (dx - x1); > - glBegin(GL_POLYGON); > - glVertex2d(ax, ay); > - glVertex2d(bx, by); > - glVertex2d(cx, cy); > - glVertex2d(dx, dy); > - glEnd(); > -} > - > -static double glc_stroke_line_dash(double x1, double y1, double x2, double y2, > - double width, LineDash *dash) > -{ > - double ax, ay, bx, by; > - double mx, my, len; > - double dash_len, total = 0; > - > - len = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); > - if (!dash->dashes || !dash->num_dashes) { > - glc_stroke_line(x1, y1, x2, y2, width); > - return len; > - } > - mx = (x2 - x1) / len; > - my = (y2 - y1) / len; > - ax = x1; > - ay = y1; > - while (total < len) { > - if (dash->cur_dash >= 0) { > - dash_len = dash->dashes[dash->cur_dash % dash->num_dashes] - dash->dash_pos; > - } else { > - dash_len = dash->offset - dash->dash_pos; > - } > - total += dash_len; > - if (total < len) { > - bx = x1 + mx * total; > - by = y1 + my * total; > - dash->dash_pos = 0; > - } else { > - bx = x2; > - by = y2; > - dash->dash_pos = dash->dashes[dash->cur_dash % dash->num_dashes] - (total - len); > - } > - if (dash->cur_dash % 2 == 0) { > - glc_stroke_line(ax, ay, bx, by, width); > - } > - if (dash->dash_pos == 0) { > - dash->cur_dash = (dash->cur_dash + 1) % (2 * dash->num_dashes); > - } > - ax = bx; > - ay = by; > - } > - return len; > -} > - > -static void glc_vertex2d(InternaCtx *ctx, double x, double y) > -{ > - if (ctx->path_stroke.state == GLC_STROKE_ACTIVE) { > - glc_stroke_line_dash(ctx->path_stroke.x, ctx->path_stroke.y, x, y, > - ctx->line_width, &ctx->line_dash); > - ctx->path_stroke.x = x; > - ctx->path_stroke.y = y; > - } else if (ctx->path_stroke.state == GLC_STROKE_FIRST) { > - ctx->path_stroke.x = x; > - ctx->path_stroke.y = y; > - ctx->path_stroke.state = GLC_STROKE_ACTIVE; > - } else { > - spice_assert(ctx->path_stroke.state == GLC_STROKE_NONACTIVE); > - //error > - } > -} > - > -static void glc_begin_path(InternaCtx *ctx) > -{ > - ctx->path_stroke.state = GLC_STROKE_FIRST; > - ctx->line_dash.cur_dash = ctx->line_dash.offset ? -1 : 0; > - ctx->line_dash.dash_pos = 0; > -} > - > -static void glc_end_path(InternaCtx *ctx) > -{ > - ctx->path_stroke.state = GLC_STROKE_NONACTIVE; > -} > - > -void glc_stroke_path(GLCCtx glc, GLCPath path_ref) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - InternalPath *path = (InternalPath *)path_ref; > - > - spice_assert(ctx && path); > - if (ctx->line_width == 0) { > - return; > - } > - start_draw(ctx); > - > - reset_tass_vertex(ctx); > - PathPoint *current_point = path->points; > - PathSegment *current_segment = path->segments; > - Path *current_path = path->paths; > - Path *end_path = current_path + path->paths_pos; > - for (; current_path < end_path; current_path++) { > - glc_begin_path(ctx); > - PathSegment *end_segment = current_segment + current_path->num_segments; > - glc_vertex2d(ctx, current_point->x, current_point->y); > - current_point++; > - for (; current_segment < end_segment; current_segment++) { > - PathPoint *end_point; > - if (current_segment->type == GLC_PATH_SEG_BEIZER) { > - end_point = current_point + current_segment->count * 3; > - for (; current_point < end_point; current_point += 3) { > - TassVertex *vertex = bezier_flattener(ctx, current_point - 1); > - while (vertex) { > - glc_vertex2d(ctx, vertex->point.x, vertex->point.y); > - vertex = vertex->list_link; > - } > - glc_vertex2d(ctx, current_point[2].x, current_point[2].y); > - } > - } else { > - spice_assert(current_segment->type == GLC_PATH_SEG_LINES); > - end_point = current_point + current_segment->count; > - for (; current_point < end_point; current_point++) { > - glc_vertex2d(ctx, current_point->x, current_point->y); > - } > - } > - } > - glc_end_path(ctx); > - } > -} > - > -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image, > - int scale_mode, double alpha) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - uint8_t *pixels; > - const int pix_bytes = 4; > - > - spice_assert(ctx && image); > - spice_assert(src->width > 0 && src->height > 0); > - > - spice_assert(image->format == GLC_IMAGE_RGB32 || image->format == GLC_IMAGE_ARGB32); //for now > - start_draw(ctx); > - if (ctx->pat) { > - glDisable(GL_TEXTURE_2D); > - } > - set_raster_pos(ctx, dest->x, dest->y + dest->height); > - > - if (dest->width == src->width && src->height == dest->height) { > - glPixelZoom(1, 1); > - } else { > - glPixelZoom((float)dest->width / src->width, (float)dest->height / src->height); > - } > - > - pixels = image->pixels + src->x * 4 + (image->height - (src->y + src->height)) * image->stride; > - if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) { > - glPixelTransferf(GL_ALPHA_SCALE, (GLfloat)alpha); > - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); > - glEnable(GL_BLEND); > - } > - spice_assert(image->stride % pix_bytes == 0); > - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->stride / pix_bytes); > - glDrawPixels(src->width, src->height, GL_BGRA, GL_UNSIGNED_BYTE, pixels); > - > - if (image->format == GLC_IMAGE_ARGB32 || alpha != 1) { > - glDisable(GL_BLEND); > - } > - > - if (ctx->pat) { > - glEnable(GL_TEXTURE_2D); > - } > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width, > - int height) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > -#if 1 /* USE_COPY_PIXELS */ > - start_draw(ctx); > - if (ctx->pat) { > - glDisable(GL_TEXTURE_2D); > - } > - set_raster_pos(ctx, x_dest, y_dest + height); > - glPixelZoom(1, 1); > - glCopyPixels(x_src, ctx->height - (y_src + height), width, height, GL_COLOR); > - if (ctx->pat) { > - glEnable(GL_TEXTURE_2D); > - } > -#else > - int recreate = 0; > - int width2 = gl_get_to_power_two(width); > - int height2 = gl_get_to_power_two(height); > - > - start_draw(ctx); > - glEnable(GL_TEXTURE_2D); > - glBindTexture(GL_TEXTURE_2D, 0); > - > - if (width2 > ctx->private_tex_width) { > - ctx->private_tex_width = width2; > - recreate = 1; > - } > - if (height2 > ctx->private_tex_height) { > - ctx->private_tex_height = height2; > - recreate = 1; > - } > - if (recreate) { > - glDeleteTextures(1, &ctx->private_tex); > - glGenTextures(1, &ctx->private_tex); > - glBindTexture(GL_TEXTURE_2D, ctx->private_tex); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); > - ctx->private_tex_width = gl_get_to_power_two(width); > - ctx->private_tex_height = gl_get_to_power_two(height); > - glTexImage2D(GL_TEXTURE_2D, 0, 4, ctx->private_tex_width, > - ctx->private_tex_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); > - } > - spice_assert(ctx->private_tex); > - glBindTexture(GL_TEXTURE_2D, ctx->private_tex); > - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x_src, ctx->height - (y_src + height), > - width2, height2, 0); > - > - GLfloat s_gen_params[] = { (GLfloat)1.0 / width2, 0, 0, 0 }; > - GLfloat t_gen_params[] = { 0, (GLfloat)1.0 / height2, 0, 0 }; > - glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params); > - glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params); > - > - glMatrixMode(GL_TEXTURE); > - glLoadIdentity(); > - glTranslatef((float)-x_dest / width2, (float)-Y(y_dest + height) / height2, 0); > - > - glRecti(x_dest, Y(y_dest), x_dest + width, Y(y_dest + height)); > - glFlush(); > - if (!ctx->pat) { > - glDisable(GL_TEXTURE_2D); > - } else { > - set_pat(ctx, ctx->pat); > - } > -#endif > - GLC_ERROR_TEST_FLUSH; > -} > - > -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx && image); > - spice_assert(image->format == GLC_IMAGE_RGB32); //for now > - spice_assert((image->stride % 4) == 0); //for now > - glPixelStorei(GL_PACK_ROW_LENGTH, image->stride / 4); > - glReadPixels(x, ctx->height - (y + image->height), image->width, image->height, > - GL_BGRA, GL_UNSIGNED_BYTE, image->pixels); > -} > - > -void glc_clear(GLCCtx glc) > -{ > - InternaCtx *ctx = (InternaCtx *)glc; > - > - spice_assert(ctx); > - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); > - glClear(GL_COLOR_BUFFER_BIT); > -} > - > -void glc_flush(GLCCtx glc) > -{ > - glFlush(); > - > - GLC_ERROR_TEST_FLUSH; > -} > - > -static void tessellation_combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], > - GLdouble **data_out, void *usr_data) > -{ > - TassVertex *vertex; > - > - vertex = alloc_tess_vertex((InternaCtx *)usr_data); > - vertex->point.x = coords[0]; > - vertex->point.y = coords[1]; > - //vertex->point.z = coords[2]; > - *data_out = (GLdouble *)&vertex->point; > -} > - > -static void tessellation_error(GLenum errorCode) > -{ > - printf("%s: %s\n", __FUNCTION__, gluErrorString(errorCode)); > -} > - > -#ifdef WIN32 > -#define TESS_CALL_BACK_TYPE void(CALLBACK *)() > -#else > -#define TESS_CALL_BACK_TYPE void(*)() > -#endif > - > -static int init(InternaCtx *ctx, int width, int height) > -{ > -#ifdef WIN32 > - if (!(ctx->glBlendEquation = (PFNGLBLENDEQUATIONPROC)wglGetProcAddress("glBlendEquation"))) { > - return FALSE; > - } > -#endif > - ctx->width = width; > - ctx->height = height; > - ctx->line_width = 1; > - > - glClearColor(0, 0, 0, 0); > - glClearStencil(0); > - > - if (!(ctx->tesselator = gluNewTess())) { > - return FALSE; > - } > - > - glGenTextures(1, &ctx->private_tex); > - glBindTexture(GL_TEXTURE_2D, ctx->private_tex); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); > - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); > - glTexImage2D(GL_TEXTURE_2D, 0, 4, gl_get_to_power_two(width), > - gl_get_to_power_two(height), 0, > - GL_BGRA, GL_UNSIGNED_BYTE, NULL); > - ctx->private_tex_width = gl_get_to_power_two(width); > - ctx->private_tex_height = gl_get_to_power_two(height); > - glBindTexture(GL_TEXTURE_2D, 0); > - > - glViewport(0, 0, width, height); > - glMatrixMode(GL_PROJECTION); > - glLoadIdentity(); > - glOrtho(0, width, 0, height, -1, 1); > - > - gluTessProperty(ctx->tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); > - gluTessCallback(ctx->tesselator, GLU_BEGIN, (TESS_CALL_BACK_TYPE)glBegin); > - gluTessCallback(ctx->tesselator, GLU_VERTEX, (TESS_CALL_BACK_TYPE)glVertex3dv); > - gluTessCallback(ctx->tesselator, GLU_END, (TESS_CALL_BACK_TYPE)glEnd); > - gluTessCallback(ctx->tesselator, GLU_TESS_COMBINE_DATA, > - (TESS_CALL_BACK_TYPE)tessellation_combine); > - gluTessCallback(ctx->tesselator, GLU_TESS_ERROR, (TESS_CALL_BACK_TYPE)tessellation_error); > - > - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); > - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); > - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); > - glEnable(GL_TEXTURE_GEN_S); > - glEnable(GL_TEXTURE_GEN_T); > - > - glMatrixMode(GL_MODELVIEW); > - glLoadIdentity(); > - glTranslatef(0, (GLfloat)height, 0); > - > - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size); > - > - glPixelStorei(GL_PACK_ALIGNMENT, 1); > - > - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); > - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); > - glPixelTransferf(GL_ALPHA_BIAS, 0); > -#ifdef WIN32 > - ctx->glBlendEquation(GL_FUNC_ADD); > -#else > - glBlendEquation(GL_FUNC_ADD); > -#endif > - > - glStencilMask(0xff); > - glClear(GL_STENCIL_BUFFER_BIT); > - > - glClear(GL_COLOR_BUFFER_BIT); > - > - return TRUE; > -} > - > -GLCCtx glc_create(int width, int height) > -{ > - InternaCtx *ctx; > - > - spice_static_assert(sizeof(PathPoint) == sizeof(Vertex)); > - > - ctx = spice_new0(InternaCtx, 1); > - if (!init(ctx, width, height)) { > - free(ctx); > - return NULL; > - } > - return ctx; > -} > - > -/* > - * In glx video mode change the textures will be destroyed, therefore > - * if we will try to glDeleteTextures() them we might get seagfault. > - * (this why we use the textures_lost parameter) > - */ > -void glc_destroy(GLCCtx glc, int textures_lost) > -{ > - InternaCtx *ctx; > - > - if (!(ctx = (InternaCtx *)glc)) { > - return; > - } > - > - if (!textures_lost) { > - unref_pat(ctx->pat); > - ctx->pat = NULL; > - if (ctx->private_tex) { > - glDeleteTextures(1, &ctx->private_tex); > - } > - } > - > - free_tass_vertex_bufs(ctx); > - free(ctx->line_dash.dashes); > - free(ctx); > - GLC_ERROR_TEST_FINISH; > -} > - > -/* > - todo: > - 1. test double vs float in gl calls > - 2. int vs flat raster position > - 3. pixels stride vs bytes stride > - 4. improve non power of two. > - glGetString(GL_EXTENSIONS); > - ARB_texture_non_power_of_two > - ARB_texture_rectangle > - GL_TEXTURE_RECTANGLE_ARB > - 5. scale > - 6. origin > - 7. fonts > - 8. support more image formats > - 9. use GLCImage in mask ops? > -*/ > diff --git a/common/glc.h b/common/glc.h > deleted file mode 100644 > index 34b9420..0000000 > --- a/common/glc.h > +++ /dev/null > @@ -1,164 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, write to the Free Software > - > - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > -*/ > - > -#ifndef _H_GL_CANVASE > -#define _H_GL_CANVASE > - > -#include <stdint.h> > -#include <spice/macros.h> > - > -SPICE_BEGIN_DECLS > - > -typedef void * GLCCtx; > -typedef void * GLCPattern; > -typedef void * GLCPath; > - > -typedef struct GLCRect { > - double x; > - double y; > - double width; > - double height; > -} GLCRect; > - > -typedef struct GLCRecti { > - int x; > - int y; > - int width; > - int height; > -} GLCRecti; > - > -typedef enum { > - GLC_IMAGE_RGB32, > - GLC_IMAGE_ARGB32, > -} GLCImageFormat; > - > -typedef struct GLCPImage { > - GLCImageFormat format; > - int width; > - int height; > - int stride; > - uint8_t *pixels; > - uint32_t *pallet; > -} GLCImage; > - > -GLCPattern glc_pattern_create(GLCCtx glc, int x_orign, int y_orign, const GLCImage *image); > -void glc_pattern_set(GLCPattern pattern, int x_orign, int y_orign, const GLCImage *image); > -void glc_pattern_destroy(GLCPattern pattern); > - > -void glc_path_move_to(GLCPath path, double x, double y); > -void glc_path_line_to(GLCPath path, double x, double y); > -void glc_path_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y, > - double p3_x, double p3_y); > -void glc_path_rel_move_to(GLCPath path, double x, double y); > -void glc_path_rel_line_to(GLCPath path, double x, double y); > -void glc_path_rel_curve_to(GLCPath path, double p1_x, double p1_y, double p2_x, double p2_y, > - double p3_x, double p3_y); > -void glc_path_close(GLCPath path); > - > -void glc_path_cleare(GLCPath); > -GLCPath glc_path_create(GLCCtx glc); > -void glc_path_destroy(GLCPath path); > - > -void glc_set_rgb(GLCCtx glc, double red, double green, double blue); > -void glc_set_rgba(GLCCtx glc, double red, double green, double blue, double alpha); > -void glc_set_pattern(GLCCtx glc, GLCPattern pattern); > - > -typedef enum { > - GLC_OP_CLEAR = 0x1500, > - GLC_OP_SET = 0x150F, > - GLC_OP_COPY = 0x1503, > - GLC_OP_COPY_INVERTED = 0x150C, > - GLC_OP_NOOP = 0x1505, > - GLC_OP_INVERT = 0x150A, > - GLC_OP_AND = 0x1501, > - GLC_OP_NAND = 0x150E, > - GLC_OP_OR = 0x1507, > - GLC_OP_NOR = 0x1508, > - GLC_OP_XOR = 0x1506, > - GLC_OP_EQUIV = 0x1509, > - GLC_OP_AND_REVERSE = 0x1502, > - GLC_OP_AND_INVERTED = 0x1504, > - GLC_OP_OR_REVERSE = 0x150B, > - GLC_OP_OR_INVERTED = 0x150D, > -} GLCOp; > - > -void glc_set_op(GLCCtx glc, GLCOp op); > -void glc_set_alpha_factor(GLCCtx glc, double alpah); > - > -typedef enum { > - GLC_FILL_MODE_WINDING_ODD, > - GLC_FILL_MODE_WINDING_NONZERO, > -} GLCFillMode; > - > -void glc_set_fill_mode(GLCCtx glc, GLCFillMode mode); > -void glc_set_line_width(GLCCtx glc, double width); > -void glc_set_line_end_cap(GLCCtx glc, int style); > -void glc_set_line_join(GLCCtx glc, int style); > -void glc_set_miter_limit(GLCCtx glc, int limit); > -void glc_set_line_dash(GLCCtx glc, const double *dashes, int num_dashes, double offset); > - > -typedef enum { > - GLC_MASK_A, > - GLC_MASK_B, > -} GLCMaskID; > - > -void glc_set_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, > - int stride, const uint8_t *bitmap, GLCMaskID id); > -void glc_mask_rects(GLCCtx glc, int num_rect, GLCRect *rects, GLCMaskID id); > -void glc_clear_mask(GLCCtx glc, GLCMaskID id); > - > -typedef enum { > - GLC_CLIP_OP_SET, > - GLC_CLIP_OP_OR, > - GLC_CLIP_OP_AND, > - GLC_CLIP_OP_EXCLUDE, > -} GLCClipOp; > - > -void glc_clip_rect(GLCCtx glc, const GLCRect *rect, GLCClipOp op); > -void glc_clip_path(GLCCtx glc, GLCPath path, GLCClipOp op); > -void glc_clip_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride, > - const uint8_t *bitmap, GLCClipOp op); > -void glc_clip_reset(GLCCtx glc); > - > -void glc_fill_rect(GLCCtx glc, const GLCRect *rect); > -void glc_fill_path(GLCCtx glc, GLCPath path); > -void _glc_fill_mask(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride, > - const uint8_t *bitmap); > -void glc_fill_alpha(GLCCtx glc, int x_dest, int y_dest, int width, int height, int stride, > - const uint8_t *alpha_mask); > - > -void glc_stroke_rect(GLCCtx glc, const GLCRect *rect); > -void glc_stroke_path(GLCCtx glc, GLCPath path); > - > -void glc_draw_image(GLCCtx glc, const GLCRecti *dest, const GLCRecti *src, const GLCImage *image, > - int scale_mode, double alpha); > - > -void glc_copy_pixels(GLCCtx glc, int x_dest, int y_dest, int x_src, int y_src, int width, > - int height); > -void glc_read_pixels(GLCCtx glc, int x, int y, GLCImage *image); > - > -void glc_flush(GLCCtx glc); > -void glc_clear(GLCCtx glc); > -GLCCtx glc_create(int width, int height); > -void glc_destroy(GLCCtx glc, int textures_lost); > - > -SPICE_END_DECLS > - > -#endif > diff --git a/common/ogl_ctx.c b/common/ogl_ctx.c > deleted file mode 100644 > index 2de1b0d..0000000 > --- a/common/ogl_ctx.c > +++ /dev/null > @@ -1,249 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, see <http://www.gnu.org/licenses/>. > -*/ > -#ifdef HAVE_CONFIG_H > -#include <config.h> > -#endif > -#include "spice_common.h" > - > -#include <X11/Xlib.h> > -#include <GL/glx.h> > - > -#include "ogl_ctx.h" > - > -enum { > - OGLCTX_TYPE_PBUF, > - OGLCTX_TYPE_PIXMAP, > -}; > - > -struct OGLCtx { > - int type; > - Display *x_display; > - GLXContext glx_context; > - GLXDrawable drawable; > -}; > - > -typedef struct OGLPixmapCtx { > - OGLCtx base; > - Pixmap pixmap; > -} OGLPixmapCtx; > - > - > - > -const char *oglctx_type_str(OGLCtx *ctx) > -{ > - static const char *pbuf_str = "pbuf"; > - static const char *pixmap_str = "pixmap"; > - static const char *invalid_str = "invalid"; > - > - switch (ctx->type) { > - case OGLCTX_TYPE_PBUF: > - return pbuf_str; > - case OGLCTX_TYPE_PIXMAP: > - return pixmap_str; > - default: > - return invalid_str; > - } > -} > - > -void oglctx_make_current(OGLCtx *ctx) > -{ > - if (!glXMakeCurrent(ctx->x_display, ctx->drawable, ctx->glx_context)) { > - printf("%s: failed\n", __FUNCTION__); > - } > -} > - > -OGLCtx *pbuf_create(int width, int heigth) > -{ > - OGLCtx *ctx; > - Display *x_display; > - int num_configs; > - GLXFBConfig *fb_config; > - GLXPbuffer glx_pbuf; > - GLXContext glx_context; > - > - const int glx_attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, > - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT, > - GLX_RED_SIZE, 8, > - GLX_GREEN_SIZE, 8, > - GLX_BLUE_SIZE, 8, > - GLX_ALPHA_SIZE, 8, > - GLX_STENCIL_SIZE, 4, > - 0 }; > - > - int pbuf_attrib[] = { GLX_PRESERVED_CONTENTS, True, > - GLX_PBUFFER_WIDTH, width, > - GLX_PBUFFER_HEIGHT, heigth, > - GLX_LARGEST_PBUFFER, False, > - 0, 0 }; > - > - if (!(ctx = calloc(1, sizeof(*ctx)))) { > - printf("%s: alloc pbuf failed\n", __FUNCTION__); > - return NULL; > - } > - > - if (!(x_display = XOpenDisplay(NULL))) { > - printf("%s: open display failed\n", __FUNCTION__); > - goto error_1; > - } > - > - if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes, &num_configs)) || > - !num_configs) { > - printf("%s: choose fb config failed\n", __FUNCTION__); > - goto error_2; > - } > - > - if (!(glx_pbuf = glXCreatePbuffer(x_display, fb_config[0], pbuf_attrib))) { > - goto error_3; > - } > - > - if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) { > - printf("%s: create context failed\n", __FUNCTION__); > - goto error_4; > - } > - > - XFree(fb_config); > - > - ctx->type = OGLCTX_TYPE_PBUF; > - ctx->drawable = glx_pbuf; > - ctx->glx_context = glx_context; > - ctx->x_display = x_display; > - > - return ctx; > - > -error_4: > - glXDestroyPbuffer(x_display, glx_pbuf); > - > -error_3: > - XFree(fb_config); > - > -error_2: > - XCloseDisplay(x_display); > - > -error_1: > - free(ctx); > - > - return NULL; > -} > - > -OGLCtx *pixmap_create(int width, int heigth) > -{ > - Display *x_display; > - int num_configs; > - GLXFBConfig *fb_config; > - GLXPixmap glx_pixmap; > - GLXContext glx_context; > - Pixmap pixmap; > - int screen; > - Window root_window; > - OGLPixmapCtx *pix; > - > - const int glx_attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, > - GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, > - GLX_RED_SIZE, 8, > - GLX_GREEN_SIZE, 8, > - GLX_BLUE_SIZE, 8, > - GLX_ALPHA_SIZE, 8, > - GLX_STENCIL_SIZE, 4, > - 0 }; > - > - if (!(pix = calloc(1, sizeof(*pix)))) { > - printf("%s: alloc pix failed\n", __FUNCTION__); > - return NULL; > - } > - > - if (!(x_display = XOpenDisplay(NULL))) { > - printf("%s: open display failed\n", __FUNCTION__); > - goto error_1; > - } > - > - screen = DefaultScreen(x_display); > - root_window = RootWindow(x_display, screen); > - > - if (!(fb_config = glXChooseFBConfig(x_display, 0, glx_attributes, &num_configs)) || > - !num_configs) { > - printf("%s: choose fb config failed\n", __FUNCTION__); > - goto error_2; > - } > - > - if (!(pixmap = XCreatePixmap(x_display, root_window, width, heigth, 32 /*use fb config*/))) { > - printf("%s: create x pixmap failed\n", __FUNCTION__); > - goto error_3; > - } > - > - if (!(glx_pixmap = glXCreatePixmap(x_display, fb_config[0], pixmap, NULL))) { > - printf("%s: create glx pixmap failed\n", __FUNCTION__); > - goto error_4; > - } > - > - > - if (!(glx_context = glXCreateNewContext(x_display, fb_config[0], GLX_RGBA_TYPE, NULL, True))) { > - printf("%s: create context failed\n", __FUNCTION__); > - goto error_5; > - } > - > - XFree(fb_config); > - > - pix->base.type = OGLCTX_TYPE_PIXMAP; > - pix->base.x_display = x_display; > - pix->base.drawable = glx_pixmap; > - pix->base.glx_context = glx_context; > - pix->pixmap = pixmap; > - > - return &pix->base; > - > -error_5: > - glXDestroyPixmap(x_display, glx_pixmap); > - > -error_4: > - XFreePixmap(x_display, pixmap); > - > -error_3: > - XFree(fb_config); > - > -error_2: > - XCloseDisplay(x_display); > - > -error_1: > - free(pix); > - > - return NULL; > -} > - > -void oglctx_destroy(OGLCtx *ctx) > -{ > - if (!ctx) { > - return; > - } > - // test is current ? > - > - glXDestroyContext(ctx->x_display, ctx->glx_context); > - switch (ctx->type) { > - case OGLCTX_TYPE_PBUF: > - glXDestroyPbuffer(ctx->x_display, ctx->drawable); > - break; > - case OGLCTX_TYPE_PIXMAP: > - glXDestroyPixmap(ctx->x_display, ctx->drawable); > - XFreePixmap(ctx->x_display, ((OGLPixmapCtx *)ctx)->pixmap); > - break; > - default: > - spice_error("invalid ogl ctx type"); > - } > - > - XCloseDisplay(ctx->x_display); > - free(ctx); > -} > diff --git a/common/ogl_ctx.h b/common/ogl_ctx.h > deleted file mode 100644 > index 5a5935e..0000000 > --- a/common/ogl_ctx.h > +++ /dev/null > @@ -1,36 +0,0 @@ > -/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ > -/* > - Copyright (C) 2009 Red Hat, Inc. > - > - This library is free software; you can redistribute it and/or > - modify it under the terms of the GNU Lesser General Public > - License as published by the Free Software Foundation; either > - version 2.1 of the License, or (at your option) any later version. > - > - This library 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 > - Lesser General Public License for more details. > - > - You should have received a copy of the GNU Lesser General Public > - License along with this library; if not, see <http://www.gnu.org/licenses/>. > -*/ > - > -#ifndef _H_GLCTX > -#define _H_GLCTX > - > -#include <spice/macros.h> > - > -SPICE_BEGIN_DECLS > - > -typedef struct OGLCtx OGLCtx; > - > -const char *oglctx_type_str(OGLCtx *ctx); > -void oglctx_make_current(OGLCtx *ctx); > -OGLCtx *pbuf_create(int width, int heigth); > -OGLCtx *pixmap_create(int width, int heigth); > -void oglctx_destroy(OGLCtx *ctx); > - > -SPICE_END_DECLS > - > -#endif > diff --git a/configure.ac b/configure.ac > index 7adb2c5..f8ff024 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -37,11 +37,10 @@ SPICE_CHECK_SMARTCARD > SPICE_CHECK_CELT051 > SPICE_CHECK_GLIB2 > SPICE_CHECK_OPUS > -SPICE_CHECK_OPENGL > SPICE_CHECK_OPENSSL > > -SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(GL_CFLAGS) $(OPENSSL_CFLAGS)' > -SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(CELT051_LIBS) $(GLIB2_LIBS) $(OPUS_LIBS) $(GL_LIBS) $(OPENSSL_LIBS)' > +SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(OPENSSL_CFLAGS)' > +SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(CELT051_LIBS) $(GLIB2_LIBS) $(OPUS_LIBS) $(OPENSSL_LIBS)' > AC_SUBST(SPICE_COMMON_CFLAGS) > AC_SUBST(SPICE_COMMON_LIBS) > > diff --git a/m4/spice-deps.m4 b/m4/spice-deps.m4 > index 2f294f3..2e2fcf5 100644 > --- a/m4/spice-deps.m4 > +++ b/m4/spice-deps.m4 > @@ -128,37 +128,6 @@ AC_DEFUN([SPICE_CHECK_OPUS], [ > ]) > > > -# SPICE_CHECK_OPENGL > -# ------------------ > -# Adds a --disable-opengl switch in order to enable/disable OpenGL > -# support, and checks if the needed libraries are available. If found, it will > -# return the flags to use in the GL_CFLAGS and GL_LIBS variables, and > -# it will define USE_OPENGL and GL_GLEXT_PROTOTYPES preprocessor symbol as well > -# as a HAVE_GL Makefile conditional. > -# ------------------ > -AC_DEFUN([SPICE_CHECK_OPENGL], [ > - AC_ARG_ENABLE([opengl], > - AS_HELP_STRING([--enable-opengl=@<:@yes/no@:>@], > - [Enable opengl support (not recommended) @<:@default=no@:>@]), > - [], > - [enable_opengl="no"]) > - AM_CONDITIONAL(HAVE_GL, test "x$enable_opengl" = "xyes") > - > - if test "x$enable_opengl" = "xyes"; then > - AC_SUBST(GL_CFLAGS) > - AC_SUBST(GL_LIBS) > - AC_CHECK_LIB(GL, glBlendFunc, GL_LIBS="$GL_LIBS -lGL", enable_opengl=no) > - AC_CHECK_LIB(GLU, gluSphere, GL_LIBS="$GL_LIBS -lGLU", enable_opengl=no) > - AC_DEFINE([USE_OPENGL], [1], [Define to build with OpenGL support]) > - AC_DEFINE([GL_GLEXT_PROTOTYPES], [], [Enable GLExt prototypes]) > - > - if test "x$enable_opengl" = "xno"; then > - AC_MSG_ERROR([GL libraries not available]) > - fi > - fi > -]) > - > - > # SPICE_CHECK_PIXMAN > # ------------------ > # Check for the availability of pixman. If found, it will return the flags to > -- > 2.8.2 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/spice-devel
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel