Compare commits

..

231 Commits

Author SHA1 Message Date
Matthias Clasen d14a5acd4e gsk: Support hue interpolation in cairo
Since cairos gradient code isn't flexible enough  to let us
interpolate in oklch, add additional color stops and let cairo
interpolate in the ccs. This isn't as accurate as interpolating
in oklch, but it gets an ok result for fallback situations.
2024-10-04 23:32:44 -04:00
Matthias Clasen 4de67b2fe5 gtk: Don't optimize gradients away too eagerly
Even if the stops are the same color, with hue interpolation,
it might still make a beautiful rainbow.
2024-10-04 21:21:32 -04:00
Matthias Clasen 6d878bd21c css: Pass oklab and oklch color states through 2024-10-04 21:16:36 -04:00
Matthias Clasen 965fd476a5 node parser: handle oklab and oklch 2024-10-04 21:16:36 -04:00
Matthias Clasen 3bce60c433 gsk: Handle hue-interpolation in ops
Make all our gradient ops adjust the hue according to
the hue interpolation.

This is currently modifying the values in the vertex array.
If reading those values back is bad, we may need to change that.
2024-10-04 21:16:36 -04:00
Matthias Clasen 8083456599 gsk: Handle oklab and oklch color states 2024-10-04 21:16:35 -04:00
Matthias Clasen 2a1b8c4fcc gdk: Add oklab and oklch color states
These are new default color states.

Tests for the tf and matrices included.
2024-10-04 20:37:09 -04:00
Matthias Clasen ed9e759917 Add a test for gradient rendering
This tests that gradients get interpolated differently in
srgb and rec2100-linear.
2024-10-04 17:13:27 -04:00
Matthias Clasen f69d7f804a tests: Use the new gradient node apis
Properly replay gradient nodes with color state information.
2024-10-04 17:13:27 -04:00
Matthias Clasen 4368583cbe gsk: Make non-default interpolation cs work
If the interpolation color state is not a default one, use the
offscreen we already for rendering big gradients, interpolate
the gradient into it, and then use a cicp convert shader to
convert the result to the ccs.
2024-10-04 15:08:34 -04:00
Matthias Clasen c44efc31ba inspector: Show full gradient information
Use the new gradient apis to show color stops, and show
interpolation color state and hue interpolation as well.
2024-10-04 15:08:34 -04:00
Matthias Clasen 3c6cc6c362 gtk: Use the new private snapshot api
Preserve color states from css as much as possible.
2024-10-04 15:08:34 -04:00
Matthias Clasen eff0d5b37b gtk: Add new snapshot api for gradients
These are private snapshot apis that uses the new gradient node
constructors to create nodes with the given color states.
2024-10-04 15:08:34 -04:00
Matthias Clasen 579878a855 css: Add helper functions
We need to be able to translate css color spaces into gdk color
states, and css hue interplation into gsk hue interpolation.
2024-10-04 15:08:34 -04:00
Matthias Clasen b43294c1c3 nodeparser: Handle color states for gradients
Test included.
2024-10-04 15:08:34 -04:00
Matthias Clasen 5d8e801d80 gsk: Use new gradient node apis
This requires changing the gradient ops again too,
so we can pass GskColorStop2 arrays to them.
2024-10-04 14:51:33 -04:00
Matthias Clasen 4c7631a645 gsk: Add new private gradient node api
These new apis take GskColorStop2 instead of GskColorStop.
2024-10-04 14:50:23 -04:00
Matthias Clasen 9fe78d9f75 cairo: Add gdk_cairo_pattern_add_color_stop_color
This is a generalization of gdk_cairo_pattern_add_color_stop_rgba_ccs
to allow non-sRGB sources.
2024-10-04 14:50:23 -04:00
Matthias Clasen 9a7d84b441 gsk: Change gradient op apis
Pass the ccs, opacity, interpolation color state and hue
interpolation explicitly, and change the argument order to
match other ops.

Since we now apply opacity in the op, change the node processor
to pass colors as-is. For now, it always passes GDK_COLOR_STATE_SRGB
for ics and GSK_HUE_INTERPOLATION_SHORTER for hue interpolation.
2024-10-04 14:50:11 -04:00
Matthias Clasen 1fe9918f3c gsk: Add GskHueInterpolation enum
This will be used in gradient-related apis.
2024-10-04 14:48:50 -04:00
Matthias Clasen cd04aa1cd4 gsk: Change a precondition
It is nicer if gsk_gpu_color_states_create_explicit (a, a) works
regardless of whether the two are default colorstates or not.

The gradient shaders will rely on this when the ics is a non-default
color state and we use ccs == ics.
2024-10-04 14:48:50 -04:00
Matthias Clasen ac1c0d37c6 Merge branch 'gstreamer-no-gl' into 'main'
gstreamer: Fix gl context creation

See merge request GNOME/gtk!7796
2024-10-04 15:57:46 +00:00
Matthias Clasen ea6bcdbd3d gstreamer: Fix gl context creation
We may not have a surface (since realizing media streams is optional),
so use the display when creating a gl context.
2024-10-04 11:18:48 -04:00
Matthias Clasen fe83b06eaf Merge branch 'gbsneto/fix-a11y-nonwidget-recurse' into 'main'
atcontext: Only recurse parents for non-widget accessibles

Closes #7058

See merge request GNOME/gtk!7793
2024-10-04 13:19:07 +00:00
Matthias Clasen be5fd3d89f Merge branch 'gstreamer-no-gl' into 'main'
gstreamer: Make dmabufs work without GL

Closes #7048

See merge request GNOME/gtk!7787
2024-10-04 13:09:42 +00:00
Matthias Clasen bef38bd9c4 gstreamer: Tweak gl context handling
Just create the context when it is needed.
2024-10-04 08:21:58 -04:00
Georges Basile Stavracas Neto 06f08ea804 atcontext: Only recurse parents for non-widget accessibles
The original intent was to only realize parents recursively for
non-widget accessible objects. The implementation, however, always
try to realize parents. In the case of GtkStackPage, which is a
non-widget accessible with a widget accessible child, this breaks.

Only realize non-widget accessible parents recursively if the
current accessible is not a widget as well.

Closes https://gitlab.gnome.org/GNOME/gtk/-/issues/7058
Fixes 6074a18e3e
2024-10-04 09:19:57 -03:00
Matthias Clasen 79bb805a02 gstreamer: Simplify
Add a uses-gl property to our sink implementation, and use
it in the paintable code. This avoids juggling a second gl
context, with the risk of leaking it.
2024-10-04 07:49:07 -04:00
Matthias Clasen d70c005021 gstreamer: Improve caps handling
Separate out the caps for dmabuf, gl and memory and add them
when appropriate.
2024-10-04 07:44:20 -04:00
Matthias Clasen 9fc7d8e947 Restructure gtk_gst_paintable_video_renderer_create_video_sink
This code had too many early exits and was leaking GL contexts
and Gstreamer elements. Simplify.
2024-10-04 07:44:20 -04:00
Matthias Clasen b06ac9826c gstreamer: Use the default display if needed
Calling gtk_media_stream_realize is not mandatory, but we can
still try to make dmabufs happen. Tested by removing the realize
call from GtkVideo and using GDK_DISABLE=gl.
2024-10-04 07:44:20 -04:00
Matthias Clasen 94cacd79f9 gstreamer: Restructure gtk_gst_sink_propose_allocation
Split this clearly into two cases: dmabuf or gl memory.
2024-10-04 07:44:20 -04:00
Matthias Clasen 17d3631605 gstreamer: Make dmabufs work without GL
We only need a display to negotiate dmabuf formats. Pass that
directly, instead of getting the display of the GL context as
we did so far.

With this,

GSK_RENDERER=vulkan GL_DISABLE=gl gtk4-demo --run video_player

still uses dmabufs.

Related: #7048
2024-10-04 07:44:20 -04:00
Matthias Clasen 3b027cf466 Merge branch 'for-main' into 'main'
gpu: Add GSK_GPU_DISABLE=repeat

See merge request GNOME/gtk!7791
2024-10-04 00:48:58 +00:00
Matthias Clasen 5d4f2822d0 Fix testsuite setup
We no longer say GDK_DEBUG=gl-prefer-gl, we say GDK_DISABLE=gles-api.
2024-10-03 20:11:00 -04:00
Benjamin Otte 5a11ee7b9c gpu: Add GSK_GPU_DISABLE=repeat
This is useful for testing of repeat nodes - both performance
and conformance, and potentially even driver issues with GL_REPEAT.

We have code for manual repeating anyway, so adding a flag to force
always using it is easy.
2024-10-03 20:11:00 -04:00
Matthias Clasen 874410129e Merge branch 'fix-scrolled-window-criticals' into 'main'
scrolledwindow: Fix measuring non-overlay, always visible scrollbars

See merge request GNOME/gtk!7790
2024-10-03 17:52:16 +00:00
Sergey Bugaev 2cf1651235 scrolledwindow: Fix measuring non-overlay, always visible scrollbars
The last part of logic in gtk_scrolled_window_measure () that accounted
for scrollbars was handling the hscrollbar first, and vscrollbar second.
For each of them, it looked at the orientation we're being measured in,
and either added or MAX'ed scrollbar's size request into ours (or not,
depending on scrollbar policy and whether overlay scrolling is used).

In case of GTK_ORIENTATION_HORIZONTAL, this resulted in

    // MAX in hscrollbar width.
    minimum_req = MAX (minimum_req, min_scrollbar_width + sborder.left + sborder.right);
    // Add in vscrollbar width.
    minimum_req += min_scrollbar_width;

whereas for GTK_ORIENTATION_VERTICAL, it was

    // Add in hscrollbar height.
    minimum_req += min_scrollbar_height;
    // MAX in vscrollbar height.
    minimum_req = MAX (minimum_req, min_scrollbar_height + sborder.top + sborder.bottom);

The former is correct and the latter is wrong: we should be adding the
size requests of the scrollbars together, and MAX'ing them with the
content size request.

Fix this by refactoring the logic to first handle the MAX'ing, and then
the addition.

This fixes the following criticals:

Gtk-CRITICAL **: 17:26:51.406: Allocation height too small. Tried to allocate 15x31, but GtkScrollbar 0x2a00fac0 needs at least 15x46.

that were happening when all of:
- scrollbar policy was set to ALWAYS,
- overlay scrolling was disabled,
- the scrollable child was really small.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 19:04:15 +03:00
Matthias Clasen ad2221ce29 Merge branch 'fix-filechooser-crash' into 'main'
window: Fix crash when unexporting unrealized window

See merge request GNOME/gtk!7769
2024-10-03 15:53:44 +00:00
Sergey Bugaev 6dd0be2f06 printdialog: Call gtk_window_unexport_handle
We need to track the handle and properly unexport it.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 17:14:11 +03:00
Sergey Bugaev 2103ab99a5 window: Fix crash when unexporting unrealized window
It is possible that the window gets unrealized while a handle to its
surface is exported. This, naturally, invalidates the handle, so there
is nothing left to unexport. We should just note that and do nothing,
rather than crashing.

Fixes a crash when a portal-backed file dialog parented to a window is
closed after the window it was parented to.

Reported-by: Ivan Molodetskikh <yalterz@gmail.com>
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 17:14:11 +03:00
Sergey Bugaev d7ab7e9628 window: Fix a typo
Fortunately, it didn't impact string length.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-10-03 17:14:11 +03:00
Matthias Clasen 3d7ac47e5e Merge branch 'gbsneto/atspi-socket-realize' into 'main'
atcontext: Always realize non-widget accessibles

See merge request GNOME/gtk!7784
2024-10-03 09:46:40 +00:00
Chun-wei Fan c373e2c76b Merge branch 'gdk-win32-rename' into 'main'
GDK/Win32: Rename instances of "window" as in the GTK+-3.x-era GdkWindow as appropriate

See merge request GNOME/gtk!7738
2024-10-03 05:44:07 +00:00
Matthias Clasen ec3b27bb68 Merge branch 'for-main' into 'main'
Don't draw transparent fillers

See merge request GNOME/gtk!7788
2024-10-03 03:43:54 +00:00
Benjamin Otte 5b87dba1a3 Merge branch 'wip/otte/for-main' into 'main'
picture: Only queue_resize() if necessary

See merge request GNOME/gtk!7786
2024-10-03 01:10:53 +00:00
Matthias Clasen 12dcaf1e7a Don't draw transparent fillers
Repeat nodes take child bounds that let us achieve the desired
spacing without resorting to transparent fillers.
2024-10-02 21:05:21 -04:00
Benjamin Otte 5031f30f28 picture: Only queue_resize() if necessary
When setting a new paintable, we don't need to queue_resize() when it's
the same size as the old paintable.

This is especially useful when pictures are used in a listview or
gridview and different rows display images of the same size.
2024-10-03 02:56:12 +02:00
Matthias Clasen ad465e81aa Merge branch 'for-main' into 'main'
ci: Stop using catch

See merge request GNOME/gtk!7785
2024-10-03 00:41:40 +00:00
Matthias Clasen 39374c7209 gtk4-demo: Make demos standalone
Making the demo windows transient and modal makes gnome-shell
treat them like dialogs, which is not right.
2024-10-02 19:15:31 -04:00
Matthias Clasen 170a1cd941 ci: Stop using catch
It is useful to track down mysterious crashes in ci, but it causes
sporadic test failures, so disable it for now, until we have another
mysterious crash.
2024-10-02 19:15:31 -04:00
Georges Basile Stavracas Neto 6074a18e3e atcontext: Always realize non-widget accessibles
Upon joining the a11y tree. And do so recursively, as long as the parent
is also not a widget.

As for the explanation, please grab a mug of your favorite drink. It's
a little complicated.

GTK realizes AT contexts in 3 situations:

 1. When it's a toplevel, it's realized unconditionally
 2. When the widget is focused
 3. When the accessible is appended to a realized parent

Most importantly, GTK lazily realizes accessibles, and does not realize
child accessibles recursively.

Clearly, conditions 1 and 2 only ever happen for GtkWidgets, which are
accessible objects themselves. These two conditions will handle the vast
majority of cases of apps and platform libraries.

However, there are non-widget accessibles out there. GTK itself offers a
non-widget accessible implementation - GtkAtspiSocket - which is used by
WebKitGTK.

Now, let's look at WebKitGTK use case. It'll demonstrate the problem
nicely.

WebKitGTK creates the GtkAtspiSocket object *after* loading most of the
page. At this point, there are 2 possibilities:

 1. The web view widget is focused. In this case, the AT context of the
    web view is realized, and GTK will realize the GtkAtspiSocket when
    it is added to the a11y tree (condition 3 above).

 2. The web view widget is *not* focused. At some point the user focuses
    the web view, and GTK will realize the AT context of the web view.
    But remember, GTK does not realize child accessibles! That means
    GtkAtspiSocket won't be realized.

This example demonstrates a general problem with non-widget accessibles:
non-widget accessibles cannot trigger conditions 1 and 2, so they're
never realized. The only way they're realized in if they happen to be
added to an already realized accessible (condition 3).

To fix that, the following is proposed: always realize non-widget
accessibles, and also of their non-widget accessible parents. This is
not ideal, of course, as it might generate some D-Bus chattery, but GTK
does not have enough information to realize these objects at more
appropriate times.
2024-10-02 16:07:30 -03:00
Georges Basile Stavracas Neto 5d5b612630 atcontext: Factor out some code
Move the code that realizes an AT context if the parent is realized,
into to a separate function. This will make the next patch easier to
read.

No functional changes.
2024-10-02 14:51:33 -03:00
Matthias Clasen 5942252175 Merge branch 'scrolling-underline-demo' into 'main'
gtk4-demo: Add another scrolling case

See merge request GNOME/gtk!7781
2024-10-02 17:32:22 +00:00
Benjamin Otte 9a3898fe89 Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Change a debug message

See merge request GNOME/gtk!7782
2024-10-02 12:36:02 +00:00
Benjamin Otte c6a3efaf70 dmabuf: Unify initialization debug messages
... and print if a format is advertised.

We now use the same style of message and use the term "advertise" for
formats that will be available via GdkDisplay::dmabuf-formats and
"supports" for formats the backend pretends it can handle but don't
want to advertise them.
2024-10-02 13:39:48 +02:00
Benjamin Otte 9870234294 dmabuf: Change a debug message
Instead of only printing the advertised dmabuf formats, print all
supported ones. This is now useful information because we will try to
use them when downloading.

Fixes me looking like I don't know what I'm talking about on IRC when
claiming that llvmpipe can't do dmabufs, because it only supports linear
ones and we didn't print those.
2024-10-02 13:39:48 +02:00
Matthias Clasen 64ecb972cf gtk4-demo: Add another scrolling case
Add a case for text with various underlines. In particular error
underlines, since these are more complicated and use repeat nodes
and offscreens.
2024-10-02 07:21:41 -04:00
Matthias Clasen ded6d400d7 gtk-demo: Make scrolling benchmark resizable
The small window does not really tax our renderer much. Make it
resizable, so we can test fullscreen scrolling.
2024-10-02 07:20:36 -04:00
Chun-wei Fan 979a37d3f7 GDK/Win32: Rename _gdk_win32_get_window_rect()
... to gdk_win32_get_surface_hwnd_rect(), so that things are a bit
clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 270e6165f4 GDK/Win32: Rename GtkShowWindow() to GtkShowSurfaceHWND()
Makes this function a bit clearer on what is being done.
2024-10-02 12:52:44 +08:00
Chun-wei Fan df51d474fc GDK/Win32: Rename "window" for event handling code
We want to make the distinction between GdkSurface's and native Windows
HWNDs clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 1e0ab6f249 gdkprivate-win32.h: Rename "window" as needed
We want to make the distinction between GdkSurface's and native Windows
HWNDs clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan deb4de6332 gdkvulkancontext-win32.c: Rename "window" as needed
We want to make the distinction between GdkSurface's and native Windows
HWNDs clear, and we don't want to confuse between GdkSurface's and
Vulkan surfaces.
2024-10-02 12:52:44 +08:00
Chun-wei Fan b4c7dd770c GDK/Win32: Rename "window" for DND/clipboard code
We want to make the distinction between GdkSurface's and native Windows
HWND clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 7488644176 gdkdisplay-win32.c: Rename "window" as appropriate
We want to make the distinction between GDK surfaces and the native
(underlying) Windows HWNDs clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 9ed7cecd42 GDK/Win32: Rename "window" in GdkDevice/GdkDeviceManager code
Make the distinction between GdkSurfaces and the underlying native
Windows HWND clearer in the code and in the comments.
2024-10-02 12:52:44 +08:00
Chun-wei Fan df36ab3f93 GDK/Win32: Rename "window" items in Cairo context code
Make the distinction between GDK surfaces and native Windows HWNDs
clearer.
2024-10-02 12:52:44 +08:00
Chun-wei Fan 7e4fdea71b GDK/Win32: Rename "window" in gdksurface-win32.* code
In order to help us in our refactoring, make the distinction between Gdk
surfaces and native Win32 HWND clearer in terms of the variables that we
used, and in the comments in the code.

Also, group forward function prototype declarations in one place, and
drop some unneeded items in gdkprivate-win32.h to fold them into
gdksurface-win32.c, as they are only used there.
2024-10-02 12:52:44 +08:00
Matthias Clasen ea8062e86a Merge branch 'for-main' into 'main'
gsk: Allow Vulkan software rendering as fallback

See merge request GNOME/gtk!7780
2024-10-02 01:31:05 +00:00
Matthias Clasen c4efe7709b Drop GDK_VULKAN_DEVICE support
We don't need our own mechanism for device selection; mesa has a
Vulkan layer that works perfectly fine for this purpose; just set
MESA_VK_DEVICE_SELECT.
2024-10-01 21:00:16 -04:00
Matthias Clasen fdea496883 gsk: Allow Vulkan software rendering as fallback
There is no reason to exclude lavapipe when we accept llvmpipe,
and lavapipe has the advantage that it supports dmabufs.
2024-10-01 20:57:49 -04:00
Matthias Clasen 60878e4186 Merge branch 'for-main' into 'main'
gsk: Prefer ngl over cairo

See merge request GNOME/gtk!7779
2024-10-02 00:45:13 +00:00
Matthias Clasen 02297138f3 gsk: Tweak renderer selection debug spew
Print a message for every get_renderer function that returns
FALSE, so the debug spew lets us get a clear picture of what
possibilities were tried.
2024-10-01 20:12:17 -04:00
Benjamin Otte 6603e02beb Merge branch 'wip/otte/for-main' into 'main'
Revert "tools: Drop support for the gl renderer"

See merge request GNOME/gtk!7778
2024-10-01 23:57:20 +00:00
Matthias Clasen bfb7573810 gsk: Prefer ngl over cairo
Now that the gl renderer is no longer in our fallback sequence, use
ngl instead. With current ngl, llvmpipe is still better than cairo.
2024-10-01 19:42:08 -04:00
Benjamin Otte 6847c3469d testsuite: Keep bounds for clip tests
The hope here is that it makes clip tests more reproducible because the
coordinates in device pixels are still the same as before.
2024-10-02 01:26:24 +02:00
Benjamin Otte 7a1e5b4418 compare-render: Add a KEEP_BOUNDS flag
If that flag is set, we keep the bounds of the original node when
rendering the modified node.

Gets around the replay test having to draw a transparent color node to
ensure the same bounds.
2024-10-02 01:26:24 +02:00
Benjamin Otte 76980e10a0 Revert "tools: Drop support for the gl renderer"
This reverts commit fd02afa2e4.

We don't want to remove the GL renderer from our tools yet, because we
use those tools for manual testing and having it available is useful.

In particular, reinstate the GL renderer for rendernode-tool benchmark.
2024-10-02 01:25:30 +02:00
Matthias Clasen 34f4a06691 Merge branch 'gl-renderer-memorytexture-test' into 'main'
Stop using a gl renderer in the memorytexture text

See merge request GNOME/gtk!7773
2024-10-01 21:29:29 +00:00
Matthias Clasen 2dea5ae958 Merge branch 'for-main' into 'main'
inspector: Plug a  memory leak

See merge request GNOME/gtk!7775
2024-10-01 15:52:05 +00:00
Matthias Clasen 5856716188 inspector: Plug a memory leak
Found by code inspection of all the places where we use texture
builders.
2024-10-01 08:59:52 -04:00
Matthias Clasen 1c4a0dae62 Merge branch 'gst-texture-builder-leak' into 'main'
gst: Don't leak texture builders

See merge request GNOME/gtk!7774
2024-10-01 12:20:48 +00:00
Matthias Clasen b7fba6298f gst: Don't leak texture builders
Found by code inspection. The leak was introduced in 4707784755.

Might help for #4184
2024-10-01 07:18:32 -04:00
Matthias Clasen 5ce196fe9f Rename memory texture tests from ngl to gl 2024-09-30 21:59:59 -04:00
Matthias Clasen c31c89c794 Drop gl renderer tests from memory texture test 2024-09-30 21:55:33 -04:00
Matthias Clasen 1eb8c3ea34 tests: Add ngl-released in memory texture test
This is parallel to the gl-released method, but for ngl.
2024-09-30 21:52:16 -04:00
Matthias Clasen b2414b1ecd Merge branch 'for-main' into 'main'
gtk4-demo: Drop the glshader demos

See merge request GNOME/gtk!7771
2024-10-01 01:47:09 +00:00
Matthias Clasen fd3dfaf2c3 Merge branch 'dmabuf-import-fixup' into 'main'
gl: Treat internal textures as special case

See merge request GNOME/gtk!7772
2024-10-01 01:46:44 +00:00
Benjamin Otte 43a6c8c5f5 gl: Treat internal textures as special case
Treat external as the normal case, and only try importing dmabufs
as non-external images if their format is on the internal formats
list.

Also add internal linear formats to the internal formats list.

This fixes an issue where AR24:0 dmabufs were imported as external
textures, causing some of the compare tests to fail.
2024-09-30 21:16:41 -04:00
Matthias Clasen 3789191853 docs: Stop mentioning the gl renderer
It is going away.
2024-09-30 19:24:42 -04:00
Matthias Clasen eb4fb2af0e gsk: Stop falling back to the gl renderer
The GL renderer is going away. For now, it is still possible
to use it explicitly, with GSK_RENDERER=gl.
2024-09-30 19:22:54 -04:00
Matthias Clasen fd02afa2e4 tools: Drop support for the gl renderer
The GL renderer is going away in 4.18.
2024-09-30 19:22:54 -04:00
Matthias Clasen 55bb77cffc tests: Use the ngl renderer in one more place 2024-09-30 19:22:54 -04:00
Matthias Clasen 119ba5844f testsuite: Drop glshader tests
And drop the gl renderer test here, but add ngl and Vulkan
equivalents.
2024-09-30 19:22:54 -04:00
Matthias Clasen 9b2b5ebb65 gsk: Stop supporting gl shaders
The GL shader code uses the GL renderer for compilation, and that
renderer is going away.
2024-09-30 19:22:54 -04:00
Matthias Clasen 1624455a32 gsk: Use the ngl renderer for serializing to png
This is a step towards dropping the GL renderer.
2024-09-30 18:58:33 -04:00
Matthias Clasen d483883f38 node-editor: Use NGL for exporting images
This is a step towards dropping the GL renderer.
2024-09-30 18:58:33 -04:00
Matthias Clasen 0dc0bea1d5 gtk4-demo: Drop the glshader demos
The GL renderer will be going away in 4.18, and with that, shader
nodes will stop working for good. It is time to start preparing
for that.
2024-09-30 18:58:33 -04:00
Matthias Clasen 55e31b972c Merge branch 'dmabuf-failable-download' into 'main'
Make gdk_dmabuf_downloader_download failable

See merge request GNOME/gtk!7720
2024-09-30 22:41:57 +00:00
Matthias Clasen 1013874de8 gpu: Drop get_dmabuf_formats
This vfunc is no longer needed.
2024-09-30 18:37:20 -04:00
Matthias Clasen c397460c11 Drop gdk_dmabuf_downloader_supports
It is not used anymore.
2024-09-30 18:37:20 -04:00
Matthias Clasen ff0045b8c9 dmabuftexture: Stop having a fixed downloader
Change things from picking a download method at creation time to
trying all methods at download time until one succeeds.
2024-09-30 18:37:20 -04:00
Matthias Clasen d0b409d349 Make gsk_gpu_frame_download_texture return status
Importing a dmabuf can fail, even if the format is supported
in princicple, In these cases, gsk_gpu_frame_download_texture
will return FALSE.
2024-09-30 18:37:20 -04:00
Matthias Clasen c0cb10262d Make gdk_dmabuf_download_mmap return status
Make this function return whether it was successful, and only emit
a debug message if we succeeded. In particular, make it return FALSE
if the dmabuf format is not linear.
2024-09-30 18:37:20 -04:00
Matthias Clasen 279a5f7825 Make gdk_dmabuf_downloader_download failable
This will enable us to try multiple downloaders in a row.
2024-09-30 18:37:20 -04:00
Matthias Clasen 6fa87d4f37 gsk renderer: Add a debug message
Add a debug message so we can see what downloaders are used
for dmabufs.
2024-09-30 18:37:20 -04:00
Matthias Clasen fe35daaf34 Merge branch 'wip/otte/dont-download-the-upload-of-the-download' into 'main'
gpu: Don't use copies for dmabuf downloads

Closes #7046

See merge request GNOME/gtk!7770
2024-09-30 22:30:58 +00:00
Benjamin Otte c3b836951a gl: ref the previous context
The current context might be the last reference to the context, which
would make it go away when the renderer calls make_current().

See commit 0fa2ae48d4 for a similar case.
2024-09-30 23:54:08 +02:00
Matthias Clasen ec10f1fe16 gsk: Don't lose context during download
When we use download in the middle of an upload operation (or the
other way around), we may end up making a different GL context
current. The downloader code is reponsible for reestablishing
the previous context when it is done. The old GL renderer was
doing that, NGL wasn't, until now.
2024-09-30 23:49:59 +02:00
Benjamin Otte ae741a06c0 gpu: Compare fourccs, not GdkMemoryFormat
For dmabufs, the format is not an exact description of the data, it only
gives the closest memory format for a given fourcc.
This of course means that multiple different fourccs may report the same
format.

So when deciding if we need to copy the image to get the right data to
download, we need to check if the fourcc is correct, not if the format
is.

Related: #7046
2024-09-30 22:14:38 +02:00
Benjamin Otte 754c9cb323 gpu: Don't use copies for dmabuf downloads
When we want to download a dmabuf, we want to download the actual
dmabuf.

If we just grab the cached image and use that, we might get the
(reuploaded) copy of the dmabuf. This happens when this renderer
doesn't support downloading this dmabuf but has used it before.

Worse, this is a reentrancy issue, where this renderer is trying to
render the dmabuf and has already scheduled the upload but the upload
has not finished. We will then download from an empty image, which is
very wrong.

The way to check that we have the actual dmabuf is a bit brittle, but it
should work.

Fixes #7046
2024-09-30 19:52:30 +02:00
Benjamin Otte a3683a080b Merge branch 'wip/otte/global-globals' into 'main'
ngl: Use a single buffer for globals

See merge request GNOME/gtk!7753
2024-09-30 17:09:52 +00:00
Matthias Clasen 0673d74986 Merge branch 'for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!7768
2024-09-30 13:53:51 +00:00
Matthias Clasen 8c46df425e Merge branch 'default-cursor-xdg' into 'main'
wayland: Look for default cursor theme in XDG directories

