Commit Graph

92 Commits

Author SHA1 Message Date
Robert Bragg
8b22b0da65 journal: avoiding some _cogl_matrix_entry_get()'s
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)
2012-08-06 14:27:40 +01:00
Robert Bragg
e3d6bc36d3 Re-design the matrix stack using a graph of ops
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)
2012-08-06 14:27:40 +01:00
Robert Bragg
54735dec84 Switch use of primitive glib types to c99 equivalents
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)
2012-08-06 14:27:39 +01:00
Robert Bragg
09642a83b5 Removes all remaining use of CoglHandle
Removing CoglHandle has been an on going goal for quite a long time now
and finally this patch removes the last remaining uses of the CoglHandle
type and the cogl_handle_ apis.

Since the big remaining users of CoglHandle were the cogl_program_ and
cogl_shader_ apis which have replaced with the CoglSnippets api this
patch removes both of these apis.

Reviewed-by: Neil Roberts <neil@linux.intel.com>

(cherry picked from commit 6ed3aaf4be21d605a1ed3176b3ea825933f85cf0)

  Since the original patch was done after removing deprecated API
  this back ported patch doesn't affect deprecated API and so
  actually this cherry-pick doesn't remove all remaining use of
  CoglHandle as it did for the master branch of Cogl.
2012-08-06 14:27:39 +01:00
Robert Bragg
3881fd3259 Adds cogl_framebuffer_draw_[*_]rectangle functions
This adds experimental 2.0 api replacements for the cogl_rectangle[_*]
functions that don't depend on having a current pipeline set on the
context via cogl_{set,push}_source() or having a current framebuffer set
on the context via cogl_push_framebuffer(). The aim for 2.0 is to switch
away from having a statefull context that affects drawing to having
framebuffer drawing apis that are explicitly passed a framebuffer and
pipeline.

To test this change several of the conformance tests were updated to use
this api instead of cogl_rectangle and
cogl_rectangle_with_texture_coords. Since it's quite laborious going
through all of the conformance tests the opportunity was taken to make
other clean ups in the conformance tests to replace other uses of
1.x api with experimental 2.0 api so long as that didn't affect what was
being tested.
2012-03-20 12:33:40 +00:00
Neil Roberts
a5f2f0fe2d journal: Don't push and pop the framebuffer when flushing
In theory none of the journal flushing code should be using anything
that relies on the global framebuffer stack because it should all be
using the new 2.0-style API which explicitly mentions the target
framebuffer. Eventually we want to get rid of the framebuffer stack so
we might as well remove the push and pop now.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-16 17:31:03 +00:00
Neil Roberts
ff48f3b174 journal: Always keep a pointer back to the framebuffer
Previously when adding a quad to the journal it would assume the
journal belongs to the framebuffer at the top of the framebuffer stack
and store a reference to that. We eventually want to get rid of the
framebuffer stack so we should avoid using it here. The journal now
takes a pointer back to the framebuffer in its constructor and it
always retains the pointer. As was done previously, the journal still
does not take a reference on the framebuffer unless it is non-empty so
it does not create a permanent circular reference.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-16 17:26:30 +00:00
Neil Roberts
185630085c Add -Wmissing-declarations to maintainer flags and fix problems
This option to GCC makes it give a warning whenever a global function
is defined without a declaration. This should catch cases were we've
defined a function but forgot to put it in a header. In that case it
is either only used within one file so we should make it static or we
should declare it in a header.

The following changes where made to fix problems:

• Some functions were made static

• cogl-path.h (the one containing the 1.0 API) was split into two
  files, one defining the functions and one defining the enums so that
  cogl-path.c can include the enum and function declarations from the
  2.0 API as well as the function declarations from the 1.0 API.

• cogl2-clip-state has been removed. This only had one experimental
  function called cogl_clip_push_from_path but as this is unstable we
  might as well remove it favour of the equivalent cogl_framebuffer_*
  API.

• The GLX, SDL and WGL winsys's now have a private header to define
  their get_vtable function instead of directly declaring in the C
  file where it is called.

• All places that were calling COGL_OBJECT_DEFINE need to have the
  cogl_is_whatever function declared so these have been added either
  as a public function or in a private header.

