[cairo-commit] 3 commits - src/cairo-gl-composite.c src/cairo-gl-gradient.c src/cairo-gl-operand.c src/cairo-gl-private.h src/cairo-gl-shaders.c src/cairo-gl-spans-compositor.c src/cairo-gl-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Sun Oct 9 11:55:25 PDT 2011
src/cairo-gl-composite.c | 6 -
src/cairo-gl-gradient.c | 8 -
src/cairo-gl-operand.c | 175 +++++++++++++++++++++++++++++++---------
src/cairo-gl-private.h | 10 ++
src/cairo-gl-shaders.c | 6 -
src/cairo-gl-spans-compositor.c | 2
src/cairo-gl-surface.c | 9 --
7 files changed, 163 insertions(+), 53 deletions(-)
New commits:
commit 34f507a919b0709caa2c0be30e43719356293dd1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Oct 8 13:54:28 2011 +0100
gl: Need to increment reference count when copying operands
Or else watch everything die with use-after-free of the cached
gradients.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index c59501e..6413255 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -69,7 +69,7 @@ _cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
const cairo_gl_operand_t *source)
{
_cairo_gl_operand_destroy (&setup->src);
- setup->src = *source;
+ _cairo_gl_operand_copy (&setup->src, source);
}
void
@@ -104,7 +104,7 @@ _cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
{
_cairo_gl_operand_destroy (&setup->mask);
if (mask)
- setup->mask = *mask;
+ _cairo_gl_operand_copy (&setup->mask, mask);
}
void
@@ -242,7 +242,6 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
- _cairo_gl_gradient_reference (operand->gradient.gradient);
glActiveTexture (GL_TEXTURE0 + tex_unit);
glBindTexture (ctx->tex_target, operand->gradient.gradient->tex);
_cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend);
@@ -292,7 +291,6 @@ _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
- _cairo_gl_gradient_destroy (ctx->operands[tex_unit].gradient.gradient);
dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
break;
}
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index a429257..aad2773 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -226,7 +226,7 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
tex_width = _cairo_gl_gradient_sample_width (n_stops, stops);
- CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1);
+ CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 2);
gradient->cache_entry.hash = hash;
gradient->cache_entry.size = tex_width;
gradient->device = &ctx->base;
@@ -272,8 +272,8 @@ _cairo_gl_gradient_create (cairo_gl_context_t *ctx,
}
/* we ignore errors here and just return an uncached gradient */
- if (likely (! _cairo_cache_insert (&ctx->gradients, &gradient->cache_entry)))
- _cairo_gl_gradient_reference (gradient);
+ if (unlikely (_cairo_cache_insert (&ctx->gradients, &gradient->cache_entry)))
+ CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1);
*gradient_out = gradient;
return CAIRO_STATUS_SUCCESS;
diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index 86a96df..f0f7656 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -313,6 +313,30 @@ _cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
}
void
+_cairo_gl_operand_copy (cairo_gl_operand_t *dst,
+ const cairo_gl_operand_t *src)
+{
+ *dst = *src;
+ switch (dst->type) {
+ case CAIRO_GL_OPERAND_CONSTANT:
+ break;
+ case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
+ case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
+ _cairo_gl_gradient_reference (dst->gradient.gradient);
+ break;
+ case CAIRO_GL_OPERAND_TEXTURE:
+ break;
+ default:
+ case CAIRO_GL_OPERAND_COUNT:
+ ASSERT_NOT_REACHED;
+ case CAIRO_GL_OPERAND_NONE:
+ break;
+ }
+}
+
+void
_cairo_gl_operand_destroy (cairo_gl_operand_t *operand)
{
switch (operand->type) {
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 7002392..6d8aab8 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -640,6 +640,10 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
uint8_t alpha);
cairo_private void
+_cairo_gl_operand_copy (cairo_gl_operand_t *dst,
+ const cairo_gl_operand_t *src);
+
+cairo_private void
_cairo_gl_operand_destroy (cairo_gl_operand_t *operand);
cairo_private const cairo_compositor_t *
commit a6c27b500ba8f910ff2a731eb6989c96e8977339
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Oct 8 11:08:43 2011 +0100
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 at chris-wilson.co.uk>
diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index 862430e..a429257 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 8b345bb..86a96df 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 e1005ba..7002392 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 57cccc9..3e52f28 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 dec4b82..9fcbc3e 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);
}
commit 22c485017df7979c47e9c4ba708279c8c35e5149
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Oct 8 05:57:49 2011 +0100
gl: Declare coverage input for fragment shaders.
The most minor of oversights which prevented compilation of any spans
based compositors.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c
index 69609df..446b6af 100644
--- a/src/cairo-gl-shaders.c
+++ b/src/cairo-gl-shaders.c
@@ -866,8 +866,10 @@ cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx,
cairo_gl_shader_emit_color (stream, ctx, mask, CAIRO_GL_TEX_MASK);
coverage_str = "";
- if (use_coverage)
- coverage_str = " * coverage.a";
+ if (use_coverage) {
+ _cairo_output_stream_printf (stream, "varying float coverage;\n");
+ coverage_str = " * coverage";
+ }
_cairo_output_stream_printf (stream,
"void main()\n"
More information about the cairo-commit
mailing list