material: Adds backend abstraction for fragment processing

As part of an effort to improve the architecture of CoglMaterial
internally this overhauls how we flush layer state to OpenGL by adding a
formal backend abstraction for fragment processing and further
formalizing the CoglTextureUnit abstraction.

There are three backends: "glsl", "arbfp" and "fixed". The fixed backend
uses the OpenGL fixed function APIs to setup the fragment processing,
the arbfp backend uses code generation to handle fragment processing
using an ARBfp program, and the GLSL backend is currently only there as
a formality to handle user programs associated with a material. (i.e.
the glsl backend doesn't yet support code generation)

The GLSL backend has highest precedence, then arbfp and finally the
fixed. If a backend can't support some particular CoglMaterial feature
then it will fallback to the next backend.

This adds three new COGL_DEBUG options:
* "disable-texturing" as expected should disable all texturing
* "disable-arbfp" always make the arbfp backend fallback
* "disable-glsl" always make the glsl backend fallback
* "show-source" show code generated by the arbfp/glsl backends
This commit is contained in:
Robert Bragg
2010-04-26 10:01:43 +01:00
parent 8ebf76a9a9
commit acc44161c1
20 changed files with 2445 additions and 1076 deletions

View File

@ -159,7 +159,6 @@
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
#define glMapBuffer ctx->drv.pf_glMapBuffer
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
#define glActiveTexture ctx->drv.pf_glActiveTexture
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
@ -1509,7 +1508,7 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
}
}
static void
static CoglHandle
enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
{
GList *tmp;
@ -1522,8 +1521,9 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
guint32 fallback_layers = 0;
int i;
CoglMaterialFlushOptions options;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
if (buffer->new_attributes)
cogl_vertex_buffer_submit_real (buffer);
@ -1717,18 +1717,29 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
options.fallback_layers = fallback_layers;
_cogl_material_flush_gl_state (ctx->source_material, &options);
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
if (G_UNLIKELY (ctx->legacy_state_set))
{
source = cogl_material_copy (ctx->source_material);
_cogl_material_apply_legacy_state (source);
}
else
source = ctx->source_material;
_cogl_material_flush_gl_state (source, &options);
enable_flags |= _cogl_material_get_cogl_enable_flags (source);
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
_cogl_enable (enable_flags);
_cogl_flush_face_winding ();
return source;
}
static void
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer,
CoglHandle source)
{
GList *tmp;
GLenum gl_type;
@ -1738,6 +1749,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (G_UNLIKELY (source != ctx->source_material))
cogl_handle_unref (source);
/* Disable all the client state that cogl doesn't currently know
* about:
*/
@ -1798,6 +1812,7 @@ cogl_vertex_buffer_draw (CoglHandle handle,
int count)
{
CoglVertexBuffer *buffer;
CoglHandle source;
if (!cogl_is_vertex_buffer (handle))
return;
@ -1806,11 +1821,11 @@ cogl_vertex_buffer_draw (CoglHandle handle,
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
enable_state_for_drawing_buffer (buffer);
source = enable_state_for_drawing_buffer (buffer);
GE (glDrawArrays (mode, first, count));
disable_state_for_drawing_buffer (buffer);
disable_state_for_drawing_buffer (buffer, source);
}
static int
@ -1934,6 +1949,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
gsize byte_offset;
CoglVertexBufferIndices *indices = NULL;
CoglHandle source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1949,7 +1965,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
enable_state_for_drawing_buffer (buffer);
source = enable_state_for_drawing_buffer (buffer);
byte_offset = indices_offset * get_indices_type_size (indices->type);
if (fallback)
@ -1961,7 +1977,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
GE (glDrawRangeElements (mode, min_index, max_index,
count, indices->type, (void *)byte_offset));
disable_state_for_drawing_buffer (buffer);
disable_state_for_drawing_buffer (buffer, source);
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
}