It is not needed since spice-server commit c5c176a5c7718177f23b07981556b5d460627498 --- common/Makefile.am | 12 - 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 -- 10 files changed, 2 insertions(+), 3020 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/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