• Some files that were not including the header containing their
  function declarations have been fixed to do so.

• Any unused error quark functions have been removed. If we later want
  them we should add them back one by one and add a declaration for
  them in a header.

• _cogl_is_framebuffer has been renamed to cogl_is_framebuffer and
  made a public function with a declaration in cogl-framebuffer.h

• Similarly for CoglOnscreen.

• cogl_vdraw_indexed_attributes is called
  cogl_framebuffer_vdraw_indexed_attributes in the header. The
  definition has been changed to match the header.

• cogl_index_buffer_allocate has been removed. This had no declaration
  and I'm not sure what it's supposed to do.

• CoglJournal has been changed to use the internal CoglObject macro so
  that it won't define an exported cogl_is_journal symbol.

• The _cogl_blah_pointer_from_handle functions have been removed.
  CoglHandle isn't used much anymore anyway and in the few places
  where it is used I think it's safe to just use the implicit cast
  from void* to the right type.

• The test-utils.h header for the conformance tests explicitly
  disables the -Wmissing-declaration option using a pragma because all
  of the tests declare their main function without a header. Any
  mistakes relating to missing declarations aren't really important
  for the tests.

• cogl_quaternion_init_from_quaternion and init_from_matrix have been
  given declarations in cogl-quaternion.h

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-06 18:45:44 +00:00
Neil Roberts
1397a2da19 Make _cogl_bitmap_get_{width,height,format,rowstride} public
This are now marked as public experimental

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-05 18:47:52 +00:00
Neil Roberts
10a38bb14f Add a public cogl_framebuffer_read_pixels_into_bitmap
This adds a public function to read pixels from a framebuffer into a
CoglBitmap. This replaces the internal function
_cogl_read_pixels_with_rowstride because a CoglBitmap contains a
rowstride so it can be used for the same purpose. A CoglBitmap already
has public API to make one that points to a CoglPixelBuffer so this
function can be used to read pixels into a PBO. It also avoids the
need to push the framebuffer on to the context's stack so it provides
a function which can be used in the 2.0 API after the stack is
removed.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-03-05 18:16:10 +00:00
Robert Bragg
785e6375eb Adds a context arg to cogl_pipeline_new()
As we move towards Cogl 2.0 we are aiming to remove the need for a
default global CoglContext and so everything should be explicitly
related to a context somehow. CoglPipelines are top level objects and
so this patch adds a context argument to cogl_pipeline_new().

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-21 12:38:24 +00:00
Robert Bragg
680f63a48c Remove all internal includes of cogl.h
The cogl.h header is meant to be the public header for including the 1.x
api used by Clutter so we should stop using that as a convenient way to
include all likely prototypes and typedefs. Actually we already do a
good job of listing the specific headers we depend on in each of the .c
files we have so mostly this patch just strip out the redundant
includes for cogl.h with a few fixups where that broke the build.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-20 23:12:45 +00:00
Robert Bragg
ee940a3d0d Move all types/prototypes from cogl.h -> cogl[1]-context.h
So we can get to the point where cogl.h is merely an aggregation of
header includes for the 1.x api this moves all the function prototypes
and type definitions into a cogl-context.h and a new cogl1-context.h.

Ideally no code internally should ever need to include cogl.h as it just
represents the public facing header for accessing the 1.x api which
should only be used by Clutter.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-20 23:12:44 +00:00
Robert Bragg
3ea6acc072 buffer: explicitly relate buffers to a context
All CoglBuffer constructors now take an explicit CoglContext
constructor. This is part of the on going effort to adapt to Cogl API so
it no longer depends on a global, default context.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-09 14:28:02 +00:00
Robert Bragg
b168ff8ef6 journal: use pipeline term instead of source
Since we are adapting the Cogl api to be less stateful one of the things
we no longer require is the cogl_set_source() api since a pipeline can
be explicitly passed as an argument when drawing. This means the term
"source" has been deprecated and internally we should aim to
consistently use the term "pipeline" instead. This patch updates the
journal code to use the term pipeline instead of source.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-09 13:13:07 +00:00
Robert Bragg
92c3063014 framebuffer: Add cogl_framebuffer draw methods
This adds cogl_framebuffer_ apis for drawing attributes and primitives
that replace corresponding apis that depend on the default CoglContext.
This is part of the on going effort to adapt the Cogl api so it no
longer depends on a global context variable.

