summaryrefslogtreecommitdiff
path: root/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c')
-rw-r--r--Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c281
1 files changed, 190 insertions, 91 deletions
diff --git a/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c b/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
index 5b1411472d0..5477ef0d8ac 100644
--- a/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
+++ b/Build/source/libs/cairo/cairo-src/src/cairo-gl-composite.c
@@ -52,9 +52,96 @@
#include "cairo-error-private.h"
#include "cairo-image-surface-private.h"
+/* FIXME: Copy of same routine in cairo-gl-msaa-compositor.c */
+static cairo_int_status_t
+_draw_int_rect (cairo_gl_context_t *ctx,
+ cairo_gl_composite_t *setup,
+ cairo_rectangle_int_t *rect)
+{
+ cairo_box_t box;
+ cairo_point_t quad[4];
+
+ _cairo_box_from_rectangle (&box, rect);
+ quad[0].x = box.p1.x;
+ quad[0].y = box.p1.y;
+ quad[1].x = box.p1.x;
+ quad[1].y = box.p2.y;
+ quad[2].x = box.p2.x;
+ quad[2].y = box.p2.y;
+ quad[3].x = box.p2.x;
+ quad[3].y = box.p1.y;
+
+ return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad);
+}
+
+static cairo_int_status_t
+_blit_texture_to_renderbuffer (cairo_gl_surface_t *surface)
+{
+ cairo_gl_context_t *ctx = NULL;
+ cairo_gl_composite_t setup;
+ cairo_surface_pattern_t pattern;
+ cairo_rectangle_int_t extents;
+ cairo_int_status_t status;
+
+ /* FIXME: This only permits blit when glesv3 is enabled. But note that
+ glesv2 with the ANGLE extension should also be able to support this feature,
+ so once the ANGLE support code is in place this check can be relaxed. */
+ if (((cairo_gl_context_t *)surface->base.device)->gl_flavor != CAIRO_GL_FLAVOR_ES3)
+ return CAIRO_INT_STATUS_SUCCESS;
+
+ if (! surface->content_in_texture)
+ return CAIRO_INT_STATUS_SUCCESS;
+
+ memset (&setup, 0, sizeof (cairo_gl_composite_t));
+
+ status = _cairo_gl_composite_set_operator (&setup,
+ CAIRO_OPERATOR_SOURCE,
+ FALSE);
+
+ if (status)
+ return status;
+
+ setup.dst = surface;
+ setup.clip_region = surface->clip_region;
+
+ _cairo_pattern_init_for_surface (&pattern, &surface->base);
+ status = _cairo_gl_composite_set_source (&setup, &pattern.base,
+ NULL, NULL, FALSE);
+ _cairo_pattern_fini (&pattern.base);
+
+ if (unlikely (status))
+ goto FAIL;
+
+ _cairo_gl_composite_set_multisample (&setup);
+
+ status = _cairo_gl_composite_begin (&setup, &ctx);
+
+ if (unlikely (status))
+ goto FAIL;
+
+ extents.x = extents.y = 0;
+ extents.width = surface->width;
+ extents.height = surface->height;
+
+ status = _draw_int_rect (ctx, &setup, &extents);
+
+ if (status == CAIRO_INT_STATUS_SUCCESS)
+ surface->content_in_texture = FALSE;
+
+FAIL:
+ _cairo_gl_composite_fini (&setup);
+
+ if (ctx) {
+ _cairo_gl_composite_flush (ctx);
+ status = _cairo_gl_context_release (ctx, status);
+ }
+
+ return status;
+}
+
cairo_int_status_t
_cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
- const cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
const cairo_rectangle_int_t *sample,
const cairo_rectangle_int_t *extents,
cairo_bool_t use_texgen)
@@ -68,8 +155,13 @@ void
_cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup,
const cairo_gl_operand_t *source)
{
+ cairo_int_status_t status;
+
_cairo_gl_operand_destroy (&setup->src);
_cairo_gl_operand_copy (&setup->src, source);
+
+ if (source->type == CAIRO_GL_OPERAND_TEXTURE)
+ status = _cairo_gl_surface_resolve_multisampling (source->texture.surface);
}
void
@@ -89,7 +181,7 @@ _cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
{
_cairo_gl_operand_destroy (&setup->mask);
if (pattern == NULL)
- return CAIRO_STATUS_SUCCESS;
+ return CAIRO_STATUS_SUCCESS;
return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst,
sample, extents, use_texgen);
@@ -99,9 +191,13 @@ void
_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
const cairo_gl_operand_t *mask)
{
+ cairo_int_status_t status;
_cairo_gl_operand_destroy (&setup->mask);
- if (mask)
+ if (mask) {
_cairo_gl_operand_copy (&setup->mask, mask);
+ if (mask->type == CAIRO_GL_OPERAND_TEXTURE)
+ status = _cairo_gl_surface_resolve_multisampling (mask->texture.surface);
+ }
}
void
@@ -118,7 +214,7 @@ _cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup)
void
_cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup,
- cairo_region_t *clip_region)
+ cairo_region_t *clip_region)
{
setup->clip_region = clip_region;
}
@@ -142,8 +238,8 @@ _cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx,
static void
_cairo_gl_texture_set_filter (cairo_gl_context_t *ctx,
- GLuint target,
- cairo_filter_t filter)
+ GLuint target,
+ cairo_filter_t filter)
{
switch (filter) {
case CAIRO_FILTER_FAST:
@@ -165,16 +261,17 @@ _cairo_gl_texture_set_filter (cairo_gl_context_t *ctx,
static void
_cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
- GLuint target,
- cairo_extend_t extend)
+ GLuint target,
+ cairo_extend_t extend)
{
GLint wrap_mode;
assert (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base) ||
- (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));
+ (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT));
switch (extend) {
case CAIRO_EXTEND_NONE:
- if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES)
+ if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES3 ||
+ ctx->gl_flavor == CAIRO_GL_FLAVOR_ES2)
wrap_mode = GL_CLAMP_TO_EDGE;
else
wrap_mode = GL_CLAMP_TO_BORDER;
@@ -207,10 +304,10 @@ _cairo_gl_texture_set_extend (cairo_gl_context_t *ctx,
static void
_cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
- cairo_gl_tex_t tex_unit,
- cairo_gl_operand_t *operand,
- unsigned int vertex_offset,
- cairo_bool_t vertex_size_changed)
+ cairo_gl_tex_t tex_unit,
+ cairo_gl_operand_t *operand,
+ unsigned int vertex_offset,
+ cairo_bool_t vertex_size_changed)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
cairo_bool_t needs_setup;
@@ -219,36 +316,36 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
* to no shaders (or back) */
needs_setup = vertex_size_changed;
needs_setup |= _cairo_gl_operand_needs_setup (&ctx->operands[tex_unit],
- operand,
- vertex_offset);
+ operand,
+ vertex_offset);
if (needs_setup) {
- _cairo_gl_composite_flush (ctx);
- _cairo_gl_context_destroy_operand (ctx, tex_unit);
+ _cairo_gl_composite_flush (ctx);
+ _cairo_gl_context_destroy_operand (ctx, tex_unit);
}
memcpy (&ctx->operands[tex_unit], operand, sizeof (cairo_gl_operand_t));
ctx->operands[tex_unit].vertex_offset = vertex_offset;
if (! needs_setup)
- return;
+ return;
switch (operand->type) {
default:
case CAIRO_GL_OPERAND_COUNT:
- ASSERT_NOT_REACHED;
+ ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
- break;
- /* fall through */
+ break;
+ /* fall through */
case CAIRO_GL_OPERAND_CONSTANT:
- break;
+ break;
case CAIRO_GL_OPERAND_TEXTURE:
- glActiveTexture (GL_TEXTURE0 + tex_unit);
- glBindTexture (ctx->tex_target, operand->texture.tex);
- _cairo_gl_texture_set_extend (ctx, ctx->tex_target,
- operand->texture.attributes.extend);
- _cairo_gl_texture_set_filter (ctx, ctx->tex_target,
- operand->texture.attributes.filter);
+ glActiveTexture (GL_TEXTURE0 + tex_unit);
+ glBindTexture (ctx->tex_target, operand->texture.tex);
+ _cairo_gl_texture_set_extend (ctx, ctx->tex_target,
+ operand->texture.attributes.extend);
+ _cairo_gl_texture_set_filter (ctx, ctx->tex_target,
+ operand->texture.attributes.filter);
if (! operand->texture.texgen) {
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
@@ -256,15 +353,15 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
ctx->vb + vertex_offset);
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
}
- break;
+ 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:
- 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);
- _cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
+ 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);
+ _cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
if (! operand->gradient.texgen) {
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
@@ -299,7 +396,7 @@ _cairo_gl_context_setup_spans (cairo_gl_context_t *ctx,
void
_cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
- cairo_gl_tex_t tex_unit)
+ cairo_gl_tex_t tex_unit)
{
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
@@ -309,21 +406,21 @@ _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
switch (ctx->operands[tex_unit].type) {
default:
case CAIRO_GL_OPERAND_COUNT:
- ASSERT_NOT_REACHED;
+ ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
- break;
- /* fall through */
+ break;
+ /* fall through */
case CAIRO_GL_OPERAND_CONSTANT:
- break;
+ break;
case CAIRO_GL_OPERAND_TEXTURE:
- dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
- break;
+ dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+ 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:
- dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
- break;
+ dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
+ break;
}
memset (&ctx->operands[tex_unit], 0, sizeof (cairo_gl_operand_t));
@@ -331,7 +428,7 @@ _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx,
static void
_cairo_gl_set_operator (cairo_gl_context_t *ctx,
- cairo_operator_t op,
+ cairo_operator_t op,
cairo_bool_t component_alpha)
{
struct {
@@ -359,7 +456,7 @@ _cairo_gl_set_operator (cairo_gl_context_t *ctx,
assert (op < ARRAY_LENGTH (blend_factors));
/* different dst and component_alpha changes cause flushes elsewhere */
if (ctx->current_operator != op)
- _cairo_gl_composite_flush (ctx);
+ _cairo_gl_composite_flush (ctx);
ctx->current_operator = op;
src_factor = blend_factors[op].src;
@@ -384,23 +481,23 @@ _cairo_gl_set_operator (cairo_gl_context_t *ctx,
}
if (ctx->current_target->base.content == CAIRO_CONTENT_ALPHA) {
- glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
+ glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
} else if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) {
- glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE);
+ glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE);
} else {
- glBlendFunc (src_factor, dst_factor);
+ glBlendFunc (src_factor, dst_factor);
}
}
static cairo_status_t
_cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
- cairo_gl_composite_t *setup)
+ cairo_gl_composite_t *setup)
{
cairo_gl_shader_t *pre_shader = NULL;
cairo_status_t status;
/* For CLEAR, cairo's rendering equation (quoting Owen's description in:
- * http://lists.cairographics.org/archives/cairo/2005-August/004992.html)
+ * https://lists.cairographics.org/archives/cairo/2005-August/004992.html)
* is:
* mask IN clip ? src OP dest : dest
* or more simply:
@@ -420,7 +517,7 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
* mask IN clip ? 0 : dest
*/
if (setup->op == CAIRO_OPERATOR_CLEAR) {
- _cairo_gl_solid_operand_init (&setup->src, CAIRO_COLOR_WHITE);
+ _cairo_gl_solid_operand_init (&setup->src, CAIRO_COLOR_WHITE);
setup->op = CAIRO_OPERATOR_DEST_OUT;
}
@@ -477,17 +574,17 @@ _cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx,
if (setup->op == CAIRO_OPERATOR_OVER) {
setup->op = CAIRO_OPERATOR_ADD;
status = _cairo_gl_get_shader_by_type (ctx,
- &setup->src,
- &setup->mask,
+ &setup->src,
+ &setup->mask,
setup->spans,
- CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
- &pre_shader);
- if (unlikely (status))
- return status;
+ CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA,
+ &pre_shader);
+ if (unlikely (status))
+ return status;
}
if (ctx->pre_shader != pre_shader)
- _cairo_gl_composite_flush (ctx);
+ _cairo_gl_composite_flush (ctx);
ctx->pre_shader = pre_shader;
return CAIRO_STATUS_SUCCESS;
@@ -661,7 +758,7 @@ _cairo_gl_composite_setup_clipping (cairo_gl_composite_t *setup,
if (setup->clip)
return _cairo_gl_composite_setup_painted_clipping (setup, ctx,
- vertex_size);
+ vertex_size);
disable_all_clipping:
_disable_stencil_buffer ();
glDisable (GL_SCISSOR_TEST);
@@ -701,13 +798,13 @@ _cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
component_alpha ?
CAIRO_GL_SHADER_IN_CA_SOURCE :
CAIRO_GL_SHADER_IN_NORMAL,
- &shader);
+ &shader);
if (unlikely (status)) {
ctx->pre_shader = NULL;
return status;
}
if (ctx->current_shader != shader)
- _cairo_gl_composite_flush (ctx);
+ _cairo_gl_composite_flush (ctx);
status = CAIRO_STATUS_SUCCESS;
@@ -769,7 +866,7 @@ _cairo_gl_composite_begin (cairo_gl_composite_t *setup,
FAIL:
if (unlikely (status))
- status = _cairo_gl_context_release (ctx, status);
+ status = _cairo_gl_context_release (ctx, status);
return status;
}
@@ -800,17 +897,17 @@ _cairo_gl_composite_draw_triangles (cairo_gl_context_t *ctx,
unsigned int count)
{
if (! ctx->pre_shader) {
- glDrawArrays (GL_TRIANGLES, 0, count);
+ glDrawArrays (GL_TRIANGLES, 0, count);
} else {
- cairo_gl_shader_t *prev_shader = ctx->current_shader;
+ cairo_gl_shader_t *prev_shader = ctx->current_shader;
- _cairo_gl_set_shader (ctx, ctx->pre_shader);
- _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
- glDrawArrays (GL_TRIANGLES, 0, count);
+ _cairo_gl_set_shader (ctx, ctx->pre_shader);
+ _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
+ glDrawArrays (GL_TRIANGLES, 0, count);
- _cairo_gl_set_shader (ctx, prev_shader);
- _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
- glDrawArrays (GL_TRIANGLES, 0, count);
+ _cairo_gl_set_shader (ctx, prev_shader);
+ _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
+ glDrawArrays (GL_TRIANGLES, 0, count);
}
}
@@ -849,7 +946,7 @@ _cairo_gl_composite_flush (cairo_gl_context_t *ctx)
int i;
if (_cairo_gl_context_is_flushed (ctx))
- return;
+ return;
count = ctx->vb_offset / ctx->vertex_size;
_cairo_gl_composite_unmap_vertex_buffer (ctx);
@@ -931,8 +1028,8 @@ _cairo_gl_composite_emit_point (cairo_gl_context_t *ctx,
static void
_cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
- GLfloat x1, GLfloat y1,
- GLfloat x2, GLfloat y2)
+ GLfloat x1, GLfloat y1,
+ GLfloat x2, GLfloat y2)
{
_cairo_gl_composite_prepare_buffer (ctx, 6,
CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -962,9 +1059,9 @@ _cairo_gl_context_emit_rect (cairo_gl_context_t *ctx,
static void
_cairo_gl_composite_emit_span (cairo_gl_context_t *ctx,
- GLfloat x1, GLfloat y1,
- GLfloat x2, GLfloat y2,
- uint8_t alpha)
+ GLfloat x1, GLfloat y1,
+ GLfloat x2, GLfloat y2,
+ uint8_t alpha)
{
_cairo_gl_composite_prepare_buffer (ctx, 6,
CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -1038,7 +1135,7 @@ _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
default:
case CAIRO_GL_OPERAND_COUNT:
- ASSERT_NOT_REACHED;
+ ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
case CAIRO_GL_OPERAND_CONSTANT:
break;
@@ -1079,10 +1176,10 @@ _cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx,
static void
_cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx,
- GLfloat x1, GLfloat y1,
- GLfloat x2, GLfloat y2,
- GLfloat glyph_x1, GLfloat glyph_y1,
- GLfloat glyph_x2, GLfloat glyph_y2)
+ GLfloat x1, GLfloat y1,
+ GLfloat x2, GLfloat y2,
+ GLfloat glyph_x1, GLfloat glyph_y1,
+ GLfloat glyph_x2, GLfloat glyph_y2)
{
_cairo_gl_composite_prepare_buffer (ctx, 6,
CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES);
@@ -1130,7 +1227,7 @@ _cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx)
switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
default:
case CAIRO_GL_OPERAND_COUNT:
- ASSERT_NOT_REACHED;
+ ASSERT_NOT_REACHED;
case CAIRO_GL_OPERAND_NONE:
case CAIRO_GL_OPERAND_CONSTANT:
return _cairo_gl_composite_emit_solid_glyph;
@@ -1157,13 +1254,13 @@ _cairo_gl_composite_set_operator (cairo_gl_composite_t *setup,
cairo_bool_t assume_component_alpha)
{
if (assume_component_alpha) {
- if (op != CAIRO_OPERATOR_CLEAR &&
- op != CAIRO_OPERATOR_OVER &&
- op != CAIRO_OPERATOR_ADD)
- return UNSUPPORTED ("unsupported component alpha operator");
+ if (op != CAIRO_OPERATOR_CLEAR &&
+ op != CAIRO_OPERATOR_OVER &&
+ op != CAIRO_OPERATOR_ADD)
+ return UNSUPPORTED ("unsupported component alpha operator");
} else {
- if (! _cairo_gl_operator_is_supported (op))
- return UNSUPPORTED ("unsupported operator");
+ if (! _cairo_gl_operator_is_supported (op))
+ return UNSUPPORTED ("unsupported operator");
}
setup->op = op;
@@ -1172,12 +1269,14 @@ _cairo_gl_composite_set_operator (cairo_gl_composite_t *setup,
cairo_status_t
_cairo_gl_composite_init (cairo_gl_composite_t *setup,
- cairo_operator_t op,
- cairo_gl_surface_t *dst,
- cairo_bool_t assume_component_alpha)
+ cairo_operator_t op,
+ cairo_gl_surface_t *dst,
+ cairo_bool_t assume_component_alpha)
{
cairo_status_t status;
+ status = _blit_texture_to_renderbuffer (dst);
+
memset (setup, 0, sizeof (cairo_gl_composite_t));
status = _cairo_gl_composite_set_operator (setup, op,