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>
Mutter needs to fetch the X11 Window ID from the onscreen and did that
by using an X11 specific API on the CoglOnscreen, where the X11 type was
"expanded" (Window -> uint32_t). Change this by introducing an interface
called CoglX11Onscreen, implemented by both the Xlib and GLX onscreen
implementations, that keeps the right type (Window), while avoiding X11
specific API for CoglOnscreen.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
Mutter didn't use the APIs for resizeability of CoglOnscreens but
managed the size itself. For the native backend we don't ever resize
onscreens. Thus, remove this unused functionality.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
The framebuffer driver was lazilly initialized on demand in some cases
(onscreen), and up front other (offscreen). Replace this with a more
predictable up front initialization, done at framebuffer allocation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
The CoglGLFramebuffer (not CoglGlFramebuffer) is a private struct for
keeping track of the framebuffer object. To avoid confusing with
CoglGlFramebuffer, rename it CoglGlFbo.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
This way we can have separate types per modes of operation (e.g. if it's
backed by an EGLSurface or single texture), instead of being dependent
on a certain type (onscreen vs offscreen).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
Instead of calling "init_onscreen()" on two different separate vtables
from the allocate() funtion, just have the CoglOnscreen sub types
themself implement allocate() and initialize in there.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
Thins means that e.g. MetaOnscreenNative now inherits CoglOnscreenEgl,
which inherits CoglOnscreen which inherits CoglFramebuffer, all being
the same GObject instance.
This makes it necessary to the one creating the onscreen to know what it
wants to create. For the X11 backend, the type of renderer (Xlib EGL or
GLX) determines the type, and for the native backend, it's currently
always MetaOnscreenNative.
The "winsys" vfunc entries related to onscreens hasn't been moved yet,
that will come later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
The mutter naming convention for types and their instance variables is:
Type name:
[Namespace][BaseName][SubType]
Instance name:
[base_name]_[sub_type]
This means that e.g. CoglOnscreenGLX is renamed CoglOnscreenGlx, and
glx_onscreen is renamed onscreen_glx. This is in preparation for
GObjectification.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>
The GLX winsys code had split up the GLX onscreen implementation into an
Xlib part (with a struct name confusingly enough identical to that of
the onscreen in the actual Xlib winsys). To remove some confusion,
combine the two.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>