All the new drawing functions also take an explicit pipeline argument
since we are also aiming to avoid being a stateful api like Cairo and
OpenGL. Being stateless makes it easier for orthogonal components to
share access to the GPU. Being stateless should also minimize any
impedance miss-match for those wanting to build higher level stateless
apis on top of Cogl.

Note: none of the legacy, global state options such as
cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
cogl_program_use() are supported by these new drawing apis and if set
will simply be silently ignored.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2012-02-09 13:09:15 +00:00
Neil Roberts
d42f1873fc framebuffer: Flush the journal on destruction
Instead of flushing the journal whenever the current framebuffer on a
context is changed it is now flushed whenever the framebuffer is about
to be destroyed instead. To do this it implements a custom unref
function which detects when there is going to be exactly one reference
on the framebuffer and then flushes its journal. The journal now
always has a reference on the framebuffer whenever it is non-empty.
That means the unref will only cause a flush if the only thing keeping
the framebuffer alive is the entries in the journal.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2012-01-27 17:23:03 +00:00
Neil Roberts
f005f517fe Flush matrices in the progend and flip with a vector
Previously flushing the matrices was performed as part of the
framebuffer state. When on GLES2 this matrix flushing is actually
diverted so that it only keeps a reference to the intended matrix
stack. This is necessary because on GLES2 there are no builtin
uniforms so it can't actually flush the matrices until the program for
the pipeline is generated. When the matrices are flushed it would
store the age of modifications on the matrix stack so that it could
detect when the matrix hasn't changed and avoid flushing it.

This patch changes it so that the pipeline is responsible for flushing
the matrices even when we are using the GL builtins. The same
mechanism for detecting unmodified matrix stacks is used in all
cases. There is a new CoglMatrixStackCache type which is used to store
a reference to the intended matrix stack along with its last flushed
age. There are now two of these attached to the CoglContext to track
the flushed state for the global matrix builtins and also two for each
glsl progend program state to track the flushed state for a
program. The framebuffer matrix flush now just updates the intended
matrix stacks without actually trying to flush.

When a vertex snippet is attached to the pipeline, the GLSL vertend
will now avoid using the projection matrix to flip the rendering. This
is necessary because any vertex snippet may cause the projection
matrix not to be used. Instead the flip is done as a forced final step
by multiplying cogl_position_out by a vec4 uniform. This uniform is
updated as part of the progend pre_paint depending on whether the
framebuffer is offscreen or not.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Robert Bragg
042dc7c8cd framebuffer: Optimize _cogl_framebuffer_flush_state()
Previously the cost of _cogl_framebuffer_state_flush() would always
scale by the total amount of state tracked by CoglFramebuffer even in
cases where we knew up-front that we only wanted to flush a subset of
the state or in cases where we requested to flush the same framebuffer
multiple times with no changes being made to the framebuffer.

We now track a set of state changed flags with each framebuffer and
track the current read/draw buffers as part of the CoglContext so that
we can quickly bail out when asked to flush the same framebuffer
multiple times with no changes.

_cogl_framebuffer_flush_state() now takes a mask of the state that we
want to flush and the implementation has been redesigned so that the
cost of checking what needs to be flushed and flushing those changes
now scales by how much state we actually plan to update.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
39a7bcff67 matrix-stack: Avoid referencing the default CoglContext
This removes the use of _COGL_GET_CONTEXT() from cogl-matrix-stack.c
as part of the ongoing effort to evolve cogl to get rid of the need for
a default context.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
c86f698eb9 make COGL_FEATURE_VBOS a private feature
Cogl provides a consistent public interface regardless of whether the
underlying GL driver supports VBOs so it doesn't make much sense to have
this feature as part of the public api.  We can't break the api by
removing the enum but at least we no longer ever set the feature flag.

We now have a replacement private feature flag COGL_PRIVATE_FEATURE_VBOS
which cogl now checks for internally.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-01 12:03:01 +00:00
Robert Bragg
4c3dadd35e Add a strong CoglTexture type to replace CoglHandle
As part of the on going, incremental effort to purge the non type safe
CoglHandle type from the Cogl API this patch tackles most of the
CoglHandle uses relating to textures.

We'd postponed making this change for quite a while because we wanted to
have a clearer understanding of how we wanted to evolve the texture APIs
towards Cogl 2.0 before exposing type safety here which would be
difficult to change later since it would imply breaking APIs.

The basic idea that we are steering towards now is that CoglTexture
can be considered to be the most primitive interface we have for any
object representing a texture. The texture interface would provide
roughly these methods:

  cogl_texture_get_width
  cogl_texture_get_height
  cogl_texture_can_repeat
  cogl_texture_can_mipmap
  cogl_texture_generate_mipmap;
  cogl_texture_get_format
  cogl_texture_set_region
  cogl_texture_get_region

Besides the texture interface we will then start to expose types
corresponding to specific texture types: CoglTexture2D,
CoglTexture3D, CoglTexture2DSliced, CoglSubTexture, CoglAtlasTexture and
CoglTexturePixmapX11.

We will then also expose an interface for the high-level texture types
we have (such as CoglTexture2DSlice, CoglSubTexture and
CoglAtlasTexture) called CoglMetaTexture. CoglMetaTexture is an
additional interface that lets you iterate a virtual region of a meta
texture and get mappings of primitive textures to sub-regions of that
virtual region. Internally we already have this kind of abstraction for
dealing with sliced texture, sub-textures and atlas textures in a
consistent way, so this will just make that abstraction public. The aim
here is to clarify that there is a difference between primitive textures
(CoglTexture2D/3D) and some of the other high-level textures, and also
enable developers to implement primitives that can support meta textures
since they can only be used with the cogl_rectangle API currently.

The thing that's not so clean-cut with this are the texture constructors
we have currently; such as cogl_texture_new_from_file which no longer
make sense when CoglTexture is considered to be an interface.  These
will basically just become convenient factory functions and it's just a
bit unusual that they are within the cogl_texture namespace.  It's worth
noting here that all the texture type APIs will also have their own type
specific constructors so these functions will only be used for the
convenience of being able to create a texture without really wanting to
know the details of what type of texture you need.  Longer term for 2.0
we may come up with replacement names for these factory functions or the
other thing we are considering is designing some asynchronous factory
functions instead since it's so often detrimental to application
performance to be blocked waiting for a texture to be uploaded to the
GPU.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-09-21 15:27:03 +01:00
Neil Roberts
2059ae3ac8 Add internal _cogl_push_source to optionally disable legacy state
Some code in Cogl such as when flushing a stencil clip assumes that it
can push a temporary simple pipeline to reset to a known state for
internal drawing operations. However this breaks down if the
application has set any legacy state because that is set globally so
it will also get applied to the internal pipeline.

_cogl_draw_attributes already had an internal flag to disable applying
the legacy state but I think this is quite awkward to use because not
all places that push a pipeline draw the attribute buffers directly so
it is difficult to pass the flag down through the layers.

Conceptually the legacy state is meant to be like a layer on top of
the purely pipeline-based state API so I think ideally we should have
an internal function to push the source without the applying the
legacy state. The legacy state can't be applied as the pipeline is
pushed because the global state can be modified even after it is
pushed. This patch adds a _cogl_push_source() function which takes an
extra boolean flag to mark whether to enable the legacy state. The
value of this flag is stored alongside the pipeline in the pipeline
stack. Another new internal function called
_cogl_get_enable_legacy_state queries whether the top entry in the
pipeline stack has legacy state enabled. cogl-primitives and the
vertex array drawing code now use this to determine whether to apply
the legacy state when drawing. The COGL_DRAW_SKIP_LEGACY_STATE flag is
now removed.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-09-19 16:40:06 +01:00
Neil Roberts
e81c1f3e9a cogl-journal: Fix software clipping for non-intersecting rectangles
When the clip contains two rectangles which do not intersect it was
generating a clip bounds where the bottom-right corner was above or to
the left of the top-left corner. This would end up allowing the pixels
between the two rectangles instead of clipping everything like it
should. To fix this there is now an extra check which detects this
situation and just clears the clip bounds to all zeroes in a similar
way to what cogl-clip-stack does.

