mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
[cogl-material] Some improvements for how we sync CoglMaterial state with OpenGL
This flattens the three functions: cogl_material_flush_gl_material_state, .._flush_gl_alpha_func and .._flush_gl_blend_func into one: cogl_flush_material_gl_state which doesn't takes a material handle. (the handle is instead taken from the context.) This has allows us to avoid re-submitting some state to OpenGL when the material has not been replaced. Note: Avoiding redundant state changes for material layers isn't dealt with in this patch.
This commit is contained in:
parent
ef992f55db
commit
e4548bcdc5
@ -152,20 +152,6 @@ void cogl_material_set_shininess (CoglHandle material,
|
||||
void cogl_material_set_emission (CoglHandle material,
|
||||
const CoglColor *emission);
|
||||
|
||||
/**
|
||||
* cogl_set_source:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This function sets the source material that will be used to fill
|
||||
* subsequent geometry emitted via the cogl API.
|
||||
*
|
||||
* XXX: This doesn't really belong to the cogl-material API, it should
|
||||
* move to cogl.h
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_set_source (CoglHandle material);
|
||||
|
||||
/**
|
||||
* CoglMaterialAlphaFunc:
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through.
|
||||
@ -586,34 +572,10 @@ void cogl_material_set_layer_matrix (CoglHandle material,
|
||||
* Note: This API is hopfully just a stop-gap solution. Ideally
|
||||
* cogl_enable will be replaced.
|
||||
*/
|
||||
/* TODO: find a nicer solution! */
|
||||
gulong
|
||||
cogl_material_get_cogl_enable_flags (CoglHandle handle);
|
||||
|
||||
/**
|
||||
* cogl_material_flush_gl_material_state:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This commits the glMaterial state to the OpenGL driver. Normally you
|
||||
* shouldn't need to use this function directly, since Cogl will do this
|
||||
* internally, but if you are developing custom primitives directly with
|
||||
* OpenGL you may want to use this.
|
||||
*/
|
||||
void cogl_material_flush_gl_material_state (CoglHandle material_handle);
|
||||
|
||||
/**
|
||||
* cogl_material_flush_gl_alpha_func:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
*/
|
||||
void cogl_material_flush_gl_alpha_func (CoglHandle material_handle);
|
||||
|
||||
/**
|
||||
* cogl_material_flush_gl_blend_func:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
*/
|
||||
void cogl_material_flush_gl_blend_func (CoglHandle material_handle);
|
||||
|
||||
/**
|
||||
* cogl_material_get_layers:
|
||||
* @material: A CoglMaterial object
|
||||
@ -691,6 +653,38 @@ CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle);
|
||||
*/
|
||||
void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle);
|
||||
|
||||
/**
|
||||
* cogl_set_source:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This function sets the source material that will be used to fill
|
||||
* subsequent geometry emitted via the cogl API.
|
||||
*
|
||||
* Note: 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.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
/* XXX: This doesn't really belong to the cogl-material API, it should
|
||||
* move to cogl.h */
|
||||
void cogl_set_source (CoglHandle material);
|
||||
|
||||
/**
|
||||
* cogl_flush_material_gl_state:
|
||||
*
|
||||
* This function commits all the state of the source CoglMaterial - not
|
||||
* including the per-layer state - to the OpenGL[ES] driver.
|
||||
*
|
||||
* Normally you shouldn't need to use this function directly, but if you
|
||||
* are developing a custom primitive using raw OpenGL that works with
|
||||
* CoglMaterials, then you may want to use this function.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
/* XXX: This should be moved with cogl_set_source to cogl.h */
|
||||
void cogl_flush_material_gl_state (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_MATERIAL_H__ */
|
||||
|
@ -79,7 +79,8 @@ cogl_material_set_ambient (CoglHandle handle,
|
||||
ambient[1] = cogl_color_get_green_float (ambient_color);
|
||||
ambient[2] = cogl_color_get_blue_float (ambient_color);
|
||||
ambient[3] = cogl_color_get_alpha_float (ambient_color);
|
||||
/* material->ambient = *ambient_color; */
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
@ -98,7 +99,8 @@ cogl_material_set_diffuse (CoglHandle handle,
|
||||
diffuse[1] = cogl_color_get_green_float (diffuse_color);
|
||||
diffuse[2] = cogl_color_get_blue_float (diffuse_color);
|
||||
diffuse[3] = cogl_color_get_alpha_float (diffuse_color);
|
||||
/* material->diffuse = *diffuse_color; */
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
@ -125,7 +127,8 @@ cogl_material_set_specular (CoglHandle handle,
|
||||
specular[1] = cogl_color_get_green_float (specular_color);
|
||||
specular[2] = cogl_color_get_blue_float (specular_color);
|
||||
specular[3] = cogl_color_get_alpha_float (specular_color);
|
||||
/* material->specular = *specular_color; */
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
@ -143,6 +146,8 @@ cogl_material_set_shininess (CoglHandle handle,
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
material->shininess = (GLfloat)shininess * 128.0;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
@ -161,22 +166,8 @@ cogl_material_set_emission (CoglHandle handle,
|
||||
emission[1] = cogl_color_get_green_float (emission_color);
|
||||
emission[2] = cogl_color_get_blue_float (emission_color);
|
||||
emission[3] = cogl_color_get_alpha_float (emission_color);
|
||||
/* material->emission = *emission_color; */
|
||||
}
|
||||
|
||||
/* TODO: Should go in cogl.c */
|
||||
void
|
||||
cogl_set_source (CoglHandle material_handle)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
|
||||
if (ctx->source_material)
|
||||
cogl_material_unref (ctx->source_material);
|
||||
|
||||
cogl_material_ref (material_handle);
|
||||
ctx->source_material = material_handle;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
@ -191,6 +182,8 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
material->alpha_func = alpha_func;
|
||||
material->alpha_func_reference = (GLfloat)alpha_reference;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
@ -205,6 +198,8 @@ cogl_material_set_blend_factors (CoglHandle handle,
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
material->blend_src_factor = src_factor;
|
||||
material->blend_dst_factor = dst_factor;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
/* Asserts that a layer corresponding to the given index exists. If no
|
||||
@ -492,44 +487,6 @@ cogl_material_get_cogl_enable_flags (CoglHandle material_handle)
|
||||
return enable_flags;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_flush_gl_material_state (CoglHandle material_handle)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess));
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_flush_gl_alpha_func (CoglHandle material_handle)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
|
||||
/* NB: Currently the Cogl defines are compatible with the GL ones: */
|
||||
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_flush_gl_blend_func (CoglHandle material_handle)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor));
|
||||
}
|
||||
|
||||
/* It's a bit out of the ordinary to return a const GList *, but it's
|
||||
* probably sensible to try and avoid list manipulation for every
|
||||
* primitive emitted in a scene, every frame.
|
||||
@ -678,3 +635,50 @@ cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle)
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Should go in cogl.c, but that implies duplication which is also
|
||||
* not ideal. */
|
||||
void
|
||||
cogl_set_source (CoglHandle material_handle)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
|
||||
if (ctx->source_material == material_handle)
|
||||
return;
|
||||
|
||||
if (ctx->source_material)
|
||||
cogl_material_unref (ctx->source_material);
|
||||
|
||||
cogl_material_ref (material_handle);
|
||||
ctx->source_material = material_handle;
|
||||
}
|
||||
/* TODO: add cogl_set_front_source (), and cogl_set_back_source () */
|
||||
|
||||
void
|
||||
cogl_flush_material_gl_state (void)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (ctx->source_material);
|
||||
|
||||
if (ctx->source_material == ctx->current_material
|
||||
&& !(material->flags & COGL_MATERIAL_FLAG_DIRTY))
|
||||
return;
|
||||
|
||||
/* FIXME - we only need to set these if lighting is enabled... */
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess));
|
||||
|
||||
/* NB: Currently the Cogl defines are compatible with the GL ones: */
|
||||
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
|
||||
|
||||
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor));
|
||||
|
||||
ctx->current_material = ctx->source_material;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ cogl_create_context ()
|
||||
_context->material_handles = NULL;
|
||||
_context->material_layer_handles = NULL;
|
||||
_context->source_material = NULL;
|
||||
_context->current_material = NULL;
|
||||
|
||||
_context->fbo_handles = NULL;
|
||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||
|
@ -70,6 +70,7 @@ typedef struct
|
||||
GArray *material_handles;
|
||||
GArray *material_layer_handles;
|
||||
CoglHandle source_material;
|
||||
CoglHandle current_material;
|
||||
|
||||
/* Framebuffer objects */
|
||||
GArray *fbo_handles;
|
||||
|
@ -2531,9 +2531,8 @@ cogl_material_rectangle (CoglFixed x1,
|
||||
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords));
|
||||
|
||||
/* Setup the remaining GL state according to this material... */
|
||||
cogl_material_flush_gl_material_state (material);
|
||||
cogl_material_flush_gl_alpha_func (material);
|
||||
cogl_material_flush_gl_blend_func (material);
|
||||
cogl_flush_material_gl_state ();
|
||||
|
||||
/* 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 (material);
|
||||
|
Loading…
Reference in New Issue
Block a user