Merge branch 'cogl-journal-batching'
[cogl] Improve ability to break out into raw OpenGL via begin/end mechanism Adds a cogl_flush() to give developers breaking into raw GL a fighting chance [cogl-material] Be more carefull about flushing in cogl_material_remove_layer Revert "[rectangle] Avoid modifying materials mid scene" Revert "[actor] Avoid modifying materials mid-scene to improve journal batching" [cogl-vertex-buffer] Disable unused client tex coord arrays [cogl] disable all client tex coord arrays in _cogl_add_path_to_stencil_buffer [cogl] flush matrices in _cogl_add_path_to_stencil_buffer [journal] Don't resize a singlton VBO; create and destroy a VBO each flush [cogl] avoid using the journal in _cogl_add_path_to_stencil_buffer [pango-display-list] Use the Cogl journal for short runs of text [material] _cogl_material_equal: catch the simplest case of matching handles [material] avoid flushing the journal when just changing the color [cogl journal] Perform software modelview transform on logged quads. [Cogl journal] use G_UNLIKLEY around runtime debugging conditions [cogl journal] Adds a --cogl-debug=batching option to trace batching [Cogl journal] Adds a --cogl-debug=journal option for tracing the journal [cogl] Adds a debug option for disabling use of VBOs --cogl-debug=disable-vbos [cogl] Force Cogl to always use the client side matrix stack [cogl-debug] Adds a "client-side-matrices" Cogl debug option [cogl-color] Adds a cogl_color_equal() function [cogl material] optimize logging of material colors in the journal [rectangle] Avoid modifying materials mid scene [actor] Avoid modifying materials mid-scene to improve journal batching [journal] Always pad our vertex data as if at least 2 layers are enabled [cogl] Improving Cogl journal to minimize driver overheads + GPU state changes The Cogl journal is a mechanism Cogl uses to batch geometry resulting from any of the cogl_rectangle* functions before sending it to OpenGL. This aims to improve the Cogl journal so that it can reduce the number of state changes and draw calls we issue to the OpenGL driver and hopfully improve performance. Previously each call to any of the cogl_rectangle* functions would imply an immediate GL draw call, as well as a corresponding modelview change; material state changes and gl{Vertex,Color,TexCoord}Pointer calls. Now though we have tried to open the scope for batching up as much as possible so we only have to flush the geometry either before calling glXSwapBuffers, or when we change state that isn't tracked by the journal. As a basic example, it's now possible for us to batch typical picking renders into a single draw call for the whole scene. Some key points about this change: - We now perform transformations of quads in software (except for long runs of text which continue to use VBOs) * It might seem surprising at first, but when you consider that so many Clutter actors are little more than textured quads and each actor typically implies a modelview matrix change; the costs involved in setting up the GPU with the new modelview can easily out weigh the cost of simply transforming 4 vertices. - We always use Cogl's own client side matrix API now. * We found the performance of querying the OpenGL driver for matrix state was often worse than using the client matrix code, and also - discussing with Mesa developers - agreed that since khronos has essentially deprecated the GL matrix API (by removing it from OpenGL 3 and OpenGL-ES 2) it was appropriate to take full responsibility for all our matrix manipulation. - Developers should avoid modifying materials mid-scene. * With the exception of material color changes, if you try and modify a material that is referenced in the journal we will currently force a journal flush. Note: you can assume that re-setting the same value for a material property won't require a flush though. - Several new --cogl-debug options have been added * "disable-batching" can be used to identify bugs in the way that the journal does its batching; of could this shouldn't ever be needed :-) * "disable-vbos" can be used to test the VBO fallback paths where we simply use malloc()'d buffers instead. * "batching" lets you get an overview of how the journal is batching your geometry and may help you identify ways to improve your application performance. * "journal" lets you trace all the geometry as it gets logged in the journal, and all the geometry as its flushed from the journal. Obviously an inconsistency can identify a bug, but the numbers may help you verify application logic too. * "disable-software-transform" as implied will instead use the driver /GPU to transform quads by the modelview matrix. Although committed separately a --clutter-debug=nop-picking option was also added that lets you remove picking from the equation, which can sometimes help make problem analysis more deterministic.
This commit is contained in:
commit
4d55d146b3
16
cogl-color.h
16
cogl-color.h
@ -240,6 +240,22 @@ float cogl_color_get_alpha (const CoglColor *color);
|
||||
*/
|
||||
void cogl_color_premultiply (CoglColor *color);
|
||||
|
||||
/**
|
||||
* cogl_color_equal:
|
||||
* @v1: a #CoglColor
|
||||
* @v2: a #CoglColor
|
||||
*
|
||||
* Compares two #CoglColor<!-- -->s and checks if they are the same.
|
||||
*
|
||||
* This function can be passed to g_hash_table_new() as the @key_equal_func
|
||||
* parameter, when using #CoglColor<!-- -->s as keys in a #GHashTable.
|
||||
*
|
||||
* Return value: %TRUE if the two colors are the same.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
gboolean cogl_color_equal (gconstpointer v1, gconstpointer v2);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_COLOR_H__ */
|
||||
|
26
cogl-debug.h
26
cogl-debug.h
@ -29,16 +29,22 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
COGL_DEBUG_MISC = 1 << 0,
|
||||
COGL_DEBUG_TEXTURE = 1 << 1,
|
||||
COGL_DEBUG_MATERIAL = 1 << 2,
|
||||
COGL_DEBUG_SHADER = 1 << 3,
|
||||
COGL_DEBUG_OFFSCREEN = 1 << 4,
|
||||
COGL_DEBUG_DRAW = 1 << 5,
|
||||
COGL_DEBUG_PANGO = 1 << 6,
|
||||
COGL_DEBUG_RECTANGLES = 1 << 7,
|
||||
COGL_DEBUG_HANDLE = 1 << 8,
|
||||
COGL_DEBUG_BLEND_STRINGS = 1 << 9
|
||||
COGL_DEBUG_MISC = 1 << 0,
|
||||
COGL_DEBUG_TEXTURE = 1 << 1,
|
||||
COGL_DEBUG_MATERIAL = 1 << 2,
|
||||
COGL_DEBUG_SHADER = 1 << 3,
|
||||
COGL_DEBUG_OFFSCREEN = 1 << 4,
|
||||
COGL_DEBUG_DRAW = 1 << 5,
|
||||
COGL_DEBUG_PANGO = 1 << 6,
|
||||
COGL_DEBUG_RECTANGLES = 1 << 7,
|
||||
COGL_DEBUG_HANDLE = 1 << 8,
|
||||
COGL_DEBUG_BLEND_STRINGS = 1 << 9,
|
||||
COGL_DEBUG_DISABLE_BATCHING = 1 << 10,
|
||||
COGL_DEBUG_FORCE_CLIENT_SIDE_MATRICES = 1 << 11,
|
||||
COGL_DEBUG_DISABLE_VBOS = 1 << 12,
|
||||
COGL_DEBUG_JOURNAL = 1 << 13,
|
||||
COGL_DEBUG_BATCHING = 1 << 14,
|
||||
COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM = 1 << 15
|
||||
} CoglDebugFlags;
|
||||
|
||||
#ifdef COGL_ENABLE_DEBUG
|
||||
|
@ -673,6 +673,16 @@ void cogl_material_set_layer_matrix (CoglHandle material,
|
||||
*/
|
||||
const GList *cogl_material_get_layers (CoglHandle material);
|
||||
|
||||
/**
|
||||
* cogl_material_get_n_layers:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* Returns: The number of layers defined for the given material
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
int cogl_material_get_n_layers (CoglHandle material);
|
||||
|
||||
/**
|
||||
* CoglMaterialLayerType:
|
||||
* @COGL_MATERIAL_LAYER_TYPE_TEXTURE: The layer represents a
|
||||
@ -713,15 +723,6 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
|
||||
* likely return COGL_INVALID_HANDLE if you try to get the texture.
|
||||
* Considering this, you can call cogl_material_layer_get_type first,
|
||||
* to check it is of type COGL_MATERIAL_LAYER_TYPE_TEXTURE.
|
||||
*
|
||||
* Note: It is possible for a layer object of type
|
||||
* COGL_MATERIAL_LAYER_TYPE_TEXTURE to be realized before a texture
|
||||
* object has been associated with the layer. For example this happens
|
||||
* if you setup layer combining for a given layer index before calling
|
||||
* cogl_material_set_layer for that index.
|
||||
*
|
||||
* Returns: A CoglHandle to the layers texture object or COGL_INVALID_HANDLE
|
||||
* if a texture has not been set yet.
|
||||
*/
|
||||
CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle);
|
||||
|
||||
|
107
cogl.h.in
107
cogl.h.in
@ -724,6 +724,113 @@ void cogl_read_pixels (int x,
|
||||
CoglPixelFormat format,
|
||||
guint8 *pixels);
|
||||
|
||||
/**
|
||||
* cogl_flush:
|
||||
*
|
||||
* This function should only need to be called in exceptional circumstances.
|
||||
*
|
||||
* As an optimization Cogl drawing functions may batch up primitives
|
||||
* internally, so if you are trying to use raw GL outside of Cogl you stand a
|
||||
* better chance of being successful if you ask Cogl to flush any batched
|
||||
* geometry before making your state changes.
|
||||
*
|
||||
* It only ensure that the underlying driver is issued all the commands
|
||||
* necessary to draw the batched primitives. It provides no guarantees about
|
||||
* when the driver will complete the rendering.
|
||||
*
|
||||
* This provides no guarantees about the GL state upon returning and to avoid
|
||||
* confusing Cogl you should aim to restore any changes you make before
|
||||
* resuming use of Cogl.
|
||||
*
|
||||
* If you are making state changes with the intention of affecting Cogl drawing
|
||||
* primitives you are 100% on your own since you stand a good chance of
|
||||
* conflicting with Cogl internals. For example clutter-gst which currently
|
||||
* uses direct GL calls to bind ARBfp programs will very likely break when Cogl
|
||||
* starts to use ARBfb programs itself for the material API.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void cogl_flush (void);
|
||||
|
||||
/**
|
||||
* cogl_begin_gl:
|
||||
*
|
||||
* We do not advise nor reliably support the interleaving of raw GL drawing and
|
||||
* Cogl drawing functions, but if you insist, cogl_begin_gl() and cogl_end_gl()
|
||||
* provide a simple mechanism that may at least give you a fighting chance of
|
||||
* succeeding.
|
||||
*
|
||||
* Note: this doesn't help you modify the behaviour of Cogl drawing functions
|
||||
* through the modification of GL state; that will never be reliably supported,
|
||||
* but if you are trying to do something like:
|
||||
* <programlisting>
|
||||
* {
|
||||
* - setup some OpenGL state.
|
||||
* - draw using OpenGL (e.g. glDrawArrays() )
|
||||
* - reset modified OpenGL state.
|
||||
* - continue using Cogl to draw
|
||||
* }
|
||||
* </programlisting>
|
||||
* You should surround blocks of drawing using raw GL with cogl_begin_gl()
|
||||
* and cogl_end_gl():
|
||||
* <programlisting>
|
||||
* {
|
||||
* cogl_begin_gl ();
|
||||
* - setup some OpenGL state.
|
||||
* - draw using OpenGL (e.g. glDrawArrays() )
|
||||
* - reset modified OpenGL state.
|
||||
* cogl_end_gl ();
|
||||
* - continue using Cogl to draw
|
||||
* }
|
||||
* </programlisting>
|
||||
*
|
||||
* Don't ever try and do:
|
||||
* <programlisting>
|
||||
* {
|
||||
* - setup some OpenGL state.
|
||||
* - use Cogl to draw
|
||||
* - reset modified OpenGL state.
|
||||
* }
|
||||
* </programlisting>
|
||||
* When the internals of Cogl evolves, this is very liable to break.
|
||||
*
|
||||
* This function will flush all batched primitives, and subsequently flush
|
||||
* all internal Cogl state to OpenGL as if it were going to draw something
|
||||
* itself.
|
||||
*
|
||||
* The result is that the OpenGL modelview matrix will be setup; the state
|
||||
* corresponding to the current source material will be set up and other world
|
||||
* state such as backface culling, depth and fogging enabledness will be sent
|
||||
* to OpenGL.
|
||||
*
|
||||
* Note: no special material state is flushed, so if you want Cogl to setup a
|
||||
* simplified material state it is your responsibility to set a simple source
|
||||
* material before calling cogl_begin_gl. E.g. by calling
|
||||
* cogl_set_source_color4ub().
|
||||
*
|
||||
* Note: It is your responsibility to restore any OpenGL state that you modify
|
||||
* to how it was after calling cogl_begin_gl() if you don't do this then the
|
||||
* result of further Cogl calls is undefined.
|
||||
*
|
||||
* Note: You can not nest begin/end blocks.
|
||||
*
|
||||
* Again we would like to stress, we do not advise the use of this API and if
|
||||
* possible we would prefer to improve Cogl than have developers require raw
|
||||
* OpenGL.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void cogl_begin_gl (void);
|
||||
|
||||
/**
|
||||
* cogl_end_gl:
|
||||
*
|
||||
* This is the counterpart to cogl_begin_gl() used to delimit blocks of drawing
|
||||
* code using raw OpenGL. Please refer to cogl_begin_gl() for full details.
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void cogl_end_gl (void);
|
||||
|
||||
/*
|
||||
* Internal API available only to Clutter.
|
||||
|
@ -324,6 +324,10 @@ _cogl_clip_stack_rebuild (void)
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* The current primitive journal does not support tracking changes to the
|
||||
* clip stack... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
stack = (CoglClipStack *) ctx->clip.stacks->data;
|
||||
|
||||
ctx->clip.stack_dirty = FALSE;
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cogl.h"
|
||||
#include "cogl-color.h"
|
||||
#include "cogl-fixed.h"
|
||||
@ -184,3 +186,16 @@ cogl_set_source_color4f (float red,
|
||||
cogl_color_set_from_4f (&c, red, green, blue, alpha);
|
||||
cogl_set_source_color (&c);
|
||||
}
|
||||
|
||||
gboolean
|
||||
cogl_color_equal (gconstpointer v1, gconstpointer v2)
|
||||
{
|
||||
const guint32 *c1 = v1, *c2 = v2;
|
||||
|
||||
g_return_val_if_fail (v1 != NULL, FALSE);
|
||||
g_return_val_if_fail (v2 != NULL, FALSE);
|
||||
|
||||
/* XXX: We don't compare the padding */
|
||||
return *c1 == *c2 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
|
@ -320,7 +320,10 @@ _cogl_current_matrix_state_init (void)
|
||||
ctx->matrix_mode = COGL_MATRIX_MODELVIEW;
|
||||
ctx->modelview_stack = NULL;
|
||||
|
||||
if (ctx->indirect)
|
||||
#if 0
|
||||
if (ctx->indirect ||
|
||||
cogl_debug_flags & COGL_DEBUG_FORCE_CLIENT_SIDE_MATRICES)
|
||||
#endif
|
||||
{
|
||||
ctx->modelview_stack =
|
||||
_cogl_matrix_stack_new ();
|
||||
|
@ -40,7 +40,13 @@ static const GDebugKey cogl_debug_keys[] = {
|
||||
{ "pango", COGL_DEBUG_PANGO },
|
||||
{ "rectangles", COGL_DEBUG_RECTANGLES },
|
||||
{ "handle", COGL_DEBUG_HANDLE },
|
||||
{ "blend-strings", COGL_DEBUG_BLEND_STRINGS }
|
||||
{ "blend-strings", COGL_DEBUG_BLEND_STRINGS },
|
||||
{ "disable-batching", COGL_DEBUG_DISABLE_BATCHING },
|
||||
{ "client-side-matrices", COGL_DEBUG_FORCE_CLIENT_SIDE_MATRICES },
|
||||
{ "disable-vbos", COGL_DEBUG_DISABLE_VBOS },
|
||||
{ "journal", COGL_DEBUG_JOURNAL },
|
||||
{ "batching", COGL_DEBUG_BATCHING },
|
||||
{ "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM }
|
||||
};
|
||||
|
||||
static const gint n_cogl_debug_keys = G_N_ELEMENTS (cogl_debug_keys);
|
||||
|
@ -36,6 +36,16 @@
|
||||
typedef struct _CoglMaterial CoglMaterial;
|
||||
typedef struct _CoglMaterialLayer CoglMaterialLayer;
|
||||
|
||||
typedef enum _CoglMaterialEqualFlags
|
||||
{
|
||||
/* Return FALSE if any component of either material isn't set to its
|
||||
* default value. (Note: if the materials have corresponding flush
|
||||
* options indicating that e.g. the material color won't be flushed then
|
||||
* this will not assert a default color value.) */
|
||||
COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS = 1L<<0,
|
||||
|
||||
} CoglMaterialEqualFlags;
|
||||
|
||||
/* XXX: I don't think gtk-doc supports having private enums so these aren't
|
||||
* bundled in with CoglMaterialLayerFlags */
|
||||
typedef enum _CoglMaterialLayerPrivFlags
|
||||
@ -90,22 +100,24 @@ struct _CoglMaterialLayer
|
||||
|
||||
typedef enum _CoglMaterialFlags
|
||||
{
|
||||
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<0,
|
||||
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<1,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<2,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<3,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<4,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC = 1L<<5
|
||||
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<0,
|
||||
|
||||
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<1,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<2,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<3,
|
||||
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<4,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_BLEND = 1L<<5
|
||||
} CoglMaterialFlags;
|
||||
|
||||
struct _CoglMaterial
|
||||
{
|
||||
CoglHandleObject _parent;
|
||||
gulong journal_ref_count;
|
||||
|
||||
gulong flags;
|
||||
|
||||
/* If no lighting is enabled; this is the basic material color */
|
||||
GLfloat unlit[4];
|
||||
GLubyte unlit[4];
|
||||
|
||||
/* Standard OpenGL lighting model attributes */
|
||||
GLfloat ambient[4];
|
||||
@ -130,6 +142,7 @@ struct _CoglMaterial
|
||||
GLint blend_dst_factor_rgb;
|
||||
|
||||
GList *layers;
|
||||
guint n_layers;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -183,39 +196,60 @@ typedef enum _CoglMaterialLayerFlags
|
||||
gulong _cogl_material_layer_get_flags (CoglHandle layer_handle);
|
||||
|
||||
/*
|
||||
* CoglMaterialFlushOption:
|
||||
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: Follow this by a guin32 mask
|
||||
* of the layers that can't be supported with the user supplied texture
|
||||
* and need to be replaced with fallback textures. (1 = fallback, and the
|
||||
* least significant bit = layer 0)
|
||||
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: Follow this by a guint32 mask
|
||||
* of the layers that you want to completly disable texturing for
|
||||
* (1 = fallback, and the least significant bit = layer 0)
|
||||
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: Follow this by a GLuint OpenGL texture
|
||||
* name to override the texture used for layer 0 of the material. This is
|
||||
* intended for dealing with sliced textures where you will need to point
|
||||
* to each of the texture slices in turn when drawing your geometry.
|
||||
* Passing a value of 0 is the same as not passing the option at all.
|
||||
* CoglMaterialFlushFlag:
|
||||
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: The fallback_layers member is set to
|
||||
* a guint32 mask of the layers that can't be supported with the user
|
||||
* supplied texture and need to be replaced with fallback textures. (1 =
|
||||
* fallback, and the least significant bit = layer 0)
|
||||
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: The disable_layers member is set to
|
||||
* a guint32 mask of the layers that you want to completly disable
|
||||
* texturing for (1 = fallback, and the least significant bit = layer 0)
|
||||
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is
|
||||
* set to a GLuint OpenGL texture name to override the texture used for
|
||||
* layer 0 of the material. This is intended for dealing with sliced
|
||||
* textures where you will need to point to each of the texture slices in
|
||||
* turn when drawing your geometry. Passing a value of 0 is the same as
|
||||
* not passing the option at all.
|
||||
* @COGL_MATERIAL_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the
|
||||
* material don't call glColor.
|
||||
*/
|
||||
typedef enum _CoglMaterialFlushOption
|
||||
typedef enum _CoglMaterialFlushFlag
|
||||
{
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK,
|
||||
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
|
||||
} CoglMaterialFlushOption;
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1L<<0,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK = 1L<<1,
|
||||
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE = 1L<<2,
|
||||
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR = 1L<<3
|
||||
} CoglMaterialFlushFlag;
|
||||
|
||||
/*
|
||||
* cogl_material_flush_gl_state:
|
||||
* @material: A CoglMaterial object
|
||||
* @...: A NULL terminated list of (CoglMaterialFlushOption, data) pairs
|
||||
* CoglMaterialFlushOptions:
|
||||
*
|
||||
* This function commits the state of the specified CoglMaterial - including
|
||||
* the texture state for all the layers - to the OpenGL[ES] driver.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
typedef struct _CoglMaterialFlushOptions
|
||||
{
|
||||
CoglMaterialFlushFlag flags;
|
||||
|
||||
guint32 fallback_layers;
|
||||
guint32 disable_layers;
|
||||
GLuint layer0_override_texture;
|
||||
} CoglMaterialFlushOptions;
|
||||
|
||||
|
||||
|
||||
void _cogl_material_get_colorubv (CoglHandle handle,
|
||||
guint8 *color);
|
||||
|
||||
void _cogl_material_flush_gl_state (CoglHandle material,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
CoglMaterialFlushOptions *options);
|
||||
|
||||
gboolean _cogl_material_equal (CoglHandle material0_handle,
|
||||
CoglMaterialFlushOptions *material0_flush_options,
|
||||
CoglHandle material1_handle,
|
||||
CoglMaterialFlushOptions *material1_flush_options,
|
||||
CoglMaterialEqualFlags flags);
|
||||
|
||||
CoglHandle _cogl_material_journal_ref (CoglHandle material_handle);
|
||||
void _cogl_material_journal_unref (CoglHandle material_handle);
|
||||
|
||||
|
||||
#endif /* __COGL_MATERIAL_PRIVATE_H */
|
||||
|
@ -76,14 +76,14 @@ cogl_material_new (void)
|
||||
{
|
||||
/* Create new - blank - material */
|
||||
CoglMaterial *material = g_new0 (CoglMaterial, 1);
|
||||
GLfloat *unlit = material->unlit;
|
||||
GLubyte *unlit = material->unlit;
|
||||
GLfloat *ambient = material->ambient;
|
||||
GLfloat *diffuse = material->diffuse;
|
||||
GLfloat *specular = material->specular;
|
||||
GLfloat *emission = material->emission;
|
||||
|
||||
/* Use the same defaults as the GL spec... */
|
||||
unlit[0] = 1.0; unlit[1] = 1.0; unlit[2] = 1.0; unlit[3] = 1.0;
|
||||
unlit[0] = 0xff; unlit[1] = 0xff; unlit[2] = 0xff; unlit[3] = 0xff;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR;
|
||||
|
||||
/* Use the same defaults as the GL spec... */
|
||||
@ -111,9 +111,10 @@ cogl_material_new (void)
|
||||
#endif
|
||||
material->blend_src_factor_rgb = GL_ONE;
|
||||
material->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND;
|
||||
|
||||
material->layers = NULL;
|
||||
material->n_layers = 0;
|
||||
|
||||
return _cogl_material_handle_new (material);
|
||||
}
|
||||
@ -130,15 +131,24 @@ _cogl_material_free (CoglMaterial *material)
|
||||
g_free (material);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_automatic_blend_enable (CoglMaterial *material)
|
||||
static gboolean
|
||||
_cogl_material_needs_blending_enabled (CoglMaterial *material,
|
||||
GLubyte *override_color)
|
||||
{
|
||||
GList *tmp;
|
||||
|
||||
/* XXX: If we expose manual control over ENABLE_BLEND, we'll add
|
||||
* a flag to know when it's user configured, so we don't trash it */
|
||||
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
/* XXX: Uncomment this to disable all blending */
|
||||
#if 0
|
||||
return;
|
||||
#endif
|
||||
|
||||
if ((override_color && override_color[3] != 0xff) ||
|
||||
material->unlit[3] != 0xff)
|
||||
return TRUE;
|
||||
|
||||
for (tmp = material->layers; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
CoglMaterialLayer *layer = tmp->data;
|
||||
@ -149,13 +159,46 @@ handle_automatic_blend_enable (CoglMaterial *material)
|
||||
continue;
|
||||
|
||||
if (cogl_texture_get_format (layer->texture) & COGL_A_BIT)
|
||||
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (material->unlit[3] != 1.0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_automatic_blend_enable (CoglMaterial *material)
|
||||
{
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
|
||||
if (_cogl_material_needs_blending_enabled (material, NULL))
|
||||
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
}
|
||||
|
||||
/* If primitives have been logged in the journal referencing the current
|
||||
* state of this material we need to flush the journal before we can
|
||||
* modify it... */
|
||||
static void
|
||||
_cogl_material_pre_change_notify (CoglMaterial *material,
|
||||
gboolean only_color_change,
|
||||
GLubyte *new_color)
|
||||
{
|
||||
/* XXX: We don't usually need to flush the journal just due to color changes
|
||||
* since material colors are logged in the journals vertex buffer. The
|
||||
* exception is when the change in color enables or disables the need for
|
||||
* blending. */
|
||||
if (only_color_change)
|
||||
{
|
||||
gboolean will_need_blending =
|
||||
_cogl_material_needs_blending_enabled (material, new_color);
|
||||
if (will_need_blending ==
|
||||
(material->flags & COGL_MATERIAL_FLAG_ENABLE_BLEND) ? TRUE : FALSE)
|
||||
return;
|
||||
}
|
||||
|
||||
if (material->journal_ref_count)
|
||||
_cogl_journal_flush ();
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_get_color (CoglHandle handle,
|
||||
CoglColor *color)
|
||||
@ -166,11 +209,20 @@ cogl_material_get_color (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
cogl_color_set_from_4f (color,
|
||||
material->unlit[0],
|
||||
material->unlit[1],
|
||||
material->unlit[2],
|
||||
material->unlit[3]);
|
||||
cogl_color_set_from_4ub (color,
|
||||
material->unlit[0],
|
||||
material->unlit[1],
|
||||
material->unlit[2],
|
||||
material->unlit[3]);
|
||||
}
|
||||
|
||||
/* This is used heavily by the cogl journal when logging quads */
|
||||
void
|
||||
_cogl_material_get_colorubv (CoglHandle handle,
|
||||
guint8 *color)
|
||||
{
|
||||
CoglMaterial *material = _cogl_material_pointer_from_handle (handle);
|
||||
memcpy (color, material->unlit, 4);
|
||||
}
|
||||
|
||||
void
|
||||
@ -178,26 +230,29 @@ cogl_material_set_color (CoglHandle handle,
|
||||
const CoglColor *unlit_color)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
GLfloat unlit[4];
|
||||
GLubyte unlit[4];
|
||||
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
unlit[0] = cogl_color_get_red_float (unlit_color);
|
||||
unlit[1] = cogl_color_get_green_float (unlit_color);
|
||||
unlit[2] = cogl_color_get_blue_float (unlit_color);
|
||||
unlit[3] = cogl_color_get_alpha_float (unlit_color);
|
||||
unlit[0] = cogl_color_get_red_byte (unlit_color);
|
||||
unlit[1] = cogl_color_get_green_byte (unlit_color);
|
||||
unlit[2] = cogl_color_get_blue_byte (unlit_color);
|
||||
unlit[3] = cogl_color_get_alpha_byte (unlit_color);
|
||||
if (memcmp (unlit, material->unlit, sizeof (unlit)) == 0)
|
||||
return;
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, TRUE, unlit);
|
||||
|
||||
memcpy (material->unlit, unlit, sizeof (unlit));
|
||||
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_COLOR;
|
||||
if (unlit[0] == 1.0 &&
|
||||
unlit[1] == 1.0 &&
|
||||
unlit[2] == 1.0 &&
|
||||
unlit[3] == 1.0)
|
||||
if (unlit[0] == 0xff &&
|
||||
unlit[1] == 0xff &&
|
||||
unlit[2] == 0xff &&
|
||||
unlit[3] == 0xff)
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR;
|
||||
|
||||
handle_automatic_blend_enable (material);
|
||||
@ -255,6 +310,9 @@ cogl_material_set_ambient (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
ambient = material->ambient;
|
||||
ambient[0] = cogl_color_get_red_float (ambient_color);
|
||||
ambient[1] = cogl_color_get_green_float (ambient_color);
|
||||
@ -292,6 +350,9 @@ cogl_material_set_diffuse (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
diffuse = material->diffuse;
|
||||
diffuse[0] = cogl_color_get_red_float (diffuse_color);
|
||||
diffuse[1] = cogl_color_get_green_float (diffuse_color);
|
||||
@ -337,6 +398,9 @@ cogl_material_set_specular (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
specular = material->specular;
|
||||
specular[0] = cogl_color_get_red_float (specular_color);
|
||||
specular[1] = cogl_color_get_green_float (specular_color);
|
||||
@ -372,6 +436,9 @@ cogl_material_set_shininess (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
material->shininess = (GLfloat)shininess * 128.0;
|
||||
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
@ -405,6 +472,9 @@ cogl_material_set_emission (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
emission = material->emission;
|
||||
emission[0] = cogl_color_get_red_float (emission_color);
|
||||
emission[1] = cogl_color_get_green_float (emission_color);
|
||||
@ -424,6 +494,10 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
material->alpha_func = alpha_func;
|
||||
material->alpha_func_reference = (GLfloat)alpha_reference;
|
||||
|
||||
@ -571,6 +645,9 @@ cogl_material_set_blend (CoglHandle handle,
|
||||
a = &statements[1];
|
||||
}
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
#ifndef HAVE_COGL_GLES
|
||||
setup_blend_state (rgb,
|
||||
&material->blend_equation_rgb,
|
||||
@ -587,7 +664,7 @@ cogl_material_set_blend (CoglHandle handle,
|
||||
&material->blend_dst_factor_rgb);
|
||||
#endif
|
||||
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -604,13 +681,16 @@ cogl_material_set_blend_constant (CoglHandle handle,
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
constant = material->blend_constant;
|
||||
constant[0] = cogl_color_get_red_float (constant_color);
|
||||
constant[1] = cogl_color_get_green_float (constant_color);
|
||||
constant[2] = cogl_color_get_blue_float (constant_color);
|
||||
constant[3] = cogl_color_get_alpha_float (constant_color);
|
||||
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -644,6 +724,9 @@ _cogl_material_get_layer (CoglMaterial *material,
|
||||
if (!create_if_not_found)
|
||||
return NULL;
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
layer = g_new0 (CoglMaterialLayer, 1);
|
||||
|
||||
layer_handle = _cogl_material_layer_handle_new (layer);
|
||||
@ -682,20 +765,23 @@ cogl_material_set_layer (CoglHandle material_handle,
|
||||
{
|
||||
CoglMaterial *material;
|
||||
CoglMaterialLayer *layer;
|
||||
int n_layers;
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
g_return_if_fail (texture_handle == COGL_INVALID_HANDLE
|
||||
|| cogl_is_texture (texture_handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
|
||||
layer = _cogl_material_get_layer (material_handle, layer_index, TRUE);
|
||||
|
||||
if (texture_handle == layer->texture)
|
||||
return;
|
||||
|
||||
n_layers = g_list_length (material->layers);
|
||||
if (n_layers >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
material->n_layers = g_list_length (material->layers);
|
||||
if (material->n_layers >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
|
||||
{
|
||||
if (!(material->flags & COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING))
|
||||
{
|
||||
@ -856,6 +942,9 @@ cogl_material_set_layer_combine (CoglHandle handle,
|
||||
a = &statements[1];
|
||||
}
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
setup_texture_combine_state (rgb,
|
||||
&layer->texture_combine_rgb_func,
|
||||
layer->texture_combine_rgb_src,
|
||||
@ -886,6 +975,9 @@ cogl_material_set_layer_combine_constant (CoglHandle handle,
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
constant = layer->texture_combine_constant;
|
||||
constant[0] = cogl_color_get_red_float (constant_color);
|
||||
constant[1] = cogl_color_get_green_float (constant_color);
|
||||
@ -909,6 +1001,9 @@ cogl_material_set_layer_matrix (CoglHandle material_handle,
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
layer->matrix = *matrix;
|
||||
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
@ -931,18 +1026,29 @@ cogl_material_remove_layer (CoglHandle material_handle,
|
||||
CoglMaterial *material;
|
||||
CoglMaterialLayer *layer;
|
||||
GList *tmp;
|
||||
gboolean notified_change = FALSE;
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
|
||||
for (tmp = material->layers; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
layer = tmp->data;
|
||||
if (layer->index == layer_index)
|
||||
{
|
||||
CoglHandle handle = (CoglHandle) layer;
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
if (!notified_change)
|
||||
{
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
notified_change = TRUE;
|
||||
}
|
||||
|
||||
cogl_handle_unref (handle);
|
||||
material->layers = g_list_remove (material->layers, layer);
|
||||
material->n_layers--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -992,6 +1098,18 @@ cogl_material_get_layers (CoglHandle material_handle)
|
||||
return material->layers;
|
||||
}
|
||||
|
||||
int
|
||||
cogl_material_get_n_layers (CoglHandle material_handle)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_val_if_fail (cogl_is_material (material_handle), 0);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
|
||||
return material->n_layers;
|
||||
}
|
||||
|
||||
CoglMaterialLayerType
|
||||
cogl_material_layer_get_type (CoglHandle layer_handle)
|
||||
{
|
||||
@ -1318,7 +1436,10 @@ _cogl_material_flush_layers_gl_state (CoglMaterial *material,
|
||||
!gl_layer_info->disabled))
|
||||
#endif
|
||||
{
|
||||
/* XXX: Debug: Comment this out to disable all texturing: */
|
||||
#if 1
|
||||
GE (glEnable (gl_target));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1369,18 +1490,30 @@ _cogl_material_flush_layers_gl_state (CoglMaterial *material,
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_material_flush_base_gl_state (CoglMaterial *material)
|
||||
_cogl_material_flush_base_gl_state (CoglMaterial *material,
|
||||
gboolean skip_gl_color)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR))
|
||||
/* XXX:
|
||||
* Currently we only don't update state when the flags indicate that the
|
||||
* current material uses the defaults, and the new material also uses the
|
||||
* defaults, but we could do deeper comparisons of state. */
|
||||
|
||||
if (!skip_gl_color)
|
||||
{
|
||||
/* GLES doesn't have glColor4fv... */
|
||||
GE (glColor4f (material->unlit[0],
|
||||
material->unlit[1],
|
||||
material->unlit[2],
|
||||
material->unlit[3]));
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR) ||
|
||||
/* Assume if we were previously told to skip the color, then
|
||||
* the current color needs updating... */
|
||||
ctx->current_material_flush_options.flags &
|
||||
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR)
|
||||
{
|
||||
GE (glColor4ub (material->unlit[0],
|
||||
material->unlit[1],
|
||||
material->unlit[2],
|
||||
material->unlit[3]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL
|
||||
@ -1401,8 +1534,8 @@ _cogl_material_flush_base_gl_state (CoglMaterial *material)
|
||||
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
|
||||
}
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC))
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND))
|
||||
{
|
||||
#if defined (HAVE_COGL_GLES2)
|
||||
gboolean have_blend_equation_seperate = TRUE;
|
||||
@ -1441,32 +1574,33 @@ _cogl_material_flush_base_gl_state (CoglMaterial *material)
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_material_flush_gl_state (CoglHandle handle, ...)
|
||||
_cogl_material_flush_gl_state (CoglHandle handle,
|
||||
CoglMaterialFlushOptions *options)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
va_list ap;
|
||||
CoglMaterialFlushOption option;
|
||||
guint32 fallback_layers = 0;
|
||||
guint32 disable_layers = 0;
|
||||
GLuint layer0_override_texture = 0;
|
||||
CoglMaterial *material;
|
||||
guint32 fallback_layers = 0;
|
||||
guint32 disable_layers = 0;
|
||||
GLuint layer0_override_texture = 0;
|
||||
gboolean skip_gl_color = FALSE;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
_cogl_material_flush_base_gl_state (material);
|
||||
|
||||
va_start (ap, handle);
|
||||
while ((option = va_arg (ap, CoglMaterialFlushOption)))
|
||||
if (options)
|
||||
{
|
||||
if (option == COGL_MATERIAL_FLUSH_FALLBACK_MASK)
|
||||
fallback_layers = va_arg (ap, guint32);
|
||||
else if (option == COGL_MATERIAL_FLUSH_DISABLE_MASK)
|
||||
disable_layers = va_arg (ap, guint32);
|
||||
else if (option == COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE)
|
||||
layer0_override_texture = va_arg (ap, GLuint);
|
||||
if (options->flags & COGL_MATERIAL_FLUSH_FALLBACK_MASK)
|
||||
fallback_layers = options->fallback_layers;
|
||||
if (options->flags & COGL_MATERIAL_FLUSH_DISABLE_MASK)
|
||||
disable_layers = options->disable_layers;
|
||||
if (options->flags & COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE)
|
||||
layer0_override_texture = options->layer0_override_texture;
|
||||
if (options->flags & COGL_MATERIAL_FLUSH_SKIP_GL_COLOR)
|
||||
skip_gl_color = TRUE;
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
_cogl_material_flush_base_gl_state (material,
|
||||
skip_gl_color);
|
||||
|
||||
_cogl_material_flush_layers_gl_state (material,
|
||||
fallback_layers,
|
||||
@ -1483,6 +1617,162 @@ _cogl_material_flush_gl_state (CoglHandle handle, ...)
|
||||
|
||||
ctx->current_material = handle;
|
||||
ctx->current_material_flags = material->flags;
|
||||
if (options)
|
||||
ctx->current_material_flush_options = *options;
|
||||
else
|
||||
memset (&ctx->current_material_flush_options,
|
||||
0, sizeof (CoglMaterialFlushOptions));
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_material_equal (CoglHandle material0_handle,
|
||||
CoglMaterialFlushOptions *material0_flush_options,
|
||||
CoglHandle material1_handle,
|
||||
CoglMaterialFlushOptions *material1_flush_options,
|
||||
CoglMaterialEqualFlags flags)
|
||||
{
|
||||
CoglMaterial *material0;
|
||||
CoglMaterial *material1;
|
||||
GList *l0, *l1;
|
||||
|
||||
if (material0_handle == material1_handle &&
|
||||
material0_flush_options->flags == material1_flush_options->flags)
|
||||
return TRUE;
|
||||
|
||||
if (!(flags & COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS))
|
||||
{
|
||||
g_critical ("FIXME: _cogl_material_equal doesn't yet support "
|
||||
"deep comparisons of materials");
|
||||
return FALSE;
|
||||
}
|
||||
/* Note: the following code is written with the assumption this
|
||||
* constraint will go away*/
|
||||
|
||||
material0 = _cogl_material_pointer_from_handle (material0_handle);
|
||||
material1 = _cogl_material_pointer_from_handle (material1_handle);
|
||||
|
||||
if (!((material0_flush_options->flags & COGL_MATERIAL_FLUSH_SKIP_GL_COLOR &&
|
||||
material1_flush_options->flags & COGL_MATERIAL_FLUSH_SKIP_GL_COLOR)))
|
||||
{
|
||||
if ((material0->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR) !=
|
||||
(material1->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR))
|
||||
return FALSE;
|
||||
else if (flags & COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS &&
|
||||
!(material0->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR))
|
||||
return FALSE;
|
||||
else if (!memcmp (material0->unlit, material1->unlit,
|
||||
sizeof (material0->unlit)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((material0->flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL) !=
|
||||
(material1->flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL))
|
||||
return FALSE;
|
||||
else if (flags & COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS &&
|
||||
!(material0->flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL))
|
||||
return FALSE;
|
||||
#if 0
|
||||
else if (!_deep_are_gl_materials_equal ())
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if ((material0->flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC) !=
|
||||
(material1->flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC))
|
||||
return FALSE;
|
||||
else if (flags & COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS &&
|
||||
!(material0->flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC))
|
||||
return FALSE;
|
||||
#if 0
|
||||
else if (!_deep_are_alpha_funcs_equal ())
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if ((material0->flags & COGL_MATERIAL_FLAG_ENABLE_BLEND) !=
|
||||
(material1->flags & COGL_MATERIAL_FLAG_ENABLE_BLEND))
|
||||
return FALSE;
|
||||
/* XXX: potentially blending could be "enabled" but the blend mode
|
||||
* could be equivalent to being disabled. */
|
||||
|
||||
if (material0->flags & COGL_MATERIAL_FLAG_ENABLE_BLEND)
|
||||
{
|
||||
if ((material0->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND) !=
|
||||
(material1->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND))
|
||||
return FALSE;
|
||||
else if (flags & COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS &&
|
||||
!(material0->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND))
|
||||
return FALSE;
|
||||
#if 0
|
||||
else if (!_deep_is_blend_equal ())
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (material0_flush_options->fallback_layers !=
|
||||
material1_flush_options->fallback_layers ||
|
||||
material0_flush_options->disable_layers !=
|
||||
material1_flush_options->disable_layers)
|
||||
return FALSE;
|
||||
|
||||
l0 = material0->layers;
|
||||
l1 = material1->layers;
|
||||
|
||||
while (l0 && l1)
|
||||
{
|
||||
CoglMaterialLayer *layer0;
|
||||
CoglMaterialLayer *layer1;
|
||||
|
||||
if ((l0 == NULL && l1 != NULL) ||
|
||||
(l1 == NULL && l0 != NULL))
|
||||
return FALSE;
|
||||
|
||||
layer0 = l0->data;
|
||||
layer1 = l1->data;
|
||||
|
||||
if (layer0->texture != layer1->texture)
|
||||
return FALSE;
|
||||
|
||||
if ((layer0->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE) !=
|
||||
(layer1->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE))
|
||||
return FALSE;
|
||||
else if (flags & COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS &&
|
||||
!(layer0->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE))
|
||||
return FALSE;
|
||||
#if 0
|
||||
else if (!_deep_are_layer_combines_equal ())
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
l0 = l0->next;
|
||||
l1 = l1->next;
|
||||
}
|
||||
|
||||
if ((l0 == NULL && l1 != NULL) ||
|
||||
(l1 == NULL && l0 != NULL))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* While a material is referenced by the Cogl journal we can not allow
|
||||
* modifications, so this gives us a mechanism to track journal
|
||||
* references separately */
|
||||
CoglHandle
|
||||
_cogl_material_journal_ref (CoglHandle material_handle)
|
||||
{
|
||||
CoglMaterial *material =
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
material->journal_ref_count++;
|
||||
cogl_handle_ref (material_handle);
|
||||
return material_handle;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_material_journal_unref (CoglHandle material_handle)
|
||||
{
|
||||
CoglMaterial *material =
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
material->journal_ref_count--;
|
||||
cogl_handle_unref (material_handle);
|
||||
}
|
||||
|
||||
/* TODO: Should go in cogl.c, but that implies duplication which is also
|
||||
@ -1558,6 +1848,9 @@ cogl_material_set_layer_filters (CoglHandle handle,
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
/* possibly flush primitives referencing the current state... */
|
||||
_cogl_material_pre_change_notify (material, FALSE, NULL);
|
||||
|
||||
layer->min_filter = min_filter;
|
||||
layer->mag_filter = mag_filter;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -57,4 +57,6 @@ struct _CoglBezCubic
|
||||
floatVec2 p4;
|
||||
};
|
||||
|
||||
void _cogl_journal_flush (void);
|
||||
|
||||
#endif /* __COGL_PRIMITIVES_H */
|
||||
|
@ -137,6 +137,7 @@
|
||||
#include "cogl-vertex-buffer-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-material-private.h"
|
||||
#include "cogl-primitives.h"
|
||||
|
||||
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
|
||||
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
|
||||
@ -1500,9 +1501,10 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
gulong enable_flags = 0;
|
||||
guint max_texcoord_attrib_unit = 0;
|
||||
const GList *layers;
|
||||
guint32 fallback_mask = 0;
|
||||
guint32 disable_mask = ~0;
|
||||
guint32 fallback_layers = 0;
|
||||
guint32 disable_layers = ~0;
|
||||
int i;
|
||||
CoglMaterialFlushOptions options;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -1573,7 +1575,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
pointer));
|
||||
if (attribute->texture_unit > max_texcoord_attrib_unit)
|
||||
max_texcoord_attrib_unit = attribute->texture_unit;
|
||||
disable_mask &= ~(1 << attribute->texture_unit);
|
||||
disable_layers &= ~(1 << attribute->texture_unit);
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
|
||||
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
||||
@ -1638,17 +1640,24 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
* vertices once for each layer, each time with a fiddled texture
|
||||
* matrix.
|
||||
*/
|
||||
fallback_mask |= (1 << i);
|
||||
fallback_layers |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material,
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
|
||||
fallback_mask,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK,
|
||||
disable_mask,
|
||||
NULL);
|
||||
for (i = max_texcoord_attrib_unit + 1; i < ctx->n_texcoord_arrays_enabled; i++)
|
||||
{
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 + i));
|
||||
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
}
|
||||
ctx->n_texcoord_arrays_enabled = max_texcoord_attrib_unit + 1;
|
||||
|
||||
options.flags =
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK |
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
options.fallback_layers = fallback_layers;
|
||||
options.disable_layers = disable_layers;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
@ -1730,6 +1739,9 @@ cogl_vertex_buffer_draw (CoglHandle handle,
|
||||
if (!cogl_is_vertex_buffer (handle))
|
||||
return;
|
||||
|
||||
_cogl_journal_flush ();
|
||||
cogl_clip_ensure ();
|
||||
|
||||
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
|
||||
|
||||
cogl_clip_ensure ();
|
||||
@ -1859,6 +1871,9 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
|
||||
if (!cogl_is_vertex_buffer (handle))
|
||||
return;
|
||||
|
||||
_cogl_journal_flush ();
|
||||
cogl_clip_ensure ();
|
||||
|
||||
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
|
||||
|
||||
if (!cogl_is_vertex_buffer_indices (indices_handle))
|
||||
|
116
common/cogl.c
116
common/cogl.c
@ -216,6 +216,9 @@ cogl_get_enable ()
|
||||
void
|
||||
cogl_set_depth_test_enabled (gboolean setting)
|
||||
{
|
||||
/* Currently the journal can't track changes to depth state... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
if (setting)
|
||||
{
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
@ -236,6 +239,9 @@ cogl_set_backface_culling_enabled (gboolean setting)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Currently the journal can't track changes to backface culling state... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
ctx->enable_backface_culling = setting;
|
||||
}
|
||||
|
||||
@ -388,9 +394,15 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
float height,
|
||||
gboolean first)
|
||||
{
|
||||
CoglHandle current_source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->stencil_material, NULL);
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* temporarily swap in our special stenciling material */
|
||||
current_source = cogl_handle_ref (ctx->source_material);
|
||||
cogl_set_source (ctx->stencil_material);
|
||||
|
||||
if (first)
|
||||
{
|
||||
@ -443,9 +455,17 @@ _cogl_add_stencil_clip (float x_offset,
|
||||
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
||||
}
|
||||
|
||||
/* make sure our rectangles hit the stencil buffer before we restore
|
||||
* the stencil function / operation */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* Restore the stencil mode */
|
||||
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
|
||||
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
|
||||
|
||||
/* restore the original source material */
|
||||
cogl_set_source (current_source);
|
||||
cogl_handle_unref (current_source);
|
||||
}
|
||||
|
||||
void
|
||||
@ -554,6 +574,9 @@ cogl_get_features (void)
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
if (cogl_debug_flags & COGL_DEBUG_DISABLE_VBOS)
|
||||
ctx->feature_flags &= ~COGL_FEATURE_VBOS;
|
||||
|
||||
return ctx->feature_flags;
|
||||
}
|
||||
|
||||
@ -630,6 +653,9 @@ cogl_set_fog (const CoglColor *fog_color,
|
||||
GLfloat fogColor[4];
|
||||
GLenum gl_mode = GL_LINEAR;
|
||||
|
||||
/* The cogl journal doesn't currently track fog state changes */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
fogColor[0] = cogl_color_get_red_float (fog_color);
|
||||
fogColor[1] = cogl_color_get_green_float (fog_color);
|
||||
fogColor[2] = cogl_color_get_blue_float (fog_color);
|
||||
@ -667,6 +693,9 @@ cogl_set_fog (const CoglColor *fog_color,
|
||||
void
|
||||
cogl_disable_fog (void)
|
||||
{
|
||||
/* Currently the journal can't track changes to fog state... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
glDisable (GL_FOG);
|
||||
}
|
||||
|
||||
@ -678,6 +707,12 @@ cogl_flush_gl_state (int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
cogl_flush (void)
|
||||
{
|
||||
_cogl_journal_flush ();
|
||||
}
|
||||
|
||||
void
|
||||
cogl_read_pixels (int x,
|
||||
int y,
|
||||
@ -711,6 +746,10 @@ cogl_read_pixels (int x,
|
||||
glPixelStorei (GL_PACK_SKIP_ROWS, 0);
|
||||
#endif /* HAVE_COGL_GL */
|
||||
|
||||
/* make sure any batched primitives get emitted to the GL driver before
|
||||
* issuing our read pixels... */
|
||||
cogl_flush ();
|
||||
|
||||
glReadPixels (x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
/* TODO: consider using the GL_MESA_pack_invert extension in the future
|
||||
@ -732,3 +771,78 @@ cogl_read_pixels (int x,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cogl_begin_gl (void)
|
||||
{
|
||||
CoglMaterialFlushOptions options;
|
||||
gulong enable_flags;
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (ctx->in_begin_gl_block)
|
||||
{
|
||||
static gboolean shown = FALSE;
|
||||
if (!shown)
|
||||
g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks");
|
||||
shown = TRUE;
|
||||
return;
|
||||
}
|
||||
ctx->in_begin_gl_block = TRUE;
|
||||
|
||||
/* Flush all batched primitives */
|
||||
cogl_flush ();
|
||||
|
||||
/* Flush our clipping state to GL */
|
||||
cogl_clip_ensure ();
|
||||
|
||||
/* Flush any client side matrix state */
|
||||
_cogl_current_matrix_state_flush ();
|
||||
|
||||
|
||||
/* Setup the state for the current material */
|
||||
|
||||
/* We considered flushing a specific, minimal material here to try and
|
||||
* simplify the GL state, but decided to avoid special cases and second
|
||||
* guessing what would be actually helpful.
|
||||
*
|
||||
* A user should instead call cogl_set_source_color4ub() before
|
||||
* cogl_begin_gl() to simplify the state flushed.
|
||||
*/
|
||||
options.flags = 0;
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
|
||||
/* FIXME: This api is a bit yukky, ideally it will be removed if we
|
||||
* re-work the cogl_enable mechanism */
|
||||
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
/* Disable all client texture coordinate arrays */
|
||||
for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++)
|
||||
{
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 + i));
|
||||
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
}
|
||||
ctx->n_texcoord_arrays_enabled = 0;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_end_gl (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (!ctx->in_begin_gl_block)
|
||||
{
|
||||
static gboolean shown = FALSE;
|
||||
if (!shown)
|
||||
g_warning ("cogl_end_gl is being called before cogl_begin_gl");
|
||||
shown = TRUE;
|
||||
return;
|
||||
}
|
||||
ctx->in_begin_gl_block = FALSE;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,11 @@ cogl_set_source_texture
|
||||
CoglReadPixelsFlags
|
||||
cogl_read_pixels
|
||||
|
||||
<SUBSECTION>
|
||||
cogl_flush
|
||||
cogl_begin_gl
|
||||
cogl_end_gl
|
||||
|
||||
<SUBSECTION Standard>
|
||||
COGL_TYPE_ATTRIBUTE_TYPE
|
||||
COGL_TYPE_BUFFER_BIT
|
||||
|
@ -69,9 +69,13 @@ cogl_create_context ()
|
||||
|
||||
_context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
|
||||
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
|
||||
_context->journal_vbo = 0;
|
||||
_context->journal_vbo_len = 0;
|
||||
|
||||
_context->current_material = NULL;
|
||||
_context->current_material_flags = 0;
|
||||
memset (&_context->current_material_flush_options,
|
||||
0, sizeof (CoglMaterialFlushOptions));
|
||||
_context->current_layers = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglLayerInfo));
|
||||
_context->n_texcoord_arrays_enabled = 0;
|
||||
@ -86,6 +90,8 @@ cogl_create_context ()
|
||||
_context->last_path = 0;
|
||||
_context->stencil_material = cogl_material_new ();
|
||||
|
||||
_context->in_begin_gl_block = FALSE;
|
||||
|
||||
_context->pf_glGenRenderbuffersEXT = NULL;
|
||||
_context->pf_glBindRenderbufferEXT = NULL;
|
||||
_context->pf_glRenderbufferStorageEXT = NULL;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "cogl-clip-stack.h"
|
||||
#include "cogl-matrix-stack.h"
|
||||
#include "cogl-current-matrix.h"
|
||||
#include "cogl-material-private.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -78,10 +79,13 @@ typedef struct
|
||||
* can batch things together. */
|
||||
GArray *journal;
|
||||
GArray *logged_vertices;
|
||||
GLuint journal_vbo;
|
||||
size_t journal_vbo_len;
|
||||
|
||||
/* Some simple caching, to minimize state changes... */
|
||||
CoglHandle current_material;
|
||||
gulong current_material_flags;
|
||||
CoglMaterialFlushOptions current_material_flush_options;
|
||||
GArray *current_layers;
|
||||
guint n_texcoord_arrays_enabled;
|
||||
|
||||
@ -106,6 +110,8 @@ typedef struct
|
||||
guint quad_indices_short_len;
|
||||
CoglHandle quad_indices_short;
|
||||
|
||||
gboolean in_begin_gl_block;
|
||||
|
||||
/* Relying on glext.h to define these */
|
||||
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
|
||||
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
|
||||
|
@ -169,6 +169,8 @@ cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_journal_flush ();
|
||||
|
||||
g_assert (ctx->draw_buffer_stack != NULL);
|
||||
draw_buffer = ctx->draw_buffer_stack->data;
|
||||
|
||||
|
@ -76,16 +76,18 @@ _cogl_path_stroke_nodes ()
|
||||
{
|
||||
guint path_start = 0;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
CoglMaterialFlushOptions options;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK,
|
||||
(guint32)~0, /* disable all texture layers */
|
||||
NULL);
|
||||
options.flags = COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
/* disable all texture layers */
|
||||
options.disable_layers = (guint32)~0;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
|
||||
while (path_start < ctx->path_nodes->len)
|
||||
@ -123,18 +125,25 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
CoglPathNode *path,
|
||||
gboolean merge)
|
||||
{
|
||||
guint path_start = 0;
|
||||
guint sub_path_num = 0;
|
||||
float bounds_x;
|
||||
float bounds_y;
|
||||
float bounds_w;
|
||||
float bounds_h;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
guint path_start = 0;
|
||||
guint sub_path_num = 0;
|
||||
float bounds_x;
|
||||
float bounds_y;
|
||||
float bounds_w;
|
||||
float bounds_h;
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
CoglHandle prev_source;
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_journal_flush ();
|
||||
|
||||
/* Just setup a simple material that doesn't use texturing... */
|
||||
_cogl_material_flush_gl_state (ctx->stencil_material, NULL);
|
||||
prev_source = cogl_handle_ref (ctx->source_material);
|
||||
cogl_set_source (ctx->stencil_material);
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, NULL);
|
||||
|
||||
enable_flags |=
|
||||
_cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
@ -161,7 +170,15 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
|
||||
GE( glDepthMask (FALSE) );
|
||||
|
||||
for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++)
|
||||
{
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 + i));
|
||||
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
}
|
||||
ctx->n_texcoord_arrays_enabled = 0;
|
||||
|
||||
_cogl_current_matrix_state_flush ();
|
||||
|
||||
while (path_start < path_size)
|
||||
{
|
||||
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
@ -175,9 +192,8 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
significant bit */
|
||||
GE( glStencilMask (merge ? 6 : 3) );
|
||||
GE( glStencilOp (GL_ZERO, GL_REPLACE, GL_REPLACE) );
|
||||
cogl_rectangle (bounds_x, bounds_y,
|
||||
bounds_x + bounds_w, bounds_y + bounds_h);
|
||||
|
||||
glRectf (bounds_x, bounds_y,
|
||||
bounds_x + bounds_w, bounds_y + bounds_h);
|
||||
GE( glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT) );
|
||||
}
|
||||
|
||||
@ -210,8 +226,10 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
_cogl_current_matrix_push ();
|
||||
_cogl_current_matrix_identity ();
|
||||
|
||||
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
|
||||
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
|
||||
_cogl_current_matrix_state_flush ();
|
||||
|
||||
glRectf (-1.0, -1.0, 1.0, 1.0);
|
||||
glRectf (-1.0, -1.0, 1.0, 1.0);
|
||||
|
||||
_cogl_current_matrix_pop ();
|
||||
|
||||
@ -227,6 +245,10 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
||||
|
||||
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
|
||||
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
|
||||
|
||||
/* restore the original material */
|
||||
cogl_set_source (prev_source);
|
||||
cogl_handle_unref (prev_source);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -128,6 +128,11 @@ cogl_program_use (CoglHandle handle)
|
||||
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
|
||||
return;
|
||||
|
||||
/* The Cogl journal doesn't currently cope with the use of
|
||||
* shaders so we have to flush all priitives whenever the
|
||||
* current shader changes... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
if (handle == COGL_INVALID_HANDLE)
|
||||
gl_handle = 0;
|
||||
else
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "cogl-bitmap-private.h"
|
||||
#include "cogl-handle.h"
|
||||
#include "cogl-material-private.h"
|
||||
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
@ -99,10 +100,13 @@ struct _CoglTexture
|
||||
* later flush the journal we aim to batch data, and gl draw calls. */
|
||||
typedef struct _CoglJournalEntry
|
||||
{
|
||||
CoglHandle material;
|
||||
gint n_layers;
|
||||
guint32 fallback_mask;
|
||||
GLuint layer0_override_texture;
|
||||
CoglHandle material;
|
||||
int n_layers;
|
||||
CoglMaterialFlushOptions flush_options;
|
||||
CoglMatrix model_view;
|
||||
/* XXX: These entries are pretty big now considering the padding in
|
||||
* CoglMaterialFlushOptions and CoglMatrix, so we might need to optimize this
|
||||
* later. */
|
||||
} CoglJournalEntry;
|
||||
|
||||
CoglTexture*
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "cogl-material.h"
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-handle.h"
|
||||
#include "cogl-primitives.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -60,8 +61,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
extern void _cogl_journal_flush (void);
|
||||
|
||||
static void _cogl_texture_free (CoglTexture *tex);
|
||||
|
||||
COGL_HANDLE_DEFINE (Texture, texture);
|
||||
|
@ -1480,6 +1480,13 @@ cogl_wrap_glColor4f (GLclampf r, GLclampf g, GLclampf b, GLclampf a)
|
||||
glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB, r, g, b, a);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_wrap_glColor4ub (GLubyte r, GLubyte g, GLubyte b, GLubyte a)
|
||||
{
|
||||
glVertexAttrib4f (COGL_GLES2_WRAPPER_COLOR_ATTRIB,
|
||||
r/255.0, g/255.0, b/255.0, a/255.0);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation)
|
||||
{
|
||||
|
@ -340,6 +340,7 @@ void cogl_wrap_glDisableClientState (GLenum array);
|
||||
void cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref);
|
||||
|
||||
void cogl_wrap_glColor4f (GLclampf r, GLclampf g, GLclampf b, GLclampf a);
|
||||
void cogl_wrap_glColor4ub (GLubyte r, GLubyte g, GLubyte b, GLubyte a);
|
||||
|
||||
void cogl_wrap_glClipPlanef (GLenum plane, GLfloat *equation);
|
||||
|
||||
@ -393,6 +394,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
|
||||
#define glDisableClientState cogl_wrap_glDisableClientState
|
||||
#define glAlphaFunc cogl_wrap_glAlphaFunc
|
||||
#define glColor4f cogl_wrap_glColor4f
|
||||
#define glColor4ub cogl_wrap_glColor4ub
|
||||
#define glClipPlanef cogl_wrap_glClipPlanef
|
||||
#define glGetIntegerv cogl_wrap_glGetIntegerv
|
||||
#define glGetFloatv cogl_wrap_glGetFloatv
|
||||
|
Loading…
Reference in New Issue
Block a user