Add support for a cogl function to set the damage_region on an onscreen
framebuffer.
The goal of this is to enable using the EGL_KHR_partial_update extension
which can potentially reduce memory bandwidth usage by some GPUs,
particularly on embedded GPUs that operate on a tiling rendering model.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2023>
These match their alpha counterparts, apart from not setting the
alpha bit. This allows our internal mashinery to more easily
distinguish whether we need a slow alpha-pass during rendering or not.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1810>
These match their alpha counterparts, apart from not setting the
alpha bit. This allows our internal mashinery to more easily
distinguish whether we need a slow alpha-pass during rendering or not.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1810>
Using "framebuffer_discard" in the list refers to an invalid extension.
The extension which introduces glDiscardFramebufferEXT is
"GL_EXT_discard_framebuffer".
With this fix, cogl_gl_framebuffer_fbo_discard_buffers can actually call
glDiscardFramebufferEXT.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1974>
A trace "anchor" is a trace head (CoglTraceHead) that is placed in a
certain scope (e.g. function scope), but then only triggered in another
scope, e.g. a condition.
This makes it possible to have optional trace instrumentation, that is
enabled only given e.g. a debug flag.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1700>
Seems glGetString(GL_RENDERER) in the wild can return NULL, causing
issues with strstr(). Handle this more gracefully by using
g_return_val_if_fail(), that assumes a NULL renderer means software
rendering.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1931>
Add utilities that allow getting the current GPU timestamp and creating
a query which completes upon completion of all operations currently
submitted on a framebuffer. Combined, these two allow measuring how long
it took the GPU to finish rendering something to a framebuffer.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
We need to call eglBindAPI() with GLES before we setup the secondary
GPU blit. We've been lucky not really needing this, as it has been
GLES default, which is what the secondary blit uses, in order to not
depend on the default, or if we want to create the secondary blit
objects after initializing cogl, we must make sure to bind the right API
at the right time.
As we need to bind the GLES API when setting up the secondary blit, we
need to make sure that cogl gets the right API bound when that's done,
so Cogl can continue working. For this, add a "bind_api()" method on the
CoglRenderer object, that will know what API is correct to bind.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
Just like we do on EGL. Two bits are required because
`cogl-clip-stack-gl.c` needs each stencil buffer element to be able to
count from 0 to 2.
This mistake probably went unnoticed because:
* Drivers usually provide more than 1 anyway; and
* Optimizations in `cogl-clip-stack-gl.c` avoid calling the code that
needs to count past 1 in most cases.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1873>
Previously we were using a mask of 0x1 for the lifetime of the stencil.
This was wrong for two reasons:
* The intersection algorithm needs to count up to a maximum 2, so a
mask of 1 would clamp to 1 instead. Then decrementing all pixels
resulted in all pixels being zero even though we want some to be 1.
So the stencil then blocked some color buffer pixels being rendered.
* The lifetime of the mask was too long. By leaving it non-zero at
the end of the function we could accidentally end up modifying the
stencil contents during our later color buffer paints.
This fixes faulty rendering of some actors seen in gnome-shell with
test case: `env COGL_DEBUG=stencilling`
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1873>
Previously we were using a mask of 0x1 for the lifetime of the stencil.
This was wrong for two reasons:
* The intersection algorithm needs to count up to a maximum 2, so a
mask of 1 would clamp to 1 instead. Then decrementing all pixels
resulted in all pixels being zero even though we want some to be 1.
So the stencil then blocked some color buffer pixels being rendered.
* The lifetime of the mask was too long. By leaving it non-zero at
the end of the function we could accidentally end up modifying the
stencil contents during our later color buffer paints.
This fixes missing rendering of some actors seen in gnome-shell with
test case: `env COGL_DEBUG=stencilling CLUTTER_PAINT=disable-clipped-redraws`
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1873>
As documented in g_once_init_enter(): "While @location has a volatile qualifier,
this is a historical artifact and the pointer passed to it should not be
volatile.". And effectively this now warns with modern glibc.
Drop the "volatile" qualifier from these static variables as it's expected.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1785>
This concerns only the cases when the presentation timestamp is received
directly from the device (from KMS or from GLX). In the majority of
cases this timestamp is already MONOTONIC. When it isn't, after this
commit, the current value of the MONOTONIC clock is sampled instead.
The alternative is to store the clock id alongside the timestamp, with
possible values of MONOTONIC, REALTIME (from KMS) and GETTIMEOFDAY (from
GLX; this might be the same as REALTIME, I'm not sure), and then
"convert" the timestamp to MONOTONIC when needed. An example of such a
conversion was done in compositor.c (removed in this commit). It would
also be needed for the presentation-time Wayland protocol. However, it
seems that the vast majority of up-to-date systems are using MONOTONIC
anyway, making this effort not justified.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
KMS and GLX device timestamps have microsecond precision, and whenever
we sample the time ourselves it's not the real presentation time anyway,
so nanosecond precision for that case is unnecessary.
The presentation timestamp in ClutterFrameInfo is in microseconds, too,
so this commit makes them have the same precision.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
A flag indicating whether the presentation timestamp was provided by the
display hardware (rather than sampled in user space).
It will be used for the presentation-time Wayland protocol.
This is definitely the case for page_flip_handler(), and I'm assuming
this is also the case for the two instances in the GLX code.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1484>
d42f1873fc introduced a semi circular
reference between the CoglFramebuffer, and CoglJournal, where
CoglJournal would keep a reference on the CoglFramebuffer when there
were any entries in the journal log.
To avoid risking leaking these objects indefinitely, when freeing
objects without doing anything that triggered a flush, CoglFramebuffer
had a "filter" on cogl_object_unref() calls, which knew
about under what conditions CoglJournal had a reference to it. When it
could detect that there were only the journal itself holding such a
reference, it'd flush the journal, effectively releasing the reference
the journal held, thus freeing itself, as well as the journal.
When CoglFramebuffer was ported to be implemented using GObject instead
of CoglObject, this "filter" was missed, causing not only awkward but
infrequent leaks, but also situations where we'd flush journals when
only the journal itself held the last reference to the framebuffer,
meaning the journal would free the framebuffer, thus itself, in the
middle of flushing, causing memory corruption and crashes.
A way to detect this, by asserting on CoglObject reference count during
flush, is by adding the `g_assert()` as described below, which will
assert instead cause memory corruption.
void
_cogl_journal_flush (CoglJournal *journal
{
...
_cogl_journal_discard (journal);
+ g_assert (journal->_parent.ref_count > 0);
...
}
Fix this by making CoglFramebuffer the owner of the journal, which it
already was, and remove any circle referencing that was there before, as
it is not needed given that the CoglFramebuffer pointer is guaranteed to
be valid for the lifetime of CoglJournal as the framebuffer is the owner
of the journal.
However, to not miss flushing before tearing down, which is important as
this flushes painting calls to the driver that is important for e.g.
using the result of those journal entries, flush the journal the first
time cogl_framebuffer_dispose() is called, before doing anything else.
This also adds a test case. Without having broken the circular
reference, the test would fail on g_assert_null (offscreen), as it would
have been "leaked" at this point, but the actual memory corruption would
be a result of the `cogl_texture_get_data()` call, which flushes the
framebuffer, and causes the 'mid-flush' destruction of the journal
described above. Note that the texture keeps track of dependent
framebuffers, but it does not hold any references to them.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1474
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1735>
It's currently only handled by a surface backend framebuffer (assuming
the right GLX extensions are available). While it's theoretically
possible to do the same with the offcreen by having multiple textures,
it's not supported, so leave the FBO variant with a single warning if we
end up there.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
The object was still pretending to be CoglFramebuffer itself, by using
naming and calling conventions making it seem like that. Fix that by
passing around the driver instead of the framebuffer.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>