Calling g_strdup for attribute names was starting to show up in profiles
due to calling malloc for new string storage so frequently. This avoids
calling g_strdup and calls g_intern_string() instead. For the really
common case names we even avoid the cost of g_intern_string since we
can trivially relate our internal name_id to a static string.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
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>
This adds an internal function to set the backface culling state on a
pipeline. This includes properties to set the culling mode (front,
back or both) and also to set which face is considered the front
(COGL_WINDING_CLOCKWISE or COGL_WINDING_COUNTER_CLOCKWISE). The actual
front face flushed to GL depends on whether we are rendering to an
offscreen buffer or not. This means that when changing between on- and
off- screen framebuffers it now checks whether the last flushed
pipeline has backface culling enabled and forces a reflush of the cull
face state if so.
The backface culling is now set on a pipeline as part of the legacy
state. This is important because some code in Cogl assumes it can
flush a temporary pipeline to revert to a known state, but previously
this wouldn't disable backface culling so things such as flushing the
clip stack could get confused.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
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>
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
cogl-ext-functions.h now contains definitions for all of the core GL
and GLES functions that we would normally link to directly. All of the
code has changed to access them through the cogl context pointer. The
GE macro now takes an extra parameter to specify the context because
the macro itself needs to make GL calls but various points in the Cogl
source use different names for the context variable.
Instead of storing all of the feature function pointers in the driver
specific data of the CoglContext they are now all stored directly in
CoglContext. There is a single header containing the description of
the functions which gets included by cogl-context.h. There is a single
function in cogl-feature-private.c to check for all of these
functions.
The name of the function pointer variables have been changed from
ctx->drv.pf_glWhatever to just ctx->glWhatever.
The feature flags that get set when an extension is available are now
separated from the table of extensions. This is necessary because
different extensions can mean different things on GLES and GL. For
example, having access to glMapBuffer implies read and write support
on GL but only write support on GLES. The flags are instead set in the
driver specific init function by checking whether the function
pointers were successfully resolved.
_cogl_feature_check has been changed to assume the feature is
supported if any of the listed extensions are available instead of
requiring all of them. This makes it more convenient to specify
alternate names for the extension. Nothing else had previously listed
more than one name for an extension so this shouldn't cause any
problems.
It used to be that we passed around NULL terminated arrays of
attributes, but since 3c1e83c7f we now explicitly pass an n_attributes
count instead. There were some leftovers of the old approach in the
cogl_vdraw_[indexed]_attributes functions and also there was an
off-by-one error with the n_attributes values passed on which was
causing crashes.
Signed-off-by: Neil Roberts <neil@linux.intel.com>
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.
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 strongly imply a relationship between
CoglBuffers and CoglIndexBuffers and be consistent with the
CoglAttributeBuffer and CoglPixelBuffer APIs.
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.
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.
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
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.
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.
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.