mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +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,
|
void cogl_material_set_emission (CoglHandle material,
|
||||||
const CoglColor *emission);
|
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:
|
* CoglMaterialAlphaFunc:
|
||||||
* @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through.
|
* @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
|
* Note: This API is hopfully just a stop-gap solution. Ideally
|
||||||
* cogl_enable will be replaced.
|
* cogl_enable will be replaced.
|
||||||
*/
|
*/
|
||||||
|
/* TODO: find a nicer solution! */
|
||||||
gulong
|
gulong
|
||||||
cogl_material_get_cogl_enable_flags (CoglHandle handle);
|
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:
|
* cogl_material_get_layers:
|
||||||
* @material: A CoglMaterial object
|
* @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);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_MATERIAL_H__ */
|
#endif /* __COGL_MATERIAL_H__ */
|
||||||
|
@ -79,7 +79,8 @@ cogl_material_set_ambient (CoglHandle handle,
|
|||||||
ambient[1] = cogl_color_get_green_float (ambient_color);
|
ambient[1] = cogl_color_get_green_float (ambient_color);
|
||||||
ambient[2] = cogl_color_get_blue_float (ambient_color);
|
ambient[2] = cogl_color_get_blue_float (ambient_color);
|
||||||
ambient[3] = cogl_color_get_alpha_float (ambient_color);
|
ambient[3] = cogl_color_get_alpha_float (ambient_color);
|
||||||
/* material->ambient = *ambient_color; */
|
|
||||||
|
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -98,7 +99,8 @@ cogl_material_set_diffuse (CoglHandle handle,
|
|||||||
diffuse[1] = cogl_color_get_green_float (diffuse_color);
|
diffuse[1] = cogl_color_get_green_float (diffuse_color);
|
||||||
diffuse[2] = cogl_color_get_blue_float (diffuse_color);
|
diffuse[2] = cogl_color_get_blue_float (diffuse_color);
|
||||||
diffuse[3] = cogl_color_get_alpha_float (diffuse_color);
|
diffuse[3] = cogl_color_get_alpha_float (diffuse_color);
|
||||||
/* material->diffuse = *diffuse_color; */
|
|
||||||
|
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -125,7 +127,8 @@ cogl_material_set_specular (CoglHandle handle,
|
|||||||
specular[1] = cogl_color_get_green_float (specular_color);
|
specular[1] = cogl_color_get_green_float (specular_color);
|
||||||
specular[2] = cogl_color_get_blue_float (specular_color);
|
specular[2] = cogl_color_get_blue_float (specular_color);
|
||||||
specular[3] = cogl_color_get_alpha_float (specular_color);
|
specular[3] = cogl_color_get_alpha_float (specular_color);
|
||||||
/* material->specular = *specular_color; */
|
|
||||||
|
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -143,6 +146,8 @@ cogl_material_set_shininess (CoglHandle handle,
|
|||||||
material = _cogl_material_pointer_from_handle (handle);
|
material = _cogl_material_pointer_from_handle (handle);
|
||||||
|
|
||||||
material->shininess = (GLfloat)shininess * 128.0;
|
material->shininess = (GLfloat)shininess * 128.0;
|
||||||
|
|
||||||
|
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -161,22 +166,8 @@ cogl_material_set_emission (CoglHandle handle,
|
|||||||
emission[1] = cogl_color_get_green_float (emission_color);
|
emission[1] = cogl_color_get_green_float (emission_color);
|
||||||
emission[2] = cogl_color_get_blue_float (emission_color);
|
emission[2] = cogl_color_get_blue_float (emission_color);
|
||||||
emission[3] = cogl_color_get_alpha_float (emission_color);
|
emission[3] = cogl_color_get_alpha_float (emission_color);
|
||||||
/* material->emission = *emission_color; */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Should go in cogl.c */
|
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -191,6 +182,8 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
|
|||||||
material = _cogl_material_pointer_from_handle (handle);
|
material = _cogl_material_pointer_from_handle (handle);
|
||||||
material->alpha_func = alpha_func;
|
material->alpha_func = alpha_func;
|
||||||
material->alpha_func_reference = (GLfloat)alpha_reference;
|
material->alpha_func_reference = (GLfloat)alpha_reference;
|
||||||
|
|
||||||
|
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -205,6 +198,8 @@ cogl_material_set_blend_factors (CoglHandle handle,
|
|||||||
material = _cogl_material_pointer_from_handle (handle);
|
material = _cogl_material_pointer_from_handle (handle);
|
||||||
material->blend_src_factor = src_factor;
|
material->blend_src_factor = src_factor;
|
||||||
material->blend_dst_factor = dst_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
|
/* 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;
|
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
|
/* 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
|
* probably sensible to try and avoid list manipulation for every
|
||||||
* primitive emitted in a scene, every frame.
|
* 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_handles = NULL;
|
||||||
_context->material_layer_handles = NULL;
|
_context->material_layer_handles = NULL;
|
||||||
_context->source_material = NULL;
|
_context->source_material = NULL;
|
||||||
|
_context->current_material = NULL;
|
||||||
|
|
||||||
_context->fbo_handles = NULL;
|
_context->fbo_handles = NULL;
|
||||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||||
|
@ -70,6 +70,7 @@ typedef struct
|
|||||||
GArray *material_handles;
|
GArray *material_handles;
|
||||||
GArray *material_layer_handles;
|
GArray *material_layer_handles;
|
||||||
CoglHandle source_material;
|
CoglHandle source_material;
|
||||||
|
CoglHandle current_material;
|
||||||
|
|
||||||
/* Framebuffer objects */
|
/* Framebuffer objects */
|
||||||
GArray *fbo_handles;
|
GArray *fbo_handles;
|
||||||
|
@ -2531,9 +2531,8 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords));
|
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords));
|
||||||
|
|
||||||
/* Setup the remaining GL state according to this material... */
|
/* Setup the remaining GL state according to this material... */
|
||||||
cogl_material_flush_gl_material_state (material);
|
cogl_flush_material_gl_state ();
|
||||||
cogl_material_flush_gl_alpha_func (material);
|
|
||||||
cogl_material_flush_gl_blend_func (material);
|
|
||||||
/* FIXME: This api is a bit yukky, ideally it will be removed if we
|
/* FIXME: This api is a bit yukky, ideally it will be removed if we
|
||||||
* re-work the cogl_enable mechanism */
|
* re-work the cogl_enable mechanism */
|
||||||
enable_flags |= cogl_material_get_cogl_enable_flags (material);
|
enable_flags |= cogl_material_get_cogl_enable_flags (material);
|
||||||
|
Loading…
Reference in New Issue
Block a user