See merge request GNOME/gtk!7766
2024-09-30 13:27:57 +00:00
Ilya Fedin ff78e1888b wayland: Look for default cursor theme in XDG directories
Currently it's looked up only in /usr/share what is a problem for non-FHS distros like NixOS
2024-09-30 15:50:11 +04:00
Matthias Clasen f2f219f304 Cosmetics
Make the debug message match the rest: FORMAT:MODIFIER.
2024-09-30 07:40:48 -04:00
Matthias Clasen bb46edcc21 dmabuf: Initizalize some memory
I've seen valgrind complain about external_only being uninitialized
after the call, when using llvmpipe. Better be safe than sorry, and
initialize these arrays.
2024-09-30 06:55:57 -04:00
Matthias Clasen 24173e3f93 Cosmetics
No point in having an early return since EGL_NO_IMAGE is what we
want to return anyway.
2024-09-30 06:50:20 -04:00
Anders Jonsson ec73bcb05b Update Swedish translation
(cherry picked from commit 82f08089f1)
2024-09-29 22:16:13 +00:00
Juliano de Souza Camargo 6c74c9c970 Update Brazilian Portuguese translation
(cherry picked from commit 1610ecbbac)
2024-09-29 16:30:00 +00:00
Matthias Clasen c9c35ae41d Merge branch 'for-main' into 'main'
testsuite: Don't assert more than guaranteed

See merge request GNOME/gtk!7763
2024-09-29 14:33:35 +00:00
Matthias Clasen 95cea06462 Revamp GDK_VULKAN_DEVICE slightly
Support a "help" value, as we do for other env vars.
2024-09-29 09:54:24 -04:00
Matthias Clasen d01ca53bde testsuite: Don't assert more than guaranteed
Compositors don't guarantee that there's any physical devices
around to correspond to the input capabilities.

This was found running the tests against mutter headless.
2024-09-29 09:30:56 -04:00
Matthias Clasen 3d3cafefc8 Merge branch 'clear-settings-portal' into 'main'
wayland: Clear settings_portal when going to fallback with no portal settings

See merge request GNOME/gtk!7756
2024-09-29 13:25:15 +00:00
Matthias Clasen 86cdb0ceb2 Merge branch '7040-improve-video-input-stream-error-message' into 'main'
gstmediafile: improve error message when there is an input stream.

Closes #7040

See merge request GNOME/gtk!7747
2024-09-29 13:22:28 +00:00
nee 0c97c86573 gstmediafile: improve error message when there is an input stream.
Previously it was unclear why passing an input stream would crash a video,
unless you went into the source and read it.

This adds a clarifying message that only file based media files are supported.
2024-09-29 13:41:17 +02:00
Benjamin Otte 10fa570195 Merge branch 'wip/otte/for-main' into 'main'
gpu: Consider scissor when intersecting with recangle

Closes #7044

See merge request GNOME/gtk!7762
2024-09-29 04:55:12 +00:00
Benjamin Otte e18c553457 gpu: Consider scissor when intersecting with recangle
The clip might be different from the scissor due to incompatible
intersections.

But the resulting intersection might be fully clipped, so we should
consider it.

Testsuite with longer explanation attached.

Fixes #7044
2024-09-29 06:29:47 +02:00
Matthias Clasen 187763d286 Merge branch 'for-main' into 'main'
wayland: Bring back the pointer viewporter

See merge request GNOME/gtk!7761
2024-09-29 00:21:36 +00:00
Fran Dieguez e6ae136de0 Update Galician translation
(cherry picked from commit 8360bfc772)
2024-09-28 21:50:23 +00:00
Matthias Clasen 81efb63073 emojichooser: insert before closing the popover
Doing otherwise risks that the focus is moved back to the entry,
causing everything to be selected, and then replaced by the Emoji
we insert. Which is not the desired effect!
2024-09-28 14:53:12 -04:00
Matthias Clasen cbadb1ed8e Merge branch 'pointer-viewporter-again' into 'main'
wayland: Bring back the pointer viewporter

See merge request GNOME/gtk!7760
2024-09-28 16:13:06 +00:00
Matthias Clasen 103e98f570 Merge branch 'default-cursor-size' into 'main'
wayland: Use the same default cursor size as gsettings schema

Closes #7043

See merge request GNOME/gtk!7754
2024-09-28 14:32:48 +00:00
Matthias Clasen 3768c751c5 wayland: Improve our cursor size selection
When picking a cursor image size for a given size, look for sizes
that do better when scaled by the viewporter:
- exact size
- twice the size
- closest larger size
- closest size
2024-09-28 10:26:42 -04:00
Matthias Clasen e42014573a wayland: Bring back the pointer viewporter
This was a thinko in 403da9a2d5. We have the cursor
image in device pixels, but we still need to apply the viewporter
to inform the compositor about the desired pointer size in
application pixels.
2024-09-28 10:01:04 -04:00
Ilya Fedin a9f1ff471b wayland: Use the same default cursor size as gsettings schema
Fixes: #7043
2024-09-28 16:50:05 +04:00
Ilya Fedin e26a1bbda9 wayland: Clear settings_portal when going to fallback with no portal settings
All other code paths with goto fallback clear it, this makes the behavior consistent with them
2024-09-28 16:41:13 +04:00
Matthias Clasen b2ae7a2448 Merge branch 'for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!7751
2024-09-28 01:16:53 +00:00
Matthias Clasen cb682c759d Cosmetics
No newlines in g_warning.
2024-09-27 20:54:46 -04:00
Benjamin Otte b154c9caf4 ngL: Use a single buffer for globals
Instead of using glBuffer(Sub)Data() every time we set new globals, fill
a single buffer with all the globals and use glBindBufferRange() on that
buffer to set the current globals.
2024-09-28 02:25:40 +02:00
Matthias Clasen 523fca21e9 Merge branch 'wip/kabus/a11y-present-label' into 'main'
label: Don't set a11y label when role is presentation

See merge request GNOME/gtk!7750
2024-09-27 17:34:39 +00:00
Matthias Clasen 73ddde6eda Merge branch 'cursor-size-again' into 'main'
inspector: Tweak the cursor size control

See merge request GNOME/gtk!7749
2024-09-27 17:29:41 +00:00
Matthias Clasen 403da9a2d5 wayland: Redo cursor loading
Stop using a viewporter to scale cursors. Instead, just pass
the surface scale to the cursor loading code, and take the
buffer dimensions and hotspot that it returns, unchanged.

This avoids problems with cursor themes like Breeze, where
buffer dimensions are different from the nominal cursor size.

Make the cursor loading code take a floating point scale,
and return the closest sized cursor that it can find.
2024-09-27 12:37:25 -04:00
Khalid Abu Shawarib fb6f211869 label: Don't set a11y label when role is presentation
This resolves issue with labels of model buttons being set to
presentation a11y role but still have a11y label.

See: https://gitlab.gnome.org/GNOME/gtk/-/blob/b7e5a79468312706e7465caed2cd55badbee432d/gtk/gtkmodelbutton.c?page=2#L1539
2024-09-27 19:15:41 +03:00
Matthias Clasen c358606a46 inspector: Tweak the cursor size control
Useful for debugging our cursor loading code.
2024-09-27 12:11:31 -04:00
Matthias Clasen b7e5a79468 Merge branch 'listbox_tab_behavior' into 'main'
listbox: Introduce tab-behavior property

See merge request GNOME/gtk!7739
2024-09-27 11:42:14 +00:00
Benjamin Otte 06bcb0ee47 Merge branch 'wip/otte/ngl-downloader' into 'main'
Use NGL renderer for dmabuf downloads

See merge request GNOME/gtk!7741
2024-09-26 20:58:01 +00:00
Matthias Clasen 58ce0a39dc dmabuf: Use the ngl downloader
It works, now and is faster than the old GL downloader.

Playing the Barbie trailer @ 4k with hardware decoding but the Cairo
renderer on a 4k screen:

downloader  windowed  fullscreen
GL          12fps     19fps
NGL         16fps     29fps
Vulkan      16fps     29fps
no dmabufs  12fps     19fps
2024-09-26 22:06:18 +02:00
Benjamin Otte 6d3c333208 gpu: Actually ensure a downloadable dmabuf
For some formats, we could not download the dmabuf directly - in
particular YUV formats.
For those, do a copy on the GPU into the correct format.

While we're at it, also check the desired format and colorstate and if
they don't match, do the conversion on the GPU instead of using
gdk_memory_convert().
Reserve the CPU conversion for situations where the GPU doesn't support
the final format - like for example G8A8 (or often also RGB16).
2024-09-26 22:06:18 +02:00
Benjamin Otte 62c3923e5a gpu: Handle all colorstates in cache
Make gsk_gpu_cache_cache_texture_image() API safer by accepting all
color states as input and just not caching the images for colorstates we
don't care about.
2024-09-26 22:06:18 +02:00
Benjamin Otte 3be8b1d927 gpu: Check if the image is cached in right colorstate
This is most likely not a very likely check, but just to be sure, check
if the image exists in the cache in the desired colorstate already.
2024-09-26 22:06:18 +02:00
Benjamin Otte 27a61e221f gpu: Shuffle function arguments
Instead of passing down the depth and extracting format/srgb from it at
the end, extract format/srgb in the nodeprocessor and pass it down.

This allows creating offscreens for weirder formats in the future.
2024-09-26 22:06:18 +02:00
Benjamin Otte 52df3481d6 gpu: Add a gsk_gpu_download_into_op()
... and use it for the dmabuf downloader

Splits the download op into 2 separate ops: One for downloading textures
and one for downloading into preallocated memory.

The download into memory is the fallback for the texture downloading op,
so they need to share code.

But keeping them separate ensures that the different codepaths for
dmabuf download and render_texture() don't get mixed up in weird ways
that potentially call into each other.

By passing the emory down into the op we can also avoid an extra memcpy
which can lead to quite large speedups for big textures.
2024-09-26 22:06:17 +02:00
Benjamin Otte ccb993d87b gpu: Split out a function
I want to use it from elsewhere in future commits.
2024-09-26 22:06:17 +02:00
Benjamin Otte 5fdaa4a232 gl: Move function
We want to share the texture download function with the renderers, so
they can download textures without needing to wrap them in a
GdkGLTexture.

Move it into gdkglcontext.c for that purpose.
2024-09-26 22:06:17 +02:00
Benjamin Otte 8b166dff74 gltexture: Split out a function
No functional changes
2024-09-26 22:06:17 +02:00
Benjamin Otte f6b3f321a4 dmabuf: Refactor GPU renderer
We don't want to ever try fallback uploads in the dmabuf path. So
refactor gdk_frame_upload_texture() to have a flag that turns that off.
2024-09-26 22:06:17 +02:00
Benjamin Otte a314143a83 gpu: Pass color state to download op
Previously we were always implicitly using SRGB, which was correct more
or less by accident.
2024-09-26 22:06:17 +02:00
Benjamin Otte 6c7abf425a Merge branch 'wip/otte/for-main' into 'main'
testsuite: Remove leftover test.in files

See merge request GNOME/gtk!7744
2024-09-26 18:47:49 +00:00
Matthias Clasen b11e45762b Merge branch 'cursor-update-now' into 'main'
wayland: Make cursor changes effective immediately

Closes #6909

See merge request GNOME/gtk!7745
2024-09-26 18:07:28 +00:00
Benjamin Otte d041a681a5 Merge branch 'wip/otte/drop-gles2' into 'main'
Drop support for GLES 2 and GL < 3.3

See merge request GNOME/gtk!7743
2024-09-26 17:51:09 +00:00
Matthias Clasen d22d2f77a6 wayland: Make cursor changes effective immediately
When the cursor theme changes, update the cursors of our surfaces.

Fixes: #6909
2024-09-26 12:53:38 -04:00
Benjamin Otte 7458461d06 gl: Remove unpack-subimage checks
GLES 3.0 supports it unconditionally.
2024-09-26 18:41:13 +02:00
Benjamin Otte 283615936b gl: Remove check for half-float vertex data
All supported versions require it after we dropped support for GLES 2.
2024-09-26 18:41:13 +02:00
Benjamin Otte 2274bca95b gl: Require support for GLsync
It's supported by GL >= 3.2 and GLES >= 3.0 and we require both now.
2024-09-26 18:41:13 +02:00
Benjamin Otte f8b4deeac0 gdk: Drop support for GL < 3.3
The new renderers need features from GL 3.3 and GLSync is very required
these days, too.

Note that this is about GL proper, not GLES.
2024-09-26 18:41:13 +02:00
Benjamin Otte afa503c2e0 gl: Remove GLES 2 specific parts of format checks 2024-09-26 18:41:13 +02:00
Benjamin Otte 105f5f1137 gpu: Remove check for GLES 2
GLES 2 is no longer supported.
2024-09-26 18:41:13 +02:00
Benjamin Otte b83ad60a1f gdk: Drop support for GLES 2
We now require GLES 3.
2024-09-26 18:41:13 +02:00
Benjamin Otte 58b44ebc1c testsuite: Remove GLES 2 tests
We want to drop GLES 2 support.
2024-09-26 18:41:13 +02:00
Benjamin Otte b598f21506 testsuite: Remove leftover test.in files
We stopped supporting installed tests in 3121f88265 but forgot to remove
these files.
2024-09-26 16:35:47 +00:00
Matthias Clasen d3c166d511 Merge branch 'for-main' into 'main'
gtk-demo: Stop using g_time_zone_new

See merge request GNOME/gtk!7742
2024-09-26 15:35:06 +00:00
Matthias Clasen 76e93206f3 Stop using G_APPLICATION_FLAGS_NONE
It has been deprecated in favor of G_APPLICATION_DEFAULT_FLAGS.
2024-09-25 22:03:23 -04:00
Matthias Clasen ecfe47af73 docs: Drop a note about old GLib
We require GLib 2.76 now.
2024-09-25 22:00:38 -04:00
Matthias Clasen f20ca9067e gtk-demo: Stop using g_time_zone_new
It is deprecated in favor of g_time_zone_new_identifier.
2024-09-25 21:57:49 -04:00
Matthias Clasen 8f3cd4733c Merge branch 'for-main' into 'main'
Stop using g_memdup

See merge request GNOME/gtk!7740
2024-09-26 01:22:23 +00:00
Matthias Clasen 402ee9b39c Tweak the issue template
Ask for more relevant information.
2024-09-26 02:53:54 +02:00
Matthias Clasen becbf4e1f9 Update the README slightly 2024-09-26 02:53:54 +02:00
Matthias Clasen 67407d5dcf tools: Minor cleanup
No need to register all types here.
2024-09-26 02:53:54 +02:00
Matthias Clasen fcc0f243cf Stop using g_pattern_match_string
It has been deprecated in favor of g_pattern_spec_match_string.
2024-09-26 02:53:54 +02:00
Matthias Clasen 282dcfa9ac Apply review feedback, mostly formatting. 2024-09-25 11:21:52 +00:00
Matthias Clasen 8c04801f6a Stop using g_memdup
Its deprecated in favor of g_memdup2
2024-09-25 10:56:36 +02:00
Lukáš Tyrychtr abe2d1cb16 listbox: Introduce tab-behavior property
This is similar to the other tab-behavior properties, and allows
to control how the tabbing behaves in context of a GtkListBox.

It allows to make gnome-initial-setup#216 history, for example.
2024-09-25 10:07:43 +02:00
Benjamin Otte e407d22b1e Merge branch 'wip/otte/for-main' into 'main'
keynames: Use C types

See merge request GNOME/gtk!7737
2024-09-25 02:07:23 +00:00
Benjamin Otte 37cefde5b0 demo: Unmix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte 310a4a3bf6 gdk: Fix parameter names
Believe in your self!
2024-09-25 02:50:22 +02:00
Benjamin Otte e6896aa8dc gpu: Fix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte 36ce68a3ca textbuffer: includes go before G_BEGIN_DECLS 2024-09-25 02:50:22 +02:00
Benjamin Otte 797343da59 gtkpango: Fix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte bd3223d452 testsuite: Add missing headers 2024-09-25 02:50:22 +02:00
Benjamin Otte 87a1a17868 memoryformat: Rename parameter
It's meant to match the prototype.
2024-09-25 02:50:22 +02:00
Benjamin Otte 70f386bd68 keynames: Use C types
Then we don't need to include glib.h
2024-09-25 02:50:22 +02:00
Benjamin Otte 0af89088ba gdk: Include missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 7342317c31 gdk: Fix parameter names 2024-09-25 02:50:22 +02:00
Benjamin Otte 8d8bd4efba broadway: Fix argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 0ae3c8968e gdk: Add missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 5e3f13acd1 filetransferportal: Include missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 32cdf35583 broadway: Fix argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 2f670bdc59 demo: Fix typo 2024-09-25 02:50:22 +02:00
Benjamin Otte 8d5660b4ab demo: Fix argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 2a39f427e1 testsuite: include missing headers 2024-09-25 02:50:22 +02:00
Benjamin Otte ca86294325 tools: Include missing headers 2024-09-25 02:50:22 +02:00
Benjamin Otte 820ba1ef13 demo: Correct argument name 2024-09-25 02:50:22 +02:00
Benjamin Otte 9507130dbc demo: Unmix argument names 2024-09-25 02:50:22 +02:00
Benjamin Otte d2dede635b demo: include missing header 2024-09-25 02:50:22 +02:00
Benjamin Otte 5a7fc4054b memoryformat: Fix argument names in prototype 2024-09-25 02:50:22 +02:00
Benjamin Otte 7fe22845e3 Merge branch 'wip/otte/fix-ci' into 'main'
testsuite: Use RGBA8 reference images

See merge request GNOME/gtk!7735
2024-09-24 17:52:55 +00:00
Matthias Clasen 6c9a7cc708 Merge branch 'gtk-find' into 'main'
Add gtk_string_list_find method

See merge request GNOME/gtk!7733
2024-09-24 17:24:10 +00:00
Benjamin Otte feeca98270 testsuite: Use RGBA8 reference images
Due to a Mesa bug, RGBA16 images aren't properly handled sometimes and
can cause random failures.
In this case, generating the modified reference images for the tests
fails.

Fixes CI breakage.

Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11750
2024-09-24 13:57:09 +00:00
taozuhong 7c27241479 Add gtk_string_list_find method
This is a convenience API to find a given string's position.

Test included.
2024-09-24 15:44:04 +02:00
Matthias Clasen fb73040d70 Merge branch 'for-main' into 'main'
Fix tests for 4.17

See merge request GNOME/gtk!7736
2024-09-24 13:42:25 +00:00
Matthias Clasen bbe74abf51 Fix tests for 4.17 2024-09-24 14:23:31 +02:00
Matthias Clasen 34bd3fc854 Merge branch 'scale-focus-fix' into 'main'
theme: Fix scale sizing during .fine-tune

See merge request GNOME/gtk!7659
2024-09-24 11:54:21 +00:00
Benjamin Otte 940b5af2a8 Merge branch 'wip/otte/for-main' into 'main'
Revert "dmabuf: Use the ngl downloader"

See merge request GNOME/gtk!7734
2024-09-24 10:05:27 +00:00
Benjamin Otte 0929d77f7f Revert "Fix the ngl downloader"
This reverts commit c7dfb8cb55.
2024-09-24 11:29:59 +02:00
Benjamin Otte 617297ddd7 Revert "gpu: Make gsk_gpu_copy_image available"
This reverts commit 42d26720d6.
2024-09-24 11:29:59 +02:00
Benjamin Otte 67cec180ca Revert "gsk: Make downloaders work fully"
This reverts commit de74fa0836.
2024-09-24 11:29:59 +02:00
Benjamin Otte bab8f2f976 Revert "dmabuf: Use the ngl downloader"
This reverts commit 97e0f872a2.
2024-09-24 11:29:59 +02:00
Matthias Clasen 4801c3275e Merge branch 'wip/otte/win32-remove-sync' into 'main'
win32: Remove gdk_display_sync()

See merge request GNOME/gtk!7727
2024-09-24 07:03:53 +00:00
Matthias Clasen 39354b3b99 Merge branch 'wip/otte/x11-remove-sync' into 'main'
x11: Remove gdk_display_sync() call

See merge request GNOME/gtk!7728
2024-09-24 07:03:20 +00:00
Matthias Clasen 661e953558 Merge branch 'dmabuf-downloader-investigations' into 'main'
Fix the ngl downloader

See merge request GNOME/gtk!7731
2024-09-24 07:02:09 +00:00
Matthias Clasen 039b97ef9e Start 4.17 2024-09-24 08:42:21 +02:00
Matthias Clasen 97e0f872a2 dmabuf: Use the ngl downloader
It works, now.
2024-09-23 21:14:53 +02:00
Matthias Clasen de74fa0836 gsk: Make downloaders work fully
Use gsk_gpu_copy_image when necessary to get the image converted
into the right format before downloading it.
2024-09-23 21:14:19 +02:00
Matthias Clasen 42d26720d6 gpu: Make gsk_gpu_copy_image available
This was a static helper in gsknodeprocessor.c, but we want to
use it elsewhere, so make it available.
2024-09-23 21:14:19 +02:00
Matthias Clasen c7dfb8cb55 Fix the ngl downloader
The image is already associated with the original texture, the
one that the download op creates is purely to hand it to the
downloader, it should not be associated with the image.

This makes the ngl downloader work as well as the vulkan one
(ie rgba dmabufs work, yuv ones don't, since we don't convert
them).
2024-09-23 21:14:08 +02:00
Benjamin Otte 236b6d1cd6 x11: Remove gdk_display_sync() call
This is unnecessary.
Worse, it is reentrant and can cause all sorts of avoc when processing
events halfway through initializing the Vulkan context.

It was introduced in commit e11a6a0e68 but back then GTK was barely
branched for GTK4 and Vulkan drivers were very new, and it looks like an
unnecessary workaround.

Testing did not seem to indicate any issues with just removing it, so
here it goes.

Related: #7022
2024-09-21 18:59:49 +02:00
Benjamin Otte 6e714722c4 win32: Remove gdk_display_sync()
This is unnecessary.
Worse, it is reentrant and causes all sorts of avoc when processing
events halfway through initializing the context.

It only exists because in commit c4244ea1 the win32 Vulkan code was
copy/pasted from another backend.

Related: #7022
2024-09-21 18:19:26 +02:00
Matthijs Velsink 2e2dab9c3d theme: Fix scale sizing during .fine-tune
Using fine-tune on a GtkScale is maybe a little known feature, but it's
also quite wonky. It causes marks, values, and sliders to jump around
when activated. This is because it's implemented with less padding
around the scale and an increased minimum size.

For example a value drawn left or right of a horizontal scale, as then
the height of the scale is the value height plus padding. So fine-tuning
compresses the scale vertically.

We can fix this by adding negative margin on the trough instead, without
any changes to the padding or minimum size of the scale.

Also, because the trough now grows 3px in all directions, the slider has
to do that to, so that margin increases by 3px in all directions
compared to what it was, also for the cases with marks.

One last minor detail is that for vertical scales, fine-tuning causes
the height of the mark indicators to grow, whereas their width should
decrease. That's also fixed.
2024-08-27 22:35:02 +02:00
Matthijs Velsink a6eea6ba3c theme: Fix positioning of scale values
Commit d58b545f fixed a double counting of value size, but didn't check
whether that actually looked great. It doesn't.

