Unless the renderer has been explicitly selected via the
GSK_RENDERER environment variable, don't use it with llvmpipe.
It is important that we allow explicit setting to override
this, so we can continue to use ngl in ci, where we don't
have hw and want to test with llvmpipe.
This should address many of the "performance is terrible in
GNOME OS" complaints that are coming from people running in
VMs, etc.
We can just check if the subsurfaces contain content - and if they do,
they will be offloading and we can ignore the diff.
This essentially reverts 48740de71a
Instead of relying on diffing subsurface nodes, we track damage
generated by offloaded contents inside GskOffload.
There are 3 stages a subsurface node can be in:
1. not offloaded
Drawing is done by the renderer
2. offloaded above
The renderer draws nothing
3. offloaded below
The renderer needs to punch a hole.
Whenever the stage changes, we need to repaint.
And that can happen without the subsurface's contents changing, like
when a widget is put above the subsurface and it needs to to go from
offloaded above to below.
So we now recruit GskOffload for tracking these changes, instead of
relying on the subsurface diffing.
But we still need the subsurface diffing code to work for the
non-offloaded case, because then the offloading code is not used.
So we keep using it whenever that happens.
Not that when a subsurface transitions between being offloaded and not
being offloaded, we may diff it twice - once in the offload code and
once in the node diffing - but that shouldn't matter.
The intent of this change to get wider testing and verify that the
new renderers are production-ready. If significant problems show
up, we will revert this change for 4.14.
The new preference order is ngl > gl > vulkan > cairo.
The gl renderer is still there because we need it to support gles2
systems, and vulkan still has some rough edges in application support
(no gl area support, webkit only works with gl).
If you need to override the default renderer choice, you can
still use the GSK_RENDERER environment variable.
The Vulkan renderer can just be public API, because it doesn't expose
any Vulkan-specific APIs.
And it can just exist when compiled without Vulkan, because it can fail
to realize.
Also move get rid of the gsk/vulkan/gskvulkanrenderer.h header. It was
experimental and isn't necessary now that the renderer is included via
gsk.h.
It's better than the Cairo renderer, so use it instead.
It's still only picked once GL fails, so it will probably only ever be
picked when people use GDK_DEBUG=gl-disable, but at least it will be
picked.
per-backend renderers and GL renderers are a different thing, so treat
them as such.
Also, try the GL renderer unconditionally. The renderer initialization
code will take care of GL not being available.
We want to introduce a new one next.
Technically, this breaks API, because gsk_vulkan_renderer_new() is going
away, but practically, we're gonna bring it back once we introduce that
renderer in a few commits.
The convert_texture() path only works for the GL renderer, the new
renderers potentially use dmabuf textures as result of render_texture(),
so they need to be smarter here.
This flag must be set when creating the class or offloading
will be disabled for this renderer.
Set that flag for the GL renderer.
Fixes the Cairo and Vulkan renderer not showing Video.
Add an extra argument to pass offload info to the diffing code.
This is then used for diffing subsurface nodes differently,
depending on their offloading status.
It started out as busywork, but it does many separate things. If I could
start over, I'd take them apart into multiple commits:
1. Remove G_ENABLE_DEBUG around GDK_DEBUG_*() calls
This is not needed at all, the calls themselves take care of it.
2. Remove G_ENABLE_DEBUG around profiling code
This now enables profiling support in release builds.
3. Stop poking _gdk_debug_flags and use GDK_DEBUG_CHECK()
This was old code that was never updated.
4. Make !G_ENABLE_DEBUG turn off GDK_DEBUG_CHECK()
The code used to
#define GDK_DEBUG_CHECK(...) false
#define GDK_DEBUG(...)
which would compile away all the code inside those macros. This
means a lot of variable definitions and debug utility functions
would suddenly no longer be used and cause compiler errors.
This is a simple helper that feed a GdkTexture
through a renderer and returns the resulting
texture. This will be used to convert dmabuf
textures to 'native' textures.
Those property features don't seem to be in use anywhere.
They are redundant since the docs cover the same information
and more. They also created unnecessary translation work.
Closes#4904
Since now we have the shaders working on Windows under GLES with libANGLE using
a 3.0+ context, drop the check to fall back to the Cairo renderer when GLES is
being used.
Document the return value and more importantly, specify that a call to
`gsk_renderer_realize()` needs to be matched with a call
`gsk_renderer_unrealize()`.
Prevents issues like https://gitlab.gnome.org/GNOME/gtk/-/issues/4625
The primary goal here was to cleanup the current GL renderer to make
maintenance easier going forward. Furthermore, it tracks state to allow
us to implement more advanced renderer features going forward.
Reordering
This renderer will reorder batches by render target to reduce the number
of times render targets are changed.
In the future, we could also reorder by program within the render target
if we can determine that vertices do not overlap.
Uniform Snapshots
To allow for reordering of batches all uniforms need to be tracked for
the programs. This allows us to create the full uniform state when the
batch has been moved into a new position.
Some care was taken as it can be performance sensitive.
Attachment Snapshots
Similar to uniform snapshots, we need to know all of the texture
attachments so that we can rebind them when necessary.
Render Jobs
To help isolate the process of creating GL commands from the renderer
abstraction a render job abstraction was added. This could be extended
in the future if we decided to do tiling.
Command Queue
Render jobs create batches using the command queue. The command queue
will snapshot uniform and attachment state so that it can reorder
batches right before executing them.
Currently, the only reordering done is to ensure that we only visit
each render target once. We could extend this by tracking vertices,
attachments, and others.
This code currently uses an inline array helper to reduce overhead
from GArray which was showing up on profiles. It could be changed to
use GdkArray without too much work, but had roughly double the
instructions. Cycle counts have not yet been determined.
GLSL Programs
This was simplified to use XMACROS so that we can just extend one file
(gskglprograms.defs) instead of multiple places. The programs are added
as fields in the driver for easy access.
Driver
The driver manages textures, render targets, access to atlases,
programs, and more. There is one driver per display, by using the
shared GL context.
Some work could be done here to batch uploads so that we make fewer
calls to upload when sending icon theme data to the GPU. We'd need
to keep a copy of the atlas data for such purposes.
The only likely place where this is going to happen
is if a renderer was explicitly requested with the
GSK_RENDERER environment variable, and in that case,
it is misleading to silently use a different renderer.
Since we have now made the Win32 GL contexts share the global context as
the other backends have, we are more ready to use the GL renderer by
default on Windows as well.
Note that currently we can only enable this when not running on
OpenGL/ES as the OpenGL/ES shaders are not ready at this point, and the
OpenGL/ES support that we have from libANGLE does not support full
desktop OpenGL operations.
This is fairly substantial rewrite of the GDK backend for quartz and
renamed to macOS to allow for a greenfield implementation.
Many things have come across from the quartz implementation fairly
intact such as the eventloop integration design and discovery of
event windows from the NSEvent.
However much has been changed to fit in with the new GDK design and
how removal of child GdkWindow have been completely eliminated.
Furthermore, the new GdkPopup allows for regular NSWindow to be used
to provide popovers unlike the previous implementation.
The object design more closely follows the ideal for a GDK backend.
Views have been broken out into subclasses so that we can support
multiple GSK renderer paths such as GL and Cairo (and Metal in the
future). However mixed mode GL and Cairo will not be supported. Currently
only the Cairo renderer has been implemented.
A new frame clock implementation using CVDisplayLink provides more
accurate information about when to draw drawing the next frame. Some
testing will need to be done here to understand the power implications
of this.
This implementation has also gained edge snapping for CSD windows. Some
work was also done to ensure that CSD windows have opaque regions
registered with the display server.
** This is still very much a work-in-progress **
Some outstanding work that needs to be done:
- Finish a GL context for macOS and alternate NSView for GL rendering
(possibly using speciailized CALayer for OpenGL).
- Input rework to ensure that we don't loose remapping of keys that was
dropped from GDK during GTK 4 development.
- Make sure input methods continue to work.
- Drag-n-Drop is still very much a work in progress
- High resolution input scrolling needs various work in GDK to land
first before we can plumb that to NSEvent.
- gtk/ has a number of things based on GDK_WINDOWING_QUARTZ that need
to be updated to use the macOS backend.
But this is good enough to start playing with and breaking things which
is what I'd like to see.