https://bugzilla.gnome.org/show_bug.cgi?id=659029

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-09-14 16:30:16 +01:00
Robert Bragg
f7b1bab1ad framebuffer: don't reference default fb in _clear apis
Some of the functions we were calling in cogl_framebuffer_clear[4f] were
referring to the current framebuffer, which would result in a crash
if nothing had been pushed before trying to explicitly clear a given
framebuffer.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-08-12 15:28:43 +01:00
Neil Roberts
b2e735ff7f Dynamically load the GL or GLES library
The GL or GLES library is now dynamically loaded by the CoglRenderer
so that it can choose between GL, GLES1 and GLES2 at runtime. The
library is loaded by the renderer because it needs to be done before
calling eglInitialize. There is a new environment variable called
COGL_DRIVER to choose between gl, gles1 or gles2.

The #ifdefs for HAVE_COGL_GL, HAVE_COGL_GLES and HAVE_COGL_GLES2 have
been changed so that they don't assume the ifdefs are mutually
exclusive. They haven't been removed entirely so that it's possible to
compile the GLES backends without the the enums from the GL headers.

When using GLX the winsys additionally dynamically loads libGL because
that also contains the GLX API. It can't be linked in directly because
that would probably conflict with the GLES API if the EGL is
selected. When compiling with EGL support the library links directly
to libEGL because it doesn't contain any GL API so it shouldn't have
any conflicts.

When building for WGL or OSX Cogl still directly links against the GL
API so there is a #define in config.h so that Cogl won't try to dlopen
the library.

Cogl-pango previously had a #ifdef to detect when the GL backend is
used so that it can sneakily pass GL_QUADS to
cogl_vertex_buffer_draw. This is now changed so that it queries the
CoglContext for the backend. However to get this to work Cogl now
needs to export the _cogl_context_get_default symbol and cogl-pango
needs some extra -I flags to so that it can include
cogl-context-private.h
2011-07-11 12:57:38 +01:00
Robert Bragg
c4eb869bd7 framebuffer: expose viewport getters/setters
This exposes experimental cogl_framebuffer APIs for getting and setting
a viewport without having to refer to the implicit CoglContext. It adds
the following experimental API:

  cogl_framebuffer_set_viewport
  cogl_framebuffer_get_viewport4fv
  cogl_framebuffer_get_viewport_x
  cogl_framebuffer_get_viewport_y
  cogl_framebuffer_get_viewport_width
  cogl_framebuffer_get_viewport_height

Signed-off-by: Neil Roberts <neil@linux.intel.com>
2011-06-30 14:33:11 +01:00
Neil Roberts
efadc439a4 cogl-journal: Use a pool of vertex arrays
Previously whenever the journal is flushed a new vertex array would be
created to contain the vertices. To avoid the overhead of reallocating
a buffer every time, this patch makes it use a pool of 8 buffers which
are cycled in turn. The buffers are never destroyed but instead the
data is replaced. The journal should only ever be using one buffer at
a time but we cache more than one buffer anyway in case the GL driver
is internally using the buffer in which case mapping the buffer may
cause it to create a new buffer anyway.
2011-06-01 14:41:59 +01:00
Robert Bragg
3c1e83c7f5 Don't pass around NULL terminated CoglAttribute arrays
For the first iteration of the CoglAttribute API several of the new
functions accepted a pointer to a NULL terminated list of CoglAttribute
pointers - probably as a way to reduce the number of arguments required.
This style isn't consistent with existing Cogl APIs though and so we now
explicitly pass n_attributes arguments and don't require the NULL
termination.
2011-05-16 14:32:37 +01:00
Robert Bragg
ce7c06dc03 Rename CoglVertexArray to CoglAttributeBuffer
This is part of a broader cleanup of some of the experimental Cogl API.
One of the reasons for this particular rename is to switch away from
using the term "Array" which implies a regular, indexable layout which
isn't the case. We also want to have a strongly implied relationship
between CoglAttributes and CoglAttributeBuffers.
2011-05-16 14:31:31 +01:00
Robert Bragg
0b45110302 framebuffer: expose experimental cogl_get_draw_framebuffer
This renames the two internal functions _cogl_get_draw/read_buffer
as cogl_get_draw_framebuffer and _cogl_get_read_framebuffer. The
former is now also exposed as experimental API.
2011-04-11 15:28:53 +01:00
Robert Bragg
fdbc741770 cogl: rename cogl-context.h cogl-context-private.h
Since we plan to add public cogl_context_* API we need to rename the
current cogl-context.h which contains private member details.
2011-04-11 15:18:12 +01:00
Robert Bragg
bc372d2734 viewport: consistently use floats for viewports
OpenGL < 4.0 only supports integer based viewports and internally we
have a mixture of code using floats and integers for viewports. This
patch switches all viewports throughout clutter and cogl to be
represented using floats considering that in the future we may want to
take advantage of floating point viewports with modern hardware/drivers.
2011-03-07 13:26:19 +00:00
Robert Bragg
b3d9f313d4 util: tune point_in_poly test for polys in screen coords
This makes a change to the original point_in_poly algorithm from:
http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html

The aim was to tune the test so that tests against screen aligned
rectangles are more resilient to some in-precision in how we transformed
that rectangle into screen coordinates. In particular gnome-shell was
finding that for some stage sizes then row 0 of the stage would become a
dead zone when going through the software picking fast-path and this was
because the y position of screen aligned rectangles could end up as
something like 0.00024 and the way the algorithm works it doesn't have
any epsilon/fuz factor to consider that in-precision.

We've avoided introducing an epsilon factor to the comparisons since we
feel there's a risk of changing some semantics in ways that might not be
desirable. One of those is that if you transform two polygons which
share an edge and test a point close to that edge then this algorithm
will currently give a positive result for only one polygon.

Another concern is the way this algorithm resolves the corner case where
the horizontal ray being cast to count edge crossings may cross directly
through a vertex. The solution is based on the "idea of Simulation of
Simplicity" and "pretends to shift the ray infinitesimally down so that
it either clearly intersects, or clearly doesn't touch". I'm not
familiar with the idea myself so I expect a misplaced epsilon is likely
to break that aspect of the algorithm.

The simple solution this patch applies is to pixel align the polygon
vertices which should eradicate most noise due to in-precision.

https://bugzilla.gnome.org/show_bug.cgi?id=641197
2011-03-07 13:26:19 +00:00
Neil Roberts
dd7b1326eb cogl: Avoid pointer arithmetic on void* pointers
Some code was doing pointer arithmetic on the return value from
cogl_buffer_map which is void* pointer. This is a GCC extension so we
should try to avoid it. This patch adds casts to guint8* where
appropriate.

Based on a patch by Fan, Chun-wei.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2561
2011-02-15 14:26:17 +00:00
Neil Roberts
a067e7a16b cogl-framebuffer: Separate the draw and read buffer
The current framebuffer is now internally separated so that there can
be a different draw and read buffer. This is required to use the
GL_EXT_framebuffer_blit extension. The current draw and read buffers
are stored as a pair in a single stack so that pushing the draw and
read buffer is done simultaneously with the new
_cogl_push_framebuffers internal function. Calling
cogl_pop_framebuffer will restore both the draw and read buffer to the
previous state. The public cogl_push_framebuffer function is layered
on top of the new function so that it just pushes the same buffer for
both drawing and reading.

