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_size, unsigned int vertex_offset) { cairo_gl_dispatch_t *dispatch = &ctx->dispatch; cairo_bool_t needs_setup; /* XXX: we need to do setup when switching from shaders * to no shaders (or back) */ needs_setup = ctx->vertex_size != vertex_size; needs_setup |= _cairo_gl_operand_needs_setup (&ctx->operands[tex_unit], operand, vertex_offset); if (needs_setup) { _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; switch (operand->type) { default: case CAIRO_GL_OPERAND_COUNT: ASSERT_NOT_REACHED; case CAIRO_GL_OPERAND_NONE: break; /* fall through */ case CAIRO_GL_OPERAND_CONSTANT: 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); dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2, GL_FLOAT, GL_FALSE, vertex_size, (void *) (uintptr_t) 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: 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); dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2, GL_FLOAT, GL_FALSE, vertex_size, (void *) (uintptr_t) vertex_offset); dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit); break; } }
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_size, unsigned int vertex_offset) { cairo_gl_dispatch_t *dispatch = &ctx->dispatch; cairo_bool_t needs_setup; cairo_bool_t needs_flush = TRUE; /* XXX: we need to do setup when switching from shaders * to no shaders (or back) */ needs_setup = ctx->vertex_size != vertex_size; needs_setup |= _cairo_gl_operand_needs_setup (&ctx->operands[tex_unit], operand, vertex_offset, &needs_flush); if (needs_setup && needs_flush) { _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; switch (operand->type) { default: case CAIRO_GL_OPERAND_COUNT: ASSERT_NOT_REACHED; case CAIRO_GL_OPERAND_NONE: break; /* fall through */ case CAIRO_GL_OPERAND_CONSTANT: if (operand->use_color_attribute) { dispatch->VertexAttribPointer (CAIRO_GL_COLOR_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, vertex_size, ctx->vb + vertex_offset); dispatch->EnableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX); } break; case CAIRO_GL_OPERAND_TEXTURE: if (ctx->states_cache.active_texture != GL_TEXTURE0 + tex_unit) { glActiveTexture (GL_TEXTURE0 + tex_unit); ctx->states_cache.active_texture = GL_TEXTURE0 + tex_unit; } glBindTexture (ctx->tex_target, operand->texture.tex); _cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->texture.attributes.extend, operand->texture.use_atlas); _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.use_atlas) { dispatch->VertexAttribPointer (CAIRO_GL_START_COORD0_ATTRIB_INDEX + tex_unit, 2, GL_FLOAT, GL_FALSE, vertex_size, ctx->vb + vertex_offset + 2 * sizeof (float)); dispatch->EnableVertexAttribArray (CAIRO_GL_START_COORD0_ATTRIB_INDEX + tex_unit); dispatch->VertexAttribPointer (CAIRO_GL_STOP_COORD0_ATTRIB_INDEX + tex_unit, 2, GL_FLOAT, GL_FALSE, vertex_size, ctx->vb + vertex_offset + 4 * sizeof (float)); dispatch->EnableVertexAttribArray (CAIRO_GL_STOP_COORD0_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: if(ctx->states_cache.active_texture != GL_TEXTURE0 + tex_unit) { glActiveTexture (GL_TEXTURE0 + tex_unit); ctx->states_cache.active_texture = GL_TEXTURE0 + tex_unit; } glBindTexture (ctx->tex_target, operand->gradient.gradient->tex); _cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend, FALSE); _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); break; } }