summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-10-08 11:08:43 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-10-09 19:54:15 +0100
commita6c27b500ba8f910ff2a731eb6989c96e8977339 (patch)
treeb81e6ed42a416e736f127b83b571ed16d2d2f4e2
parent22c485017df7979c47e9c4ba708279c8c35e5149 (diff)
gl: Basic fixes to get cairo-gl running again
Let there be textures! Unbreak the setup of surface operands after my lazy convertion to the new compositor interface. This is still only the first step, but it gets the essentials up and running again, enough to keep me happy whilst sitting in the airport. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/cairo-gl-gradient.c2
-rw-r--r--src/cairo-gl-operand.c151
-rw-r--r--src/cairo-gl-private.h6
-rw-r--r--src/cairo-gl-spans-compositor.c2
-rw-r--r--src/cairo-gl-surface.c9
5 files changed, 126 insertions, 44 deletions
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index 862430e5..a429257f 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -213,7 +213,7 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
return CAIRO_INT_STATUS_UNSUPPORTED;
hash = _cairo_gl_gradient_hash (n_stops, stops);
-
+
gradient = _cairo_gl_gradient_lookup (ctx, hash, n_stops, stops);
if (gradient) {
*gradient_out = _cairo_gl_gradient_reference (gradient);
diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index 8b345bbd..86a96df5 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -49,6 +49,8 @@
#include "cairo-error-private.h"
#include "cairo-image-surface-private.h"
#include "cairo-surface-backend-private.h"
+#include "cairo-surface-offset-private.h"
+#include "cairo-surface-subsurface-private.h"
static cairo_int_status_t
_cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst,
@@ -67,60 +69,124 @@ _cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst,
return _cairo_gl_context_release (ctx, status);
}
-/*
- * Like cairo_pattern_acquire_surface(), but returns a matrix that transforms
- * from dest to src coords.
- */
+static cairo_status_t
+_cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
+ const cairo_pattern_t *_src,
+ cairo_gl_surface_t *dst,
+ int src_x, int src_y,
+ int dst_x, int dst_y,
+ int width, int height)
+{
+ const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
+ cairo_gl_surface_t *surface;
+ cairo_surface_attributes_t *attributes;
+ cairo_matrix_t m;
+
+ surface = (cairo_gl_surface_t *) src->surface;
+ if (surface->base.type != CAIRO_SURFACE_TYPE_GL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ if (surface->base.backend->type != CAIRO_SURFACE_TYPE_GL) {
+ if (_cairo_surface_is_subsurface (&surface->base)) {
+ surface = (cairo_gl_surface_t *)
+ _cairo_surface_subsurface_get_target_with_offset (&surface->base, &src_x, &src_y);
+ }
+ }
+
+ attributes = &operand->texture.attributes;
+
+ operand->type = CAIRO_GL_OPERAND_TEXTURE;
+ operand->texture.surface =
+ (cairo_gl_surface_t *) cairo_surface_reference (&surface->base);
+ operand->texture.tex = surface->tex;
+
+ /* Translate the matrix from
+ * (unnormalized src -> unnormalized src) to
+ * (unnormalized dst -> unnormalized src)
+ */
+ cairo_matrix_init_translate (&m, src_x - dst_x, src_y - dst_y);
+ cairo_matrix_multiply (&attributes->matrix, &m, &src->base.matrix);
+
+ /* Translate the matrix from
+ * (unnormalized dst -> unnormalized src) to
+ * (unnormalized dst -> normalized src)
+ */
+ if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) {
+ cairo_matrix_init_scale (&m,
+ 1.0,
+ 1.0);
+ } else {
+ cairo_matrix_init_scale (&m,
+ 1.0 / surface->width,
+ 1.0 / surface->height);
+ }
+ cairo_matrix_multiply (&attributes->matrix,
+ &attributes->matrix,
+ &m);
+
+ attributes->extend = src->base.extend;
+ attributes->filter = src->base.filter;
+ return CAIRO_STATUS_SUCCESS;
+}
+
static cairo_status_t
_cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
- const cairo_pattern_t *src,
+ const cairo_pattern_t *_src,
cairo_gl_surface_t *dst,
int src_x, int src_y,
int dst_x, int dst_y,
int width, int height)
{
+ const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
cairo_status_t status;
cairo_matrix_t m;
cairo_gl_surface_t *surface;
+ cairo_gl_context_t *ctx;
cairo_surface_attributes_t *attributes;
attributes = &operand->texture.attributes;
-#if 0
- status = _cairo_pattern_acquire_surface (src, &dst->base,
- src_x, src_y,
- width, height,
- CAIRO_PATTERN_ACQUIRE_NONE,
- (cairo_surface_t **)
- &surface,
- attributes);
+ status = _cairo_gl_context_acquire (dst->base.device, &ctx);
if (unlikely (status))
return status;
-#endif
- if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device) &&
- (attributes->extend == CAIRO_EXTEND_REPEAT ||
- attributes->extend == CAIRO_EXTEND_REFLECT))
- {
- return UNSUPPORTED ("EXT_texture_rectangle with repeat/reflect");
+ surface = (cairo_gl_surface_t *)
+ _cairo_gl_surface_create_scratch (ctx,
+ src->surface->content,
+ width, height);
+ if (src->surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE) {
+ status = _cairo_gl_surface_draw_image (surface,
+ (cairo_image_surface_t *)src->surface,
+ src_x, src_y,
+ width, height,
+ 0, 0);
+
+ attributes->extend = src->base.extend;
+ attributes->filter = src->base.filter;
+ } else {
+ cairo_surface_t *image;
+
+ image = cairo_surface_map_to_image (&surface->base, NULL);
+ status = _cairo_surface_offset_paint (image, src_x, src_y,
+ CAIRO_OPERATOR_SOURCE, _src,
+ NULL);
+ cairo_surface_unmap_image (&surface->base, image);
+
+ attributes->extend = CAIRO_EXTEND_NONE;
+ attributes->filter = CAIRO_FILTER_NEAREST;
}
- assert (_cairo_gl_surface_is_texture (surface));
+ status = _cairo_gl_context_release (ctx, status);
operand->type = CAIRO_GL_OPERAND_TEXTURE;
operand->texture.surface = surface;
operand->texture.tex = surface->tex;
+
/* Translate the matrix from
* (unnormalized src -> unnormalized src) to
* (unnormalized dst -> unnormalized src)
*/
- cairo_matrix_init_translate (&m,
- src_x - dst_x + attributes->x_offset,
- src_y - dst_y + attributes->y_offset);
- cairo_matrix_multiply (&attributes->matrix,
- &m,
- &attributes->matrix);
-
+ cairo_matrix_init_translate (&m, -dst_x, -dst_y);
+ cairo_matrix_multiply (&attributes->matrix, &m, &src->base.matrix);
/* Translate the matrix from
* (unnormalized dst -> unnormalized src) to
@@ -138,7 +204,6 @@ _cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
cairo_matrix_multiply (&attributes->matrix,
&attributes->matrix,
&m);
-
return CAIRO_STATUS_SUCCESS;
}
@@ -286,26 +351,38 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
_cairo_gl_solid_operand_init (operand,
&((cairo_solid_pattern_t *) pattern)->color);
return CAIRO_STATUS_SUCCESS;
+ case CAIRO_PATTERN_TYPE_SURFACE:
+ status = _cairo_gl_surface_operand_init (operand,
+ pattern, dst,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height);
+ if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+ break;
+
+ return status;
+
case CAIRO_PATTERN_TYPE_LINEAR:
case CAIRO_PATTERN_TYPE_RADIAL:
status = _cairo_gl_gradient_operand_init (operand,
pattern, dst,
src_x, src_y,
dst_x, dst_y);
- if (status != CAIRO_INT_STATUS_UNSUPPORTED)
- return status;
+ if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+ break;
- /* fall through */
+ return status;
default:
case CAIRO_PATTERN_TYPE_MESH:
- case CAIRO_PATTERN_TYPE_SURFACE:
- return _cairo_gl_pattern_texture_setup (operand,
- pattern, dst,
- src_x, src_y,
- dst_x, dst_y,
- width, height);
+ break;
}
+
+ return _cairo_gl_pattern_texture_setup (operand,
+ pattern, dst,
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height);
}
cairo_filter_t
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index e1005ba8..70023922 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -664,6 +664,12 @@ _cairo_gl_composite_glyphs (void *_dst,
int dst_y,
cairo_composite_glyphs_info_t *info);
+cairo_private cairo_surface_t *
+_cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
+ cairo_content_t content,
+ int width,
+ int height);
+
slim_hidden_proto (cairo_gl_surface_create);
slim_hidden_proto (cairo_gl_surface_create_for_texture);
diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
index 57cccc9f..3e52f286 100644
--- a/src/cairo-gl-spans-compositor.c
+++ b/src/cairo-gl-spans-compositor.c
@@ -337,7 +337,7 @@ static inline cairo_gl_operand_t *
source_to_operand (cairo_surface_t *surface)
{
cairo_gl_source_t *source = (cairo_gl_source_t *)surface;
- return &source->operand;
+ return source ? &source->operand : NULL;
}
static cairo_int_status_t
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index dec4b82a..9fcbc3e0 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -392,7 +392,7 @@ _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t *ctx,
return &surface->base;
}
-static cairo_surface_t *
+cairo_surface_t *
_cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
cairo_content_t content,
int width,
@@ -715,13 +715,12 @@ _cairo_gl_surface_create_similar (void *abstract_surface,
}
static cairo_int_status_t
-_cairo_gl_surface_fill_alpha_channel (void *abstract_dst,
+_cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst,
+ cairo_gl_context_t *ctx,
int x, int y,
int width, int height)
{
- cairo_gl_surface_t *dst = abstract_dst;
cairo_gl_composite_t setup;
- cairo_gl_context_t *ctx;
cairo_status_t status;
_cairo_gl_composite_flush (ctx);
@@ -849,7 +848,7 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
* texture data.
*/
if (!has_alpha) {
- _cairo_gl_surface_fill_alpha_channel (dst,
+ _cairo_gl_surface_fill_alpha_channel (dst, ctx,
dst_x, dst_y,
width, height);
}