Because the slider has negative margins, we need to add margin to the
value if it's on a side with no marks. If it is on a side with marks,
the scale will make it touch the marks. We therefore apply a mark's size
of margin to have the value be in the same place, with or without marks.
2024-08-27 22:33:54 +02:00
261 changed files with 29873 additions and 7754 deletions
-3
View File
@@ -68,7 +68,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles2.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
@@ -136,8 +135,6 @@ release-build:
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build wayland gtk
# only repeat test runs that are likely affected by test setups
- .gitlab-ci/run-tests.sh _build wayland_gles2 gtk:gdk,gtk:gsk-gl
fedora-clang:
extends: .build-fedora-default
+3 -1
View File
@@ -34,7 +34,9 @@
<!--
- Which version of GTK you are using
- What operating system and version
- For Linux, which distribution
- What windowing system (X11 or Wayland)
- What graphics driver / mesa version
- For Linux, which distribution
- If you built GTK yourself, the list of options used to configure the build
-->
+5 -62
View File
@@ -1,65 +1,8 @@
Overview of Changes in 4.16.4, 01-11-2024
Overview of Changes in 4.17.0, xx-xx-xxxx
=========================================
* GtkTextView:
- Fix some missing CSS invalidation
- Handle charsets in clipboard datatypes
* GtkApplication:
- Respect GDK_DEBUG=no-portals
* Printing:
- Avoid warnings for avahi errors
- Fix a segfault in the print dialog setup code
* Accessibility:
- Handle NULL values in more places
* Gdk:
- vulkan: Fix validation errors
- Fix 32bit build for the jpeg loader
* Wayland:
- Fix a possible deadlock with high-priority sources
triggering Wayland roundtrips
* Translation updates
Belarusian
British English
Latvian
Romanian
Overview of Changes in 4.16.3, 04-10-2024
=========================================
* GtkScrolledWindow
- Fix criticals in size allocation code
* GtkFileChooser
- Fix a crash in the portal code
* GtkPicture
- Avoid unnecessary resizes
* GtkVideo
- Make dmabufs work without GL
* Accessibility:
- Always realized non-widget accessibles
* Wayland:
- Improve settings portal handling
- Improve fallback for cursor themes
- Sync default values for settings with schema defaults
* Translation updates:
Brazilian Portuguese
Galician
Swedish
Overview of Changes in 4.16.2, 25-09-2024
Overview of Changes in 4.16.2, 09-25-2024
=========================================
* GtkLabel:
@@ -100,7 +43,7 @@ Overview of Changes in 4.16.2, 25-09-2024
Ukrainian
Overview of Changes in 4.16.1, 16-09-2024
Overview of Changes in 4.16.1, 09-16-2024
=========================================
* GtkFileChooser:
@@ -141,7 +84,7 @@ Overview of Changes in 4.16.1, 16-09-2024
Swedish
Overview of Changes in 4.16.0, 06-09-2024
Overview of Changes in 4.16.0, 09-06-2024
=========================================
Note: This release changes the default GSK renderer to be Vulkan,
@@ -239,7 +182,7 @@ with the new renderers.
Ukrainian
Overview of Changes in 4.15.6, 26-08-2024
Overview of Changes in 4.15.6, 08-26-2024
=========================================
* GtkCheckButton:
+4
View File
@@ -136,9 +136,13 @@ In the bug report please include:
- which version of GTK you are using
- what operating system and version
- what windowing system (X11 or Wayland)
- what graphics driver / mesa version
- for Linux, which distribution
- if you built GTK, the list of options used to configure the build
Most of this information can be found in the GTK inspector.
And anything else you think is relevant.
* How to reproduce the bug.
File diff suppressed because it is too large Load Diff
-26
View File
@@ -1,26 +0,0 @@
uniform float u_time;
void
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
float t0 = sin ((u_time + 0.00)*1.0);
float t1 = sin ((u_time + 0.30)*0.4);
float t2 = cos ((u_time + 0.23)*0.9);
float t3 = cos ((u_time + 0.41)*0.6);
float t4 = cos ((u_time + 0.11)*0.3);
vec2 p0 = vec2 (t1, t0) ;
vec2 p1 = vec2 (t2, t3) ;
vec2 p2 = vec2 (t4, t3) ;
float r = 1.0/distance (pos, p0);
float g = 1.0/distance (pos, p1);
float b = 1.0/distance (pos, p2);
float sum = r + g + b;
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
}
-226
View File
@@ -1,226 +0,0 @@
uniform float iTime;
// Originally from: https://www.shadertoy.com/view/3ljyDD
// License CC0: Hexagonal tiling + cog wheels
// Nothing fancy, just hexagonal tiling + cog wheels
#define PI 3.141592654
#define TAU (2.0*PI)
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
float hash(in vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}
float pcos(float a) {
return 0.5 + 0.5*cos(a);
}
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}
float modPolar(inout vec2 p, float repetitions) {
float angle = 2.0*PI/repetitions;
float a = atan(p.y, p.x) + angle/2.;
float r = length(p);
float c = floor(a/angle);
a = mod(a,angle) - angle/2.;
p = vec2(cos(a), sin(a))*r;
// For an odd number of repetitions, fix cell index of the cell in -x direction
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
if (abs(c) >= (repetitions/2.0)) c = abs(c);
return c;
}
float pmin(float a, float b, float k) {
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
const vec2 sz = vec2(1.0, sqrt(3.0));
const vec2 hsz = 0.5*sz;
const float smallCount = 16.0;
vec2 hextile(inout vec2 p) {
// See Art of Code: Hexagonal Tiling Explained!
// https://www.youtube.com/watch?v=VmrIDyYiJBA
vec2 p1 = mod(p, sz)-hsz;
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
vec2 n = p3 - p;
p = p3;
return n;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
float unevenCapsule(vec2 p, float r1, float r2, float h) {
p.x = abs(p.x);
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(p,vec2(-b,a));
if( k < 0.0 ) return length(p) - r1;
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
return dot(p, vec2(a,b) ) - r1;
}
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
float cogWidth = 0.25*innerRadius*TAU/cogs;
float d0 = circle(p, innerRadius);
vec2 icp = p;
modPolar(icp, holes);
icp -= vec2(innerRadius*0.55, 0.0);
float d1 = circle(icp, innerRadius*0.25);
vec2 cp = p;
modPolar(cp, cogs);
cp -= vec2(innerRadius, 0.0);
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
float d3 = circle(p, innerRadius*0.20);
float d = 1E6;
d = min(d, d0);
d = pmin(d, d2, 0.5*cogWidth);
d = min(d, d2);
d = max(d, -d1);
d = max(d, -d3);
return d;
}
float ccell1(vec2 p, float r) {
float d = 1E6;
const float bigCount = 60.0;
vec2 cp0 = p;
rot(cp0, -iTime*TAU/bigCount);
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
vec2 cp1 = p;
float nm = modPolar(cp1, 6.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
d = min(d, d0);
d = min(d, d1);
return d;
}
float ccell2(vec2 p, float r) {
float d = 1E6;
vec2 cp0 = p;
float nm = modPolar(cp0, 6.0);
vec2 cp1 = cp0;
const float off = 0.275;
const float count = smallCount + 2.0;
cp0 -= vec2(off, 0.0);
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
float l = length(p);
float d2 = l - (off+0.055);
float d3 = d2 + 0.020;;
vec2 tp0 = p;
modPolar(tp0, 60.0);
tp0.x -= off;
float d4 = box(tp0, vec2(0.0125, 0.005));
float ctime = -(iTime*0.05 + r)*TAU;
vec2 tp1 = p;
rot(tp1, ctime*12.0);
tp1.x -= 0.13;
float d5 = box(tp1, vec2(0.125, 0.005));
vec2 tp2 = p;
rot(tp2, ctime);
tp2.x -= 0.13*0.5;
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
float d7 = l - 0.025;
float d8 = l - 0.0125;
d = min(d, d0);
d = min(d, d1);
d = min(d, d2);
d = max(d, -d3);
d = min(d, d4);
d = min(d, d5);
d = min(d, d6);
d = min(d, d7);
d = max(d, -d8);
return d;
}
float df(vec2 p, float scale, inout vec2 nn) {
p /= scale;
nn = hextile(p);
nn = floor(nn + 0.5);
float r = hash(nn);
float d;;
if (r < 0.5) {
d = ccell1(p, r);
} else {
d = ccell2(p, r);
}
return d*scale;
}
vec3 postProcess(vec3 col, vec2 q) {
//col = saturate(col);
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
return col;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
vec2 q = fragCoord/resolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= resolution.x/resolution.y;
float tm = iTime*0.1;
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
float aa = 4.0 / resolution.y;
vec2 nn = vec2(0.0);
float d = df(p, z, nn);
vec3 col = vec3(160.0)/vec3(255.0);
vec3 baseCol = vec3(0.3);
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
col = postProcess(col, q);
fragColor = vec4(col, 1.0);
}
-27
View File
@@ -1,27 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/crosswarp
// Author: Eke Péter <peterekepeter@gmail.com>
// License: MIT
vec4 transition(vec2 p) {
float x = progress;
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+1 -16
View File
@@ -146,21 +146,6 @@
<file>cogs.glsl</file>
<file>glowingstars.glsl</file>
</gresource>
<gresource prefix="/gltransition">
<file>gtkshaderstack.c</file>
<file>gtkshaderstack.h</file>
<file>gtkshaderbin.h</file>
<file>gtkshaderbin.c</file>
<file>gskshaderpaintable.h</file>
<file>gskshaderpaintable.c</file>
<file>wind.glsl</file>
<file>radial.glsl</file>
<file>crosswarp.glsl</file>
<file>kaleidoscope.glsl</file>
<file>cogs2.glsl</file>
<file>ripple.glsl</file>
<file>background.glsl</file>
</gresource>
<gresource prefix="/iconscroll">
<file>iconscroll.ui</file>
</gresource>
@@ -296,7 +281,6 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
<file>iconscroll.c</file>
@@ -457,6 +441,7 @@
<file>portland-rose-thumbnail.png</file>
<file>large-image-thumbnail.png</file>
<file compressed="true">large-image.png</file>
<file compressed="true">Moby-Dick.txt</file>
</gresource>
<gresource prefix="/org/gtk/Demo4/gtk">
<file preprocess="xml-stripblanks">help-overlay.ui</file>
-42
View File
@@ -9,7 +9,6 @@
#include "gtkfishbowl.h"
#include "gtkgears.h"
#include "gskshaderpaintable.h"
#include "nodewidget.h"
#include "graphwidget.h"
@@ -152,46 +151,6 @@ create_switch (void)
return w;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
create_cogs (void)
{
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
GtkWidget *picture;
static GskGLShader *cog_shader = NULL;
GdkPaintable *paintable;
if (cog_shader == NULL)
cog_shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (g_object_ref (cog_shader), NULL);
picture = gtk_picture_new_for_paintable (paintable);
gtk_widget_set_size_request (picture, 150, 75);
gtk_widget_add_tick_callback (picture, update_paintable, NULL, NULL);
return picture;
G_GNUC_END_IGNORE_DEPRECATIONS
}
static gboolean
check_cogs (GtkFishbowl *fb)
{
return GSK_IS_GL_RENDERER (gtk_native_get_renderer (gtk_widget_get_native (GTK_WIDGET (fb))));
}
static void
mapped (GtkWidget *w)
{
@@ -241,7 +200,6 @@ static const struct {
{ "Gears", create_gears, NULL },
{ "Switch", create_switch, NULL },
{ "Menubutton", create_menu_button, NULL },
{ "Shader", create_cogs, check_cogs },
{ "Tiger", create_tiger, NULL },
{ "Graph", create_graph, NULL },
};
+1 -1
View File
@@ -276,7 +276,7 @@ gtk_font_plane_class_init (GtkFontPlaneClass *class)
GtkWidget *
gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj)
GtkAdjustment *width_adj)
{
return g_object_new (GTK_TYPE_FONT_PLANE,
"weight-adjustment", weight_adj,
+2 -2
View File
@@ -55,7 +55,7 @@ struct _GtkFontPlaneClass
GType gtk_font_plane_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_font_plane_new (GtkAdjustment *width_adj,
GtkAdjustment *weight_adj);
GtkWidget * gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj);
G_END_DECLS
-366
View File
@@ -1,366 +0,0 @@
/* OpenGL/Transitions and Effects
* #Keywords: OpenGL, shader, effect
*
* Create transitions between pages using a custom fragment shader.
*
* The example transitions here are taken from gl-transitions.com, and you
* can edit the shader code itself on the last page of the stack.
*
* The transitions work with arbitrary content. We use images, shaders
* GL areas and plain old widgets to demonstrate this.
*
* The demo also shows some over-the-top effects like wobbly widgets,
* and animated backgrounds.
*/
#include <math.h>
#include <gtk/gtk.h>
#include "gtkshaderstack.h"
#include "gtkshaderbin.h"
#include "gtkshadertoy.h"
#include "gskshaderpaintable.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *demo_window = NULL;
static void
close_window (GtkWidget *widget)
{
/* Reset the state */
demo_window = NULL;
}
static void
text_changed (GtkTextBuffer *buffer,
GtkWidget *button)
{
gtk_widget_set_visible (button, TRUE);
}
static void
apply_text (GtkWidget *button,
GtkTextBuffer *buffer)
{
GtkWidget *stack;
GskGLShader *shader;
GtkTextIter start, end;
char *text;
stack = g_object_get_data (G_OBJECT (button), "the-stack");
gtk_text_buffer_get_bounds (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
GBytes *bytes = g_bytes_new_take (text, strlen (text));
shader = gsk_gl_shader_new_from_bytes (bytes);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
g_bytes_unref (bytes);
gtk_widget_set_visible (button, FALSE);
}
static void
go_back (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), FALSE);
}
static void
go_forward (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), TRUE);
}
static void
clicked_cb (GtkGestureClick *gesture,
guint n_pressed,
double x,
double y,
gpointer data)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static GtkWidget *
ripple_bin_new (void)
{
GtkWidget *bin = gtk_shader_bin_new ();
static GskGLShader *shader = NULL;
if (shader == NULL)
shader = gsk_gl_shader_new_from_resource ("/gltransition/ripple.glsl");
gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT, 20);
return bin;
}
static GtkWidget *
new_shadertoy (const char *path)
{
GBytes *shader;
GtkWidget *toy;
toy = gtk_shadertoy_new ();
shader = g_resources_lookup_data (path, 0, NULL);
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (toy),
g_bytes_get_data (shader, NULL));
g_bytes_unref (shader);
return toy;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
make_shader_stack (const char *name,
const char *resource_path,
int active_child,
GtkWidget *scale)
{
GtkWidget *stack, *child, *widget, *vbox, *hbox, *bin;
GtkWidget *label, *button, *tv;
GskGLShader *shader;
GObjectClass *class;
GParamSpecFloat *pspec;
GtkAdjustment *adjustment;
GtkTextBuffer *buffer;
GBytes *bytes;
GtkEventController *controller;
GdkPaintable *paintable;
stack = gtk_shader_stack_new ();
shader = gsk_gl_shader_new_from_resource (resource_path);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
child = gtk_picture_new_for_resource ("/css_blendmodes/ducky.png");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (shader, NULL);
child = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (child, update_paintable, NULL, NULL);
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = new_shadertoy ("/shadertoy/neon.glsl");
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
class = g_type_class_ref (GTK_TYPE_SHADER_STACK);
pspec = G_PARAM_SPEC_FLOAT (g_object_class_find_property (class, "duration"));
adjustment = gtk_range_get_adjustment (GTK_RANGE (scale));
if (gtk_adjustment_get_lower (adjustment) == 0.0 &&
gtk_adjustment_get_upper (adjustment) == 0.0)
{
gtk_adjustment_configure (adjustment,
pspec->default_value,
pspec->minimum,
pspec->maximum,
0.1, 0.5, 0);
}
g_type_class_unref (class);
g_object_bind_property (adjustment, "value",
stack, "duration",
G_BINDING_DEFAULT);
widget = gtk_scrolled_window_new ();
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (widget), TRUE);
gtk_widget_set_hexpand (widget, TRUE);
gtk_widget_set_vexpand (widget, TRUE);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
g_signal_connect (controller, "released", G_CALLBACK (clicked_cb), NULL);
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
gtk_widget_add_controller (GTK_WIDGET (widget), controller);
tv = gtk_text_view_new ();
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_top_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW (tv), 4);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
bytes = g_resources_lookup_data (resource_path, 0, NULL);
gtk_text_buffer_set_text (buffer,
(const char *)g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
g_bytes_unref (bytes);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (widget), tv);
gtk_box_append (GTK_BOX (child), widget);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
gtk_shader_stack_set_active (GTK_SHADER_STACK (stack), active_child);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
widget = gtk_center_box_new ();
label = gtk_label_new (name);
gtk_widget_add_css_class (label, "title-4");
gtk_widget_set_size_request (label, -1, 26);
gtk_center_box_set_center_widget (GTK_CENTER_BOX (widget), label);
button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
g_object_set_data (G_OBJECT (button), "the-stack", stack);
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_widget_add_css_class (button, "small");
gtk_widget_set_visible (button, FALSE);
gtk_center_box_set_end_widget (GTK_CENTER_BOX (widget), button);
gtk_box_append (GTK_BOX (vbox), widget);
GtkWidget *bin2 = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin2), stack);
gtk_box_append (GTK_BOX (vbox), bin2);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), hbox);
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_back), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_forward), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
return vbox;
}
static void
remove_provider (gpointer data)
{
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
g_object_unref (provider);
}
static GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
GdkPaintable *paintable;
GtkCssProvider *provider;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Transitions and Effects");
headerbar = gtk_header_bar_new ();
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
gtk_widget_set_size_request (scale, 100, -1);
gtk_widget_set_tooltip_text (scale, "Transition duration");
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), scale);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
outer_grid = gtk_grid_new ();
gtk_window_set_child (GTK_WINDOW (window), outer_grid);
paintable = gsk_shader_paintable_new (gsk_gl_shader_new_from_resource ("/gltransition/background.glsl"), NULL);
background = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (background, update_paintable, NULL, NULL);
gtk_grid_attach (GTK_GRID (outer_grid),
background,
0, 0, 1, 1);
grid = gtk_grid_new ();
gtk_grid_attach (GTK_GRID (outer_grid),
grid,
0, 0, 1, 1);
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (grid, 12);
gtk_widget_set_margin_end (grid, 12);
gtk_widget_set_margin_top (grid, 12);
gtk_widget_set_margin_bottom (grid, 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Wind", "/gltransition/wind.glsl", 0, scale),
0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Radial", "/gltransition/radial.glsl", 1, scale),
1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Crosswarp", "/gltransition/crosswarp.glsl", 2, scale),
0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
1, 1, 1, 1);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, "button.small { padding: 0; }");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
return window;
}
GtkWidget *
do_gltransition (GtkWidget *do_widget)
{
if (!demo_window)
demo_window = create_gltransition_window (do_widget);
if (!gtk_widget_get_visible (demo_window))
gtk_widget_set_visible (demo_window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (demo_window));
return demo_window;
}
G_GNUC_END_IGNORE_DEPRECATIONS
-338
View File
@@ -1,338 +0,0 @@
/*
* Copyright © 2020 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gskshaderpaintable.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/**
* GskShaderPaintable:
*
* `GskShaderPaintable` is an implementation of the `GdkPaintable` interface
* that uses a `GskGLShader` to create pixels.
*
* You can set the uniform data that the shader needs for rendering
* using gsk_shader_paintable_set_args(). This function can
* be called repeatedly to change the uniform data for the next
* snapshot.
*
* Commonly, time is passed to shaders as a float uniform containing
* the elapsed time in seconds. The convenience API
* gsk_shader_paintable_update_time() can be called from a `GtkTickCallback`
* to update the time based on the frame time of the frame clock.
*/
struct _GskShaderPaintable
{
GObject parent_instance;
GskGLShader *shader;
GBytes *args;
gint64 start_time;
};
struct _GskShaderPaintableClass
{
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_SHADER,
PROP_ARGS,
N_PROPS,
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gsk_shader_paintable_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (paintable);
gtk_snapshot_push_gl_shader (snapshot, self->shader, &GRAPHENE_RECT_INIT(0, 0, width, height), g_bytes_ref (self->args));
gtk_snapshot_pop (snapshot);
}
static void
gsk_shader_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gsk_shader_paintable_paintable_snapshot;
}
G_DEFINE_TYPE_EXTENDED (GskShaderPaintable, gsk_shader_paintable, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gsk_shader_paintable_paintable_init))
static void
gsk_shader_paintable_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
gsk_shader_paintable_set_shader (self, g_value_get_object (value));
break;
case PROP_ARGS:
gsk_shader_paintable_set_args (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
g_value_set_object (value, self->shader);
break;
case PROP_ARGS:
g_value_set_boxed (value, self->args);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_finalize (GObject *object)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
g_clear_pointer (&self->args, g_bytes_unref);
g_clear_object (&self->shader);
G_OBJECT_CLASS (gsk_shader_paintable_parent_class)->finalize (object);
}
static void
gsk_shader_paintable_class_init (GskShaderPaintableClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gsk_shader_paintable_get_property;
gobject_class->set_property = gsk_shader_paintable_set_property;
gobject_class->finalize = gsk_shader_paintable_finalize;
properties[PROP_SHADER] =
g_param_spec_object ("shader", "Shader", "The shader",
GSK_TYPE_GL_SHADER,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_ARGS] =
g_param_spec_boxed ("args", "Arguments", "The uniform arguments",
G_TYPE_BYTES,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gsk_shader_paintable_init (GskShaderPaintable *self)
{
}
/**
* gsk_shader_paintable_new:
* @shader: (transfer full) (nullable): the shader to use
* @data: (transfer full) (nullable): uniform data
*
* Creates a paintable that uses the @shader to create
* pixels. The shader must not require input textures.
* If @data is %NULL, all uniform values are set to zero.
*
* Returns: (transfer full): a new `GskShaderPaintable`
*/
GdkPaintable *
gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data)
{
GdkPaintable *ret;
g_return_val_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader), NULL);
if (shader && !data)
{
int size = gsk_gl_shader_get_args_size (shader);
data = g_bytes_new_take (g_new0 (guchar, size), size);
}
ret = g_object_new (GSK_TYPE_SHADER_PAINTABLE,
"shader", shader,
"args", data,
NULL);
g_clear_object (&shader);
g_clear_pointer (&data, g_bytes_unref);
return ret;
}
/**
* gsk_shader_paintable_set_shader:
* @self: a `GskShaderPaintable`
* @shader: the `GskGLShader` to use
*
* Sets the shader that the paintable will use
* to create pixels. The shader must not require
* input textures.
*/
void
gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader));
g_return_if_fail (shader == NULL || gsk_gl_shader_get_n_textures (shader) == 0);
if (!g_set_object (&self->shader, shader))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHADER]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_clear_pointer (&self->args, g_bytes_unref);
}
/**
* gsk_shader_paintable_get_shader:
* @self: a `GskShaderPaintable`
*
* Returns the shader that the paintable is using.
*
* Returns: (transfer none): the `GskGLShader` that is used
*/
GskGLShader *
gsk_shader_paintable_get_shader (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->shader;
}
/**
* gsk_shader_paintable_set_args:
* @self: a `GskShaderPaintable`
* @data: Data block with uniform data for the shader
*
* Sets the uniform data that will be passed to the
* shader when rendering. The @data will typically
* be produced by a `GskUniformDataBuilder`.
*
* Note that the @data should be considered immutable
* after it has been passed to this function.
*/
void
gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (data == NULL || g_bytes_get_size (data) == gsk_gl_shader_get_args_size (self->shader));
g_clear_pointer (&self->args, g_bytes_unref);
if (data)
self->args = g_bytes_ref (data);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ARGS]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
/**
* gsk_shader_paintable_get_args:
* @self: a `GskShaderPaintable`
*
* Returns the uniform data set with
* gsk_shader_paintable_get_args().
*
* Returns: (transfer none): the uniform data
*/
GBytes *
gsk_shader_paintable_get_args (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->args;
}
/**
* gsk_shader_paintable_update_time:
* @self: a `GskShaderPaintable`
* @time_idx: the index of the uniform for time in seconds as float
* @frame_time: the current frame time, as returned by `GdkFrameClock`
*
* This function is a convenience wrapper for
* gsk_shader_paintable_set_args() that leaves all
* uniform values unchanged, except for the uniform with
* index @time_idx, which will be set to the elapsed time
* in seconds, since the first call to this function.
*
* This function is usually called from a `GtkTickCallback`.
*/
void
gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time)
{
GskShaderArgsBuilder *builder;
GBytes *args;
float time;
if (self->start_time == 0)
self->start_time = frame_time;
time = (frame_time - self->start_time) / (float)G_TIME_SPAN_SECOND;
builder = gsk_shader_args_builder_new (self->shader, self->args);
gsk_shader_args_builder_set_float (builder, time_idx, time);
args = gsk_shader_args_builder_free_to_args (builder);
gsk_shader_paintable_set_args (self, args);
g_bytes_unref (args);
}
G_GNUC_END_IGNORE_DEPRECATIONS
-47
View File
@@ -1,47 +0,0 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#pragma once
#include <gdk/gdk.h>
#include <gsk/gsk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data);
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader);
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data);
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS
+1 -1
View File
@@ -55,7 +55,7 @@ void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
gboolean animating);
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
gboolean animating);
gboolean benchmark);
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
-268
View File
@@ -1,268 +0,0 @@
#include "gtkshaderbin.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef struct {
GskGLShader *shader;
GtkStateFlags state;
GtkStateFlags state_mask;
float extra_border;
gboolean compiled;
gboolean compiled_ok;
} ShaderInfo;
struct _GtkShaderBin
{
GtkWidget parent_instance;
GtkWidget *child;
ShaderInfo *active_shader;
GPtrArray *shaders;
guint tick_id;
float time;
float mouse_x, mouse_y;
gint64 first_frame_time;
};
struct _GtkShaderBinClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkShaderBin, gtk_shader_bin, GTK_TYPE_WIDGET)
static void
shader_info_free (ShaderInfo *info)
{
g_object_unref (info->shader);
g_free (info);
}
static void
gtk_shader_bin_finalize (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_ptr_array_free (self->shaders, TRUE);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->finalize (object);
}
static void
gtk_shader_bin_dispose (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_clear_pointer (&self->child, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->dispose (object);
}
static gboolean
gtk_shader_bin_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer unused)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
if (self->first_frame_time == 0)
self->first_frame_time = frame_time;
self->time = (frame_time - self->first_frame_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
motion_cb (GtkEventControllerMotion *controller,
double x,
double y,
GtkShaderBin *self)
{
self->mouse_x = x;
self->mouse_y = y;
}
static void
gtk_shader_bin_init (GtkShaderBin *self)
{
GtkEventController *controller;
self->shaders = g_ptr_array_new_with_free_func ((GDestroyNotify)shader_info_free);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
void
gtk_shader_bin_update_active_shader (GtkShaderBin *self)
{
GtkStateFlags new_state = gtk_widget_get_state_flags (GTK_WIDGET (self));
ShaderInfo *new_shader = NULL;
for (int i = 0; i < self->shaders->len; i++)
{
ShaderInfo *info = g_ptr_array_index (self->shaders, i);
if ((info->state_mask & new_state) == info->state)
{
new_shader = info;
break;
}
}
if (self->active_shader == new_shader)
return;
self->active_shader = new_shader;
self->first_frame_time = 0;
if (self->active_shader)
{
if (self->tick_id == 0)
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
gtk_shader_bin_tick,
NULL, NULL);
}
else
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_shader_bin_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state_flags)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border)
{
ShaderInfo *info = g_new0 (ShaderInfo, 1);
info->shader = g_object_ref (shader);
info->state = state;
info->state_mask = state_mask;
info->extra_border = extra_border;
g_ptr_array_add (self->shaders, info);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child)
{
if (self->child == child)
return;
g_clear_pointer (&self->child, gtk_widget_unparent);
if (child)
{
self->child = child;
gtk_widget_set_parent (child, GTK_WIDGET (self));
}
}
GtkWidget *
gtk_shader_bin_get_child (GtkShaderBin *self)
{
return self->child;
}
static void
gtk_shader_bin_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
if (self->active_shader)
{
if (!self->active_shader->compiled)
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
GError *error = NULL;
self->active_shader->compiled = TRUE;
self->active_shader->compiled_ok =
gsk_gl_shader_compile (self->active_shader->shader,
renderer, &error);
if (!self->active_shader->compiled_ok)
{
g_warning ("GtkShaderBin failed to compile shader: %s", error->message);
g_error_free (error);
}
}
if (self->active_shader->compiled_ok)
{
float border = self->active_shader->extra_border;
graphene_vec2_t mouse;
graphene_vec2_init (&mouse, self->mouse_x + border, self->mouse_y + border);
gtk_snapshot_push_gl_shader (snapshot, self->active_shader->shader,
&GRAPHENE_RECT_INIT(-border, -border, width+2*border, height+2*border),
gsk_gl_shader_format_args (self->active_shader->shader,
"u_time", self->time,
"u_mouse", &mouse,
NULL));
gtk_widget_snapshot_child (widget, self->child, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot);
gtk_snapshot_pop (snapshot);
return;
}
}
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, self->child, snapshot);
}
static void
gtk_shader_bin_class_init (GtkShaderBinClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_bin_finalize;
object_class->dispose = gtk_shader_bin_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
widget_class->snapshot = gtk_shader_bin_snapshot;
widget_class->state_flags_changed = gtk_shader_bin_state_flags_changed;
}
GtkWidget *
gtk_shader_bin_new (void)
{
GtkShaderBin *self;
self = g_object_new (GTK_TYPE_SHADER_BIN, NULL);
return GTK_WIDGET (self);
}
G_GNUC_END_IGNORE_DEPRECATIONS
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_BIN (gtk_shader_bin_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderBin, gtk_shader_bin, GTK, SHADER_BIN, GtkWidget)
GtkWidget *gtk_shader_bin_new (void);
void gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border);
void gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child);
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS
-365
View File
@@ -1,365 +0,0 @@
#include "gtkshaderstack.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
struct _GtkShaderStack
{
GtkWidget parent_instance;
GskGLShader *shader;
GPtrArray *children;
int current;
int next;
gboolean backwards;
guint tick_id;
float time;
float duration;
gint64 start_time;
};
struct _GtkShaderStackClass
{
GtkWidgetClass parent_class;
};
enum {
PROP_DURATION = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
G_DEFINE_TYPE (GtkShaderStack, gtk_shader_stack, GTK_TYPE_WIDGET)
static void
gtk_shader_stack_finalize (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
g_object_unref (self->shader);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->finalize (object);
}
static void
update_child_visible (GtkShaderStack *self)
{
int i;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
gtk_widget_set_child_visible (child,
i == self->current || i == self->next);
}
}
static gboolean
transition_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer unused)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (clock);
if (self->start_time == 0)
self->start_time = frame_time;
self->time = (frame_time - self->start_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
if (self->time >= self->duration)
{
self->current = self->next;
self->next = -1;
update_child_visible (self);
return G_SOURCE_REMOVE;
}
else
return G_SOURCE_CONTINUE;
}
static void
start_transition (GtkShaderStack *self)
{
self->start_time = 0;
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
transition_cb,
NULL, NULL);
}
static void
stop_transition (GtkShaderStack *self)
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
if (self->next != -1)
self->current = self->next;
self->next = -1;
update_child_visible (self);
}
static void
gtk_shader_stack_dispose (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
stop_transition (self);
g_clear_pointer (&self->children, g_ptr_array_unref);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->dispose (object);
}
void
gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward)
{
stop_transition (self);
self->backwards = !forward;
if (self->backwards)
self->next = (self->current + self->children->len - 1) % self->children->len;
else
self->next = (self->current + 1) % self->children->len;
update_child_visible (self);
start_transition (self);
}
static void
gtk_shader_stack_init (GtkShaderStack *self)
{
self->children = g_ptr_array_new_with_free_func ((GDestroyNotify)gtk_widget_unparent);
self->current = -1;
self->next = -1;
self->backwards = FALSE;
self->duration = 1.0;
}
static void
gtk_shader_stack_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int i;
*minimum = 0;
*natural = 0;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
int child_min, child_nat;
if (gtk_widget_get_visible (child))
{
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
}
}
static void
gtk_shader_stack_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
GtkAllocation child_allocation;
GtkWidget *child;
int i;
child_allocation.x = 0;
child_allocation.y = 0;
child_allocation.width = width;
child_allocation.height = height;
for (i = 0; i < self->children->len; i++)
{
child = g_ptr_array_index (self->children, i);
if (gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, -1);
}
}
static void
gtk_shader_stack_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int width, height;
GtkWidget *current, *next;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
current = g_ptr_array_index (self->children, self->current);
if (self->next == -1)
{
gtk_widget_snapshot_child (widget, current, snapshot);
}
else
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
float progress;
next = g_ptr_array_index (self->children, self->next);
progress = self->time / self->duration;
if (self->backwards)
{
GtkWidget *tmp = next;
next = current;
current = tmp;
progress = 1. - progress;
}
if (gsk_gl_shader_compile (self->shader, renderer, NULL))
{
gtk_snapshot_push_gl_shader (snapshot,
self->shader,
&GRAPHENE_RECT_INIT(0, 0, width, height),
gsk_gl_shader_format_args (self->shader,
"progress", progress,
NULL));
gtk_widget_snapshot_child (widget, current, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* current child */
gtk_widget_snapshot_child (widget, next, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* next child */
gtk_snapshot_pop (snapshot);
}
else
{
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, current, snapshot);
}
}
}
static void
gtk_shader_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
g_value_set_float (value, self->duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
self->duration = g_value_get_float (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_class_init (GtkShaderStackClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_stack_finalize;
object_class->dispose = gtk_shader_stack_dispose;
object_class->get_property = gtk_shader_stack_get_property;
object_class->set_property = gtk_shader_stack_set_property;
widget_class->snapshot = gtk_shader_stack_snapshot;
widget_class->measure = gtk_shader_stack_measure;
widget_class->size_allocate = gtk_shader_stack_size_allocate;
properties[PROP_DURATION] =
g_param_spec_float ("duration", "Duration", "Duration",
0.1, 3.0, 1.0,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
GtkWidget *
gtk_shader_stack_new (void)
{
return g_object_new (GTK_TYPE_SHADER_STACK, NULL);
}
void
gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader)
{
g_set_object (&self->shader, shader);
}
void
gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child)
{
g_ptr_array_add (self->children, child);
gtk_widget_set_parent (child, GTK_WIDGET (self));
gtk_widget_queue_resize (GTK_WIDGET (self));
if (self->current == -1)
self->current = 0;
else
gtk_widget_set_child_visible (child, FALSE);
}
void
gtk_shader_stack_set_active (GtkShaderStack *self,
int index)
{
stop_transition (self);
self->current = MIN (index, self->children->len);
update_child_visible (self);
}
G_GNUC_END_IGNORE_DEPRECATIONS
-24
View File
@@ -1,24 +0,0 @@
#pragma once
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_STACK (gtk_shader_stack_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderStack, gtk_shader_stack, GTK, SHADER_STACK, GtkWidget)
GtkWidget * gtk_shader_stack_new (void);
void gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader);
void gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child);
void gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward);
void gtk_shader_stack_set_active (GtkShaderStack *self,
int index);
G_END_DECLS
G_GNUC_END_IGNORE_DEPRECATIONS
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include <gdk/gdk.h>
typedef struct _GdkHSLA GdkHSLA;
struct _GdkHSLA {
+73 -29
View File
@@ -13,7 +13,7 @@ static GtkWidget *window = NULL;
static GtkWidget *scrolledwindow;
static int selected;
#define N_WIDGET_TYPES 8
#define N_WIDGET_TYPES 9
static int hincrement = 5;
@@ -73,30 +73,77 @@ populate_icons (void)
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), grid);
}
static char *content;
static gsize content_len;
extern void fontify (const char *format, GtkTextBuffer *buffer);
enum {
PLAIN_TEXT,
HIGHLIGHTED_TEXT,
UNDERLINED_TEXT,
};
static void
populate_text (gboolean highlight)
underlinify (GtkTextBuffer *buffer)
{
GtkTextTagTable *tags;
GtkTextTag *tag[3];
GtkTextIter start, end;
tags = gtk_text_buffer_get_tag_table (buffer);
tag[0] = gtk_text_tag_new ("error");
tag[1] = gtk_text_tag_new ("strikeout");
tag[2] = gtk_text_tag_new ("double");
g_object_set (tag[0], "underline", PANGO_UNDERLINE_ERROR, NULL);
g_object_set (tag[1], "strikethrough", TRUE, NULL);
g_object_set (tag[2],
"underline", PANGO_UNDERLINE_DOUBLE,
"underline-rgba", &(GdkRGBA){0., 1., 1., 1. },
NULL);
gtk_text_tag_table_add (tags, tag[0]);
gtk_text_tag_table_add (tags, tag[1]);
gtk_text_tag_table_add (tags, tag[2]);
gtk_text_buffer_get_start_iter (buffer, &end);
while (TRUE)
{
gtk_text_iter_forward_word_end (&end);
start = end;
gtk_text_iter_backward_word_start (&start);
gtk_text_buffer_apply_tag (buffer, tag[g_random_int_range (0, 3)], &start, &end);
if (!gtk_text_iter_forward_word_ends (&end, 3))
break;
}
}
static void
populate_text (const char *resource, int kind)
{
GtkWidget *textview;
GtkTextBuffer *buffer;
char *content;
gsize content_len;
GBytes *bytes;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
bytes = g_resources_lookup_data (resource, 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buffer, content, (int)content_len);
if (highlight)
fontify ("c", buffer);
switch (kind)
{
case HIGHLIGHTED_TEXT:
fontify ("c", buffer);
break;
case UNDERLINED_TEXT:
underlinify (buffer);
break;
case PLAIN_TEXT:
default:
break;
}
textview = gtk_text_view_new ();
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
@@ -155,14 +202,6 @@ populate_image (void)
{
GtkWidget *image;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
image = gtk_picture_new_for_resource ("/sliding_puzzle/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
@@ -255,35 +294,40 @@ set_widget_type (int type)
case 1:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
populate_text (FALSE);
populate_text ("/sources/font_features.c", PLAIN_TEXT);
break;
case 2:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
populate_text (TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Scrolling colored text");
populate_text ("/sources/font_features.c", HIGHLIGHTED_TEXT);
break;
case 3:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with underlines");
populate_text ("/org/gtk/Demo4/Moby-Dick.txt", UNDERLINED_TEXT);
break;
case 4:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with Emoji");
populate_emoji_text ();
break;
case 4:
case 5:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
populate_image ();
break;
case 5:
case 6:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
populate_list ();
break;
case 6:
case 7:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a columned list");
populate_list2 ();
break;
case 7:
case 8:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
populate_grid ();
break;
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">0</property>
<property name="resizable">1</property>
<property name="default-width">500</property>
<property name="default-height">500</property>
<child type="titlebar">
-41
View File
@@ -1,41 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/kaleidoscope
// Author: nwoeanhinnogaehr
// License: MIT
const float speed = 1.0;
const float angle = 1.0;
const float power = 1.5;
vec4 transition(vec2 uv) {
vec2 p = uv.xy / vec2(1.0).xy;
vec2 q = p;
float t = pow(progress, power)*speed;
p = p -0.5;
for (int i = 0; i < 7; i++) {
p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);
t += angle;
p = abs(mod(p, 2.0) - 1.0);
}
abs(mod(p, 1.0));
return mix(
mix(getFromColor(q), getToColor(q), progress),
mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+8 -8
View File
@@ -355,28 +355,28 @@ create_clocks_model (void)
g_list_store_append (result, clock);
g_object_unref (clock);
/* A bunch of timezones with GTK hackers */
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
clock = gtk_clock_new ("San Francisco", g_time_zone_new_identifier ("America/Los_Angeles"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Xalapa", g_time_zone_new ("America/Mexico_City"));
clock = gtk_clock_new ("Xalapa", g_time_zone_new_identifier ("America/Mexico_City"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
clock = gtk_clock_new ("Boston", g_time_zone_new_identifier ("America/New_York"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("London", g_time_zone_new ("Europe/London"));
clock = gtk_clock_new ("London", g_time_zone_new_identifier ("Europe/London"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Berlin", g_time_zone_new ("Europe/Berlin"));
clock = gtk_clock_new ("Berlin", g_time_zone_new_identifier ("Europe/Berlin"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Moscow", g_time_zone_new ("Europe/Moscow"));
clock = gtk_clock_new ("Moscow", g_time_zone_new_identifier ("Europe/Moscow"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("New Delhi", g_time_zone_new ("Asia/Kolkata"));
clock = gtk_clock_new ("New Delhi", g_time_zone_new_identifier ("Asia/Kolkata"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Shanghai", g_time_zone_new ("Asia/Shanghai"));
clock = gtk_clock_new ("Shanghai", g_time_zone_new_identifier ("Asia/Shanghai"));
g_list_store_append (result, clock);
g_object_unref (clock);
-8
View File
@@ -156,11 +156,6 @@ gtk_demo_run (GtkDemo *self,
if (result == NULL)
return FALSE;
if (GTK_IS_WINDOW (result))
{
gtk_window_set_transient_for (GTK_WINDOW (result), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (result), TRUE);
}
return TRUE;
}
@@ -832,9 +827,6 @@ static gboolean
demo_can_run (GtkWidget *window,
const char *name)
{
if (name != NULL && strcmp (name, "gltransition") == 0)
return GSK_IS_GL_RENDERER (gtk_native_get_renderer (GTK_NATIVE (window)));
return TRUE;
}
-4
View File
@@ -33,7 +33,6 @@ demos = files([
'gears.c',
'gestures.c',
'glarea.c',
'gltransition.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -117,10 +116,7 @@ extra_demo_sources = files([
'gtkfishbowl.c',
'fontplane.c',
'gtkgears.c',
'gtkshaderbin.c',
'gtkshadertoy.c',
'gtkshaderstack.c',
'gskshaderpaintable.c',
'hsla.c',
'puzzlepiece.c',
'bluroverlay.c',
+1 -1
View File
@@ -5,4 +5,4 @@
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *file);
GtkWidget * node_widget_new (const char *resource);
-34
View File
@@ -1,34 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/Radial
// License: MIT
// Author: Xaychru
const float smoothness = 1.0;
const float PI = 3.141592653589;
vec4 transition(vec2 p) {
vec2 rp = p*2.-1.;
return mix(
getToColor(p),
getFromColor(p),
smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)
);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
-43
View File
@@ -1,43 +0,0 @@
uniform float u_time;
uniform vec2 u_mouse;
uniform sampler2D u_texture1;
#define PI 3.141592654
float decay(float v, float t)
{
return v * (1.0 / (1.0 + t*t));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
// Temporary to loop time every 1 sec
float time = u_time;
// we normalize all the effects according to the min height/width
float size = min(resolution.x, resolution.y);
// Animate one wave over size in 0.3 sec
float wave_speed = size / 0.3;
float wave_length = size / 1.0;
float wave_height = size * 0.1;
vec2 center = u_mouse;
vec2 direction_from_center = fragCoord - center;
float distance_from_center = length(direction_from_center);
/* Normalize direction */
direction_from_center = direction_from_center / distance_from_center;
float propagation_length = time * wave_speed;
float t = (propagation_length - distance_from_center) / wave_length;
float offset_magnitude = 0.0;
if (t > 0.0)
offset_magnitude = decay(wave_height * sin(t * 2.0 * PI), t);
vec2 offset = direction_from_center * min(offset_magnitude, distance_from_center);
vec2 source = fragCoord - offset;
vec2 uv2 = source / resolution;
fragColor = GskTexture(u_texture1, vec2(uv2.x, 1.0-uv2.y));
}
+1 -1
View File
@@ -43,7 +43,7 @@ GtkListItemFactory *
suggestion_entry_get_factory (SuggestionEntry *self);
void suggestion_entry_set_use_filter (SuggestionEntry *self,
gboolean use_ilter);
gboolean use_filter);
gboolean suggestion_entry_get_use_filter (SuggestionEntry *self);
void suggestion_entry_set_expression (SuggestionEntry *self,
-33
View File
@@ -1,33 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/wind
// Author: gre
// License: MIT
const float size = 0.2;
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
vec4 transition(vec2 p) {
float r = rand(vec2(0, p.y));
float m = smoothstep(0.0, -size, p.x*(1.0-size) + size*r - (progress * (1.0 + size)));
return mix(getFromColor(p), getToColor(p), m);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}
+1 -1
View File
@@ -925,7 +925,7 @@ export_image_response_cb (GObject *source,
GdkTexture *texture;
GskRenderer *renderer;
renderer = gsk_gl_renderer_new ();
renderer = gsk_ngl_renderer_new ();
if (!gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), NULL))
{
g_object_unref (renderer);
-4
View File
@@ -66,10 +66,6 @@ You can compile the program above with GCC using:
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
```
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
others in this documentation.
For more information on how to compile a GTK application, please
refer to the [Compiling GTK Applications](compiling.html)
section in this reference.
+31 -21
View File
@@ -181,15 +181,21 @@ matrix3d() production to specify all 16 values individually.
### conic-gradient
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| center | `<point>` | 25, 25 | always |
| rotation | `<number>` | 0 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
| property | syntax | default | printed |
| ----------------- | --------------- | -------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| center | `<point>` | 25, 25 | always |
| rotation | `<number>` | 0 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
| interpolation | `<color-state>` | srgb | non-default |
| hue-interpolation | `<hue-interp>` | shorter | non-default |
Creates a node like `gsk_conic_gradient_node_new()` with the given properties.
Possible values for the hue-interpolation property are:
hue-interpolation: shorter | longer | increasing | decreasing
### cross-fade
| property | syntax | default | printed |
@@ -258,12 +264,14 @@ Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
### linear-gradient
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| start | `<point>` | 0 0 | always |
| end | `<point>` | 0 50 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
| property | syntax | default | printed |
| ----------------- | --------------- | -------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| start | `<point>` | 0 0 | always |
| end | `<point>` | 0 50 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
| interpolation | `<color-state>` | srgb | non-default |
| hue-interpolation | `<hue-interp>` | shorter | non-default |
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
@@ -305,15 +313,17 @@ Creates a node like `gsk_outset_shadow_node_new()` with the given properties.
### radial-gradient
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| center | `<point>` | 25 25 | always |
| hradius | `<number>` | 25 | always |
| vradius | `<number>` | 25 | always |
| start | `<number>` | 0 | always |
| end | `<number>` | 1 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
| property | syntax | default | printed |
| ----------------- | --------------- | -------------- | ----------- |
| bounds | `<rect>` | 50 | always |
| center | `<point>` | 25 25 | always |
| hradius | `<number>` | 25 | always |
| vradius | `<number>` | 25 | always |
| start | `<number>` | 0 | always |
| end | `<number>` | 1 | always |
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
| interpolation | `<color-state>` | srgb | non-default |
| hue-interpolation | `<hue-interp>` | shorter | non-default |
Creates a node like `gsk_radial_gradient_node_new()` with the given properties.
+1 -14
View File
@@ -380,13 +380,6 @@ does not support them.
`base-instance`
:GL_EXT_base_instance
### `GDK_VULKAN_DEVICE`
This variable can be set to the index of a Vulkan device to override
the default selection of the device that is used for Vulkan rendering.
The special value `list` can be used to obtain a list of all Vulkan
devices.
### `GDK_VULKAN_DISABLE`
This variable can be set to a list of values, which cause GDK to
@@ -430,14 +423,8 @@ using and the GDK backend supports them:
`cairo`
: Selects the fallback Cairo renderer
`opengl`
: Selects the default OpenGL renderer
`gl`
: Selects the "gl" OpenGL renderer
`ngl`
: Selects the "ngl" OpenGL renderer
: Selects the OpenGL renderer
`vulkan`
: Selects the Vulkan renderer
+1 -1
View File
@@ -49,7 +49,7 @@ main (int argc,
g_chdir (GTK_SRCDIR);
#endif
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
GtkApplication *app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
int status = g_application_run (G_APPLICATION (app), argc, argv);
+1 -1
View File
@@ -173,7 +173,7 @@ main (int argc,
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
+1 -1
View File
@@ -60,7 +60,7 @@ main (int argc,
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
+2 -4
View File
@@ -37,10 +37,8 @@ main (int argc,
{
GtkApplication *app;
app = gtk_application_new ("org.gtk.Example.GtkSearchBar",
G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate",
G_CALLBACK (activate_cb), NULL);
app = gtk_application_new ("org.gtk.Example.GtkSearchBar", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate_cb), NULL);
return g_application_run (G_APPLICATION (app), argc, argv);
}
+1 -1
View File
@@ -19,7 +19,7 @@ main (int argc,
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
app = gtk_application_new ("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
+1 -1
View File
@@ -111,7 +111,7 @@ gboolean broadway_server_surface_translate (BroadwayServer *
int dx,
int dy);
guint32 broadway_server_upload_texture (BroadwayServer *server,
GBytes *texture);
GBytes *bytes);
void broadway_server_release_texture (BroadwayServer *server,
guint32 id);
cairo_surface_t * broadway_server_create_surface (int width,
+7
View File
@@ -257,6 +257,12 @@ gdk_broadway_display_flush (GdkDisplay *display)
_gdk_broadway_server_flush (broadway_display->server);
}
static gboolean
gdk_broadway_display_has_pending (GdkDisplay *display)
{
return FALSE;
}
static void
gdk_broadway_display_dispose (GObject *object)
{
@@ -479,6 +485,7 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
display_class->beep = gdk_broadway_display_beep;
display_class->sync = gdk_broadway_display_sync;
display_class->flush = gdk_broadway_display_flush;
display_class->has_pending = gdk_broadway_display_has_pending;
display_class->queue_events = _gdk_broadway_display_queue_events;
display_class->get_next_serial = gdk_broadway_display_get_next_serial;
+1 -1
View File
@@ -56,7 +56,7 @@ void _gdk_broadway_surface_translate (GdkSurface *surface,
int dx,
int dy);
gboolean _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
BroadwayInputMsg *msg);
BroadwayInputMsg *event);
gboolean _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
GdkSurface *surface);
void _gdk_broadway_roundtrip_notify (GdkSurface *surface,
+1
View File
@@ -17,6 +17,7 @@
#pragma once
#include <gio/gio.h>
void file_transfer_portal_register (void);
+12
View File
@@ -122,6 +122,18 @@ gdk_cairo_pattern_add_color_stop_rgba_ccs (cairo_pattern_t *pattern,
cairo_pattern_add_color_stop_rgba (pattern, offset, color[0], color[1], color[2], color[3]);
}
static inline void
gdk_cairo_pattern_add_color_stop_color (cairo_pattern_t *pattern,
GdkColorState *ccs,
double offset,
const GdkColor *color)
{
float values[4];
gdk_color_to_float (color, ccs, values);
cairo_pattern_add_color_stop_rgba (pattern, offset, values[0], values[1], values[2], values[3]);
}
static inline void
gdk_cairo_rect (cairo_t *cr,
const graphene_rect_t *rect)
+1 -1
View File
@@ -79,6 +79,6 @@ gdk_cicp_equivalent (const GdkCicp *p1,
return gdk_cicp_equal (&n1, &n2);
}
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *params);
const GdkCicp * gdk_cicp_params_get_cicp (GdkCicpParams *self);
GdkCicpParams * gdk_cicp_params_new_for_cicp (const GdkCicp *cicp);
+53
View File
@@ -20,6 +20,9 @@
* and tests, and must not include other headers.
*/
#include <glib.h>
#include <math.h>
static inline int
sign (float v)
{
@@ -230,3 +233,53 @@ static const float srgb_to_rec2020[9] = {
0.069108, 0.919519, 0.011360,
0.016394, 0.088011, 0.895380,
};
/* oklab conversion */
static float
from_oklab_nl (float v)
{
return v * v * v;
}
static float
to_oklab_nl (float v)
{
return cbrtf (v);
}
static const float oklab_to_lms[9] = {
1, 0.3963377774, 0.2158037573,
1, -0.1055613458, -0.0638541728,
1, -0.0894841775, -1.2914855480
};
static const float lms_to_srgb[9] = {
4.0767416621, -3.3077115913, 0.2309699292,
-1.2684380046, 2.6097574011, -0.3413193965,
-0.0041960863, -0.7034186147, 1.7076147010,
};
static const float srgb_to_lms[9] = {
0.4122214708, 0.5363325363, 0.0514459929,
0.2119034982, 0.6806995451, 0.1073969566,
0.0883024619, 0.2817188376, 0.6299787005,
};
static const float lms_to_oklab[9] = {
0.2104542553, 0.7936177850, -0.0040720468,
1.9779984951, -2.4285922050, 0.4505937099,
0.0259040371, 0.7827717662, -0.8086757660,
};
static const float rec2020_to_lms[9] = {
0.616645, 0.360250, 0.023064,
0.265075, 0.635874, 0.099059,
0.100076, 0.203907, 0.696161,
};
static const float lms_to_rec2020[9] = {
2.140325, -1.246734, 0.106491,
-0.884665, 2.163141, -0.278489,
-0.048559, -0.454366, 1.502711,
};
+2
View File
@@ -18,6 +18,8 @@
#pragma once
#include "gdkcolorprivate.h"
#include "gdkcolorstateprivate.h"
+2 -2
View File
@@ -79,8 +79,8 @@ void gdk_color_init_from_rgba (GdkColor *self,
const GdkRGBA *rgba);
void gdk_color_finish (GdkColor *self);
gboolean gdk_color_equal (const GdkColor *color1,
const GdkColor *color2);
gboolean gdk_color_equal (const GdkColor *self,
const GdkColor *other);
gboolean gdk_color_is_clear (const GdkColor *self);
gboolean gdk_color_is_opaque (const GdkColor *self);
+254 -67
View File
@@ -172,6 +172,18 @@ gdk_color_state_get_rec2100_linear (void)
return GDK_COLOR_STATE_REC2100_LINEAR;
}
GdkColorState *
gdk_color_state_get_oklab (void)
{
return GDK_COLOR_STATE_OKLAB;
}
GdkColorState *
gdk_color_state_get_oklch (void)
{
return GDK_COLOR_STATE_OKLCH;
}
/**
* gdk_color_state_equal:
* @self: a `GdkColorState`
@@ -223,56 +235,171 @@ gdk_color_state_create_cicp_params (GdkColorState *self)
/* {{{ Conversion functions */
typedef float (* GdkTransferFunc) (float v);
typedef void (* GdkConvertFunc) (GdkColorState *self,
float values[4]);
typedef const float GdkColorMatrix[9];
#define IDENTITY ((float*)0)
#define NONE ((GdkTransferFunc)0)
#define TRANSFORM(name, eotf, matrix, oetf) \
#define CONVERT_FUNC(name) \
static void \
name (GdkColorState *self, \
float (*values)[4], \
gsize n_values) \
gdk_convert_ ## name (GdkColorState *self, \
float (*values)[4], \
gsize n_values) \
{ \
for (gsize i = 0; i < n_values; i++) \
{ \
if (eotf != NONE) \
{ \
values[i][0] = eotf (values[i][0]); \
values[i][1] = eotf (values[i][1]); \
values[i][2] = eotf (values[i][2]); \
} \
if (matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = matrix[0] * values[i][0] + matrix[1] * values[i][1] + matrix[2] * values[i][2]; \
res[1] = matrix[3] * values[i][0] + matrix[4] * values[i][1] + matrix[5] * values[i][2]; \
res[2] = matrix[6] * values[i][0] + matrix[7] * values[i][1] + matrix[8] * values[i][2]; \
values[i][0] = res[0]; \
values[i][1] = res[1]; \
values[i][2] = res[2]; \
} \
if (oetf != NONE) \
{ \
values[i][0] = oetf (values[i][0]); \
values[i][1] = oetf (values[i][1]); \
values[i][2] = oetf (values[i][2]); \
} \
name (self, values[i]); \
} \
}
TRANSFORM(gdk_default_srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE);
TRANSFORM(gdk_default_srgb_linear_to_srgb, NONE, IDENTITY, srgb_oetf)
TRANSFORM(gdk_default_rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE)
TRANSFORM(gdk_default_rec2100_linear_to_rec2100_pq, NONE, IDENTITY, pq_oetf)
TRANSFORM(gdk_default_srgb_linear_to_rec2100_linear, NONE, srgb_to_rec2020, NONE)
TRANSFORM(gdk_default_rec2100_linear_to_srgb_linear, NONE, rec2020_to_srgb, NONE)
TRANSFORM(gdk_default_srgb_to_rec2100_linear, srgb_eotf, srgb_to_rec2020, NONE)
TRANSFORM(gdk_default_rec2100_pq_to_srgb_linear, pq_eotf, rec2020_to_srgb, NONE)
TRANSFORM(gdk_default_srgb_linear_to_rec2100_pq, NONE, srgb_to_rec2020, pq_oetf)
TRANSFORM(gdk_default_rec2100_linear_to_srgb, NONE, rec2020_to_srgb, srgb_oetf)
TRANSFORM(gdk_default_srgb_to_rec2100_pq, srgb_eotf, srgb_to_rec2020, pq_oetf)
TRANSFORM(gdk_default_rec2100_pq_to_srgb, pq_eotf, rec2020_to_srgb, srgb_oetf)
#define TRANSFORM(name, eotf, matrix, nonlinear, matrix2, oetf) \
static inline void \
name (GdkColorState *self, \
float values[4]) \
{ \
if (eotf != NONE) \
{ \
values[0] = eotf (values[0]); \
values[1] = eotf (values[1]); \
values[2] = eotf (values[2]); \
} \
if (matrix != IDENTITY) \
{ \
float res[3]; \
res[0] = matrix[0] * values[0] + matrix[1] * values[1] + matrix[2] * values[2]; \
res[1] = matrix[3] * values[0] + matrix[4] * values[1] + matrix[5] * values[2]; \
res[2] = matrix[6] * values[0] + matrix[7] * values[1] + matrix[8] * values[2]; \
values[0] = res[0]; \
values[1] = res[1]; \
values[2] = res[2]; \
} \
if (nonlinear != NONE) \
{ \
values[0] = nonlinear (values[0]); \
values[1] = nonlinear (values[1]); \
values[2] = nonlinear (values[2]); \
} \
if (matrix2 != IDENTITY) \
{ \
float res[3]; \
res[0] = matrix2[0] * values[0] + matrix2[1] * values[1] + matrix2[2] * values[2]; \
res[1] = matrix2[3] * values[0] + matrix2[4] * values[1] + matrix2[5] * values[2]; \
res[2] = matrix2[6] * values[0] + matrix2[7] * values[1] + matrix2[8] * values[2]; \
values[0] = res[0]; \
values[1] = res[1]; \
values[2] = res[2]; \
} \
if (oetf != NONE) \
{ \
values[0] = oetf (values[0]); \
values[1] = oetf (values[1]); \
values[2] = oetf (values[2]); \
} \
} \
CONVERT_FUNC (name)
#define TRANSFORM_PAIR(name, func1, func2) \
static inline void \
name (GdkColorState *self, \
float values[4]) \
{ \
func1 (self, values); \
func2 (self, values); \
} \
CONVERT_FUNC (name)
TRANSFORM(srgb_to_srgb_linear, srgb_eotf, IDENTITY, NONE, IDENTITY, NONE)
TRANSFORM(srgb_linear_to_srgb, NONE, IDENTITY, NONE, IDENTITY, srgb_oetf)
TRANSFORM(rec2100_pq_to_rec2100_linear, pq_eotf, IDENTITY, NONE, IDENTITY, NONE)
TRANSFORM(rec2100_linear_to_rec2100_pq, NONE, IDENTITY, NONE, IDENTITY, pq_oetf)
TRANSFORM(srgb_linear_to_rec2100_linear, NONE, srgb_to_rec2020, NONE, IDENTITY, NONE)
TRANSFORM(rec2100_linear_to_srgb_linear, NONE, rec2020_to_srgb, NONE, IDENTITY, NONE)
TRANSFORM(srgb_to_rec2100_linear, srgb_eotf, srgb_to_rec2020, NONE, IDENTITY, NONE)
TRANSFORM(rec2100_pq_to_srgb_linear, pq_eotf, rec2020_to_srgb, NONE, IDENTITY, NONE)
TRANSFORM(srgb_linear_to_rec2100_pq, NONE, srgb_to_rec2020, NONE, IDENTITY, pq_oetf)
TRANSFORM(rec2100_linear_to_srgb, NONE, rec2020_to_srgb, NONE, IDENTITY, srgb_oetf)
TRANSFORM(srgb_to_rec2100_pq, srgb_eotf, srgb_to_rec2020, NONE, IDENTITY, pq_oetf)
TRANSFORM(rec2100_pq_to_srgb, pq_eotf, rec2020_to_srgb, NONE, IDENTITY, srgb_oetf)
TRANSFORM(oklab_to_srgb_linear, NONE, oklab_to_lms, from_oklab_nl, lms_to_srgb, NONE)
TRANSFORM(oklab_to_srgb, NONE, oklab_to_lms, from_oklab_nl, lms_to_srgb, srgb_oetf)
TRANSFORM(oklab_to_rec2100_linear, NONE, oklab_to_lms, from_oklab_nl, lms_to_rec2020, NONE)
TRANSFORM(oklab_to_rec2100_pq, NONE, oklab_to_lms, from_oklab_nl, lms_to_rec2020, pq_oetf)
TRANSFORM(srgb_linear_to_oklab, NONE, srgb_to_lms, to_oklab_nl, lms_to_oklab, NONE)
TRANSFORM(srgb_to_oklab, srgb_eotf, srgb_to_lms, to_oklab_nl, lms_to_oklab, NONE)
TRANSFORM(rec2100_linear_to_oklab, NONE, rec2020_to_lms, to_oklab_nl, lms_to_oklab, NONE)
TRANSFORM(rec2100_pq_to_oklab, pq_eotf, rec2020_to_lms, to_oklab_nl, lms_to_oklab, NONE)
#define DEG_TO_RAD(x) ((x) * G_PI / 180)
#define RAD_TO_DEG(x) ((x) * 180 / G_PI)
static inline void
_sincosf (float angle,
float *out_s,
float *out_c)
{
#ifdef HAVE_SINCOSF
sincosf (angle, out_s, out_c);
#else
*out_s = sinf (angle);
*out_c = cosf (angle);
#endif
}
static void
oklch_to_oklab (GdkColorState *self,
float values[4])
{
float L, C, H, a, b;
L = values[0];
C = values[1];
H = values[2];
_sincosf (DEG_TO_RAD (H), &b, &a);
a *= C;
b *= C;
values[0] = L;
values[1] = a;
values[2] = b;
}
static void
oklab_to_oklch (GdkColorState *self,
float values[4])
{
float L, a, b, C, H;
L = values[0];
a = values[1];
b = values[2];
C = hypotf (a, b);
H = RAD_TO_DEG (atan2 (b, a));
H = fmod (H, 360);
if (H < 0)
H += 360;
values[0] = L;
values[1] = C;
values[2] = H;
}
CONVERT_FUNC (oklch_to_oklab)
CONVERT_FUNC (oklab_to_oklch)
TRANSFORM_PAIR (srgb_to_oklch, srgb_to_oklab, oklab_to_oklch)
TRANSFORM_PAIR (srgb_linear_to_oklch, srgb_linear_to_oklab, oklab_to_oklch)
TRANSFORM_PAIR (rec2100_pq_to_oklch, rec2100_pq_to_oklab, oklab_to_oklch)
TRANSFORM_PAIR (rec2100_linear_to_oklch, rec2100_linear_to_oklab, oklab_to_oklch)
TRANSFORM_PAIR (oklch_to_srgb, oklch_to_oklab, oklab_to_srgb)
TRANSFORM_PAIR (oklch_to_srgb_linear, oklch_to_oklab, oklab_to_srgb_linear)
TRANSFORM_PAIR (oklch_to_rec2100_pq, oklch_to_oklab, oklab_to_rec2100_pq)
TRANSFORM_PAIR (oklch_to_rec2100_linear, oklch_to_oklab, oklab_to_rec2100_pq)
/* }}} */
/* {{{ Default implementation */
@@ -328,6 +455,9 @@ gdk_default_color_state_get_cicp (GdkColorState *color_state)
{
GdkDefaultColorState *self = (GdkDefaultColorState *) color_state;
if (self->cicp.color_primaries == 0)
return NULL;
return &self->cicp;
}
@@ -419,9 +549,11 @@ GdkDefaultColorState gdk_default_color_states[] = {
.name = "srgb",
.no_srgb = GDK_COLOR_STATE_SRGB_LINEAR,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_srgb_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_to_rec2100_linear,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_srgb_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_srgb_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_srgb_to_rec2100_linear,
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_srgb_to_oklab,
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_srgb_to_oklch,
},
.clamp = gdk_color_state_clamp_0_1,
.cicp = { 1, 13, 0, 1 },
@@ -437,9 +569,11 @@ GdkDefaultColorState gdk_default_color_states[] = {
.name = "srgb-linear",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_srgb_linear_to_srgb,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_srgb_linear_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_srgb_linear_to_rec2100_linear,
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_srgb_linear_to_srgb,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_srgb_linear_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_srgb_linear_to_rec2100_linear,
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_srgb_linear_to_oklab,
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_srgb_linear_to_oklch,
},
.clamp = gdk_color_state_clamp_0_1,
.cicp = { 1, 8, 0, 1 },
@@ -455,9 +589,11 @@ GdkDefaultColorState gdk_default_color_states[] = {
.name = "rec2100-pq",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_pq_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_pq_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_default_rec2100_pq_to_rec2100_linear,
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_rec2100_pq_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_rec2100_pq_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_rec2100_pq_to_rec2100_linear,
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_rec2100_pq_to_oklab,
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_rec2100_pq_to_oklch,
},
.clamp = gdk_color_state_clamp_0_1,
.cicp = { 9, 16, 0, 1 },
@@ -473,16 +609,54 @@ GdkDefaultColorState gdk_default_color_states[] = {
.name = "rec2100-linear",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_default_rec2100_linear_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_default_rec2100_linear_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_default_rec2100_linear_to_rec2100_pq,
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_rec2100_linear_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_rec2100_linear_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_rec2100_linear_to_rec2100_pq,
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_rec2100_linear_to_oklab,
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_rec2100_linear_to_oklch,
},
.clamp = gdk_color_state_clamp_unbounded,
.cicp = { 9, 8, 0, 1 },
},
[GDK_COLOR_STATE_ID_OKLAB] = {
.parent = {
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
.ref_count = 0,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_SRGB,
},
.name = "oklab",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_oklab_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_oklab_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_oklab_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_oklab_to_rec2100_linear,
[GDK_COLOR_STATE_ID_OKLCH] = gdk_convert_oklab_to_oklch,
},
.cicp = { 0, 0, 0, 0 },
},
[GDK_COLOR_STATE_ID_OKLCH] = {
.parent = {
.klass = &GDK_DEFAULT_COLOR_STATE_CLASS,
.ref_count = 0,
.depth = GDK_MEMORY_FLOAT16,
.rendering_color_state = GDK_COLOR_STATE_SRGB,
},
.name = "oklch",
.no_srgb = NULL,
.convert_to = {
[GDK_COLOR_STATE_ID_SRGB] = gdk_convert_oklch_to_srgb,
[GDK_COLOR_STATE_ID_SRGB_LINEAR] = gdk_convert_oklch_to_srgb_linear,
[GDK_COLOR_STATE_ID_REC2100_PQ] = gdk_convert_oklch_to_rec2100_pq,
[GDK_COLOR_STATE_ID_REC2100_LINEAR] = gdk_convert_oklch_to_rec2100_linear,
[GDK_COLOR_STATE_ID_OKLAB] = gdk_convert_oklch_to_oklab,
},
.cicp = { 0, 0, 0, 0 },
},
};
/* }}} */
/* }}} */
/* {{{ Cicp implementation */
typedef struct _GdkCicpColorState GdkCicpColorState;
@@ -509,17 +683,22 @@ struct _GdkCicpColorState
#define cicp ((GdkCicpColorState *)self)
TRANSFORM(gdk_cicp_to_srgb, cicp->eotf, cicp->to_srgb, srgb_oetf)
TRANSFORM(gdk_cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE)
TRANSFORM(gdk_cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, pq_oetf)
TRANSFORM(gdk_cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE)
TRANSFORM(gdk_cicp_from_srgb, srgb_eotf, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_srgb_linear, NONE, cicp->from_srgb, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, cicp->oetf)
TRANSFORM(gdk_cicp_from_rec2100_linear, NONE, cicp->from_rec2020, cicp->oetf)
TRANSFORM(cicp_to_srgb, cicp->eotf, cicp->to_srgb, NONE, IDENTITY, srgb_oetf)
TRANSFORM(cicp_to_srgb_linear, cicp->eotf, cicp->to_srgb, NONE, IDENTITY, NONE)
TRANSFORM(cicp_to_rec2100_pq, cicp->eotf, cicp->to_rec2020, NONE, IDENTITY, pq_oetf)
TRANSFORM(cicp_to_rec2100_linear, cicp->eotf, cicp->to_rec2020, NONE, IDENTITY, NONE)
TRANSFORM(cicp_from_srgb, srgb_eotf, cicp->from_srgb, NONE, IDENTITY, cicp->oetf)
TRANSFORM(cicp_from_srgb_linear, NONE, cicp->from_srgb, NONE, IDENTITY, cicp->oetf)
TRANSFORM(cicp_from_rec2100_pq, pq_eotf, cicp->from_rec2020, NONE, IDENTITY, cicp->oetf)
TRANSFORM(cicp_from_rec2100_linear, NONE, cicp->from_rec2020, NONE, IDENTITY, cicp->oetf)
#undef cicp
TRANSFORM_PAIR (cicp_to_oklab, cicp_to_srgb_linear, srgb_linear_to_oklab)
TRANSFORM_PAIR (cicp_from_oklab, oklab_to_srgb_linear, cicp_from_srgb_linear)
TRANSFORM_PAIR (cicp_to_oklch, cicp_to_srgb_linear, srgb_linear_to_oklch)
TRANSFORM_PAIR (cicp_from_oklch, oklch_to_srgb_linear, cicp_from_srgb_linear)
/* }}} */
/* {{{ Vfuncs */
@@ -572,13 +751,17 @@ gdk_cicp_color_state_get_convert_to (GdkColorState *self,
switch (GDK_DEFAULT_COLOR_STATE_ID (target))
{
case GDK_COLOR_STATE_ID_SRGB:
return gdk_cicp_to_srgb;
return gdk_convert_cicp_to_srgb;
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
return gdk_cicp_to_srgb_linear;
return gdk_convert_cicp_to_srgb_linear;
case GDK_COLOR_STATE_ID_REC2100_PQ:
return gdk_cicp_to_rec2100_pq;
return gdk_convert_cicp_to_rec2100_pq;
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
return gdk_cicp_to_rec2100_linear;
return gdk_convert_cicp_to_rec2100_linear;
case GDK_COLOR_STATE_ID_OKLAB:
return gdk_convert_cicp_to_oklab;
case GDK_COLOR_STATE_ID_OKLCH:
return gdk_convert_cicp_to_oklch;
case GDK_COLOR_STATE_N_IDS:
default:
@@ -598,13 +781,17 @@ gdk_cicp_color_state_get_convert_from (GdkColorState *self,
switch (GDK_DEFAULT_COLOR_STATE_ID (source))
{
case GDK_COLOR_STATE_ID_SRGB:
return gdk_cicp_from_srgb;
return gdk_convert_cicp_from_srgb;
case GDK_COLOR_STATE_ID_SRGB_LINEAR:
return gdk_cicp_from_srgb_linear;
return gdk_convert_cicp_from_srgb_linear;
case GDK_COLOR_STATE_ID_REC2100_PQ:
return gdk_cicp_from_rec2100_pq;
return gdk_convert_cicp_from_rec2100_pq;
case GDK_COLOR_STATE_ID_REC2100_LINEAR:
return gdk_cicp_from_rec2100_linear;
return gdk_convert_cicp_from_rec2100_linear;
case GDK_COLOR_STATE_ID_OKLAB:
return gdk_convert_cicp_from_oklab;
case GDK_COLOR_STATE_ID_OKLCH:
return gdk_convert_cicp_from_oklch;
case GDK_COLOR_STATE_N_IDS:
default:
+7 -1
View File
@@ -49,6 +49,12 @@ GdkColorState * gdk_color_state_get_rec2100_pq (void);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_rec2100_linear (void);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_oklab (void);
GDK_AVAILABLE_IN_4_16
GdkColorState * gdk_color_state_get_oklch (void);
GDK_AVAILABLE_IN_4_16
gboolean gdk_color_state_equal (GdkColorState *self,
GdkColorState *other);
@@ -57,6 +63,6 @@ GDK_AVAILABLE_IN_4_16
GdkCicpParams *gdk_color_state_create_cicp_params (GdkColorState *self);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkColorState, gdk_color_state_unref);
G_END_DECLS
+5 -1
View File
@@ -13,6 +13,8 @@ typedef enum
GDK_COLOR_STATE_ID_SRGB_LINEAR,
GDK_COLOR_STATE_ID_REC2100_PQ,
GDK_COLOR_STATE_ID_REC2100_LINEAR,
GDK_COLOR_STATE_ID_OKLAB,
GDK_COLOR_STATE_ID_OKLCH,
GDK_COLOR_STATE_N_IDS
} GdkColorStateId;
@@ -73,12 +75,14 @@ extern GdkDefaultColorState gdk_default_color_states[GDK_COLOR_STATE_N_IDS];
#define GDK_COLOR_STATE_SRGB_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_SRGB_LINEAR])
#define GDK_COLOR_STATE_REC2100_PQ ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_PQ])
#define GDK_COLOR_STATE_REC2100_LINEAR ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_REC2100_LINEAR])
#define GDK_COLOR_STATE_OKLAB ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_OKLAB])
#define GDK_COLOR_STATE_OKLCH ((GdkColorState *) &gdk_default_color_states[GDK_COLOR_STATE_ID_OKLCH])
#define GDK_IS_DEFAULT_COLOR_STATE(c) ((GdkDefaultColorState *) (c) >= &gdk_default_color_states[0] && \
(GdkDefaultColorState *) (c) < &gdk_default_color_states[GDK_COLOR_STATE_N_IDS])
#define GDK_DEFAULT_COLOR_STATE_ID(c) ((GdkColorStateId) (((GdkDefaultColorState *) c) - gdk_default_color_states))
const char * gdk_color_state_get_name (GdkColorState *color_state);
const char * gdk_color_state_get_name (GdkColorState *self);
GdkColorState * gdk_color_state_get_no_srgb_tf (GdkColorState *self);
GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp *cicp,
+3 -3
View File
@@ -124,7 +124,7 @@ gdk_content_provider_new_for_value (const GValue *value)
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_VALUE, NULL);
g_value_init (&content->value, G_VALUE_TYPE (value));
g_value_copy (value, &content->value);
return GDK_CONTENT_PROVIDER (content);
}
@@ -409,7 +409,7 @@ gdk_content_provider_union_init (GdkContentProviderUnion *self)
* ```c
* gdk_content_provider_new_union ((GdkContentProvider *[2]) {
* gdk_content_provider_new_typed (G_TYPE_FILE, file),
* gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture)
* gdk_content_provider_new_typed (G_TYPE_TEXTURE, texture)
* }, 2);
* ```
*
@@ -594,7 +594,7 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_BYTES, NULL);
content->mime_type = g_intern_string (mime_type);
content->bytes = g_bytes_ref (bytes);
return GDK_CONTENT_PROVIDER (content);
}
+1 -1
View File
@@ -117,7 +117,7 @@ struct _GdkDeviceClass
};
void _gdk_device_set_associated_device (GdkDevice *device,
GdkDevice *relative);
GdkDevice *associated);
void _gdk_device_reset_axes (GdkDevice *device);
guint _gdk_device_add_axis (GdkDevice *device,
+2 -2
View File
@@ -436,7 +436,7 @@ gdk_display_dispose (GObject *object)
g_queue_clear (&display->queued_events);
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
g_clear_pointer (&display->egl_internal_formats, gdk_dmabuf_formats_unref);
#ifdef GDK_RENDERING_VULKAN
if (display->vk_dmabuf_formats)
{
@@ -2002,7 +2002,7 @@ gdk_display_init_dmabuf (GdkDisplay *self)
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
GDK_DISPLAY_DEBUG (self, DMABUF,
"Initialized support for %zu dmabuf formats",
"Initialization finished. Advertising %zu dmabuf formats",
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
}
+7 -6
View File
@@ -137,7 +137,7 @@ struct _GdkDisplay
/* Cached data the EGL dmabuf downloader */
GdkDmabufFormats *egl_dmabuf_formats;
GdkDmabufFormats *egl_external_formats;
GdkDmabufFormats *egl_internal_formats;
};
struct _GdkDisplayClass
@@ -154,6 +154,7 @@ struct _GdkDisplayClass
void (*beep) (GdkDisplay *display);
void (*sync) (GdkDisplay *display);
void (*flush) (GdkDisplay *display);
gboolean (*has_pending) (GdkDisplay *display);
void (*queue_events) (GdkDisplay *display);
void (*make_default) (GdkDisplay *display);
@@ -239,15 +240,15 @@ GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
GdkSurface *surface,
GError **error);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *self);
gboolean gdk_display_init_egl (GdkDisplay *display,
gboolean gdk_display_init_egl (GdkDisplay *self,
int /*EGLenum*/ platform,
gpointer native_display,
gboolean allow_any,
GError **error);
gpointer gdk_display_get_egl_display (GdkDisplay *display);
gpointer gdk_display_get_egl_config (GdkDisplay *display,
gpointer gdk_display_get_egl_display (GdkDisplay *self);
gpointer gdk_display_get_egl_config (GdkDisplay *self,
GdkMemoryDepth depth);
void gdk_display_set_rgba (GdkDisplay *display,
@@ -288,7 +289,7 @@ void gdk_display_set_double_click_time (GdkDisplay *display,
void gdk_display_set_double_click_distance (GdkDisplay *display,
guint distance);
void gdk_display_set_cursor_theme (GdkDisplay *display,
const char *theme,
const char *name,
int size);
G_END_DECLS
+32 -19
View File
@@ -2068,7 +2068,7 @@ gdk_dmabuf_get_mmap_formats (void)
continue;
GDK_DEBUG (DMABUF,
"mmap dmabuf format %.4s:%#0" G_GINT64_MODIFIER "x",
"mmap advertises dmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
(char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_formats_builder_add_format (builder,
@@ -2082,7 +2082,7 @@ gdk_dmabuf_get_mmap_formats (void)
return formats;
}
static void
static gboolean
gdk_dmabuf_do_download_mmap (GdkTexture *texture,
guchar *data,
gsize stride)
@@ -2093,16 +2093,17 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
gsize sizes[GDK_DMABUF_MAX_PLANES];
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, };
gsize i, j;
gboolean retval = FALSE;
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
if (dmabuf->modifier != DRM_FORMAT_MOD_LINEAR)
return FALSE;
info = get_drm_format_info (dmabuf->fourcc);
g_return_if_fail (info && info->download);
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
"Using mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
gdk_texture_get_width (texture), gdk_texture_get_height (texture),
(char *)&dmabuf->fourcc, dmabuf->modifier);
if (!info || !info->download)
return FALSE;
for (i = 0; i < dmabuf->n_planes; i++)
{
@@ -2139,14 +2140,21 @@ gdk_dmabuf_do_download_mmap (GdkTexture *texture,
needs_unmap[i] = TRUE;
}
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
retval = TRUE;
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
"Used mmap for downloading %dx%d dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
gdk_texture_get_width (texture), gdk_texture_get_height (texture),
(char *)&dmabuf->fourcc, dmabuf->modifier);
out:
for (i = 0; i < dmabuf->n_planes; i++)
@@ -2159,9 +2167,11 @@ out:
if (gdk_dmabuf_ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
}
return retval;
}
void
gboolean
gdk_dmabuf_download_mmap (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
@@ -2170,10 +2180,11 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
{
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
GdkColorState *src_color_state = gdk_texture_get_color_state (texture);
gboolean retval;
if (format == src_format)
{
gdk_dmabuf_do_download_mmap (texture, data, stride);
retval = gdk_dmabuf_do_download_mmap (texture, data, stride);
gdk_memory_convert_color_state (data, stride, format,
src_color_state, color_state,
gdk_texture_get_width (texture),
@@ -2191,7 +2202,7 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
src_stride = width * gdk_memory_format_bytes_per_pixel (src_format);
src_data = g_new (guchar, src_stride * height);
gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
retval = gdk_dmabuf_do_download_mmap (texture, src_data, src_stride);
gdk_memory_convert (data, stride, format, color_state,
src_data, src_stride, src_format, src_color_state,
@@ -2199,6 +2210,8 @@ gdk_dmabuf_download_mmap (GdkTexture *texture,
g_free (src_data);
}
return retval;
}
int
+2 -16
View File
@@ -19,19 +19,6 @@ gdk_dmabuf_downloader_close (GdkDmabufDownloader *self)
}
gboolean
gdk_dmabuf_downloader_supports (GdkDmabufDownloader *self,
GdkDmabufTexture *texture,
GError **error)
{
GdkDmabufDownloaderInterface *iface;
g_return_val_if_fail (GDK_IS_DMABUF_DOWNLOADER (self), FALSE);
iface = GDK_DMABUF_DOWNLOADER_GET_IFACE (self);
return iface->supports (self, texture, error);
}
void
gdk_dmabuf_downloader_download (GdkDmabufDownloader *self,
GdkDmabufTexture *texture,
GdkMemoryFormat format,
@@ -41,9 +28,8 @@ gdk_dmabuf_downloader_download (GdkDmabufDownloader *self,
{
GdkDmabufDownloaderInterface *iface;
g_return_if_fail (GDK_IS_DMABUF_DOWNLOADER (self));
g_return_val_if_fail (GDK_IS_DMABUF_DOWNLOADER (self), FALSE);
iface = GDK_DMABUF_DOWNLOADER_GET_IFACE (self);
iface->download (self, texture, format, color_state, data, stride);
return iface->download (self, texture, format, color_state, data, stride);
}
+3 -9
View File
@@ -14,10 +14,7 @@ struct _GdkDmabufDownloaderInterface
GTypeInterface g_iface;
void (* close) (GdkDmabufDownloader *downloader);
gboolean (* supports) (GdkDmabufDownloader *downloader,
GdkDmabufTexture *texture,
GError **error);
void (* download) (GdkDmabufDownloader *downloader,
gboolean (* download) (GdkDmabufDownloader *downloader,
GdkDmabufTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
@@ -25,11 +22,8 @@ struct _GdkDmabufDownloaderInterface
gsize stride);
};
void gdk_dmabuf_downloader_close (GdkDmabufDownloader *downloader);
gboolean gdk_dmabuf_downloader_supports (GdkDmabufDownloader *downloader,
GdkDmabufTexture *texture,
GError **error);
void gdk_dmabuf_downloader_download (GdkDmabufDownloader *downloader,
void gdk_dmabuf_downloader_close (GdkDmabufDownloader *self);
gboolean gdk_dmabuf_downloader_download (GdkDmabufDownloader *downloader,
GdkDmabufTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
+28 -25
View File
@@ -40,7 +40,7 @@
static gboolean
gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
GdkDmabufFormatsBuilder *formats,
GdkDmabufFormatsBuilder *external)
GdkDmabufFormatsBuilder *internal)
{
GdkGLContext *context = gdk_display_get_gl_context (display);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
@@ -61,8 +61,8 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
eglQueryDmaBufFormatsEXT (egl_display, num_fourccs, fourccs, &num_fourccs);
n_mods = 80;
modifiers = g_new (guint64, n_mods);
external_only = g_new (unsigned int, n_mods);
modifiers = g_new0 (guint64, n_mods);
external_only = g_new0 (unsigned int, n_mods);
for (int i = 0; i < num_fourccs; i++)
{
@@ -94,24 +94,27 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
for (int j = 0; j < num_modifiers; j++)
{
/* All linear formats we support are already added my the mmap downloader.
/* All linear formats we support are already advertised by the mmap downloader.
* We don't add external formats, unless we can use them (via GLES)
*/
if (modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
(!external_only[j] || gdk_gl_context_get_use_es (context)))
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"%s EGL dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
external_only[j] ? "external " : "",
(char *) &fourccs[i],
modifiers[j]);
gboolean advertise = modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
(!external_only[j] || gdk_gl_context_get_use_es (context));
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
GDK_DISPLAY_DEBUG (display, DMABUF,
"EGL %s %sdmabuf format %.4s::%016" G_GINT64_MODIFIER "x",
advertise ? "advertises" : "supports",
external_only[j] ? "external " : "",
(char *) &fourccs[i],
modifiers[j]);
if (advertise)
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
if (!external_only[j])
{
gdk_dmabuf_formats_builder_add_format (internal, fourccs[i], modifiers[j]);
all_external = FALSE;
}
if (external_only[j])
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
else
all_external = FALSE;
}
/* Accept implicit modifiers as long as we accept the format at all.
@@ -123,8 +126,8 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display,
*/
if (!all_external || gdk_gl_context_get_use_es (context))
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], DRM_FORMAT_MOD_INVALID);
if (all_external)
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], DRM_FORMAT_MOD_INVALID);
if (!all_external)
gdk_dmabuf_formats_builder_add_format (internal, fourccs[i], DRM_FORMAT_MOD_INVALID);
}
g_free (modifiers);
@@ -213,7 +216,6 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating EGLImage for dmabuf failed: %#x",
eglGetError ());
return 0;
}
return image;
@@ -229,6 +231,7 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
typedef struct _GskRenderer GskRenderer;
extern GskRenderer * gsk_gl_renderer_new (void);
extern GskRenderer * gsk_ngl_renderer_new (void);
extern gboolean gsk_renderer_realize_for_display (GskRenderer *renderer,
GdkDisplay *display,
GError **error);
@@ -238,7 +241,7 @@ gdk_dmabuf_egl_init (GdkDisplay *display)
{
#if defined (HAVE_DMABUF) && defined (HAVE_EGL)
GdkDmabufFormatsBuilder *formats;
GdkDmabufFormatsBuilder *external;
GdkDmabufFormatsBuilder *internal;
gboolean retval = FALSE;
GError *error = NULL;
GskRenderer *renderer;
@@ -254,16 +257,16 @@ gdk_dmabuf_egl_init (GdkDisplay *display)
}
formats = gdk_dmabuf_formats_builder_new ();
external = gdk_dmabuf_formats_builder_new ();
internal = gdk_dmabuf_formats_builder_new ();
previous = gdk_gl_context_get_current ();
if (previous)
g_object_ref (previous);
retval = gdk_dmabuf_egl_downloader_collect_formats (display, formats, external);
retval = gdk_dmabuf_egl_downloader_collect_formats (display, formats, internal);
display->egl_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (formats);
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
display->egl_internal_formats = gdk_dmabuf_formats_builder_free_to_formats (internal);
if (!retval)
{
@@ -272,7 +275,7 @@ gdk_dmabuf_egl_init (GdkDisplay *display)
return;
}
renderer = gsk_gl_renderer_new ();
renderer = gsk_ngl_renderer_new ();
if (!gsk_renderer_realize_for_display (renderer, display, &error))
{
+1 -1
View File
@@ -55,6 +55,6 @@ GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_formats_equal (const GdkDmabufFormats *formats1,
const GdkDmabufFormats *formats2);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GdkDmabufFormats, gdk_dmabuf_formats_unref);
G_END_DECLS
+1 -1
View File
@@ -27,7 +27,7 @@ void gdk_dmabuf_close_fds (GdkDmabuf
#ifdef HAVE_DMABUF
GdkDmabufFormats * gdk_dmabuf_get_mmap_formats (void) G_GNUC_CONST;
void gdk_dmabuf_download_mmap (GdkTexture *texture,
gboolean gdk_dmabuf_download_mmap (GdkTexture *texture,
GdkMemoryFormat format,
GdkColorState *color_state,
guchar *data,
+49 -41
View File
@@ -50,7 +50,6 @@ struct _GdkDmabufTexture
GdkTexture parent_instance;
GdkDisplay *display;
GdkDmabufDownloader *downloader;
GdkDmabuf dmabuf;
@@ -85,7 +84,6 @@ gdk_dmabuf_texture_dispose (GObject *object)
self->destroy = NULL;
}
g_clear_object (&self->downloader);
g_clear_object (&self->display);
G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object);
@@ -107,16 +105,49 @@ static gboolean
gdk_dmabuf_texture_invoke_callback (gpointer data)
{
Download *download = data;
GdkDisplay *display = download->texture->display;
gdk_dmabuf_downloader_download (download->texture->downloader,
download->texture,
download->format,
download->color_state,
download->data,
download->stride);
if (display->egl_downloader &&
gdk_dmabuf_downloader_download (display->egl_downloader,
download->texture,
download->format,
download->color_state,
download->data,
download->stride))
{
/* Successfully downloaded using EGL */
}
else if (display->vk_downloader &&
gdk_dmabuf_downloader_download (display->vk_downloader,
download->texture,
download->format,
download->color_state,
download->data,
download->stride))
{
/* Successfully downloaded using Vulkan */
}
#ifdef HAVE_DMABUF
else if (gdk_dmabuf_download_mmap (GDK_TEXTURE (download->texture),
download->format,
download->color_state,
download->data,
download->stride))
{
/* Successfully downloaded using mmap */
}
#endif
else
{
const GdkDmabuf *dmabuf = gdk_dmabuf_texture_get_dmabuf (download->texture);
g_critical ("Failed to download %dx%d dmabuf texture (format %.4s:%#" G_GINT64_MODIFIER "x)",
gdk_texture_get_width (GDK_TEXTURE (download->texture)),
gdk_texture_get_height (GDK_TEXTURE (download->texture)),
(char *)&(dmabuf->fourcc), dmabuf->modifier);
}
g_atomic_int_set (&download->spinlock, 1);
return FALSE;
}
@@ -130,14 +161,6 @@ gdk_dmabuf_texture_download (GdkTexture *texture,
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
Download download = { self, format, color_state, data, stride, 0 };
if (self->downloader == NULL)
{
#ifdef HAVE_DMABUF
gdk_dmabuf_download_mmap (texture, format, color_state, data, stride);
#endif
return;
}
g_main_context_invoke (NULL, gdk_dmabuf_texture_invoke_callback, &download);
while (g_atomic_int_get (&download.spinlock) == 0);
@@ -232,37 +255,22 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
: GDK_MEMORY_R8G8B8A8;
}
if (display->egl_downloader)
if (!gdk_dmabuf_formats_contains (display->dmabuf_formats, dmabuf.fourcc, dmabuf.modifier))
{
if (gdk_dmabuf_downloader_supports (display->egl_downloader, self, error))
self->downloader = g_object_ref (display->egl_downloader);
}
if (!self->downloader && display->vk_downloader)
{
g_clear_error (error);
if (gdk_dmabuf_downloader_supports (display->vk_downloader, self, error))
self->downloader = g_object_ref (display->vk_downloader);
}
if (!self->downloader)
{
if (!gdk_dmabuf_formats_contains (gdk_dmabuf_get_mmap_formats (), dmabuf.fourcc, dmabuf.modifier))
{
g_object_unref (self);
return NULL;
}
g_clear_error (error);
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
(char *) &dmabuf.fourcc, dmabuf.modifier);
g_object_unref (self);
return NULL;
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u, downloader %s",
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u",
(char *) &dmabuf.fourcc, dmabuf.modifier,
gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "",
dmabuf.n_planes,
GDK_TEXTURE (self)->format,
self->downloader ? G_OBJECT_TYPE_NAME (self->downloader) : "none");
GDK_TEXTURE (self)->format);
/* Set this only once we know that the texture will be created.
* Otherwise dispose() will run the callback */
+5 -5
View File
@@ -375,7 +375,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
/**
* GdkDmabufTextureBuilder:update-region:
*
* The update region for [property@Gdk.DmabufTextureBuilder:update-texture].
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
*
* Since: 4.14
*/
@@ -496,7 +496,7 @@ gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self)
*
* Sets the width of the texture.
*
* The width must be set before calling [method@Gdk.DmabufTextureBuilder.build].
* The width must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
@@ -540,7 +540,7 @@ gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self)
*
* Sets the height of the texture.
*
* The height must be set before calling [method@Gdk.DmabufTextureBuilder.build].
* The height must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
@@ -588,7 +588,7 @@ gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self)
*
* The format is specified as a fourcc code.
*
* The format must be set before calling [method@Gdk.DmabufTextureBuilder.build].
* The format must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
@@ -807,7 +807,7 @@ gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
*
* Sets the stride for a plane.
*
* The stride must be set for all planes before calling [method@Gdk.DmabufTextureBuilder.build].
* The stride must be set for all planes before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.14
*/
+2 -2
View File
@@ -5,9 +5,9 @@
G_BEGIN_DECLS
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder);
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *self);
void gdk_dmabuf_texture_builder_set_dmabuf (GdkDmabufTextureBuilder *builder,
void gdk_dmabuf_texture_builder_set_dmabuf (GdkDmabufTextureBuilder *self,
const GdkDmabuf *dmabuf);
G_END_DECLS
+2 -2
View File
@@ -511,9 +511,9 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
* Use `GskRenderNode` and `GskRenderer`.
*/
const cairo_region_t *
_gdk_draw_context_get_frame_region (GdkDrawContext *context)
_gdk_draw_context_get_frame_region (GdkDrawContext *self)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (self);
return priv->frame_region;
}
+6 -6
View File
@@ -87,12 +87,12 @@ typedef enum
/**
* GdkModifierType:
* @GDK_SHIFT_MASK: the Shift key.
* @GDK_LOCK_MASK: a Lock key (depending on the Windowing System configuration,
* this may either be <kbd>CapsLock</kbd> or <kbd>ShiftLock</kbd>).
* @GDK_LOCK_MASK: a Lock key (depending on the modifier mapping of the
* X server this may either be CapsLock or ShiftLock).
* @GDK_CONTROL_MASK: the Control key.
* @GDK_ALT_MASK: the fourth modifier key (it depends on the Windowing System
* configuration which key is interpreted as this modifier, but normally it
* is the <kbd>Alt</kbd> key).
* @GDK_ALT_MASK: the fourth modifier key (it depends on the modifier
* mapping of the X server which key is interpreted as this modifier, but
* normally it is the Alt key).
* @GDK_BUTTON1_MASK: the first mouse button.
* @GDK_BUTTON2_MASK: the second mouse button.
* @GDK_BUTTON3_MASK: the third mouse button.
@@ -109,7 +109,7 @@ typedef enum
* Apple, CapsLock or ShiftLock.
*
* Note that GDK may add internal values to events which include values outside
* of this enumeration. Your code should preserve and ignore them. You can use
* of this enumeration. Your code should preserve and ignore them. You can use
* %GDK_MODIFIER_MASK to remove all private values.
*/
typedef enum
-11
View File
@@ -82,7 +82,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
cairo_surface_t *image;
guint framebuffer;
int alpha_size = 0;
int major, minor, version;
gboolean es_use_bgra = FALSE;
paint_context = gdk_surface_get_paint_gl_context (surface, NULL);
@@ -118,16 +117,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
return;
}
gdk_gl_context_get_version (paint_context, &major, &minor);
version = major * 100 + minor;
/* TODO: Use glTexSubImage2D() and do a row-by-row copy to replace
* the GL_UNPACK_ROW_LENGTH support
*/
if (gdk_gl_context_get_use_es (paint_context) &&
!(version >= 300 || gdk_gl_context_has_feature (paint_context, GDK_GL_FEATURE_UNPACK_SUBIMAGE)))
return;
/* TODO: avoid reading back non-required data due to dest clip */
image = cairo_surface_create_similar_image (cairo_get_target (cr),
(alpha_size == 0) ? CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32,
+355 -153
View File
@@ -105,9 +105,6 @@
static const GdkDebugKey gdk_gl_feature_keys[] = {
{ "debug", GDK_GL_FEATURE_DEBUG, "GL_KHR_debug" },
{ "unpack-subimage", GDK_GL_FEATURE_UNPACK_SUBIMAGE, "GL_EXT_unpack_subimage" },
{ "half-float", GDK_GL_FEATURE_VERTEX_HALF_FLOAT, "GL_OES_vertex_half_float" },
{ "sync", GDK_GL_FEATURE_SYNC, "GL_ARB_sync" },
{ "base-instance", GDK_GL_FEATURE_BASE_INSTANCE, "GL_ARB_base_instance" },
{ "buffer-storage", GDK_GL_FEATURE_BUFFER_STORAGE, "GL_EXT_buffer_storage" },
};
@@ -385,6 +382,8 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
if (ctx == EGL_NO_CONTEXT)
return 0;
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
priv->egl_context = ctx;
gdk_gl_context_set_version (context, &supported_versions[j]);
gdk_gl_context_set_is_legacy (context, legacy);
@@ -1058,16 +1057,9 @@ gdk_gl_context_get_matching_version (GdkGLContext *context,
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (api == GDK_GL_API_GL)
{
if (legacy)
min_version = GDK_GL_MIN_GL_LEGACY_VERSION;
else
min_version = GDK_GL_MIN_GL_VERSION;
}
min_version = GDK_GL_MIN_GL_VERSION;
else
{
min_version = GDK_GL_MIN_GLES_VERSION;
}
min_version = GDK_GL_MIN_GLES_VERSION;
if (gdk_gl_version_greater_equal (&priv->required, &min_version))
*out_version = priv->required;
@@ -1590,38 +1582,35 @@ gdk_gl_context_init_memory_flags (GdkGLContext *self)
priv->memory_flags[GDK_MEMORY_G8A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
#endif
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
/* GLES 3.0.6 spec, table 3.13 */
priv->memory_flags[GDK_MEMORY_G8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= GDK_GL_FORMAT_USABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
/* no changes in GLES 3.1 spec, table 8.13 */
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
{
/* GLES 3.0.6 spec, table 3.13 */
priv->memory_flags[GDK_MEMORY_G8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= GDK_GL_FORMAT_USABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
/* no changes in GLES 3.1 spec, table 8.13 */
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
{
/* GLES 3.2 spec, table 8.10 */
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
}
/* GLES 3.2 spec, table 8.10 */
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_RENDERABLE;
}
if (epoxy_has_gl_extension ("GL_OES_rgb8_rgba8"))
@@ -1629,64 +1618,55 @@ gdk_gl_context_init_memory_flags (GdkGLContext *self)
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
}
if (epoxy_has_gl_extension ("GL_EXT_abgr"))
{
priv->memory_flags[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
priv->memory_flags[GDK_MEMORY_X8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_X8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
}
if (epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888"))
{
priv->memory_flags[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_B8G8R8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
priv->memory_flags[GDK_MEMORY_B8G8R8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_B8G8R8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
}
/* Technically, those extensions are supported on GLES2.
* However, GTK uses the wrong format/type pairs with them, so we don't enable them.
*/
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
if (epoxy_has_gl_extension ("GL_EXT_texture_norm16"))
{
if (epoxy_has_gl_extension ("GL_EXT_texture_norm16"))
{
priv->memory_flags[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
}
if (epoxy_has_gl_extension ("GL_OES_texture_half_float"))
{
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_half_float"))
flags |= GDK_GL_FORMAT_RENDERABLE;
if (epoxy_has_gl_extension ("GL_OES_texture_half_float_linear"))
flags |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= flags;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= flags;
/* disabled for now, see https://gitlab.freedesktop.org/mesa/mesa/-/issues/10378 */
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= flags;
}
if (epoxy_has_gl_extension ("GL_OES_texture_float"))
{
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_float"))
flags |= GDK_GL_FORMAT_RENDERABLE;
if (epoxy_has_gl_extension ("GL_OES_texture_float_linear"))
flags |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= flags;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= flags;
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= flags;
}
priv->memory_flags[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
}
if (epoxy_has_gl_extension ("GL_OES_texture_half_float"))
{
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_half_float"))
flags |= GDK_GL_FORMAT_RENDERABLE;
if (epoxy_has_gl_extension ("GL_OES_texture_half_float_linear"))
flags |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= flags;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= flags;
/* disabled for now, see https://gitlab.freedesktop.org/mesa/mesa/-/issues/10378 */
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= flags;
}
if (epoxy_has_gl_extension ("GL_OES_texture_float"))
{
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_float"))
flags |= GDK_GL_FORMAT_RENDERABLE;
if (epoxy_has_gl_extension ("GL_OES_texture_float_linear"))
flags |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= flags;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= flags;
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= flags & ~GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= flags;
}
}
@@ -1701,32 +1681,11 @@ gdk_gl_version_init_epoxy (GdkGLVersion *version)
static GdkGLFeatures
gdk_gl_context_check_features (GdkGLContext *context)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
GdkGLFeatures features = 0;
if (gdk_gl_context_get_use_es (context))
{
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)) ||
epoxy_has_gl_extension ("GL_EXT_unpack_subimage"))
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE;
}
else
{
features |= GDK_GL_FEATURE_UNPACK_SUBIMAGE;
}
if (epoxy_has_gl_extension ("GL_KHR_debug"))
features |= GDK_GL_FEATURE_DEBUG;
if (gdk_gl_context_check_version (context, "3.0", "3.0") ||
epoxy_has_gl_extension ("GL_OES_vertex_half_float"))
features |= GDK_GL_FEATURE_VERTEX_HALF_FLOAT;
if (gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GL_APPLE_sync"))
features |= GDK_GL_FEATURE_SYNC;
if (gdk_gl_context_check_version (context, "4.2", "9.9") ||
epoxy_has_gl_extension ("GL_EXT_base_instance") ||
epoxy_has_gl_extension ("GL_ARB_base_instance"))
@@ -1793,20 +1752,22 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
{
int i, max_texture_size;
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
gdk_debug_message ("%s version: %d.%d (%s)",
gdk_debug_message ("%s version: %d.%d (%s)\n"
"* GLSL version: %s\n"
"* Max texture size: %d\n",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
priv->is_legacy ? "legacy" : "core");
gdk_debug_message ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
gdk_debug_message ("Max texture size: %d", max_texture_size);
priv->is_legacy ? "legacy" : "core",
glGetString (GL_SHADING_LANGUAGE_VERSION),
max_texture_size);
gdk_debug_message ("Enabled features (use GDK_GL_DISABLE env var to disable):");
for (i = 0; i < G_N_ELEMENTS (gdk_gl_feature_keys); i++)
{
gdk_debug_message (" %s: %s",
gdk_gl_feature_keys[i].key,
(priv->features & gdk_gl_feature_keys[i].value) ? "" :
(priv->features & gdk_gl_feature_keys[i].value) ? "YES" :
((disabled_features & gdk_gl_feature_keys[i].value) ? "disabled via env var" :
(((supported_features & gdk_gl_feature_keys[i].value) == 0) ? "" :
(((supported_features & gdk_gl_feature_keys[i].value) == 0) ? "not supported" :
"Hum, what? This should not happen.")));
}
}
@@ -2258,59 +2219,26 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
gdk_dmabuf_egl_init (display);
if (gdk_dmabuf_formats_contains (display->egl_dmabuf_formats, dmabuf->fourcc, dmabuf->modifier))
if (gdk_dmabuf_formats_contains (display->egl_internal_formats, dmabuf->fourcc, dmabuf->modifier))
{
/* This is the path for modern drivers that support modifiers */
if (!gdk_dmabuf_formats_contains (display->egl_external_formats, dmabuf->fourcc, dmabuf->modifier))
{
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
GL_TEXTURE_2D);
if (texture_id == 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Import of %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
width, height,
(char *) &dmabuf->fourcc, dmabuf->modifier);
return 0;
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_2D texture",
width, height,
(char *) &dmabuf->fourcc, dmabuf->modifier);
*external = FALSE;
return texture_id;
}
if (!gdk_gl_context_get_use_es (self))
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't import external_only %.4s:%#" G_GINT64_MODIFIER "x outside of GLES",
(char *) &dmabuf->fourcc, dmabuf->modifier);
return 0;
}
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
width, height,
dmabuf,
GL_TEXTURE_EXTERNAL_OES);
GL_TEXTURE_2D);
if (texture_id == 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Import of external_only %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
"Import of %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
width, height,
(char *) &dmabuf->fourcc, dmabuf->modifier);
return 0;
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_EXTERNAL_OES texture",
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_2D texture",
width, height,
(char *) &dmabuf->fourcc, dmabuf->modifier);
*external = TRUE;
*external = FALSE;
return texture_id;
}
else
@@ -2467,3 +2395,277 @@ out:
return FALSE;
#endif
}
static gboolean
gdk_gl_context_find_format (GdkGLContext *self,
GdkMemoryAlpha alpha,
GLint gl_format,
GLint gl_type,
GdkMemoryFormat *out_format)
{
GdkMemoryFormat format;
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
{
GLint q_internal_format, q_internal_srgb_format;
GLenum q_format, q_type;
GLint q_swizzle[4];
if (gdk_memory_format_alpha (format) != alpha)
continue;
if (!(gdk_gl_context_get_format_flags (self, format) & GDK_GL_FORMAT_RENDERABLE))
continue;
gdk_memory_format_gl_format (format,
gdk_gl_context_get_use_es (self),
&q_internal_format,
&q_internal_srgb_format,
&q_format,
&q_type,
q_swizzle);
if (q_format != gl_format || q_type != gl_type)
continue;
*out_format = format;
return TRUE;
}
return FALSE;
}
void
gdk_gl_context_download (GdkGLContext *self,
GLuint tex_id,
GdkMemoryFormat tex_format,
GdkColorState *tex_color_state,
guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
GdkColorState *dest_color_state,
gsize width,
gsize height)
{
gsize expected_stride;
GLint gl_internal_format, gl_internal_srgb_format;
GLenum gl_format, gl_type;
GLint gl_swizzle[4];
expected_stride = width * gdk_memory_format_bytes_per_pixel (dest_format);
if (!gdk_gl_context_get_use_es (self) &&
((gdk_gl_context_get_format_flags (self, tex_format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
{
gdk_memory_format_gl_format (tex_format,
gdk_gl_context_get_use_es (self),
&gl_internal_format, &gl_internal_srgb_format,
&gl_format, &gl_type, gl_swizzle);
if (dest_stride == expected_stride &&
dest_format == tex_format)
{
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
dest_data);
gdk_memory_convert_color_state (dest_data,
dest_stride,
dest_format,
dest_color_state,
tex_color_state,
width,
height);
}
else
{
gsize stride = width * gdk_memory_format_bytes_per_pixel (tex_format);
guchar *pixels = g_malloc_n (stride, height);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
pixels);
gdk_memory_convert (dest_data,
dest_stride,
dest_format,
dest_color_state,
pixels,
stride,
tex_format,
tex_color_state,
width,
height);
g_free (pixels);
}
}
else
{
GdkMemoryFormat actual_format;
GLenum gl_read_format, gl_read_type;
GLuint fbo;
glGenFramebuffers (1, &fbo);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0);
if (gdk_gl_context_check_version (self, "4.3", "3.1"))
{
GLint read_format, read_type;
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
if (gdk_gl_context_find_format (self, gdk_memory_format_alpha (tex_format), read_format, read_type, &actual_format))
{
gl_read_format = read_format;
gl_read_type = read_type;
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (tex_format, FALSE));
if (gdk_memory_format_alpha (tex_format) == GDK_MEMORY_ALPHA_STRAIGHT)
actual_format = gdk_memory_format_get_straight (actual_format);
gdk_memory_format_gl_format (actual_format,
gdk_gl_context_get_use_es (self),
&gl_internal_format, &gl_internal_srgb_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (tex_format, FALSE));
if (gdk_memory_format_alpha (tex_format) == GDK_MEMORY_ALPHA_STRAIGHT)
actual_format = gdk_memory_format_get_straight (actual_format);
gdk_memory_format_gl_format (actual_format,
gdk_gl_context_get_use_es (self),
&gl_internal_format, &gl_internal_srgb_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
if (dest_format == actual_format &&
(dest_stride == expected_stride))
{
glReadPixels (0, 0,
width, height,
gl_read_format,
gl_read_type,
dest_data);
gdk_memory_convert_color_state (dest_data,
dest_stride,
dest_format,
dest_color_state,
tex_color_state,
width,
height);
}
else
{
gsize actual_bpp = gdk_memory_format_bytes_per_pixel (actual_format);
gsize stride = actual_bpp * width;
guchar *pixels = g_malloc_n (stride, height);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glReadPixels (0, 0,
width, height,
gl_read_format,
gl_read_type,
pixels);
/* Fix up gles inadequacies */
if (gl_read_format == GL_RGBA &&
gl_read_type == GL_UNSIGNED_BYTE &&
(tex_format == GDK_MEMORY_G8A8 ||
tex_format == GDK_MEMORY_G8A8_PREMULTIPLIED ||
tex_format == GDK_MEMORY_G8 ||
tex_format == GDK_MEMORY_A8))
{
for (unsigned int y = 0; y < height; y++)
{
for (unsigned int x = 0; x < width; x++)
{
guchar *data = &pixels[y * stride + x * actual_bpp];
if (tex_format == GDK_MEMORY_G8A8 ||
tex_format == GDK_MEMORY_G8A8_PREMULTIPLIED)
{
data[3] = data[1];
data[1] = data[0];
data[2] = data[0];
}
else if (tex_format == GDK_MEMORY_G8)
{
data[1] = data[0];
data[2] = data[0];
data[3] = 0xff;
}
else if (tex_format == GDK_MEMORY_A8)
{
data[3] = data[0];
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
}
}
}
if (gl_read_format == GL_RGBA &&
gl_read_type == GL_UNSIGNED_SHORT &&
(tex_format == GDK_MEMORY_G16A16 ||
tex_format == GDK_MEMORY_G16A16_PREMULTIPLIED ||
tex_format == GDK_MEMORY_G16 ||
tex_format == GDK_MEMORY_A16))
{
for (unsigned int y = 0; y < height; y++)
{
for (unsigned int x = 0; x < width; x++)
{
guint16 *data = (guint16 *) &pixels[y * stride + x * actual_bpp];
if (tex_format == GDK_MEMORY_G16A16 ||
tex_format == GDK_MEMORY_G16A16_PREMULTIPLIED)
{
data[3] = data[1];
data[1] = data[0];
data[2] = data[0];
}
else if (tex_format == GDK_MEMORY_G16)
{
data[1] = data[0];
data[2] = data[0];
data[3] = 0xffff;
}
else if (tex_format == GDK_MEMORY_A16)
{
data[3] = data[0];
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
}
}
}
gdk_memory_convert (dest_data,
dest_stride,
dest_format,
dest_color_state,
pixels,
stride,
actual_format,
tex_color_state,
width,
height);
g_free (pixels);
}
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glDeleteFramebuffers (1, &fbo);
}
}
+16 -8
View File
@@ -29,11 +29,8 @@ G_BEGIN_DECLS
typedef enum {
GDK_GL_FEATURE_DEBUG = 1 << 0,
GDK_GL_FEATURE_UNPACK_SUBIMAGE = 1 << 1,
GDK_GL_FEATURE_VERTEX_HALF_FLOAT = 1 << 2,
GDK_GL_FEATURE_SYNC = 1 << 3,
GDK_GL_FEATURE_BASE_INSTANCE = 1 << 4,
GDK_GL_FEATURE_BUFFER_STORAGE = 1 << 5,
GDK_GL_FEATURE_BASE_INSTANCE = 1 << 1,
GDK_GL_FEATURE_BUFFER_STORAGE = 1 << 2,
} GdkGLFeatures;
typedef enum {
@@ -133,16 +130,16 @@ void gdk_gl_context_set_version (GdkGLContext
const GdkGLVersion *version);
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy);
gboolean gdk_gl_context_check_gl_version (GdkGLContext *context,
gboolean gdk_gl_context_check_gl_version (GdkGLContext *self,
const GdkGLVersion *gl_version,
const GdkGLVersion *gles_version);
static inline gboolean
gdk_gl_context_check_version (GdkGLContext *context,
gdk_gl_context_check_version (GdkGLContext *self,
const char *gl_version,
const char *gles_version)
{
return gdk_gl_context_check_gl_version (context,
return gdk_gl_context_check_gl_version (self,
gl_version ? &GDK_GL_VERSION_STRING (gl_version) : NULL,
gles_version ? &GDK_GL_VERSION_STRING (gles_version) : NULL);
}
@@ -181,6 +178,17 @@ gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext
double gdk_gl_context_get_scale (GdkGLContext *self);
void gdk_gl_context_download (GdkGLContext *self,
GLuint tex_id,
GdkMemoryFormat tex_format,
GdkColorState *tex_color_state,
guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
GdkColorState *dest_color_state,
gsize width,
gsize height);
guint gdk_gl_context_import_dmabuf (GdkGLContext *self,
int width,
int height,
+13 -264
View File
@@ -151,276 +151,26 @@ struct _Download
gsize stride;
};
static gboolean
gdk_gl_texture_find_format (GdkGLContext *context,
GdkMemoryAlpha alpha,
GLint gl_format,
GLint gl_type,
GdkMemoryFormat *out_format)
{
GdkMemoryFormat format;
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
{
GLint q_internal_format, q_internal_srgb_format;
GLenum q_format, q_type;
GLint q_swizzle[4];
if (gdk_memory_format_alpha (format) != alpha)
continue;
if (!(gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_RENDERABLE))
continue;
gdk_memory_format_gl_format (format,
gdk_gl_context_get_use_es (context),
&q_internal_format,
&q_internal_srgb_format,
&q_format,
&q_type,
q_swizzle);
if (q_format != gl_format || q_type != gl_type)
continue;
*out_format = format;
return TRUE;
}
return FALSE;
}
static inline void
static void
gdk_gl_texture_do_download (GdkGLTexture *self,
GdkGLContext *context,
gpointer download_)
{
GdkTexture *texture = GDK_TEXTURE (self);
GdkMemoryFormat format;
gsize expected_stride;
Download *download = download_;
GLint gl_internal_format, gl_internal_srgb_format;
GLenum gl_format, gl_type;
GLint gl_swizzle[4];
format = gdk_texture_get_format (texture),
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
if (!gdk_gl_context_get_use_es (context) &&
((gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
{
gdk_memory_format_gl_format (format,
gdk_gl_context_get_use_es (context),
&gl_internal_format, &gl_internal_srgb_format,
&gl_format, &gl_type, gl_swizzle);
if (download->stride == expected_stride &&
download->format == format)
{
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
download->data);
gdk_memory_convert_color_state (download->data,
download->stride,
download->format,
download->color_state,
texture->color_state,
texture->width,
texture->height);
}
else
{
gsize stride = texture->width * gdk_memory_format_bytes_per_pixel (format);
guchar *pixels = g_malloc_n (stride, texture->height);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glGetTexImage (GL_TEXTURE_2D,
0,
gl_format,
gl_type,
pixels);
gdk_memory_convert (download->data,
download->stride,
download->format,
download->color_state,
pixels,
stride,
format,
texture->color_state,
texture->width,
texture->height);
g_free (pixels);
}
}
else
{
GdkMemoryFormat actual_format;
GLenum gl_read_format, gl_read_type;
GLuint fbo;
glGenFramebuffers (1, &fbo);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
{
GLint read_format, read_type;
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
if (gdk_gl_texture_find_format (context, gdk_memory_format_alpha (format), read_format, read_type, &actual_format))
{
gl_read_format = read_format;
gl_read_type = read_type;
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format, FALSE));
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
actual_format = gdk_memory_format_get_straight (actual_format);
gdk_memory_format_gl_format (actual_format,
gdk_gl_context_get_use_es (context),
&gl_internal_format, &gl_internal_srgb_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format, FALSE));
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
actual_format = gdk_memory_format_get_straight (actual_format);
gdk_memory_format_gl_format (actual_format,
gdk_gl_context_get_use_es (context),
&gl_internal_format, &gl_internal_srgb_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
if (download->format == actual_format &&
(download->stride == expected_stride))
{
glReadPixels (0, 0,
texture->width, texture->height,
gl_read_format,
gl_read_type,
download->data);
gdk_memory_convert_color_state (download->data,
download->stride,
download->format,
download->color_state,
texture->color_state,
texture->width,
texture->height);
}
else
{
gsize actual_bpp = gdk_memory_format_bytes_per_pixel (actual_format);
gsize stride = actual_bpp * texture->width;
guchar *pixels = g_malloc_n (stride, texture->height);
glPixelStorei (GL_PACK_ALIGNMENT, 1);
glReadPixels (0, 0,
texture->width, texture->height,
gl_read_format,
gl_read_type,
pixels);
/* Fix up gles inadequacies */
if (gl_read_format == GL_RGBA &&
gl_read_type == GL_UNSIGNED_BYTE &&
(format == GDK_MEMORY_G8A8 ||
format == GDK_MEMORY_G8A8_PREMULTIPLIED ||
format == GDK_MEMORY_G8 ||
format == GDK_MEMORY_A8))
{
for (unsigned int y = 0; y < texture->height; y++)
{
for (unsigned int x = 0; x < texture->width; x++)
{
guchar *data = &pixels[y * stride + x * actual_bpp];
if (format == GDK_MEMORY_G8A8 ||
format == GDK_MEMORY_G8A8_PREMULTIPLIED)
{
data[3] = data[1];
data[1] = data[0];
data[2] = data[0];
}
else if (format == GDK_MEMORY_G8)
{
data[1] = data[0];
data[2] = data[0];
data[3] = 0xff;
}
else if (format == GDK_MEMORY_A8)
{
data[3] = data[0];
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
}
}
}
if (gl_read_format == GL_RGBA &&
gl_read_type == GL_UNSIGNED_SHORT &&
(format == GDK_MEMORY_G16A16 ||
format == GDK_MEMORY_G16A16_PREMULTIPLIED ||
format == GDK_MEMORY_G16 ||
format == GDK_MEMORY_A16))
{
for (unsigned int y = 0; y < texture->height; y++)
{
for (unsigned int x = 0; x < texture->width; x++)
{
guint16 *data = (guint16 *) &pixels[y * stride + x * actual_bpp];
if (format == GDK_MEMORY_G16A16 ||
format == GDK_MEMORY_G16A16_PREMULTIPLIED)
{
data[3] = data[1];
data[1] = data[0];
data[2] = data[0];
}
else if (format == GDK_MEMORY_G16)
{
data[1] = data[0];
data[2] = data[0];
data[3] = 0xffff;
}
else if (format == GDK_MEMORY_A16)
{
data[3] = data[0];
data[0] = 0;
data[1] = 0;
data[2] = 0;
}
}
}
}
gdk_memory_convert (download->data,
download->stride,
download->format,
download->color_state,
pixels,
stride,
actual_format,
texture->color_state,
texture->width,
texture->height);
g_free (pixels);
}
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glDeleteFramebuffers (1, &fbo);
}
gdk_gl_context_download (context,
gdk_gl_texture_get_id (self),
gdk_texture_get_format (texture),
gdk_texture_get_color_state (texture),
download->data,
download->stride,
download->format,
download->color_state,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
static void
gdk_gl_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
@@ -527,8 +277,7 @@ gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
self->id = gdk_gl_texture_builder_get_id (builder);
GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder);
self->has_mipmap = gdk_gl_texture_builder_get_has_mipmap (builder);
if (gdk_gl_context_has_feature (self->context, GDK_GL_FEATURE_SYNC))
self->sync = gdk_gl_texture_builder_get_sync (builder);
self->sync = gdk_gl_texture_builder_get_sync (builder);
self->destroy = destroy;
self->data = data;
+2 -10
View File
@@ -33,13 +33,9 @@ G_BEGIN_DECLS
/* Minimum OpenGL versions supported by GTK.
* Backends should make sure to never create a context of a previous version.
*
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
* OPENGL_PROFILE_MASK; and OpenGL ES respectively
*/
#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 2)
#define GDK_GL_MIN_GL_LEGACY_VERSION GDK_GL_VERSION_INIT (3, 0)
#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (2, 0)
#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 3)
#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (3, 0)
typedef struct _GdkGLVersion GdkGLVersion;
@@ -60,9 +56,6 @@ static const GdkGLVersion supported_gl_versions[] = {
GDK_GL_VERSION_INIT (4, 1),
GDK_GL_VERSION_INIT (4, 0),
GDK_GL_VERSION_INIT (3, 3),
GDK_GL_VERSION_INIT (3, 2),
GDK_GL_VERSION_INIT (3, 1),
GDK_GL_VERSION_INIT (3, 0),
GDK_GL_VERSION_INIT (0, 0)
};
@@ -71,7 +64,6 @@ static const GdkGLVersion supported_gles_versions[] = {
GDK_GL_VERSION_INIT (3, 2),
GDK_GL_VERSION_INIT (3, 1),
GDK_GL_VERSION_INIT (3, 0),
GDK_GL_VERSION_INIT (2, 0),
GDK_GL_VERSION_INIT (0, 0)
};
+9 -9
View File
@@ -2479,8 +2479,8 @@ void
gdk_memory_convert_color_state (guchar *data,
gsize stride,
GdkMemoryFormat format,
GdkColorState *src_cs,
GdkColorState *dest_cs,
GdkColorState *src_color_state,
GdkColorState *dest_color_state,
gsize width,
gsize height)
{
@@ -2488,24 +2488,24 @@ gdk_memory_convert_color_state (guchar *data,
.data = data,
.stride = stride,
.format = format,
.src_cs = src_cs,
.dest_cs = dest_cs,
.src_cs = src_color_state,
.dest_cs = dest_color_state,
.width = width,
.height = height,
};
if (gdk_color_state_equal (src_cs, dest_cs))
if (gdk_color_state_equal (src_color_state, dest_color_state))
return;
if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
src_cs == GDK_COLOR_STATE_SRGB &&
dest_cs == GDK_COLOR_STATE_SRGB_LINEAR)
src_color_state == GDK_COLOR_STATE_SRGB &&
dest_color_state == GDK_COLOR_STATE_SRGB_LINEAR)
{
gdk_parallel_task_run (gdk_memory_convert_color_state_srgb_to_srgb_linear, &mc);
}
else if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
src_cs == GDK_COLOR_STATE_SRGB_LINEAR &&
dest_cs == GDK_COLOR_STATE_SRGB)
src_color_state == GDK_COLOR_STATE_SRGB_LINEAR &&
dest_color_state == GDK_COLOR_STATE_SRGB)
{
gdk_parallel_task_run (gdk_memory_convert_color_state_srgb_linear_to_srgb, &mc);
}
+2 -2
View File
@@ -96,11 +96,11 @@ const char * gdk_memory_format_get_name (GdkMemoryFormat
void gdk_memory_convert (guchar *dest_data,
gsize dest_stride,
GdkMemoryFormat dest_format,
GdkColorState *src_cs,
GdkColorState *dest_cs,
const guchar *src_data,
gsize src_stride,
GdkMemoryFormat src_format,
GdkColorState *dest_cs,
GdkColorState *src_cs,
gsize width,
gsize height);
void gdk_memory_convert_color_state (guchar *data,
+21 -104
View File
@@ -35,7 +35,7 @@
#include <math.h>
#ifdef GDK_RENDERING_VULKAN
static const GdkDebugKey gdk_vulkan_feature_keys[] = {
static const GdkDebugKey gsk_vulkan_feature_keys[] = {
{ "dmabuf", GDK_VULKAN_FEATURE_DMABUF, "Never import Dmabufs" },
{ "ycbcr", GDK_VULKAN_FEATURE_YCBCR, "Do not support Ycbcr textures (also disables dmabufs)" },
{ "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" },
@@ -419,10 +419,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
VkDevice device;
guint i;
GDK_DEBUG (VULKAN, "(Re)creating the swapchain for surface of size %dx%d",
gdk_surface_get_width (surface),
gdk_surface_get_height (surface));
device = gdk_vulkan_context_get_device (context);
/*
@@ -460,10 +456,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
GDK_DEBUG (VULKAN, "Using surface present mode %s",
surface_present_mode_to_string (present_mode));
GDK_DEBUG (VULKAN, "Using extent %dx%d",
capabilities.currentExtent.width,
capabilities.currentExtent.height);
/*
* Per https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkSurfaceCapabilitiesKHR
@@ -476,10 +468,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
capabilities.currentExtent.width = MAX (1, (int) ceil (gdk_surface_get_width (surface) * scale));
capabilities.currentExtent.height = MAX (1, (int) ceil (gdk_surface_get_height (surface) * scale));
GDK_DEBUG (VULKAN, "Effective extent %dx%d",
capabilities.currentExtent.width,
capabilities.currentExtent.height);
}
res = GDK_VK_CHECK (vkCreateSwapchainKHR, device,
@@ -566,20 +554,12 @@ physical_device_supports_extension (VkPhysicalDevice device,
{
VkExtensionProperties *extensions;
uint32_t n_device_extensions;
static gboolean first = TRUE;
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, NULL);
extensions = g_newa (VkExtensionProperties, n_device_extensions);
GDK_VK_CHECK (vkEnumerateDeviceExtensionProperties, device, NULL, &n_device_extensions, extensions);
if (first)
{
first = FALSE;
for (uint32_t i = 0; i < n_device_extensions; i++)
g_print ("%s\n", extensions[i].extensionName);
}
for (uint32_t i = 0; i < n_device_extensions; i++)
{
if (g_str_equal (extensions[i].extensionName, extension_name))
@@ -706,37 +686,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
{
GError *error = NULL;
if (acquire_result == VK_SUBOPTIMAL_KHR)
{
const VkPipelineStageFlags mask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
vkQueueSubmit (gdk_vulkan_context_get_queue (context),
1,
&(VkSubmitInfo) {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &priv->draw_semaphore,
.pWaitDstStageMask = &mask,
},
VK_NULL_HANDLE);
vkQueueWaitIdle (gdk_vulkan_context_get_queue (context));
if (gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE))
{
PFN_vkReleaseSwapchainImagesEXT vkReleaseSwapchainImagesEXT;
vkReleaseSwapchainImagesEXT = (PFN_vkReleaseSwapchainImagesEXT) vkGetDeviceProcAddr (gdk_vulkan_context_get_device (context), "vkReleaseSwapchainImagesEXT");
vkReleaseSwapchainImagesEXT (gdk_vulkan_context_get_device (context),
&(VkReleaseSwapchainImagesInfoEXT) {
.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
.pNext = NULL,
.swapchain = priv->swapchain,
.imageIndexCount = 1,
.pImageIndices = &priv->draw_index,
});
}
}
GDK_DEBUG (VULKAN, "Recreating the swapchain");
if (gdk_vulkan_context_check_swapchain (context, &error))
continue;
@@ -1455,9 +1405,6 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
{
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
uint32_t i, j, k;
const char *override;
gboolean list_devices;
int first, last;
GdkVulkanFeatures skip_features;
uint32_t n_devices = 0;
@@ -1475,45 +1422,14 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
devices = g_newa (VkPhysicalDevice, n_devices);
GDK_VK_CHECK(vkEnumeratePhysicalDevices, display->vk_instance, &n_devices, devices);
first = 0;
last = n_devices;
skip_features = gdk_parse_debug_var ("GDK_VULKAN_DISABLE",
"GDK_VULKAN_DISABLE can be set to a list of Vulkan features to disable.\n",
gdk_vulkan_feature_keys,
G_N_ELEMENTS (gdk_vulkan_feature_keys));
gsk_vulkan_feature_keys,
G_N_ELEMENTS (gsk_vulkan_feature_keys));
if (skip_features & GDK_VULKAN_FEATURE_YCBCR)
skip_features |= GDK_VULKAN_FEATURE_DMABUF;
override = g_getenv ("GDK_VULKAN_DEVICE");
list_devices = FALSE;
if (override)
{
if (g_strcmp0 (override, "list") == 0)
list_devices = TRUE;
else
{
gint64 device_idx;
GError *error2 = NULL;
if (!g_ascii_string_to_signed (override, 10, 0, G_MAXINT, &device_idx, &error2))
{
g_warning ("Failed to parse %s: %s", "GDK_VULKAN_DEVICE", error2->message);
g_error_free (error2);
device_idx = -1;
}
if (device_idx < 0 || device_idx >= n_devices)
g_warning ("%s value out of range, ignoring", "GDK_VULKAN_DEVICE");
else
{
first = device_idx;
last = first + 1;
}
}
}
if (list_devices || GDK_DISPLAY_DEBUG_CHECK (display, VULKAN))
if (GDK_DISPLAY_DEBUG_CHECK (display, VULKAN))
{
for (i = 0; i < n_devices; i++)
{
@@ -1564,7 +1480,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
}
}
for (i = first; i < last; i++)
for (i = 0; i < n_devices; i++)
{
GdkVulkanFeatures features, device_features;
uint32_t n_queue_props;
@@ -1580,7 +1496,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
{
if (queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = {
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT,
.swapchainMaintenance1 = VK_TRUE,
};
@@ -1656,13 +1572,13 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
display->vulkan_features = features;
GDK_DISPLAY_DEBUG (display, VULKAN, "Enabled features (use GDK_VULKAN_DISABLE env var to disable):");
for (i = 0; i < G_N_ELEMENTS (gdk_vulkan_feature_keys); i++)
for (i = 0; i < G_N_ELEMENTS (gsk_vulkan_feature_keys); i++)
{
GDK_DISPLAY_DEBUG (display, VULKAN, " %s: %s",
gdk_vulkan_feature_keys[i].key,
(features & gdk_vulkan_feature_keys[i].value) ? "" :
((skip_features & gdk_vulkan_feature_keys[i].value) ? "disabled via env var" :
(((device_features & gdk_vulkan_feature_keys[i].value) == 0) ? "" :
gsk_vulkan_feature_keys[i].key,
(features & gsk_vulkan_feature_keys[i].value) ? "YES" :
((skip_features & gsk_vulkan_feature_keys[i].value) ? "disabled via env var" :
(((device_features & gsk_vulkan_feature_keys[i].value) == 0) ? "not supported" :
"Hum, what? This should not happen.")));
}
@@ -1995,19 +1911,20 @@ gdk_vulkan_init_dmabuf (GdkDisplay *display)
g_warn_if_fail (modifier_props.drmFormatModifierCount < sizeof (modifier_list));
for (j = 0; j < modifier_props.drmFormatModifierCount; j++)
{
gboolean advertise = modifier_list[j].drmFormatModifier != DRM_FORMAT_MOD_LINEAR;
GDK_DISPLAY_DEBUG (display, DMABUF,
"Vulkan supports dmabuf format %.4s::%016llx with %u planes and features 0x%x",
"Vulkan %s dmabuf format %.4s::%016"G_GINT64_MODIFIER"x with %u planes and features 0x%x",
advertise ? "advertises" : "supports",
(char *) &fourcc,
(long long unsigned) modifier_list[j].drmFormatModifier,
modifier_list[j].drmFormatModifier,
modifier_list[j].drmFormatModifierPlaneCount,
modifier_list[j].drmFormatModifierTilingFeatures);
if (modifier_list[j].drmFormatModifier == DRM_FORMAT_MOD_LINEAR)
continue;
gdk_dmabuf_formats_builder_add_format (vulkan_builder,
fourcc,
modifier_list[j].drmFormatModifier);
if (advertise)
gdk_dmabuf_formats_builder_add_format (vulkan_builder,
fourcc,
modifier_list[j].drmFormatModifier);
}
}
+2 -2
View File
@@ -63,8 +63,8 @@ print ";\n\n";
print <<EOT;
typedef struct {
guint keyval;
guint offset;
unsigned int keyval;
unsigned int offset;
} gdk_key;
static const gdk_key gdk_keys_by_keyval[] = {
-10
View File
@@ -42,12 +42,6 @@
#define siglongjmp longjmp
#endif
#define JPEG_MEM_DEST_USES_SIZE_T \
(!(LIBJPEG_TURBO_VERSION_NUMBER) && \
(((JPEG_LIB_VERSION) > 90) || \
((JPEG_LIB_VERSION) == 90 && (JPEG_LIB_VERSION_MAJOR) > 9) || \
((JPEG_LIB_VERSION) == 90 && (JPEG_LIB_VERSION_MAJOR) == 9 && (JPEG_LIB_VERSION_MINOR) > 3)))
struct error_handler_data {
struct jpeg_error_mgr pub;
sigjmp_buf setjmp_buffer;
@@ -237,11 +231,7 @@ gdk_save_jpeg (GdkTexture *texture)
struct error_handler_data jerr;
struct jpeg_error_mgr err;
guchar *data = NULL;
#if JPEG_MEM_DEST_USES_SIZE_T
gsize size = 0;
#else
gulong size = 0;
#endif
guchar *input = NULL;
GdkTextureDownloader downloader;
GBytes *texbytes = NULL;
+8
View File
@@ -146,6 +146,14 @@ typedef NSString *CALayerContentsGravity;
inManualResize = NO;
inMove = NO;
/* We need to deliver the event to the proper drag gestures or we
* will leave the window in inconsistent state that requires clicking
* in the window to cancel the gesture.
*
* TODO: Can we improve grab breaking to fix this?
*/
_gdk_macos_display_send_event ([self gdkDisplay], event);
_gdk_macos_display_break_all_grabs (GDK_MACOS_DISPLAY (display), time);
/* Reset gravity */
+8
View File
@@ -270,6 +270,13 @@ gdk_macos_display_get_next_serial (GdkDisplay *display)
return ++serial;
}
static gboolean
gdk_macos_display_has_pending (GdkDisplay *display)
{
return _gdk_event_queue_find_first (display) ||
_gdk_macos_event_source_check_pending ();
}
static void
gdk_macos_display_notify_startup_complete (GdkDisplay *display,
const char *startup_notification_id)
@@ -604,6 +611,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
display_class->get_next_serial = gdk_macos_display_get_next_serial;
display_class->get_name = gdk_macos_display_get_name;
display_class->get_setting = gdk_macos_display_get_setting;
display_class->has_pending = gdk_macos_display_has_pending;
display_class->init_gl = gdk_macos_display_init_gl;
display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete;
display_class->queue_events = gdk_macos_display_queue_events;
+1 -1
View File
@@ -391,7 +391,7 @@ _gdk_macos_pasteboard_register_drag_types (NSWindow *window)
/* Default to an url type (think gobject://internal)
* to support internal, GType-based DnD.
*/
if ([ret count] == 0)
if (n_mime_types == 0)
{
GdkContentFormats *formats;
gsize n_gtypes;
+16 -46
View File
@@ -208,21 +208,16 @@ wl_cursor_destroy(struct wl_cursor *cursor)
static struct wl_cursor *
wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
const char *name,
unsigned int size,
unsigned int scale)
unsigned int size)
{
char *path;
XcursorImages *images;
struct wl_cursor *cursor;
struct cursor_image *image;
int i, nbytes;
unsigned int load_size;
int load_scale = 1;
load_size = size * scale;
path = g_strconcat (theme->path, "/", name, NULL);
images = xcursor_load_images (path, load_size);
images = xcursor_load_images (path, size);
if (!images)
{
@@ -230,14 +225,6 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
return NULL;
}
if (images->images[0]->width != load_size ||
images->images[0]->height != load_size)
{
xcursor_images_destroy (images);
images = xcursor_load_images (path, size);
load_scale = scale;
}
g_free (path);
cursor = malloc(sizeof *cursor);
@@ -255,7 +242,7 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
}
cursor->name = strdup(name);
cursor->size = load_size;
cursor->size = images->images[0]->size;
for (i = 0; i < images->nimage; i++) {
image = malloc(sizeof *image);
@@ -265,10 +252,10 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
image->theme = theme;
image->buffer = NULL;
image->image.width = images->images[i]->width * load_scale;
image->image.height = images->images[i]->height * load_scale;
image->image.hotspot_x = images->images[i]->xhot * load_scale;
image->image.hotspot_y = images->images[i]->yhot * load_scale;
image->image.width = images->images[i]->width;
image->image.height = images->images[i]->height;
image->image.hotspot_x = images->images[i]->xhot;
image->image.hotspot_y = images->images[i]->yhot;
image->image.delay = images->images[i]->delay;
nbytes = image->image.width * image->image.height * 4;
@@ -278,24 +265,9 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
break;
}
if (load_scale == 1) {
/* copy pixels to shm pool */
memcpy(theme->pool->data + image->offset,
images->images[i]->pixels, nbytes);
}
else {
/* scale image up while copying it */
for (int y = 0; y < image->image.height; y++) {
char *p = theme->pool->data + image->offset + y * image->image.width * 4;
char *q = ((char *)images->images[i]->pixels) + (y / load_scale) * images->images[i]->width * 4;
for (int x = 0; x < image->image.width; x++) {
p[4 * x] = q[4 * (x/load_scale)];
p[4 * x + 1] = q[4 * (x/load_scale) + 1];
p[4 * x + 2] = q[4 * (x/load_scale) + 2];
p[4 * x + 3] = q[4 * (x/load_scale) + 3];
}
}
}
/* copy pixels to shm pool */
memcpy(theme->pool->data + image->offset,
images->images[i]->pixels, nbytes);
cursor->images[i] = (struct wl_cursor_image *) image;
}
cursor->image_count = i;
@@ -316,12 +288,11 @@ wl_cursor_create_from_xcursor_images(struct wl_cursor_theme *theme,
static void
load_cursor(struct wl_cursor_theme *theme,
const char *name,
unsigned int size,
unsigned int scale)
unsigned int size)
{
struct wl_cursor *cursor;
cursor = wl_cursor_create_from_xcursor_images(theme, name, size, scale);
cursor = wl_cursor_create_from_xcursor_images(theme, name, size);
if (cursor) {
theme->cursor_count++;
@@ -405,12 +376,12 @@ wl_cursor_theme_destroy(struct wl_cursor_theme *theme)
struct wl_cursor *
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
const char *name,
unsigned int scale)
float scale)
{
unsigned int i;
unsigned int size;
size = theme->size * scale;
size = ceil (theme->size * scale);
for (i = 0; i < theme->cursor_count; i++) {
if (size == theme->cursors[i]->size &&
@@ -418,11 +389,10 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
return theme->cursors[i];
}
load_cursor (theme, name, theme->size, scale);
load_cursor (theme, name, size);
if (i < theme->cursor_count) {
if (size == theme->cursors[i]->size &&
strcmp (name, theme->cursors[theme->cursor_count - 1]->name) == 0)
if (strcmp (name, theme->cursors[theme->cursor_count - 1]->name) == 0)
return theme->cursors[theme->cursor_count - 1];
}
+1 -1
View File
@@ -59,7 +59,7 @@ wl_cursor_theme_destroy(struct wl_cursor_theme *theme);
struct wl_cursor *
wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
const char *name,
unsigned int scale);
float scale);
struct wl_buffer *
wl_cursor_image_get_buffer(struct wl_cursor_image *image);
+51
View File
@@ -402,6 +402,38 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader,
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
continue;
thisSize = fileHeader->tocs[n].subtype;
if (thisSize == size)
{
bestSize = size;
nsizes++;
}
}
if (bestSize)
goto done;
for (n = 0; n < fileHeader->ntoc; n++)
{
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
continue;
thisSize = fileHeader->tocs[n].subtype;
if (thisSize == 2 * size)
{
bestSize = 2 * size;
nsizes++;
}
}
if (bestSize)
goto done;
for (n = 0; n < fileHeader->ntoc; n++)
{
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
continue;
thisSize = fileHeader->tocs[n].subtype;
if (thisSize < size)
continue;
if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
{
bestSize = thisSize;
@@ -410,6 +442,25 @@ _XcursorFindBestSize (XcursorFileHeader *fileHeader,
else if (thisSize == bestSize)
nsizes++;
}
if (bestSize)
goto done;
for (n = 0; n < fileHeader->ntoc; n++)
{
if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
continue;
thisSize = fileHeader->tocs[n].subtype;
if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
{
bestSize = thisSize;
nsizes = 1;
}
else if (thisSize == bestSize)
nsizes++;
}
done:
*nsizesp = nsizes;
return bestSize;
}
+10 -27
View File
@@ -119,7 +119,7 @@ name_fallback (const char *name)
static struct wl_cursor *
gdk_wayland_cursor_load_for_name (GdkWaylandDisplay *display_wayland,
struct wl_cursor_theme *theme,
int scale,
float scale,
const char *name)
{
struct wl_cursor *c;
@@ -156,7 +156,6 @@ struct wl_buffer *
_gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
GdkCursor *cursor,
double desired_scale,
gboolean use_viewporter,
guint image_index,
int *hotspot_x,
int *hotspot_y,
@@ -169,7 +168,6 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
if (gdk_cursor_get_name (cursor))
{
struct wl_cursor *c;
int scale_factor;
if (g_str_equal (gdk_cursor_get_name (cursor), "none"))
{
@@ -179,12 +177,11 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
return NULL;
}
scale_factor = (int) ceil (desired_scale);
c = gdk_wayland_cursor_load_for_name (display,
display->cursor_theme,
scale_factor,
desired_scale,
gdk_cursor_get_name (cursor));
if (c && c->image_count > 0)
{
struct wl_cursor_image *image;
@@ -199,22 +196,12 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
image = c->images[image_index];
*width = display->cursor_theme_size;
*height = display->cursor_theme_size;
*scale = image->width / (double) *width;
*hotspot_x = image->hotspot_x / scale_factor;
*hotspot_y = image->hotspot_y / scale_factor;
*scale = c->size / (double) display->cursor_theme_size;
if (*scale != scale_factor && !use_viewporter)
{
g_warning (G_STRLOC " cursor image size (%d) not an integer "
"multiple of theme size (%d)", image->width, *width);
*width = image->width;
*height = image->height;
*hotspot_x = image->hotspot_x;
*hotspot_y = image->hotspot_y;
*scale = 1;
}
*width = image->width / *scale;
*height = image->height / *scale;
*hotspot_x = image->hotspot_x / *scale;
*hotspot_y = image->hotspot_y / *scale;
return wl_cursor_image_get_buffer (image);
}
@@ -260,14 +247,11 @@ from_texture:
}
else
{
if (!use_viewporter)
*scale = ceil (desired_scale);
else
*scale = desired_scale;
*scale = desired_scale;
texture = gdk_cursor_get_texture_for_size (cursor,
display->cursor_theme_size,
*scale,
desired_scale,
width,
height,
hotspot_x,
@@ -302,7 +286,6 @@ from_texture:
return _gdk_wayland_cursor_get_buffer (display,
gdk_cursor_get_fallback (cursor),
desired_scale,
use_viewporter,
image_index,
hotspot_x, hotspot_y,
width, height,
+3 -10
View File
@@ -265,22 +265,17 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
guint next_image_index, next_image_delay;
gboolean retval = G_SOURCE_REMOVE;
GdkWaylandTabletData *tablet;
gboolean use_viewport = FALSE;
tablet = gdk_wayland_seat_find_tablet (seat, device);
if (pointer->pointer_surface_viewport &&
g_getenv ("USE_POINTER_VIEWPORT"))
use_viewport = TRUE;
if (pointer->cursor)
{
buffer = _gdk_wayland_cursor_get_buffer (GDK_WAYLAND_DISPLAY (seat->display),
pointer->cursor,
pointer->current_output_scale,
use_viewport,
pointer->cursor_image_index,
&x, &y, &w, &h, &scale);
&x, &y, &w, &h,
&scale);
}
else
{
@@ -317,7 +312,7 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
if (buffer)
{
wl_surface_attach (pointer->pointer_surface, buffer, 0, 0);
if (use_viewport)
if (pointer->pointer_surface_viewport)
{
wp_viewport_set_source (pointer->pointer_surface_viewport,
wl_fixed_from_int (0),
@@ -326,8 +321,6 @@ gdk_wayland_device_update_surface_cursor (GdkDevice *device)
wl_fixed_from_double (h * scale));
wp_viewport_set_destination (pointer->pointer_surface_viewport, w, h);
}
else if (wl_surface_get_version (pointer->pointer_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
wl_surface_set_buffer_scale (pointer->pointer_surface, scale);
wl_surface_damage (pointer->pointer_surface, 0, 0, w, h);
wl_surface_commit (pointer->pointer_surface);
}
+25 -2
View File
@@ -43,6 +43,7 @@
#include "gdksurface-wayland.h"
#include "gdksurfaceprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdevice-wayland-private.h"
#include "gdkkeysprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkcairocontext-wayland.h"
@@ -623,7 +624,7 @@ _gdk_wayland_display_open (const char *display_name)
display = g_object_new (GDK_TYPE_WAYLAND_DISPLAY, NULL);
display_wayland = GDK_WAYLAND_DISPLAY (display);
display_wayland->wl_display = wl_display;
gdk_wayland_display_install_gsources (display_wayland);
display_wayland->event_source = _gdk_wayland_display_event_source_new (display);
init_settings (display);
@@ -724,7 +725,12 @@ gdk_wayland_display_dispose (GObject *object)
g_list_free_full (display_wayland->toplevels, destroy_toplevel);
gdk_wayland_display_uninstall_gsources (display_wayland);
if (display_wayland->event_source)
{
g_source_destroy (display_wayland->event_source);
g_source_unref (display_wayland->event_source);
display_wayland->event_source = NULL;
}
g_list_free_full (display_wayland->async_roundtrips, (GDestroyNotify) wl_callback_destroy);
@@ -876,6 +882,12 @@ gdk_wayland_display_make_default (GdkDisplay *display)
display_wayland->startup_notification_id = g_strdup (startup_id);
}
static gboolean
gdk_wayland_display_has_pending (GdkDisplay *display)
{
return FALSE;
}
static gulong
gdk_wayland_display_get_next_serial (GdkDisplay *display)
{
@@ -1042,6 +1054,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
display_class->sync = gdk_wayland_display_sync;
display_class->flush = gdk_wayland_display_flush;
display_class->make_default = gdk_wayland_display_make_default;
display_class->has_pending = gdk_wayland_display_has_pending;
display_class->queue_events = _gdk_wayland_display_queue_events;
display_class->get_app_launch_context = _gdk_wayland_display_get_app_launch_context;
display_class->get_next_serial = gdk_wayland_display_get_next_serial;
@@ -1151,6 +1164,7 @@ _gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY(display);
struct wl_cursor_theme *theme;
GList *seats;
g_assert (display_wayland);
g_assert (display_wayland->shm);
@@ -1180,6 +1194,15 @@ _gdk_wayland_display_set_cursor_theme (GdkDisplay *display,
g_free (display_wayland->cursor_theme_name);
display_wayland->cursor_theme_name = g_strdup (name);
display_wayland->cursor_theme_size = size;
seats = gdk_display_list_seats (display);
for (GList *l = seats; l; l = l->next)
{
GdkSeat *seat = l->data;
gdk_wayland_device_update_surface_cursor (gdk_seat_get_pointer (seat));
}
g_list_free (seats);
}
struct wl_cursor_theme *
-1
View File
@@ -146,7 +146,6 @@ struct _GdkWaylandDisplay
GHashTable *cursor_surface_cache;
GSource *event_source;
GSource *poll_source;
uint32_t server_decoration_mode;
+81 -173
View File
@@ -24,119 +24,44 @@
#include <unistd.h>
#include <errno.h>
typedef struct _GdkWaylandEventSource GdkWaylandEventSource;
typedef struct _GdkWaylandPollSource GdkWaylandPollSource;
struct _GdkWaylandEventSource
{
GSource source;
GdkWaylandDisplay *display;
};
struct _GdkWaylandPollSource
{
typedef struct _GdkWaylandEventSource {
GSource source;
GPollFD pfd;
GdkWaylandDisplay *display;
guint reading : 1;
guint can_dispatch : 1;
};
/* If we should try wl_display_dispatch_pending() before
* polling the Wayland fd
*/
static gboolean
gdk_wayland_display_can_dispatch (GdkWaylandDisplay *display_wayland)
{
GdkWaylandPollSource *poll_source = (GdkWaylandPollSource *) display_wayland->poll_source;
return poll_source->can_dispatch;
}
/* If we still have events to process and don't need to poll */
static gboolean
gdk_wayland_display_has_events_pending (GdkWaylandDisplay *display_wayland)
{
return gdk_wayland_display_can_dispatch (display_wayland) ||
_gdk_event_queue_find_first (GDK_DISPLAY (display_wayland)) != NULL;
}
uint32_t mask;
GdkDisplay *display;
gboolean reading;
} GdkWaylandEventSource;
static gboolean
gdk_wayland_event_source_prepare (GSource *base,
int *timeout)
gdk_event_source_prepare (GSource *base,
int *timeout)
{
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
*timeout = -1;
return gdk_wayland_display_has_events_pending (source->display);
}
static gboolean
gdk_wayland_event_source_check (GSource *base)
{
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
return gdk_wayland_display_has_events_pending (source->display);
}
static gboolean
gdk_wayland_event_source_dispatch (GSource *base,
GSourceFunc callback,
gpointer data)
{
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
GdkEvent *event;
event = gdk_display_get_event (GDK_DISPLAY (source->display));
if (event)
{
_gdk_event_emit (event);
gdk_event_unref (event);
}
return G_SOURCE_CONTINUE;
}
static void
gdk_wayland_event_source_finalize (GSource *base)
{
}
static GSourceFuncs gdk_wayland_event_source_funcs = {
gdk_wayland_event_source_prepare,
gdk_wayland_event_source_check,
gdk_wayland_event_source_dispatch,
gdk_wayland_event_source_finalize
};
static gboolean
gdk_wayland_poll_source_prepare (GSource *base,
int *timeout)
{
GdkWaylandPollSource *source = (GdkWaylandPollSource *) base;
GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display;
GList *l;
*timeout = -1;
if (gdk_wayland_display_has_events_pending (source->display))
return FALSE;
if (source->display->event_pause_count > 0)
return _gdk_event_queue_find_first (source->display) != NULL;
/* We have to add/remove the GPollFD if we want to update our
* poll event mask dynamically. Instead, let's just flush all
* write on idle instead, which is what this amounts to.
*/
if (_gdk_event_queue_find_first (source->display) != NULL)
return TRUE;
/* wl_display_prepare_read() needs to be balanced with either
* wl_display_read_events() or wl_display_cancel_read()
* (in gdk_wayland_event_source_check() */
* (in gdk_event_source_check() */
if (source->reading)
return FALSE;
/* if prepare_read() returns non-zero, there are events to be dispatched */
if (wl_display_prepare_read (display->wl_display) != 0)
{
source->can_dispatch = TRUE;
return TRUE;
}
return TRUE;
/* We need to check whether there are pending events on the surface queues as well,
* but we also need to make sure to only have one active "read" in the end,
@@ -149,8 +74,6 @@ gdk_wayland_poll_source_prepare (GSource *base,
if (wl_display_prepare_read_queue (display->wl_display, queue) != 0)
{
source->can_dispatch = TRUE;
/* cancel the read from before the for loop */
wl_display_cancel_read (display->wl_display);
return TRUE;
}
@@ -169,19 +92,23 @@ gdk_wayland_poll_source_prepare (GSource *base,
}
static gboolean
gdk_wayland_poll_source_check (GSource *base)
gdk_event_source_check (GSource *base)
{
GdkWaylandPollSource *source = (GdkWaylandPollSource *) base;
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
GdkWaylandDisplay *display_wayland = (GdkWaylandDisplay *) source->display;
if (source->display->event_pause_count > 0)
{
if (source->reading)
wl_display_cancel_read (display_wayland->wl_display);
source->reading = FALSE;
return _gdk_event_queue_find_first (source->display) != NULL;
}
/* read the events from the wayland fd into their respective queues if we have data */
if (source->reading)
{
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
{
g_message ("Lost connection to Wayland compositor.");
_exit (1);
}
if (source->pfd.revents & G_IO_IN)
{
if (wl_display_read_events (display_wayland->wl_display) < 0)
@@ -189,40 +116,53 @@ gdk_wayland_poll_source_check (GSource *base)
g_message ("Error reading events from display: %s", g_strerror (errno));
_exit (1);
}
source->pfd.revents = 0;
source->can_dispatch = TRUE;
}
else
wl_display_cancel_read (display_wayland->wl_display);
source->reading = FALSE;
}
return FALSE;
return _gdk_event_queue_find_first (source->display) != NULL ||
source->pfd.revents;
}
static gboolean
gdk_wayland_poll_source_dispatch (GSource *base,
GSourceFunc callback,
gpointer data)
gdk_event_source_dispatch (GSource *base,
GSourceFunc callback,
gpointer data)
{
return G_SOURCE_CONTINUE;
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
GdkDisplay *display = source->display;
GdkEvent *event;
event = gdk_display_get_event (display);
if (event)
{
_gdk_event_emit (event);
gdk_event_unref (event);
}
return TRUE;
}
static void
gdk_wayland_poll_source_finalize (GSource *base)
gdk_event_source_finalize (GSource *base)
{
GdkWaylandPollSource *source = (GdkWaylandPollSource *) base;
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display;
if (source->reading)
wl_display_cancel_read (source->display->wl_display);
wl_display_cancel_read (display->wl_display);
source->reading = FALSE;
}
static GSourceFuncs gdk_wayland_poll_source_funcs = {
gdk_wayland_poll_source_prepare,
gdk_wayland_poll_source_check,
gdk_wayland_poll_source_dispatch,
gdk_wayland_poll_source_finalize
static GSourceFuncs wl_glib_source_funcs = {
gdk_event_source_prepare,
gdk_event_source_check,
gdk_event_source_dispatch,
gdk_event_source_finalize
};
void
@@ -236,81 +176,45 @@ _gdk_wayland_display_deliver_event (GdkDisplay *display,
_gdk_display_get_next_serial (display));
}
void
gdk_wayland_display_install_gsources (GdkWaylandDisplay *display_wayland)
GSource *
_gdk_wayland_display_event_source_new (GdkDisplay *display)
{
GdkDisplay *display = GDK_DISPLAY (display_wayland);
GSource *source;
GdkWaylandEventSource *event_source;
GdkWaylandPollSource *poll_source;
GdkWaylandEventSource *wl_source;
GdkWaylandDisplay *display_wayland;
char *name;
/* SOURCE 1 */
source = g_source_new (&gdk_wayland_event_source_funcs,
source = g_source_new (&wl_glib_source_funcs,
sizeof (GdkWaylandEventSource));
display_wayland->event_source = source;
event_source = (GdkWaylandEventSource *) source;
name = g_strdup_printf ("GDK Wayland Event source (%s)",
gdk_display_get_name (display));
g_source_set_name (source, name);
g_free (name);
wl_source = (GdkWaylandEventSource *) source;
event_source->display = display_wayland;
display_wayland = GDK_WAYLAND_DISPLAY (display);
wl_source->display = display;
wl_source->pfd.fd = wl_display_get_fd (display_wayland->wl_display);
wl_source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
g_source_add_poll (source, &wl_source->pfd);
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
g_source_set_can_recurse (source, TRUE);
g_source_attach (source, NULL);
/* SOURCE 2 */
source = g_source_new (&gdk_wayland_poll_source_funcs,
sizeof (GdkWaylandPollSource));
display_wayland->poll_source = source;
poll_source = (GdkWaylandPollSource *) source;
name = g_strdup_printf ("GDK Wayland Poll source (%s)",
gdk_display_get_name (display));
g_source_set_name (source, name);
g_free (name);
poll_source->display = display_wayland;
poll_source->pfd.fd = wl_display_get_fd (display_wayland->wl_display);
poll_source->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
g_source_add_poll (source, &poll_source->pfd);
/* We must guarantee to ALWAYS be called and called FIRST after
* every poll - or rather: after every prepare().
* Any other source might call Wayland functions and in turn
* block while waiting for us.
* And GSource has no after_pool() vfunc, check() is not guaranteed
* to be called.
*/
g_source_set_priority (source, G_MININT);
g_source_attach (source, NULL);
}
void
gdk_wayland_display_uninstall_gsources (GdkWaylandDisplay *display_wayland)
{
if (display_wayland->event_source)
{
g_source_destroy (display_wayland->event_source);
g_source_unref (display_wayland->event_source);
display_wayland->event_source = NULL;
}
if (display_wayland->poll_source)
{
g_source_destroy (display_wayland->poll_source);
g_source_unref (display_wayland->poll_source);
display_wayland->poll_source = NULL;
}
return source;
}
void
_gdk_wayland_display_queue_events (GdkDisplay *display)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GdkWaylandPollSource *poll_source;
GdkWaylandDisplay *display_wayland;
GdkWaylandEventSource *source;
GList *l;
display_wayland = GDK_WAYLAND_DISPLAY (display);
source = (GdkWaylandEventSource *) display_wayland->event_source;
if (wl_display_dispatch_pending (display_wayland->wl_display) < 0)
{
g_message ("Error %d (%s) dispatching to Wayland display.",
@@ -330,6 +234,10 @@ _gdk_wayland_display_queue_events (GdkDisplay *display)
}
}
poll_source = (GdkWaylandPollSource *) display_wayland->poll_source;
poll_source->can_dispatch = FALSE;
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
{
g_message ("Lost connection to Wayland compositor.");
_exit (1);
}
source->pfd.revents = 0;
}
+1 -3
View File
@@ -117,7 +117,6 @@ void gdk_wayland_display_system_bell (GdkDisplay *display,
struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
GdkCursor *cursor,
double desired_scale,
gboolean use_viewporter,
guint image_index,
int *hotspot_x,
int *hotspot_y,
@@ -184,8 +183,7 @@ void gdk_wayland_device_unset_touch_grab (GdkDevice *device,
GdkEventSequence *sequence);
void _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
void gdk_wayland_display_install_gsources (GdkWaylandDisplay *display_wayland);
void gdk_wayland_display_uninstall_gsources (GdkWaylandDisplay *display_wayland);
GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
void _gdk_wayland_display_queue_events (GdkDisplay *display);
GdkAppLaunchContext *_gdk_wayland_display_get_app_launch_context (GdkDisplay *display);
-1
View File
@@ -4261,7 +4261,6 @@ init_pointer_data (GdkWaylandPointerData *pointer_data,
wl_surface_add_listener (pointer_data->pointer_surface,
&pointer_surface_listener,
logical_device);
if (display_wayland->viewporter)
pointer_data->pointer_surface_viewport = wp_viewporter_get_viewport (display_wayland->viewporter, pointer_data->pointer_surface);
}
+1 -1
View File
@@ -266,7 +266,7 @@ get_gl_texture_wl_buffer (GdkWaylandSubsurface *self,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
&gl_buffer_listener,
g_memdup (&gldata, sizeof (gldata)));
g_memdup2 (&gldata, sizeof (gldata)));
}
static struct wl_buffer *
+1 -1
View File
@@ -389,7 +389,7 @@ create_image_desc (GdkWaylandColor *color,
}
else
{
xx_image_description_v4_add_listener (desc, &cs_image_desc_listener, g_memdup (&data, sizeof data));
xx_image_description_v4_add_listener (desc, &cs_image_desc_listener, g_memdup2 (&data, sizeof data));
}
}
+15 -15
View File
@@ -63,23 +63,23 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
int scale;
cairo_t *cr;
int width, height;
RECT queued_window_rect;
RECT queued_hwnd_rect;
surface = gdk_draw_context_get_surface (draw_context);
scale = gdk_surface_get_scale_factor (surface);
queued_window_rect = gdk_win32_surface_handle_queued_move_resize (draw_context);
queued_hwnd_rect = gdk_win32_surface_handle_queued_move_resize (draw_context);
width = queued_window_rect.right - queued_window_rect.left;
height = queued_window_rect.bottom - queued_window_rect.top;
width = queued_hwnd_rect.right - queued_hwnd_rect.left;
height = queued_hwnd_rect.bottom - queued_hwnd_rect.top;
width = MAX (width, 1);
height = MAX (height, 1);
self->window_surface = create_cairo_surface_for_surface (surface, scale);
self->hwnd_surface = create_cairo_surface_for_surface (surface, scale);
if (!self->double_buffered)
/* Non-double-buffered windows paint on the window surface directly */
self->paint_surface = cairo_surface_reference (self->window_surface);
/* Non-double-buffered GDK surfaces paint on the window surface directly */
self->paint_surface = cairo_surface_reference (self->hwnd_surface);
else
{
if (width > self->db_width ||
@@ -92,13 +92,13 @@ gdk_win32_cairo_context_begin_frame (GdkDrawContext *draw_context,
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
self->db_surface = gdk_surface_create_similar_surface (surface,
cairo_surface_get_content (self->window_surface),
cairo_surface_get_content (self->hwnd_surface),
self->db_width,
self->db_height);
G_GNUC_END_IGNORE_DEPRECATIONS
}
/* Double-buffered windows paint on a DB surface.
/* Double-buffered GDK surfaces paint on a DB surface.
* Due to performance concerns we don't recreate it unless forced to.
*/
self->paint_surface = cairo_surface_reference (self->db_surface);
@@ -128,19 +128,19 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
{
GdkWin32CairoContext *self = GDK_WIN32_CAIRO_CONTEXT (draw_context);
/* The code to resize double-buffered windows immediately
/* The code to resize double-buffered GDK surfaces immediately
* before blitting the buffer contents onto them used
* to be here.
*/
/* For double-buffered windows we need to blit
* the DB buffer contents into the window itself.
/* For double-buffered GDK surfaces we need to blit
* the DB buffer contents into the GDK surface itself.
*/
if (self->double_buffered)
{
cairo_t *cr;
cr = cairo_create (self->window_surface);
cr = cairo_create (self->hwnd_surface);
cairo_set_source_surface (cr, self->paint_surface, 0, 0);
gdk_cairo_region (cr, painted);
@@ -152,10 +152,10 @@ gdk_win32_cairo_context_end_frame (GdkDrawContext *draw_context,
cairo_destroy (cr);
}
cairo_surface_flush (self->window_surface);
cairo_surface_flush (self->hwnd_surface);
g_clear_pointer (&self->paint_surface, cairo_surface_destroy);
g_clear_pointer (&self->window_surface, cairo_surface_destroy);
g_clear_pointer (&self->hwnd_surface, cairo_surface_destroy);
}
static void
+4 -4
View File
@@ -39,7 +39,7 @@ struct _GdkWin32CairoContext
GdkCairoContext parent_instance;
/* Set to TRUE when double-buffering is used.
* Layered windows use their own, custom double-buffering
* Layered HWNDs use their own, custom double-buffering
* code that is unaffected by this flag.
*/
guint double_buffered : 1;
@@ -51,11 +51,11 @@ struct _GdkWin32CairoContext
int db_width;
int db_height;
/* Surface for the window DC */
cairo_surface_t *window_surface;
/* Surface for the underlying window DC */
cairo_surface_t *hwnd_surface;
/* A reference to db_surface (when double-buffering).
* When not using double-buffering this is a reference
* to window_surface.
* to hwnd_surface.
*/
cairo_surface_t *paint_surface;
};
+35 -35
View File
@@ -89,7 +89,7 @@ texts (strings) or textures (GdkPixbufs) this way.
On Windows:
Clipboard is opened by OpenClipboard(), emptied by EmptyClipboard() (which also
makes the window the clipboard owner), data is put into it by SetClipboardData().
makes the HWND the clipboard owner), data is put into it by SetClipboardData().
Clipboard is closed with CloseClipboard().
If SetClipboardData() is given a NULL data value, the owner will later
receive WM_RENDERFORMAT message, in response to which it must call
@@ -239,7 +239,7 @@ on all the clipboards it owns. This creates multiple write stream (one for each
format being stored), each backed by a HGLOBAL memory object. Once all memory
objects are written, the backend queues a store operation, passing along
all these HGLOBAL objects. The clipboard thread processes that by sending
WM_RENDERALLFORMATS to the window, then signals the task that it's done.
WM_RENDERALLFORMATS to the surface HWND, then signals the task that it's done.
When clipboard owner changes, the old owner receives WM_DESTROYCLIPBOARD message,
the clipboard thread schedules a call to gdk_clipboard_claim_remote()
@@ -390,10 +390,10 @@ typedef struct _GdkWin32ClipboardThread GdkWin32ClipboardThread;
struct _GdkWin32ClipboardThread
{
/* A hidden window that owns our clipboard
/* A hidden HWND that owns our clipboard
* and receives clipboard-related messages.
*/
HWND clipboard_window;
HWND clipboard_hwnd;
/* We receive instructions from the main thread in this queue */
GAsyncQueue *input_queue;
@@ -483,11 +483,11 @@ _gdk_win32_format_uses_hdata (UINT w32format)
/* This function is called in the main thread */
static gboolean
clipboard_window_created (gpointer user_data)
clipboard_hwnd_created (gpointer user_data)
{
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
clipdrop->clipboard_window = (HWND) user_data;
clipdrop->clipboard_hwnd = (HWND) user_data;
return G_SOURCE_REMOVE;
}
@@ -730,7 +730,7 @@ process_advertise (GdkWin32ClipboardThreadAdvertise *adv)
return FALSE;
}
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_window);
error_code = try_open_clipboard (adv->unset ? NULL : clipboard_thread_data->clipboard_hwnd);
if (error_code == ERROR_ACCESS_DENIED)
return TRUE;
@@ -809,7 +809,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
return FALSE;
}
error_code = try_open_clipboard (clipboard_thread_data->clipboard_window);
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
if (error_code == ERROR_ACCESS_DENIED)
return TRUE;
@@ -831,7 +831,7 @@ process_store (GdkWin32ClipboardThreadStore *store)
* that we already own, otherwise we're just killing stuff that some other
* process put in there, which is not nice.
*/
if (GetClipboardOwner () != clipboard_thread_data->clipboard_window)
if (GetClipboardOwner () != clipboard_thread_data->clipboard_hwnd)
{
send_response (store->parent.item_type,
store->parent.opaque_task,
@@ -952,7 +952,7 @@ process_retrieve (GdkWin32ClipboardThreadRetrieve *retr)
}
if (clipboard_thread_data->clipboard_opened_for == INVALID_HANDLE_VALUE)
error_code = try_open_clipboard (clipboard_thread_data->clipboard_window);
error_code = try_open_clipboard (clipboard_thread_data->clipboard_hwnd);
else
error_code = try_open_clipboard (clipboard_thread_data->clipboard_opened_for);
@@ -1119,7 +1119,7 @@ discard_render (GdkWin32ClipboardThreadRender *render,
}
static LRESULT
inner_clipboard_window_procedure (HWND hwnd,
inner_clipboard_hwnd_procedure (HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam)
@@ -1139,7 +1139,7 @@ inner_clipboard_window_procedure (HWND hwnd,
if (queue_is_empty && clipboard_thread_data->wakeup_timer)
{
API_CALL (KillTimer, (clipboard_thread_data->clipboard_window, clipboard_thread_data->wakeup_timer));
API_CALL (KillTimer, (clipboard_thread_data->clipboard_hwnd, clipboard_thread_data->wakeup_timer));
clipboard_thread_data->wakeup_timer = 0;
}
@@ -1159,11 +1159,11 @@ inner_clipboard_window_procedure (HWND hwnd,
clipboard_thread_data->wakeup_timer != 0)
return 0;
if (SetTimer (clipboard_thread_data->clipboard_window, 1, 1000, NULL))
if (SetTimer (clipboard_thread_data->clipboard_hwnd, 1, 1000, NULL))
clipboard_thread_data->wakeup_timer = 1;
else
g_critical ("Failed to set a timer for the clipboard window 0x%p: %lu",
clipboard_thread_data->clipboard_window,
g_critical ("Failed to set a timer for the clipboard HWND 0x%p: %lu",
clipboard_thread_data->clipboard_hwnd,
GetLastError ());
}
@@ -1235,7 +1235,7 @@ inner_clipboard_window_procedure (HWND hwnd,
clipboard_thread_data->stored_hwnd_owner = hwnd_owner;
clipboard_thread_data->owner_change_time = g_get_monotonic_time ();
if (hwnd_owner != clipboard_thread_data->clipboard_window)
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
{
if (clipboard_thread_data->cached_advertisement)
g_array_free (clipboard_thread_data->cached_advertisement, TRUE);
@@ -1243,9 +1243,9 @@ inner_clipboard_window_procedure (HWND hwnd,
clipboard_thread_data->cached_advertisement = NULL;
}
API_CALL (PostMessage, (clipboard_thread_data->clipboard_window, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipboard_thread_data->clipboard_hwnd, thread_wakeup_message, 0, 0));
if (hwnd_owner != clipboard_thread_data->clipboard_window)
if (hwnd_owner != clipboard_thread_data->clipboard_hwnd)
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_owner_changed, NULL, NULL);
}
@@ -1383,7 +1383,7 @@ inner_clipboard_window_procedure (HWND hwnd,
}
LRESULT CALLBACK
_clipboard_window_procedure (HWND hwnd,
_clipboard_hwnd_procedure (HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam)
@@ -1392,7 +1392,7 @@ _clipboard_window_procedure (HWND hwnd,
GDK_NOTE (EVENTS, g_print ("clipboard thread %s %p",
_gdk_win32_message_to_string (message), hwnd));
retval = inner_clipboard_window_procedure (hwnd, message, wparam, lparam);
retval = inner_clipboard_hwnd_procedure (hwnd, message, wparam, lparam);
GDK_NOTE (EVENTS, g_print (" => %" G_GINT64_FORMAT "\n", (gint64) retval));
@@ -1400,7 +1400,7 @@ _clipboard_window_procedure (HWND hwnd,
}
/*
* Creates a hidden window and add a clipboard listener
* Creates a hidden HWND and add a clipboard listener
*/
static gboolean
register_clipboard_notification ()
@@ -1409,7 +1409,7 @@ register_clipboard_notification ()
ATOM klass;
wclass.lpszClassName = L"GdkClipboardNotification";
wclass.lpfnWndProc = _clipboard_window_procedure;
wclass.lpfnWndProc = _clipboard_hwnd_procedure;
wclass.hInstance = this_module ();
wclass.cbWndExtra = sizeof (GdkWin32ClipboardThread *);
@@ -1417,23 +1417,23 @@ register_clipboard_notification ()
if (!klass)
return FALSE;
clipboard_thread_data->clipboard_window = CreateWindow (MAKEINTRESOURCE (klass),
clipboard_thread_data->clipboard_hwnd = CreateWindow (MAKEINTRESOURCE (klass),
NULL, WS_POPUP,
0, 0, 0, 0, NULL, NULL,
this_module (), NULL);
if (clipboard_thread_data->clipboard_window == NULL)
if (clipboard_thread_data->clipboard_hwnd == NULL)
goto failed;
SetLastError (0);
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_window) == FALSE)
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_hwnd) == FALSE)
{
DestroyWindow (clipboard_thread_data->clipboard_window);
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
goto failed;
}
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_window_created, (gpointer) clipboard_thread_data->clipboard_window, NULL);
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_hwnd_created, (gpointer) clipboard_thread_data->clipboard_hwnd, NULL);
return TRUE;
@@ -1472,8 +1472,8 @@ _gdk_win32_clipboard_thread_main (gpointer data)
}
/* Just in case, as this should only happen when we shut down */
DestroyWindow (clipboard_thread_data->clipboard_window);
CloseHandle (clipboard_thread_data->clipboard_window);
DestroyWindow (clipboard_thread_data->clipboard_hwnd);
CloseHandle (clipboard_thread_data->clipboard_hwnd);
g_async_queue_unref (queue);
g_clear_pointer (&clipboard_thread_data, g_free);
@@ -2756,7 +2756,7 @@ _gdk_win32_advertise_clipboard_contentformats (GTask *task,
gsize mime_types_len;
gsize i;
g_assert (clipdrop->clipboard_window != NULL);
g_assert (clipdrop->clipboard_hwnd != NULL);
adv->parent.item_type = GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_ADVERTISE;
adv->parent.start_time = g_get_monotonic_time ();
@@ -2779,7 +2779,7 @@ _gdk_win32_advertise_clipboard_contentformats (GTask *task,
}
g_async_queue_push (clipdrop->clipboard_open_thread_queue, adv);
API_CALL (PostMessage, (clipdrop->clipboard_window, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
return;
}
@@ -2794,7 +2794,7 @@ _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
gsize mime_types_len;
gsize i;
g_assert (clipdrop->clipboard_window != NULL);
g_assert (clipdrop->clipboard_hwnd != NULL);
retr->parent.item_type = GDK_WIN32_CLIPBOARD_THREAD_QUEUE_ITEM_RETRIEVE;
retr->parent.start_time = g_get_monotonic_time ();
@@ -2809,7 +2809,7 @@ _gdk_win32_retrieve_clipboard_contentformats (GTask *task,
_gdk_win32_add_contentformat_to_pairs (mime_types[i], retr->pairs);
g_async_queue_push (clipdrop->clipboard_open_thread_queue, retr);
API_CALL (PostMessage, (clipdrop->clipboard_window, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
return;
}
@@ -2890,7 +2890,7 @@ clipboard_store_hdata_ready (GObject *clipboard,
store->elements = prep->elements;
g_async_queue_push (clipdrop->clipboard_open_thread_queue, store);
API_CALL (PostMessage, (clipdrop->clipboard_window, thread_wakeup_message, 0, 0));
API_CALL (PostMessage, (clipdrop->clipboard_hwnd, thread_wakeup_message, 0, 0));
g_free (prep);
}
@@ -2907,7 +2907,7 @@ _gdk_win32_store_clipboard_contentformats (GdkClipboard *cb,
GdkWin32Clipdrop *clipdrop = _gdk_win32_clipdrop_get ();
GdkWin32ClipboardStorePrep *prep;
g_assert (clipdrop->clipboard_window != NULL);
g_assert (clipdrop->clipboard_hwnd != NULL);
mime_types = gdk_content_formats_get_mime_types (contentformats, &n_mime_types);
+3 -3
View File
@@ -178,12 +178,12 @@ struct _GdkWin32Clipdrop
*/
GAsyncQueue *clipboard_render_queue;
/* Window handle for the clipboard window that we
/* Window handle for the clipboard surface that we
* receive from the clipboard thread. We use that
* to wake up the clipboard window main loop by
* to wake up the clipboard surface main loop by
* posting a message to it.
*/
HWND clipboard_window;
HWND clipboard_hwnd;
/* The thread that calls DoDragDrop (), which would
* normally block our main thread, as it runs its own
+17 -17
View File
@@ -61,10 +61,10 @@ _gdk_device_virtual_set_active (GdkDevice *device,
static void
gdk_device_virtual_set_surface_cursor (GdkDevice *device,
GdkSurface *window,
GdkSurface *surface,
GdkCursor *cursor)
{
GdkDisplay *display = gdk_surface_get_display (window);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWin32HCursor *win32_hcursor = NULL;
if (cursor == NULL)
@@ -74,39 +74,39 @@ gdk_device_virtual_set_surface_cursor (GdkDevice *device,
win32_hcursor = gdk_win32_display_get_win32hcursor (GDK_WIN32_DISPLAY (display), cursor);
/* This is correct because the code up the stack already
* checked that cursor is currently inside this window,
* checked that cursor is currently inside this surface,
* and wouldn't have called this function otherwise.
*/
if (win32_hcursor != NULL)
SetCursor (gdk_win32_hcursor_get_handle (win32_hcursor));
g_set_object (&GDK_WIN32_SURFACE (window)->cursor, win32_hcursor);
g_set_object (&GDK_WIN32_SURFACE (surface)->cursor, win32_hcursor);
}
void
gdk_device_virtual_query_state (GdkDevice *device,
GdkSurface *window,
GdkSurface **child_window,
double *win_x,
double *win_y,
GdkModifierType *mask)
GdkSurface *surface,
GdkSurface **child_surface,
double *win_x,
double *win_y,
GdkModifierType *mask)
{
GdkDeviceVirtual *virtual = GDK_DEVICE_VIRTUAL (device);
_gdk_device_win32_query_state (virtual->active_device,
window, child_window,
surface, child_surface,
win_x, win_y,
mask);
}
static GdkGrabStatus
gdk_device_virtual_grab (GdkDevice *device,
GdkSurface *window,
gboolean owner_events,
GdkEventMask event_mask,
GdkSurface *confine_to,
GdkCursor *cursor,
guint32 time_)
GdkSurface *surface,
gboolean owner_events,
GdkEventMask event_mask,
GdkSurface *confine_to,
GdkCursor *cursor,
guint32 time_)
{
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
{
@@ -124,7 +124,7 @@ gdk_device_virtual_grab (GdkDevice *device,
else
SetCursor (LoadCursor (NULL, IDC_ARROW));
SetCapture (GDK_SURFACE_HWND (window));
SetCapture (GDK_SURFACE_HWND (surface));
}
return GDK_GRAB_SUCCESS;
+2 -2
View File
@@ -49,8 +49,8 @@ void _gdk_device_virtual_set_active (GdkDevice *device,
void
gdk_device_virtual_query_state (GdkDevice *device,
GdkSurface *window,
GdkSurface **child_window,
GdkSurface *surface,
GdkSurface **child_surface,
double *win_x,
double *win_y,
GdkModifierType *mask);
+25 -25
View File
@@ -32,9 +32,9 @@
G_DEFINE_TYPE (GdkDeviceWin32, gdk_device_win32, GDK_TYPE_DEVICE)
static void
gdk_device_win32_set_surface_cursor (GdkDevice *device,
GdkSurface *window,
GdkCursor *cursor)
gdk_device_win32_set_surface_cursor (GdkDevice *device,
GdkSurface *surface,
GdkCursor *cursor)
{
}
@@ -66,8 +66,8 @@ get_current_mask (void)
static void
gdk_device_win32_query_state (GdkDevice *device,
GdkSurface *window,
GdkSurface **child_window,
GdkSurface *surface,
GdkSurface **child_surface,
double *win_x,
double *win_y,
GdkModifierType *mask)
@@ -76,10 +76,10 @@ gdk_device_win32_query_state (GdkDevice *device,
HWND hwnd, hwndc;
int scale;
if (window)
if (surface)
{
scale = GDK_WIN32_SURFACE (window)->surface_scale;
hwnd = GDK_SURFACE_HWND (window);
scale = GDK_WIN32_SURFACE (surface)->surface_scale;
hwnd = GDK_SURFACE_HWND (surface);
}
else
{
@@ -100,14 +100,14 @@ gdk_device_win32_query_state (GdkDevice *device,
if (win_y)
*win_y = point.y / scale;
if (hwnd && child_window)
if (hwnd && child_surface)
{
hwndc = ChildWindowFromPoint (hwnd, point);
if (hwndc && hwndc != hwnd)
*child_window = gdk_win32_handle_table_lookup_ (hwndc);
*child_surface = gdk_win32_handle_table_lookup_ (hwndc);
else
*child_window = NULL; /* Direct child unknown to gdk */
*child_surface = NULL; /* Direct child unknown to gdk */
}
if (mask)
@@ -116,26 +116,26 @@ gdk_device_win32_query_state (GdkDevice *device,
void
_gdk_device_win32_query_state (GdkDevice *device,
GdkSurface *window,
GdkSurface **child_window,
GdkSurface *surface,
GdkSurface **child_surface,
double *win_x,
double *win_y,
GdkModifierType *mask)
{
if (GDK_IS_DEVICE_VIRTUAL (device))
gdk_device_virtual_query_state (device, window, child_window, win_x, win_y, mask);
gdk_device_virtual_query_state (device, surface, child_surface, win_x, win_y, mask);
else if (GDK_IS_DEVICE_WINTAB (device))
gdk_device_wintab_query_state (device, window, child_window, win_x, win_y, mask);
gdk_device_wintab_query_state (device, surface, child_surface, win_x, win_y, mask);
else
gdk_device_win32_query_state (device, window, child_window, win_x, win_y, mask);
gdk_device_win32_query_state (device, surface, child_surface, win_x, win_y, mask);
}
static GdkGrabStatus
gdk_device_win32_grab (GdkDevice *device,
GdkSurface *window,
GdkSurface *surface,
gboolean owner_events,
GdkEventMask event_mask,
GdkSurface *confine_to,
GdkSurface *confine_to,
GdkCursor *cursor,
guint32 time_)
{
@@ -162,7 +162,7 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
double *win_y,
GdkModifierType *mask)
{
GdkSurface *window = NULL;
GdkSurface *surface = NULL;
GdkWin32Surface *impl = NULL;
POINT screen_pt, client_pt;
HWND hwnd;
@@ -173,21 +173,21 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
/* Use WindowFromPoint instead of ChildWindowFromPoint(Ex).
* Only WindowFromPoint is able to look through transparent
* layered windows.
* layered HWNDs.
*/
hwnd = GetAncestor (WindowFromPoint (screen_pt), GA_ROOT);
/* Verify that we're really inside the client area of the window */
/* Verify that we're really inside the client area of the HWND */
GetClientRect (hwnd, &rect);
screen_to_client (hwnd, screen_pt, &client_pt);
if (!PtInRect (&rect, client_pt))
hwnd = NULL;
window = gdk_win32_handle_table_lookup_ (hwnd);
surface = gdk_win32_handle_table_lookup_ (hwnd);
if (window && (win_x || win_y))
if (surface && (win_x || win_y))
{
impl = GDK_WIN32_SURFACE (window);
impl = GDK_WIN32_SURFACE (surface);
if (win_x)
*win_x = client_pt.x / impl->surface_scale;
@@ -195,7 +195,7 @@ _gdk_device_win32_surface_at_position (GdkDevice *device,
*win_y = client_pt.y / impl->surface_scale;
}
return window;
return surface;
}
static void

Some files were not shown because too many files have changed in this diff Show More