When flushing the framebuffer state, the cogl_framebuffer_flush_state
function now tackes a pointer to both the draw and the read
buffer. Anywhere that was just flushing the state for the current
framebuffer with _cogl_get_framebuffer now needs to call both
_cogl_get_draw_buffer and _cogl_get_read_buffer.
2011-02-15 12:10:54 +00:00
Neil Roberts
2ddab50ae4 cogl-debug: Add a debug option for tracing clipping
This adds a COGL_DEBUG=clipping option that reports how the clip is
being flushed. This is needed to determine whether the scissor,
stencil clip planes or software clipping is being used.
2011-01-24 17:39:48 +00:00
Neil Roberts
c4a94439de cogl-debug: Split the flags to support more than 32
The CoglDebugFlags are now stored in an array of unsigned ints rather
than a single variable. The flags are accessed using macros instead of
directly peeking at the cogl_debug_flags variable. The index values
are stored in the enum rather than the actual mask values so that the
enum doesn't need to be more than 32 bits wide. The hope is that the
code to determine the index into the array can be optimized out by the
compiler so it should have exactly the same performance as the old
code.
2011-01-24 15:45:45 +00:00
Robert Bragg
4758ed2cf2 journal: start uprof flush timer after flushing fb deps
This avoids us recursively starting the _cogl_journal_flush uprof timer
by only starting it after flushing the journals of dependency
framebuffers.
2011-01-21 17:38:14 +00:00
Robert Bragg
9b0fd92527 cogl: rename CoglVertexAttribute CoglAttribute
This is part of a broader cleanup of some of the experimental Cogl API.
One of the reasons for this particular rename is to reduce the verbosity
of using the API. Another reason is that CoglVertexArray is going to be
renamed CoglAttributeBuffer and we want to help emphasize the
relationship between CoglAttributes and CoglAttributeBuffers.
2011-01-21 16:24:14 +00:00
Robert Bragg
5f6cb16e2b debug: Adds a COGL_DEBUG=disable-fast-read-pixel option
COGL_DEBUG=disable-fast-read-pixel can be used to disable the
optimization for reading a single pixel colour back by looking at the
geometry in the journal and not involving the GPU. With this disabled we
will always flush the journal, rendering to the framebuffer and then use
glReadPixels to get the result.
2011-01-21 16:18:11 +00:00
Robert Bragg
a8d6c3f686 cogl: Implements a software only read-pixel fast-path
This adds a transparent optimization to cogl_read_pixels for when a
single pixel is being read back and it happens that all the geometry of
the current frame is still available in the framebuffer's associated
journal.

The intention is to indirectly optimize Clutter's render based picking
mechanism in such a way that the 99% of cases where scenes are comprised
of trivial quad primitives that can easily be intersected we can avoid
the latency of kicking a GPU render and blocking for the result when we
know we can calculate the result manually on the CPU probably faster
than we could even kick a render.

A nice property of this solution is that it maintains all the
flexibility of the render based picking provided by Clutter and it can
gracefully fall back to GPU rendering if actors are drawn using anything
more complex than a quad for their geometry.

It seems worth noting that there is a limitation to the extensibility of
this approach in that it can only optimize picking a against geometry
that passes through Cogl's journal which isn't something Clutter
directly controls.  For now though this really doesn't matter since
basically all apps should end up hitting this fast-path. The current
idea to address this longer term would be a pick2 vfunc for ClutterActor
that can support geometry and render based input regions of actors and
move this optimization up into Clutter instead.

Note: currently we don't have a primitive count threshold to consider
that there could be scenes with enough geometry for us to compensate for
the cost of kicking a render and determine a result more efficiently by
utilizing the GPU. We don't currently expect this to be common though.

Note: in the future it could still be interesting to revive something
like the wip/async-pbo-picking branch to provide an asynchronous
read-pixels based optimization for Clutter picking in cases where more
complex input regions that necessitate rendering are in use or if we do
add a threshold for rendering as mentioned above.
2011-01-21 16:18:11 +00:00
Robert Bragg
e1563436b1 clip: rename get_clip_stack + add framebuffer_get_stack
Instead of having _cogl_get/set_clip stack which reference the global
CoglContext this instead makes those into CoglClipState method functions
named _cogl_clip_state_get/set_stack that take an explicit pointer to a
CoglClipState.

This also adds _cogl_framebuffer_get/set_clip_stack convenience
functions that avoid having to first get the ClipState from a
framebuffer then the stack from that - so we can maintain the
convenience of _cogl_get_clip_stack.
2011-01-21 16:18:10 +00:00
Robert Bragg
1a5a4df326 journal: Support per-framebuffer journals
Instead of having a single journal per context, we now have a
CoglJournal object for each CoglFramebuffer. This means we now don't
have to flush the journal when switching/pushing/popping between
different framebuffers so for example a Clutter scene that involves some
ClutterEffect actors that transiently redirect to an FBO can still be
batched.

