From 1b9a247174d7d23a1de36738437046734ef9568d Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Mon, 25 Oct 2010 13:25:21 +0100 Subject: [PATCH] cogl: Adds {push,pop,get}_source functions This exposes the idea of a stack of source materials instead of just having a single current material. This allows the writing of orthogonal code that can change the current source material and restore it to its previous state. It also allows the implementation of new composite primitives that may want to validate the current source material and possibly make override changes in a derived material. --- cogl/cogl-clip-stack.c | 7 +- cogl/cogl-context.c | 6 +- cogl/cogl-context.h | 2 +- cogl/cogl-material-private.h | 3 + cogl/cogl-path.c | 41 +++++----- cogl/cogl-primitives.c | 99 +++++++++++------------ cogl/cogl-texture.c | 7 +- cogl/cogl-vertex-buffer.c | 38 +++++---- cogl/cogl.c | 113 ++++++++++++++++++++++++--- cogl/cogl.h | 58 ++++++++++++-- doc/reference/cogl/cogl-sections.txt | 3 + 11 files changed, 254 insertions(+), 123 deletions(-) diff --git a/cogl/cogl-clip-stack.c b/cogl/cogl-clip-stack.c index 120793dd7..9f33274bb 100644 --- a/cogl/cogl-clip-stack.c +++ b/cogl/cogl-clip-stack.c @@ -298,7 +298,6 @@ add_stencil_clip_rectangle (float x_1, float y_2, gboolean first) { - CoglHandle current_source; CoglFramebuffer *framebuffer = _cogl_get_framebuffer (); _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -310,8 +309,7 @@ add_stencil_clip_rectangle (float x_1, _cogl_framebuffer_flush_state (framebuffer, 0); /* temporarily swap in our special stenciling material */ - current_source = cogl_object_ref (ctx->source_material); - cogl_set_source (ctx->stencil_material); + cogl_push_source (ctx->stencil_material); if (first) { @@ -370,8 +368,7 @@ add_stencil_clip_rectangle (float x_1, GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); /* restore the original source material */ - cogl_set_source (current_source); - cogl_object_unref (current_source); + cogl_pop_source (); } static void diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index 5b3418a5a..38954caf6 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -130,8 +130,8 @@ cogl_create_context (void) _context->legacy_fog_state.enabled = FALSE; _context->simple_material = cogl_material_new (); - _context->source_material = NULL; _context->arbfp_source_buffer = g_string_new (""); + _context->source_stack = NULL; _context->legacy_state_set = 0; @@ -226,8 +226,8 @@ cogl_create_context (void) 0, /* auto calc row stride */ default_texture_data); - cogl_set_source (_context->simple_material); - _cogl_material_flush_gl_state (_context->source_material, FALSE); + cogl_push_source (_context->simple_material); + _cogl_material_flush_gl_state (_context->simple_material, FALSE); _cogl_enable (enable_flags); _cogl_flush_face_winding (); diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h index 028b79fa7..50eef3556 100644 --- a/cogl/cogl-context.h +++ b/cogl/cogl-context.h @@ -84,8 +84,8 @@ typedef struct /* Materials */ CoglMaterial *simple_material; - CoglMaterial *source_material; GString *arbfp_source_buffer; + GList *source_stack; int legacy_state_set; diff --git a/cogl/cogl-material-private.h b/cogl/cogl-material-private.h index 1a3915217..b3820e25d 100644 --- a/cogl/cogl-material-private.h +++ b/cogl/cogl-material-private.h @@ -919,5 +919,8 @@ _cogl_material_get_layer_combine_constant (CoglMaterial *material, int layer_index, float *constant); +void +_cogl_material_prune_to_n_layers (CoglMaterial *material, int n); + #endif /* __COGL_MATERIAL_PRIVATE_H */ diff --git a/cogl/cogl-path.c b/cogl/cogl-path.c index 904b7ef65..2ac194975 100644 --- a/cogl/cogl-path.c +++ b/cogl/cogl-path.c @@ -181,7 +181,8 @@ _cogl_path_stroke_nodes (void) unsigned int path_start = 0; unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY; CoglPathData *data; - CoglHandle source; + CoglMaterial *copy = NULL; + CoglMaterial *source; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -198,25 +199,25 @@ _cogl_path_stroke_nodes (void) if (G_UNLIKELY (ctx->legacy_state_set)) { - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_legacy_state (source); + CoglMaterial *users_source = cogl_get_source (); + copy = cogl_material_copy (users_source); + _cogl_material_apply_legacy_state (copy); + source = copy; } else - source = ctx->source_material; + source = cogl_get_source (); if (cogl_material_get_n_layers (source) != 0) { - CoglMaterialFlushOptions options; - options.flags = COGL_MATERIAL_FLUSH_DISABLE_MASK; - /* disable all texture layers */ - options.disable_layers = (guint32)~0; - - /* If we haven't already created a derived material... */ - if (source == ctx->source_material) - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_overrides (source, &options); + /* If we haven't already created a derivative material... */ + if (!copy) + copy = cogl_material_copy (source); + _cogl_material_prune_to_n_layers (copy, 0); + source = copy; } + cogl_push_source (source); + _cogl_material_flush_gl_state (source, FALSE); /* Disable all client texture coordinate arrays */ @@ -234,8 +235,7 @@ _cogl_path_stroke_nodes (void) path_start += node->path_size; } - if (G_UNLIKELY (source != ctx->source_material)) - cogl_handle_unref (source); + cogl_pop_source (); } void @@ -308,7 +308,7 @@ _cogl_path_fill_nodes (CoglPath *path) textures or textures with waste then it won't work to draw the path directly. Instead we can use draw the texture as a quad clipped to the stencil buffer. */ - for (l = cogl_material_get_layers (ctx->source_material); l; l = l->next) + for (l = cogl_material_get_layers (cogl_get_source ()); l; l = l->next) { CoglHandle layer = l->data; CoglHandle texture = cogl_material_layer_get_texture (layer); @@ -352,7 +352,6 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path, { CoglPathData *data = path->data; unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY; - CoglHandle prev_source; CoglFramebuffer *framebuffer = _cogl_get_framebuffer (); CoglMatrixStack *modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer); @@ -371,10 +370,9 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path, _cogl_framebuffer_flush_state (framebuffer, 0); /* Just setup a simple material that doesn't use texturing... */ - prev_source = cogl_object_ref (ctx->source_material); - cogl_set_source (ctx->stencil_material); + cogl_push_source (ctx->stencil_material); - _cogl_material_flush_gl_state (ctx->source_material, FALSE); + _cogl_material_flush_gl_state (ctx->stencil_material, FALSE); _cogl_enable (enable_flags); @@ -464,8 +462,7 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path, GE (glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP)); /* restore the original material */ - cogl_set_source (prev_source); - cogl_object_unref (prev_source); + cogl_pop_source (); } void diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c index f380795bf..8f0c41a87 100644 --- a/cogl/cogl-primitives.c +++ b/cogl/cogl-primitives.c @@ -495,17 +495,17 @@ _cogl_rectangles_with_multitexture_coords ( struct _CoglMutiTexturedRect *rects, int n_rects) { - CoglHandle material; - const GList *layers; - int n_layers; - const GList *tmp; - guint32 fallback_layers = 0; - gboolean all_use_sliced_quad_fallback = FALSE; - int i; + CoglMaterial *material; + const GList *layers; + int n_layers; + const GList *tmp; + guint32 fallback_layers = 0; + gboolean all_use_sliced_quad_fallback = FALSE; + int i; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - material = ctx->source_material; + material = cogl_get_source (); layers = cogl_material_get_layers (material); n_layers = cogl_material_get_n_layers (material); @@ -839,7 +839,7 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle, float virtual_origin_y; float v_to_s_scale_x; float v_to_s_scale_y; - CoglHandle source; + CoglMaterial *source; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -868,13 +868,10 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle, v += state->stride; } + source = cogl_material_copy (cogl_get_source ()); + if (G_UNLIKELY (ctx->legacy_state_set)) - { - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_legacy_state (source); - } - else - source = ctx->source_material; + _cogl_material_apply_legacy_state (source); options.flags = COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE | @@ -904,16 +901,13 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle, } /* If we haven't already created a derived material... */ - if (source == ctx->source_material) - source = cogl_material_copy (ctx->source_material); _cogl_material_apply_overrides (source, &options); _cogl_material_flush_gl_state (source, FALSE); GE (glDrawArrays (GL_TRIANGLE_FAN, 0, state->n_vertices)); - if (G_UNLIKELY (source != ctx->source_material)) - cogl_handle_unref (source); + cogl_handle_unref (source); } /* handles 2d-sliced textures with > 1 slice */ @@ -934,7 +928,7 @@ _cogl_texture_polygon_multiple_primitives (const CoglTextureVertex *vertices, /* We can assume in this case that we have at least one layer in the * material that corresponds to a sliced cogl texture */ - layers = cogl_material_get_layers (ctx->source_material); + layers = cogl_material_get_layers (cogl_get_source ()); layer0 = (CoglHandle)layers->data; tex_handle = cogl_material_layer_get_texture (layer0); @@ -986,11 +980,12 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices, GList *tmp; GLfloat *v; CoglMaterialFlushOptions options; - CoglHandle source; + CoglMaterial *copy = NULL; + CoglMaterial *source; _COGL_GET_CONTEXT (ctx, NO_RETVAL); - material = ctx->source_material; + material = cogl_get_source (); layers = cogl_material_get_layers (material); /* Convert the vertices into an array of GLfloats ready to pass to @@ -1045,11 +1040,12 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices, if (G_UNLIKELY (ctx->legacy_state_set)) { - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_legacy_state (source); + copy = cogl_material_copy (cogl_get_source ()); + _cogl_material_apply_legacy_state (copy); + source = copy; } else - source = ctx->source_material; + source = cogl_get_source (); options.flags = 0; @@ -1066,17 +1062,20 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices, if (options.flags) { /* If we haven't already created a derived material... */ - if (source == ctx->source_material) - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_overrides (source, &options); + if (!copy) + { + copy = cogl_material_copy (source); + source = copy; + } + _cogl_material_apply_overrides (copy, &options); } _cogl_material_flush_gl_state (source, use_color); GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices)); - if (G_UNLIKELY (source != ctx->source_material)) - cogl_handle_unref (source); + if (G_UNLIKELY (copy)) + cogl_handle_unref (copy); } void @@ -1084,7 +1083,8 @@ cogl_polygon (const CoglTextureVertex *vertices, unsigned int n_vertices, gboolean use_color) { - CoglHandle material; + CoglMaterial *material; + CoglMaterial *copy = NULL; const GList *layers, *tmp; int n_layers; gboolean use_sliced_polygon_fallback = FALSE; @@ -1096,8 +1096,6 @@ cogl_polygon (const CoglTextureVertex *vertices, GLfloat *v; CoglMaterialWrapModeOverrides wrap_mode_overrides; CoglMaterialWrapModeOverrides *wrap_mode_overrides_p = NULL; - CoglHandle original_source_material = NULL; - gboolean overrode_material = FALSE; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -1108,8 +1106,8 @@ cogl_polygon (const CoglTextureVertex *vertices, * always be done first when preparing to draw. */ _cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0); - material = ctx->source_material; - layers = cogl_material_get_layers (ctx->source_material); + material = cogl_get_source (); + layers = cogl_material_get_layers (material); n_layers = g_list_length ((GList *)layers); memset (&wrap_mode_overrides, 0, sizeof (wrap_mode_overrides)); @@ -1237,24 +1235,19 @@ cogl_polygon (const CoglTextureVertex *vertices, if (use_color) { - CoglHandle override; enable_flags |= COGL_ENABLE_COLOR_ARRAY; GE( glColorPointer (4, GL_UNSIGNED_BYTE, stride_bytes, /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */ v + 3 + 2 * n_layers) ); - if (!_cogl_material_get_real_blend_enabled (ctx->source_material)) + if (!_cogl_material_get_real_blend_enabled (material)) { CoglMaterialBlendEnable blend_enabled = COGL_MATERIAL_BLEND_ENABLE_ENABLED; - original_source_material = ctx->source_material; - override = cogl_material_copy (original_source_material); - _cogl_material_set_blend_enabled (override, blend_enabled); - - /* XXX: cogl_push_source () */ - overrode_material = TRUE; - ctx->source_material = override; + copy = cogl_material_copy (material); + _cogl_material_set_blend_enabled (copy, blend_enabled); + material = copy; } } @@ -1277,6 +1270,8 @@ cogl_polygon (const CoglTextureVertex *vertices, _cogl_bitmask_set_range (&ctx->temp_bitmask, n_layers, TRUE); _cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask); + cogl_push_source (material); + if (use_sliced_polygon_fallback) _cogl_texture_polygon_multiple_primitives (vertices, n_vertices, @@ -1291,15 +1286,13 @@ cogl_polygon (const CoglTextureVertex *vertices, fallback_layers, wrap_mode_overrides_p); - /* XXX: cogl_pop_source () */ - if (overrode_material) - { - cogl_handle_unref (ctx->source_material); - ctx->source_material = original_source_material; - /* XXX: when we have weak materials then any override material - * should get associated with the original material so we don't - * create lots of one-shot materials! */ - } + cogl_pop_source (); + + if (copy) + cogl_object_unref (copy); + /* XXX: when we have weak materials then any override material + * should get associated with the original material so we don't + * create lots of one-shot materials! */ /* Reset the size of the logged vertex array because rendering rectangles expects it to start at 0 */ diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c index 157d62720..22b0a1fdf 100644 --- a/cogl/cogl-texture.c +++ b/cogl/cogl-texture.c @@ -1047,7 +1047,6 @@ _cogl_texture_draw_and_read (CoglHandle handle, CoglFramebuffer *framebuffer; int viewport[4]; CoglBitmap *alpha_bmp; - CoglHandle prev_source; CoglMatrixStack *projection_stack; CoglMatrixStack *modelview_stack; int target_width = _cogl_bitmap_get_width (target_bmp); @@ -1093,8 +1092,7 @@ _cogl_texture_draw_and_read (CoglHandle handle, NULL); } - prev_source = cogl_handle_ref (ctx->source_material); - cogl_set_source (ctx->texture_download_material); + cogl_push_source (ctx->texture_download_material); cogl_material_set_layer (ctx->texture_download_material, 0, handle); @@ -1178,8 +1176,7 @@ _cogl_texture_draw_and_read (CoglHandle handle, _cogl_matrix_stack_pop (projection_stack); /* restore the original material */ - cogl_set_source (prev_source); - cogl_handle_unref (prev_source); + cogl_pop_source (); return TRUE; } diff --git a/cogl/cogl-vertex-buffer.c b/cogl/cogl-vertex-buffer.c index 65f275a65..31522e6d6 100644 --- a/cogl/cogl-vertex-buffer.c +++ b/cogl/cogl-vertex-buffer.c @@ -1524,11 +1524,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) int i; gboolean skip_gl_color = FALSE; CoglMaterialFlushOptions options; - CoglHandle source; + CoglMaterial *source; + CoglMaterial *copy = NULL; _COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE); - source = ctx->source_material; + source = cogl_get_source (); if (buffer->new_attributes) cogl_vertex_buffer_submit_real (buffer); @@ -1592,12 +1593,13 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) attribute->stride, pointer)); - if (!_cogl_material_get_real_blend_enabled (ctx->source_material)) + if (!_cogl_material_get_real_blend_enabled (source)) { CoglMaterialBlendEnable blend_enable = COGL_MATERIAL_BLEND_ENABLE_ENABLED; - source = cogl_material_copy (ctx->source_material); - _cogl_material_set_blend_enabled (source, blend_enable); + copy = cogl_material_copy (source); + _cogl_material_set_blend_enabled (copy, blend_enable); + source = copy; skip_gl_color = TRUE; } break; @@ -1745,9 +1747,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) if (G_UNLIKELY (options.flags)) { /* If we haven't already created a derived material... */ - if (source == ctx->source_material) - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_overrides (source, &options); + if (!copy) + { + copy = cogl_material_copy (source); + source = copy; + } + _cogl_material_apply_overrides (copy, &options); /* TODO: * overrides = cogl_material_get_data (material, @@ -1770,7 +1775,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) * { * overrides = g_slice_new (Overrides); * overrides->weak_material = - * cogl_material_weak_copy (ctx->source_material); + * cogl_material_weak_copy (source); * _cogl_material_apply_overrides (overrides->weak_material, * &options); * @@ -1786,9 +1791,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) if (G_UNLIKELY (ctx->legacy_state_set)) { /* If we haven't already created a derived material... */ - if (source == ctx->source_material) - source = cogl_material_copy (ctx->source_material); - _cogl_material_apply_legacy_state (source); + if (!copy) + { + copy = cogl_material_copy (source); + source = copy; + } + _cogl_material_apply_legacy_state (copy); } _cogl_material_flush_gl_state (source, skip_gl_color); @@ -1804,7 +1812,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) static void disable_state_for_drawing_buffer (CoglVertexBuffer *buffer, - CoglHandle source) + CoglMaterial *source) { GList *tmp; GLenum gl_type; @@ -1814,8 +1822,8 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer, _COGL_GET_CONTEXT (ctx, NO_RETVAL); - if (G_UNLIKELY (source != ctx->source_material)) - cogl_handle_unref (source); + if (G_UNLIKELY (source != cogl_get_source ())) + cogl_object_unref (source); /* Disable all the client state that cogl doesn't currently know * about: diff --git a/cogl/cogl.c b/cogl/cogl.c index 6ec98e07e..8392caf91 100644 --- a/cogl/cogl.c +++ b/cogl/cogl.c @@ -756,7 +756,7 @@ cogl_begin_gl (void) * A user should instead call cogl_set_source_color4ub() before * cogl_begin_gl() to simplify the state flushed. */ - _cogl_material_flush_gl_state (ctx->source_material, FALSE); + _cogl_material_flush_gl_state (cogl_get_source (), FALSE); if (ctx->enable_backface_culling) enable_flags |= COGL_ENABLE_BACKFACE_CULLING; @@ -946,22 +946,113 @@ _cogl_driver_error_quark (void) return g_quark_from_static_string ("cogl-driver-error-quark"); } -void -cogl_set_source (CoglHandle material_handle) +typedef struct _CoglSourceState { + CoglMaterial *material; + int push_count; +} CoglSourceState; + +static void +_push_source_real (CoglMaterial *material) +{ + CoglSourceState *top = g_slice_new (CoglSourceState); _COGL_GET_CONTEXT (ctx, NO_RETVAL); - g_return_if_fail (cogl_is_material (material_handle)); + top->material = cogl_object_ref (material); + top->push_count = 1; - if (ctx->source_material == material_handle) + ctx->source_stack = g_list_prepend (ctx->source_stack, top); +} + +/* FIXME: This should take a context pointer for Cogl 2.0 Technically + * we could make it so we can retrieve a context reference from the + * material, but this would not by symmetric with cogl_pop_source. */ +void +cogl_push_source (CoglMaterial *material) +{ + CoglSourceState *top; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + g_return_if_fail (cogl_is_material (material)); + + if (ctx->source_stack) + { + top = ctx->source_stack->data; + if (top->material == material) + { + top->push_count++; + return; + } + else + _push_source_real (material); + } + else + _push_source_real (material); +} + +/* FIXME: This needs to take a context pointer for Cogl 2.0 */ +void +cogl_pop_source (void) +{ + CoglSourceState *top; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + g_return_if_fail (ctx->source_stack); + + top = ctx->source_stack->data; + top->push_count--; + if (top->push_count == 0) + { + cogl_object_unref (top->material); + g_slice_free (CoglSourceState, top); + ctx->source_stack = g_list_delete_link (ctx->source_stack, + ctx->source_stack); + } +} + +/* FIXME: This needs to take a context pointer for Cogl 2.0 */ +CoglMaterial * +cogl_get_source (void) +{ + CoglSourceState *top; + + _COGL_GET_CONTEXT (ctx, NULL); + + g_return_val_if_fail (ctx->source_stack, NULL); + + top = ctx->source_stack->data; + return top->material; +} + +void +cogl_set_source (CoglMaterial *material) +{ + CoglSourceState *top; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + g_return_if_fail (cogl_is_material (material)); + g_return_if_fail (ctx->source_stack); + + top = ctx->source_stack->data; + if (top->material == material) return; - cogl_handle_ref (material_handle); - - if (ctx->source_material) - cogl_handle_unref (ctx->source_material); - - ctx->source_material = material_handle; + if (top->push_count == 1) + { + /* NB: top->material may be only thing keeping material + * alive currently so ref material first... */ + cogl_object_ref (material); + cogl_object_unref (top->material); + top->material = material; + } + else + { + top->push_count--; + cogl_push_source (material); + } } void diff --git a/cogl/cogl.h b/cogl/cogl.h index 8d17880a4..4427aff82 100644 --- a/cogl/cogl.h +++ b/cogl/cogl.h @@ -574,19 +574,61 @@ cogl_clear (const CoglColor *color, /** * cogl_set_source: - * @material: A #CoglHandle for a material + * @material: A #CoglMaterial * - * This function sets the source material that will be used to fill subsequent - * geometry emitted via the cogl API. - * - * In the future we may add the ability to set a front facing material, - * and a back facing material, in which case this function will set both to the - * same. + * This function changes the material at the top of the source stack. + * The material at the top of this stack defines the GPU state used to + * process subsequent primitives, such as rectangles drawn with + * cogl_rectangle() or vertices drawn using cogl_vertex_buffer_draw(). * * Since: 1.0 */ void -cogl_set_source (CoglHandle material); +cogl_set_source (CoglMaterial *material); + +/** + * cogl_get_source: + * + * Returns the current source material as previously set using + * cogl_set_source(). + * + * You should typically consider the returned material immutable + * and not try to change any of its properties unless you own a + * reference to that material. At times you may be able to get a + * reference to an internally managed materials and the result of + * modifying such materials is undefined. + * + * Return value: The current source material. + * + * Since: 1.6 + */ +CoglMaterial * +cogl_get_source (void); + +/** + * cogl_push_source: + * @material: A #CoglMaterial + * + * Pushes the given @material to the top of the source stack. The + * material at the top of this stack defines the GPU state used to + * process later primitives as defined by cogl_set_source(). + * + * Since: 1.6 + */ +void +cogl_push_source (CoglMaterial *material); + +/** + * cogl_pop_source: + * + * Removes the material at the top of the source stack. The material + * at the top of this stack defines the GPU state used to process + * later primitives as defined by cogl_set_source(). + * + * Since: 1.6 + */ +void +cogl_pop_source (void); /** * cogl_set_source_color: diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt index 8acacc786..d6c0cb74f 100644 --- a/doc/reference/cogl/cogl-sections.txt +++ b/doc/reference/cogl/cogl-sections.txt @@ -61,6 +61,9 @@ cogl_set_source_color cogl_set_source_color4ub cogl_set_source_color4f cogl_set_source_texture +cogl_get_source +cogl_push_source +cogl_pop_source CoglReadPixelsFlags