According to the GLES1/2 spec, the transpose argument of
glUniformMatrix* should always be FALSE. Cogl directly exposes the
transposedness of the uniform value in
cogl_pipeline_set_uniform_matrix and we were previously passing this
value on to GL. This patch makes it instead just always transpose the
matrix in Cogl itself when copying the value to the CoglBoxedValue. It
doesn't seem like there could be much advantage to letting GL
transpose the uniform value and at least Mesa just does a very similar
loop to handle the transpose.
Mesa has started being more pedantic about this which was making
test_pipeline_uniforms fail.
http://cgit.freedesktop.org/mesa/mesa/commit/?id=60e8a4944081b42127b3
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit f42ee670ff663d03073d6b1038b21a0aa1b3ec2b)
Comments are interpreted as docbook snippets and <pre> is from html. The
closest maching tag for inline content seems to be <literal>.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 66c9f26dfb3133f43d319128d6636f793a1ceb4a)
The first argument has been removed from the function. Update the
example accordingly.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 06e47af3144565bdf85abf8ae561c7ceeafa2cbc)
Contrary to the other inversion functions, invert_matrix_3d() does not
initialize the inverse to the identity and then only touches the
elements it cares about. Problem is the ww component is left alone,
which makes everything go to a black hole when using an inverse matrix
as the transform matrix of a framebuffer.
This is how cameras are typically implemented, they have a transform
and the framebuffer matrix stack is initialized with the inverse
of that transform. A gdb session gives away what happens:
The camera model view matrix, slightly rotation around the X axis:
camera mv 1.000000 0.000000 0.000000 0.000000
camera mv 0.000000 0.984808 -0.173648 0.000000
camera mv 0.000000 0.173648 0.984808 10.000000
camera mv 0.000000 0.000000 0.000000 1.000000
Breakpoint 5, invert_matrix_3d (matrix=0x8056b58) at ./cogl-matrix.c:671
671 const float *in = (float *)matrix;
(gdb) p *matrix
$1 = {xx = 1, yx = 0, zx = 0, wx = 0, xy = 0, yy = 0.98480773,
zy = 0.173648164, wy = 0, xz = 0, yz = -0.173648164, zz = 0.98480773,
wz = 0, xw = 0, yw = 0, zw = 10, ww = 1, inv = {0 <repeats 16 times>},
type = 6, flags = 1030, _padding3 = 0}
(gdb) finish
Run till exit from #0 invert_matrix_3d (matrix=0x8056b58)
at ./cogl-matrix.c:671
0x00141ced in _cogl_matrix_update_inverse (matrix=0x8056b58)
at ./cogl-matrix.c:1123
1123 if (inv_mat_tab[matrix->type](matrix))
Value returned is $2 = 1
(gdb) p *matrix
$3 = {xx = 1, yx = 0, zx = 0, wx = 0, xy = 0, yy = 0.98480773,
zy = 0.173648164, wy = 0, xz = 0, yz = -0.173648164, zz = 0.98480773,
wz = 0, xw = 0, yw = 0, zw = 10, ww = 1, inv = {1, 0, 0, 0, 0, 0.98480773,
-0.173648164, 0, 0, 0.173648164, 0.98480773, 0, -0, -1.73648167,
-9.84807777, 0}, type = 6, flags = 1030, _padding3 = 0}
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 9a19ea0147eb316247c45cbba6bb70dec5b9be4c)
Some drivers have good support for GLSL but don't have the complete
set of features needed to advertise GL 2.0 support. We should accept
the three old GLSL extensions (GL_ARB_shader_objects,
GL_ARB_vertex_shader and GL_ARB_fragment_shader) to support shaders on
these drivers.
This patch splits the shader functions into four sections :- those
that are provided only in GL 2.0, those that have the same name in the
shader objects extension, those that are provided by the vertex
shader extension (they all share the same name) and those that have a
different name in the shader objects extension.
If GL 2.0 is not supported but all three of the extensions are then
the pointers to the GL2-only functions will be replaced to point to
the equivalent functions from the extensions. That way the rest of the
Cogl source doesn't have to worry about the name differences.
https://bugzilla.gnome.org/show_bug.cgi?id=677078
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 71ecb51bd20dc3053b4221961b57e5a2b1029bdf)
If cogl_pipeline_remove_layer is called on a copied pipeline to remove
a parent layer then it will still end up calling
_cogl_pipeline_remove_layer_difference on the layer. This function
was directly trying to remove the layer from the pipeline's list of
layer differences. However in the child pipeline the layer isn't in
the list because it is unchanged from its parent. The function had an
assertion to verify that this situation wasn't hit so in a debug build
it would just bail out.
This patch removes the assertion and changes it to only remove the
layer if it is owned by the pipeline. Otherwise it just sets the
COGL_PIPELINE_STATE_LAYERS difference as normal and decrements the
number of layers. This will cause it to successfully remove the layer
because either it is the last layer in which case it will be ignored
after n_layers is decreased or if it is in the middle of the list then
the subsequent layers will all be shifted down so there will be a
replacement layer difference.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 88e73dd93fa09a158064a946ab229591a5888b97)
This adds an alternate version of the SDL winsys using the SDL 2 API.
The two versions are mutually exclusive and share the same
CoglWinsysID. Version 2 of SDL fits a little bit better with Cogl
because it supports multiple windows and the video subsystem can be
initialised entirely independently of the rest of the subsystems.
The SDL2 winsys creates an invisible dummy window in order to bind the
GL context after creating the Cogl display. This is similar to how the
X11 winsys's work.
SDL2 seems to support compiling with support for both GL and GLES.
However there doesn't seem to be a way to select between the two
backends outside of SDL. In fact if you do compile them both in it
seems to break down because it will always try to use the window
system functions from the GLES backend because those are filled in
second in the vtable. However when creating the window it will always
prefer to use the GL function to choose a visual. This function gets
confused because the GL backend has not been initialised at that
point. The Cogl backend therefore just leaves it up to SDL to pick a
sensible backend. It will then verify that it picked a GL library
which matches the Cogl driver by checking the string from
glGetString(GL_VERSION).
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 6cb5ab41355e7bfe28f367cf4afa39a7afcfeec2)
When having the [0, 0, 0] vector, normalize() won't try to divide by 0
and thus it's always safe to use that funtion.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 64370e7ddd32f25556a1792c00d14adc48a81d45)
Until now, we hardcoded the internal format to GL_RGBA and used the
internal format returned by pixel_format_to_gl() as the format for
checking the texture size and format we're asked to create.
Let's use the proper internal format/format from now on.
This is needed as a later patch introduces DEPTH and DEPTH_STENCIL
textures.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit ec45f60ee2545f88302da314bcdbe1439c4ba9c9)
Missing bit of 4bb6eff3dbd50d8fef7d6bdbed55c5aaa70036a8
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 1674cf28f1f5b71bd25a1f253c99825d427dd243)
The y translation was being initialised with the z value and the z
translation was being left as 0.0.
(cherry picked from commit b44feb617ecb9cbf7d53f0d745f686c17ef3246d)
When rendering the debug wireframe Cogl generates a child pipeline of
the application's pipeline to replace the fragment processing.
Previously it was creating a new snippet every time something was
drawn. Cogl doesn't attempt to compare the contents of snippets when
looking in the program cache for a matching pipeline so this would
cause it to generate a new program for every primitive. It then quite
quickly ends printing the warning about there being more than 50
programs in the cache. To fix that this patch makes it cache the
snippet so that Cogl can successfully recognise that it already has a
program generated for the new pipeline.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit c4bb08ee8767b5320980dba10b20921393cb5613)
Previously the CoglDrawFlags passed to
_cogl_framebuffer_draw_indexed_attributes when drawing is redirected
to draw a wireframe are overriden to avoid validating the pipeline,
flushing the framebuffer state and flushing the journal. This ends up
breaking scenes that only contain models drawn from attributes in the
application because nothing will flush the matrices. It seems to make
more sense to just use whatever draw flags were passed from the
original draw command so that it will flush the matrices if the caller
was expecting it.
One problem with this is that if the wireframe causes the journal to
be flushed then it will already have temporarily disabled the
wireframe debug flag so the journal will not be drawn with wireframes.
To fix this the patch adds a CoglDrawFlag to disable the wireframe and
uses that instead of disabling the debug flag.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 283f6733e63ba65d9921f45868edaabbd9420a61)
Previously if an application does not use the matrix stack as a stack
but instead just loads its own matrices for each frame using
cogl_framebuffer_set_modelview_matrix then it will continously push
OP_LOAD entries on the stack and the stack will grow forever. This
patch fixes that use case by resetting the top of the stack to the
last save entry whenever something is pushed that replaces the
previous matrix on the stack.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit d31ed33241a9e9e3bc25f01b2614678827a7a9aa)
This adds the following new functions to apply a rotation described by
a euler or a quaternion to either a CoglMatrix or directly to the
modelview stack of a framebuffer:
cogl_matrix_rotate_quaternion
cogl_matrix_rotate_euler
cogl_framebuffer_rotate_quaternion
cogl_framebuffer_rotate_euler
The direct framebuffer functions have corresponding functions in the
CoglMatrixStack to store an entry describing the rotation.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 5064315678b496395e1d01f266f322d73e55e324)
The _cogl_matrix_entry_equal function has a large switch statement to
do the right kind of comparison for the entry. However most of the
entries have a return statement that is only conditionally reached.
There were no corresponding break statements to the case labels so
presumably if the comparison succeeded for the correct entry type it
would also flow through and try the comparison for the next type which
would be extremely unlikely to pass.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 339db0f9cc3ee2bee4c56f9cb05dcb4ddd6815ed)
This creates a matrix to represent the given euler rotation. This
should be more efficient than creating the matrix by doing three
separate rotations because no separate intermediate matrices are
created and no matrix multiplication is needed.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit e66d9965897999a4889063f6df9a20ea6abf97fe)
The quaternion is not modified so for consistency with the rest of the
API it should probably be const.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 7fa8c05c2ffb90cba03289a04e37866efc0890a5)
The documentation for cogl_quaternion_init_from_array contradicts
itself and says that the array is w,x,y,z in one part but x,y,z,w in
another. This fixes it to say w,x,y,z in both parts.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit b08a81e5dfb05fec867c08c689237fae937341ad)
When --disable-debug is passed to the configure script it was actually
still defining COGL_ENABLE_DEBUG so very little would end up being
disabled. If COGL_ENABLE_DEBUG actually got defined it would also fail
to compile because _cogl_debug_instances and COGL_DEBUG_N_LONGS from
cogl-debug.h were only defined if debugging is enabled but they are
used regardless.
This patch also makes it so that the _COGL_RETURN_IF_FAIL family of
macros that are used when glib support is disabled are now disabled if
debugging is disabled. When the glib macros are used they are already
disabled because we additionally define G_DISABLE_CHECKS.
'COGL_HANDLE_DEBUG' has been removed from the list of defines passed
when debugging is enabled because CoglHandle has already been removed
and it is not used anywhere in the code.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 9811a0101c9cbb4ab95c55a2b41fd10ff4c77d9f)
This adds a new renderer constraint enum:
COGL_RENDERER_CONSTRAINT_SUPPORTS_GLES2_CONTEXT
that can be used by applications to ensure the renderer they connect to
has support for creating a GLES2 context via cogl_gles2_context_new().
The cogl-gles2-context and cogl-gles2-gears examples and the conformance
tests have been updated to use this constraint.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit ed61463d7194354b26624e8014859f0fbfc06a12)
This adds a library that can be used instead of libGLESv2.so to provide
symbols for the GLES 2.0 api. This can be used for convenience when
using the cogl_gles2_context_ api since you don't need to manually go
through a CoglGLES2Vtable when calling the gles2 api so it should be
easier to port existing gles2 code to integrate with Cogl.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 80d7599a2acefca7d01d8d7de9df524278ef72c5)
This makes it possible to integrate existing GLES2 code with
applications using Cogl as the rendering api.
Currently all GLES2 usage is handled with separate GLES2 contexts to
ensure that GLES2 api usage doesn't interfere with Cogl's own use of
OpenGL[ES]. The api has been designed though so we can provide tighter
integration later.
The api would allow us to support GLES2 virtualized on top of an
OpenGL/GLX driver as well as GLES2 virtualized on the core rendering api
of Cogl itself. Virtualizing the GLES2 support on Cogl will allow us to
take advantage of Cogl debugging facilities as well as let us optimize
the cost of allocating multiple GLES2 contexts and switching between
them which can both be very expensive with many drivers.
As as a side effect of this patch Cogl can also now be used as a
portable window system binding API for GLES2 as an alternative to EGL.
Parts of this patch are based on work done by Tomeu Vizoso
<tomeu.vizoso@collabora.com> who did the first iteration of adding GLES2
API support to Cogl so that WebGL support could be added to
webkit-clutter.
This patch adds a very minimal cogl-gles2-context example that shows how
to create a gles2 context, clear the screen to a random color and also
draw a triangle with the cogl api.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 4bb6eff3dbd50d8fef7d6bdbed55c5aaa70036a8)
This fixes a bug in _cogl_pipeline_flush_color_blend_alpha_depth_state
whereby we were only calling flush_depth_state if we knew that at least
depth testing was enabled. This didn't take into account that enabling
and disabling depth writing is a useful change to make even if depth
testing is disabled. It also seemed a bit messy to flush the
depth-testing enable separately from the other depth state.
_cogl_pipeline_flush_color_blend_alpha_depth_state now simply calls
flush_depth_state() if there is a _DEPTH_STATE difference and
flush_depth_state() also handles flushing the depth-testing enable
in along with all the other depth state.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 6a9dfc55b8f55d7023cb592e5bef2118d0f3d50c)
This ensures that when we initialize a CoglOnscreenTemplate that
->swap_throttled is set to TRUE so by default Cogl applications should
have their swap buffer requests throttled to the vblank frequency.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit bdac9ab56284fb84ec09af176c7e31c44dc1bfc6)
This detects when we are running on any of Mesa's software rasterizer
backends and disables use of glBlitFramebuffer and glXCopySubBuffer.
Both of these currently result in full-screen copies so there's little
point in using these to optimize how much of the screen we present.
To help ensure we re-evaluate this workaround periodically we have added
a comment marker of "ONGOING BUG" above the workaround and added a note
to our RELEASING document that says we should grep for this marker and
write a NEWS section about ongoing bug workarounds.
https://bugzilla.gnome.org/show_bug.cgi?id=674208
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 11f2f6ebb42398978ec8dd92b3c332ae8140a728)
The GPU info api previously told us a driver package name and a driver
vendor name, but now we have introduced detection for the gpu
architecture too and started to track architecture feature flags that
can tell us whether a gpu is a deferred or immediate mode renderer for
example or if a software rasterizer is being used.
This also adds support for checking more vendor names. We should now
detect the following cases:
Vendors: Intel, Imagination Technologies, ARM, Qualcomm, Nvidia, ATI
Architectures: Sandybridge, SGX, Mali
Architecture flags:
- vertex tiled
- vertex immediate mode
- vertex software
- fragment deferred
- fragment immediate mode
- fragment software
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit b3803a0a7c9e663ed219e83626841895c7d95ad7)
There are numerous APIs added/removed in the following commits:
e7f15826 Add a CoglPrimitiveTexture interface
6197e3ab Add constructors which take a CoglBitmap to all primitive textures
bdb645e7 kms: defer setting crtc modes until first swap buffers
9a1f1df8 Rework sdl integration api
ac0c72ab Removed legacy cogl-fixed 1.x api
e8c4c80c Remove deprecated cogl_vertex_buffer api
06d522cb Remove the legacy CoglPath API
713a8f81 Replace cogl_path_{stroke,fill} with framebuffer API
6ed3aaf4 Removes all remaining use of CoglHandle
068b3b59 matrix: Add a init_translation() constructor
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 2625354b8accaebe33ee2747ff03f665aea07e4f)
-Create a pre-defined cogl/cogl-gl-header.h(.win32) that is to be used on
any Windows builds, and adapt the MSVC build process to set up and use
that file.
-Fix up glib-mkenums code generation .bat file that is generated during
"make"/"make dist", like the autotools-based builds.
-Since cogl/cogl-defines.h now contain versionioning info, and it no longer
directly includes the GL headers, update the pre-configured
cogl-defines.h[.win32|.win32_SDL] and use autotools to fill in the
versioning info during "make"/"make dist".
-Fix up cogl/cogl-pango.rc.in so that they reflect the cogl-2.x versioning
stuff correctly and versioning info can be filled in correctly during
"make"/"make dist"
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 7ff42bb1c5280b0f53370f8d94ef5f10c9f39e2f)
Clearly from a copy and paste from init_from_y_rotation().
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 2f06f4d79e29bbf30a44edbf48e8eaa637e30930)
Several little changes were needed to make the CoglEuler documentation
appear:
• Fix the embeded docbook snippet in the CoglEuler section header
• Add the xinclude directive to the main document
• Add the missing <SECTION> in -sections.txt
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit c7f6e07f7b8ba0d7dc9604e888c8a46165ec3ed4)
This allows people to initialize a matrix with a translation
transformation. The options to do it at the moment were:
* init_from_array() but it give cogl no information about the type of
matrix.
* init_indentity() and then translate() but it means doing a lot of
computations for no reason.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 068b3b59221e405dc288d434b0008464684a7c12)
The stock 1.2.x version of SDL only supports regular OpenGL. The
version on WebOS is specially patched to add some extra API to request
a GLES1 or GLES2 context. This patch adds a configure check to detect
when Cogl is being built with the patched version of SDL. In that case
it will additionally allow the gles1 and gles2 drivers and set the
right video mode attributes to get the corresponding context.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 3726c60deab2bd94617a562abb63f735627a25e4)
This fixes a few problems that occur when only using a GLES2 header.
• The use of GL_CLAMP_TO_BORDER and GL_MIRRORED_REPEAT were moved from
cogl-pipelinelayer-state.h to cogl-sampler-cache-private.h but the
corresponding defines were not.
• cogl-sampler-cache.c was using GL_TEXTURE_WRAP_R but this is only
defined as GL_TEXTURE_WRAP_R_OES from the GLES2 header so it needs a
#define.
• cogl-framebuffer-private.h uses GLuint but it does not include
cogl-gl-header.h. It gets away with this when GLX support is enabled
because the GL header would be included via glx.h.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 9cdb87c864fc262c4b26c13963670d60d7c18058)
The function to convert the CoglBufferUpdateHint to a GL enum was
previously ifdef'd to only use GL_STREAM_DRAW when Cogl is compiled
with big GL support. One problem with this is that it would end up
trying to use it on GLES1 if support for both is compiled. The other
problem is that GLES2 seems to actually support GL_STREAM_DRAW so we
might as well use it in that case.
This patch also changes it so that if the hint is stream with GLES1
then it will default to GL_DYNAMIC_DRAW instead of GL_STATIC_DRAW
because I think that is closer to the meaning of the stream hint.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 9e997476a7f9271bc000abdc82b1e343b92afb4c)
CoglMemoryStack was being typedef'd twice, once in the private header
as an incomplete struct and once in the C source with the actual
struct definition. This removes the second typedef so that it just
defines the struct.
This patch was written by Jack River.
https://bugzilla.gnome.org/show_bug.cgi?id=675119
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 75cd425a48e0fc403bf88eace212a6d37b65df11)
Cogl has feature flags for basic npot texture support and then separate
flags for npot + repeat and npot + mipmap. If those three features are
available then there is a feature for full-npot support too for
convenience. The cogl_texture_2d_new_ constructors were checking for
full npot support and failing if not available but since we expose the
fine grained features to the user the user should be able to check the
limitations of npot textures and still choose to allocate them.
_cogl_texture_2d_can_create() now only checks for basic npot support
when creating a npot texture. Since this change also affects the
automagic cogl_texture_ constructors they now check for basic npot +
mipmap support before considering using a Texture2D.
Notably the cogl_texture_ constructors will try constructing a Texture2D
even if we don't have npot + repeat support since the alternative is a
sliced texture which will need manual repeating anyway. Accordingly the
Texture2D::can_hardware_repeat and ::transform_quad_coords_to_gl vfuncs
have been made aware of the npot + repeat feature flag.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 6f6c5734d076372d98d0ec331b177ef7d65aa67d)
This adds a version header which contains macros to define which
version of Cogl the application is being compiled against. This helps
applications that want to support multiple incompatible versions of
Cogl at compile time.
The macros are called COGL_VERSION_{MAJOR,MINOR,MICRO}. This does not
match Clutter which names them CLUTTER_{MAJOR,MINOR,MICRO}_VERSION but
I think the former is nicer and it at least matches Cairo and Pango.
The values of the macro are defined to COGL_VERSION_*_INTERNAL which
is generated by the configure script into cogl-defines.h.
There is also a macro for the entire version as a string called
COGL_VERSION_STRING.
The internal utility macros for encoding a 3 part version number into
a single integer have been moved into the new header so they can be
used publicly as a convenient way to check if the version is within a
particular range. There is also a COGL_VERSION_CHECK macro for the
very common case that a feature will be used since a particular
version of Cogl. There is a macro called COGL_VERSION which contains
the pre-encoded version of Cogl being compiled against for
convenience.
Unlike in Clutter this patch does not add any runtime version
identification mechanism.
A test case is also added which just contains static asserts to sanity
check the macros.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 3480cf140dc355fa87ab3fbcf0aeeb0124798a8f)
When uploading the vertices the journal calls _cogl_matrix_entry_get()
to get a CoglMatrix for each journal entry so that it can so a software
transform. Since _cogl_matrix_entry_get() can be a performance hot-spot
and since it's trivial to keep track of the last CoglMatrixEntry seen we
now avoid repeatedly calling _cogl_matrix_entry_get() for sequential
entries with the same transform.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 70cad61533316e2303b8e188f2f361701dfb0c61)
This re-designs the matrix stack so we now keep track of each separate
operation such as rotating, scaling, translating and multiplying as
immutable, ref-counted nodes in a graph.
Being a "graph" here means that different transformations composed of
a sequence of linked operation nodes may share nodes.
The first node in a matrix-stack is always a LOAD_IDENTITY operation.
As an example consider if an application where to draw three rectangles
A, B and C something like this:
cogl_framebuffer_scale (fb, 2, 2, 2);
cogl_framebuffer_push_matrix(fb);
cogl_framebuffer_translate (fb, 10, 0, 0);
cogl_framebuffer_push_matrix(fb);
cogl_framebuffer_rotate (fb, 45, 0, 0, 1);
cogl_framebuffer_draw_rectangle (...); /* A */
cogl_framebuffer_pop_matrix(fb);
cogl_framebuffer_draw_rectangle (...); /* B */
cogl_framebuffer_pop_matrix(fb);
cogl_framebuffer_push_matrix(fb);
cogl_framebuffer_set_modelview_matrix (fb, &mv);
cogl_framebuffer_draw_rectangle (...); /* C */
cogl_framebuffer_pop_matrix(fb);
That would result in a graph of nodes like this:
LOAD_IDENTITY
|
SCALE
/ \
SAVE LOAD
| |
TRANSLATE RECTANGLE(C)
| \
SAVE RECTANGLE(B)
|
ROTATE
|
RECTANGLE(A)
Each push adds a SAVE operation which serves as a marker to rewind too
when a corresponding pop is issued and also each SAVE node may also
store a cached matrix representing the composition of all its ancestor
nodes. This means if we repeatedly need to resolve a real CoglMatrix
for a given node then we don't need to repeat the composition.
Some advantages of this design are:
- A single pointer to any node in the graph can now represent a
complete, immutable transformation that can be logged for example
into a journal. Previously we were storing a full CoglMatrix in
each journal entry which is 16 floats for the matrix itself as well
as space for flags and another 16 floats for possibly storing a
cache of the inverse. This means that we significantly reduce
the size of the journal when drawing lots of primitives and we also
avoid copying over 128 bytes per entry.
- It becomes much cheaper to check for equality. In cases where some
(unlikely) false negatives are allowed simply comparing the pointers
of two matrix stack graph entries is enough. Previously we would use
memcmp() to compare matrices.
- It becomes easier to do comparisons of transformations. By looking
for the common ancestry between nodes we can determine the operations
that differentiate the transforms and use those to gain a high level
understanding of the differences. For example we use this in the
journal to be able to efficiently determine when two rectangle
transforms only differ by some translation so that we can perform
software clipping.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit f75aee93f6b293ca7a7babbd8fcc326ee6bf7aef)
This adds a very minimal and fast allocator for chunks of memory of a
predetermined size. This has some similarities to the glib slice
allocator although notably it is not thread safe and instead of
internally tracking multiple magazines for various sized allocations the
api lets you explicitly allocate a single magazine for a single specific
size and a pointer to the magazine is passed explicitly to the allocate
and free functions.
This allocator builds on the CoglMemoryStack allocator as an underlying
heap allocator and just never rewinds the stack. This means the heap is
effectively a grow only linked list of malloc()'d blocks of memory.
A CoglMagazine tracks a singly linked list of chunks of a predetermined
size and _cogl_magazine_chunk_alloc() simply unlinks and returns the
head of the list. If the list is empty it falls back to allocating from
the underlying stack.
_cogl_magazine_chunk_free() links the chunk back into the singly linked
list for re-use.
The chunk size passed to _cogl_magazine_new() is automatically rounded
to a multiple of 8 bytes to ensure that all stack allocations end up
aligned to 8 bytes. This also ensures that when a chunk is freed then it
will be large enough to store a pointer to the next free chunk as part
of a singly linked list.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 17799c2f109a008d6cf767f501b81aa9b32bbda8)
This adds a very minimal internal allocator api that lets us create a
dynamically growable (grow only) stack.
Underlying the allocator is the idea of "sub stacks" which are simply
malloc()'d chunks of memory kept in a linked list. The stack itself
maintains a pointer to the current sub-stack and a current
sub-stack-offset. 99% of the time allocating from the stack is just a
case of returning a pointer to the current sub-stack + sub-stack-offset
and bumping the offset by the allocation size. If there isn't room in
the current sub-stack then we walk through the list of free sub-stacks
looking for one that's big enough for the allocation and if we reach the
end of the list then we allocate a new sub-stack twice as big as the
last (or twice as big as the requested allocation if that's bigger).
Since it's a stack model there is no api to free allocations, just a
function to rewind the stack to the beginning.
We expect this to be useful in multiple places in Cogl as an extremely
fast allocator in cases when we know we can scrap all the allocations
after we're done figuring something out or as a building block for
other allocators.
For example the tessellator used for CoglPath allocates lots of tiny
structures that can all be freed after tessellation.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 6ee4a7a1b7f695bdfeb10ffa4112e776beea0a9d)
Since 5967dad2400d32c we have stopped using glib types such as guint16
and guint32 in favour of the equivalent c99 types such as uint16_t and
uint32_t. When that patch was tested we must have used a configuration
that just happened to include <stdint.h> because we have since seen that
builds can fail due to missing c99 typedefs. This patch explicitly
includes stdint.h in cogl-types.h.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit c1e2220a4314071482d2d5638688b6bcf83882a2)
The existing functions for stroking and filling a path depend on the
global framebuffer and source stacks. These are now replaced with
cogl_framebuffer_{stroke,fill}_path which get explicitly passed the
framebuffer and pipeline.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 713a8f8160bc5884b091c69eb7a84b069e0950e6)
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)