At this point, we are still only changing CoglMatrix APIs internally, and
it should still produce the same output as before.
To achieve this, using graphens matrix implementation, we need to exploit
some knowledge about conventions used in Cogl and graphene respectively.
In Cogl, transformation matrices are equivalent to those of affine
transformation matrices. The convention used by graphene, however, is to
operate on matrices that are transposed compared to their affine
counterparts.
So for example, let's say we want to multiply the affine matrices A and B,
to get C.
A × B = C
The first step is to convert A and B to graphene matrices. We do this by
importing the floating point array, importing it directly using graphene.
Cogl exports its matrix to a column major floating point array. When we
import this in graphene, being row major, we end up with the same matrix,
only transposed.
Cogl Graphene
A <===> Aᵀ
B <===> Bᵀ
We then multiply these imported matrices in reverse
Bᵀ × Aᵀ
which in turn, due to ABᵀ = BᵀAᵀ, gives us
Bᵀ × Aᵀ = (A × B)ᵀ
Our original goal was to find C, thus we know that
A × B = C
That means we can shuffle things around a bit.
A × B = C
Bᵀ × Aᵀ = (A × B)ᵀ
Bᵀ × Aᵀ = Cᵀ
With the same conversion as done when going from Cogl to graphene, only
the other way around, we still end up effectively transposing the matrix
during the conversion.
Graphene Cogl
Cᵀ <===> C
Thus when converting Cᵀ to Cogl, we in fact end up with C.
(Explanation authored by Jonas Ådahl)
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
Graphene provides skewing as part of graphene_matrix_t API, and it'll
be easier for the transition to just expose similar API surfaces.
Move the matrix skew methods to CoglMatrix.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1439
Writing tests' output to a log file makes them difficult to debug when
the test might be running on an autobuilder or CI system where only
stdout/stderr are recorded. This is particularly troublesome if a
failure is only reproducible on a particular autobuilder.
Recent Automake versions have the convention that detailed output from
failing tests is written to stdout/stderr, not just to log files, when
the VERBOSE environment variable is set; borrow that convention as a
trigger for producing detailed test output.
This was originally cogl!14, but applies equally to mutter's fork of cogl.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1273
Signed-off-by: Simon McVittie <smcv@debian.org>
This resolves a couple of FIXMEs. The FIXME comments were right in
stating that not *all* journals needed flushing, only the one we
are trying to put on screen needs flushing.
However we can't eliminate all flushes because the winsys swap calls
that follow go directly into OpenGL which knows nothing about cogl
journalling. So the journal *must* be flushed before the swap, to give
OpenGL the correct state.
P.S. If this turns out to cause any bugs then the next best answer is
to just remove the FIXME comments. Because flushing is still the right
thing to do.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1362
Even when a direct client buffer has a compatible format, stride and
modifier for direct scanout, drmModePageFlip() may still fail sometimes.
From testing, it has been observed that it may seemingly randomly fail
with ENOSPC, where all subsequent attempts later on the same CRTC
failing with EBUSY.
Handle this by falling back to flipping after having composited a full
frame again.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1410
When the CoglRenderer didn't set the DMA buffer constructor vfunc, we
return NULL. What we didn't do was set the error, meaning the caller
would crash if it tried to look up why DMA buffer construction failed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1430
This will be used when screencasting monitors so that if
there's scanout in place, it'll still be possible to blit
it to a PipeWire-owned framebuffer, and stream it.
Add a new 'blit_to_framebuffer' vfunc to CoglScanout, and
implement it in MetaDrmBufferGbm.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1421
In certain situations it's desirable to keep pipelines around for
the whole lifetime of the session. In order to not leak them and
properly clean them up on shutdown, introduce a new mechanism to
create named pipelines that are bound to their correstponding
context and may be used across file boundries.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1372
In order to support the DRM formats DRM_FORMAT_ABGR16161616F and
friends, as well as the wl_shm formats WL_SHM_FORMAT_ABGR16161616F and
friends, cogl needs to have knowledge about said formats too.
We don't have a software implementation of the half point data types
however, so the pack/unpack methods remain unimplemented. We don't need
them for now, so it's not crucial that we add them.
For the GLES2 driver, currently only two formats are supported, and
since we don't currently have pack/unpack implementations, the other
formats will for now remain unsupported, until we have a half float
implementation.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/804
In the case of indirect rendering like the first frame to use mutter's
background wallpaper:
Texture_A -> FBO_B (Texture_B) -> FBO_C (screen)
we would be trying to render the contents of both FBO_B and FBO_C in
the same flush, before the contents of Texture_A had made it to FBO_B.
So when FBO_C wants to use mipmaps of Texture_B they didn't exist yet
and appeared all black. And the blackness would remain for subsequent
frames as cogl has now decided the mipmaps of FBO_B are no longer
"dirty" and don't need refreshing:
FBO_B (Texture_B) (mipmaps_dirty==FALSE but black) -> FBO_C (screen)
We must flush FBO_B before referencing Texture_B for use in rendering
FBO_C. This only happens when Texture_A changes (e.g. when the user
changes their background wallpaper) so there's no ongoing performance
penalty from this flush.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1347
The native backend had a plain counter, and the X11 backend used the
CoglOnscreen of the screen; change it into a plain counter in
ClutterStageCogl. This also moves the global frame count setting to the
frame info constuctor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We currently have mutter set a global frame counter on the frame info in
the native backend, but in order to do this from clutter, change the
frame info construction from being implicitly done so when swapping
buffers to having the caller create the frame info and passing that to
the swap buffers call.
While this commit doesn't introduce any other changes than the API, the
intention is later to have the caller be able to pass it's own state
(e.g. the global frame count) along with the frame info.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The property is deprecated and the current implementation simply
redirects it to ClutterActor::background-color, so remove it.
Also update the tests to set the background color directly.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1332
_cogl_shader_set_source_with_boilerplate and _cogl_shader_compile_real
have enough GL assumptions that it makes sense to push them into the
backend. Taken together their only callers are under driver/gl, so.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
This had been an entirely-too-GL-aware collection of renderer queries,
mostly to work around driver bugs and handle software drivers
intelligently. The driver workarounds have been removed (fix your
driver, and if you can't because it's closed-source, fix that first),
and we now delegate the am-i-software-or-not logic to the backend, so
this can all go
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
We delegate the answer through CoglDriverVtable::is_hardware_accelerated
since this is properly a property of the renderer, and not something the
cogl core should know about. The answer given for the nop driver is
admittedly arbitrary, yes it's infinitely fast but no there's not any
"hardware" making it so.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1194
If a test is not expected to succeed, then running it could be considered
to be a waste of resources, particularly if the failure might manifest
as an indefinite hang (see cogl!11), or if the test is likely to dump core
and trigger "expensive" crash-reporting mechanisms like systemd-coredump,
corekeeper, abrt or apport.
Skip the tests that are expected to fail. They can still be requested via
an environment variable, which can be set after fixing a bug to check which
tests are now passing.
Originally cogl!15, adapted for mutter's fork of cogl to use gboolean
instead of CoglBool.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1272
Signed-off-by: Simon McVittie <smcv@debian.org>
When r is 128 or more, running tests compiled with the undefined behaviour
sanitizer (ubsan) reports:
test-utils.c:312:45: runtime error: left shift of 128 by 24 places cannot be represented in type 'int'
which indeed it cannot. Force the type to be unsigned 32-bit so that we
get defined behaviour.
Similarly, in test-atlas-migration, the left-shifted guint8 is promoted
to int, which again does not have enough non-sign bits available to
left-shift a value >= 128 by 24 bits. Again, force the shift to be done
in unsigned 32-bit space.
This was originally cogl!22, but applies equally to mutter's fork of cogl.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1271
Signed-off-by: Simon McVittie <smcv@debian.org>
According to the cogl_bitmap_new_for_data documentation, the data is not
copied, so the application must keep the buffer alive for the lifetime
of the CoglBitmap. Freeing it too early led to a use-after-free in the
cogl unit tests. With that fixed, the test passes, so remove the known
failure annotation.
This AddressSanitizer trace is from the original cogl, but the bug and
fix apply equally to mutter's fork of cogl:
==6223==ERROR: AddressSanitizer: heap-use-after-free on address 0x62100001a500 at pc 0x7f3e2d4e7f4e bp 0x7ffcd9c41f30 sp 0x7ffcd9c416e0
READ of size 4096 at 0x62100001a500 thread T0
#0 0x7f3e2d4e7f4d (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x96f4d)
#1 0x7f3e260c7f6b in util_copy_box ../src/gallium/auxiliary/util/u_surface.c:131
#2 0x7f3e268c6c10 in u_default_texture_subdata ../src/gallium/auxiliary/util/u_transfer.c:67
#3 0x7f3e26486459 in st_TexSubImage ../src/mesa/state_tracker/st_cb_texture.c:1480
#4 0x7f3e26487029 in st_TexImage ../src/mesa/state_tracker/st_cb_texture.c:1709
#5 0x7f3e26487029 in st_TexImage ../src/mesa/state_tracker/st_cb_texture.c:1691
#6 0x7f3e2644bdba in teximage ../src/mesa/main/teximage.c:3105
#7 0x7f3e2644bdba in teximage_err ../src/mesa/main/teximage.c:3132
#8 0x7f3e2644d84f in _mesa_TexImage2D ../src/mesa/main/teximage.c:3170
#9 0x7f3e2cd1f7df in _cogl_texture_driver_upload_to_gl driver/gl/gl/cogl-texture-driver-gl.c:347
#10 0x7f3e2ccd441b in allocate_from_bitmap driver/gl/cogl-texture-2d-gl.c:255
#11 0x7f3e2ccd441b in _cogl_texture_2d_gl_allocate driver/gl/cogl-texture-2d-gl.c:462
#12 0x7f3e2ce3a6c0 in cogl_texture_allocate cogl/cogl-texture.c:1398
#13 0x7f3e2ce3e116 in _cogl_texture_pre_paint cogl/cogl-texture.c:359
#14 0x7f3e2cdee177 in _cogl_pipeline_layer_pre_paint cogl/cogl-pipeline-layer.c:864
#15 0x7f3e2cd574af in _cogl_rectangles_validate_layer_cb cogl/cogl-primitives.c:542
#16 0x7f3e2cdd742f in cogl_pipeline_foreach_layer cogl/cogl-pipeline.c:735
#17 0x7f3e2cd5c8b0 in _cogl_framebuffer_draw_multitextured_rectangles cogl/cogl-primitives.c:658
#18 0x7f3e2cd60152 in cogl_rectangle cogl/cogl-primitives.c:858
#19 0x5570a71ed6a0 in check_texture tests/conform/test-premult.c:103
#20 0x5570a71ed946 in test_premult tests/conform/test-premult.c:159
#21 0x5570a71df0d6 in main tests/conform/test-conform-main.c:58
#22 0x7f3e2bcd809a in __libc_start_main ../csu/libc-start.c:308
#23 0x5570a71e0869 in _start (/home/smcv/src/debian/cogl/tests/conform/.libs/test-conformance+0x33869)
0x62100001a500 is located 0 bytes inside of 4096-byte region [0x62100001a500,0x62100001b500)
freed by thread T0 here:
#0 0x7f3e2d5581d7 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x1071d7)
#1 0x5570a71ed58b in make_texture tests/conform/test-premult.c:69
previously allocated by thread T0 here:
#0 0x7f3e2d558588 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x107588)
#1 0x7f3e2d384500 in g_malloc ../../../glib/gmem.c:99
This was originally cogl!12.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1274
Signed-off-by: Simon McVittie <smcv@debian.org>
Make it possible to cause the next frame to scan out directly from the
passed CoglScannout. This makes it possible to completely bypass
compositing for the following frame.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
Instead of always swapping buffers and flipping the back buffer, make it
possible to scan out a provided buffer directly without swapping any EGL
buffers.
A buffer is passed as an object implementing the empty CoglScanout
interface. It is only possible to do this in the native backend; and the
interface is implemented by MetaDrmBufferGbm. When directly scanned out,
instead of calling gbm_surface_lock_front_buffer() to get the gbm_bo and
fbid, get it directly from the MetaDrmBufferGbm, and use that to create
the page flip KMS update.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
It isn't immediately obvious that this is impossible, because there's some
"action at a distance" going on with framebuffers that have their size
set lazily, after their textures get allocated; so let's make this a
critical warning rather than crashing.
In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.
Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172
Signed-off-by: Simon McVittie <smcv@debian.org>
A texture with no pixels isn't a useful thing to have, and breaks
assumptions elsewhere. For example, CoglFramebuffer assumes that after
a texture has been allocated, it will have width and height both greater
than 0.
In particular, this works around a crash when gnome-shell tries to blur a
background that hasn't yet had any space allocated for it - which it seems
is really an actor layout bug, but more robustness seems good to have.
Workaround for <https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2538>.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1172
Signed-off-by: Simon McVittie <smcv@debian.org>
cogl_object_[get|set]_value_object() are annotated as [get|set]-value-func
for objects and primitives, so they must be visible for any derived types
to be usable from introspection.
https://gitlab.gnome.org/GNOME/mutter/-/issues/1146
In commit d846fabda we moved to using the override color alpha, however
it was missed that the actor opacity is transferred to the PangoRenderer
through the default color alpha, and the reason it was used there.
We actually want to factor in both alpha values, in order to respect
both foreground color alpha and actor opacity. This is done on the
unpremultiplied color, so we just need to change the alpha value.
Fixes effects on text actors that involve actor opacity.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1158
pango_renderer_get_alpha() returns 0 to indicate that the alpha value
should be inherited from the environment, but we are passing it on
(and therefore making the text fully translucent).
Instead, make the text fully opaque as expected.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1156
Cogl shares some GL functions between the GLES and the big
GL drivers. Namely, it shares _cogl_driver_gl_context_init
and _cogl_driver_gl_context_deinit between these two drivers.
The plot twist is: even though these functions are shared and
their prototypes are in cogl-util-gl-private.h, they're actually
implemented inside cogl-driver-gl.c, which is strictly only
about the big GL driver.
This is problematic when building Mutter on ARM v7, where we
need to disable OpenGL, but keep GLES enabled.
Fix this by moving the shared GL functions to a shared GL file.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1151
Just like libmutter-clutter, and libmutter, mark exported symbols with
an COGL_EXPORT macro. This removes the .map and .map.in files previously
used, containing a list of semi private symbols. This symbol was out of
date, i.e. pointed to non-existing symbols, and was also replaced with
COGL_EXPORT macros.
unit_test_* symbols are exported by the help of the unit test defining
macro. test_* symbols are no longer supported as it proved unnecessary.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1059
This is so that cogl-trace.h can start using things from cogl-macros.h,
and so that it doesn't leak cogl-config.h into the world, while exposing
it to e.g. gnome-shell so that it can make use of it as well. There is
no practical reason why we shouldn't just include cogl-trace.h via
cogl.h as we do with everything else.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1059
We need the stencil buffer to consist of binary values of 0 and 1
because we're doing additions and subtractions on the buffer, so even
though this is the default, explicitely set the stencil mask to 0x1.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1096
When using a region clip and something has a rectangle clip pushed, a
special drawing method for ClutterTexts (emit_vertex_buffer_geometry()
in cogl-pango-display-list.c) starts to fail and clipping issues with
long texts (because emit_vertex_buffer_geometry() is only used for texts
longer than 25 characters) start to appear. This specifically happened
in Looking Glass, where the StViewport of the ScrollView sets a
rectangle clips and the texts are usually longer than 25 characters.
This is caused by the changing of the perspective and modelview matrix
when drawing to the stencil buffer and started happening when
region-clipping was introduced with commit 8598b654. Even though the
changing of the matrices was done before that, too, the issue probably
didn't happen because `rect->can_be_scissor` was TRUE and no stencil
buffer clipping was used at all.
To fix this, temporarily save the old matrices, then set the new ones
and restore the old ones when we're done drawing to the stencil buffer.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/2246https://gitlab.gnome.org/GNOME/mutter/merge_requests/1096
This is a winsys-specific API that allows exporting a DMA buffer fd.
The CoglDmaBufHandle structure allows passing the ownership of the
DMA buffer to whoever is using it, so the winsys doesn't need to
manually track it.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
In future patches, we'll create additional CoglFramebuffers that
will be shared via DMA-Buf with PipeWire. When recording frames,
we'll blit the current onscreen framebuffer into the shared one.
However, that presents a problem: cogl_framebuffer_blit() mimics
glBlitFramebuffer() semantics, and doesn't do an implicit flush
of the GPU command stream. As a consequence, clients may receive
unblitted or incomplete framebuffers.
We could use cogl_framebuffer_finish() to ensure the commands were
submitted to the GPU, but it is too harsh -- it blocks the CPU
completely until the commands are finished!
Add cogl_framebuffer_flush(), which ensures the command stream is
submitted to the GPU without blocking the CPU. Even though we don't
use the framebuffer specifically, it may be useful in the future
for e.g. a potential Vulkan backend to have access to the framebuffer.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086