A change to a layer is also going to be a change to its owning material
so we have to chain up in _cogl_material_layer_pre_change_notify and
call _cogl_material_pre_change_notify. Previously we were only
considering if the owning material was referenced in the journal but
that ignores that it might also have dependants. We no longer need to
flush the journal directly in layer_pre_change_notify.
In _cogl_material_layer_pre_change_notify when we see that a layer has
dependants and it can't be modified directly then we allocate a new
layer. In this case we also have to link the new layer to its required
owner. If the immutable layer we copied had the same owner though we
weren't unlinking that old layer.
In _cogl_material_pre_change_notify we need to identify if it's a sparse
property being changed and if so initialize the state group if the given
material isn't currently the authority for it.
Previously we were unconditionally calling
_cogl_material_initialize_state which would e.g. NULL the layer
differences list of a material each time a layer change was notified.
It would also call _cogl_material_initialize_state for non-sparse
properties which should always be valid at this point so the function
has been renamed to _cogl_material_initialize_sparse_state to make this
clearer with a corresponding g_return_if_fail check.
This fixes how we copy layer differences in
_cogl_material_copy_layer_differences.
We were making a redundant g_list_copy of the src differences and then
iterating the src list calling _cogl_material_add_layer_difference for
each entry which would double the list length, but the initial copy
directly referenced the original layers which wasn't correct.
Also we were initializing dest->n_layers before copying the layer
differences but the act of copying the differences will re-initialize
n_layers to 0 when adding the first layer_difference since it will
trigger a layer_pre_change_notify and since the dest material isn't yet
a STATE_LAYERS authority the state group is initialized before allowing
the change.
In _cogl_material_texture_storage_change_notify we were potentially
dereferencing layer->texture without checking first that it is the
authority of texture state. We now use
_cogl_material_layer_get_texture() instead.
This improve the dot file output available when calling
_cogl_debug_dump_materials_dot_file. The material graph now directly
points into the layer graph and the layers now show the texture unit
index.
When the texture is set on a layer so that it is back to the parent's
texture it would clear the texture change flag but it wouldn't unref
the texture. The free function for a material layer does not unref the
texture if the change flag is cleared so the texture would end up
leaking. This happens for ClutterTexture because it disposes the
texture by setting layer 0 of the material to COGL_INVALID_HANDLE
which ends up the same as the default material.
In _cogl_material_layer_pre_paint we were mistakenly dereferencing the
layer->texture member for the passed layer instead of dereferencing the
texture state authority which was causing crashes in some cases.
* elliot/cookbook-animations-rotating:
cookbook: Added recipe for animated rotation of an actor
cookbook: Add explanation about including code samples
cookbook: Make filename used in video example consistent
cookbook: Add example code for animated rotation
This makes the gles2 cogl_program_use consistent with the GL version by
not binding the program immediately and instead leaving it to
cogl-material.c to bind the program when actually drawing something.
Previously custom uniforms were tracked in _CoglGles2Wrapper but as part
of a process to consolidate the gl/gles2 shader code it seems to make
sense for this state to be tracked in the CoglProgram object instead.
http://bugzilla.o-hand.com/show_bug.cgi?id=2179
Instead of having to query GL and translate the GL enum into a
CoglShaderType each time cogl_shader_get_type is called we now keep
track of the type in CoglShader.
Nothing was storing the shader type when a shader was created so it
would get confused about whether it was a custom vertex or fragment
shader.
Also the 'type' member of CoglShader was a GLenum but the only place
that read it was treating it as if it was CoglShaderType. This changes
it be CoglShaderType.
When loading an RGB image GdkPixbuf will pad the rowstride so that the
beginning of each row is aligned to 4 bytes. This was causing us to
fallback to the code that copies the buffer. It is probably safe to
avoid copying the buffer if we can detect that the rowstride is simply
an alignment of the packed rowstride.
This also changes the copying fallback code so that it uses the
aligned rowstride. However it is now extremely unlikely that the
fallback code would ever be used.
In commit b780413e5a the GdkPixbuf loading code was changed so that
if it needs to copy the pixbuf then it would tightly pack it. However
it was still using the rowstride from the pixbuf so the image would
end up skewed. This fixes it to use the real rowstride.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2235
In OpenGL the 'shininess' lighting parameter is floating point value
limited to the range 0.0→128.0. This number is used to affect the size
of the specular highlight. Cogl materials used to only accept a number
between 0.0 and 1.0 which then gets multiplied by 128.0 before sending
to GL. I think the assumption was that this is just a weird GL quirk
so we don't expose it. However the value is used as an exponent to
raise the attenuation to a power so there is no conceptual limit to
the value.
This removes the mapping and changes some of the documentation.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2222
When flushing a fixed-function or arbfp material it would always call
disable_glsl to try to get rid of the previous GLSL shader. This is
needed even if current_use_program_type is not GLSL because if an
application calls cogl_program_uniform then Cogl will have to bind the
program to set the uniform. If this happens then it won't update
current_use_program_type presumably because the enabled state of arbfp
is still valid.
The problem was that disable_glsl would only select program zero when
the current_use_program_type is set to GLSL which wouldn't be the case
if cogl_program_uniform was called. This patch changes it to just
directly call _cogl_gl_use_program_wrapper(0) instead of having a
separate disable_glsl function. The current program is cached in the
cogl context anyway so it shouldn't cause any extra unnecessary GL
calls.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2232
g_ascii_dtostr was being used in four separate arguments to
g_string_append_printf but all invocations of it were using the same
buffer. This would end up with all of the arguments having the same
value which would depend on whichever order the compiler evaluates
them in. This patches changes it to use a multi-dimensional array and
a loop to fill in the separate buffers.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2219
The ARBfp programs are created with a printf() wrapper, which usually
fails in non-en locales as soon as you start throwing things like
floating point values in the mix.
We should use the g_ascii_dtostr() function which places a double into a
string buffer in a locale-independent way.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2219
* elliot/cookbook-include-videos:
cookbook: Tweak so that videos sit inside a paragraph for better spacing
docs: Note the P_() macro in the HACKING file
cookbook: Added support for inline video
Conflicts:
doc/cookbook/Makefile.am
This function creates a CoglBitmap which internally references a
CoglBuffer. The map and unmap functions will divert to mapping the
buffer. There are also now bind and unbind functions which should be
used instead of map and unmap whenever the data doesn't need to be
read from the CPU but will instead be passed to GL for packing or
unpacking. For bitmaps created from buffers this just binds the
bitmap.
cogl_texture_new_from_buffer now just uses this function to wrap the
buffer in a bitmap rather than trying to bind the buffer
immediately. This means that the buffer will be bound only at the
point right before the texture data is uploaded.
This approach means that using a pixel array will take the fastest
upload route if possible, but can still fallback to copying the data
by mapping the buffer if some conversion is needed. Previously it
would just crash in this case because the texture functions were all
passed a NULL pointer.
http://bugzilla.clutter-project.org/show_bug.cgi?id=2112
The docs for GdkPixbuf say that the last row of the image won't
necessarily be allocated to the size of the full rowstride. The rest
of Cogl and possibly GL assumes that we can copy the bitmap with
memcpy(height*rowstride) so we previously would copy the pixbuf data
to ensure this. However if the rowstride is the same as bpp*width then
there is no way for the last row to be under-allocated so in this case
we can just directly upload from the gdk pixbuf. Now that CoglBitmap
can be created with a destroy function we can make it keep a reference
to the pixbuf and unref it during its destroy callback. GdkPixbuf
seems to always pack the image with no padding between rows even if it
is RGB so this should end up always avoiding the memcpy.
The fallback code for when we do have to copy the pixbuf is now
simplified so that it copies all of the rows in a single loop. We only
copy the useful region of each row so this should be safe. The
rowstride of the CoglBitmap is now always allocated to bpp*width
regardless of the rowstride of the pixbuf.
The CoglBitmap struct is now only defined within cogl-bitmap.c so that
all of its members can now only be accessed with accessor
functions. To get to the data pointer for the bitmap image you must
first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map
function takes the same arguments as cogl_pixel_array_map so that
eventually we can make a bitmap optionally internally divert to a
pixel array.
There is a _cogl_bitmap_new_from_data function which constructs a new
bitmap object and takes ownership of the data pointer. The function
gets passed a destroy callback which gets called when the bitmap is
freed. This is similar to how gdk_pixbuf_new_from_data
works. Alternatively NULL can be passed for the destroy function which
means that the caller will manage the life of the pointer (but must
guarantee that it stays alive at least until the bitmap is
freed). This mechanism is used instead of the old approach of creating
a CoglBitmap struct on the stack and manually filling in the
members. It could also later be used to create a CoglBitmap that owns
a GdkPixbuf ref so that we don't necessarily have to copy the
GdkPixbuf data when converting to a bitmap.
There is also _cogl_bitmap_new_shared. This creates a bitmap using a
reference to another CoglBitmap for the data. This is a bit of a hack
but it is needed by the atlas texture backend which wants to divert
the set_region virtual to another texture but it needs to override the
format of the bitmap to ignore the premult flag.
The 'format' member of CoglTexture2DSliced is returned by
cogl_texture_get_format. All of the other backends return the internal
format of the GL texture in this case. However the sliced backend was
returning the format of the image data used to create the texture. It
doesn't make any sense to retain this information because it doesn't
necessarily indicate the format of the actual texture. This patch
changes it to store the internal format instead.
In ddb9016be4 the GL texture driver backend was changed to include
cogl-material-opengl-private.h instead of cogl-material-private.h.
However the gles texture backend was missed from this so it was giving
a compiler warning about using an undeclared function.
glTexSubImage3D was being called directly in cogl-texture-3d.c but the
function is only available since GL version 1.2 so on Windows it won't
be possible to directly link to it. Also under GLES it is only
available conditionally in an extension.
In ddb9016be4 the texture backends were changed to include
cogl-material-opengl-private.h instead of cogl-material-private.h.
However the 3D texture backend was missed from this so it was giving a
compiler warning about using an undeclared function.
This moves the code supporting _cogl_material_flush_gl_state into
cogl-material-opengl.c as part of an effort to reduce the size of
cogl-material.c to keep it manageable.
In general cogl-material.c has become far to large to manage in one
source file. As one of the ways to try and break it down this patch
starts to move some of lower level texture unit state management out
into cogl-material-opengl.c. The naming is such because the plan is to
follow up and migrate the very GL specific state flushing code into the
same file.
When the support for redirecting the legacy fog state through cogl
material was added in 9b9e764dc, the code to handle copying the fog
state in _cogl_material_copy_differences was missed.
The CoglTexture2DSliced backend has a fallback for when the
framebuffer extension is missing so it's not possible to use
glGenerateMipmap. This involves keeping a copy of the upper-left pixel
of the tex image so that we can temporarily enable GL_GENERATE_MIPMAP
on the texture object and do a sub texture update by reuploading the
contents of the first pixel. This patch copies that mechanism to the
2D and 3D backends. The CoglTexturePixel structure which was
previously internal to the sliced backend has been moved to
cogl-texture-private.h so that it can be shared.
* wip/xkb-support:
x11: Use XKB to translate keycodes into key symbols
x11: Use XKB to track the Locks state
x11: Use XKB detectable auto-repeat
x11: Add a Keymap ancillary object
x11: Store the group inside the event platform data
events: Add platform-data to allocated Events
build: Check for the XKB extension
Using 'r' to name the third component is problematic because that is
commonly used to represent the red component of a vector representing
a color. Under GLSL this is awkward because the texture swizzling for
a vector uses a single letter for each component and the names for
colors, textures and positions are synonymous. GLSL works around this
by naming the components of the texture s, t, p and q. Cogl already
effectively already exposes this naming because it exposes GLSL so it
makes sense to use that naming consistently. Another alternative could
be u, v and w. This is what Blender and Direct3D use. However the w
component conflicts with the w component of a position vertex.
This adds a publicly exposed experimental API for a 3D texture
backend. There is a feature flag which can be checked for whether 3D
textures are supported. Although we require OpenGL 1.2 which has 3D
textures in core, GLES only provides them through an extension so the
feature can be used to detect that.
The textures can be created with one of two new API functions :-
cogl_texture_3d_new_with_size
and
cogl_texture_3d_new_from_data
There is also internally a new_from_bitmap function. new_from_data is
implemented in terms of this function.
The two constructors are effectively the only way to upload data to a
3D texture. It does not work to call glTexImage2D with the
GL_TEXTURE_3D target so the virtual for cogl_texture_set_region does
nothing. It would be possible to make cogl_texture_get_data do
something sensible like returning all of the images as a single long
image but this is not currently implemented and instead the virtual
just always fails. We may want to add API specific to the 3D texture
backend to get and set a sub region of the texture.
All of those three functions can throw a GError. This will happen if
the GPU does not support 3D textures or it does not support NPOTs and
an NPOT size is requested. It will also fail if the FBO extension is
not supported and the COGL_TEXTURE_NO_AUTO_MIPMAP flag is not
given. This could be avoided by copying the code for the
GL_GENERATE_MIPMAP TexParameter fallback, but in the interests of
keeping the code simple this is not yet done.
This adds a couple of functions to cogl-texture-driver for uploading
3D data and querying the 3D proxy
texture. prep_gl_for_pixels_upload_full now also takes sets the
GL_UNPACK_IMAGE_HEIGHT parameter so that 3D textures can have padding
between the images. Whenever 3D texture is uploading, both the height
of the images and the height of all of the data is specified (either
explicitly or implicilty from the CoglBitmap) so that the image height
can be deduced by dividing by the depth.
Under big GL, glext.h is included automatically by gl.h. However under
GLES this doesn't appear to happen so it has to be included explicitly
to get the defines for extensions. This patch changes the
clutter_gl_header to be called cogl_gl_headers and it can now take a
space seperated list of multiple headers. This is then later converted
to a list of #include lines which ends up cogl-defines.h. The gles2
and gles1 backends now add their respective ext header to this list.
There are many places in the texture backend that need to do
conversion using the CoglBitmap code. Currently none of these
functions can throw an error but they do return a value to indicate
failure. In future it would make sense if new texture functions could
throw an error and in that case they would want to use a CoglBitmap
error if the failure was due to the conversion. This moves the
internal CoglBitmap error from the quartz backend to be public in
cogl-bitmap.h so that it can be used in this way.
We can use this error in more unsupported situations than just when we
have a Cogl feature flag for the error. For example if a non-sliced
texture is created with dimensions that are too large then we could
throw this error. Therefore it seems good to rename to something more
general.
Previously when comparing whether the settings for a layer are equal
it would only check if one of them was enabled. If so then it would
assume the other one was enabled and continue to compare the texture
environment. Now it also checks whether the enabledness differs.