Since we do all offscreen rendering upside down (so that we can have the
origin for texture coordinates be the top left of textures for the cases
where offscreen draw buffers are bound to textures) we don't need to flip
data read back from an offscreen framebuffer before we we return it to the
user.
I was originally expecting the code not to handle offset viewports or
viewports with a different size to the framebuffer, but it turns out the
code worked fine. In the process though I think I made the code slightly
more readable.
cogl_viewport only accepted a viewport width and height, but there are times
when it's also desireable to have a viewport offset so that a scene can be
translated after projection but before hitting the framebuffer.
Because Cogl defines the origin of viewport and window coordinates to be
top-left it always needs to know the size of the current window so that Cogl
window/viewport coordinates can be transformed into OpenGL coordinates.
This also fixes cogl_read_pixels to use the current draw buffer height
instead of the viewport height to determine the OpenGL y coordinate to use
for glReadPixels.
First a few notes about Cogl coordinate systems:
- Cogl defines the window origin, viewport origin and texture coordinates
origin to be top left unlike OpenGL which defines them as bottom left.
- Cogl defines the modelview and projection identity matrices in exactly the
same way as OpenGL.
- I.e. we believe that for 2D centric constructs: windows/framebuffers,
viewports and textures developers are more used to dealing with a top left
origin, but when modeling objects in 3D; an origin at the center with y
going up is quite natural.
The way Cogl handles textures is by uploading data upside down in OpenGL
terms so that bottom left becomes top left. (Note: This also has the
benefit that we don't need to flip the data we get from image decoding
libraries since they typically also consider top left to be the image
origin.)
The viewport and window coords are mostly handled with various y =
height - y tweaks before we pass y coordinates to OpenGL.
Generally speaking though the handling of coordinate spaces in Cogl is a bit
fragile. I guess partly because none of it was design to be, it just
evolved from how Clutter defines its coordinates without much consideration
or testing. I hope to improve this over a number of commits; starting here.
This commit deals with the fact that offscreen draw buffers may be bound to
textures but we don't "upload" the texture data upside down, and so if you
texture from an offscreen draw buffer you need to manually flip the texture
coordinates to get it the right way around. We now force offscreen
rendering to be flipped upside down by tweaking the projection matrix right
before we submit it to OpenGL to scale y by -1. The tweak is entirely
hidden from the user such that if you call cogl_get_projection you will not
see this scale.
We were ignoring the possibility that the current modelview matrix may flip
the incoming rectangle in which case we didn't calculate a valid scissor
rectangle for clipping.
This fixes: http://bugzilla.o-hand.com/show_bug.cgi?id=1809
(Clipping doesn't work within an FBO)
Cogl's support for offscreen rendering was originally written just to support
the clutter_texture_new_from_actor API and due to lack of documentation and
several confusing - non orthogonal - side effects of using the API it wasn't
really possible to use directly.
This commit does a number of things:
- It removes {gl,gles}/cogl-fbo.{c,h} and adds shared cogl-draw-buffer.{c,h}
files instead which should be easier to maintain.
- internally CoglFbo objects are now called CoglDrawBuffers. A
CoglDrawBuffer is an abstract base class that is inherited from to
implement CoglOnscreen and CoglOffscreen draw buffers. CoglOffscreen draw
buffers will initially be used to support the
cogl_offscreen_new_to_texture API, and CoglOnscreen draw buffers will
start to be used internally to represent windows as we aim to migrate some
of Clutter's backend code to Cogl.
- It makes draw buffer objects the owners of the following state:
- viewport
- projection matrix stack
- modelview matrix stack
- clip state
(This means when you switch between draw buffers you will automatically be
switching to their associated viewport, matrix and clip state)
Aside from hopefully making cogl_offscreen_new_to_texture be more useful
short term by having simpler and well defined semantics for
cogl_set_draw_buffer, as mentioned above this is the first step for a couple
of other things:
- Its a step toward moving ownership for windows down from Clutter backends
into Cogl, by (internally at least) introducing the CoglOnscreen draw
buffer. Note: the plan is that cogl_set_draw_buffer will accept on or
offscreen draw buffer handles, and the "target" argument will become
redundant since we will instead query the type of the given draw buffer
handle.
- Because we have a common type for on and offscreen framebuffers we can
provide a unified API for framebuffer management. Things like:
- blitting between buffers
- managing ancillary buffers (e.g. attaching depth and stencil buffers)
- size requisition
- clearing
This ensures that glViewport is called before the first stage paint.
Previously _clutter_stage_maybe_setup_viewport (which is done before we
start painting) was bailing out without calling cogl_setup_viewport because
the CLUTTER_STAGE_IN_RESIZE flag may be set if the stage was resized before
the first paint. (NB: The CLUTTER_STAGE_IN_RESIZE flag isn't removed until
we get an explicit event back from the X server since the window manager may
choose to deny/alter the resize.)
We now special case the first resize - where the viewport hasn't previously
been initialized and use the requested geometry to initialize the
glViewport without waiting for a reply from the server.
Over time the two cogl-fbo.c files have needlessly diverged as bug fixes or
cleanups went into one version but not the other. This tries to bring them
back in line with each other. It should actually be simple enough to move
cogl-fbo.c to be a common file, and simply not build it for GLES 1.1, so
maybe I'll follow up with such a patch soon.
The comment just said: "Some implementation require a clear before drawing
to an fbo. Luckily it is affected by scissor test." and did a scissored
clear, which is clearly a driver bug workaround, but for what driver? The
fact that it was copied into the gles backend (or vica versa is also
suspicious since it seems unlikely that the workaround is necessary for both
backends.)
We can easily restore the workaround with a better comment if this problem
really still exists on current drivers, but for now I'd rather minimize
hand-wavey workaround code that can't be tested.
Just like CLUTTER_CHECK_VERSION does version checking at compile
time, we need a way to verify the version of the library that we
are linking against. This is mostly needed for language bindings
and for run-time loadable modules -- when we'll get those.
Otherwise you can't use the alpha channel of the vertex colors unless
the material has a texture with alpha or the material's color has
alpha less than 255.
Apparently, on 64bit systems the floating point noise is enough
to screw up the float-to-int truncation.
The solution is to round up by 0.5 and then use floorf(). This
gives predictable and correct results on both 32bit and 64bit
systems.
When calling remove_child_meta() we check if there is a LayoutMeta
already attached to the Actor, and if that LayoutMeta matches the
(manager, container, actor) tuple. If the LayoutMeta does not match,
though, we create a new LayoutMeta instance -- in order to remove it
right afterwards.
Instead of doing this, we can simply check for a matching LayoutMeta
and if present, remove it.
In case of an existing, non-matching LayoutMeta, we're left with a
dangling instance, but it does not matter: the removal happens in the
unparenting phase of a ClutterContainer, so either the Actor will be
destroyed and thus the LayoutMeta will be disposed along with it; or
it will be parented to another container, and thus the LayoutMeta
will be replaced.
A ClutterBox might not have a ClutterLayoutManager instance
associated -- for instance, during destruction. We should check
for one before calling methods on it.
When cogl_texture_new_from_data() fails in clutter_texture_set_from_data()
and no GError is provided, the clutter app will segfault when dereferencing
the GError ** and emitting LOAD_FINISHED signal.
Based on a patch by: Haakon Sporsheim <haakon.sporsheim@gmail.com>
http://bugzilla.openedhand.com/show_bug.cgi?id=1806
Some changes to make COGL pass distcheck with Automake 1.11 and
anal-retentiveness turned up to 11.
The "major" change is the flattening of the winsys/ part of COGL,
which is built directly inside libclutter-cogl.la instead of an
intermediate libclutter-cogl-winsys.la object.
Ideally, the whole COGL should be flattened out using a
quasi-non-recursive Automake layout; unfortunately, the driver/
sub-section ships with identical targets and Automake cannot
distinguish GL and GLES objects.
If an actor calls directly or indirectly clutter_actor_queue_relayout()
on itself from within the allocate() implementation it will cause a
relayout cycle. This is usually a condition that should be checked by
ClutterActor and we should emit a warning if it is verified.
ClutterActor should check whether the current instance is being
destroyed and avoid performing operations like:
• queueing redraws
• queueing relayouts
It should also warn if the actor is being parented to an actor
currently being destroyed.
When showing a warning in the state checks we perform to verify that
the invariants are maintained when showing, mapping and realizing, we
should also print out the name of the actor failing the checks. If the
actor has no name, the GType name should be used as a fallback.
When defining an Alpha in ClutterScript we should allow setting
the alpha function by using a custom property. This makes it
possible to have both:
{
"id" : "behaviour-1",
"type" : "ClutterBehaviourDepth",
"alpha" : { "timeline" : "timeline-1", "function" : "alpha_func" },
...
}
And:
{
"id" : "alpha-1",
"type" : "ClutterAlpha",
"timeline" : "timeline-1",
"function" : "alpha_func"
},
{
"id" : "behaviour-1",
"type" : "ClutterBehaviourDepth",
"alpha" : "alpha-1",
...
}
The latter allows defining a single alpha function for multiple
behaviours.
The block that allows setting a GObject property holding an object
instance is conditionally depending on the USE_PIXBUF define. This
makes it impossible to reference an object inside ClutterScript on
platforms not using GdkPixbuf.
When an actor is hidden, the parent actor is not required to
size request or allocate it. (ClutterGroup does, but, for example,
NbtkBoxLayout doesn't.) This means that the
needs_width_request/needs_height_request/needs_allocate can be
stale when we go to show it again - they are set for the actor
but not the parent. Explicitly setting them to FALSE avoids
clutter_actor_relayout() improperly short-circuiting.
http://bugzilla.openedhand.com/show_bug.cgi?id=1831
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
The change in commit 3bbc96e17e moved the
:text property setter to use set_text_internal(); this function does not
invalidate the Layout cache and does not queue a relayout, thus breaking
the behaviour of ClutterText when setting the contents of the actor using
the property.
http://bugzilla.openedhand.com/show_bug.cgi?id=1851
Since we no longer depend on the GL matrix API in Cogl we can remove a lot
of wrapper code from the GLES 2 backend. This is particularly nice given
that there was no code shared between the cogl-matrix-stack API and gles2
wrappers so we had a lot of duplicated logic.
The indirection through this API isn't necessary since we no longer
arbitrate between the OpenGL matrix API and Cogl's client side API. Also it
doesn't help to maintain an OpenGL style matrix mode API for internal use
since it's awkward to keep restoring the MODELVIEW mode and easy enough to
directly work with the matrix stacks of interest.
This replaces use of the _cogl_current_matrix API with direct use of the
_cogl_matrix_stack API. All the unused cogl_current_matrix API is removed
and the matrix utility code left in cogl-current-matrix.c was moved to
cogl.c.
This cache of the gl matrix mode lets us avoid repeat calls to glMatrixMode
in _cogl_matrix_stack_flush_to_gl when we have lots of sequential modelview
matrix modifications.
This goes a bit further than the previous patch, and as a special case
we now simply represent identity matrices using a boolean, and only
lazily initialize them when they need to be modified.
The journal always uses an identity matrix since it uses software
transformation. Currently it manually uses glLoadMatrix since previous
experimentation showed that the cogl-matrix-stack gave bad performance, but
it would be nice to fix performance so we only have to care about one path
for loading matrices.
For the common case where we do:
cogl_matrix_stack_push()
cogl_matrix_stack_load_identity()
we were effectively initializing the matrix 3 times. Once due to use of
g_slice_new0, then we had a cogl_matrix_init_identity in
_cogl_matrix_state_new for good measure, and then finally in
cogl_matrix_stack_load_identity we did another cogl_matrix_init_identity.
We don't use g_slice_new0 anymore, _cogl_matrix_state_new is documented as
not initializing the matrix (instead _cogl_matrix_stack_top_mutable now
takes a boolean to choose if new stack entries should be initialised) and so
we now only initialize once in cogl_matrix_stack_load_identity.
This relates back to an earlier commitment to stop using the OpenGL matrix
API which is considered deprecated. (ref 54159f5a1d)
The new texture matrix stacks are hung from a list of (internal only)
CoglTextureUnit structures which the CoglMaterial code internally references
via _cogl_get_texure_unit ().
So we would be left with only the cogl-matrix-stack code being responsible
for glMatrixMode, glLoadMatrix and glLoadIdentity this commit updates the
journal code so it now uses the matrix-stack API instead of GL directly.
• Fix list_stages() and peek_stages() documentation
• Fix clutter_text_set_preedit_string() arguments in the header
to match source and documentation
• Add clutter_units_cm() to the private section for Units
• Rename the LayoutManager section
• Add FlowLayout:homogeneous accessors