Remove GL support

It is not needed since spice-server commit
c5c176a5c7718177f23b07981556b5d460627498

Acked-by: Christophe Fergeau <cfergeau@redhat.com>
This commit is contained in:
Pavel Grunt 2016-05-11 15:47:56 +02:00 committed by Frediano Ziglio
parent ad862c4d4b
commit 384698af37
11 changed files with 6 additions and 3057 deletions

View File

@ -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 \

View File

@ -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;

View File

@ -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, &copy->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, &copy->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;
}

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -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