[cogl material] optimize logging of material colors in the journal

We now put the color of materials into the vertex array used by the journal
instead of calling glColor() but the number of requests for the material
color were quite expensive so we have changed the material color to
internally be byte components instead of floats to avoid repeat conversions
and added _cogl_material_get_colorubv as a fast-path for the journal to
copy data into the vertex array.
This commit is contained in:
Robert Bragg 2009-06-04 14:23:16 +01:00
parent 938452f1b1
commit aca1bf4329
5 changed files with 56 additions and 51 deletions

View File

@ -117,7 +117,7 @@ struct _CoglMaterial
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];
@ -234,20 +234,11 @@ typedef struct _CoglMaterialFlushOptions
GLuint layer0_override_texture;
} CoglMaterialFlushOptions;
/*
* cogl_material_flush_gl_state:
* @material: A CoglMaterial object
* @...: A NULL terminated list of (CoglMaterialFlushOption, data) pairs
*
* 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.
*/
void _cogl_material_get_colorubv (CoglHandle handle,
guint8 *color);
void _cogl_material_flush_gl_state (CoglHandle material,
CoglMaterialFlushOptions *options);

View File

@ -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... */
@ -160,7 +160,7 @@ handle_automatic_blend_enable (CoglMaterial *material)
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
}
if (material->unlit[3] != 1.0)
if (material->unlit[3] != 0xff)
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
}
@ -184,11 +184,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
@ -196,16 +205,16 @@ 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;
@ -215,10 +224,10 @@ cogl_material_set_color (CoglHandle handle,
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);
@ -1469,10 +1478,10 @@ _cogl_material_flush_base_gl_state (CoglMaterial *material,
ctx->current_material_flush_options.flags &
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR)
{
GE (glColor4f (material->unlit[0],
material->unlit[1],
material->unlit[2],
material->unlit[3]));
GE (glColor4ub (material->unlit[0],
material->unlit[1],
material->unlit[2],
material->unlit[3]));
}
}

View File

@ -575,16 +575,15 @@ _cogl_journal_log_quad (float x_1,
int next_vert;
GLfloat *v;
GLubyte *c;
GLubyte *src_c;
int i;
int next_entry;
guint32 disable_layers;
CoglJournalEntry *entry;
CoglColor color;
guint8 r, g, b, a;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* The vertex data is logged into a seperate array in a layout that can be
/* The vertex data is logged into a separate array in a layout that can be
* directly passed to OpenGL
*/
@ -605,26 +604,23 @@ _cogl_journal_log_quad (float x_1,
/* XXX: we could defer expanding the vertex data for GL until we come
* to flushing the journal. */
cogl_material_get_color (material, &color);
r = cogl_color_get_red_byte (&color);
g = cogl_color_get_green_byte (&color);
b = cogl_color_get_blue_byte (&color);
a = cogl_color_get_alpha_byte (&color);
/* FIXME: This is a hacky optimization, since it will break if we
* change the definition of CoglColor: */
_cogl_material_get_colorubv (material, c);
src_c = c;
for (i = 0; i < 3; i++)
{
c += byte_stride;
memcpy (c, src_c, 4);
}
v[0] = x_1; v[1] = y_1;
c[0] = r; c[1] = g; c[2] = b; c[3] = a;
v += stride;
c += byte_stride;
v[0] = x_1; v[1] = y_2;
c[0] = r; c[1] = g; c[2] = b; c[3] = a;
v += stride;
c += byte_stride;
v[0] = x_2; v[1] = y_2;
c[0] = r; c[1] = g; c[2] = b; c[3] = a;
v += stride;
c += byte_stride;
v[0] = x_2; v[1] = y_1;
c[0] = r; c[1] = g; c[2] = b; c[3] = a;
for (i = 0; i < n_layers; i++)
{

View File

@ -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)
{

View File

@ -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