We were incorrectly guarding the use of GL_TEXTURE_RECTANGLE_ARB with
ifdef ARB_texture_rectangle instead of ifdef GL_ARB_texture_rectangle
which broke test-cogl-texture-rectangle.
This was mistakenly added some time ago because at some point when we
were discussing how to handle premultiplied alpha in Clutter/Cogl we
were considering having a magic "just do the right thing" option which
was later abandoned.
This is to try and improve API consistency. Simple cogl structures that
don't derive from CoglObject and which can be allocated on the stack,
such as CoglColor and CoglMatrix should all have "_init" or
"_init_from" functions to initialize all the structure members. (As
opposed to a cogl_xyz_new() function for CoglObjects). CoglColor
previously used the naming scheme "_set_from" for these initializers but
"_set" is typically reserved for setting individual properties of a
structure/object.
This adds three _init functions:
cogl_color_init_from_4ub
cogl_color_init_from_4f
cogl_color_init_from_4fv
The _set_from functions are now deprecated but only with a gtk-doc
annotation for now. This is because the cogl_color_set_from API is quite
widely used already and so were giving a grace period before enabling a
GCC deprecated warning just because otherwise the MX maintainers will
complain to me that I've made their build logs look messy.
The journal logs colors as 4bytes into a vertex array and since we are
planning to make CoglMaterial track its color using a CoglColor instead
of a byte array this convenience will be useful for re-implementing
_cogl_material_get_colorubv.
Some internal symbols used for the GLES 2 wrapper were accidentally
being exported. This prepends an underscore to them so they won't
appear in the shared library.
Whenever a path or a rectangle is added to the clip stack it now also
stores a screen space bounding box in the entry. Then when the clip
stack is flushed the bounding box is first used to set up the
scissor. That way when we eventually come to use the stencil buffer
the clear will be affected by the scissor so we don't have to clear
the entire buffer.
_cogl_path_get_bounds is no longer static and is exported in
cogl-path-private.h so that it can be used in the clip stack code. The
old version of the function returned x/y and width/height. However
this was mostly used to call cogl_rectangle which takes x1/y1
x2/y2. The function has been changed to just directly return the
second form because it is more useful. Anywhere that was previously
using the function now just directly looks at path->path_nodes_min and
path->path_nodes_max instead.
The transform_point function takes a modelview matrix, projection
matrix and a viewport and performs all three transformations on a
point to give a Cogl window coordinate. This is useful in a number of
places in Cogl so this patch moves it to cogl.c and adds it to
cogl-internal.h
For sliced 2D textures, _cogl_texture_2d_sliced_get_data() uses the
bitmap width, instead of the rowstride, when memcpy()ing into the
dest buffer.
Signed-off-by: Robert Bragg <robert@linux.intel.com>
We only had getters for the red, green, blue and alpha channels of a
color. This meant that, if you wanted to change, say, the alpha
component of a color, one would need to query the red, green and blue
channels and use set_from_4ub() or set_from_4f().
Instead of this, just provide some setters for CoglColor, using the same
naming scheme than the existing getters.
For some operations on pre-multiplied colors (say, replace the alpha
value), you need to unpremultiply the color.
This patch provides the counterpart to cogl_color_premultiply().
The place where we actually change the framebuffer is
_cogl_framebuffer_flush_state(), so if we changed to a new frame buffer
we need to initialize the color bits there.
http://bugzilla.openedhand.com/show_bug.cgi?id=2094
OpenGL 3.0 deprecated querying of the GL_{RED,GREEN,BLUE}_BITS
constants, and the FBO extension provides a mechanism to query for the
color buffer sizes which *should* work even with the default
framebuffer. Unfortunately, this doesn't seem to hold for Mesa - so we
just use this for the offscreen CoglFramebuffer type, and we fall back
to glGetIntegerv() for the onscreen one.
http://bugzilla.openedhand.com/show_bug.cgi?id=2094
This function had two problems. Firstly it would clear the enable
blend flag before calling pre_change_notify so that if blending was
previously enabled the journal would end up being flushed while the
flag was still cleared. Secondly it would call the pre change notify
whenever blending is needed regardless of whether it was already
needed previously.
This was causing problems in test-depth.
This adds a _cogl_bind_gl_texture_transient function that should be used
instead of glBindTexture so we can have a consistent cache of the
textures bound to each texture unit so we can avoid some redundant
binding.
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
_cogl_atlas_texture_blit_begin binds a texture to use as the
destination and it expects it to stay bound until
_cogl_atlas_texture_end_blit is called. However there was a call to
_cogl_journal_flush directly after setting up the blit state which
could cause the wrong texture to be bound. This just moves the flush
to before the call to _cogl_atlas_texture_blit_begin.
This was breaking test-cogl-sub-texture.
1) Always flush when migrating textures out of an atlas because although
it's true that the original texture data will remain valid in the
original texture we can't assume that journal entries have resolved the
GL texture that will be used. This is only true if a layer0_override has
been used.
2) Don't flush at the point of creating a new atlas simply flush
immediately before reorganizing an atlas. This means we are now assuming
that we will never see recursion due to atlas textures being modified
during a journal flush. This means it's the responsibility of the
primitives code to _ensure_mipmaps for example not the responsibility of
_cogl_material_flush_gl_state.
We want to make sure that the material state flushing code will never
result in changes to the texture storage for that material. So for
example mipmaps need to be ensured by the primitives code.
Changes to the texture storage will invalidate the texture coordinates
in the journal and we want to avoid a recursion of journal flushing.
This adds a way to compare two CoglMatrix structures to see if they
represent the same transformations. memcmp can't be used because a
CoglMatrix contains private flags and padding.
THIS IS A WORK IN PROGRESS
Mesa is building a big shader when using ARB_texture_env_combine. The
idea is to bypass that computation, do it ourselves and cache the
compiled program in a CoglMaterial.
For now that feature can be enabled by setting the COGL_PIPELINE
environment variable to "arbfp". COGL_SHOW_FP_SOURCE can be set to a non
empty string to dump the fragment program source too.
TODO:
* fog (really easy, using OPTION)
* support tex env combiner operands, DOT3, ADD_SIGNED, INTERPOLATE
combine modes (need refactoring the generation of temporary
variables) (not too hard)
* alpha testing for GLES 2.0?
The Cogl context has now a feature_flags_private enum that will allow us
to query and use OpenGL features without exposing them in the public
API.
The ARB_fragment_program extension is the first user of those flags.
Looking for this extension only happens in the gl driver as the gles
drivers will not expose them.
One can use _cogl_features_available_private() to check for the
availability of such private features.
While at it, reindent cogl-internal.h as described in CODING_STYLE.
At two places in cogl_wrap_prepare_for_draw it was trying to loop over
the texture units to flush some state. However it was retrieving the
texture unit pointer using w->active_texture_unit instead of the loop
index so it would end up with the wrong state.
Also in glEnableClientState it was using the active unit instead of
the client active unit.
• 3 general fixes (typos, copy/paste),
• ignore cogl-object-private.h,
• cogl_fixed_atani() was in reality cogl_fixed_atan(), fixed in commit
43564f05.
• Fix the cogl-vector section: sections must have a </SECTION> tag at
the end. Also the cogl-vector section was added in the middle of the
cogl-buffer one. Let's shiffle it out and add that </SECTION> tag.
As with a351ff2af earlier, distributing headers generated at configure
time conflicts with out of tree builds as the distributed headers will
be included first instead of including the generated ones.
This provides a mechanism for associating private data with any
CoglObject. We expect Clutter will use this to associate weak materials
with normal materials.
This replaces the use of CoglHandle with strongly type CoglClipStack *
pointers instead. The only function not converted for now is
cogl_is_clip_stack which will be done in a later commit.
This replaces the use of CoglHandle with strongly type CoglBitmap *
pointers instead. The only function not converted for now is
cogl_is_bitmap which will be done in a later commit.
This replaces the use of CoglHandle with strongly type CoglPath *
pointers instead. The only function not converted for now is
cogl_is_path which will be done in a later commit.
This patch makes it so that only the backwards compatibility
COGL_HANDLE_DEFINE macro defines a _cogl_xyz_handle_new function. The
new COGL_OBJECT_DEFINE macro only defines a _cogl_xyz_object_new
function.
It's valid C to declare a function omitting it prototype, but it seems
to be a good practise to always declare a function with its
corresponding prototype.
While this is totally fine (0 in the pointer context will be converted
in the right internal NULL representation, which could be a value with
some bits to 1), I believe it's clearer to use NULL in the pointer
context.
It seems that, in most case, it's more an overlook than a deliberate
choice to use FALSE/0 as NULL, eg. copying a _COGL_GET_CONTEXT (ctx, 0)
or a g_return_val_if_fail (cond, 0) from a function returning a
gboolean.
This replaces the use of CoglHandle with strongly type CoglBuffer *
pointers instead. The only function not converted for now is
cogl_is_buffer which will be done in a later commit.
CoglHandle is a common source of complaints and confusion because people
expect a "handle" to be some form of integer type with some indirection
to lookup the corresponding objects as opposed to a direct pointer.
This patch starts by renaming CoglHandle to CoglObject * and creating
corresponding cogl_object_ APIs to replace the cogl_handle ones.
The next step though is to remove all use of CoglHandle in the Cogl APIs
and replace with strongly typed pointer types such as CoglMaterial * or
CoglTexture * etc also all occurrences of COGL_INVALID_HANDLE can just
use NULL instead.
After this we will consider switching to GTypeInstance internally so we
can have inheritance for our types and hopefully improve how we handle
bindings.
Note all these changes will be done in a way that maintains the API and
ABI.
Since the default alpha test function of GL_ALWAYS is equivalent to
GL_ALPHA_TEST being disabled we don't need to worry about Enabling/Disabling
it when flushing material state, instead it's enough to leave it always
enabled. We will assume that any driver worth its salt wont incur any
additional cost for glEnable (GL_ALPHA_TEST) + GL_ALWAYS vs
glDisable (GL_ALPHA_TEST).
This patch simply calls glEnable (GL_ALPHA_TEST) in cogl_create_context
When _cogl_disable_other_texcoord_arrays is called it disables the
neccessary texcoord arrays and then removes the bits for the disabled
arrays in ctx->texcoord_arrays_enabled. However none of the places
that call the function then set any bits in ctx->texcoord_arrays_enabled
so the arrays would never get marked and they would never get disabled
again.
This patch just changes it so that _cogl_disable_other_texcoord_arrays
also sets the corresponding bits in ctx->texcoord_arrays_enabled.
Instead of directly using a guint32 to store a bitmask for each used
texcoord array, it now stores them in a CoglBitmask. This removes the
limitation of 32 layers (although there are still other places in Cogl
that imply this restriction). To disable texcoord arrays code should
call _cogl_disable_other_texcoord_arrays which takes a bitmask of
texcoord arrays that should not be disabled. There are two extra
bitmasks stored in the CoglContext which are used temporarily for this
function to avoid allocating a new bitmask each time.
http://bugzilla.openedhand.com/show_bug.cgi?id=2132
This implements a growable array of bits called CoglBitmask. The
CoglBitmask is intended to be cheap if less than 32 bits are used. If
more bits are required it will allocate a GArray. The type is meant to
be allocated on the stack but because it can require additional
resources it also has a destroy function.
http://bugzilla.openedhand.com/show_bug.cgi?id=2132
Previously the counter for the number of layers was only updated
whenever the texture handle for a layer changes. However there are
many other ways for a new layer to be created for example by setting a
layer combine constant. Also by default the texture on a layer is
COGL_INVALID_HANDLE so if the application tries to create an explicit
layer with no texture by calling cogl_material_set_layer with
COGL_INVALID_HANDLE then it also wouldn't update the count.
This patch fixes that by incrementing the count in
cogl_material_get_layer instead. This function is called by all
functions that may end up creating a layer so it seems like the most
appropriate place.
http://bugzilla.openedhand.com/show_bug.cgi?id=2132
It should be quite acceptable to use a texture without defining any
texture coords. For example a shader may be in use that is doing
texture lookups without referencing the texture coordinates. Also it
should be possible to replace the vertex colors using a texture layer
without a texture but with a constant layer color.
enable_state_for_drawing_buffer no longer sets any disabled layers in
the overrides. Instead of counting the number of units with texture
coordinates it now keeps them in a mask. This means there can now be
gaps in the list of enabled texture coordinate arrays. To cope with
this, the Cogl context now also stores a mask to track the enabled
arrays. Instead of code manually iterating each enabled array to
disable them, there is now an internal function called
_cogl_disable_texcoord_arrays which disables a given mask.
I think this could also fix potential bugs when a vertex buffer has
gaps in the texture coordinate attributes that it provides. For
example if the vertex buffer only had texture coordinates for layer 2
then the disabling code would not disable the coordinates for layers 0
and 1 even though they are not used. This could cause a crash if the
previous data for those arrays is no longer valid.
http://bugzilla.openedhand.com/show_bug.cgi?id=2132
This adds a math utility API for handling 3 component, single precision
float vectors with the following; mostly self explanatory functions:
cogl_vector3_init
cogl_vector3_init_zero
cogl_vector3_equal
cogl_vector3_equal_with_epsilon
cogl_vector3_copy
cogl_vector3_free
cogl_vector3_invert
cogl_vector3_add
cogl_vector3_subtract
cogl_vector3_multiply_scalar
cogl_vector3_divide_scalar
cogl_vector3_normalize
cogl_vector3_magnitude
cogl_vector3_cross_product
cogl_vector3_dot_product
cogl_vector3_distance
Since the API is experimental you will need to define
COGL_ENABLE_EXPERIMENTAL_API before including cogl.h if you want to use
the API.
This stubs out an xlib event handling mechanism for Cogl. The intention
is for Clutter to use this to forward all x11 events to Cogl. As we move
winsys functionality down into Cogl, Cogl will become responsible for
handling a number of X events: ConfigureNotify events for onscreen
framebuffers, swap events and Damage events for cogl_x11_texture_pixmap.
Previously it would only try to set the blend equation if the RGB and
alpha blending functions were different. However it's completely valid
to use a non-standard blending function when the functions are the
same. This patch moves the blending equation to outside the if
statement.
Previously it would only set the blend constant if glBlendFuncSeparate
was used but it is perfectly acceptable to use the blend constant when
the same factor is used for each. It now sets the blend constant
whenever one of the factors would use the constant.
When a single statement is used to specify the factors for both the
RGB and alpha parts it previously split up the statement into
two. This works but it ends up unnecessarily using glBlendFuncSeparate
when glBlendFunc would suffice.
For example, the blend statement
RGBA = ADD(SRC_COLOR*(SRC_COLOR), DST_COLOR*(1-SRC_COLOR))
would get split into the two statements
RGBA = ADD(SRC_COLOR*(SRC_COLOR[RGB]), DST_COLOR*(1-SRC_COLOR[RGB]))
A = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))
That translates to:
glBlendFuncSeparate (GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
This patch makes it so that arg_to_gl_blend_factor can handle the
combined RGBA mask instead. That way the single statement gets
translated to the equivalent call:
glBlendFunc (GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
Previously a path copy was implemented such that only the array of
path nodes was shared with the source and the rest of the data is
copied. This was so that the copy could avoid a deep copy if the
source path is appended to because the copy keeps track of its own
length. This optimisation is probably not worthwhile because it makes
the copies less cheap. Instead the CoglPath struct now just contains a
single pointer to a new CoglPathData struct which is separately
ref-counted. When the path is modified it will be copied if the ref
count on the data is not 1.
Since framebuffer state is not flushed prior to replaying the journal,
the trick of marking the framebuffer dirty prior to calling
glBindFramebuffer() doesn't work... the outstanding journal entries
will get replayed to the newly created framebuffer.
Fix this by flushing the journal as well.
http://bugzilla.openedhand.com/show_bug.cgi?id=2110
Signed-off-by: Robert Bragg <robert@linux.intel.com>
If the clip stack is empty then _cogl_clip_stack_flush exits
immediately. This was missing out the assignment of *stencil_used_p at
the bottom of the function. If a path is then used after the clip is
cleared then it would think it needs to merge with the clip so the
stencil would not be cleared correctly.
Instead of using cogl_get_bitmasks() to query the GL machinery for the
size of the color bits, we should store the values inside the
CoglFramebuffer object and query them the first time we set the framebuffer
as the current one.
Currently, cogl_get_bitmasks() is re-implemented in terms of
cogl_framebuffer_get_*_bits(). As soon as we are able to expose the
CoglOnscreen framebuffer object in the public API we'll be able to
deprecate cogl_get_bitmasks() altogether.
http://bugzilla.openedhand.com/show_bug.cgi?id=2094
In 91cde78a7 I accidentally changed the function names that get looked
up for the framebuffer extension under GLES so that they didn't have
any suffix. The spec for extension specifies that they should have the
OES suffix.
Debugging code is not meant to be run in the nominal code path. Use
G_UNLIKELY to be reduce the number of bubbles in the instruction
pipeline.
Took the opportunity to re-indent the macros.
When uploading texture data the cogl-texture-2d-sliced backend was
using _cogl_texture_prepare_for_upload to create a bitmap suitable for
upload but then it was using the original bitmap instead of the new
bitmap for the data. This was causing any format conversions performed
by cogl_texture_prepare_for_upload to be ignored.
http://bugzilla.openedhand.com/show_bug.cgi?id=2059
In commit abe91784c4 I changed cogl-texture so that it would use the
OpenGL mechanism to specify a different internal texture format from
the image format so that it can do the conversion instead of
Cogl. However under GLES the internal format and the image format must
always be the same and it only supports a limited set of formats. This
patch changes _cogl_texture_prepare_for_upload so that it does the
conversion using the cogl bitmap code when compiling for GLES.
http://bugzilla.openedhand.com/show_bug.cgi?id=2059
There was a check at the bottom of the loop which sets up the state
for each of the layers so that it would break from the loop when the
maximum number of layers is reached. However after doing this it would
not increment 'i'. 'i' is later used to disable the remaining layers
so it would end up disabling the last layer it just set up.
This patch moves the check to be part of the loop condition so that
the check is performed after incrementing 'i'.
http://bugzilla.openedhand.com/show_bug.cgi?id=2064
The warning displayed when too many layers are used had an off-by-one
error so that it would display even if exactly the maximum number is
used. There was also a missing space at the end of the line in the
message which looked wrong when displayed on the terminal.
http://bugzilla.openedhand.com/show_bug.cgi?id=2064
cogl_path_arc_rel was never in any public headers so it isn't part of
the public API. It also has a slightly inconsistent name because the
rest of the relative path functions are called cogl_path_rel_*. This
patch makes it static for now to make it more obvious that it isn't
public. The name has changed to _cogl_path_rel_arc.
If a path is copied and then appended to, the copy needs to have the
last sub path truncated so that it fits in the total path size in case
the original path was modified. However the path size check was broken
so if the copied path had more than one sub path it would fail.
Previously the clip stack code was trying to detect when the
orientation of the on-screen rectangle had changed by checking if the
order of the y-coordinates on the left edge was different from the
order the x-coordinates on the top edge. This doesn't work for some
rotations which was causing the clip planes to clip the wrong side of
the line. This patch makes it detect the orientation by calculating
the signed area which is a standard computer graphics algorithm.
http://bugzilla.openedhand.com/show_bug.cgi?id=2079
When drawing a path with only a single sub path, Cogl uses the
'even-odd' fill rule which means that if a part of the path intersects
with another part then the intersection would be inverted. However
when combining sub paths it treats them as separate paths and then
unions them together. This doesn't match the semantics of the even-odd
rule in SVG and Cairo. This patch makes it so that a new sub path is
just drawn as another triangle fan so that it will continue to invert
the stencil buffer. This is also much simpler and more efficient as
well as being more correct.
http://bugzilla.openedhand.com/show_bug.cgi?id=2088
Under GLES glReadPixels is documented to only support GL_RGBA with
GL_UNSIGNED_BYTE and an implementation specfic format which can be
fetched with glGet, GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES and
GL_IMPLEMENTATION_COLOR_READ_TYPE_OES. This patch makes it always read
using GL_RGBA and GL_UNSIGNED_BYTE and then convert the results if
neccessary.
This has some room for improvement because it doesn't attempt to use
the implementation specific format. Also the conversion is somewhat
wasteful because there are currently no cogl_bitmap_* functions to
convert without allocating a new buffer so it ends up doing an
intermediate copy.
http://bugzilla.openedhand.com/show_bug.cgi?id=2057
_cogl_bitmap_convert_format_and_premult was failing when converting
from RGBA to RGB and vice versa. _cogl_bitmap_fallback_convert
converts without altering the premult status so when choosing a new
format it would copy over the premult bit. However, it did this
regardless of whether the new format had an alpha channel so when
converting from RGBA_8888_PRE to RGB_888 it would end up inventing a
new meaningless format which would be RGB_888_PRE. This patch makes it
avoid copying the premult flag if the destination has no alpha. It
doesn't matter if it copies when the source format has no alpha
because it will always be unset.
_cogl_bitmap_convert_format_and_premult was also breaking when
converting from RGBA_8888_PRE to RGB_888 because it would think
RGB_888 is unpremultiplied and try to convert but then
_cogl_bitmap_fallback_premult wouldn't know how to do the conversion.
http://bugzilla.openedhand.com/show_bug.cgi?id=2057
This adds three new internal API functions which can be used to retain
the clip stack state and restore it later:
_cogl_get_clip_stack
_cogl_set_clip_stack
_cogl_clip_stack_copy
The functions are currently internal and not yet used but we may want
to make them public in future to replace the cogl_clip_stack_save()
and cogl_clip_stack_restore() APIs.
The get function just returns the handle to the clip stack at the top
of the stack of stacks and the set function just replaces it.
The copy function makes a cheap copy of an existing stack by taking a
reference to the top stack entry. This ends up working like a deep
copy because there is no way to modify entries of a stack but it
doesn't actually copy the data.
CoglClipStackState has now been renamed to CoglClipState and is moved
to a separate file. CoglClipStack now just maintains a stack and
doesn't worry about the rest of the state. CoglClipStack sill contains
the code to flush the stack to GL.
When glScissor is called it needs to pass coordinates in GL's
coordinate space where the origin is the bottom left. Previously this
conversion was done before storing the window rect in the clip
stack. However this might make it more difficult if we want to be able
to grab a handle to a clip stack and use it in different circumstances
later. This patch moves the coordinate conversion to inside the clip
state flushing code.
The stack is now stored as a list of reference counted entries.
Instead of using a GList, each entry now contains a link with a
reference to its parent. The idea is that this would allow copying
stacks with a shared ancestry.
Previously the code flushed the state by finding the bottom of the
stack and then applying each entry by walking back up to the top. This
is slightly harder to do now because the list is no longer
doubly-linked. However I don't think it matters which order the
entries are applied so I've just changed it to apply them in reverse
order.
There was also a restriction that if ever the stencil buffer is used
then we could no longer use clip planes for any subsequent entries. I
don't think this makes sense because it should always work as long as
it doesn't attempt to use the clip planes more than once. I've
therefore removed the restriction.
The CoglAtlasTexture struct was not being freed in
_cogl_atlas_texture_free so there would be a small leak whenever a
texture was destroyed.
Thanks to Robert Bragg for spotting this.
CoglMaterial now sets GL_CLAMP_TO_EDGE if WRAP_MODE_AUTOMATIC is used
unless it is overridden when the material is flushed. The primitives
are still expected to expose repeat semantics so no user visible
changes are made. The idea is that drawing non-repeated textures is
the most common case so if we make clamp_to_ege the default then we
will reduce the number of times we have to override the
material. Avoiding overrides will become important if the overriding
mechanism is replaced with one where the primitive is expected to copy
the material and change that instead.
Previously, Cogl's texture coordinate system was effectively always
GL_REPEAT so that if an application specifies coordinates outside the
range 0→1 it would get repeated copies of the texture. It would
however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates
are in the range 0→1 so that in the common case that the whole texture
is being drawn with linear filtering it will not blend in edge pixels
from the opposite sides.
This patch adds the option for applications to change the wrap mode
per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge'
and 'automatic'. The automatic map mode is the default and it
implements the previous behaviour. The wrap mode can be changed for
the s and t coordinates independently. I've tried to make the
internals support setting the r coordinate but as we don't support 3D
textures yet I haven't exposed any public API for it.
The texture backends still have a set_wrap_mode virtual but this value
is intended to be transitory and it will be changed whenever the
material is flushed (although the backends are expected to cache it so
that it won't use too many GL calls). In my understanding this value
was always meant to be transitory and all primitives were meant to set
the value before drawing. However there were comments suggesting that
this is not the expected behaviour. In particular the vertex buffer
drawing code never set a wrap mode so it would end up with whatever
the texture was previously used for. These issues are now fixed
because the material will always set the wrap modes.
There is code to manually implement clamp-to-edge for textures that
can't be hardware repeated. However this doesn't fully work because it
relies on being able to draw the stretched parts using quads with the
same values for tx1 and tx2. The texture iteration code doesn't
support this so it breaks. This is a separate bug and it isn't
trivially solved.
When flushing a material there are now extra options to set wrap mode
overrides. The overrides are an array of values for each layer that
specifies an override for the s, t or r coordinates. The primitives
use this to implement the automatic wrap mode. cogl_polygon also uses
it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced
textures. Although this code has been added it looks like the sliced
trick has been broken for a while and I haven't attempted to fix it
here.
I've added a constant to represent the maximum number of layers that a
material supports so that I can size the overrides array. I've set it
to 32 because as far as I can tell we have that limit imposed anyway
because the other flush options use a guint32 to store a flag about
each layer. The overrides array ends up adding 32 bytes to each flush
options struct which may be a concern.
http://bugzilla.openedhand.com/show_bug.cgi?id=2063
GL supports setting different wrap modes for the s, t and r
coordinates so we should design the backend interface to support that
also. The r coordinate is not currently used by any of the backends
but we might as well have it to make life easier if we ever add
support for 3D textures.
http://bugzilla.openedhand.com/show_bug.cgi?id=2063
CoglColor and CoglMatrix have public declarations with private members
so that we are free to change the implementation but the structures
could still be allocated on the stack in applications. However it's
quite easy not to realise the members are private and then access them
directly. This patch wraps the members in a macro which redefines the
symbol name when including the header outside of the clutter source.
http://bugzilla.openedhand.com/show_bug.cgi?id=2065
The xx, yx, zx etc fields are meant to be read-only but they were
marked as private with the gtk-doc annotation. This patch moves the
private marker so that the 16 float member fields are public but the
type, inverted matrix, flags and padding are not.
This adds three new API calls:
CoglHandle cogl_path_get()
void cogl_path_set(CoglHandle path)
CoglHandle cogl_path_copy(CoglHandle path)
All of the fields relating to the path have been moved from the Cogl
context to a new CoglPath handle type. The cogl context now just
contains a CoglPath handle. All of the existing path commands
manipulate the data in the current path handle. cogl_path_new now just
creates a new path handle and unrefs the old one.
The path handle can be stored for later with cogl_path_get. The path
can then be copied with cogl_path_copy. Internally it implements
copy-on-write semantics with an extra optimisation that it will only
copy the data if the new path is modified, but not if the original
path is modified. It can do this because the only way to modify a path
is by appending to it so the copied path is able to store its own path
length and only render the nodes up to that length. For this to work
the copied path also needs to keep its own copies of the path extents
because the parent path may change these by adding nodes.
The clip stack now uses the cogl_path_copy mechanism to store paths in
the stack instead of directly copying the data. This should save some
memory and processing time.
Although cogl_multiply_matrix was consistent with OpenGL, after further
consideration it was agreed that cogl_transform is a better name. Given
that it's in the global cogl_ namespace cogl_transform seems more self
documenting.
This adds an example of how to setup a Clutter style 2D coordinate space
and clarifies what state is owned by a framebuffer. (projection,
modelview, viewport and clip stack)
When we expose more cogl_framebuffer API this example will hopefully be
migrated into a more extensive introduction to using framebuffers.
Previously cogl_set_source and cogl_set_source_texture were in
cogl-material.c and the cogl_set_source_color* funcs were in
cogl-color.c. Originally this was because cogl.c was duplicated between
the GL and GLES backends and we didn't want to add to the amount of
duplicated code, but these files have since been consolidated into one
cogl.c.
Quite often it's desirable to be able to multiply the current modelview
matrix by an arbitrary matrix. Currently though you have to first
explicitly call cogl_get_modelview_matrix to get the current modelview
into a temporary variable, then you need to multiply it with your matrix
using cogl_matrix_multiply and finally use cogl_set_modelview_matrix to
make the result be the new modelview. This new convenience function lets
more efficiently skip the first get and last set steps.
Every now and then someone sees the cogl_enable API and gets confused,
thinking its public API so this renames the symbol to be clear that it's
is an internal only API.
When setting up the state for a layer, we need to switch texture
units before we do anything that might bind the texture, or
we'll bind the wrong texture to the previous unit.
http://bugzilla.openedhand.com/show_bug.cgi?id=2033
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
We need to set up the rowstride and alignment properly in
CoglTexture2D before reading texture data.
http://bugzilla.openedhand.com/show_bug.cgi?id=2036
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This makes it more likely consumers notice invalid unreferences.
GObject has the same assertion.
http://bugzilla.openedhand.com/show_bug.cgi?id=2029
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
When entering cogl_texture_2d_new_from_bitmap the internal format can
be COGL_PIXEL_FORMAT_ANY. This was causing _cogl_texture_2d_can_create
to use an invalid GL format type. Mesa apparently ignores this but it
was causing errors when Cogl is compiled with debugging under NVidia.
http://bugzilla.openedhand.com/show_bug.cgi?id=2026
Add a return result from CoglTexture.transform_quad_coords_to_gl(),
so that we can properly determine the nature of repeats in
the face of GL_TEXTURE_RECTANGLE_ARB, where the returned
coordinates are not normalized.
The comment "We also work out whether any of the texture
coordinates are outside the range [0.0,1.0]. We need to do
this after calling transform_coords_to_gl in case the texture
backend is munging the coordinates (such as in the sub texture
backend)." is disregarded and removed, since it's actually
the virtual coordinates that determine whether we repeat,
not the GL coordinates.
Warnings about disregarded layers are used in all cases where
applicable, including for subtextures.
http://bugzilla.openedhand.com/show_bug.cgi?id=2016
Signed-off-by: Neil Roberts <neil@linux.intel.com>
In _cogl_texture_2d_sliced_foreach_sub_texture_in_region(), don't
assert that the target is GL_TEXTURE_2D; instead conditionalize
normalization on the target.
http://bugzilla.openedhand.com/show_bug.cgi?id=2015
commit 511e5ceb51 accidentally removed the #ifdef COGL_ENABLE_DEBUG
guards around the "cogl-debug" and "cogl-no-debug" cogl_args[] which
this patch restores.
Just like _cogl_texture_2d_new_with_size(),
_cogl_texture_2d_new_from_bitmap() needs to check if an unsliced
texture can be created at the given size, or if hardware
limitations prevent this.
http://bugzilla.openedhand.com/show_bug.cgi?id=2014
Signed-off-by: Neil Roberts <neil@linux.intel.com>
cogl_read_pixels() no longer asserts that the format passed in is
RGBA_8888 but instead accepts any format. The appropriate GL enums for
the format are passed to glReadPixels so OpenGL should be perform a
conversion if neccessary.
It currently assumes glReadPixels will always give us premultiplied
data. This will usually be correct because the result of the default
blending operations for Cogl ends up with premultiplied data in the
framebuffer. However it is possible for the framebuffer to be in
whatever format depending on what CoglMaterial is used to render to
it. Eventually we may want to add a way for an application to inform
Cogl that the framebuffer is not premultiplied in case it is being
used for some special purpose.
If the requested format is not premultiplied then Cogl will convert
it. The tests have been changed to read the data as premultiplied so
that they won't be affected by the conversion. Picking in Clutter has
been changed to use COGL_PIXEL_FORMAT_RGB_888 because it doesn't need
the alpha component. clutter_stage_read_pixels is left unchanged
because the application can't specify a format for that so it seems to
make most sense to store unpremultiplied values.
http://bugzilla.openedhand.com/show_bug.cgi?id=1959
Since using addresses that might change is something that finally
the FSF acknowledge as a plausible scenario (after changing address
twice), the license blurb in the source files should use the URI
for getting the license in case the library did not come with it.
Not that URIs cannot possibly change, but at least it's easier to
set up a redirection at the same place.
As a side note: this commit closes the oldes bug in Clutter's bug
report tool.
http://bugzilla.openedhand.com/show_bug.cgi?id=521
This adds a COGL_INDICES_TYPE_UNSIGNED_INT enum value so that unsigned
ints can be used with cogl_vertex_buffer_indices_new. Unsigned ints
are not supported in core on GLES so a feature flag has also been
added to advertise this. GLES only sets the feature if the
GL_OES_element_index_uint extension is available. It is an error to
call indices_new() with unsigned ints unless the feature is
advertised.
http://bugzilla.openedhand.com/show_bug.cgi?id=1998
Previously the GLES2 backend needed a special wrapper for
glBindTexture because it needed to know the internal GL format of the
texture in order to correctly implement the GL_MODULATE texture env
mode. When GL_MODULATE is used then the RGB values are taken from the
previous texture layer rather than being fetched from the
texture. However since the material API was added Cogl no longer uses
the GL_MODULATE texture env mode but instead always uses GL_COMBINE.
Compiling the GLES2 backend broke since the more-texture-backends
branch merge because the cogl_get_internal_gl_format function was
removed and there was one place in GLES2 specific code that was using
this to bind the texture.
The texture layer combine functions are now hard coded to GL_COMBINE
instead of GL_MODULATE. The combine function can be customized with
all the parameters of GL_COMBINE. A shader is generated to implement
the given parameters.
Currently it will try to generate code for the constant color but it
will use a uniform which does not exist.
The GLES2 backend for Cogl is failing to compile because
GL_MAX_TEXTURE_UNITS is not defined. Let's define it and provide a
wrapper which uses GL_MAX_TEXTURE_IMAGE_UNITS or
COGL_GLES2_MAX_TEXTURE_UNITS, whichever is the smallest.
To aid in the debugging of Clutter stage resize issues this adds a
COGL_DEBUG=opengl option that will trace "some select OpenGL calls"
(currently just glViewport calls)
Most Cogl debugging code conditions are marked as G_UNLIKELY with the
intention of having the CPU branch prediction always assume the
path is disabled so having debugging support in release binaries has
negligible overhead.
This patch simply fixes a few cases where we weren't using G_UNLIKELY.
COGL_DEBUG=all wasn't previously useful as there are several options
that change the behaviour of Cogl and all together wouldn't help anyone
debug anything.
This patch makes it so COGL_DEBUG=all|verbose now only enables options
that don't change the behaviour of Cogl, i.e. they only affect the
amount of noise we'll print to a terminal.
In addition to that this patch also improves the output from
COGL_DEBUG=help so we now print a table of options including one liner
descriptions of what each option enables.
We now never query the width and height of the given texture object
from OpenGL. The problem is that the user may be creating a Cogl
texture from a texture_from_pixmap object where glTexImage2D was
never called and the texture_from_pixmap spec doesn't clarify that
it's reliable to query the width from OpenGL.
This should address:
http://bugzilla.openedhand.com/show_bug.cgi?id=1502
Thanks to Johan Bilien for reporting
The size and position of the window rectangle for clipping in
try_pushing_rect_as_window_rect is calculated by projecting the
rectangle coordinates. Due to rounding errors, this can end up with
slightly off numbers like 34.999999. These were then being cast
directly to an integer so it could end up off by one.
This uses a new macro called COGL_UTIL_NEARBYINT which is a
replacement for the C99 nearbyint function.
If FBOs aren't supported then it will end up very slow to reorganize
the atlas. Also currently the CoglTexture2D backend will refuse to
create any textures anyway so the full atlas texture won't be created.
cogl_texture_2d_new may fail in certain circumstances so
cogl_atlas_texture_reserve_space should detect this and also
fail. This will cause cogl_texture_new to fallback to a sliced
texture.
Thanks to Vladimir Ivakin for reporting this problem.
In the frenzy of the last 10mins before API freeze, I obviously forgot
to update the OpenGL path for _cogl_buffer_hints_to_gl_enum(). This
commit fixes this.
When the atlas is reorganised we could potentially be moving around
textures that are already referenced in the journal. We therefore need
to flush the journal otherwise they will be rendered with incorrect
texture coordinates. We also need to flush the journal even if we are
not reorganizing so that we can rely on the old texture contents
remaining in the atlas after migrating a texture out.
When creating a Cogl sub-texture, if the full texture is also a sub
texture it will now just offset the x and y and reference the full
texture instead. This avoids one level of indirection when rendering
the texture which reduces the chances of getting rounding errors in
the calculations.
The function _cogl_get_max_texture_units is called quite often while
rendering and it returns a constant value so we might as well cache
the result. Calling glGetInteger on Mesa can be expensive because it
flushes a lot of state.
An initial pass over the Cogl source code using the Clang static
analysis tool flagged a few low hanging issues such as un-used variables
or redundant initializing of variables which this patch fixes.
All the cogl_rectangle* APIs normalize their input into into an array of
_CoglMutiTexturedRect rectangles and pass these on to our work horse;
_cogl_rectangles_with_multitexture_coords. The definition of
_CoglMutiTexturedRect had 4 separate float members, x_1, y_1, x_2 and
y_2 which meant for some common cases we were having to copy out from an
array into these members. We are now able to simply point into the users
array avoiding a copy which seems desirable when submiting lots of
rectangles.
This uses the G_GNUC_DEPRECATED macros to mark the
cogl_{texture,vertex_buffer,shader}_ref and unref APIs as deprecated.
Since this flagged that cogl-pango-display-list.c and
clutter-glx-texture-pixmap.c were still using deprecated _ref/_unref
APIs they have now been changed to use the cogl_handle_ref/unref API
instead.
The function prototypes for the primitives API were spread between
cogl-path.h and cogl-texture.h and should have been in a
cogl-primitives.h.
As well as shuffling the prototypes around into more sensible places
this commit splits the cogl-path API out from cogl-primitives.c into
a cogl-path.c
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
OpenGL is an implementation detail for Cogl so it's not appropriate to
expose OpenGL extensions through the Cogl API.
Note: Clutter is currently still using this API, because it is still
doing raw GL calls in ClutterGLXTexturePixmap, so this introduces a
couple of (legitimate) build warnings while compiling Clutter.
The signbit macro is defined in C99 so it should be available but some
versions of GCC don't appear to define it by default. If it's not
available we can use a hack to test the bit directly.
A material layer can not be considered equal if it is using different
texture filtering modes. This was causing problems where rectangles
with different filters would end up batched together and then rendered
with the wrong filter mode.
The function modifies the pixels pointed by p in-place so the pointer
can not be constant. The compiler was accepting this because the
modification is done from inline assembler.
_cogl_texture_driver_gen is needed to set the texture minification
mode to Cogl's default of GL_LINEAR. There was also a line to set this
in _cogl_texture_2d_new_with_size but it wasn't working because it was
called *before* the texture was bound. If the texture was later
rendered with the default material it then it would end up with GL's
default mipmap filtering mode but without mipmaps so it would render
white squares instead.
This adds a fast path for premultiplying an RGBA image using SSE2
instructions. SSE registers are 128-bit and we need at least 16-bits
per component for the intermediate result of the multiplication so we
can do two pixels in parallel with one register. The function
interleaves 2 SSE registers to multiply 4 pixels in one function call
with the hope that this will pipeline better.
http://bugzilla.openedhand.com/show_bug.cgi?id=1939
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
OpenGL ES has no PBO extension, so we fallback to using a malloc'ed
buffer. Make sure the OpenGL-only defines don't leak into the OpenGL ES
compilation.
First, let's add a new public feature called, surprisingly,
COGL_FEATURE_PBOS to check the availability of PBOs and provide a
fallback path when running on older GL implementations or on OpenGL ES
In case the underlying OpenGL implementation does not provide PBOs, we
need a fallback path (a malloc'ed buffer). The CoglPixelBufer
constructors will instanciate a subclass of CoglBuffer that handles
map/unmap and set_data() with a malloc'ed buffer.
The public feature is useful to check before using set_data() on a
buffer as it will mean doing a memcpy() when not supporting PBOs (in
that case, it's better to create the texture directly instead of using a
CoglBuffer).
The only goal of using COGL buffers is to use them to create
textures. cogl_texture_new_from_buffer() is the new symbol to create
textures out of buffers.
This subclass of CoglBuffer aims at wrapping PBOs or other system
surfaces like DRM buffer objects. Two constructors are available:
cogl_pixel_buffer_new() with a size when you only care about the size of
the buffer (such a buffer can be used to store several texture data such
as the three planes of a I420 frame).
cogl_pixel_buffer_new_full() is more a 1:1 mapping between the data and
an underlying surface, with the possibility of having access to a low
level memory buffer that may have a stride.
Buffer objects are cool! This abstracts the buffer API first introduced
by GL_ARB_vertex_buffer_object and then extended to other objects.
The coglBuffer abstract class is intended to be the base class of all
the buffer objects, letting the user map() buffers. If the underlying
implementation does not support buffer objects (or only support VBO but
not FBO for instance), fallback paths should be provided.
The only way the user has to set the mipmap filters is through the
material/layer API. This API defaults to GL_LINEAR/GL_LINEAR for the max
and min filters. With the main use case of cogl being 2D interfaces, it
makes sense do default to GL_LINEAR for the min filter.
When creating new textures, we did not set any filter on them, using
OpenGL defaults': GL_NEAREST_MIPMAP_LINEAR for the min filter and
GL_LINEAR for the max filter. This will make the driver allocate memory
for the mipmap tree, memory that will not be used in the nominal case
(as the material API defaults to GL_LINEAR).
This patch tries to ensure that the min filter is set to GL_LINEAR
before any glTexImage*() call is done on the texture by setting the
filter when generating new OpenGL handles.
Some GL functions have a return value that the GE() macro is not able to
handle. Let's define a new Ge_RET() macro which will be able to handle
functions such as glMapBuffer().
While at it, removed the unused variadic dots to the GE() macro.
When we trashed the contents of the stencil buffer during
_cogl_path_fill_nodes we marked the clip stack state as dirty and expected
the clip stack code would clean up our glStencilFunc state.
The problem is that we only try and update the clip state during
_cogl_journal_init (when we flush the framebuffer state) which is only
called when the journal first gets something logged in it.
To make sure the stencil state is cleaned up we now also flush the journal
so _cogl_journal_init will be called for the next logged rectangle.
This adds three new texture backends.
- CoglTexture2D: This is a trimmed down version of CoglTexture2DSliced
which only supports a single texture and only works with the
GL_TEXTURE_2D target. The code is a lot simpler so it has a less
overheads than dealing with slices. Cogl will use this wherever
possible.
- CoglSubTexture: This is used to get a CoglHandle to represent a
subregion of another texture. The texture can be used as if it was a
standalone texture but it does not need to copy the resources.
- CoglAtlasTexture: This collects RGB and RGBA textures into a single
GL texture with the aim of reducing texture state changes and
increasing batching. The backend will try to manage the atlas and
may move the textures around to close gaps in the texture. By
default all textures will be placed in the atlas.
There was a typo in getting the height of the full texture to check
whether the sub region fits so that it was using the width
instead. This was causing crashes when debugging is enabled for some
apps.
In cogl_texture_new_from_file we create and own a temporary
bitmap. There's no need to copy this data if we need to do a premult
conversion so instead it just does conversion before passing it on to
cogl_texture_new_from_bitmap.
The Cogl atlas code was using _cogl_texture_prepare_for_upload with a
NULL pointer for the dst_bmp to determine the internal format of the
texture without converting the bitmap. It needs to do this to decide
whether the texture will go in the atlas before wasting time on the
conversion. This use of the function is a little confusing so that
part of it has been split out into a new function called
_cogl_texture_determine_internal_format. The code to decide whether a
premult conversion is needed has also been split out.
Commit 92a375ab4 changed the initial value of max_texcoord_attrib_unit
to -1 so that it could disable the texture coord array for the first
texture unit when there are no texture coords used in the vbo. However
max_texcoord_attrib_unit was an unsigned value so this actually became
G_MAXUINT. The disabling loop at the bottom still worked because
G_MAXUINT+1==0 but the check for whether any texture unit is greater
than max_texcoord_attrib_unit was failing so it would always end up
disabling all texture units. This is now fixed by changing
max_texcoord_attrib_unit to be signed.
When deciding if a material layer is equal it now compares the GL
target and texture number if the textures are not sliced. This is
needed to get batching across atlased textures.
Cogl accepts a pixel format for both the data in memory and the
internal format to be used for the texture. If they do not match then
it would convert them using the CoglBitmap functions before uploading
the data. However, GL also lets you specify both formats so it makes
more sense to let GL do the conversion. The driver may need the
texture in a specific format so it may end up being converted anyway.
The cogl_texture_upload_data functions have been removed and replaced
with a single function to prepare the bitmap. This will only do the
premultiplication conversion because that is the only part that GL
can't do directly.
The premult part of _cogl_convert_premult has now been split out as
_cogl_convert_premult_status. _cogl_convert_premult has been renamed
to _cogl_convert_format to make it less confusing. The premult
conversion is now done in-place instead of copying the
buffer. Previously it was copying the buffer once for the format
conversion and then copying it again for the premult conversion. The
premult conversion never changes the size of the buffer so it's quite
easy to do in place. We can also use the separated out function
independently.
The internal format of the atlas texture is still set to the
appropriate format so Cogl will disable blending for textures that are
intended to be RGB. This should end up ignoring the alpha channel from
the texture in the atlas. This makes the code slightly easier to
maintain and should also improve the chances of batching.
Instead of assigning a new colour to each quad of a batch, the
rectangle debugging code now assigns a new colour to each batch so
that it can be used to visually see what is being batched. The colour
is stored in a global variable that is reset during cogl_clear. This
improves the chances that the same colour will be used for a batch in
the next frames to avoid flickering.
When setting up the state for the vertex buffer,
enable_state_for_drawing_buffer tries to keep track of the highest
numbered texture unit in use. It then disables any texture arrays for
units that were previously enabled if they are greater than that
number. However if there is no texturing in the VBO then the max used
unit would be left at 0 which it would later think meant unit 0 is
still in use so it wouldn't disable it. To fix this it now initialises
the max used unit to -1 which it should interpret as ‘no units are in
use’ so it will later disable the arrays for all units.
Thanks to Jon Mayo for reporting the bug.
http://bugzilla.openedhand.com/show_bug.cgi?id=1957
We were checking the number of texture units against the GL enum that is
used in glGetInteger() to query that number. Let's abstract this in a
little function.
Took the opportunity to dig a bit on the usage of GL limits for the
number of texture (image) units and document our use of them. We'll need
something finer grained if we want to fully exploit texture image units
with a programmable pipeline.
The index field of CoglTextureUnit was never set, leading to the
creation of units with index set to 0. When trying to retrieve a texture
unit by its index (!= 0) with _cogl_get_texture_unit(), a new one was
created as it could not find it back in the list of textures units:
ctx->texture_units.
http://bugzilla.openedhand.com/show_bug.cgi?id=1958
Previously the atlas textures were being created with whatever format
the first sub texture is in. Only three formats are supported so this
only matters if the first texture is a premultiplied alpha
texture. Instead it now masks out the premultiplied bit so that the
textures are always either RGB_888 or RGBA_8888.
When uploading texture data it was just calling cogl_texture_set_data
on the large texture. This would attempt to convert the data to the
format of the large texture. All of the textures with alpha channels
are stored together regardless of whether they are premultiplied so
this was causing premultiplied textures to be unpremultiplied
again. It now just uploads the data ignoring the premult bit of the
format so that it only gets converted once.
With the atlas texture backend ensuring the mipmaps can make it become
a completely different texture which will have different texture
coordinates or may even be sliced. Therefore we need to ensure the
mipmaps before deciding which quads to log in the journal. This adds a
new private function to cogl-material which ensures the mipmaps if
needed.
The sub texture backend doesn't work well as a completely general
texture backend because for example when rendering with cogl_polygon
it needs to be able to tranform arbitrary texture coordinates without
reference to the other coordintes. This can't be done when the texture
coordinates are a multiple of one because sometimes the coordinate
should represent the left or top edge and sometimes it should
represent the bottom or top edge. For example if the s coordinates are
0 and 1 then 1 represents the right edge but if they are 1 and 2 then
1 represents the left edge.
Instead the sub-textures are now documented not to support coordinates
outside the range [0,1]. The coordinates for the sub-region are now
represented as integers as this helps avoid rounding issues. The
region can no longer be a super-region of the texture as this
simplifies the code quite a lot.
There are two new texture virtual functions:
transform_quad_coords_to_gl - This transforms two pairs of coordinates
representing a quad. It will return FALSE if the coordinates can
not be transformed. The sub texture backend uses this to detect
coordinates that require repeating which causes cogl-primitives
to use manual repeating.
ensure_non_quad_rendering - This is used in cogl_polygon and
cogl_vertex_buffer to inform the texture backend that
transform_quad_to_gl is going to be used. The atlas backend
migrates the texture out of the atlas when it hits this.
When calculating the next integer position for negative coordinates it
would not increment if the position is already a multiple of one so we
need to manually add one.
When try_creating_fbo fails it returns 0 to report the error and if it
succeeds it returns ‘flags’. However cogl_offscreen_new_to_texture
also passes in 0 for the flags as the last fallback to create the fbo
with nothing but the color buffer. In that case it will return 0
regardless of whether it succeeded so the last fallback will always be
considered a failure.
To fix this it now just returns a gboolean to indicate whether it
succeeded and the flags used for each attempt is assigned when passing
the argument rather than from the return value of the function.
Also if the only configuration that succeeded was with flags==0 then
it would always try all combinations because last_working_flags would
also be zero. To avoid this it now uses a separate gboolean to mark
whether we found a successful set of flags.
http://bugzilla.openedhand.com/show_bug.cgi?id=1873
Since 755cce33a7 the framebuffer code is using the GL enums
GL_DEPTH_ATTACHMENT and GL_DEPTH_COMPONENT16. These aren't available
directly under GLES except with the OES suffix so we need to define
them manually as we do with the other framebuffer constants.
These macros used to define Cogl wrappers for the GLenum values. There are
now Cogl enums everywhere in the API where these were required so we
shouldn't need them anymore. They were in the public headers but as
they are not neccessary and were not in the API docs for Clutter 1.0
it should be safe to remove them.
If a user supplied multiple groups of texture coordinates with
cogl_rectangle_with_multitexture_coords() then we would repeatedly log only
the first group in the journal. This fixes that bug and adds a conformance
test to verify the fix.
Thanks to Gord Allott for reporting this bug.
The Intel drivers in Mesa 7.6 (and possibly earlier versions) don't
support creating FBOs with a stencil buffer but without a depth
buffer. This reworks framebuffer allocation so that we try a number
of fallback options before failing.
The options we try in order are:
- the same options that were sucessful last time if available
- combined depth and stencil
- separate depth and stencil
- just stencil, no depth
- just depth, no stencil
- neither depth or stencil
We weren't taking a reference on the texture to be used as the color buffer
for offscreen rendering, so it was possible to free the texture leaving the
framebuffer in an inconsistent state.
This adds gives Cogl a dedicated UProf context which will be linked together
with Clutter's context during clutter_init_real().
Initial timers cover _cogl_journal_flush and _cogl_journal_log_quad
You can explicitly ask for a report of Cogl statistics by exporting
COGL_PROFILE_OUTPUT_REPORT=1 but since the context is linked with Clutter's
the statisitcs will also be shown in the automatic Clutter reports.
* stage-use-alpha:
tests: Use accessor methods for :use-alpha
stage: Add accessors for :use-alpha
tests: Allow setting the stage opacity in test-paint-wrapper
stage: Premultiply the stage color
stage: Composite the opacity with the alpha channel
glx: Always request an ARGB visual
stage: Add :use-alpha property
materials: Get the right blend function for alpha
When the texture is in the atlas, ensuring the mipmaps can effectively
make it become a completely different texture so we should do this
before getting the GL handle.
Mipmaps don't work very well in the current atlas because there is not
enough padding between the textures. If ensure_mipmaps is called it
will now create a new texture and migrate the atlased texture to
it. It will use the same blit mechanism as when migrating so it will
try to use an FBO for a fast blit. However if this is not possible it
will end up downloading the data for the entire atlas which is not
ideal.
When reorganizing the textures, we can avoid downloading the entire
texture data if we bind the source texture in a framebuffer object and
copy the destination using glCopyTexSubImage2D. This is also
implemented using a much faster path in Mesa.
Currently it is calling the GL framebuffer API directly but ideally it
would use the Cogl offscreen API. However there is no way to tell Cogl
not to create a stencil renderbuffer which seems like a waste in this
situation.
If FBOs are not available it will fallback to reading back the entire
texture data as before.
This adds a 'dump-atlas-image' debug category. When enabled, CoglAtlas
will use Cairo to create a png which visualizes the leaf rectangles of
the atlas.
This adds an 'atlas' category to the COGL_DEBUG environment
variable. When enabled Cogl will display messages when textures are
added to the atlas and when the atlas is reorganized.
When space can't be found in the atlas for a new texture it will now
try to reorganize the atlas to make space. A new CoglAtlas is created
and all of the textures are readded in decreasing size order. If the
textures still don't fit then the size of the atlas is doubled until
either we find a space or we reach the texture size limits. If we
successfully find an organization that fits then all of the textures
will be migrated to a new texture. This involves copying the texture
data into CPU memory and then uploading it again. Potentially it could
eventually use a PBO or an FBO to transfer the image without going
through the CPU.
The algorithm for laying out the textures works a lot better if the
rectangles are added in order so we might eventually want some API for
creating multiple textures in one go to avoid reorganizing the atlas
as far as possible.
This adds a CoglAtlas type which is a data structure that keeps track
of unused sub rectangles of a larger rectangle. There is a new atlased
texture backend which uses this to put multiple textures into a single
larger texture.
Currently the atlas is always sized 256x256 and the textures are never
moved once they are put in. Eventually it needs to be able to
reorganise the atlas and grow it if necessary. It also needs to
migrate the textures out of the atlas if mipmaps are required.
This is an optimised version of CoglTexture2DSliced that always deals
with a single texture and always uses the GL_TEXTURE_2D
target. cogl_texture_new_from_bitmap now tries to use this backend
first. If it can't create a texture with that size then it falls back
the sliced backend.
cogl_texture_upload_data_prepare has been split into two functions
because the sliced backend needs to know the real internal format
before the conversion is performed. Otherwise the converted bitmap
will be wasted if the backend can't support the size.
This provides a way to upload the entire data for a texture without
having to first call glTexImage and then glTexSubImage. This should be
faster especially with indirect rendering where it would needlessy
send the data for the texture twice.
new_from_data and new_from_file can be implemented in terms of
new_from_bitmap so it makes sense to move these to cogl-texture rather
than having to implement them in every texture backend.
This adds a new texture backend which represents a sub texture of a
larger texture. The texture is created with a reference to the full
texture and a set of coordinates describing the region. The backend
simply defers to the full texture for all operations and maps the
coordinates to the other range. You can also use coordinates outside
the range [0,1] to create a repeated version of the full texture.
A new public API function called cogl_texture_new_from_sub_texture is
available to create the sub texture.
The CoglTextureSliceCallback function pointer now takes const pointers
for the texture coordinates. This makes it clearer that the callback
should not modify the array and therefore the backend can use the same
array for both sets of coords.
Given a region of texture coordinates this utility invokes a callback
enough times to cover the region with a subregion that spans the
texture at most once. Eg, if called with tx1 and tx2 as 0.5 and 3.0 it
it would invoke the callback with:
0.5,1.0 1.0,2.0 2.0,3.0
Manual repeating is needed by all texture backends regardless of
whether they can support hardware repeating because when Cogl calls
the foreach_sub_texture_in_region method then it sets the wrap mode to
GL_CLAMP_TO_EDGE and no hardware repeating is possible.
In _cogl_multitexture_quad_single_primitive we use a wrap mode of
GL_CLAMP_TO_EDGE if the texture coordinates are all in the range [0,1]
or GL_REPEAT otherwise. This is to avoid pulling in pixels from either
side when using GL_LINEAR filter mode and rendering the entire
texture. Previously it was checking using the unconverted texture
coordinates. This is ok unless the texture backend is radically
transforming the texture coordinates, such as in the sub texture
backend where the coordinates may map to something completely
different. We now check whether the coordinates are in range after
converting them.
Most of the fields that were previously in CoglTexture are specific to
the implementation of CoglTexture2DSliced so they should be placed
there instead. For example, the 'mipmaps_dirty' flag is an
implementation detail of the ensure_mipmaps function so it doesn't
make sense to force all texture backends to have this function.
Other fields such as width, height, gl_format and format may make
sense for all textures but I've added them as virtual functions
instead. This may make more sense for a sub-texture backend for
example where it can calculate these based on the full texture.
The CoglTexture struct previously contained some fields which are only
used to upload data such as the CoglBitmap and the source GL
format. These are now moved to a separate CoglTextureUploadData struct
which only exists for the duration of one of the cogl_texture_*_new
functions. In cogl-texture there are utility functions which operate
on this new struct rather than on CoglTexture directly.
Some of the fields that were previously stored in the CoglBitmap
struct are now copied to the CoglTexture such as the width, height,
format and internal GL format.
The rowstride was previously stored in CoglTexture and this was
publicly accessible with the cogl_texture_get_rowstride
function. However this doesn't seem to be a useful function because
there is no need to use the same rowstride again when uploading or
downloading new data. Instead cogl_texture_get_rowstride now just
calculates a suitable rowstride from the format and width of the
texture.
Commit 558b17ee1e added support for rectangle textures to the
framebuffer code. Under GLES there is no GL_TEXTURE_RECTANGLE_ARB
definition so this was breaking the build. The rest of Cogl uses
ifdef's around that constant so we should do the same here.
The correct blend function for the alpha channel is:
GL_ONE, GL_ONE_MINUS_SRC_ALPHA
As per bug 1406. This fix was dropped when the switch to premultiplied
alpha was merged.
We currently enable blending if the material colour has
transparency. This patch makes it also enable blending if any of the
lighting colours have transparency. Arguably this isn't neccessary
because we don't expose any API to enable lighting so there is no
bug. However it is currently possible to enable lighting with a direct
call to glEnable and this otherwise works so it is a shame not to have
it.
http://bugzilla.openedhand.com/show_bug.cgi?id=1907
cogl_push_draw_buffer, cogl_set_draw_buffer and cogl_pop_draw_buffer are now
deprecated and new code should use the new cogl_framebuffer_* API instead.
Code that previously did:
cogl_push_draw_buffer ();
cogl_set_draw_buffer (COGL_OFFSCREEN_BUFFER, buffer);
/* draw */
cogl_pop_draw_buffer ();
should now be re-written as:
cogl_push_framebuffer (buffer);
/* draw */
cogl_pop_framebuffer ();
As can be seen from the example above the rename has been used as an
opportunity to remove the redundant target argument from
cogl_set_draw_buffer; it now only takes one call to redirect to an offscreen
buffer, and finally the term framebuffer may be a bit more familiar to
anyone coming from an OpenGL background.
Instead of storing an enum with the backend type for each texture and
then using a switch statement to decide which function to call, we
should store pointers to all of the functions in a struct and have
each texture point to that struct. This is potentially slightly faster
when there are more backends and it makes implementing new backends
easier because it's more obvious which functions have to be
implemented.
cogl_offscreen_new_to_texture previously bailed out if the given texture's
GL target was anything but GL_TEXTURE_2D, but it now also allows
foreign GL_TEXTURE_RECTANGLE_ARB textures.
Thanks to Owen for reporting this issue, ref:
https://bugzilla.gnome.org/show_bug.cgi?id=601032
cogl_material_copy can be used to create a new CoglHandle referencing a copy
of some given material.
From now on we will advise that developers always aim to use this function
instead of cogl_material_new() when creating a material that is in any way
derived from another.
By using cogl_material_copy, Cogl can maintain an ancestry for each material
and keep track of "similar" materials. The plan is that Cogl will use this
information to minimize the cost of GPU state transitions.
This function was #if 0'd before we released Clutter 1.0 so there's no
implementation of it. At some point we thought it might assist with
developers breaking out into raw OpenGL. Breaking out to raw GL is a
difficult problem though so we decided instead we will wait for a specific
use case to arrise before trying to support it.
_cogl_material_get_layer expects a CoglMaterial* pointer but it was
being called with a CoglHandle. This doesn't matter because the
CoglHandle is actually just the CoglMaterial* pointer anyway but it
breaks the ability to change the _cogl_material_pointer_from_handle
macro.
• Use the same style for the Cogl API reference as the one used for
the Clutter API reference.
• Fix the introspection annotations for cogl_bitmap_get_size_from_file()
The imported Mesa matrix code has some documentation annotations
that make gtk-doc very angry. Since it's all private anyway we
can safely make gtk-doc ignore the offending stuff.
$(COGL_DRIVER)/cogl-defines.h is generated in the configure script so
it ends up in the build directory. Therefore the build rule for
cogl/cogl-defines.h should depend on the file in $(builddir) not
$(srcdir).
The deprecation notices in gtk-doc should also refer to the
release that added the deprecation, and if the deprecated
symbol has been replaced by something else then the new symbol
should be correctly referenced.
The main COGL header cogl.h is currently created at configure time
because it conditionally includes the driver-dependent defines. This
sometimes leads to a stale cogl.h with old definitions which can
break the build until you clean out the whole tree and start from
scratch.
We can generate a stable cogl-defines.h at build time from the
equivalent driver-dependent header and let cogl.h include that
file instead.
_cogl_feature_check expects the array of function names to be
terminated with a NULL pointer but I forgot to add this. This was
causing crashes depending on what happened to be in memory after the
array.
For VBOs, we don't need to check for the extension if the GL version
is greater than 1.5. Non-power-of-two textures are given in 2.0.
We could also assume shader support in GL 2.0 except that the function
names are different from those in the extension so it wouldn't work
well with the current mechanism.
Previously if you need to depend on a new GL feature you had to:
- Add typedefs for all of the functions in cogl-defines.h.in
- Add function pointers for each of the functions in
cogl-context-driver.h
- Add an initializer for the function pointers in
cogl-context-driver.c
- Add a check for the extension and all of the functions in
cogl_features_init. If the extension is available under multiple
names then you have to duplicate the checks.
This is quite tedious and error prone. This patch moves all of the
features and their functions into a list of macro invocations in
cogl-feature-functions.h. The macros can be redefined to implement all
of the above tasks from the same header.
The features are described in a struct with a pointer to a table of
functions. A new function takes the feature description from this
struct and checks for its availability. The feature can take a list of
extension names with a list of alternate namespaces (such as "EXT" or
"ARB"). It can also detect the feature from a particular version of
GL.
The typedefs are now gone and instead the function pointer in the Cogl
context just directly contains the type.
Some of the functions in the context were previously declared with the
'ARB' extension. This has been removed so that now all the functions
have no suffix. This makes more sense when the extension could
potentially be merged into GL core as well.
There is a new internal Cogl function called _cogl_check_driver_valid
which looks at the value of the GL_VERSION string to determine whether
the driver is supported. Clutter now calls this after the stage is
realized. If it fails then the stage is marked as unrealized and a
warning is shown.
_cogl_features_init now also checks the version number before getting
the function pointers for glBlendFuncSeparate and
glBlendEquationSeparate. It is not safe to just check for the presence
of the functions because some drivers may define the function without
fully implementing the spec.
The GLES version of _cogl_check_driver_valid just always returns TRUE
because there are no version requirements yet.
Eventually the function could also check for mandatory extensions if
there were any.
http://bugzilla.openedhand.com/show_bug.cgi?id=1875
When _cogl_add_path_to_stencil_buffer is used to draw a path we don't
need to clear the entire stencil buffer. Instead it can clear just the
bounding box of the path. This adds an extra parameter called
'need_clear' which is only set if the stencil buffer is being used for
clipping.
http://bugzilla.openedhand.com/show_bug.cgi?id=1829
This fixes a warning about an uninitialised value. It could also
potentially fix some crashes for example if the enable_flags value
happened to include a bit for enabling a vertex array if no vertex
buffer pointer was set.
While loading a JPEG from disk (with clutter_texture_new_from_file),
I got the following:
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8
integer bits/component; 24 bits/pixel; 3-component colorspace;
kCGImageAlphaNone; 3072 bytes/row.
<Error>: CGContextDrawImage: invalid context
Looking around, I found that CGBitmapContextCreate can't make 24bpp
offscreen pixmaps without an alpha channel...
This fixes the bug, and seems to not break other things...
http://bugzilla.openedhand.com/show_bug.cgi?id=1159
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
cogl_clip_push() which accepts a rectangle in model space shouldn't have
been defined to take x,y,width,height arguments because this isn't consistant
with other Cogl API dealing with model space rectangles. If you are using a
coordinate system with the origin at the center and the y+ extending up,
then x,y,width,height isn't as natural as (x0,y0)(x1,y1). This API has
now been replace with cogl_clip_push_rectangle()
(As a general note: the Cogl API should only use the x,y,width,height style
when the appropriate coordinate space is defined by Cogl to have a top left
origin. E.g. window coordinates, or potentially texture coordinates)
cogl_clip_push_window_rect() shouldn't have been defined to take float
arguments since we only clip with integral pixel precision. We also
shouldn't have abbreviated "rectangle". This API has been replaced with
cogl_clip_push_window_rectangle()
cogl_clip_ensure() wasn't documented at all in Clutter 1.0 and probably
no one even knew it existed. This API isn't useful, and so it's now
deprecated. If no one complains we may remove the API altogether for
Clutter 1.2.
cogl_clip_stack_save() and cogl_clip_stack_restore() were originally added
to allow us to save/restore the clip when switching to/from offscreen
rendering. Now that offscreen draw buffers are defined to own their clip
state and the state will be automatically saved and restored this API is now
redundant and so deprecated.
For a long time now the GLES driver for Cogl has supported a fallback
scanline rasterizer for filling paths when no stencil buffer is available,
but now that we build the same cogl-primitives code for GL and GLES I
thought it may sometimes be useful for debugging to force Cogl to use the
scanline rasterizer instead of the current stencil buffer approach.
These files were practically identical, except the gles code had additional
support for filling paths without a stencil buffer. All the driver code has
now been moved into cogl/cogl-primitives.c
It's useful when initialzing offscreen draw buffers to be able to ask
Cogl to create a texture of a given size and with the default internal
pixel format.
Before we call glViewport we need to convert Cogl viewport coordinates
(where the origin is defined to be top left) to OpenGL coordinates
(where the origin is defined to be bottom left)
We weren't considering that offscreen rendering is always upside down
and in this case Cogl coordinates == OpenGL coordinates.
Firstly this now uses the draw buffer height not the viewport height
when we need to perform a y = height - y conversion, since (as the
name suggests) we are dealing with window coordinates not viewport
coordinates.
Secondly this skips any conversion when the current draw buffer is an
offscreen draw buffer since offscreen rendering is always forced to be
upside down and in this case Cogl window coordinates == GL window
coordinates.
This new API takes advantage of the recently imported Mesa code to support
inverse matrix calculation. The matrix code keeps track (via internal
flags) of the transformations a matrix represents so that it can select an
optimized inversion function.
Note: although other aspects of the Cogl matrix API have followed a similar
style to Cairo's matrix API we haven't added a cogl_matrix_invert API
because the inverse of a CoglMatrix is actually cached as part of the
CoglMatrix structure meaning a destructive API like cogl_matrix_invert
doesn't let users take advantage of this caching design.
This adds a COGL_DEBUG=matrices debug option that can be used to trace all
matrix manipulation done using the Cogl API. This can be handy when you
break something in such a way that a trace is still comparable with a
previous working version since you can simply diff a log of the broken
version vs the working version to home in on the bug.
This pulls in code from Mesa to improve our matrix manipulation support. It
includes support for calculating the inverse of matrices based on top of a
matrix categorizing system that allows optimizing certain matrix types.
(the main thing we were after) but also adds some optimisations for
rotations.
Changes compared to the original code from Mesa:
- Coding style is consistent with the rest of Cogl
- Instead of allocating matrix->m and matrix->inv using malloc, our public
CoglMatrix typedef is large enough to directly contain the matrix, its
inverse, a type and a set of flags.
- Instead of having a _math_matrix_analyse which updates the type, flags and
inverse, we have _math_matrix_update_inverse which essentially does the
same thing (internally making use of _math_matrix_update_type_and_flags())
but with additional guards in place to bail out when the inverse matrix is
still valid.
- When initializing a matrix with the identity matrix we don't immediately
initialize the inverse matrix; rather we just set the dirty flag for the
inverse (since it's likely the user won't request the inverse of the
identity matrix)
Because Cogl defines the origin for texture as top left and offscreen draw
buffers can be used to render to textures, we (internally) force all
offscreen rendering to be upside down. (because OpenGL defines the origin
to be bottom left)
By forcing the users scene to be rendered upside down though we also reverse
the winding order of all the drawn triangles which may interfere with the
users use of backface culling. This patch ensures that we reverse the
winding order for a front face (if culling is in use) while rendering
offscreen so we don't conflict with the users back face culling.
Technically this change shouldn't make a difference since we are
calling glReadPixels with GL_RGBA GL_UNSIGNED_BYTE which is a 4
byte format and it should always result in the same value according
to how OpenGL calculates the location of sequential rows.
i.e. k = a/s * ceil(snl/a) where:
a = alignment
s = component size (1)
n = number of components per pixel (4)
l = number of pixels in a row
gives:
k = 4/1 * ceil(4l/4) and k = 1/1 * ceil(4l/1) which are equivalent
I'm changing it because I've seen i915 driver code that bails out of
hardware accelerated paths if the alignment isn't 1, and because
conceptually we have no alignment constraints here so even if the current
value has no effect, when we start reading back other formats it may upset
things.
We were previously calling cogl_flush() after setting up the glPixelStore
state for calling glReadPixels, but flushing the journal could itself
change the glPixelStore state.
Since offscreen rendering is forced to be upside down we don't need to do
any conversion of the users coordinates to go from Cogl window coordinates
to OpenGL window coordinates.
Since we do all offscreen rendering upside down (so that we can have the
origin for texture coordinates be the top left of textures for the cases
where offscreen draw buffers are bound to textures) we don't need to flip
data read back from an offscreen framebuffer before we we return it to the
user.
I was originally expecting the code not to handle offset viewports or
viewports with a different size to the framebuffer, but it turns out the
code worked fine. In the process though I think I made the code slightly
more readable.
cogl_viewport only accepted a viewport width and height, but there are times
when it's also desireable to have a viewport offset so that a scene can be
translated after projection but before hitting the framebuffer.
Because Cogl defines the origin of viewport and window coordinates to be
top-left it always needs to know the size of the current window so that Cogl
window/viewport coordinates can be transformed into OpenGL coordinates.
This also fixes cogl_read_pixels to use the current draw buffer height
instead of the viewport height to determine the OpenGL y coordinate to use
for glReadPixels.
First a few notes about Cogl coordinate systems:
- Cogl defines the window origin, viewport origin and texture coordinates
origin to be top left unlike OpenGL which defines them as bottom left.
- Cogl defines the modelview and projection identity matrices in exactly the
same way as OpenGL.
- I.e. we believe that for 2D centric constructs: windows/framebuffers,
viewports and textures developers are more used to dealing with a top left
origin, but when modeling objects in 3D; an origin at the center with y
going up is quite natural.
The way Cogl handles textures is by uploading data upside down in OpenGL
terms so that bottom left becomes top left. (Note: This also has the
benefit that we don't need to flip the data we get from image decoding
libraries since they typically also consider top left to be the image
origin.)
The viewport and window coords are mostly handled with various y =
height - y tweaks before we pass y coordinates to OpenGL.
Generally speaking though the handling of coordinate spaces in Cogl is a bit
fragile. I guess partly because none of it was design to be, it just
evolved from how Clutter defines its coordinates without much consideration
or testing. I hope to improve this over a number of commits; starting here.
This commit deals with the fact that offscreen draw buffers may be bound to
textures but we don't "upload" the texture data upside down, and so if you
texture from an offscreen draw buffer you need to manually flip the texture
coordinates to get it the right way around. We now force offscreen
rendering to be flipped upside down by tweaking the projection matrix right
before we submit it to OpenGL to scale y by -1. The tweak is entirely
hidden from the user such that if you call cogl_get_projection you will not
see this scale.
We were ignoring the possibility that the current modelview matrix may flip
the incoming rectangle in which case we didn't calculate a valid scissor
rectangle for clipping.
This fixes: http://bugzilla.o-hand.com/show_bug.cgi?id=1809
(Clipping doesn't work within an FBO)
Cogl's support for offscreen rendering was originally written just to support
the clutter_texture_new_from_actor API and due to lack of documentation and
several confusing - non orthogonal - side effects of using the API it wasn't
really possible to use directly.
This commit does a number of things:
- It removes {gl,gles}/cogl-fbo.{c,h} and adds shared cogl-draw-buffer.{c,h}
files instead which should be easier to maintain.
- internally CoglFbo objects are now called CoglDrawBuffers. A
CoglDrawBuffer is an abstract base class that is inherited from to
implement CoglOnscreen and CoglOffscreen draw buffers. CoglOffscreen draw
buffers will initially be used to support the
cogl_offscreen_new_to_texture API, and CoglOnscreen draw buffers will
start to be used internally to represent windows as we aim to migrate some
of Clutter's backend code to Cogl.
- It makes draw buffer objects the owners of the following state:
- viewport
- projection matrix stack
- modelview matrix stack
- clip state
(This means when you switch between draw buffers you will automatically be
switching to their associated viewport, matrix and clip state)
Aside from hopefully making cogl_offscreen_new_to_texture be more useful
short term by having simpler and well defined semantics for
cogl_set_draw_buffer, as mentioned above this is the first step for a couple
of other things:
- Its a step toward moving ownership for windows down from Clutter backends
into Cogl, by (internally at least) introducing the CoglOnscreen draw
buffer. Note: the plan is that cogl_set_draw_buffer will accept on or
offscreen draw buffer handles, and the "target" argument will become
redundant since we will instead query the type of the given draw buffer
handle.
- Because we have a common type for on and offscreen framebuffers we can
provide a unified API for framebuffer management. Things like:
- blitting between buffers
- managing ancillary buffers (e.g. attaching depth and stencil buffers)
- size requisition
- clearing
Over time the two cogl-fbo.c files have needlessly diverged as bug fixes or
cleanups went into one version but not the other. This tries to bring them
back in line with each other. It should actually be simple enough to move
cogl-fbo.c to be a common file, and simply not build it for GLES 1.1, so
maybe I'll follow up with such a patch soon.
The comment just said: "Some implementation require a clear before drawing
to an fbo. Luckily it is affected by scissor test." and did a scissored
clear, which is clearly a driver bug workaround, but for what driver? The
fact that it was copied into the gles backend (or vica versa is also
suspicious since it seems unlikely that the workaround is necessary for both
backends.)
We can easily restore the workaround with a better comment if this problem
really still exists on current drivers, but for now I'd rather minimize
hand-wavey workaround code that can't be tested.
Otherwise you can't use the alpha channel of the vertex colors unless
the material has a texture with alpha or the material's color has
alpha less than 255.
Some changes to make COGL pass distcheck with Automake 1.11 and
anal-retentiveness turned up to 11.
The "major" change is the flattening of the winsys/ part of COGL,
which is built directly inside libclutter-cogl.la instead of an
intermediate libclutter-cogl-winsys.la object.
Ideally, the whole COGL should be flattened out using a
quasi-non-recursive Automake layout; unfortunately, the driver/
sub-section ships with identical targets and Automake cannot
distinguish GL and GLES objects.
Since we no longer depend on the GL matrix API in Cogl we can remove a lot
of wrapper code from the GLES 2 backend. This is particularly nice given
that there was no code shared between the cogl-matrix-stack API and gles2
wrappers so we had a lot of duplicated logic.
The indirection through this API isn't necessary since we no longer
arbitrate between the OpenGL matrix API and Cogl's client side API. Also it
doesn't help to maintain an OpenGL style matrix mode API for internal use
since it's awkward to keep restoring the MODELVIEW mode and easy enough to
directly work with the matrix stacks of interest.
This replaces use of the _cogl_current_matrix API with direct use of the
_cogl_matrix_stack API. All the unused cogl_current_matrix API is removed
and the matrix utility code left in cogl-current-matrix.c was moved to
cogl.c.
This cache of the gl matrix mode lets us avoid repeat calls to glMatrixMode
in _cogl_matrix_stack_flush_to_gl when we have lots of sequential modelview
matrix modifications.
This goes a bit further than the previous patch, and as a special case
we now simply represent identity matrices using a boolean, and only
lazily initialize them when they need to be modified.
The journal always uses an identity matrix since it uses software
transformation. Currently it manually uses glLoadMatrix since previous
experimentation showed that the cogl-matrix-stack gave bad performance, but
it would be nice to fix performance so we only have to care about one path
for loading matrices.
For the common case where we do:
cogl_matrix_stack_push()
cogl_matrix_stack_load_identity()
we were effectively initializing the matrix 3 times. Once due to use of
g_slice_new0, then we had a cogl_matrix_init_identity in
_cogl_matrix_state_new for good measure, and then finally in
cogl_matrix_stack_load_identity we did another cogl_matrix_init_identity.
We don't use g_slice_new0 anymore, _cogl_matrix_state_new is documented as
not initializing the matrix (instead _cogl_matrix_stack_top_mutable now
takes a boolean to choose if new stack entries should be initialised) and so
we now only initialize once in cogl_matrix_stack_load_identity.
This relates back to an earlier commitment to stop using the OpenGL matrix
API which is considered deprecated. (ref 54159f5a1d)
The new texture matrix stacks are hung from a list of (internal only)
CoglTextureUnit structures which the CoglMaterial code internally references
via _cogl_get_texure_unit ().
So we would be left with only the cogl-matrix-stack code being responsible
for glMatrixMode, glLoadMatrix and glLoadIdentity this commit updates the
journal code so it now uses the matrix-stack API instead of GL directly.
The Journal can be considered a standalone component, so even though
it's currently only used to log quads, it seems better to split it
out into its own file.
When we implement atlas textures we will probably want to use the spans API
to handle texture repeating so it doesn't make sense to leave the code in
cogl-texture-2d-sliced.c. Since it's a standalone set of data structures
and algorithms it also seems reasonable to split out from cogl-texture.
cogl-texture-2d-sliced provides an implementation of CoglTexture and this
seperation lays the foundation for potentially supporting atlas textures,
pixmap textures (as in GLX_EXT_texture_from_pixmap) and fast-path
GL_TEXTURE_{1D,2D,3D,RECTANGLE} textures in a maintainable fashion.
cogl-primitives.c was previously digging right into CoglTextures so it could
manually iterate the texture slices for texturing quads and polygons and
because we were missing some state getters we were lazily just poking into
the structures directly.
This adds some extra state getter functions, and adds a higher level
_cogl_texture_foreach_slice () API that hopefully simplifies the way in
which sliced textures may be used to render primitives. This lets you
specify a rectangle in "virtual" texture coords and it will call a given
callback for each slice that intersects that rectangle giving the virtual
coords of the current slice and corresponding "real" texture coordinates for
the underlying gl texture.
At the same time a noteable bug in how we previously iterated sliced
textures was fixed, whereby we weren't correctly handling inverted texture
coordinates. E.g. with the previous code if you supplied texture coords of
tx1=100,ty1=0,tx2=0,ty2=100 (inverted along y axis) that would result in a
back-facing quad, which could be discarded if using back-face culling.
The descriptions for gl_handle and gl_target were inverted.
Thanks to Young-Ho Cha for spotting that.
Signed-off-by: Robert Bragg <robert@linux.intel.com>
As part of an incremental process to have Cogl be a standalone project we
want to re-consider how we organise the Cogl source code.
Currently this is the structure I'm aiming for:
cogl/
cogl/
<put common source here>
winsys/
cogl-glx.c
cogl-wgl.c
driver/
gl/
gles/
os/ ?
utils/
cogl-fixed
cogl-matrix-stack?
cogl-journal?
cogl-primitives?
pango/
The new winsys component is a starting point for migrating window system
code (i.e. x11,glx,wgl,osx,egl etc) from Clutter to Cogl.
The utils/ and pango/ directories aren't added by this commit, but they are
noted because I plan to add them soon.
Overview of the planned structure:
* The winsys/ API is the API that binds OpenGL to a specific window system,
be that X11 or win32 etc. Example are glx, wgl and egl. Much of the logic
under clutter/{glx,osx,win32 etc} should migrate here.
* Note there is also the idea of a winsys-base that may represent a window
system for which there are multiple winsys APIs. An example of this is
x11, since glx and egl may both be used with x11. (currently only Clutter
has the idea of a winsys-base)
* The driver/ represents a specific varient of OpenGL. Currently we have "gl"
representing OpenGL 1.4-2.1 (mostly fixed function) and "gles" representing
GLES 1.1 (fixed funciton) and 2.0 (fully shader based)
* Everything under cogl/ should fundamentally be supporting access to the
GPU. Essentially Cogl's most basic requirement is to provide a nice GPU
Graphics API and drawing a line between this and the utility functionality
we add to support Clutter should help keep this lean and maintainable.
* Code under utils/ as suggested builds on cogl/ adding more convenient
APIs or mechanism to optimize special cases. Broadly speaking you can
compare cogl/ to OpenGL and utils/ to GLU.
* clutter/pango will be moved to clutter/cogl/pango
How some of the internal configure.ac/pkg-config terminology has changed:
backendextra -> CLUTTER_WINSYS_BASE # e.g. "x11"
backendextralib -> CLUTTER_WINSYS_BASE_LIB # e.g. "x11/libclutter-x11.la"
clutterbackend -> {CLUTTER,COGL}_WINSYS # e.g. "glx"
CLUTTER_FLAVOUR -> {CLUTTER,COGL}_WINSYS
clutterbackendlib -> CLUTTER_WINSYS_LIB
CLUTTER_COGL -> COGL_DRIVER # e.g. "gl"
Note: The CLUTTER_FLAVOUR and CLUTTER_COGL defines are kept for apps
As the first thing to take advantage of the new winsys component in Cogl;
cogl_get_proc_address() has been moved from cogl/{gl,gles}/cogl.c into
cogl/common/cogl.c and this common implementation first trys
_cogl_winsys_get_proc_address() but if that fails then it falls back to
gmodule.
This moves most of cogl-context.{c.h} to cogl/common with some driver
specific members now living in a CoglContextDriver struct. Driver specific
context initialization and typedefs now live in
cogl/{gl,gles}/cogl-context-driver.{c,h}
Driver specific members can be found under ctx->drv.stuff
This splits the limited components that differed between
cogl/{gl,gles}/cogl-texture.c into new {gl,gles}/cogl-texture-driver.c files
and the rest that can now be shared into cogl/common/cogl-texture.c
When not building a debug build the compiler was warning about empty
else clauses with no braces due to code like:
if (blah)
do_foo();
else
COGL_NOTE (DRAW, "a-wibble");
This simply ensures that even for non debug builds COGL_NOTE will expand to
a single statement.
glVertexPointer expects positions with 2, 3 or 4 components, glColorPointer
expects colors with 3 or 4 components and glNormalPointer expects normals
with three components so when adding vertex buffer atributes with the names
"gl_Vertex", "gl_Color" or "gl_Normal" we assert these constraints and print
an explanation to the developer if not met.
This also fixes the previosly incorrect constraint that gl_Normal attributes
must have n_components == 1; thanks to Cat Sidhe for reporting this:
Bug: http://bugzilla.openedhand.com/show_bug.cgi?id=1819
By default, float * is considered as an out argument by gobject
introspection which is wrong for quite a few Cogl symbols. Start adding
annotations to fix that for the ones in the "Primitives" gtk-doc
section.
The lifetime of the journal VBO is entirely within the scope of the
cogl_journal_flush function so there is no need to store it globally
in the Cogl context. Instead, upload_vertices_to_vbo just returns the
new VBO. cogl_journal_flush stores this in a local variable and
destroys it before returning.
This also fixes an assertion when using the GLES backend which was
caused by nothing initialising the journal_vbo variable.
The framebuffer_object spec isn't clear in defining whether attaching a
texture as a renderbuffer with mipmap filtering enabled while the mipmaps
have not been uploaded should result in an incomplete framebuffer object.
(different drivers make different decisions)
To avoid an error with drivers that do consider this a problem we explicitly
set non mipmapped filters before calling glCheckFramebufferStatusEXT. The
filters will later be reset when the texture is actually used for rendering
according to the filters set on the corresponding CoglMaterial.
The blend string compiler checks that the syntax of a function name is
[A-Za-z_]*, preventing the use of DOT3_RGB[A].
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This reverts commit 3c47a3beb5.
Of course I remembered just after pushing the patch why we hadn't done
this before :-) If you look in the glsl spec:
http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.24.pdf
Section 3.7.10 Texture Completeness and Non-Power-Of-Two Textures
you can see GLES 2.0 doesn't support mipmaps for npot textures.
There is possibly some way we could support this in Cogl but at least
it's not as simple as or-ing in the feature flag, sadly.
The core GLES2 API supports NPOT textures, i.e. there is no extension as for
OpenGL, so we now add COGL_FEATURE_TEXTURE_NPOT to the feature flags in
_cogl_features_init.
Thanks to Gordon Williams for spotting this.
Don't let stringify.sh write to the $srcdir + use the BUILT_SOURCES var in
Makefile.am so as to ensure all .c. and .h files get generated from their
corresponding .glsl files before building other targets.
The wrong part of an expression was bracketed in the test to determine
when a new texture matrix needed to be loaded which resulted in the
first pass through _cogl_material_layer_flush_gl_sampler_state
not uploading any user matrix.
Following bug #1762, the syntax of g-ir-scanner was changed in
gobject-introspection, so Clutter does not build anymore with 0.6.4.
See the bugzilla bug:
http://bugzilla.gnome.org/show_bug.cgi?id=591669
GObject-Introspection now uses a different mechanism to extract the
SONAME when building the gir file and it needs the libtool archive as
option.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Keep the CoglContext in sync between GL and GLES backends. We ought
to find a way to have a generic context, though, and have backend
specific sections.
Fixes bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1698
On some platforms (anything but Linux, and on obscure Linux
architectures) dolt isn't used, so $(top_builddir)/doltlibtool
won't exist. $(top_builddir)/libtool will always be generated
even if dolt is used, so just use that unconditionally. We don't
need the extra speed when linking the single program for
introspection.
http://bugzilla.openedhand.com/show_bug.cgi?id=1699
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
commit e2c4a2a9f8 fixed one thing but broke many others things :-/
hopfully this fixes that.
It turned out that the journal was mistakenly setting the OVERRIDE_LAYER0
flush option for all entries, but some other logic errors were also
uncovered in _cogl_material_equal.
To help us handle sliced textures; When flushing materials there is an
override option that can be given to replace the texture name for layer0
so we may iterate the slices without needing to modify the material
in use.
Since improving the journal's ability to batch state changes we added a
_cogl_material_equals function that is used by the journal to compare
materials and identify when a state change is required, but this wasn't
correctly considering the layer0 override resulting in false positives that
meant the journal wouldn't update the GL state and the first texture name
was used for all slices.
The cost of glGetFloatv with Mesa is still representing a majority of our
time in OpenGL for some applications, and the last thing left using this is
the current-matrix API when getting the projection matrix.
This adds a matrix stack for the projection matrix, so all getting, setting
and modification of the projection matrix is now managed by Cogl and it's only
when we come to draw that we flush changes to the matrix to OpenGL.
This also brings us closer to being able to drop internal use of the
deprecated OpenGL matrix functions, re: commit 54159f5a1d
Scanners like gtk-doc and g-ir-scanner get confused by:
typedef struct _Foo {
...
} Foo;
And expect instead:
typedef struct _Foo Foo;
struct _Foo {
...
};
CoglMatrix definition should be changed to avoid the former type.
In order to validate the sequence of:
XResizeWindow
ConfigureNotify
glViewport
that should happen on X11 we need to add debug annotations to the
calls to glViewport() done through COGL.
This avoids some calls to glGetFloatv, which have at least proven to be very
in-efficient in mesa at this point in time, since it always updates all derived
state even when it may not relate to the state being requested.
Fixes and adds a unit test for creating and drawing using materials with
COGL_INVALID_HANDLE texture layers.
This may be valid if for example the user has set a texture combine string
that only references a constant color.
_cogl_material_flush_layers_gl_state will bind the fallback texture for any
COGL_INVALID_HANDLE layer, later though we could explicitly check when the
current blend mode does't actually reference a texture source in which case
binding the fallback texture is redundant.
This tests drawing using cogl_rectangle, cogl_polygon and
cogl_vertex_buffer_draw.
Although we wouldn't recommend developers try and interleve OpenGL drawing
with Cogl drawing - we would prefer patches that improve Cogl to avoid this
if possible - we are providing a simple mechanism that will at least give
developers a fighting chance if they find it necissary.
Note: we aren't helping developers change OpenGL state to modify the
behaviour of Cogl drawing functions - it's unlikley that can ever be
reliably supported - but if they are trying to do something like:
- setup some OpenGL state.
- draw using OpenGL (e.g. glDrawArrays() )
- reset modified OpenGL state.
- continue using Cogl to draw
They should surround their blocks of raw OpenGL with cogl_begin_gl() and
cogl_end_gl():
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
Again; we aren't supporting code like this:
- setup some OpenGL state.
- use Cogl to draw
- reset modified OpenGL state.
When the internals of Cogl evolves, this is very liable to break.
cogl_begin_gl() will flush all internally batched Cogl primitives, and emit
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 setup and other world
state such as backface culling, depth and fogging enabledness will be also
be sent to OpenGL.
Note: no special material state is flushed, so if developers want Cogl to setup
a simplified material state it is the their responsibility to set a simple
source material before calling cogl_begin_gl. E.g. by calling
cogl_set_source_color4ub().
Note: It is the developers responsibility to restore any OpenGL state that they
modify to how it was after calling cogl_begin_gl() if they don't do this then
the result of further Cogl calls is undefined.
This function should only need to be called in exceptional circumstances
since Cogl can normally determine internally when a flush is necessary.
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.
cogl_flush() ensures 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 internally for the material API, but for now it
can use cogl_flush() to at least ensure that the ARBfp program isn't applied
to additional primitives.
This does not provide a robust generalized solution supporting safe use of
raw GL, its use is very much discouraged.
Previously we would call _cogl_material_pre_change_notify unconditionally, but
now we wait until we really know we are removing a layer before notifying the
change, which will require a journal flush.
Since the convenience functions cogl_set_source_color4ub and
cogl_set_source_texture share a single material, cogl_set_source_color4ub
always calls cogl_material_remove_layer. Often this is a NOP though and
shouldn't require a journal flush.
This gets performance back to where it was before reverting the per-actor
material commits.
Before any cogl vertex buffer drawing we call
enable_state_for_drawing_buffer which sets up the GL state, but we weren't
disabling unsed client texture coord arrays.
This simplifies the vertex data uploading in the journal, and could improve
performance. Modifying a VBO mid-scene could reqire synchronizing with the
GPU or some form of shadowing/copying to avoid modifying data that the GPU
is currently processing; the buffer was also being marked as GL_STATIC_DRAW
which could have made things worse.
Now we simply create a GL_STATIC_DRAW VBO for each flush and and delete it
when we are finished.
Using cogl_rectangle (and thus the journal) in
_cogl_add_path_to_stencil_buffer means we have to consider all the state
that the journal may change in case it may interfer with the direct GL calls
used. This has proven to be error prone and in this case the journal is an
unnecissary overhead. We now simply call glRectf instead of using
cogl_rectangle.
We were missing the simplest test of all: are the two CoglHandles equal and
are the flush option flags for each material equal? This should improve
batching for some common cases.
Whenever we modify a material we call _cogl_material_pre_change_notify which
checks to see if the material is referenced by the journal and if so flushes
if before we modify the material.
Since the journal logs material colors directly into a vertex array (to
avoid us repeatedly calling glColor) then we know we never need to flush
the journal when material colors change.
Since most Clutter actors aren't much more than textured quads; flushing the
journal typically involves lots of 'change modelview; draw quad' sequences.
The amount of overhead involved in uploading a new modelview and queuing
that primitive is huge in comparison to simply transforming 4 vertices by
the current modelview when logging quads. (Note if your GPU supports HW
vertex transform, then it still does the projective and viewport transforms)
At the same time a --cogl-debug=disable-software-transform option has been
added for comparison and debugging.
This change allows typical pick scenes to be batched into a single draw call
and I'm seeing test-pick run over 200% faster with this. (i965 + Mesa
7.6-devel)
Enabling this option makes Cogl trace how the journal is managing to batch
your rectangles. The journal staggers how it emmits state to the GL driver
and the batches will normally get smaller for each stage, but ideally you
don't want to be in a situation where Cogl is only able to draw one quad per
modelview change and draw call.
E.g. this is a fairly ideal example:
BATCHING: journal len = 101
BATCHING: vbo offset batch len = 101
BATCHING: material batch len = 101
BATCHING: modelview batch len = 101
This isn't:
BATCHING: journal len = 1
BATCHING: vbo offset batch len = 1
BATCHING: material batch len = 1
BATCHING: modelview batch len = 1
BATCHING: journal len = 1
BATCHING: vbo offset batch len = 1
BATCHING: material batch len = 1
BATCHING: modelview batch len = 1
<repeat>
When this option is used Cogl will print a trace of all quads that get
logged into the journal, and a trace of quads as they get flushed.
If you are seeing a bug with the geometry being drawn by Cogl this may give
some clues by letting you sanity check the numbers being logged vs the
numbers being emitted.
For testing the VBO fallback paths it helps to be able to disable the
COGL_FEATURE_VBOS feature flag. When VBOs aren't available Cogl should use
client side malloc()'d buffers instead.
Previously we only used the Cogl matrix stack API for indirect contexts, but
it's too costly to keep on requesting modelview matrices from GL (for
logging in the journal) even for direct rendering.
I also experimented with a patch for mesa to improve performance and
discussed this with upstream, but we agreed to consider the GL matrix API
essentially deprecated. (For reference the GLES 2 and GL 3 specs have
removed the matrix APIs)
CoglColors shouldn't be compared using memcmp since they may contain
uninitialized padding bytes.
The prototype is also suitable for passing to g_hash_table_new as the
key_equal_func.
_cogl_pango_display_list_add_texture now uses this instead of memcmp.
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.
The number of material layers enabled when logging a quad in the journal
determines the stride of the corresponding vertex data (since we need a set
of texture coordinates for each layer.) By padding data in the case where we
have only one layer we can avoid a change in stride if we are mixing single
and double layer primitives in a scene (e.g. relevent for a composite
manager that may use 2 layers for all shaped windows) Avoiding stride
changes means we can minimize calls to gl{Vertex,Color}Pointer when flushing
the journal.
Since we need to update the texcoord pointers when the actual number of
layers changes, this adds another batch_and_call() stage to deal with
glTexCoordPointer and enabling/disabling the client arrays.
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
Use signed integers while combining window space clip rectangles, so we avoid
arithmatic errors later resulting in glScissor getting negative width and
height arguments.
Previously this was RGBA_8888. It souldn't really make a difference but for
consistency we expect almost all textures in use to have an internaly
premultiplied pixel format.
_cogl_texture_download_from_gl needs to create transient CoglBitmaps when
downloading sliced textures from GL, and then copies these as subregions
into the final target_bitmap. _cogl_texture_download_from_gl also supports
target_bitmaps with a different format to the source CoglTexture being
downloaded.
The problem was that in the case of slice textures we were always looking
at the format of the CoglTexture, not of the target_bitmap when setting
up the transient slice bitmap.
To allow for flushing of batched geometry within Cogl we can't support users
directly calling glReadPixels. glReadPixels is also awkward, not least
because it returns upside down image data.
All the unit tests have been swithed over and clutter_stage_read_pixels now
sits on top of this too.
We were calculating our vertex stride and allocating our vertex array
differently depending on whether the user passed TRUE for use_color or not.
The problem was that we were always writting color data to the array
regardless of use_color.
There was also a bug with _cogl_texture_sliced_polygon in that it was
writing byte color components but we were expecting float components. We
now use byte components in _cogl_multitexture_unsliced_polygon too and pass
GL_UNSIGNED_BYTE to glColorPointer.
Cogl already add similar defines but with the CLUTTER namespace
(CLUTTER_COGL_HAS_GL and CLUTTER_COGL_HAS_GLES). Let's just add two
similar defines with the COGL namespace. Removing the CLUTTER_COGL ones
could break applications silently for no real good reason.
HAVE_COGL_GLES2 is defined in config.h through the configure script and
should not be used in public headers.
The patch makes configure generate the right define that can be used
later in the header.
In order to be ready for the next major version of GLib we need to
disable single header inclusion by using the G_DISABLE_SINGLE_INCLUDES
define in the build process.
My patch to choose a premultiplied format when the user gives
COGL_PIXEL_FORMAT_ANY for the internal_format broke the case where the data
in question doesn't have and alpha channel.
This was accidentally missed when merging the premultiplication branch
since I merged a local version of the branch that missed this commit.
Although the underlying materials should allow layers with INVALID_HANDLES
it shouldn't be necissary to expose that via cogl_set_source_texture() and
it's easier to resolve a warning/crash here than odd artefacts/crashes later
in the pipeline.
Merge branch 'premultiplication'
[cogl-texture docs] Improves the documentation of the internal_format args
[test-premult] Adds a unit test for texture upload premultiplication semantics
[fog] Document that fogging only works with opaque or unmultipled colors
[test-blend-strings] Explicitly request RGBA_888 tex format for test textures
[premultiplication] Be more conservative with what data gets premultiplied
[bitmap] Fixes _cogl_bitmap_fallback_unpremult
[cogl-bitmap] Fix minor copy and paste error in _cogl_bitmap_fallback_premult
Avoid unnecesary unpremultiplication when saving to local data
Don't unpremultiply Cairo data
Default to a blend function that expects premultiplied colors
Implement premultiplication for CoglBitmap
Use correct texture format for pixmap textures and FBO's
Add cogl_color_premultiply()
Clarifies that if you give COGL_PIXEL_FORMAT_ANY as the internal format for
cogl_texture_new_from_file or cogl_texture_new_from_data then Cogl will
choose a premultiplied internal format.
The fixed function fogging provided by OpenGL only works with unmultiplied
colors (or if the color has an alpha of 1.0) so since we now premultiply
textures and colors by default a note to this affect has been added to
clutter_stage_set_fog and cogl_set_fog.
test-depth.c no longer uses clutter_stage_set_fog for this reason.
In the future when we can depend on fragment shaders we should also be
able to support fogging of premultiplied primitives.
We don't want to force texture data to be premultipled if the user
explicitly specifies a non premultiplied internal_format such as
COGL_PIXEL_FORMAT_RGBA_8888. So now Cogl will only automatically
premultiply data when COGL_PIXEL_FORMAT_ANY is given for the
internal_format, or a premultiplied internal format such as
COGL_PIXEL_FORMAT_RGBA_8888_PRE is requested but non-premultiplied source
data is given.
This approach is consistent with OpenVG image formats which have already
influenced Cogl's pixel format semantics.
The _cogl_unpremult_alpha_{first,last} functions which
_cogl_bitmap_fallback_unpremult depends on were incorrectly casting each
of the byte components of a texel to a gulong and performing shifts as
if it were dealing with the whole texel.
It now just uses array indexing to access the byte components without
needing to cast or manually shift any bits around.
Even though we used to depend on unpremult whenever we used a
ClutterCairoTexture, clutter_cairo_texture_context_destroy had it's own
unpremult code which worked which is why this bug wouldn't have been noticed
before.
Many operations, like mixing two textures together or alpha-blending
onto a destination with alpha, are done most logically if texture data
is in premultiplied form. We also have many sources of premultiplied
texture data, like X pixmaps, FBOs, cairo surfaces. Rather than trying
to work with two different types of texture data, simplify things by
always premultiplying texture data before uploading to GL.
Because the default blend function is changed to accommodate this,
uses of pure-color CoglMaterial need to be adapted to add
premultiplication.
gl/cogl-texture.c gles/cogl-texture.c: Always premultiply
non-premultiplied texture data before uploading to GL.
cogl-material.c cogl-material.h: Switch the default blend functions
to ONE, ONE_MINUS_SRC_ALPHA so they work correctly with premultiplied
data.
cogl.c: Make cogl_set_source_color() premultiply the color.
cogl.h.in color-material.h: Add some documentation about
premultiplication and its interaction with color values.
cogl-pango-render.c clutter-texture.c tests/interactive/test-cogl-offscreen.c:
Use premultiplied colors.
http://bugzilla.openedhand.com/show_bug.cgi?id=1406
Signed-off-by: Robert Bragg <robert@linux.intel.com>
cogl-bitmap.c cogl-bitmap-pixbuf.c cogl-bitmap-fallback.c cogl-bitmap-private.h:
Add _cogl_bitmap_can_premult(), _cogl_bitmap_premult() and implement
a reasonably fast implementation in the "fallback" code.
http://bugzilla.openedhand.com/show_bug.cgi?id=1406
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Otherwise if there is an error before the slices are created it will
try to free the first_pixels array and crash.
It now also checks whether first_pixels has been created before using
it to update the mipmaps. This should only happen for
cogl_texture_new_from_foreign and doesn't matter if the FBO extension
is available. It would be better in this case to fetch the first pixel
using glGetTexImage as Owen mentioned in the last commit.
tex->first_pixels was never set for foreign textures, leading
to a crash when the texture object is freed.
As a quick fix, simply set to NULL. A more complete fix would
require remembering if we had ever seen the first pixel uploaded,
and if not, doing a glReadPixel to get it before triggering the
mipmap update.
http://bugzilla.openedhand.com/show_bug.cgi?id=1645
Signed-off-by: Neil Roberts <neil@linux.intel.com>
It's very common that there's no reasonable fallback to do if the
blend or combine string you set isn't supported. So, rather than
requiring everybody to pass in a GError purely to catch syntax erorrs,
automatically g_warning() if a parse error is encountered and @error
is NULL.
http://bugzilla.openedhand.com/show_bug.cgi?id=1642
Signed-off-by: Robert Bragg <robert@linux.intel.com>
* 1.0-integration: (138 commits)
[x11] Disable XInput by default
[xinput] Invert the XI extension version check
[cogl-primitives] Fix an unused variable warning when building GLES
[clutter-stage-egl] Pass -1,-1 to clutter_stage_x11_fix_window_size
Update the GLES backend to have the layer filters in the material
[gles/cogl-shader] Add a missing semicolon
[cogl] Move the texture filters to be a property of the material layer
[text] Fix Pango unit to pixels conversion
[actor] Force unrealization on destroy only for non-toplevels
[x11] Rework map/unmap and resizing
[xinput] Check for the XInput entry points
[units] Validate units against the ParamSpec
[actor] Add the ::allocation-changed signal
[actor] Use flags to control allocations
[units] Rework Units into logical distance value
Remove a stray g_value_get_int()
Remove usage of Units and macros
[cogl-material] Allow setting a layer with an invalid texture handle
[timeline] Remove the concept of frames from timelines
[gles/cogl-shader] Fix parameter spec for cogl_shader_get_info_log
...
Conflicts:
configure.ac
The texture filters are now a property of the material layer rather
than the texture object. Whenever a texture is painted with a material
it sets the filters on all of the GL textures in the Cogl texture. The
filter is cached so that it won't be changed unnecessarily.
The automatic mipmap generation has changed so that the mipmaps are
only generated when the texture is painted instead of every time the
data changes. Changing the texture sets a flag to mark that the
mipmaps are dirty. This works better if the FBO extension is available
because we can use glGenerateMipmap. If the extension is not available
it will temporarily enable automatic mipmap generation and reupload
the first pixel of each slice. This requires tracking the data for the
first pixel.
The COGL_TEXTURE_AUTO_MIPMAP flag has been replaced with
COGL_TEXTURE_NO_AUTO_MIPMAP so that it will default to
auto-mipmapping. The mipmap generation is now effectively free if you
are not using a mipmap filter mode so you would only want to disable
it if you had some special reason to generate your own mipmaps.
ClutterTexture no longer has to store its own copy of the filter
mode. Instead it stores it in the material and the property is
directly set and read from that. This fixes problems with the filters
getting out of sync when a cogl handle is set on the texture
directly. It also avoids the mess of having to rerealize the texture
if the filter quality changes to HIGH because Cogl will take of
generating the mipmaps if needed.
It was previously possible to create a material layer with no texture
by setting some property on it such as the matrix. However it was not
possible to get back to that state without removing the layer and
recreating it. It is useful to be able to remove the texture to free
resources without forgetting the state of the layer so we can put a
different texture in later.
When creating a Cogl texture from a Cogl bitmap it would steal the
data by setting the bitmap_owner flag and clearing the data pointer
from the bitmap. The data would be freed by the time the
new_from_bitmap is finished. There is no reason to do this because the
data will be freed when the Cogl bitmap is unref'd and it is confusing
not to be able to reuse the bitmap for creating multiple textures.
The cogl_shader_get_info_log() function is very inconvenient for
language bindings and for regular use, as it requires a static
buffer to be filled -- basically just providing a wrapper around
glGetInfoLogARB().
Since COGL aims to be a more convenient API than raw GL we should
just make cogl_shader_get_info_log() return an allocated string
with the GLSL compiler log.
Instead of using GL_TRIANGLES and uploading the indices every time, it
now uses GL_QUADS instead on OpenGL. Under GLES it still uses indices
but it uses the new cogl_vertex_buffer_indices_get_for_quads function
to avoid uploading the vertices every time.
This requires the _cogl_vertex_buffer_indices_pointer_from_handle
function to be exposed privately to the rest of Cogl.
The static_indices array has been removed from the Cogl context.
This function can be used as an efficient way of drawing groups of
quads without using GL_QUADS. It generates a VBO containing the
indices needed to render using pairs of GL_TRIANGLES. The VBO is
globally cached so that it only needs to be uploaded whenever more
indices are requested than ever before.
The cogl-enum-types.h file is created by glib-mkenums under
/clutter/cogl/common, and then copied in /clutter/cogl in order
to make the inclusion of that file work inside cogl.h.
Since we're copying it in a different location, the Makefile
for that location has to clean up the copy.
We avoid rebuilding cogl-enum-types.h and cogl-enum-types.c by
using a "guard" -- a stamp file that will block Makefile. Since
we need cogl-enum-types.h into /clutter/cogl as well for the
cogl.h include to work, if we copy the cogl-enum-types.h
unconditionally it will cause a rebuild of the whole COGL; which
will cause a full rebuild.
To solve this, we can copy the header file when generating it
under the stamp file.
The libclutter-cogl internal object should be the only dependency
for Clutter, since we are already copying it inside clutter/cogl
for the introspection scanner. For this reason, the backend-specific,
real internal object should be built with the backend encoded into
the file name, like libclutter-common. This makes the build output
a little bit more clear: instead of having two:
LINK libclutter-cogl-common.la
...
LINK libclutter-cogl.la
LINK libclutter-cogl.la
We'll have:
LINK libclutter-cogl-common.la
...
LINK libclutter-cogl-gl.la
LINK libclutter-cogl.la
Same applies for the GLES backend.
Just like we do with GObject types and G_DEFINE_TYPE, we should
use the g_once_init_enter/g_once_init_leave mechanism to make the
GType registration of enumeration types thread safe.
The setup_viewport() function should only be used by Clutter and
not by application code.
It can be emulated by changing the Stage size and perspective and
requeueing a redraw after calling clutter_stage_ensure_viewport().
The backface culling enabling function was split and renamed, just
like the depth testing one, so we need to add the macro to the
cogl-deprecated.h header.
Previously indices were tightly bound to a particular Cogl vertex buffer
but we would like to be able to share indices so now we have
cogl_vertex_buffer_indices_new () which returns a CoglHandle.
In particular we could like to have a shared set of indices for drawing
lists of quads that can be shared between the pango renderer and the
Cogl journal.
At the moment Cogl doesn't do much batching of quads so most of the time we
are flushing a single quad at a time. This patch simplifies how we submit
those quads to OpenGL by using glDrawArrays with GL_TRIANGLE_FAN mode
instead of sending indexed vertices using GL_TRIANGLES mode.
Note: I hope to follow up soon with changes that improve our batching and
also move the indices into a VBO so they don't need to be re-validated every
time we call glDrawElements.
To assist people porting code from 0.8, the cogl_texture_* functions that
have been replaced now have defines that give some hint as to how they
should be replaced.
cogl_enable_depth_test and cogl_enable_backface_culling have been renamed
and now have corresponding getters, the new functions are:
cogl_set_depth_test_enabled
cogl_get_depth_test_enabled
cogl_set_backface_culling_enabled
cogl_get_backface_culling_enabled
This adds cogl_matrix api for multiplying matrices either by a perspective
or ortho projective transform. The internal matrix stack and current-matrix
APIs also have corresponding support added.
New public API:
cogl_matrix_perspective
cogl_matrix_ortho
cogl_ortho
cogl_set_modelview_matrix
cogl_set_projection_matrix
cogl_create_context is dealt with internally when _cogl_get_default context
is called, and cogl_destroy_context is currently never called.
It might be nicer later to get an object back when creating a context so
Cogl can support multiple contexts, so these functions are being removed
from the API until we get a chance to address context management properly.
For now cogl_destroy_context is still exported as _cogl_destroy_context so
Clutter could at least install a library deinit handler to call it.
Originally cogl_vertex_buffer_add_indices let the user pass in their own unique
ID for the indices; now the Id is generated internally and returned to the
caller.
It's now possible to add arrays of indices to a Cogl vertex buffer and
they will be put into an OpenGL vertex buffer object. Since it's quite
common for index arrays to be static it saves the OpenGL driver from
having to validate them repeatedly.
This changes the cogl_vertex_buffer_draw_elements API: It's no longer
possible to provide a pointer to an index array at draw time. So
cogl_vertex_buffer_draw_elements now takes an indices identifier that
should correspond to an idendifier returned when calling
cogl_vertex_buffer_add_indices ()
This is being removed before we release Clutter 1.0 since the implementation
wasn't complete, and so we assume no one is using this yet. Util we have
someone with a good usecase, we can't pretend to support breaking out into
raw OpenGL.
There were a number of functions intended to support creating of new
primitives using materials, but at this point they aren't used outside of
Cogl so until someone has a usecase and we can get feedback on this
API, it's being removed before we release Clutter 1.0.
This removes the following API:
cogl_material_set_blend_factors
cogl_material_set_layer_combine_function
cogl_material_set_layer_combine_arg_src
cogl_material_set_layer_combine_arg_op
These were rather awkward to use, so since it's expected very few people are
using them at this point and it should be straight forward to switch over
to blend strings, the API is being removed before we release Clutter 1.0.
Setting up layer combine functions and blend modes is very awkward to do
programatically. This adds a parser for string based descriptions which are
more consise and readable.
E.g. a material layer combine function could now be given as:
"RGBA = ADD (TEXTURE[A], PREVIOUS[RGB])"
or
"RGB = REPLACE (PREVIOUS)"
"A = MODULATE (PREVIOUS, TEXTURE)"
The simple syntax and grammar are only designed to expose standard fixed
function hardware, more advanced combining must be done with shaders.
This includes standalone documentation of blend strings covering the aspects
that are common to blending and texture combining, and adds documentation
with examples specific to the new cogl_material_set_blend() and
cogl_material_layer_set_combine() functions.
Note: The hope is to remove the now redundant bits of the material API
before 1.0
The CoglTexture constructors expose the "max-waste" argument for
controlling the maximum amount of wasted areas for slicing or,
if set to -1, disables slicing.
Slicing is really relevant only for large images that are never
repeated, so it's a useful feature only in controlled use cases.
Specifying the amount of wasted area is, on the other hand, just
a way to mess up this feature; 99% the times, you either pull this
number out of thin air, hoping it's right, or you try to do the
right thing and you choose the wrong number anyway.
Instead, we can use the CoglTextureFlags to control whether the
texture should not be sliced (useful for Clutter-GST and for the
texture-from-pixmap actors) and provide a reasonable value for
enabling the slicing ourself. At some point, we might even
provide a way to change the default at compile time or at run time,
for particular platforms.
Since max_waste is gone, the :tile-waste property of ClutterTexture
becomes read-only, and it proxies the cogl_texture_get_max_waste()
function.
Inside Clutter, the only cases where the max_waste argument was
not set to -1 are in the Pango glyph cache (which is a POT texture
anyway) and inside the test cases where we want to force slicing;
for the latter we can create larger textures that will be bigger than
the threshold we set.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Signed-off-by: Robert Bragg <robert@linux.intel.com>
Signed-off-by: Neil Roberts <neil@linux.intel.com>
Before any rendering is done by Cogl it needs to ensure the clip stack
is set up correctly by calling cogl_clip_ensure. This was not being
done for the Cogl vertex buffer so it would still use the clip from
the previous render.
Backface culling is enabled as part of cogl_enable so the different
rendering functions in Cogl need to explicitly opt-in to have backface
culling enabled. Cogl vertex buffers should allow backface culling so
they should check whether it is enabled and then set the appropriate
cogl_enable flag.
Currently, COGL depends on defining debug symbols by manually
modifying the source code. When it's done, it will forcefully
print stuff to the console.
Since COGL has also a pretty, runtime selectable debugging API
we might as well switch everything to it.
In order for this to happen, configure needs a new:
--enable-cogl-debug
command line switch; this will enable COGL debugging, the
CoglHandle debugging and will also turn on the error checking
for each GL operation.
The default setting for the COGL debug defines is off, since
it slows down the GL operations; enabling it for a particular
debug build is trivial, though.
COGL has a debug message system like Clutter's own. In parallel,
it also uses a coupld of #defines. Spread around there are also
calls to printf() instead to the more correct g_log* wrappers.
This commit tries to unify and clean up the macros and the
debug message handling inside COGL to be more consistent.
The code for the conversion of the GL error enumeration code
into a string is not following the code style and conventions
we follow in Clutter and COGL.
The GE() macro is also using fprintf(stderr) directly instead
of using g_warning() -- which is redirectable to an alternative
logging system using the g_log* API.
We use math routines inside Cogl, so it's correct to have it in
the LIBADD line. In normal usage something else was pulling in
-lm, but the introspection is relying on linking against the
convenience library.
Based on a patch by: Colin Walters <walters@verbum.org>
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
The required "fake" libclutter-cogl.la upon with the main clutter
shared object depends is only built with introspection enabled
instead of being built unconditionally.
Passing:
--library=clutter-@CLUTTER_FLAVOUR@-@CLUTTER_API_VERSION@
to g-ir-scanner, when building Cogl was causing g-ir-scanner to
link the introspection program against the installed clutter library,
if it existed or fail otherwise. Instead copy the handling from
the json/ directory where we link against the convenience library
to scan, and do the generation of the typelib later in the
main clutter/directory.
Fixes bug:
http://bugzilla.openedhand.com/show_bug.cgi?id=1594
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Previously clipping could only be specified in object coordinates, now
rectangles can also be pushed in window coordinates.
Internally rectangles pushed this way are intersected and then clipped using
scissoring. We also transparently try to convert rectangles pushed in
object coordinates into window coordinates as we anticipate the scissoring
path will be faster then the clip planes and undoubtably it will be faster
than using the stencil buffer.
COGLenum, COGLint and COGLuint which were simply typedefs for GL{enum,int,uint}
have been removed from the API and replaced with specialised enum typedefs, int
and unsigned int. These were causing problems for generating bindings and also
considered poor style.
The cogl texture filter defines CGL_NEAREST and CGL_LINEAR etc are now replaced
by a namespaced typedef 'CoglTextureFilter' so they should be replaced with
COGL_TEXTURE_FILTER_NEAREST and COGL_TEXTURE_FILTER_LINEAR etc.
The shader type defines CGL_VERTEX_SHADER and CGL_FRAGMENT_SHADER are handled by
a CoglShaderType typedef and should be replaced with COGL_SHADER_TYPE_VERTEX and
COGL_SHADER_TYPE_FRAGMENT.
cogl_shader_get_parameteriv has been replaced by cogl_shader_get_type and
cogl_shader_is_compiled. More getters can be added later if desired.
Commit 43fa38fcf5 broke out-of-tree builds by removing some of the
builddir directories from the include path. builddir/clutter/cogl and
builddir/clutter are needed because cogl.h and cogl-defines-gl.h are
automatically generated by the configure script. The main clutter
headers are in the srcdir so this needs to be in the path too.
When building Clutter with introspection enabled everything stops
at Cogl GIR generation because it depends on the installed library
to work. Since we still require some changes in the API to be able
to build the GIR and the typelib for Cogl we should disable the
generation of the GIR as well.
Currently, the introspection data for Cogl is built right into
Clutter's own typelib. This makes functions like:
cogl_path_round_rectangle()
Appear as:
Clutter.cogl_path_round_rectangle()
It should be possible, instead, to have a Cogl namespace and:
Cogl.path_round_rectangle()
This means building introspection data for Cogl alone. Unfortunately,
there are three types defined in Cogl that confuse the introspection
scanner, and make it impossible to build a typelib:
COGLint
COGLuint
COGLenum
These three types should go away before 1.0, substituted by int,
unsigned int and proper enumeration types. For this reason, we can
just set up the GIR build and wait until the last moment to create
the typelib. Once that has been done, we will be able to safely
remove the Cogl API from the Clutter GIR and typelib and let
people import Cogl if they want to use the Cogl API via introspection.
This is simply a wrapper around cogl_color_set_from_4f and
cogl_material_set_color. We already had a prototype for this, it was
an oversight that it wasn't already implemented.
There were several functions I believe no one is currently using that were
only implemented in the GL backend (cogl_offscreen_blit_region and
cogl_offscreen_blit) that have simply been removed so we have a chance to
think about design later with a real use case.
There was one nonsense function (cogl_offscreen_new_multisample) that
sounded exciting but in all cases it just returned COGL_INVALID_HANDLE
(though at least for GL it checked for multisampling support first!?)
it has also been removed.
The MASK draw buffer type has been removed. If we want to expose color
masking later then I think it at least would be nicer to have the mask be a
property that can be set on any draw buffer.
The cogl_draw_buffer and cogl_{push,pop}_draw_buffer function prototypes
have been moved up into cogl.h since they are for managing global Cogl state
and not for modifying or creating the actual offscreen buffers.
This also documents the API so for example desiphering the semantics of
cogl_offscreen_new_to_texture() should be a bit easier now.
These are necessary if nesting redirections to an fbo,
otherwise there's no way to know how to restore
previous state.
glPushAttrib(GL_COLOR_BUFFER_BIT) would save draw buffer
state, but also saves a lot of other stuff, and
cogl_draw_buffer() relies on knowing about all draw
buffer state changes. So we have to implement a
draw buffer stack ourselves.
Signed-off-by: Robert Bragg <robert@linux.intel.com>
It is valid in some situations to have a material layer with an invalid texture
handle (e.g. if you setup a texture combine mode before setting the texture)
and so _cogl_material_layer_free needs to check for a valid handle before
attempting to unref it.
Adds missing notices, and ensures all the notices are consistent. The Cogl
blurb also now reads:
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
Redundant clearing of depth and stencil buffers every render can be very
expensive, so cogl now gives control over which auxiliary buffers are
cleared.
Note: For now clutter continues to clear the color, depth and stencil buffer
each paint.
In unifying the {gl,gles}/cogl.c code recently, moving most of the code into
common/cogl.c the gmodule.h include was also mistakenly moved.
Thanks to Felix Rabe for reporting this issue.
Note: I haven't tested this fix myself, as I'm not set up to be able to
build for OS X
Buffer objects aren't currently available for glx indirect contexts, so we
now have a fallback that simply allocates fake client side vbos to store the
attributes.
This makes the #if 0'd debug code that was in _cogl_journal_flush_quad_batch
- which we have repeatedly found usefull for debugging various geometry
issues in Clutter apps - a runtime debug option.
The outline colors rotate in order from red to green to blue which can also
help confirm the order that your geometry really drawn.
The outlines are not affected by the current material state, so if you e.g.
have a blending bug where geometry mysteriously disappears this can confirm
if the underlying rectangles are actually being emitted but blending is
causing them to be invisible.
The debug macros for tracking reference counting of CoglHandles had
some typos introduced in c3d9f0 which meant it failed to compile when
COGL_DEBUG is 1.
The cogl_is_* functions were showing up quite high on profiles due to
iterating through arrays of cogl handles.
This does away with all the handle arrays and implements a simple struct
inheritance scheme. All cogl objects now add a CoglHandleObject _parent;
member to their main structures. The base object includes 2 members a.t.m; a
ref_count, and a klass pointer. The klass in turn gives you a type and
virtual function for freeing objects of that type.
Each handle type has a _cogl_##handle_type##_get_type () function
automatically defined which returns a GQuark of the handle type, so now
implementing the cogl_is_* funcs is just a case of comparing with
obj->klass->type.
Another outcome of the re-work is that cogl_handle_{ref,unref} are also much
more efficient, and no longer need extending for each handle type added to
cogl. The cogl_##handle_type##_{ref,unref} functions are now deprecated and
are no longer used internally to Clutter or Cogl. Potentially we can remove
them completely before 1.0.
A layer object may be instantiated when setting a combine mode, but before a
texture is associated. (e.g. this is done by the pango renderer) if this is the
case we shouldn't call cogl_texture_get_format() with an invalid cogl handle.
This patch skips over layers without a texture handle when determining if any
textures have an alpha channel.
The symbol name for cogl_vertex_buffer_draw_elements was wrong so it
ended up with no documentation. The name for the vertex attribute was
incorrect in cogl_vertex_buffer_add.
None of this code directly related to implementing CoglTextures, and the
code was needlessly duplicated between the GL and GLES backends. This moves
the cogl_rectangle* and cogl_polygon* code into common/cogl-primitives.c
makes which makes lot of sense since the two copies keep needlessly
diverging introducing or fixing bugs in one but not the other. For instance
I came accross one such bug regarding the enabling of texture units when
unifying the code.
The gtk-doc had a copy and paste error, saying the float array should be 8
elements per rectangle instead of 4. There was also no newline in the gles
code before the new function.
It's often nice to be able to draw a batch of vertices, even if these
have no texture coordinates. This add a cogl_rectangles, similar to
cogl_rectangles_with_texture_coords, only without.
There are various constraints for when we can support multi-texturing and
when they can't be met we try and print a clear warning explaining why the
operation isn't supported, but we shouldn't endlessly repeat the warning for
every primitive of every frame. This patch fixes that.
This function was renamed a while ago in the .c file from
cogl_vertex_buffer_draw_range_elements but the corresponding .h and
doc/reference/cogl changes weren't made.
For convenience it is now valid to avoid a seperate call to
cogl_vertex_buffer_submit() and assume that the _draw() calls will do this
for you (though of course if you do this you still need to ensure the
attribute pointers remain valid until your draw call.)
_cogl_add_path_to_stencil_buffer and _cogl_add_stencil_clip were leaving
the projection matrix current when calling cogl_rectangle which was
upsetting _cogl_current_matrix_state_flush.
Adds glFrustum wrappers (GLES only accepts floats not doubles, and GLES2
needs to use our internal cogl_wrap_glFrustumf)
Adds GL_TEXTURE_MATRIX getter code in cogl_wrap_glGetFloatv
Adds a GL_TEXTURE_MATRIX define for GLES2
Its not intended that users should use these with any other matrix mode, and
internally we now have the _cogl_current_matrix API if we need to play with
other modes.
If we later add internal flags to CoglMatrix then this code wouldn't
initialize those flags. The ways it's now done adds a redundant copy, but
if that turns out to be something worth optimizing we can look again at
using a cast but adding another way for initializing internal flags.
This is useful because sometimes we need to get the current matrix, which
is too expensive when indirect rendering.
In addition, this virtualization makes it easier to clean up the API in
the future.
The private CoglContext is created using g_malloc() and not
zeroed; this means we have to initialize the values we are
going to check, to avoid hitting garbage.
Thanks to Tommi Komulainen.
The type machinery for CoglFixed should be implemented by COGL
itself, now that COGL exports the GType of its types.
This allows moving most of what ClutterFixed did directly to
CoglFixed where it belongs.
Since the conversion of a floating point value to a fixed point
value is already done in double precision we can safely expose
a macro that converts a double precision floating point value to
a CoglFixed one.
COGL should ship its own pkg-config file, obviously still pointing
to Clutter's compiler flags and linking options, for COGL-specific
variables that might be queried at configure time.
For instance, it's easier (and less verbose) to do:
PKG_CHECK_EXISTS([cogl-gl-1.0],
[has_gl_backend=yes],
[has_gl_backend=no])
Than doing:
AC_MSG_CHECKING([for GL support in COGL])
cogl_backend=`$PKG_CONFIG --variable=cogl clutter-0.9`
if test x$cogl_backend = xgl; then
has_gl_backend=yes
AC_MSG_RESULT([found])
else
has_gl_backend=no
AC_MSG_RESULT([not found])
fi
The CoglPango code falls under the COGL "jurisdiction"; this means
that it cannot include Clutter headers unless strictly necessary.
The CoglPangoRenderer code was using the CLUTTER_NOTE() macro. Now
that COGL has it's own COGL_NOTE() similar macro, CoglPango should
use that and avoid including clutter-debug.h (which pulls in
clutter-private.h which in turn pulls in clutter-actor.h).
A new flag, COGL_DEBUG_PANGO, has been added to the COGL debug
flags.
In the future if we want to annotate matrices with internal flags, and add
caching of the inverse matrix then we need to ensure that all matrix
modifications are done by cogl_matrix API so we'd know when to dirty the
cache or update the flags.
This just adds documentation to that effect, and assuming the most likley
case where someone would try and directly write to matrix members would
probably be to load a constant matrix other than the identity matrix; I
renamed cogl_matrix_init_from_gl_matrix to cogl_matrix_init_from_array to
make it seem more general purpose.
Bug 1473 - CoglPixelFormat enum data must be declared static
When registering an enumeration GType, the GEnumValue or GFlagsValue
arrays must be declared static; otherwise, you get a segmentation
fault when calling the function again.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Clutter is able to show debug messages written using the CLUTTER_NOTE()
macro at runtime, either by using an environment variable:
CLUTTER_DEBUG=...
or by using a command line switch:
--clutter-debug=...
--clutter-no-debug=...
Both are parsed during the initialization process by using the
GOption API.
COGL would benefit from having the same support.
In order to do this, we need a cogl_get_option_group() function in
COGL that sets up a GOptionGroup for COGL and adds a pre-parse hook
that will check the COGL_DEBUG environment variable. The OptionGroup
will also install two command line switches:
--cogl-debug
--cogl-no-debug
With the same semantics of the Clutter ones.
During Clutter initialization, the COGL option group will be attached
to the GOptionContext used to parse the command line options passed
to a Clutter application.
Every debug message written using:
COGL_NOTE (SECTION, "message format", arguments);
Will then be printed only if SECTION was enabled at runtime.
This whole machinery, like the equivalent one in Clutter, depends on
a compile time switch, COGL_ENABLE_DEBUG, which is enabled at the same
time as CLUTTER_ENABLE_DEBUG. Having two different symbols allows
greater granularity.
An assert to verify there was no error when generating a buffer object
for the vertex buffer API was being hit when running the GLES1 conformance
tests.
Bug #1457 - Creating a new texture messes up the cogl material state
cache; reported by Neil Roberts
We still don't have caching of bound texture state so we always have to
re-bind the texture when flushing the GL state of any material layers.
Bug #1460 - Handling of flags in cogl_material_set_color
Cogl automatically enables/disables blending based on whether the source color
has an alhpa < 1.0, or if any textures with an alpha component are in use, but
it wasn't doing it quite right.
At the same time I removed some of the dirty flags which on second thought
are nothing more than micro-optimsations that only helped clutter the code.
thanks to Owen Taylor for reporting the bug
Since the CoglMatrix type was added for supporting texture matrices recently
it made sense to be consistent accross the Cogl API and use the Cogl type
over the GL style GLfloat m[16] arrays.
cogl_wrap_glActiveTexture needs to call the GL version of
glActiveTexture otherwise the subsequent calls to glBindTexture will
all be using texture unit 0. This fixes test-cogl-multitexture.
Previously the texture unit settings were stored in growable GArrays
and every time a new texture unit was encountered it would expand the
arrays. However the array wasn't copied when stored in a
CoglGles2WrapperSettings struct so all settings had the same
array. This meant that it wouldn't detect that a different program is
needed if a texture unit is disabled or enabled.
The texture unit settings arrays are all now a fixed size and the
enabledness of each unit is stored in a bit mask. Therefore the
settings can just be copied around by assignment as before.
This puts a limit on the number of texture units accessible by Cogl
but I think it is worth it to make the code simpler and more
efficient. The material API already poses a limit on the number of
texture units it can use.
COGL types should be registered inside the GType system, for
bindings and type checking inside properties and signals.
CoglHandle is a boxed type with a ref+unref semantics; slightly evil
from a bindings perspective (we cannot associate custom data to it),
but better than nothing.
The rest of the exposed types are enumerations or bitmasks.
The COGL_DEFINE_HANDLE macro generates a cogl_is_<type> function
as well, to check whether a CoglHandle opaque pointer is of type
<type>.
The handle for CoglMaterial does not export cogl_is_material() in
its installed header.
cogl_paint_init was a bit too miscellaneous; it mainly cleared the color, depth
and stencil buffers but arbitrarily it also disabled fogging and lighting.
It no longer disables lighting, since we know Cogl never enables lighting and
disabling of fog is now handled with a seperate function.
Since I noticed cogl_set_fog was taking a density argument documented as
"Ignored" I've also added a mode argument to cogl_set_fog which exposes the
exponential fog modes which can make use of the density.
All GL functions that are defined in a version later than 1.1 need to
be called through cogl_get_proc_address because the Windows GL DLL
does not export them to directly link against.
The main COGL header file is generated at configure time. If something
changes in the template, though, the file will not be regenerated.
Adding cogl.h to the BUILT_SOURCES list will allow the regeneration to
happen.
This hides a number of internal structs and enums from the docs, and moves
some functions to more appropriate sections as well as misc description
updates (mostly for the vertex buffer api)
Fixes some blending issues when using color arrays since we were
conflicting with the cogl_enable state + fixes a texture layer
validation bug.
Adds a basic textured triangle to test-vertex-buffer-contiguous.
When the quad log contains multiple textures (such as when a sliced
texture is drawn) it dispatches the log with multiple calls to
flush_quad_batch and walks a pointer along the list of vertices.
However this pointer was being incremented by only one vertex so the
next quad would be drawn with three of the vertices from the last
quad.
The quad drawing code keeps track of the number of texture units that
have the tex coord array enabled so that in the next call it can
disabled any that are no longer enabled. However it was using 'i+1' as
the count but 'i' is already set to 'n_layers' from the previous for
loop.
Therefore it was disabling an extra texture unit. This doesn't
normally matter but it was causing GLES 2 to pointlessly realize an
extra unit.
- In cogl-material.h it directly sets the values of the
CoglMaterialLayerCombineFunc to some GL_* constants. However these
aren't defined in GLES 2 beacuse it has no fixed function texture
combining. Instead the CGL_* versions are now used. cogl-defines.h
now sets these to either the GL_* version if it is available,
otherwise it directly uses the number.
- Under GLES 2 cogl-material.c needs to access the CoglTexture struct
so it needs to include cogl-texture-private.h
- There are now #define's in cogl-gles2-wrapper.h to remap the GL
function names to the wrapper names. These are disabled in
cogl-gles2-wrapper.c by defining COGL_GLES2_WRAPPER_NO_REMAP.
- Added missing wrappers for glLoadMatrixf and glMaterialfv.
- Renamed the TexEnvf wrapper to TexEnvi because the latter is used
instead from the material API.
Cogl previously tried to cache the currently bound texture when
drawing through the material API to avoid excessive GL calls. However,
a few other places in Cogl and Clutter rebind the texture as well so
this can cause problems.
This was causing shaped windows to fail in Mutter because
ClutterGLXTexturePixmap was binding a different texture to update it
while the second texture unit was still active which meant the mask
texture would not be selected when the shaped window was drawn
subsequent times.
Ideally we would fix this by providing a wrapper around glBindTexture
which would affect the cached value. The cache would also have to be
cleared if a selected texture was deleted.
This tries to make a number of files more comparable with the intention of
moving some code into cogl/common/
Files normalized:
cogl.c
cogl-context.c
cogl-context.h
cogl-texture.c
Someone not sure which cogl_color_set_from_* version is "best" may use
set_from_4d because taking doubles implies higher precision. Currently
it doesn't have any advantage.
This makes it consistent with cogl_rectangle_with_{multi,}texture_coords.
Notably the reason cogl_rectangle_with_{multi,}texture_coords wasn't changed
instead is that the former approach lets you describe back facing rectangles.
(though technically you could pass negative width/height values to achieve
this; it doesn't seem as neat.)
The code is #if 0 guarded, but when uncommented it outlines all drawn
rectangles with an un-blended red, green or blue border. This may e.g. help
with debugging texture slicing issues or blending issues, plus it looks quite
cool.
When drawing a texture with waste in _cogl_multitexture_unsliced_quad
it scales the texture coordinates so that the waste is not
included. However the formula was the wrong way around so it was
calculating as if the texture coordinates are ordered x1,x2,y1,y2 but
it is actually x1,y1,x2,y2.
When the texture is sliced it drops back to a fallback function and
passes it the texture coordinates from the rectangle. However if no
tex coords are given it would crash. Now it passes the default
0.0->1.0 tex coords instead.
If no texture coordinates are given then texture_unsliced_quad tries
to generate its own coordinates. However it also tries to read the
texture coordinates to check if they are in [0.0,1.0] range so it will
crash before it reaches that.
Conflicts:
clutter/cogl/gl/cogl-texture.c
clutter/cogl/gles/cogl-primitives.c
* cogl-material:
clutter-{clone-,}texture weren't updating their material opacity.
Updates GLES1 support for CoglMaterial
Normalizes gl vs gles code in preperation for synching material changes
Removes cogl_blend_func and cogl_alpha_func
Fully integrates CoglMaterial throughout the rest of Cogl
[cogl-material] Restore the GL_TEXTURE_ENV_MODE after material_rectangle
[cogl-material] Make the user_tex_coords parameter of _rectangle const
[test-cogl-material] Remove return value from material_rectangle_paint
Add cogl-material.h and cogl-matrix.h to libclutterinclude_HEADERS
[cogl-material] improvements for cogl_material_rectangle
[cogl-material] Adds a cogl_material_set_color function
[cogl-material] Some improvements for how we sync CoglMaterial state with OpenGL
[cogl-material] Converts clutter-texture/clutter-clone-texture to the material API
[doc] Hooks up cogl-material reference documentation
Updates previous GLES multi-texturing code to use CoglMaterial
Adds a CoglMaterial abstraction, which includes support for multi-texturing
[doc] Hooks up cogl-matrix reference documentation
Adds CoglMatrix utility code
[tests] Adds an interactive unit test for multi-texturing
[multi-texturing] This adds a new cogl_multi_texture API for GL,GLES1 + GLES2
This updates cogl/gles in line with the integration of CoglMaterial throughout
Cogl that has been done for cogl/gl.
Note: This is still buggy, but at least it builds again and test-actors works.
Some GLES2 specific changes were made, but these haven't been tested yet.
This changes all GLES code to use the OpenGL function names instead of
the cogl_wrap_* names. For GLES2 we now define the OpenGL name to point
to the wrapper, as opposed to defining the wrapper to point to the
OpenGL name for GLES1.
I've also done a quick pass through gl/cogl.c and gles/cogl.c to make
them more easily comparable. (most of the code is now identical)
The GL blend function and alpha function are now controlled by the material
code, and even internally Cogl should now be using the material API when
it needs control of these.
This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.
It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions
It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.
"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.
cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.
Most code that previously did:
cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (x, y,....);
In the less likely case where you were blending your source texture with a color
like:
cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
mat = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (mat, 0, tex_handle));
cogl_set_source_material (mat);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.
For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
cogl_set_source_texture (tex_handle);
cogl_polygon (verts, 3, TRUE);
All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.
Note: The GLES backend has not been updated yet; that will be done in a
following commit.
The Cogl primitives broke for GLES 1.1 and 2 after the cogl-float
branch merge.
CoglPathNode was still being declared as GLfixed for the GLES backend
but it was being filled with float values so they were all ending up
as numbers < 1.
glDrawArrays was being called with GL_FIXED so this has been changed
to GL_FLOAT.
The scanline rasterizer had a leftover hardcoded ClutterFixed constant
to add a small amount to the height of each line.
struct _CoglFloatVec2 has been removed because it is no longer used
anywhere.
The maintainer compiler flags we use trigger warnings and errors
in the autogenerated code that gtk-doc creates to scan the header
and source files. Since we cannot control that, and we must run
a distcheck with both --enable-gtk-doc and --enable-maintainer-flags
turned on, we need to use less-strict compiler flags when inside
the doc/reference subdirectories.
The way to do this is to split the maintainer compiler flags into
their own Makefile variable, called MAINTAINER_CFLAGS. The we
can use $(MAINTAINER_CFLAGS) in the INCLUDES or _CFLAGS sections
of each part of the source directories we wish to check with the
anal retentiveness suited for maintainers.
The script converted calls to COGL_FIXED_MUL(x,y) to (x*y). However
this fails for cases like this:
COGL_FIXED_MUL(a + b, c)
which become
(a + b * c)
The meaning of this is of course different because multiplication has
a higher precedence than addition.
This was causing breakages in cogl_texture_quad_sw when the vertex
coordinates are not in increasing order. This was the case in
test-backface-culling when NPOTs are not available.
Improve clutter_sinx() by replacing the low precision CFX_SIN_STEP
with a multiply/divide pair. This reduces the maximum error from
1.8e-04 to 2.4e-05.
http://bugzilla.openedhand.com/show_bug.cgi?id=1314
Based on a patch by Owen W. Taylor <otaylor@fishsoup.net>
Compute the value of the camera distance as exactly half the xx
component of the projection matrix. The heuristically derived
value for 60 degrees was off by about 0.016%, causing noticeable
blurring, and other field of view angles which didn't have the
heuristic adjustment off by much more.
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
Boolean arguments for functions are pretty evil and usually
lead to combinatorial explosion of parameters in case multiple
settings are added.
In the case of the COGL texture constructors we have a boolean
argument for enabling the auto-mipmapping; it is conceivable that
we might want to add more settings for a COGL texture without
breaking API or ABI compatibility, so the boolean argument should
become a bitmask.
The internals have not been changed: instead of checking for
a non-zero value, we check for a bitmask being set.
This better reflects the fact that the api manages sets of vertex attributes,
and the attributes really have no implied form. It is only when you use the
attributes to draw that they become mesh like; when you specify how they should
be interpreted, e.g. as triangle lists or fans etc. This rename frees up the
term "mesh", which can later be applied to a concept slightly more fitting.
E.g. at some point it would be nice to have a higher level abstraction that
sits on top of cogl vertex buffers that adds the concept of faces. (Somthing
like Blender's mesh objects.) There have also been some discussions over
particle engines, and these can be defined in terms of emitter faces; so some
other kind of mesh abstraction might be usefull here.
To deal with all the corner cases that couldn't be scripted a number of patches
were written for the remaining 10% of the effort.
Note: again no API changes were made in Clutter, only in Cogl.
This is the result of running a number of sed and perl scripts over the code to
do 90% of the work in converting from 16.16 fixed to single precision floating
point.
Note: A pristine cogl-fixed.c has been maintained as a standalone utility API
so that applications may still take advantage of fixed point if they
desire for certain optimisations where lower precision may be acceptable.
Note: no API changes were made in Clutter, only in Cogl.
Overview of changes:
- Within clutter/* all usage of the COGL_FIXED_ macros have been changed to use
the CLUTTER_FIXED_ macros.
- Within cogl/* all usage of the COGL_FIXED_ macros have been completly stripped
and expanded into code that works with single precision floats instead.
- Uses of cogl_fixed_* have been replaced with single precision math.h
alternatives.
- Uses of COGL_ANGLE_* and cogl_angle_* have been replaced so we use a float for
angles and math.h replacements.
It looks like the changes to cogl-gles2-wrapper.h were accidentally
committed to the actual file instead of the patch in commit
de27da0e. This commit moves the changes back into the patch so
cogl-gles2-wrapper.h is reverted back to master.
The patches have been updated to apply cleanly.
The patches for the g_warnings in clutter-actor.c have been removed
because master now uses CLUTTER_UNITS_FORMAT so they aren't
necessary. The clutter-units.h patch now sets CLUTTER_UNITS_FORMAT to
'f'.
The changes from the GL version of cogl-texture.c have been mirrored
in the GLES version. This adds the cogl_texture_new_from_bitmap
function and fixes the build errors.
* async-textures:
Whitespace fixes in ClutterTexture
[async-loading] Do not force the texture size on async load
[async-loading] Update asynchronous image loading
Add API for extracting image size from a file
Update/clean and apply the async-texture patch from bug #1144
The GLES 2 wrapper needs to set up some state before each
draw. Previously this was acheived by wrapping glDrawArrays. Since the
multiple-texture-rectangle branch merge, glDrawElements is used
instead so we also need a wrapper for that.
It was also directly calling glBindTexture. GLES 2 uses a wrapper for
this function so that it can cope with GL_ALPHA format textures. The
format of the current texture needs to be stored as well as the target
and object number for this to work.
For the asynchronous loading we need a function call that parses
a file, given its path, and retrieves the image width and height.
This commit adds cogl_bitmap_get_size_from_file() to the CoglBitmap
API.
Bug 1289 - Draw multiple glyphs at once
The multiple-texture-rectangle branch adds a new Cogl texture function
called cogl_texture_multiple_rectangles which is used to draw multiple
rectangles out of a texture using a single GL call. This is
significantly faster than drawing the rectangles with individual calls
on some platforms. The Pango renderer now uses this to speed up
rendering.
The conflicts are just due to the whitespace fixes in cb569a5.
Conflicts:
clutter/cogl/gl/cogl-context.c
clutter/cogl/gl/cogl-context.h
clutter/cogl/gl/cogl-texture.c
The rest of Cogl expects the texture mode to be GL_MODULATE so it
needs to be restored after calling cogl_material_rectangle. Otherwise
cogl_texture_rectangle will fail to blend with the Cogl color properly
and all of the labels will be black.
The API has been changed to take an explicit length for the number of
texture coordinates passed, and it's now documented that if there are
more layers to the current material than the number of texture coords
passed, then default coordinates will be generated for the other
layers.
cogl_material_rectangle should now handle the case where a single
sliced texture is supplied as a material layer by falling back to
cogl_texture_rectangle. We are nearly at the point that
cogl_texture_rectangle could be deprecated. A few issues remain
though, such as not considering waste in cogl_material_rectangle.
The other colors of a material; such as the ambient and diffuse color are
only relevent when we can enable lighting. This adds a basic unlit
color property.
Later cogl_set_source_color can be integrated to either modify the color
of the current source material, or maintain a special singlton CoglMaterial
that is modified by calls to cogl_set_source_color and implicitly made
current.
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.
Removed trailing white space from the following files:
- clutter-clone-texture.c
- clutter-texture.c
- clutter-texture.h
- cogl/cogl-texture.h
- cogl/gl/cogl-context.c
- cogl/gl/cogl-texture.c
- cogl/gl/cogl-context.h
test-cogl-material now runs on GLES 1 using the PVR GLES1 SDK (though since
only 2 texture units are supported the third rotating light map doesn't show)
Note: It currently doesn't build for GLES 2.0
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.