mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 01:48:07 +02:00
gl: Replace manual vertex transformation with VS computation of texcoords
Not only is our point transformation code is quite slow (well at least compared to a real GPU), but by deriving the texture coordinates from the vertex position we can elide the multiple arrays that we need to construct and pass to GL - improving performance by eliminating CPU overhead from needless transforms and data shovelling. However, not all vertex emission is suitable. For instance, for glyphs we need to emit discontiguous texture coordinates for each glyph, but span generation is suitable - which fortuitously also has the largest vertex density and so benefits the most. The only real concern is for hardware without true vertex shader support (e.g. i915) but there we are already invoking the VS to transform the vertex into the viewport. We would need to eliminate that transform as well as manually compute the texture coordinates in order to eliminate the vertex recomputation pass. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
d15a71f128
commit
05ad89f912
8 changed files with 162 additions and 63 deletions
|
|
@ -56,11 +56,12 @@ cairo_int_status_t
|
|||
_cairo_gl_composite_set_source (cairo_gl_composite_t *setup,
|
||||
const cairo_pattern_t *pattern,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
_cairo_gl_operand_destroy (&setup->src);
|
||||
return _cairo_gl_operand_init (&setup->src, pattern, setup->dst,
|
||||
sample, extents);
|
||||
sample, extents, use_texgen);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -83,14 +84,15 @@ cairo_int_status_t
|
|||
_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
|
||||
const cairo_pattern_t *pattern,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
_cairo_gl_operand_destroy (&setup->mask);
|
||||
if (pattern == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst,
|
||||
sample, extents);
|
||||
sample, extents, use_texgen);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -248,10 +250,12 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
|
|||
_cairo_gl_texture_set_filter (ctx, ctx->tex_target,
|
||||
operand->texture.attributes.filter);
|
||||
|
||||
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
|
||||
GL_FLOAT, GL_FALSE, vertex_size,
|
||||
ctx->vb + vertex_offset);
|
||||
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
|
||||
if (! operand->texture.texgen) {
|
||||
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
|
||||
GL_FLOAT, GL_FALSE, vertex_size,
|
||||
ctx->vb + vertex_offset);
|
||||
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
|
||||
}
|
||||
break;
|
||||
case CAIRO_GL_OPERAND_LINEAR_GRADIENT:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
|
||||
|
|
@ -262,10 +266,12 @@ _cairo_gl_context_setup_operand (cairo_gl_context_t *ctx,
|
|||
_cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend);
|
||||
_cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR);
|
||||
|
||||
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
|
||||
GL_FLOAT, GL_FALSE, vertex_size,
|
||||
ctx->vb + vertex_offset);
|
||||
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
|
||||
if (! operand->gradient.texgen) {
|
||||
dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2,
|
||||
GL_FLOAT, GL_FALSE, vertex_size,
|
||||
ctx->vb + vertex_offset);
|
||||
dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -698,8 +704,8 @@ _cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup,
|
|||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
dst_size = 2 * sizeof (GLfloat);
|
||||
src_size = _cairo_gl_operand_get_vertex_size (setup->src.type);
|
||||
mask_size = _cairo_gl_operand_get_vertex_size (setup->mask.type);
|
||||
src_size = _cairo_gl_operand_get_vertex_size (&setup->src);
|
||||
mask_size = _cairo_gl_operand_get_vertex_size (&setup->mask);
|
||||
vertex_size = dst_size + src_size + mask_size;
|
||||
|
||||
if (setup->spans)
|
||||
|
|
@ -993,8 +999,29 @@ _cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx,
|
|||
cairo_gl_emit_span_t
|
||||
_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
|
||||
{
|
||||
if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE)
|
||||
return _cairo_gl_composite_emit_span;
|
||||
if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE) {
|
||||
switch (ctx->operands[CAIRO_GL_TEX_MASK].type) {
|
||||
default:
|
||||
case CAIRO_GL_OPERAND_COUNT:
|
||||
ASSERT_NOT_REACHED;
|
||||
case CAIRO_GL_OPERAND_NONE:
|
||||
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:
|
||||
if (!ctx->operands[CAIRO_GL_TEX_MASK].gradient.texgen)
|
||||
return _cairo_gl_composite_emit_span;
|
||||
break;
|
||||
|
||||
case CAIRO_GL_OPERAND_TEXTURE:
|
||||
if (!ctx->operands[CAIRO_GL_TEX_MASK].texture.texgen)
|
||||
return _cairo_gl_composite_emit_span;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) {
|
||||
default:
|
||||
|
|
@ -1002,15 +1029,22 @@ _cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx)
|
|||
ASSERT_NOT_REACHED;
|
||||
case CAIRO_GL_OPERAND_NONE:
|
||||
case CAIRO_GL_OPERAND_CONSTANT:
|
||||
return _cairo_gl_composite_emit_solid_span;
|
||||
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:
|
||||
if (!ctx->operands[CAIRO_GL_TEX_SOURCE].gradient.texgen)
|
||||
return _cairo_gl_composite_emit_span;
|
||||
break;
|
||||
|
||||
case CAIRO_GL_OPERAND_TEXTURE:
|
||||
return _cairo_gl_composite_emit_span;
|
||||
if (!ctx->operands[CAIRO_GL_TEX_SOURCE].texture.texgen)
|
||||
return _cairo_gl_composite_emit_span;
|
||||
}
|
||||
|
||||
return _cairo_gl_composite_emit_solid_span;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
|
|
@ -343,7 +343,8 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
|
|||
status = _cairo_gl_composite_set_source (&setup,
|
||||
&composite->mask_pattern.base,
|
||||
&composite->mask_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
if (unlikely (status))
|
||||
goto finish;
|
||||
_cairo_gl_composite_set_multisample (&setup);
|
||||
|
|
@ -364,13 +365,15 @@ _cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compos
|
|||
status = _cairo_gl_composite_set_source (&setup,
|
||||
&composite->source_pattern.base,
|
||||
&composite->source_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
if (unlikely (status))
|
||||
goto finish;
|
||||
status = _cairo_gl_composite_set_mask (&setup,
|
||||
&composite->mask_pattern.base,
|
||||
&composite->source_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
if (unlikely (status))
|
||||
goto finish;
|
||||
status = _cairo_gl_set_operands_and_operator (&setup, ctx);
|
||||
|
|
@ -462,7 +465,8 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
|
|||
status = _cairo_gl_composite_set_source (&setup,
|
||||
&composite->source_pattern.base,
|
||||
&composite->source_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
if (unlikely (status))
|
||||
goto finish;
|
||||
|
||||
|
|
@ -470,7 +474,8 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor,
|
|||
status = _cairo_gl_composite_set_mask (&setup,
|
||||
&composite->mask_pattern.base,
|
||||
&composite->mask_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
}
|
||||
if (unlikely (status))
|
||||
goto finish;
|
||||
|
|
@ -674,7 +679,8 @@ _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor,
|
|||
status = _cairo_gl_composite_set_source (&info.setup,
|
||||
&composite->source_pattern.base,
|
||||
&composite->source_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
if (unlikely (status))
|
||||
goto finish;
|
||||
|
||||
|
|
@ -793,7 +799,8 @@ _cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor,
|
|||
status = _cairo_gl_composite_set_source (&setup,
|
||||
&composite->source_pattern.base,
|
||||
&composite->source_sample_area,
|
||||
&composite->bounded);
|
||||
&composite->bounded,
|
||||
FALSE);
|
||||
if (unlikely (status))
|
||||
goto cleanup_setup;
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
|
|||
const cairo_pattern_t *_src,
|
||||
cairo_gl_surface_t *dst,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
|
||||
cairo_surface_pattern_t local_pattern;
|
||||
|
|
@ -185,6 +186,8 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
|
|||
attributes->extend = src->base.extend;
|
||||
attributes->filter = src->base.filter;
|
||||
attributes->has_component_alpha = src->base.has_component_alpha;
|
||||
|
||||
operand->texture.texgen = use_texgen;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +196,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
|
|||
const cairo_pattern_t *_src,
|
||||
cairo_gl_surface_t *dst,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
|
||||
cairo_surface_subsurface_t *sub;
|
||||
|
|
@ -208,7 +212,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
|
|||
sample->y + sample->height > sub->extents.height)
|
||||
{
|
||||
return _cairo_gl_subsurface_clone_operand_init (operand, _src,
|
||||
dst, sample, extents);
|
||||
dst, sample, extents,
|
||||
use_texgen);
|
||||
}
|
||||
|
||||
surface = (cairo_gl_surface_t *) sub->target;
|
||||
|
|
@ -239,6 +244,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
|
|||
attributes->extend = src->base.extend;
|
||||
attributes->filter = src->base.filter;
|
||||
attributes->has_component_alpha = src->base.has_component_alpha;
|
||||
|
||||
operand->texture.texgen = use_texgen;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +254,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
|
|||
const cairo_pattern_t *_src,
|
||||
cairo_gl_surface_t *dst,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
|
||||
cairo_gl_surface_t *surface;
|
||||
|
|
@ -261,7 +269,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
|
|||
if (surface->base.backend->type != CAIRO_SURFACE_TYPE_GL) {
|
||||
if (_cairo_surface_is_subsurface (&surface->base))
|
||||
return _cairo_gl_subsurface_operand_init (operand, _src, dst,
|
||||
sample, extents);
|
||||
sample, extents,
|
||||
use_texgen);
|
||||
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
|
@ -286,6 +295,8 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
|
|||
attributes->extend = src->base.extend;
|
||||
attributes->filter = src->base.filter;
|
||||
attributes->has_component_alpha = src->base.has_component_alpha;
|
||||
|
||||
operand->texture.texgen = use_texgen;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -392,7 +403,8 @@ _cairo_gl_operand_translate (cairo_gl_operand_t *operand,
|
|||
static cairo_status_t
|
||||
_cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
|
||||
const cairo_pattern_t *pattern,
|
||||
cairo_gl_surface_t *dst)
|
||||
cairo_gl_surface_t *dst,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
const cairo_gradient_pattern_t *gradient = (const cairo_gradient_pattern_t *)pattern;
|
||||
cairo_status_t status;
|
||||
|
|
@ -475,6 +487,7 @@ _cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand,
|
|||
}
|
||||
|
||||
operand->gradient.extend = pattern->extend;
|
||||
operand->gradient.texgen = use_texgen;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -534,7 +547,8 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
|
|||
const cairo_pattern_t *pattern,
|
||||
cairo_gl_surface_t *dst,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents)
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
|
|
@ -546,7 +560,7 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
status = _cairo_gl_surface_operand_init (operand, pattern, dst,
|
||||
sample, extents);
|
||||
sample, extents, use_texgen);
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
break;
|
||||
|
||||
|
|
@ -554,7 +568,8 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
|
|||
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
status = _cairo_gl_gradient_operand_init (operand, pattern, dst);
|
||||
status = _cairo_gl_gradient_operand_init (operand, pattern, dst,
|
||||
use_texgen);
|
||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
break;
|
||||
|
||||
|
|
@ -634,6 +649,7 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
char uniform_name[50];
|
||||
char *custom_part;
|
||||
static const char *names[] = { "source", "mask" };
|
||||
const cairo_matrix_t *texgen = NULL;
|
||||
|
||||
strcpy (uniform_name, names[tex_unit]);
|
||||
custom_part = uniform_name + strlen (names[tex_unit]);
|
||||
|
|
@ -643,7 +659,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
case CAIRO_GL_OPERAND_COUNT:
|
||||
ASSERT_NOT_REACHED;
|
||||
case CAIRO_GL_OPERAND_NONE:
|
||||
break;
|
||||
return;
|
||||
|
||||
case CAIRO_GL_OPERAND_CONSTANT:
|
||||
strcpy (custom_part, "_constant");
|
||||
_cairo_gl_shader_bind_vec4 (ctx,
|
||||
|
|
@ -652,7 +669,8 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
operand->constant.color[1],
|
||||
operand->constant.color[2],
|
||||
operand->constant.color[3]);
|
||||
break;
|
||||
return;
|
||||
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
|
||||
strcpy (custom_part, "_a");
|
||||
|
|
@ -695,7 +713,21 @@ _cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx,
|
|||
strcpy (custom_part, "_texdims");
|
||||
_cairo_gl_shader_bind_vec2 (ctx, uniform_name, width, height);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (operand->type == CAIRO_GL_OPERAND_TEXTURE) {
|
||||
if (operand->texture.texgen)
|
||||
texgen = &operand->texture.attributes.matrix;
|
||||
} else {
|
||||
if (operand->gradient.texgen)
|
||||
texgen = &operand->gradient.m;
|
||||
}
|
||||
if (texgen) {
|
||||
char name[20];
|
||||
|
||||
sprintf (name, "%s_texgen", names[tex_unit]);
|
||||
_cairo_gl_shader_bind_matrix(ctx, name, texgen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -738,9 +770,9 @@ _cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
|
|||
}
|
||||
|
||||
unsigned int
|
||||
_cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type)
|
||||
_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand)
|
||||
{
|
||||
switch (type) {
|
||||
switch (operand->type) {
|
||||
default:
|
||||
case CAIRO_GL_OPERAND_COUNT:
|
||||
ASSERT_NOT_REACHED;
|
||||
|
|
@ -748,11 +780,12 @@ _cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type)
|
|||
case CAIRO_GL_OPERAND_CONSTANT:
|
||||
return 0;
|
||||
case CAIRO_GL_OPERAND_TEXTURE:
|
||||
return operand->texture.texgen ? 0 : 2 * sizeof (GLfloat);
|
||||
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:
|
||||
return 2 * sizeof (GLfloat);
|
||||
return operand->gradient.texgen ? 0 : 2 * sizeof (GLfloat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -773,7 +806,7 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
|
|||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
|
||||
{
|
||||
if (! operand->gradient.texgen) {
|
||||
double s = x;
|
||||
double t = y;
|
||||
|
||||
|
|
@ -784,7 +817,7 @@ _cairo_gl_operand_emit (cairo_gl_operand_t *operand,
|
|||
}
|
||||
break;
|
||||
case CAIRO_GL_OPERAND_TEXTURE:
|
||||
{
|
||||
if (! operand->texture.texgen) {
|
||||
cairo_surface_attributes_t *src_attributes = &operand->texture.attributes;
|
||||
double s = x;
|
||||
double t = y;
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ typedef struct cairo_gl_operand {
|
|||
cairo_gl_surface_t *surface;
|
||||
cairo_gl_surface_t *owns_surface;
|
||||
cairo_surface_attributes_t attributes;
|
||||
int texgen;
|
||||
} texture;
|
||||
struct {
|
||||
GLfloat color[4];
|
||||
|
|
@ -146,6 +147,7 @@ typedef struct cairo_gl_operand {
|
|||
cairo_circle_double_t circle_d;
|
||||
double radius_0, a;
|
||||
cairo_extend_t extend;
|
||||
int texgen;
|
||||
} gradient;
|
||||
};
|
||||
unsigned int vertex_offset;
|
||||
|
|
@ -212,6 +214,7 @@ typedef enum cairo_gl_shader_in {
|
|||
typedef enum cairo_gl_var_type {
|
||||
CAIRO_GL_VAR_NONE,
|
||||
CAIRO_GL_VAR_TEXCOORDS,
|
||||
CAIRO_GL_VAR_TEXGEN,
|
||||
} cairo_gl_var_type_t;
|
||||
|
||||
typedef enum cairo_gl_primitive_type {
|
||||
|
|
@ -234,8 +237,8 @@ typedef void (*cairo_gl_emit_glyph_t) (cairo_gl_context_t *ctx,
|
|||
GLfloat glyph_x1, GLfloat glyph_y1,
|
||||
GLfloat glyph_x2, GLfloat glyph_y2);
|
||||
|
||||
#define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 3) | ((mask) << 2 | (src << 1) | (dest))
|
||||
#define CAIRO_GL_VAR_TYPE_MAX ((CAIRO_GL_VAR_TEXCOORDS << 3) | (CAIRO_GL_VAR_TEXCOORDS << 2) | (CAIRO_GL_VAR_TEXCOORDS << 1) | CAIRO_GL_VAR_TEXCOORDS)
|
||||
#define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 5) | ((mask) << 3 | (src << 1) | (dest))
|
||||
#define CAIRO_GL_VAR_TYPE_MAX (1 << 6)
|
||||
|
||||
typedef void (*cairo_gl_generic_func_t)(void);
|
||||
typedef cairo_gl_generic_func_t (*cairo_gl_get_proc_addr_func_t)(const char *procname);
|
||||
|
|
@ -334,7 +337,7 @@ struct _cairo_gl_context {
|
|||
|
||||
cairo_bool_t has_shader_support;
|
||||
|
||||
GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX + 1];
|
||||
GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX];
|
||||
cairo_gl_shader_t fill_rectangles_shader;
|
||||
cairo_cache_t shaders;
|
||||
|
||||
|
|
@ -542,9 +545,10 @@ _cairo_gl_composite_set_clip(cairo_gl_composite_t *setup,
|
|||
|
||||
cairo_private 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);
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup,
|
||||
|
|
@ -558,7 +562,8 @@ cairo_private cairo_int_status_t
|
|||
_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup,
|
||||
const cairo_pattern_t *pattern,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents);
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup,
|
||||
|
|
@ -665,7 +670,7 @@ _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
|
|||
cairo_private void
|
||||
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
|
||||
const char *name,
|
||||
cairo_matrix_t* m);
|
||||
const cairo_matrix_t* m);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx,
|
||||
|
|
@ -697,7 +702,8 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand,
|
|||
const cairo_pattern_t *pattern,
|
||||
cairo_gl_surface_t *dst,
|
||||
const cairo_rectangle_int_t *sample,
|
||||
const cairo_rectangle_int_t *extents);
|
||||
const cairo_rectangle_int_t *extents,
|
||||
cairo_bool_t use_texgen);
|
||||
|
||||
cairo_private void
|
||||
_cairo_gl_solid_operand_init (cairo_gl_operand_t *operand,
|
||||
|
|
@ -713,7 +719,7 @@ cairo_private cairo_extend_t
|
|||
_cairo_gl_operand_get_extend (cairo_gl_operand_t *operand);
|
||||
|
||||
cairo_private unsigned int
|
||||
_cairo_gl_operand_get_vertex_size (cairo_gl_operand_type_t type);
|
||||
_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest,
|
||||
|
|
|
|||
|
|
@ -215,9 +215,9 @@ _cairo_gl_shader_fini (cairo_gl_context_t *ctx,
|
|||
static const char *operand_names[] = { "source", "mask", "dest" };
|
||||
|
||||
static cairo_gl_var_type_t
|
||||
cairo_gl_operand_get_var_type (cairo_gl_operand_type_t type)
|
||||
cairo_gl_operand_get_var_type (cairo_gl_operand_t *operand)
|
||||
{
|
||||
switch (type) {
|
||||
switch (operand->type) {
|
||||
default:
|
||||
case CAIRO_GL_OPERAND_COUNT:
|
||||
ASSERT_NOT_REACHED;
|
||||
|
|
@ -228,8 +228,9 @@ cairo_gl_operand_get_var_type (cairo_gl_operand_type_t type)
|
|||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE:
|
||||
case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT:
|
||||
return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
|
||||
case CAIRO_GL_OPERAND_TEXTURE:
|
||||
return CAIRO_GL_VAR_TEXCOORDS;
|
||||
return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +246,16 @@ cairo_gl_shader_emit_variable (cairo_output_stream_t *stream,
|
|||
break;
|
||||
case CAIRO_GL_VAR_TEXCOORDS:
|
||||
_cairo_output_stream_printf (stream,
|
||||
"attribute vec4 MultiTexCoord%d;\n"
|
||||
"varying vec2 %s_texcoords;\n",
|
||||
name,
|
||||
operand_names[name]);
|
||||
break;
|
||||
case CAIRO_GL_VAR_TEXGEN:
|
||||
_cairo_output_stream_printf (stream,
|
||||
"uniform mat3 %s_texgen;\n"
|
||||
"varying vec2 %s_texcoords;\n",
|
||||
operand_names[name],
|
||||
operand_names[name]);
|
||||
break;
|
||||
}
|
||||
|
|
@ -266,6 +276,12 @@ cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream,
|
|||
" %s_texcoords = MultiTexCoord%d.xy;\n",
|
||||
operand_names[name], name);
|
||||
break;
|
||||
|
||||
case CAIRO_GL_VAR_TEXGEN:
|
||||
_cairo_output_stream_printf (stream,
|
||||
" %s_texcoords = (%s_texgen * Vertex.xyw).xy;\n",
|
||||
operand_names[name], operand_names[name]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -301,8 +317,6 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src,
|
|||
_cairo_output_stream_printf (stream,
|
||||
"attribute vec4 Vertex;\n"
|
||||
"attribute vec4 Color;\n"
|
||||
"attribute vec4 MultiTexCoord0;\n"
|
||||
"attribute vec4 MultiTexCoord1;\n"
|
||||
"uniform mat4 ModelViewProjectionMatrix;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
|
|
@ -920,7 +934,8 @@ _cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx,
|
|||
|
||||
void
|
||||
_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx,
|
||||
const char *name, cairo_matrix_t* m)
|
||||
const char *name,
|
||||
const cairo_matrix_t* m)
|
||||
{
|
||||
cairo_gl_dispatch_t *dispatch = &ctx->dispatch;
|
||||
GLint location = dispatch->GetUniformLocation (ctx->current_shader->program,
|
||||
|
|
@ -1016,8 +1031,8 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx,
|
|||
_cairo_gl_shader_init (&entry->shader);
|
||||
status = _cairo_gl_shader_compile_and_link (ctx,
|
||||
&entry->shader,
|
||||
cairo_gl_operand_get_var_type (source->type),
|
||||
cairo_gl_operand_get_var_type (mask->type),
|
||||
cairo_gl_operand_get_var_type (source),
|
||||
cairo_gl_operand_get_var_type (mask),
|
||||
use_coverage,
|
||||
fs_source);
|
||||
free (fs_source);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@ _cairo_gl_pattern_to_source (cairo_surface_t *dst,
|
|||
*src_x = *src_y = 0;
|
||||
status = _cairo_gl_operand_init (&source->operand, pattern,
|
||||
(cairo_gl_surface_t *)dst,
|
||||
sample, extents);
|
||||
sample, extents,
|
||||
FALSE);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (&source->base);
|
||||
return _cairo_surface_create_in_error (status);
|
||||
|
|
|
|||
|
|
@ -454,7 +454,8 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
|
|||
|
||||
status = _cairo_gl_composite_set_source (&r->setup, source,
|
||||
&composite->source_sample_area,
|
||||
&composite->unbounded);
|
||||
&composite->unbounded,
|
||||
TRUE);
|
||||
if (unlikely (status))
|
||||
goto FAIL;
|
||||
|
||||
|
|
@ -465,7 +466,8 @@ _cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r,
|
|||
status = _cairo_gl_composite_set_mask (&r->setup,
|
||||
&composite->mask_pattern.base,
|
||||
&composite->mask_sample_area,
|
||||
&composite->unbounded);
|
||||
&composite->unbounded,
|
||||
TRUE);
|
||||
if (unlikely (status))
|
||||
goto FAIL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,7 +358,8 @@ traps_to_operand (void *_dst,
|
|||
pattern.base.extend = CAIRO_EXTEND_NONE;
|
||||
status = _cairo_gl_operand_init (operand, &pattern.base, _dst,
|
||||
&_cairo_unbounded_rectangle,
|
||||
&_cairo_unbounded_rectangle);
|
||||
&_cairo_unbounded_rectangle,
|
||||
FALSE);
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
if (unlikely (status))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue