Consistent with how we lazily allocate framebuffers this patch allows us
to instantiate textures but still specify constraints and requirements
before allocating storage so that we can be sure to allocate the most
appropriate/efficient storage.
This adds a cogl_texture_allocate() function that is analogous to
cogl_framebuffer_allocate() which can optionally be called to explicitly
allocate storage and catch any errors. If this function isn't used
explicitly then Cogl will implicitly ensure textures are allocated
before the storage is needed.
It is generally recommended to rely on lazy storage allocation or at
least perform explicit allocation as late as possible so Cogl can be
fully informed about the best way to allocate storage.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 1fa7c0f10a8a03043e3c75cb079a49625df098b7)
Note: This reverts the cogl_texture_rectangle_new_with_size API change
that dropped the CoglError argument and keeps the semantics of
allocating the texture immediately. This is because Mutter currently
uses this API so we will probably look at updating this later once
we have a corresponding Mutter patch prepared. The other API changes
were kept since they only affected experimental api.
We have found several times now when writing code using Cogl that it
would really help if Cogl's matrix stack api was public as a utility
api. In Rig for example we want to avoid redundant arithmetic when
deriving the matrices of entities used to render and we aren't able
to simply use the framebuffer's matrix stack to achieve this. Also when
implementing cairo-cogl we found that it would be really useful if we
could have a matrix stack utility api.
(cherry picked from commit d17a01fd935d88fab96fe6cc0b906c84026c0067)
This make _cogl_framebuffer_blit take explicit src and dest framebuffer
pointers and updates all the texture blitting strategies in cogl-blit.c
to avoid pushing/popping to/from the the framebuffer stack.
The removes the last user of the framebuffer stack which we've been
aiming to remove before Cogl 2.0
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 598ca33950a93dd7a201045c4abccda2a855e936)
This allows apps to catch out-of-memory errors when allocating textures.
Textures can be pretty huge at times and so it's quite possible for an
application to try and allocate more memory than is available. It's also
very possible that the application can take some action in response to
reduce memory pressure (such as freeing up texture caches perhaps) so
we shouldn't just automatically abort like we do for trivial heap
allocations.
These public functions now take a CoglError argument so applications can
catch out of memory errors:
cogl_buffer_map
cogl_buffer_map_range
cogl_buffer_set_data
cogl_framebuffer_read_pixels_into_bitmap
cogl_pixel_buffer_new
cogl_texture_new_from_data
cogl_texture_new_from_bitmap
Note: we've been quite conservative with how many apis we let throw OOM
CoglErrors since we don't really want to put a burdon on developers to
be checking for errors with every cogl api call. So long as there is
some lower level api for apps to use that let them catch OOM errors
for everything necessary that's enough and we don't have to make more
convenient apis more awkward to use.
The main focus is on bitmaps and texture allocations since they
can be particularly large and prone to failing.
A new cogl_attribute_buffer_new_with_size() function has been added in
case developers need to catch OOM errors when allocating attribute buffers
whereby they can first use _buffer_new_with_size() (which doesn't take a
CoglError) followed by cogl_buffer_set_data() which will lazily allocate
the buffer storage and report OOM errors.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit f7735e141ad537a253b02afa2a8238f96340b978)
Note: since we can't break the API for Cogl 1.x then actually the main
purpose of cherry picking this patch is to keep in-line with changes
on the master branch so that we can easily cherry-pick patches.
All the api changes relating stable apis released on the 1.12 branch
have been reverted as part of cherry-picking this patch so this most
just applies all the internal plumbing changes that enable us to
correctly propagate OOM errors.
The Intel Mesa gen6 driver doesn't currently handle scissoring offset
viewports correctly, so this implements a workaround to intersect the
current viewport bounds with the scissor rectangle.
(cherry picked from commit afc5daab85e5faca99d6d6866658cb82c3954830)
This splits out most of the OpenGL specific code from cogl-framebuffer.c
into cogl-framebuffer-gl.c and extends the CoglDriverVtable interface
for cogl-framebuffer.c to use.
There are hopes to support several different backends for Cogl
eventually to hopefully get us closer to the metal so this makes some
progress in organizing which parts of Cogl are OpenGL specific so these
parts can potentially be switched out later.
The only remaining use of OpenGL still in cogl-framebuffer.c is to
handle cogl_framebuffer_read_pixels.
This commit introduces some new framebuffer api to be able to
enable texture based depth buffers for a framebuffer (currently
only supported for offscreen framebuffers) and once allocated
to be able to retrieve the depth buffer as a texture for further
usage, say, to implement shadow mapping.
The API works as follow:
* Before the framebuffer is allocated, you can request that a depth
texture is created with
cogl_framebuffer_set_depth_texture_enabled()
* cogl_framebuffer_get_depth_texture() can then be used to grab a
CoglTexture once the framebuffer has been allocated.
There are two extensions, GL_OES_packed_depth_stencil and
GL_EXT_packed_depth_stencil, that inform us that the hardware supports
packing the depth and stencil values together into one format.
The OES extension is the GLES equivalent of the EXT extension and the
two extensions provide the same enums with basically the same semantics,
except that the EXT extension is a lot more wordy due to a larger number
of features in the full OpenGL api and the OES extension has some
asymmetric limitations on when the GL_DEPTH_STENCIL and
GL_DEPTH24_STENCIL8 enums can be used as internal formats.
GL_OES_packed_depth_stencil doesn't allow the GL_DEPTH_STENCIL enum
to be passed to glRenderbufferStorage (GL_DEPTH24_STENCIL8 should be
used instead) and GL_OES_packed_depth_stencil doesn't allow
GL_DEPTH24_STENCIL8 to be passed as an internal format to glTexImage2D.
We had been handling the two extensions differently in Cogl by calling
try_creating_fbo with different flags depending on whether the OES or
EXT extension was available and passing GL_DEPTH_STENCIL to
glRenderbufferStorage when we have the EXT extension or
GL_DEPTH24_STENCIL8 with the OES extension.
To localize the code that deals with the differences between the
extensions this patch does away with the need for separate flags
so we now just have COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_DEPTH_STENCIL and
right before calling glRenderbufferStorage we check which extension we
are using to decide whether to use the GL_DEPTH_STENCIL or
GL_DEPTH24_STENCIL8 enums.
(cherry picked from commit 88a05fac6609f88c0f46d9df2611d9fbaf159939)
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 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 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)
Mesa before version 8.0.2 has a slow read pixels path that gets used
with the Intel driver where it converts all of the pixels into a
floating point representation and back even if the data is being read
into exactly the same format. There is however a faster path using the
blitter when reading into a PBO with BGRA format. It works out faster
to read into a PBO and then memcpy back out into the application's
buffer even though it adds an extra memcpy. This patch adds a
workaround in cogl_framebuffer_read_pixels_into_bitmap when it detects
this situation. In that case it will create a temporary CoglBitmap
using cogl_bitmap_new_with_size, read into it and then memcpy the data
back out.
The main impetus for this patch is that Gnome Shell has implemented
this workaround directly using GL calls but it seems like the kind of
thing that would sit better at the Cogl layer.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
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>
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>
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>
This adds cogl_onscreen_template_set_swap_throttled() api that allows
developers to specify their preference for swap buffer throttling
up-front as part of the onscreen template that is used to create a
CoglDisplay when initializing Cogl. This is desirable because some
platforms may not support configuring swap throttling on a per
framebuffer basis and also since applications often want to apply the
same policy to all onscreen framebuffers anyway.
We should not be deciding whether we need to really update the GL face
winding state at the point where a new framebuffer has been pushed, we
should be waiting until we have really been asked to flush some
framebuffer state otherwise we may do redundant work if multiple
framebuffers are pushed/popped before something is really drawn.
This integrates the face winding state tracking with the design we have
for handling most of the other framebuffer state so we benefit from the
optimizations for minimizing the cost of _cogl_framebuffer_flush_state()
Reviewed-by: Neil Roberts <neil@linux.intel.com>
We should not be deciding whether we need to really update the GL color
mask state at the point where a new framebuffer has been pushed, we
should be waiting until we have really been asked to flush some
framebuffer state otherwise we may do redundant work if multiple
framebuffers are pushed/popped before something is really drawn.
This integrates the color mask state tracking with the design we have
for handling most of the other framebuffer state so we benefit from the
optimizations for minimizing the cost of _cogl_framebuffer_flush_state()
Reviewed-by: Neil Roberts <neil@linux.intel.com>
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>
This adds CoglFramebuffer methods for accessing the clip stack. We plan
on making some optimizations to how framebuffer state is flushed which
will require us to track when a framebuffer's clip state has changed.
This api also ties in to the longer term goal of removing the need for a
default global CoglContext since these methods are all implicitly
related to a specific context via their framebuffer argument.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
This ensures we don't touch a framebuffer's matrix stack directly if we
are also relying on _cogl_framebuffer_flush_state(). We want to get to
the point where we can set dirty flags against framebuffer state at the
point it changes but that means we can't allow direct access to the
matrix stack. _cogl_texture_draw_and_read() has now been changed so it
uses cogl_framebuffer_ methods to update the matrix stacks including
adding new internal _cogl_framebuffer_push/pop_projection() functions
that allow us to set transient projections.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
It's useful to be able to query back the number of
point_samples_per_pixel that may have previously be chosen using
cogl_framebuffer_set_samples_per_pixel().
Reviewed-by: Neil Roberts <neil@linux.intel.com>
This factors out the CoglOnscreen code from cogl-framebuffer.c so we now
have cogl-onscreen.c, cogl-onscreen.h and cogl-onscreen-private.h.
Notably some of the functions pulled out are currently namespaced as
cogl_framebuffer but we know we are planning on renaming them to be in
the cogl_onscreen namespace; such as cogl_framebuffer_swap_buffers().
Reviewed-by: Neil Roberts <neil@linux.intel.com>
Cogl doesn't expose public api for blitting between framebuffers so it
doesn't make much sense to have this feature as part of the public api
currently. 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_OFFSCREEN_BLIT which cogl now checks for
internally.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
This adds support for multisample rendering to offscreen framebuffers.
After an offscreen framebuffer is first instantiated using
cogl_offscreen_new_to_texture() it is then possible to use
cogl_framebuffer_set_samples_per_pixel() to request multisampling before
the framebuffer is allocated. This also adds
cogl_framebuffer_resolve_samples() for explicitly resolving point
samples into pixels. Even though we currently only support the
IMG_multisampled_render_to_texture extension which doesn't require an
explicit resolve, the plan is to also support the
EXT_framebuffer_multisample extension which uses the framebuffer_blit
extension to issue an explicit resolve.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
This adds support for multisample based rendering of onscreen windows
whereby multiple point samples per pixel can be requested and if the
hardware supports that it results in reduced aliasing (especially
considering the jagged edges of polygons)
Reviewed-by: Neil Roberts <neil@linux.intel.com>
When creating new onscreen framebuffers we need to take the
configuration in cogl terms and translate that into a configuration
applicable to any given winsys, e.g. an EGLConfig or a GLXFBConfig
or a PIXELFORMATDESCRIPTOR.
Also when we first create a context we typically have to do a very
similar thing because most OpenGL winsys APIs also associate a
framebuffer config with the context and all future configs need to be
compatible with that.
This patch introduces an internal CoglFramebufferConfig to wrap up some
of the configuration parameters that are common to CoglOnscreenTemplate
and to CoglFramebuffer so we aim to re-use code when dealing with the
above two problems.
This patch also aims to rework the winsys code so it can be more
naturally extended as we start adding more configureability to how
onscreen framebuffers are created.
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 makes cogl_framebuffer_clear and cogl_framebuffer_clear4f public as
experimental API. Since these functions take explicit framebuffer
pointers you don't need to push/pop a framebuffer just to clear it. Also
these functions are implicitly tied to a specific CoglContext via the
framebuffer pointer unlike cogl_clear.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
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>
This adds CoglPipeline and CoglFramebuffer support for setting a color
mask which is a bit mask defining which color channels should be written
to the current framebuffer.
The final color mask is the intersection of the framebuffer color mask
and the pipeline color mask. The framebuffer mask affects all rendering
to the framebuffer while the pipeline masks can be used to affect
individual primitives.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
This adds a getter and setter for requesting dithering to be enabled.
Dithering is a hardware dependent technique to increase the visible
color resolution beyond what the underlying hardware supports by playing
tricks with the colors placed into the framebuffer to give the illusion
of other colors. (For example this can be compared to half-toning used
by some news papers to show varying levels of grey even though their may
only be black and white are available).
The results of enabling dithering are platform dependent and may have no
effect.
Signed-off-by: Neil Roberts <neil@linux.intel.com>
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>
This extends cogl_onscreen_x11_set_foreign_xid to take a callback to a
function that details the event mask the Cogl requires the application
to select on foreign windows. This is required because Cogl, for
example, needs to track size changes of a window and may also in the
future want other notifications such as map/unmap.
Most applications wont need to use the foreign xwindow apis, but those
that do are required to pass a valid callback and update the event mask
of their window according to Cogl's requirements.
It's generally useful to be able to query the width and height of a
framebuffer and we expect to need this in Clutter when we move the
eglnative backend code into Cogl since Clutter will need to read back
the fixed size of the framebuffer when realizing the stage.
This migrates all the GLX window system code down from the Clutter
backend code into a Cogl winsys. Moving OpenGL window system binding
code down from Clutter into Cogl is the biggest blocker to having Cogl
become a standalone 3D graphics library, so this is an important step in
that direction.
This gives us a way to clearly track the internal Cogl API that Clutter
depends on. The aim is to split Cogl out from Clutter into a standalone
3D graphics API and eventually we want to get rid of any private
interfaces for Clutter so its useful to have a handle on that task.
Actually it's not as bad as I was expecting though.
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.
Recently _cogl_swap_buffers_notify was added (in 142b229c5c) so that
Cogl would be notified when Clutter performs a swap buffers request for
a given onscreen framebuffer. It was expected this would be required for
the recent cogl_read_pixel optimization that was implemented (ref
1bdb0e6e98) but in the end it wasn't used.
Since it wasn't used in the end this patch removes the API.
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.
This adds the _cogl_blit_framebuffer internal function which is a
wrapper around glBlitFramebuffer. The API is changed from the GL
version of the function to reflect the limitations provided by the
GL_ANGLE_framebuffer_blit extension (eg, no scaling or mirroring).
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.
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.
This adds a stop-gap mechanism for Cogl to know when the window system
is requested to present the current backbuffer to the frontbuffer by
adding a _cogl_swap_buffers_notify function that backends are now
expected to call right after issuing the equivalent request to OpenGL
vie the platforms OpenGL binding layer. This (blindly) updates all the
backends to call this new function.
For now Cogl doesn't do anything with the notification but the intention
is to use it as part of a planned read-pixel optimization which will
need to reset some state at the start of each new frame.
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.
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.
This moves the implementation of cogl_clear into cogl-framebuffer.c as
two new internal functions _cogl_framebuffer_clear and
_cogl_framebuffer_clear4f. It's not clear if this is what the API will
look like as we make more of the CoglFramebuffer API public due to the
limitations of using flags to identify buffers when framebuffers may
contain any number of ancillary buffers but conceptually it makes some
sense to tie the operation of clearing a color buffer to a framebuffer.
The short term intention is to enable tracking the current clear color
as a property of the framebuffer as part of an optimization for reading
back single pixels when the geometry is simple enough that we can
compute the result quickly on the CPU. (If the point doesn't intersect
any geometry we'll need to return the last clear color.)