This also allows us to track state in the journal that relates to the
current frame of its associated framebuffer which we'll need for our
optimization for using the CPU to handle reading a single pixel back
from a framebuffer when we know the whole scene is currently comprised
of simple rectangles in a journal.
2011-01-21 16:18:10 +00:00
Neil Roberts
a8216aff2f cogl: Fallback to set_data when mapping a buffer to fill it
In the journal code and when generating the stroke path the vertices
are generated on the fly and stored in a CoglBuffer using
cogl_buffer_map. However cogl_buffer_map is allowed to fail but it
wasn't checking for a NULL return value. In particular on GLES it will
always fail because glMapBuffer is only provided by an extension. This
adds a new pair of internal functions called
_cogl_buffer_{un,}map_for_fill_or_fallback which wrap
cogl_buffer_map. If the map fails then it will instead return a
pointer into a GByteArray attached to the context. When the buffer is
unmapped the array is copied into the buffer using
cogl_buffer_set_data.
2011-01-13 16:36:32 +00:00
Neil Roberts
3b3cfe1824 cogl-vertex-attribute: Optionally avoid applying the legacy state
When an item is added to the journal the current pipeline immediately
gets the legacy state applied to it and the modified pipeline is
logged instead of the original. However the actual drawing from the
journal is done using the vertex attribute API which was also applying
the legacy state. This meant that the legacy state used would be a
combination of the state set when the journal entry was added as well
as the state set when the journal is flushed. To fix this there is now
an extra CoglDrawFlag to avoid applying the legacy state when setting
up the GL state for the vertex attributes. The journal uses this flag
when flushing.
2011-01-11 14:06:09 +00:00
Neil Roberts
bbce77fcea cogl-journal: Avoid enabling blending if possible
The vertex attribute API assumes that if there is a color array
enabled then we can't determine if the colors are opaque so we have to
enable blending. The journal always uses a color array to avoid
switching color state between rectangles. Since the journal switched
to using vertex attributes this means we effectively always enable
blending from the journal. To fix this there is now a new flag for
_cogl_draw_vertex_attributes to specify that the color array is known
to only contain opaque colors which causes the draw function not to
copy the pipeline. If the pipeline has blending disabled then the
journal passes this flag.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2481
2011-01-10 17:11:42 +00:00
Neil Roberts
a847289850 cogl-vertex-attribute: Add flags to _cogl_draw_vertex_attributes_array
There is an internal version of cogl_draw_vertex_attributes_array
which previously just bypassed the framebuffer flushing, journal
flushing and pipeline validation so that it could be used to draw the
journal. This patch generalises the function so that it takes a set of
flags to specify which parts to flush. The public version of the
function now just calls the internal version with the flags set to
0. The '_real' version of the function has now been merged into the
internal version of the function because it was only called in one
place. This simplifies the code somewhat. The common code which
flushed the various state has been moved to a separate function. The
indexed versions of the functions have had a similar treatment.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2481
2011-01-10 17:11:41 +00:00
Robert Bragg
2c9cd76baa pipeline: generalize _cogl_pipeline_equal
_cogl_pipeline_equal now accepts a mask of pipeline differences and layer
differences to constrain what state will be compared. In addition a set
of flags are passed that can tweak the comparison semantics for some
state groups. For example when comparing layer textures we sometimes
only need to compare the texture target and can ignore the data itself.

In updating the code this patch also changes it so all required pipeline
authorities are resolved in one step up-front instead of resolving the
authority for each state group in turn and repeatedly having to traverse
the pipeline's ancestry. This adds two new functions
_cogl_pipeline_resolve_authorities and
_cogl_pipeline_layer_resolve_authorities to handle resolving a set of
authorities.
2010-12-07 16:00:32 +00:00
Neil Roberts
e292d28c56 Add a COGL_DEBUG option to disable software clipping
This adds a debug option called disable-software-clipping which causes
the journal to always log the clip stack state rather than trying to
manually clip rectangles.
2010-12-03 17:16:58 +00:00