mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-common
synced 2025-12-27 07:01:41 +00:00
Remove GL support
It is not needed since spice-server commit c5c176a5c7718177f23b07981556b5d460627498 Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This commit is contained in:
parent
ad862c4d4b
commit
384698af37
@ -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 \
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
1510
common/glc.c
1510
common/glc.c
File diff suppressed because it is too large
Load Diff
164
common/glc.h
164
common/glc.h
@ -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
|
||||
249
common/ogl_ctx.c
249
common/ogl_ctx.c
@ -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);
|
||||
}
|
||||
@ -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
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user