Compare commits

..

571 Commits

Author SHA1 Message Date
António Fernandes
d7922c189f listbase: Allow scroll_to() to grab focus on inactive windows
`gtk_[grid,column]_view_scroll_to()` does 2 things when asked to focus:
1. it sets the focus item tracker to point to the requested position.
2. then it grabs focus on the item widget if focus is within the view.

However, the way it checks whether focus is within the view is faulty.
The FOCUS_WITHIN flag is set only if the global input focus is within.
But what we want to know here is whether the GtkRoot:focus widget is
within, regardless of the window being active or not, otherwise we
are not holding to our documented promise:

> This function works no matter if the listview is shown or focused.
> If it isn’t, then the changes will take effect once that happens.

If the containing window doesn't is inactive, setting the focus item
tracker without grabbing focus is useless, because, once a the window
becomes active, it resets the focus states all the way up from the
`GtkRoot:focus` widget.  But `GtkRoot:focus` was not changed because
we didn't grab focus, so, if it is another item widget than the one
requested, then even the focus item tracker resets to the original
focus, as a side effect of .set_focus_child()

Therefore, even if the window is inactive, we should grab focus if
the  `GtkRoot:focus` is within the view.

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/6266
2023-12-16 11:02:55 +00:00
Benjamin Otte
b782f80311 Merge branch 'testsuite_fix_display_x11_on_win32' into 'main'
testsuite: don't run x11-specific tests if disabled

See merge request GNOME/gtk!6657
2023-12-14 01:57:13 +00:00
Emmanuele Bassi
d2d2fb4b50 Merge branch 'michaelweghorn/a11y_atspi_map_row_col_index_text' into 'main'
a11y atspi: Map GTK_ACCESSIBLE_RELATION_{COL,ROW}_INDEX_TEXT to AT-SPI

See merge request GNOME/gtk!6563
2023-12-13 14:48:10 +00:00
Benjamin Otte
ff9c9e05c3 Merge branch 'testsuite_fix_icontheme_win32_v2' into 'main'
testsuite: fix icontheme test failure on win32 [v2]

See merge request GNOME/gtk!6664
2023-12-12 23:54:43 +00:00
g.willems
e3f39bf0c3 testsuite: only run x11-specific tests if x11 enabled
Some testcases rely on X11 support, which is not always available,
typically on win32.
Skip them if the x11 backend is disabled.
2023-12-12 21:29:03 +01:00
g.willems
d692243727 testsuite: fix icontheme test failure on win32
g_str_has_suffix() fails due to different path separators.
Compare URIs instead.
2023-12-12 21:25:16 +01:00
Benjamin Otte
6ad9db0bf0 Merge branch 'texture-diff-against-distant-ancestors' into 'main'
texture: Enable texture diff against arbitrarily distant ancestors

See merge request GNOME/gtk!6644
2023-12-12 01:46:05 +00:00
Benjamin Otte
486157f6bf Merge branch 'wip/otte/for-main' into 'main'
testsuite: Add a test for opacity + color-matrix nodes

See merge request GNOME/gtk!6659
2023-12-12 01:05:00 +00:00
Benjamin Otte
5ca4ab3aaa dmabuf: Add gdk_dmabuf_import/export_sync_fd()
Vulkan needs this.

This code is following the code that compositors with Wayland support -
like wlroots - are doing.

The code was introduced to Linux in
https://lore.kernel.org/dri-devel/20220506180216.2095060-1-jason@jlekstrand.net/
2023-12-12 01:49:41 +01:00
Benjamin Otte
a37b3fb691 dmabuf: Add gdk_dmabuf_ioctl()
The function is a copy of libdrm's drmIoctl() and handles EINTR and
EAGAIN error.s

Use it for the sync ioctls in the dmabuf mmaping calls.
2023-12-12 01:49:41 +01:00
Benjamin Otte
c414889cfa testsuite: Make memorytexture test work with GLES < 3.1
Previously, the code was skipping various tests and not skipping others
that it should.

Fix both of these cases.
2023-12-12 01:49:41 +01:00
Benjamin Otte
4dfc07ef57 memoryformat: Fix variable types
Use the same types that GL uses.
2023-12-12 01:49:41 +01:00
Benjamin Otte
cf4b0a27f8 glcontext: Only swizzle when we can
Don't use the recently added swizzle optimization if we're using a GL
version that is too old to support swizzling (GLES 2).
2023-12-12 01:49:41 +01:00
Benjamin Otte
393ee574b6 gl: Print debug for CPU conversions of textures
When the GL renderer cannot upload a given format, print a FALLBACK
debug message with the failed format and the alternative that was
picked, for example:

Unsupported format b8g8r8a8, converting on CPU to b8g8r8a8-premultiplied

Makes it easier to figure out what's happening, especially when using
old GLES versions that don't support all formats.
2023-12-12 01:49:41 +01:00
Benjamin Otte
e3c85be53f memoryformat: Add gdk_memory_format_get_fallbacks()
Track fallback formats to use in the memoryformat directly instead of
using in the GL uploading code.

First of all, this allows sharing the code and ensuring all our
renderers use the same fallback mechanism.

But also, this allows tracking fallbacks per-format which is useful
because the fallback formats aren't really a tree. We want to make
FLOAT16 fall back to FLOAT32 when not available, but we also want
FLOAT32 fall back to FLOAT16.
By tracking the fallbacks per-format, we can achieve that.
2023-12-12 01:49:40 +01:00
Benjamin Otte
0f5fda2277 memoryformat: Introduce new (private) API
Add gdk_memory_format_get_premultiplied() and
gdk_memory_format_get_straight() which return the matching
premultiplied/straight format.

Use this to pick the premultiplied format when uploading GL textures.

And remove the duplication in the dmabuf code, where we can now use
these functions instead of tracking both the premultiplied and straight
alpha versions.
2023-12-12 01:49:40 +01:00
Benjamin Otte
0889037959 gltexture: Use the right format to download
When the format is set correctly, which it should be, we should just use
it.

So do that.
2023-12-12 01:49:40 +01:00
Benjamin Otte
ee56ad792c memoryformat: Fix 2 broken formats
They are straight alpha, and the GL renderer isn't using them yet, so
existing code is not affected.
2023-12-12 01:49:40 +01:00
Benjamin Otte
5688b7b4bb gl: Add a new alternative format
Add an "RGBA" format that just maps to the swizzled version of the
default format.

This way, BGR gets mapped to RGB + swizzling first before trying to map
it to the default format for the depth.

The benefit here is that this format has the same memory width, so
uploading/downloading code can treat it equivalent to the original
format and there's no conversion neccessary later.
2023-12-12 01:49:40 +01:00
Luca Bacci
df1802f756 Merge branch 'gdkwin32_support_debug_default-settings' into 'main'
gdk/win32: support default-settings debug flag

See merge request GNOME/gtk!6658
2023-12-11 23:15:38 +00:00
Benjamin Otte
84de90756d memoryformat: Make the big array more readable
Prefix the struct members with their name, similar to how our Vulkan
code looks.
2023-12-11 22:11:28 +01:00
Benjamin Otte
cb5a8a76da Merge branch '6261-gtkstringlist-lacks-item-type-and-n-items' into 'main'
stringlist: Introduce :item-type and :n-items

Closes #6261

See merge request GNOME/gtk!6662
2023-12-11 18:18:49 +00:00
António Fernandes
26c35c00e1 stringlist: Introduce :item-type and :n-items
While not required by the GListModel interface, they are a useful
convention which is already implemented by other GListModel public
implementation in GTK, particularly for use in expressions and
bindings.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/6261
2023-12-11 17:36:52 +00:00
Emmanuele Bassi
5d4879aae7 Merge branch 'wip/typo' into 'main'
gtk-demo: Fix typo

See merge request GNOME/gtk!6661
2023-12-11 13:58:27 +00:00
Carlos Garnacho
39b08b82ca gtk-demo: Fix typo
Close the quotes in alert dialog message.
2023-12-11 14:22:30 +01:00
Benjamin Otte
2b6e7147d6 build: Sort alphabetically 2023-12-11 07:33:26 +01:00
Benjamin Otte
3a1349e8ef gl: Make gdk_memory_format_gl_format() no longer check support
Now that we have gdk_gl_context_get_memory_flags() and code can use that
function, make the code do that.

Remove support checks from gdk_memory_format_gl_format().

This is an initial naive port that doesn't try to make use of the finer-grained
flags yet.
2023-12-11 07:33:26 +01:00
Benjamin Otte
5485d806c5 glcontext: Add gdk_gl_context_get_memory_flags()
Checks which features of a given memory format are supported by
the current GL implementation.

We check:
 * usable: Can be used as a texture with NEAREST filter
 * renderable: Can be used as a render target
 * filterable: Can be used with GL_LINEAR

In normal GL, all formats are all of these things, but GLES is a lot
more picky.

So far nobody uses this.
2023-12-11 07:33:26 +01:00
Benjamin Otte
6e7c499408 testsuite: Don't create nodes with negative size
If width or height are too small, only create one mask node.

The previous math would create the 2nd node with negative width/height.
2023-12-11 07:33:26 +01:00
Benjamin Otte
c341da32aa gsk: Set correct blur radius for cairo shadows 2023-12-11 07:33:26 +01:00
Benjamin Otte
d39ec8c09e gsk: Quality of life improvements for Cairo rendering
1. Check for an empty clip region before push/pop_group() calls

2. Remove save/restore() pairs as the vfunc invocation does so already.
2023-12-11 07:33:26 +01:00
Benjamin Otte
e3299e38df cairo: Handle clipped blur content
This is the result of experimenting with corner cases when blurring.

The result is a test that tests when the child of a blur node is
clipped out but the blurred child is not, the blurred parts are still
visible.

This immediately broke the cairo renderer, so the fix is included.
2023-12-11 07:33:24 +01:00
Benjamin Otte
8fd02f6fa2 subsurface: Do not punch holes for subsurfaces that are above
If a subsurface is not below, it is visible no matter what the opaque
region is.

Also, we don't need to care about transparency in the subsurface if we
ignore it anyway. So this is a win-win.
2023-12-11 07:32:06 +01:00
Benjamin Otte
9bc0ad9a13 gdk: Handle subsurface opaque region with transparency
We accept transparent subsurfaces for passthrough now, when they are
above the surface.
But we did not unset the opaque region to empty when the texture is
transprent.
2023-12-11 07:32:06 +01:00
Benjamin Otte
19171c7a89 testsuite: Add a test for opacity + color-matrix nodes
These are 2x2 combinations that:
1. Use a texture child node vs a color child node
   This should force an offscreen vs straight up use a texture.
2. Switch opacity and color-matrix
   Either put the color matrix into the opacity node or put the opacity
   into the color matrix.

This is worth testing because renderers often combine opacity into the
color matrix to avoid offscreens.

And they do that because applications often create faded out symbolic
images, which end up as a combination of these nodes.
2023-12-09 19:32:39 +01:00
Benjamin Otte
abf942efe5 dmabuf: Don't leak the display 2023-12-09 19:32:39 +01:00
g.willems
dfe7afdb04 gdk/win32: support default-settings debug flag 2023-12-09 17:59:24 +01:00
Ben Mather
1629b072fe texture: Enable texture diff against arbitrarily distant ancestors 2023-12-08 11:29:56 +00:00
Matthias Clasen
0b0a5a52af Merge branch 'docs_clarify_gtk_drop_down_get_selected_item' into 'main'
docs: Clarify how to obtain strings from GtkDropDown

See merge request GNOME/gtk!6647
2023-12-08 10:20:12 +00:00
Matthias Clasen
75d259eedf Merge branch 'fix-label-docs' into 'main'
Docs: Fix unfenced HTML tag in GtkLabel docs

See merge request GNOME/gtk!6650
2023-12-08 10:17:59 +00:00
FeRD (Frank Dana)
6fec018cbd Docs: Fix unfenced HTML tag in GtkLabel docs 2023-12-08 02:29:10 -05:00
Matthias Clasen
6d9c950b82 Merge branch 'ebassi/inhibit-reason-fallback' into 'main'
Add fallback string for empty inhibit reason

See merge request GNOME/gtk!6648
2023-12-08 04:06:11 +00:00
Emmanuele Bassi
0933ea63c5 Add fallback string for empty inhibit reason
The public gtk_application_inhibit() API allows a NULL reason argument,
and we have a fallback in place when going through the session manager
proxy; when using the inhibit D-Bus API directly, though, we're just
passing a potentially NULL value to g_variant_new_string(), which will
rightfully complain.
2023-12-07 11:55:20 +00:00
Logan Rathbone
8cb594696e docs: Clarify how to obtain strings from GtkDropDown 2023-12-07 00:03:04 -05:00
Matthias Clasen
9d7389aea7 Merge branch 'emoji-15.1' into 'main'
emoji: Update data to CLDR v44

See merge request GNOME/gtk!6642
2023-12-06 11:26:05 +00:00
Jeremy Bícha
76a1f1714d emoji: Update data to CLDR v44
Based on emojibase v15.3.0

Contains the changes in Unicode 15.1

https://unicode.org/versions/Unicode15.1.0/
https://cldr.unicode.org/index/downloads/cldr-44
https://github.com/milesj/emojibase/blob/emojibase-data%4015.3.0/packages/data/CHANGELOG.md
2023-12-03 16:32:42 -05:00
Yaron Shahrabani
9af08e17e0 Update Hebrew translation 2023-12-03 13:32:37 +00:00
Boyuan Yang
276afbca92 Update Chinese (China) translation 2023-12-03 01:40:50 +00:00
Yaron Shahrabani
0342d23dbe Update Hebrew translation
(cherry picked from commit cde309d9fa)
2023-12-02 22:12:14 +00:00
Matthias Clasen
1c10837b21 Merge branch 'matthiasc/for-main' into 'main'
Revert "Merge branch 'rgba-new-from-string' into 'main'"

See merge request GNOME/gtk!6640
2023-12-02 05:43:12 +00:00
Matthias Clasen
7cc5d5c7a5 Revert "Merge branch 'rgba-new-from-string' into 'main'"
This reverts commit 77f40d7508, reversing
changes made to b969f4649d.

It turns out we did not have agreement on this after all.
2023-12-02 10:55:35 +05:45
Matthias Clasen
6a59326dbf Merge branch 'emoji-15' into 'main'
emoji: Update data to CLDR v43

See merge request GNOME/gtk!6639
2023-12-02 02:12:17 +00:00
Yaron Shahrabani
1968f331d9 Update Hebrew translation 2023-12-01 21:02:25 +00:00
Jeremy Bícha
bf35836350 emoji: Update data to CLDR v43
Based on emojibase v15.2.0

Contains the changes in Unicode 15.0

https://unicode.org/versions/Unicode15.0.0/
https://cldr.unicode.org/index/downloads/cldr-43
https://github.com/milesj/emojibase/blob/emojibase-data%4015.2.0/packages/data/CHANGELOG.md
2023-12-01 15:57:02 -05:00
Daniel Rusek
036629a491 Update Czech translation 2023-11-30 18:26:58 +00:00
Arjan Molenaar
8cabf59cf3 Merge branch 'macos-secure-restore' into 'main'
macos: Add method that denotes secure restorable state

See merge request GNOME/gtk!6632
2023-11-30 15:17:04 +00:00
Arjan Molenaar
6a4b238641 macos: Add method that denotes secure restorable state
Fix process injection vulnerability on macOS.
2023-11-29 12:30:30 +01:00
Matthias Clasen
d4d0239ae7 Merge branch 'macos-fix-function-signature' into 'main'
Fix function signature warning on macOS

See merge request GNOME/gtk!6628
2023-11-29 00:53:31 +00:00
Matthias Clasen
a30f32db8d Merge branch '6236_fix_modify_textbuffer_in_irreversible' into 'main'
gtktexthistory: allow setting the modified flag in irreversible action

Closes #6236

See merge request GNOME/gtk!6626
2023-11-28 23:51:51 +00:00
Arjan Molenaar
6948a74d72 Fix function signature warning
No arguments -> void
2023-11-28 21:24:10 +01:00
Matthias Clasen
14ec255812 Merge branch 'gles-texture-slice-fixes' into 'main'
gsk: Be more careful about texture slice formats

See merge request GNOME/gtk!6627
2023-11-28 20:07:44 +00:00
Matthias Clasen
00ebd51d06 gsk: Be more careful about texture slice formats
We need to make sure that all our textures have the same memory
format, or we'll run into trouble in the upload code, at least
on GLES, which isn't as forgiving about format mismatches.

Related: #6238
2023-11-28 14:16:21 -05:00
g.willems
7de528b487 gtktexthistory: allow set modified in irreversible action
Allow setting the modified flag, but skip propagating the history state update
as it will be done by gtk_text_history_end_irreversible_action().

Fixes #6236
Closes #6236
2023-11-28 19:57:11 +01:00
Matthias Clasen
77f40d7508 Merge branch 'rgba-new-from-string' into 'main'
Add convenience function gdk_rgba_new_from_string()

See merge request GNOME/gtk!6599
2023-11-28 17:56:21 +00:00
Danial Behzadi
b969f4649d Update Persian translation 2023-11-28 08:47:40 +00:00
FeRD (Frank Dana)
f4f25e584c Fix docs function reference 2023-11-27 21:16:44 -05:00
FeRD (Frank Dana)
b049a3501a Additional review fixes 2023-11-27 19:44:24 -05:00
Emmanuele Bassi
0114fad8a5 Style/doc fixes from review 2023-11-28 00:42:19 +00:00
Matthias Clasen
afafac6878 Merge branch 'matthiasc/for-main' into 'main'
Use O_CLOEXEC instead of FD_CLOEXEC

See merge request GNOME/gtk!6624
2023-11-27 23:10:35 +00:00
Matthias Clasen
108eb43b01 gsk: Add some more proiler marks
These should help us determine if time is spent converting or
uploading textures.
2023-11-27 17:50:28 -05:00
Matthias Clasen
6961c1fe4a Use O_CLOEXEC instead of FD_CLOEXEC
GLib is complaining vocally about this.
2023-11-27 17:50:18 -05:00
Matthias Clasen
606d150e0b Merge branch 'matthiasc/for-main' into 'main'
wayland: Be more careful when loading cursors

See merge request GNOME/gtk!6622
2023-11-27 21:01:16 +00:00
Matthias Clasen
96f7bb99a7 css: Fix opacity handling
We were using the invert value for opacity.
2023-11-27 15:30:37 -05:00
Matthias Clasen
b937c17985 wayland: Be more careful when loading cursors
Make sure we don't access the cursor_images array out of bounds.

Related: #6234
2023-11-27 13:58:38 -05:00
Emmanuele Bassi
79cb370f81 Merge branch 'gtk_font_dialog_choose_font_and_features_finish_fix' into 'main'
GtkFontDialog: fix annotation for choose_font_and_features_finish

See merge request GNOME/gtk!6621
2023-11-27 17:53:38 +00:00
Val Och
154b73723f GtkFontDialog: fix annotation for choose_font_and_features_finish
Parameters in question have callee-allocated semantics.
2023-11-27 19:48:48 +03:00
Artur S0
c0efed4e4a Update Russian translation 2023-11-27 16:16:29 +00:00
Matthias Clasen
4402676aa2 Merge branch 'update-ci-images' into 'main'
ci: Update the fedora image for F39

See merge request GNOME/gtk!6620
2023-11-27 15:25:57 +00:00
Matthias Clasen
9bf4a45d47 Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!6619
2023-11-27 14:59:30 +00:00
Matthias Clasen
85ce343816 ci: Update the fedora image for F39
This will hopefully help with getting the gpu renderer tests
to work.
2023-11-27 09:51:14 -05:00
FeRD (Frank Dana)
114d0621aa Fix coding style issues 2023-11-26 16:19:06 -05:00
Matthias Clasen
d595aff52d coding style: Mention the available stack size 2023-11-26 09:07:38 -05:00
Matthias Clasen
d72fd951e1 Quiet a compiler warning 2023-11-26 08:47:51 -05:00
Matthias Clasen
78706e3fbe Merge branch 'clarify_template_builder_docs' into 'main'
docs: Clarify how to refer to instances created by <template>

See merge request GNOME/gtk!6605
2023-11-25 18:03:08 +00:00
Matthias Clasen
98b796a371 Merge branch 'ci-run-less-tests' into 'main'
ci: Pick up reports for all test setups

See merge request GNOME/gtk!6616
2023-11-25 18:01:50 +00:00
Matthias Clasen
c99f62aef1 Merge branch 'wip/dnd-fixes' into 'main'
DnD fixes

See merge request GNOME/gtk!6608
2023-11-25 17:59:39 +00:00
Matthias Clasen
8754247a90 Merge branch 'wip/otte/dmabuf' into 'main'
dmabuf: A bunch of cleanups

See merge request GNOME/gtk!6610
2023-11-25 17:58:11 +00:00
Matthias Clasen
fd12707162 Merge branch 'doc-fixes' into 'main'
Docs: Misc Fixes

See merge request GNOME/gtk!6615
2023-11-25 17:55:47 +00:00
Matthias Clasen
34bca0ff56 Merge branch 'gtk4-portal-close' into 'main'
[gtk4] Fix file chooser and open uri portal close.

See merge request GNOME/gtk!6613
2023-11-25 17:19:31 +00:00
Matthias Clasen
c668519d07 ci: Handle deprecation warnings in report scripts 2023-11-25 11:21:48 -05:00
Matthias Clasen
454e6eadc6 ci: Rebalance test runs
Move x11 to the debug build, and make it a full run.
2023-11-25 11:03:15 -05:00
Matthias Clasen
e248a01fbd ci: Run less tests
Our test setups are mostly about varying the rendering environment
(different backends, or renderers, etc). Therefore, we don't need
to duplicate the runs of the css or node parser or path tests.
Just run the gdk and gsk-gl tests under all setups.
2023-11-25 10:37:39 -05:00
Matthias Clasen
e2bd7defa4 ci: Tweak the run-tests script
The main change here is to pass the suites to run as an explicit
argument. This is in preparation for running less tests.
2023-11-25 10:37:39 -05:00
Matthias Clasen
855fa6d523 ci: Produce a junit report for asan too 2023-11-25 10:37:39 -05:00
Matthias Clasen
7c620ac2b7 ci: Pick up reports for all test setups
We added a wayland_gl test setup recently, and all the setups
have to be listed manually in .gitlab-ci.yml.
2023-11-25 09:21:16 -05:00
Maximiliano Sandoval R.
d96f2f54e9 stylecontext: Properly anotate Deprecated 2023-11-25 15:02:06 +01:00
Maximiliano Sandoval R.
71c2ee3530 gskenums: Add Since to missing enum values
Use same Since annotation as elsewhere
2023-11-25 15:01:53 +01:00
Maximiliano Sandoval R.
5e415ee916 gskenums: Don't break the docstring 2023-11-25 15:00:40 +01:00
Maximiliano Sandoval R.
e163021b8f debug: Document missing enum 2023-11-25 15:00:14 +01:00
Benjamin Otte
1bf88f1d81 Merge branch 'wip/otte/for-main' into 'main'
Revert commits that disabled the testsuite

See merge request GNOME/gtk!6614
2023-11-25 12:31:21 +00:00
Benjamin Otte
72d2b8e546 Revert "ci: Tweak the run-tests script"
This reverts commit 9aadc2b860.
2023-11-25 13:09:50 +01:00
Benjamin Otte
37f7f3d60c Revert "wip: ci: rework the test runs"
This reverts commit c679ba9ebf.
2023-11-25 13:09:50 +01:00
Benjamin Otte
8d1443994b Revert "ci: Run less tests"
This reverts commit 5a8a839921.
2023-11-25 13:09:49 +01:00
FeRD (Frank Dana)
39db73dff1 Add gdk_rgba_new_from_string()
Signed-off-by: FeRD (Frank Dana) <ferdnyc@gmail.com>
2023-11-24 22:19:39 -05:00
Emilio Cobos Álvarez
68cf5f2cf3 [gtk4] gtkopenuriportal: Fix portal close signal.
Same fix. The other instance of this pattern in gtkapplication-dbus.c
does it right.
2023-11-25 03:49:58 +01:00
Emilio Cobos Álvarez
77c4097c86 [gtk4] GtkFileChooserNative: Fix portal close.
This makes closing a portal file chooser work.

Fixes the GTK4 bits of #6225.
2023-11-25 03:47:28 +01:00
Benjamin Otte
d7bc4c719b dmabuf: Remove unused headers 2023-11-25 01:44:34 +01:00
Benjamin Otte
725857e15b dmabuf: Add a fallback list of fourccs
That way, we can work with older libdrm versions.

The list was generated via a bit of sed and grep from the current
dmabuf-fourcc.h, which is why I put it into its own file and included
all the formats, no matter how old they are.
2023-11-25 01:44:34 +01:00
Benjamin Otte
50ee872978 dmabuf: Add gdk_dmabuf_get_fourcc()
Returns the fourcc for a given GdkMemoryFormat.

Not sure if this is the best name, but I didn't know a better one.
2023-11-25 01:44:34 +01:00
Benjamin Otte
b6c82c6b54 dmabuf: Add all formats
Add the matching GdkMemoryFormat for all dmabuf formats.

This way, we don't fall back to RGBA8 for 10- and 16-bit formats that we
don't support natively when EGL or Vulkan use them.

Also includes corrections for a few mixups.
2023-11-25 01:44:34 +01:00
Benjamin Otte
1bf94b045c dmabuf: Refactor function
1. Don't require passing in a GdkDisplay

2. return TRUE/FALSE if a format was found, so calling code can
   decide how to handle failure itself
2023-11-25 01:44:34 +01:00
Matthias Clasen
13bfe188b5 Merge branch 'matthiasc/for-main' into 'main'
frameclock: Inline a few things

See merge request GNOME/gtk!6607
2023-11-25 00:04:57 +00:00
Matthias Clasen
f21175b3d0 frameclock: Inline a few things
There is no need to call type-checking getters in a loop.
2023-11-24 17:53:34 -05:00
Carlos Garnacho
d78475372f gtk: Obey GTK grabs on DnD events
Make DnD events get directed to the right places (and most
importantly, not to the wrong places) when happening over
modal parts of the UI.

Fixes DnD started from popovers being able to drop on their
modal toplevel.
2023-11-24 23:37:20 +01:00
Carlos Garnacho
988b9de210 gdk/wayland: Pass surface-relative coordinates in DnD events
Make this event behave like the other regular events, and emit
coordinates based on native surfaces. Fixes DnD over popovers
finding the correct coordinates.
2023-11-24 23:35:45 +01:00
Carlos Garnacho
0c19ef6c2c gdk/wayland: Improve recent serial lookup
This function takes an event, so the place(s) that do
not have one readily available can only pass NULL, so
the serial lookup will only work for the pointer.

Pass a device (plus optional sequence) to this function,
as these places do at least have the corresponding
GdkDevice at hand.

Fixes serial lookups for DnD, for other devices than
pointers (e.g. tablets, or touch).
2023-11-24 23:30:36 +01:00
Matthias Clasen
2bfd4a88d6 Fix some more static analysis warnings 2023-11-24 16:36:46 -05:00
Matthias Clasen
de3eeb4970 Merge branch 'docs_clarify_nested_lookup_tags' into 'main'
docs: Clarify that <lookup> tags can be nested.

See merge request GNOME/gtk!6606
2023-11-24 21:22:47 +00:00
Logan Rathbone
5c2e2977e0 docs: Clarify that <lookup> tags can be nested. 2023-11-24 15:52:32 -05:00
Logan Rathbone
24f3ec0949 docs: Clarify how to refer to instances created by <template> 2023-11-24 14:44:12 -05:00
Matthias Clasen
bcab0e4254 Merge branch 'none-bitfield' into 'main'
gdk-enums: Add GDK_NO_MODIFIER_MASK

See merge request GNOME/gtk!6602
2023-11-24 18:33:56 +00:00
Matthias Clasen
253955c017 Merge branch 'ebassi/docs-content-files' into 'main'
Add content_base_url to the docs project files

See merge request GNOME/gtk!6604
2023-11-24 18:19:06 +00:00
Maximiliano Sandoval R.
3a8834a437 gdk-enums: Add GDK_NO_MODIFIER_MASK 2023-11-24 18:04:56 +01:00
Emmanuele Bassi
48ea2ecac3 docs: Add content_base_url
Newer versions of gi-docgen support linking the rendered content files
to its source inside the repository, just like a symbol docblock.
2023-11-24 16:50:41 +00:00
Emmanuele Bassi
6d0b31128b docs: Update the user support information
The IRC channel is on Libera and there's a Matrix room.
2023-11-24 16:50:41 +00:00
Emmanuele Bassi
0b519bc353 docs: Clarify title of the Initialization content file 2023-11-24 16:50:41 +00:00
Emmanuele Bassi
bb756b35a2 docs: Remove duplicate titles 2023-11-24 16:50:41 +00:00
Emmanuele Bassi
7ba7ab1e3d docs: Fix links to the 2.x to 4 migration guide
The GTK3 migration guide is on docs.gtk.org, these days; and the
3.x to 4 migration guide is in the same location as this file.
2023-11-24 16:50:41 +00:00
Emmanuele Bassi
f73a7e29ca docs: Use consistent style for content metadata 2023-11-24 16:50:41 +00:00
Emmanuele Bassi
2eb6e3d4c5 docs: Clean up the key value content file
Use a more descriptive title, add links to the API, add code elements,
and align the text a bit better.
2023-11-24 16:50:41 +00:00
Matthias Clasen
b28cf76f11 Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!6603
2023-11-24 16:09:19 +00:00
Matthias Clasen
36314f28e2 gsk: Some more rect inlining 2023-11-24 10:35:57 -05:00
Matthias Clasen
b7a1b1d7ee Fix some static analysis warnings 2023-11-24 10:35:57 -05:00
Matthias Clasen
57e382b59c Merge branch 'sumibi-yakitori/fix-mouse-cursor-on-macos' into 'main'
macos: Change to send motion events to NSApp

Closes #6134

See merge request GNOME/gtk!6451
2023-11-24 13:06:53 +00:00
Matthias Clasen
a35a885902 Merge branch 'file-launcher-writable' into 'main'
file laucher: Add a writable property

Closes #4247

See merge request GNOME/gtk!6600
2023-11-23 00:13:19 +00:00
Matthias Clasen
5fa3a2a39f file laucher: Add a writable property
If GtkFileLauncher:writable is TRUE, we ask the openuri portal
to make the file writable for the handler that it launches.

Fixes: #4247
2023-11-22 17:43:10 -05:00
Matthias Clasen
7f53b3d3f4 openuri portal: Introduce flags 2023-11-22 17:30:37 -05:00
Matthias Clasen
9b25257cbf Merge branch 'matthiasc/for-main' into 'main'
Address various static analysis complaints

See merge request GNOME/gtk!6598
2023-11-22 11:49:57 +00:00
Matthias Clasen
a90a6c4517 Address various static analysis complaints
These were picked out of the scan_build logs in ci.
2023-11-22 00:07:47 -05:00
Matthias Clasen
e69f062c99 Merge branch 'testsuite-leaks' into 'main'
testsuite: Don't leak so much

See merge request GNOME/gtk!6597
2023-11-22 04:48:42 +00:00
Matthias Clasen
210c7f25ad testsuite: Leak even less
A memory leak spotted by asan.
2023-11-21 23:21:55 -05:00
Matthias Clasen
9695791f7b testsuite: Don't leak so much
My subsurface attach code was leaking all the nodes. Oops.
2023-11-21 23:21:55 -05:00
Matthias Clasen
ca0da0dd83 Merge branch 'matthiasc/for-main' into 'main'
ci: Run less tests

See merge request GNOME/gtk!6596
2023-11-22 03:41:15 +00:00
Matthias Clasen
5a8a839921 ci: Run less tests
Our test setups are mostly about varying the rendering environment
(different backends, or renderers, etc). Therefore, we don't need
to duplicate the runs of the css or node parser or path tests.
Just run the gdk and gsk-gl tests under all setups.
2023-11-21 22:20:47 -05:00
Matthias Clasen
eb84171cda Merge branch 'testsuite-improvements' into 'main'
ci: Tweak the run-tests script

See merge request GNOME/gtk!6587
2023-11-21 19:31:15 +00:00
Benjamin Otte
5608a8978e Merge branch 'picture-integral-size' into 'main'
picture: Keep paintable size integral

See merge request GNOME/gtk!6593
2023-11-21 19:30:53 +00:00
Matthias Clasen
efefdbd5c0 Merge branch 'no-fractional-offload' into 'main'
wayland: Don't offload with fractional scales

See merge request GNOME/gtk!6592
2023-11-21 19:28:03 +00:00
Matthias Clasen
6bea059424 Merge branch 'subsurface-api-tweaks' into 'main'
subsurface: Replace place_above/below

See merge request GNOME/gtk!6595
2023-11-21 18:52:07 +00:00
Matthias Clasen
c99c06f0da wayland: Careful offloading with fractional scales
Sadly, subsurface positioning is undefined in this case. We'll
trust the compositor to not mess up if the device coordinates
after applying the scale are integral, but otherwise, we'll
decline.
2023-11-21 13:47:10 -05:00
Matthias Clasen
bda8f5393d wayland: Allow attaching (some) non-opaque textures
Allow translucent textures when we are raising the subsurface.
2023-11-21 13:24:04 -05:00
Matthias Clasen
160fa969d4 subsurface: Replace place_above/below
Instead, do it all in attach(), which becomes more and more like
ConfigureWindow. This is good, because it will let us take the
above-ness into account when making decisions about attaching.
2023-11-21 13:24:04 -05:00
Benjamin Otte
edf33a6617 Merge branch 'wip/otte/for-main' into 'main'
subsurface: Don't marka failure as success

See merge request GNOME/gtk!6594
2023-11-21 17:01:54 +00:00
Benjamin Otte
86587a9328 subsurface: Don't marka failure as success
There was one branch in the success case that turned it into a failure,
yet we were still reporting a success (and discarding the buffer).

Don't do that.
2023-11-21 17:31:40 +01:00
Matthias Clasen
8691d471d0 picture: Keep paintable size integral
Without this, offloading is very hit-and-miss, since you need
to hit the few size combinations where you get an exact integral
size when preserving the aspect ratio.
2023-11-21 11:14:15 -05:00
Matthias Clasen
463b6dd1fd Merge branch 'egl-device-info' into 'main'
EGL: Print out the device info

See merge request GNOME/gtk!6590
2023-11-21 05:04:35 +00:00
Matthias Clasen
88e1f77f90 EGL: Print out the device info
This may become more relevant info, with dmabuf formats being
tied to specific devices.
2023-11-20 23:40:00 -05:00
Matthias Clasen
1ee488f445 Merge branch 'matthiasc/for-main' into 'main'
wayland: Move subsurface creation code

See merge request GNOME/gtk!6589
2023-11-21 00:04:02 +00:00
Matthias Clasen
eae0e15b9d wayland: Move subsurface creation code
This belongs with all the other subsurface handling.
2023-11-20 18:01:09 -05:00
Matthias Clasen
00d551bda8 Merge branch 'drop-legacy-gl' into 'main'
Drop the gl-legacy debug value

See merge request GNOME/gtk!6585
2023-11-20 13:31:27 +00:00
Matthias Clasen
2dcec44714 Drop the nograbs debug value
This was only used in the x11 backend, and I haven't seen it
actively recommended for debugging anything in ages.
2023-11-20 08:02:03 -05:00
Matthias Clasen
f04c819439 Drop the gl-legacy debug value
The consensus is that we can do without this.
2023-11-20 08:02:02 -05:00
Matthias Clasen
c679ba9ebf wip: ci: rework the test runs 2023-11-19 21:26:04 -05:00
Matthias Clasen
9aadc2b860 ci: Tweak the run-tests script
The main change here is to pass the suite to run as an explicit
argument. This is in preparation for running less tests.
2023-11-19 21:26:04 -05:00
Emmanuele Bassi
e4370cc95e Merge branch 'matthiasc/for-main' into 'main'
file dialog: Return an error if no file is selected

Closes #6139

See merge request GNOME/gtk!6586
2023-11-19 18:29:57 +00:00
Matthias Clasen
22ceb018fb file dialog: Return an error if no file is selected
This was brought as a problem for bindings in #6139.

Fixes: #6139
2023-11-19 12:46:56 -05:00
Matthias Clasen
833d307695 Merge branch 'default-to-gles' into 'main'
Use GLES by default

Closes #6170

See merge request GNOME/gtk!6520
2023-11-19 16:14:04 +00:00
Piotr Drąg
e8afb5e210 Update Polish translation 2023-11-19 15:34:46 +01:00
Matthias Clasen
b916c4dac1 ci: Reshuffle test setups
Add a wayland_gl setup that explicitly uses desktop GL, and rename
wayland_gles to wayland_gles2 (since that is what it does).

In ci, make the fedora-x86_64 runner run tests with wayland_gl
and wayland_gles2, and make the fedora-release runner run test
with wayland and x11.
2023-11-19 08:24:38 -05:00
Matthias Clasen
699c6d6159 Use GLES by default
With the advent of dmabuf support, using GLES has become more
attractive, since we can use its external texture support to
support more dmabuf formats.

You can go back to the previous preference order by setting

    GDK_DEBUG=gl-prefer-gl
2023-11-19 08:07:03 -05:00
Matthias Clasen
025b846fce Add a debug value to prefer desktop GL
This will be used in the next commit, when we change the default
preference to be GLES.
2023-11-19 08:07:02 -05:00
Matthias Clasen
fcdbab3f69 gl: Tweak debug values for GL api selection
Replace GDK_DEBUG=gl-gles with GDK_DEBUG=gl-disable-gl, and add
a GDK_DEBUG=gl-disable-gles to match.
2023-11-19 08:07:02 -05:00
Matthias Clasen
d7eac7a6ad Merge branch 'cssselector-alloc' into 'main'
css: Don't allocate needlessly while processing selectors

See merge request GNOME/gtk!6584
2023-11-19 12:46:57 +00:00
Matthias Clasen
52dbb3f372 css: Don't allocate needlessly while processing selectors
The recursive subdivide_info function works by soring the
selector infos it gets into 2 (or 3) buckets: exact matches,
matches, and remaining. Then it recurses on the matches and
remaining buckets. This can be done without allocating extra
arrays, by sorting the given array in the right way.

This needs some serious testing.

Fixes: #6583
2023-11-18 18:12:10 -05:00
Piotr Drąg
7dc38ca12f Update Polish translation 2023-11-18 17:15:18 +01:00
Matthias Clasen
e858924d03 Merge branch 'matthiasc/for-main' into 'main'
inspector: Update the logging tab

See merge request GNOME/gtk!6581
2023-11-18 15:26:33 +00:00
Matthias Clasen
852aab1576 inspector: Update the logging tab
There's two new values here, Dmabuf and Offload.
2023-11-18 09:54:43 -05:00
Matthias Clasen
5eb42815ed Merge branch 'subsurface-aboveness' into 'main'
offload: Keep was-raised for each subsurface

Closes #6214

See merge request GNOME/gtk!6580
2023-11-18 13:42:27 +00:00
Luca Bacci
0b853f62ed Merge branch '6203_gdk_win32_precalculate_keymap' into 'main'
GdkWin32: precalculate keymap at display opening

Closes #6203

See merge request GNOME/gtk!6566
2023-11-18 13:24:21 +00:00
Matthias Clasen
fb969f5431 offload: Raise all subsurfaces that can be
If two subsurfaces don't overlap and aren't otherwise obstructed,
we can just raise them  both.

Tests included.
2023-11-18 08:19:43 -05:00
Matthias Clasen
ef6ed31853 offload: Drop unused api 2023-11-18 08:19:43 -05:00
Matthias Clasen
c57245b73c diff: Take above-ness into account
We need to include the full area if a subsurface
above-ness changes, since we only punch holes if
it is above.

Fixes: #6214
2023-11-18 08:19:43 -05:00
Matthias Clasen
f9fd78b67e offload: Keep was-raised for each subsurface
We need this information for proper diffing.
2023-11-18 08:19:43 -05:00
Matthias Clasen
00a63a9fcf offload tests: Fix the simple test
This was expecting the wrong 'above'. Oops.
2023-11-18 08:19:43 -05:00
Matthias Clasen
b4ae2377b3 offload tests: Make --verbose work
When passing a directory via G_TEST_SRCDIR, still pay attention
to --verbose, and print out each file thats tests. This lets us
quickly pin down which test fails.
2023-11-18 08:19:43 -05:00
Matthias Clasen
392977d670 offload tests: fix output 2023-11-18 08:18:29 -05:00
Matthias Clasen
5a29e2704c Merge branch 'dmabuf-separate-alpha-formats' into 'main'
dmabuf: Add support for separate alpha formats

See merge request GNOME/gtk!6571
2023-11-18 07:41:44 +00:00
Matthias Clasen
ec6c52680e Merge branch 'michaelweghorn/a11y_align_paragraph_super_role_with_aria' into 'main'
a11y: Align paragraph's super role with ARIA

See merge request GNOME/gtk!6579
2023-11-17 12:02:53 +00:00
Sveinn í Felli
d850161b2f Update Icelandic translation
(cherry picked from commit e608a18043)
2023-11-17 10:36:10 +00:00
Michael Weghorn
1a3504469d a11y: Align paragraph's super role with ARIA
As the commit message in

    commit 9f078bd5c9
    Author: Michael Weghorn <m.weghorn@posteo.de>
    Date:   Mon Sep 25 10:41:42 2023 +0200

        a11y: Add paragraph role

already says, the super role of the paragraph role
in ARIA is the section role [1]. But then, that commit
accidently set the structure role for the super role,
so fix that now.

[1] https://www.w3.org/TR/wai-aria-1.2/#paragraph
2023-11-17 07:46:55 +01:00
Matthias Clasen
be0546bb39 testdmabuf: Support a separate-alpha format
This helps with verifying the support for these formats
in gdkdmabuf.c.
2023-11-16 20:54:16 -05:00
Matthias Clasen
d4a569057f Cosmetics: Typo fix 2023-11-16 20:54:15 -05:00
Matthias Clasen
c5727df568 dmabuf: Add support for separate alpha formats
Support dmabuf formats with alpha in a separate plane.

Related: #6208
2023-11-16 20:53:52 -05:00
Benjamin Otte
7406cea257 Merge branch 'wip/otte/for-main' into 'main'
wayland: Don't create a new wl_buffer if the texture didn't change

See merge request GNOME/gtk!6577
2023-11-16 23:54:57 +00:00
Benjamin Otte
de3f55fc5f testdmabuf: Use Vulkan to create dmabufs
This is somewhat hacky, but good enough for testing.

And it's definitely better than needing to chmod files owned by root.
2023-11-17 00:22:27 +01:00
Benjamin Otte
010ff81b2f wayland: Don't create a new wl_buffer if the texture didn't change
Avoids flickering in Mutter - which is probably a mutter bug.

But it also reduces traffic, so it's a good thing anyway.
2023-11-17 00:22:27 +01:00
Matthias Clasen
c94ec8b658 Merge branch 'michaelweghorn/bump_version' into 'main'
Bump version in meson.build to 4.13.4

See merge request GNOME/gtk!6574
2023-11-16 19:04:59 +00:00
Michael Weghorn
9c1ae5374d Bump version in meson.build to 4.13.4
... as commit 3a88522a19 did
for the NEWS file after the 4.13.3 release
(tag "4.13.3", commit 358cd28d09).
2023-11-16 17:02:44 +01:00
Matthias Clasen
4a018de0a1 Merge branch 'michaelweghorn/a11y_add_blockquote_role' into 'main'
a11y: Add block quote role

See merge request GNOME/gtk!6539
2023-11-16 14:25:01 +00:00
Matthias Clasen
23e50bb21d Merge branch 'main' into 'main'
Fix warnings when compiling with -pedantic

See merge request GNOME/gtk!6570
2023-11-15 23:00:41 +00:00
madmurphy
a8e3e747df Fix warnings when compiling with -pedantic 2023-11-15 23:00:41 +00:00
Matthias Clasen
7fd90853f8 Merge branch 'matthiasc/for-main' into 'main'
video: Hide controls and cursor in fullscreen

Closes #6210

See merge request GNOME/gtk!6572
2023-11-15 20:46:38 +00:00
Matthias Clasen
01aa4989f8 Merge branch 'wip/wjt/gtkgraphicsoffload-docs-typo' into 'main'
gtkgraphicsoffload: fix documentation typo

See merge request GNOME/gtk!6573
2023-11-15 20:46:15 +00:00
Will Thompson
d4fee23ff6 gtkgraphicsoffload: fix documentation typo 2023-11-15 19:45:17 +00:00
Matthias Clasen
b878949f00 video: Hide controls and cursor in fullscreen
Be a bit more aggressive about hiding the controls, and also
hide the cursor if we are paying a video and are fullscreen.

Fixes: #6210
2023-11-15 14:24:39 -05:00
Matthias Clasen
3a88522a19 Post-release version bump 2023-11-15 10:07:50 -05:00
Matthias Clasen
358cd28d09 4.13.3 2023-11-15 09:44:44 -05:00
Matthias Clasen
6eb6b0cb50 Cosmetics: typo fix 2023-11-15 06:45:52 -05:00
Matthias Clasen
c81954120a Merge branch 'fix-giodesktopappinfo-check' into 'main'
Revert "Conditional check for gdesktopappinfo header"

See merge request GNOME/gtk!6568
2023-11-15 05:13:08 +00:00
Matthias Clasen
4bdc44f4af Revert "Conditional check for gdesktopappinfo header"
This reverts commit 13b94dab10.

As pointed out in #6557, this commit is broken and causes
gio/gdesktopappinfo.h to never be found.
2023-11-14 23:45:17 -05:00
Matthias Clasen
3ab7b2d7ce Merge branch 'va-fixes-reported-by-pvs' into 'main'
Fix issues spotted by PVS-Studio

See merge request GNOME/gtk!6558
2023-11-15 00:27:08 +00:00
Matthias Clasen
429056c214 Merge branch 'wip/otte/for-mclasen' into 'main'
gl: Don't punch hole if the subsurface is above

See merge request GNOME/gtk!6567
2023-11-15 00:26:45 +00:00
Benjamin Otte
acecf519bc offload: Reject non-integer rectangles
We shouldn't just fudge with coordinates if we want accurate rendering.
2023-11-14 21:55:10 +01:00
Benjamin Otte
b2fbdcda41 subsurface: Report better error messages when rejecting textures 2023-11-14 21:54:38 +01:00
Benjamin Otte
1b08fda93e renderer: Remove offload argument from render()
It turns out it's not needed, because all relevant information for
subsurfaces is already available by querying the subsurface itself.
2023-11-14 21:54:35 +01:00
Benjamin Otte
f6b6176ec0 gl: Handle subsurfaces without GskOffload 2023-11-14 21:51:07 +01:00
Luca Bacci
2803189afd Merge branch 'gdkwin32_modernize_clipboard' into 'main'
GdkWin32: switch to new clipboard API

Closes #442

See merge request GNOME/gtk!6560
2023-11-14 20:09:55 +00:00
g.willems
ad08c1444a win32: precalculate keymap at display opening
The default keymap and keymap layouts are calculated on request.
If done once a surface is setup and listening at win32 events,
we may then enter in a recursive loop.
To avoid this, precalculate the keymap as soon as displays are open.

Fixes #6203
Closes #6203
2023-11-14 20:26:05 +01:00
Benjamin Otte
ef77a6fa73 gl: Don't punch hole if the subsurface is above
Saves some work.
2023-11-14 20:22:24 +01:00
Matthias Clasen
667f02ecd8 Merge branch 'matthiasc/for-main' into 'main'
Updates

See merge request GNOME/gtk!6562
2023-11-14 17:49:04 +00:00
Benjamin Otte
160f632668 Merge branch 'wip/otte/for-main' into 'main'
renderer: Remove priv->root_node

See merge request GNOME/gtk!6565
2023-11-14 14:43:47 +00:00
Benjamin Otte
653bf46494 offload: Refactor texture finding
It's the same code, but with way more debose debug messages.
2023-11-14 15:04:38 +01:00
Benjamin Otte
46d4c70cd7 offload: Only print one debug message
... when failing to create the wl_buffer.
2023-11-14 15:04:38 +01:00
Benjamin Otte
4920ac4a57 offload: Move a debug message
If we fail to attach a buffer, we don't want to print this.
2023-11-14 15:04:38 +01:00
Benjamin Otte
5bdc9f71fd renderer: Remove priv->root_node
It's not used anywhere.
2023-11-14 15:04:38 +01:00
Benjamin Otte
c92761b184 Merge branch 'wip/otte/for-main' into 'main'
Add a debug node for CSS outlines

See merge request GNOME/gtk!6564
2023-11-14 13:39:38 +00:00
Benjamin Otte
9185f15cd9 renderer: Add a supports_offload flag
This flag must be set when creating the class or offloading
will be disabled for this renderer.

Set that flag for the GL renderer.

Fixes the Cairo and Vulkan renderer not showing Video.
2023-11-14 13:06:05 +01:00
Benjamin Otte
efec30babb renderer: Don't crash with offload disabled 2023-11-14 13:06:05 +01:00
Benjamin Otte
190e7da317 wayland: Don't g_warning() on expected error
Print a GDK_DEBUG() message instead.
2023-11-14 13:06:05 +01:00
Benjamin Otte
28d38cd730 Add a debug node for CSS outlines
All the other CSS render operations have one, so outlines should, too.

This was found by tracking down a random border node in a rendering.
2023-11-14 13:06:05 +01:00
Michael Weghorn
d7a72493ae a11y atspi: Map GTK_ACCESSIBLE_RELATION_{COL,ROW}_INDEX_TEXT to AT-SPI
Map GTK_ACCESSIBLE_RELATION_COL_INDEX_TEXT and
GTK_ACCESSIBLE_RELATION_ROW_INDEX_TEXT to the
corresponding AT-SPI object attributes
"colindextext" and "rowindextext", as it is specified
e.g. in the Core Accessibility Mappings 1.2 for the
corresponding attributes [1] [2].

Orca makes use of these object attributes in web browsers
and since recently also for LibreOffice [3] and is
planning to use that more globally.

[1] https://www.w3.org/TR/core-aam-1.2/#ariaColIndexText
[2] https://www.w3.org/TR/core-aam-1.2/#ariaRowIndexText
[3] 3c056cd7b5
2023-11-14 12:18:47 +01:00
Benjamin Otte
7299c9baa9 Merge branch 'andyholmes/get-default-size' into 'main'
gtk: fix NULL pointer dereference

See merge request GNOME/gtk!6559
2023-11-14 11:08:53 +00:00
Andrey Kutejko
540a83327f Fix issues spotted by PVS-Studio 2023-11-14 08:56:40 +01:00
Matthias Clasen
04d41eaa66 Updates 2023-11-13 23:53:24 -05:00
Matthias Clasen
524d681496 Merge branch 'dmabuf-passthrough' into 'main'
dmabuf passthrough

Closes #6132

See merge request GNOME/gtk!6533
2023-11-14 03:20:12 +00:00
Matthias Clasen
44d977844b testsuite: Add offload tests
These tests come in two variants.

The first takes .node and .offload file, parses the node file,
and compares the resulting subsurface attachments to expected results.

The second variant takes two .node/.offload file pairs and a .diff
file, parses the node files, compares the resulting subsurface
attachments, and then diffs the nodes, comparing the resulting
area to the region in the .diff file.
2023-11-13 18:41:53 -06:00
Matthias Clasen
6259800f5a Merge branch 'matthiasc/for-main' into 'main'
gsk: Robustness fix

See merge request GNOME/gtk!6561
2023-11-13 23:36:58 +00:00
Matthias Clasen
d3a5aa5304 testdmabuf: Use GtkGraphicsOffload 2023-11-13 22:27:51 +01:00
Matthias Clasen
d32ab7544d gtk-demo: Enable offload in the video player 2023-11-13 22:27:51 +01:00
Matthias Clasen
e2e7c931c5 gtk: Use GtkGraphicsOffload in GtkVideo
Video playback is one of the main use cases for graphics offload,
so it makes a lot of sense to do it in GtkVideo.
2023-11-13 22:27:51 +01:00
Matthias Clasen
e202348380 gtk: Add GtkGraphicsOffload
This is new widget that will attempt to pass through the content
of its child via a subsurface. This is mostly meant for internal
use, but the minimal api is available.
2023-11-13 22:27:51 +01:00
Matthias Clasen
ba5403da17 gtk: Add gtk_snapshot_push_subsurface
This is currently private api.
2023-11-13 22:17:36 +01:00
Matthias Clasen
904d44074f gsk gl: Handle subsurfaces during rendering
During rendering, restack offloaded subsurfaces below the main
surface, and clear the area so they peek through. After rendering,
raise the last subsurface if we haven't drawn over it.
2023-11-13 22:17:36 +01:00
Matthias Clasen
c636baf6f5 gsk gl: Make it possible to clear a rectangle
Add a blend mode to the draw command, so it can draw transparent
black. This will be used to erase the area on top of a subsurface
when we do passthrough.
2023-11-13 22:17:36 +01:00
Matthias Clasen
b7c2528ad1 gsk: Prepare subsurface offload
Use a GskOffloadInfo to update subsurfaces (and collect info about
them). Pass that info to both the diff and the render vfuncs.
2023-11-13 22:17:36 +01:00
Matthias Clasen
48740de71a gsk: Add a subsurface mode to node diffing
Add an extra argument to pass offload info to the diffing code.
This is then used for diffing subsurface nodes differently,
depending on their offloading status.
2023-11-13 22:17:35 +01:00
Matthias Clasen
34c16b0df2 gsk: Add code to offload to subsurfaces
This code walks the node tree, finds subsurface nodes, determines
if we can offload to the subsurface, and if yes, does so. This
isn't used yet.
2023-11-13 22:17:35 +01:00
Matthias Clasen
d0a675ab01 gsk: Add subsurface nodes
Also show them in the inspector recorder, with some information.
2023-11-13 22:17:35 +01:00
Matthias Clasen
0e0bf8ed47 gsk: Add a debug flag for graphics offload
Add GSK_DEBUG=offload-disable to disable graphics offload via
attaching of dmabufs to subsurfaces. This is not used anywhere yet.
2023-11-13 22:17:35 +01:00
Matthias Clasen
00d7d4b17b wayland: Implement empty_frame in draw contexts 2023-11-13 22:17:35 +01:00
Matthias Clasen
9eef566b54 gdk: Introduce empty frames in GdkDrawContext
We need a way to commit pending subsurface changes, even when no
drawing happened for the frame. empty_frame() is that way.
2023-11-13 22:17:35 +01:00
Matthias Clasen
272168c94b inspector: Add a subsurface overlay
We have to be careful to not draw over the subsurface area with
our highlighting, otherwise this would interfere with raising
unobstructed subsurfaces.
2023-11-13 22:17:35 +01:00
Matthias Clasen
ca054bfdc9 wayland: Request frame callbacks on subsurfaces
We need this for the case when the subsurface completely covers
up the main surface. Without it, we just stop updating.
2023-11-13 22:17:35 +01:00
Matthias Clasen
59dbfb0843 wayland: Implement subsurface api
This is not used anywhere yet.
2023-11-13 22:17:35 +01:00
Matthias Clasen
223e27e7dc gdk: Add private subsurface api
Add api to allow creating subsurfaces, attaching textures to them,
and changing the stacking order.

This is just the api, there is no implementation yet.
2023-11-13 22:17:35 +01:00
Matthias Clasen
efe1415429 gdk: Add a debug flag for subsurfaces
You can now use GDK_DEBUG=offload to get debug spew about
subsurfaces and graphics offload.
2023-11-13 22:17:35 +01:00
Matthias Clasen
489723916d wayland: Get format info for dmabufs
For now, all we do with it is dump the formats if you
set GDK_DEBUG=misc. In the future, this will be used
when attaching dmabufs to subsurfaces.
2023-11-13 22:17:35 +01:00
Matthias Clasen
e8894ad383 gsk: Robustness fix
I was seeing empty regions being passed as scissor.
2023-11-13 22:17:35 +01:00
Matthias Clasen
9423d6261a gtk: Use some more inline helpers 2023-11-13 22:17:35 +01:00
Matthias Clasen
b766f92026 gsk: Use some more inline helpers 2023-11-13 22:17:35 +01:00
Matthias Clasen
a37aacf4e4 Add another inline rect helper 2023-11-13 22:17:35 +01:00
Matthias Clasen
93959ef7df gsk: Robustness fix
I was seeing empty regions being passed as scissor.
2023-11-13 22:16:07 +01:00
Matthias Clasen
209a1a69cc gtk: Use some more inline helpers 2023-11-13 22:15:57 +01:00
Matthias Clasen
982f965ea8 gsk: Use some more inline helpers 2023-11-13 22:15:45 +01:00
Matthias Clasen
f7fc90daa0 Add another inline rect helper 2023-11-13 22:15:35 +01:00
g.willems
a58424588f win32: switch to new clipboard API
This is a backport of !1143 to gtk4.

SetClipboardViewer() API is obsolete is prone to clipboard chain breaks
from other applications.
Use recommended AddClipboardFormatListener() instead.

Fixes #442
2023-11-13 21:29:48 +01:00
Andy Holmes
f8c9b3394b gtk: fix NULL pointer dereference
`gtk_window_get_default_size()` claims width/height are optional-out
arguments, but defers to `gtk_window_get_remembered_size()` which
may dereference a NULL-pointer.

Since `gtk_window_get_remembered_size()` is only called by
`gtk_window_get_default_size()`, collapse it into the latter
and perform the NULL check there.
2023-11-13 12:05:31 -08:00
Benjamin Otte
ce4d8cc6d9 Merge branch 'wip/otte/tree-indent' into 'main'
theme: Halve indentation of trees

See merge request GNOME/gtk!6553
2023-11-13 16:16:38 +00:00
Matthias Clasen
c85766ac71 Merge branch 'matthiasc/for-main' into 'main'
dmabuf: Add a debug message for format fallback

See merge request GNOME/gtk!6556
2023-11-12 12:59:22 +00:00
Matthias Clasen
b24ae31716 dmabuf: Improve consistency of debug messages
Make sure all our dmabuf debug messages are display-scoped so the
inspector doesn't trigger them, use the same formatting throughout,
and improve consistency of wording here and there.
2023-11-12 13:02:58 +01:00
Matthias Clasen
7cf805c8b3 dmabuf: Add a debug message for format fallback
This may be helpful in pinpointing why a dmabuf format behaves
unexpectedly.
2023-11-12 11:24:37 +01:00
Matthias Clasen
1f62c693cd Merge branch 'nv12-opaque' into 'main'
dmabuf: NV12 is opaque

See merge request GNOME/gtk!6555
2023-11-11 23:47:59 +00:00
Matthias Clasen
6ae9cbfe0f dmabuf: NV12 is opaque
Getting this wrong matters, since we won't offload textures in
non-opaque formats. Found by Robert Mader. At the same time,
unify the two places we have for mapping from fourcc to memory
format.
2023-11-11 23:56:01 +01:00
Benjamin Otte
7803aad872 theme: Halve indentation of trees
Deep trees quickly add so much empty space on the left, so that it gets
really hard to read after an indentation level of ~10.

By halving, we still keep the visual clarity of indenting but we can now
handle twice as many indentation levels, ie ~20.

It is what sysprof has been using, and it also feels right in the
inspector.
2023-11-11 10:34:57 +01:00
Ekaterine Papava
cc2d3fa7d6 Update Georgian translation 2023-11-09 09:41:14 +00:00
Benjamin Otte
a9e4993184 Merge branch 'wip/otte/enable-debug' into 'main'
Remove G_ENABLE_DEBUG around debug checks

See merge request GNOME/gtk!6546
2023-11-07 15:12:11 +00:00
Benjamin Otte
33703bfe01 Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Set same YUV colorspace as elsewhere

See merge request GNOME/gtk!6548
2023-11-07 05:11:10 +00:00
Benjamin Otte
7ba5cf5309 inspector: Add more info about GL
Print all the variables queryable via glGetString().

And remove them from the Windows backend.
2023-11-07 05:33:48 +01:00
Benjamin Otte
bb890f6004 inspector: Don't list unused EGL extension
We don't use that extension and I don't even know what it is about -
which is a good reason to get rid of showing it.
2023-11-07 05:12:57 +01:00
Benjamin Otte
1c7a0e7a15 inspector: Use right name for Vulkan validation layer
The name got changed a while ago, so let's reflect that.
2023-11-07 05:12:57 +01:00
Benjamin Otte
cd7e1c1387 dmabuf: Modify gdk_gl_context_import_dmabuf()
Move a bunch of code - namely the target selection - into the function.

I want to use the same code in the NGL renderer, so no need to duplicate
it.
2023-11-07 05:12:57 +01:00
Benjamin Otte
a2e1e727c5 testsuite: Make texture-scale-magnify tests have roundable numbers
Use a number that's 2^N * 255 to get floating point awesomeness combined
with uint8_t awesomeness.

Fixes rounding errors in samplers.
2023-11-07 05:12:57 +01:00
Benjamin Otte
61207f81c3 dmabuf: Set same YUV colorspace as elsewhere
We use ITU.601 full range everywhere, so ensure it's used here, too.
2023-11-07 05:12:57 +01:00
Benjamin Otte
f624586a75 testsuite: Don't skip test
The test now works without debugging as debug messages are always
available.
2023-11-05 11:16:23 +01:00
Benjamin Otte
1a93967e1f gdk: Remove debug modes in gdk_debug_parse_var()
Always support all variables.
2023-11-05 11:16:23 +01:00
Benjamin Otte
310ab7b531 Remove G_ENABLE_DEBUG around debug checks
It started out as busywork, but it does many separate things. If I could
start over, I'd take them apart into multiple commits:

1. Remove G_ENABLE_DEBUG around GDK_DEBUG_*() calls
   This is not needed at all, the calls themselves take care of it.

2. Remove G_ENABLE_DEBUG around profiling code
   This now enables profiling support in release builds.

3. Stop poking _gdk_debug_flags and use GDK_DEBUG_CHECK()
   This was old code that was never updated.

4. Make !G_ENABLE_DEBUG turn off GDK_DEBUG_CHECK()
   The code used to
     #define GDK_DEBUG_CHECK(...) false
     #define GDK_DEBUG(...)
   which would compile away all the code inside those macros. This
   means a lot of variable definitions and debug utility functions
   would suddenly no longer be used and cause compiler errors.
2023-11-05 11:16:23 +01:00
Benjamin Otte
d55801c8ba debug: Turn gdk_debug_message() into a function
1. MSVC can't deal with the nonstandard ##__VA_ARGS__

2. It allows setting a breakpoint on it.
2023-11-05 10:21:54 +01:00
Matthias Clasen
b1809bfd88 Merge branch 'matthiasc/for-main' into 'main'
print dialog: Improve local fallback

See merge request GNOME/gtk!6547
2023-11-04 23:20:53 +00:00
Matthias Clasen
deb8a35ea0 print dialog: Improve local fallback
We need to set embed-page-setup for the paper size and orientation
combos to work.
2023-11-05 01:00:39 +02:00
Jordi Mas i Hernandez
c5ce24c82c Update Catalan translation 2023-11-04 18:28:38 +00:00
Artur S0
54815e4771 Update Russian translation 2023-11-04 02:09:09 +00:00
Matthias Clasen
5a99790a87 Merge branch 'examples-gtk-widget-show' into 'main'
docs: Replace deprecated gtk_widget_show with gtk_widget_set_visible

See merge request GNOME/gtk!6538
2023-11-03 15:29:39 +00:00
Matthias Clasen
8aa7174bfb Merge branch 'faster-fps-overlay' into 'main'
inspector: Speed up the fps overlay

See merge request GNOME/gtk!6544
2023-11-01 22:44:44 +00:00
Benjamin Otte
9df5e3cbd6 inspector: Replace "no glyph" with space glyph
This makes right-aligning the text work again.
2023-11-01 21:57:56 +01:00
Benjamin Otte
8b5194c016 inspector: Use the right font for the fps overlay
Initialize the font only when we have a widget that provides it. That
way we don't pick a terrible default font, but the widget's preferred
one.
2023-11-01 21:32:55 +01:00
Matthias Clasen
9a63172cf5 Some minor fpsoverlay improvements
Avoid some allocations.
2023-11-01 14:45:57 -04:00
Matthias Clasen
3ade9ae184 inspector: Speed up the fps overlay
Do less work!
2023-11-01 14:00:42 -04:00
Benjamin Otte
76349ff6e5 Merge branch 'wip/otte/for-main' into 'main'
testsuite: Add render test for texture placement

See merge request GNOME/gtk!6543
2023-11-01 14:36:07 +00:00
Benjamin Otte
dd530b45e2 gstmediafile: Handle premultiplied alpha
1. Check GStreamer caps for premultiplied alpha and select
   GdkMemoryFormat accordingly

2. Set a GdkMemoryFormat for GL textures

Fixes the video in widget-factory being treated as premultiplied when it
isn't.
2023-11-01 08:01:27 +01:00
Benjamin Otte
00ce51472c testsuite: Add render test for texture placement
Make sure that texture nodes sample from the texture properly.
2023-11-01 08:01:27 +01:00
Matthias Clasen
b6bcbeae23 Merge branch 'matthiasc/for-main' into 'main'
inspector: Show more EGL extensions

See merge request GNOME/gtk!6542
2023-10-31 23:12:54 +00:00
Robert Ancell
cf86cc1184 docs: Use gtk_window_present instead of gtk_widget_set_visible 2023-11-01 10:54:33 +13:00
Matthias Clasen
b503b60a49 inspector: Show more EGL extensions
We care about these now.
2023-10-31 17:53:25 -04:00
Matthias Clasen
5850055b68 Merge branch 'progressbar_overflow_fix' into 'main'
GtkProgressBar: Fix: progress can overflow trough

See merge request GNOME/gtk!6445
2023-10-31 11:22:32 +00:00
Matthias Clasen
b224e66a9f Merge branch 'scale_overflow_fix' into 'main'
GtkScale: Fix: highlight can overflow trough

Closes #5751

See merge request GNOME/gtk!6444
2023-10-31 11:22:02 +00:00
Michael Weghorn
bbb0150383 a11y: Add block quote role
Add a new GTK_ACCESSIBLE_ROLE_BLOCK_QUOTE role
for block quotes/block quotations.

ARIA has a corresponding "blockquote" role as well. [1]

The role is used e.g. in document editors
like LibreOffice or web browsers like Firefox.

According to the ARIA spec (§ 5.2.8.4, [2]), the
blockquote role is among those that can be named by
the author, and the superclass role is section. [1]

Related change for LibreOffice making use of the new
role: [3]

[1] https://www.w3.org/TR/wai-aria-1.2/#blockquote
[2] https://www.w3.org/TR/wai-aria-1.2/#namefromauthor
[3] https://gerrit.libreoffice.org/c/core/+/158685
2023-10-31 09:33:06 +01:00
Robert Ancell
8aef682079 docs: Replace deprecated gtk_widget_show with gtk_widget_set_visible 2023-10-31 13:27:26 +13:00
Benjamin Otte
fe4b7a5159 Merge branch 'wip/otte/for-main' into 'main'
rendernode-tool: Add --undecorated to show command

See merge request GNOME/gtk!6537
2023-10-31 00:23:18 +00:00
Benjamin Otte
7ba4ba05e1 gl: Fix padding in icon library
The previous code would not pad the left side with the left column of
pixels but with the top row.

Test attached.
2023-10-31 00:50:00 +01:00
Benjamin Otte
85e1088171 gsk: Fix texture-scale node Cairo drawing
The code was interpreting x/y coordinates wrong sometimes and causing
things to not be drawn at the correct offset.

Testcase included.
2023-10-31 00:36:27 +01:00
Benjamin Otte
c1ed034367 rendernode: Use an exisiting function instead of reimplementing it 2023-10-31 00:36:27 +01:00
Benjamin Otte
cc3e25b163 testsuite: Be more resistant against rounding errors
Make a test use numbers that are less likely to cause rounding
issues in GPUs (read: use powers of 2).
2023-10-31 00:36:27 +01:00
Benjamin Otte
bdb3e345c8 testsuite: Add test for scaling texture-scale node
Finally figured out a way to test that a texture-scale node using
NEAREST that is upscaled using a transform node doesn't use NEAREST but
LINEAR.
2023-10-31 00:36:27 +01:00
Benjamin Otte
a30e9dcfeb testsuite: Add a test for nearest vs linear scales 2023-10-31 00:36:27 +01:00
Benjamin Otte
76007c4d09 rendernode-tool: Add --undecorated to show command
This is to get exactly just the rendernode drawn when testing, and not
any extra drawing code.
2023-10-31 00:36:27 +01:00
Matthias Clasen
020ef51cb0 Merge branch 'matthiasc/for-main' into 'main'
Revert "glcontext: Better debug spew"

See merge request GNOME/gtk!6536
2023-10-29 19:04:26 +00:00
Matthias Clasen
1914adc344 dmabuf: Don't check for image storage
I was wrong about this extension, and it isn't even a GL extension
to begin with, so revert all this.
2023-10-29 14:45:20 -04:00
Matthias Clasen
6e236b9459 Revert "gl context: Check for more GL extensions"
This reverts commit b8b5835fc6.
2023-10-29 14:44:46 -04:00
Matthias Clasen
11715760f9 Revert "glcontext: Better debug spew"
This reverts commit 30e14f73fa.
2023-10-29 14:44:29 -04:00
Matthias Clasen
f19c08ffda Merge branch 'add-view-grid-symbolic-icon' into 'main'
icons: Add view-grid-symbolic

Closes #6184

See merge request GNOME/gtk!6534
2023-10-29 15:32:27 +00:00
Kleis Auke Wolthuizen
d0f76b6ab4 widget-factory: Remove insert-image icon
This icon is already present in the hicolor icon theme.
2023-10-28 20:25:53 +02:00
Kleis Auke Wolthuizen
4c7206343a widget-factory: Remove view-grid-symbolic icon
No longer needed as it's included in the hicolor icon theme now.
2023-10-28 20:25:53 +02:00
Kleis Auke Wolthuizen
dfae2cb3a5 icons: Add view-grid-symbolic
This showed up as missing icon in the file chooser when used with
the hicolor icon theme.

Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6184
2023-10-28 20:05:27 +02:00
Matthias Clasen
de74d38039 Merge branch 'improve-msvc-force-include' into 'main'
MSVC builds: Improve build process (was: MSVC builds: Always enable items from msvc_recommended_pragmas.h)

See merge request GNOME/gtk!6114
2023-10-27 22:11:06 +00:00
Matthias Clasen
fb20542fcc Merge branch 'fix_name_computation' into 'main'
a11y: When using rule 2.E for computing accessible name, use it only if appropriate

See merge request GNOME/gtk!6495
2023-10-27 17:32:14 +00:00
Lukáš Tyrychtr
a26e289d5c Adjust tests 2023-10-26 09:44:59 +02:00
Lukáš Tyrychtr
892d3b9530 a11y: When using rule 2.E for computing accessible name, use it only if appropriate
We were using it in all cases, so, we were using it to compute descriptions,
and also for non-embedded controls. That was overriding descriptions
set, for example, in Gnome settings, and was causing the value of spinboxes
to be read multiple times.
2023-10-26 09:40:30 +02:00
Chun-wei Fan
8477dcfeff builds: Require -Zc:preprocessor for Visual Studio debug builds
This flag is actually required for the debugging code to successfully build,
so check that it is really there for debug-enabled Visual Studio builds.
2023-10-26 10:40:17 +08:00
Chun-wei Fan
25835afd9c MSVC Builds: Don't enable -utf-8 explicitly
We already require a Meson release that enables -utf-8 by default, so we don't
really need to explicitly enable it here.
2023-10-26 10:40:17 +08:00
Matthias Clasen
06dda4e12b Merge branch 'memory-format-swizzle-check' into 'main'
gl: Check all swizzle values

See merge request GNOME/gtk!6524
2023-10-26 02:38:35 +00:00
Chun-wei Fan
26edfe6d18 build: Add msvc_recommended_pragmas.h
We really always want to force-include msvc_recommended_pragmas.h to check for
things at compile time so that we can avoid stuff like missing includes or
attempting to return a value in a function that is supposed to have a
void-return-type.

The current problem is that, as indicated in the Visual Studio CI job, that we
couldn't locate msvc_recommended_pragmas.h during the build if GLib is built
as a subproject, and/or when msvc_recommended_pragmas.h is not in the paths
indicated by %INCLUDE%, meaning that the aforementioned issues would not be
caught by CI, which will then break builds on Visual Studio for people when
msvc_recommended_pragmas.h is found during their builds.

It would also be nice to be quiet from the warnings that we can really
disregard anyways.

So, add a copy of msvc_recommended_pragmas.h from GLib and update the build
files to look for it in build-aux/msvc, so that it can always be used during
the build, especially by the CI.
2023-10-26 10:38:14 +08:00
Matthias Clasen
4a749aee6e Fix swizzle values for some memory formats
For opaque formats with 3 channels, we should use the default
GL_ALPHA, but for opaque formats with an ignored 4th channel,
we must use GL_ONE.
2023-10-25 21:39:52 -04:00
Matthias Clasen
99a8417142 Merge branch 'add-bn-hi-po-translated' into 'main'
translated bn.po and hi.po

See merge request GNOME/gtk!6530
2023-10-25 16:34:19 +00:00
Matthias Clasen
20e2075a10 Merge branch 'allow-implicit-modifiers' into 'main'
Allow implicit modifiers

See merge request GNOME/gtk!6529
2023-10-25 02:52:49 +00:00
Matthias Clasen
d8c649b57f Merge branch 'matthiasc/for-main' into 'main'
dmabuf: No mipmaps for dmabuf textures

See merge request GNOME/gtk!6531
2023-10-25 02:43:19 +00:00
Matthias Clasen
bb2b8bf2c3 dmabuf: Refine the handling of implicit modifiers
If all formats with a given fourcc are external, treat the
fourcc with implicit modifiers as external too, following a
sugestion by Benjamin Otte.
2023-10-24 22:33:45 -04:00
Matthias Clasen
eb048c91be dmabuf: Allow implicit modifiers
Remove all the roadblocks we've put up to keep implicit modifiers
out. Our importing code already handles them as a signal that says
'No modifiers, please!'. Now we just hope for the best and pass
things along.

This is necessary since some drivers won't produce any explicit
modifiers.
2023-10-24 22:33:45 -04:00
Matthias Clasen
358779dfb2 dmabuf: No mipmaps for dmabuf textures
Calling glGenerateMipmap on imported dmabufs does not work, so
don't do it.
2023-10-24 22:03:31 -04:00
Matthias Clasen
8f90ddb906 dmabuf: Cache egl formats
Only call eglQueryDmaBufModifiersEXT once, and reuse the results.
2023-10-24 21:53:09 -04:00
Matthias Clasen
ed54aa8acf Merge branch 'matthiasc/for-main' into 'main'
Fix annotations

See merge request GNOME/gtk!6522
2023-10-24 15:04:16 +00:00
Matthias Clasen
a90ffb117f docs: Some additions
Add a link to the kernel docs about dmabufs.
2023-10-24 10:50:46 -04:00
Matthias Clasen
29681717ed Fix annotations
It is always org.gtk.Property, even if we are in gdk.
2023-10-24 07:16:42 -04:00
sudip
e0cd2b756f translated bn.po and hi.po
Resolves:https://gitlab.gnome.org/GNOME/gtk/-/issues/6164
2023-10-24 16:20:24 +05:30
Matthias Clasen
2c85060b5f Merge branch 'msvc-for-main' into 'main'
Few small fixes for Visual Studio builds

See merge request GNOME/gtk!6521
2023-10-24 10:44:22 +00:00
Chun-wei Fan
864c5b4608 testsuite: Disable dmabuftexture test on Windows
It's not meaningful there.
2023-10-24 14:08:16 +08:00
Chun-wei Fan
1ab501649e gsk/gskcurve.c: Avoid returning value in void-retype function
This is considered a compiler error with later GLib releases with Visual Studio
builds, so avoid that.
2023-10-24 13:18:26 +08:00
Benjamin Otte
2d874e601c Merge branch 'wip/otte/for-main' into 'main'
gl: Remove optimization that does the wrong thing

See merge request GNOME/gtk!6528
2023-10-24 02:51:02 +00:00
Benjamin Otte
c9b83dfa1d testsuite: Add a test for texture-scale filters
Check that the right filter is chosen and that that filter is
implemented correctly.

The test is disabled for Cairo because Cairo (or rather Pixman)
doesn't follow the filtering specifications for GL/Vulkan and in
particular the nearest filter picks a different pixel.
2023-10-24 01:41:25 +02:00
Benjamin Otte
dd7a38069f gl: Remove optimization that does the wrong thing
Drawing a texture-scale node like a texture node when the filter is set
to "linear" doesn't work, because the texture node switches to
trilinear when mipmaps are available.
2023-10-24 01:37:38 +02:00
Benjamin Otte
51a181af7a Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Seek back to the start

See merge request GNOME/gtk!6526
2023-10-23 19:57:21 +00:00
Benjamin Otte
8fcd9bc0c4 gl: Make sure render_texture() sets the right format for high depth
Setting the format got lost when converting this coe to the texture
builder, because that codepaths avods the texture sniffing and always
uses RGBA8.
2023-10-23 21:22:17 +02:00
Benjamin Otte
e2edf693f5 gdk: Make float32 report its true depth
I have no idea how this is the only value that is wrong.
2023-10-23 21:22:17 +02:00
Benjamin Otte
323300e92a dmabuf: Seek back to the start
https://docs.kernel.org/driver-api/dma-buf.html recommends doing that,
so we do that.
2023-10-23 17:57:57 +02:00
Benjamin Otte
e688be1cff gdk: Add some debug messages around dmabuf initialization 2023-10-23 17:57:57 +02:00
Guillaume Bernard
611d5cf844 Update French translation
(cherry picked from commit 3b8c1189f4)
2023-10-23 15:22:29 +00:00
Matthias Clasen
677e78bdce gl: Check all swizzle values
There is no reason not check the alpha swizzle for being different
from its default value. I am thinking about implementing RGBx
upload with a swizzle of rgb1, and that would break here.
2023-10-23 07:55:39 -04:00
Matthias Clasen
51cb1aeb4e Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!6519
2023-10-23 04:11:04 +00:00
Matthias Clasen
625eb508e8 dmabuftexturebuilder: Fix doc formatting 2023-10-22 23:24:46 -04:00
Matthias Clasen
2718e1715d display: Add details to the docs 2023-10-22 23:24:27 -04:00
Matthias Clasen
6ddcad6b33 dmabuf: Update a comment 2023-10-22 23:14:07 -04:00
Matthias Clasen
0c23997f70 Merge branch 'matthiasc/for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!6518
2023-10-23 03:13:41 +00:00
Matthias Clasen
4d1ef63009 gsk: Ensure dmabuf formats are initialized
We just poking at display members here, there is no guarantee that
dmabuf formats have been initialized. So do it explicitly.

This prevents a crash in the inspector when viewing a recorded frame
containing a dmabuf texture, since the inspector uses a separate
display connection.
2023-10-22 22:48:18 -04:00
Matthias Clasen
30e14f73fa glcontext: Better debug spew
Print out all the extensions we checked.
2023-10-22 22:41:53 -04:00
Matthias Clasen
39e205aa78 dmabuf: Don't print unsupported formats
We were confusingly printing "supported format" for dmabuf formats
that we end up not adding to our list of supported formats. Don't
do that, it is confusing. At the same time, we shuold print out
the linear formats we support via mmap.
2023-10-22 22:29:44 -04:00
Matthias Clasen
f0ec1660c1 Make testdmabuf fall back to memfd
If we can't open /dev/dma_heap/system, fall back to using memfd_create.
It does not let us make a 'proper' dmabuf, but it is good enough to
test our handling of linear buffers in various formats.
2023-10-22 22:18:30 -04:00
Matthias Clasen
79f98f3a13 Cosmetics
Typo fix.
2023-10-22 22:18:30 -04:00
Benjamin Otte
5f0557027d Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Add NV16, NV61, NV24 and NV42

See merge request GNOME/gtk!6517
2023-10-23 01:49:30 +00:00
Benjamin Otte
a579e3bc6d build: Fix up header includes
These weren't fixed in the merge request in
  https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6489
to the change from
  https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6514
2023-10-23 03:12:09 +02:00
Benjamin Otte
8f70f4b85e dmabuf: Add support for 3 plane YUV formats 2023-10-23 02:54:23 +02:00
Benjamin Otte
911198cddd dmabuf: Add NV16, NV61, NV24 and NV42
and sanitize them and NV21.
2023-10-23 02:54:23 +02:00
Matthias Clasen
ca5247a995 Post-release version bump 2023-10-22 19:04:54 -04:00
Matthias Clasen
004a881521 4.13.2 2023-10-22 18:58:50 -04:00
Matthias Clasen
65993ed0e0 Merge branch 'dont-claim-external-formats' into 'main'
dmabuf: We don't support external formats on GL

See merge request GNOME/gtk!6516
2023-10-22 22:40:48 +00:00
Matthias Clasen
a4d0a5bda5 dmabuf: We don't support external formats on GL
Filter out external-only formats unless we are on GLES.
2023-10-22 17:54:18 -04:00
Matthias Clasen
33bc276639 Merge branch 'dmabuf-texture-gl-downloader' into 'main'
dmabuf: Add an EGL downloader

See merge request GNOME/gtk!6489
2023-10-22 21:13:58 +00:00
Matthias Clasen
06822581f7 gsk: Use external textures
When we are running under GLES, we can use GL_TEXTURE_EXTERNAL_OES
to support YUV formats.

Since we don't want to deal with the combinatorial explosion of
compiling all our shaders with all combinations  of sampler2D vs
samplerExternalOES for all their textures, we copy the external
textures to a regular texture before using them.
2023-10-22 16:50:43 -04:00
Matthias Clasen
976143fbe9 gsk: Add a shader for external textures
This shader uses samplerExternalOES to sample an external texture
and blit it into a 'normal' texture. It only works in GLES, but
we won't use it outside of GLES.
2023-10-22 16:42:17 -04:00
Matthias Clasen
9fd4feef0c gsk: Use some GLES extensions
Allow our shaders to use samplerExternalOES, by declaring
that we use the relevant extension. Unfortunately, this
only works for gles, and requires different extensions for
gles2 and gles3. Yay
2023-10-22 16:42:17 -04:00
Matthias Clasen
5eed13bd07 gsk: Define GSK_GLES3 if we have gles3
The compiler defines GSK_GLES only for gles2. Add another define
for gles3, so we can differentiate where we need to.

This took a week to find!
2023-10-22 16:42:17 -04:00
Matthias Clasen
d02d45dd8d gsk: Allow shaders without clip variants
Add a GSK_GL_DEFINE_PROGRAM_NO_CLIP, which is like
GSK_GL_DEFINE_PROGRAM but compiles the shader just once,
with NO_CLIP defined.

This will be used in the future for shaders that do
texture conversion.
2023-10-22 16:42:17 -04:00
Matthias Clasen
13d0e311b7 gsk: Prepare for external textures
Prepare the plumbing in the GL renderer for textures that use
target GL_TEXTURE_EXTERNAL_OES. These need to use a special sampler,
so make sure our sampler machinery does not run over it.
2023-10-22 16:42:17 -04:00
Matthias Clasen
52254f755f gsk: Support dmabuf textures
Defer handling of dmabuf textures to the driver,
and add the necessary code in load_texture.
2023-10-22 16:42:17 -04:00
Matthias Clasen
494154beb6 dmabuf: Add an EGL downloader
Add an implementation of GdkDmabufDownloader that uses
gsk_renderer_render_texture + GL texture download.

Since gsk isn't threadsafe, we do the download in the main thread,
taking care to not disturb the current GL context of whatever is
going on there at the time.

And since gsk renderers are expensive to create, we cache it
in the display.

Note that gsk does not yet have any special support for
dmabuf textures, so for now, they will always get downloaded
and then reuploaded as GL textures.
2023-10-22 16:42:17 -04:00
Matthias Clasen
adde188eca gsk: Add a helper for converting textures
This is a simple helper that feed a GdkTexture
through a renderer and returns the resulting
texture. This will be used to convert dmabuf
textures to 'native' textures.
2023-10-22 16:39:24 -04:00
Matthias Clasen
8fb0ab2b43 gl context: Add private dmabuf API
Add API to import a dmabuf into a texture,
and to export a texture to a dmabuf.

All this is implemented using the relevant
EGL and GL extensions.
2023-10-22 16:39:24 -04:00
Matthias Clasen
b8b5835fc6 gl context: Check for more GL extensions
These will be used in future commits.
2023-10-22 16:39:24 -04:00
Matthias Clasen
463307655c display: Check for more EGL extensions
We are going to rely on this in future commits.
2023-10-22 16:39:24 -04:00
Matthias Clasen
d17d8e04a6 Add a few dmabuf texture tests
Test some basic import and export of dmabufs.

For now, put the test into the 'failing' suite,
since it does not work in CI, and also fails
on AMD hw.
2023-10-22 16:39:24 -04:00
Matthias Clasen
d8d1dfd8f3 Merge branch 'matthiasc/for-main' into 'main'
gsk: Restore bigendian support

See merge request GNOME/gtk!6515
2023-10-22 20:34:30 +00:00
Matthias Clasen
f581280811 gsk: Restore bigendian support
Restore the bigendian support that was lost in b0e26873f6,
by just not using GL_BGRA with GLES on bigendian. Should be a
very rare combination, but still.
2023-10-22 16:19:31 -04:00
Benjamin Otte
3a9aea44df Merge branch 'wip/otte/for-main' into 'main'
build: Change where we get drm_fourcc.h from

See merge request GNOME/gtk!6514
2023-10-22 19:33:27 +00:00
Benjamin Otte
e05764806a build: Change where we get drm_fourcc.h from
The canonical source for userspace is libdrm, not kernel headers.

Fixes compilation on Arch Linux.
2023-10-22 20:40:20 +02:00
Benjamin Otte
5ca65f04fe Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Allow downloaders to fail initialization

See merge request GNOME/gtk!6513
2023-10-22 17:19:16 +00:00
Benjamin Otte
32ba1e389c build: Check for drm/drm_fourcc.h too
It's part of the kernel headers package so I did not check for libdrm.

As a side effect I checked the #define to HAVE_DMABUF.
2023-10-22 17:27:11 +02:00
Benjamin Otte
beb9e0c906 dmabuf: Add gdk_dmabuf_is_disjoint()
No users yet, but Vulkan will use this later. So have it available
already.
2023-10-22 17:03:15 +02:00
Benjamin Otte
98f02f6221 dmabuf: Reject the INVALID modifier
Trying to use it is a programming error, applications should have code
that uses real modifiers.

Also add a check to the formatsbuilder so our code doesn't include the
invalid modifier by accident.

We don't really know how to deal with it, so better force applications
to figure out what to do.
2023-10-22 17:03:15 +02:00
Benjamin Otte
13848969f4 dmabuf: Allow downloaders to fail initialization
When adding the formats of a downloader, allow them to return FALSE to
mean "This method is not supported", which is a useful way to opt out
when checking GL or Vulkan extensions and finding out that the desired
one isn't supported.
2023-10-22 17:03:13 +02:00
Matthias Clasen
0817dfe67f Merge branch 'matthiasc/for-main' into 'main'
dmabuf: Give downloaders a name

See merge request GNOME/gtk!6511
2023-10-21 23:42:10 +00:00
Matthias Clasen
9e3f537a15 dmabuf: Give downloaders a name
Add name to the downloader struct, and add it
to the debug spew for newly created dmabuf
textures.
2023-10-21 19:19:21 -04:00
Matthias Clasen
612e0e29f9 Merge branch 'matthiasc/for-main' into 'main'
testdmabuf: Add a --download-to option

See merge request GNOME/gtk!6510
2023-10-21 21:39:36 +00:00
Matthias Clasen
e1cbc96b8c testdmabuf: Add a --download-to option
The next option we add will tilt the balance
towards GOptionContext.
2023-10-21 17:26:53 -04:00
Matthias Clasen
410240fe7b Merge branch 'matthiasc/for-main' into 'main'
Cosmetics

See merge request GNOME/gtk!6509
2023-10-21 20:34:36 +00:00
Matthias Clasen
73cf3a92f9 cosmetics 2023-10-21 16:10:09 -04:00
Matthias Clasen
dd15122ccb dmabuf: Add some debug spew 2023-10-21 14:44:28 -04:00
Benjamin Otte
5299f1384f Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Require valid fds for all planes

See merge request GNOME/gtk!6508
2023-10-21 15:15:57 +00:00
Benjamin Otte
58a0e4ffaa testdmabuf: Add --disjoint and --undecorated
The code now by default puts all planes into the same fd - like
v4l does, too.

The old behavior of one fd per plane can be enabled via --disjoint.

Also, am --undecorated option has been added so that the window
isn't decorated and all that the renderer has to do is display the
dmabuf.
This is useful when debugging just the dmabuf rendering.
2023-10-21 17:02:05 +02:00
Benjamin Otte
7ab9056c11 testdmabuf: Fix NV12
The code was computing the wrong size.
2023-10-21 16:42:16 +02:00
Benjamin Otte
2d9fbb16bc testdmabuf: Use the actual pixel
The previous code would subsample the luma channel, too. Don't do that.
2023-10-21 16:42:15 +02:00
Benjamin Otte
cbfd8542c6 dmabuf: Require valid fds for all planes
This seems to be what everyone does, so we should do it, too.

Previously it was assumed that an fd of -1 would mean reusing the
previous fd with a different offset, but that seems to be uncommon.
2023-10-21 16:42:15 +02:00
Piotr Drąg
7679504134 Update POTFILES.in 2023-10-21 14:14:02 +02:00
Sabri Ünal
446d461ad2 Update Turkish translation 2023-10-21 09:16:05 +00:00
Matthias Clasen
5b6fcfe8c9 Merge branch 'misc-dmabuf-fixes' into 'main'
Make a test app with dma heaps

See merge request GNOME/gtk!6507
2023-10-21 02:06:20 +00:00
Matthias Clasen
59ce7ab222 dmabuf: Improve the debug message
Printing the format can only help.
2023-10-20 20:03:27 -04:00
Matthias Clasen
0992837b08 dmabuf: Fix the mmap logic
We want to unmap the buffers we mapped in
the first loop, so pass the right pointers
here.
2023-10-20 20:03:11 -04:00
Matthias Clasen
aca02916ad dmabuf: Fix NV12 import
We were not seeking in the right fd,
so our sizes were wrong, and crashes
happened.
2023-10-20 19:53:33 -04:00
Matthias Clasen
98e883f9b4 Make a test app with dma heaps
This uses the dma-heap kernel api to create a dma-buf
and use it for a GdkDmabufTexture. It supports a few
formats to test how well GL conversion of YUV works.

The YUV code is adapted from weston tests.
2023-10-20 19:53:33 -04:00
Matthias Clasen
2c66aa0c15 Merge branch 'matthiasc/for-main' into 'main'
dmabuf: Fix format mapping for RGB formats

See merge request GNOME/gtk!6506
2023-10-20 23:44:52 +00:00
Matthias Clasen
8843c0d504 dmabuf: Fix format mapping for RGB formats
The channel order was reversed.
2023-10-20 19:22:00 -04:00
Matthias Clasen
8858f1c9ec Merge branch 'xrgb-formats' into 'main'
Add XRGB memory formats

Closes #6172

See merge request GNOME/gtk!6505
2023-10-20 22:34:19 +00:00
Matthias Clasen
a1c5c20e2c dmabuf: Add xrgb formats 2023-10-20 18:14:45 -04:00
Matthias Clasen
1da674423d vulkan: Add xrgb formats
For now, we just fall back to RGB.
2023-10-20 18:14:45 -04:00
Matthias Clasen
10250a0a6a Add XRGB memory formats
These are not uncommon in dmabufs,
and supporting them is easy.

Fixes: #6172
2023-10-20 17:58:06 -04:00
Matthias Clasen
c0a2f9fbc3 Merge branch 'missing-argb-format' into 'main'
Add GDK_MEMORY_A8B8G8R8_PREMULTIPLIED

See merge request GNOME/gtk!6504
2023-10-20 21:12:43 +00:00
Matthias Clasen
bd974b08b3 Add GDK_MEMORY_A8B8G8R8_PREMULTIPLIED
We did have 4 ordering variations of ARGB straight,
but only 3 premultiplied. Add the missing one.

Update all the places where we switch over memory formats.
2023-10-20 16:42:40 -04:00
Matthias Clasen
d289c0d4f1 Merge branch 'matthiasc/for-main' into 'main'
rendernodeparser: Use private memoryformat api

See merge request GNOME/gtk!6502
2023-10-20 14:00:55 +00:00
Matthias Clasen
f4722289f7 Merge branch 'more-bgra' into 'main'
gsk: Use has_bgra in more places

See merge request GNOME/gtk!6500
2023-10-20 13:43:51 +00:00
Benjamin Otte
389af3591c Merge branch 'wip/otte/for-main' into 'main'
dmabuf refactoring

See merge request GNOME/gtk!6503
2023-10-20 12:48:53 +00:00
Benjamin Otte
008d9e5327 vulkan: Actually check for GDK_DEBUG=vulkan-disable
The dmabuf code would happily init Vulkan even if it was told we don't
want it.
2023-10-20 14:26:59 +02:00
Benjamin Otte
09723d79c6 dmabuf: Support YUYV and friends
Same as the NV12 support, but necessary for the poor people stuck on
Intel laptops.
2023-10-20 14:26:59 +02:00
Benjamin Otte
4586af5876 dmabuf: Add support for NV12 and NV21
This is as-good-as-necessary and doesn't do any fancy colorspace magic
or chroma whatevering.

That's a task for the future.
2023-10-20 14:26:59 +02:00
Benjamin Otte
193d9cd31a dmabuf: Improve download
1. Split out the download function from the mmap'ing of the plane(s)

2. Make the code mmap() all the planes

3. Determine size using lseek() as documented by libdrm, instead of
   trying to guess it from the format.

4. Fix some bugs, like switcheroos of width and height
2023-10-20 14:26:59 +02:00
Benjamin Otte
f29303dea7 dmabuf: Allocate the intermediate buffer properly.
We should use the stride from the buffer's format, not from the dmabuf.
2023-10-20 14:26:59 +02:00
Benjamin Otte
4e47d0d71e dmabuf: Ensure the number of planes is sane
Make it a programming error when setting planes to 0 and throw a GError
if somebody uses more than GDK_DMABUF_MAX_PLANES.
2023-10-20 14:26:59 +02:00
Benjamin Otte
dd8c6e9f51 dmabuf: Add gdk_dmabuf_sanitize()
Tries to sanitize the dmabuf to conform to the values expected
by Vulkan/EGL which should also be the values expected by
Wayland compositors

We put these sanitized values into the GdkDmabufTexture, by
sanitizing the input from GdkDmabufTextureBuilder, which are
controlled by the callers.

Things we do here:

1. Disallow any dmabuf format that we do not know.

1. Treat the INVALID modifier the same as LINEAR.

2. Ignore all other modifiers.

3. Try and fix various inconsistencies between V4L and Mesa,
   like NV12.

*** WARNING ***

This function is not absolutely perfect, you do not have a
perfect dmabuf afterwards.

In particular, it doesn't check sizes.
2023-10-20 13:58:22 +02:00
Matthias Clasen
65676150c4 rendernodeparser: Use private memoryformat api
No need to open-code a list of all formats here,
we can just use the private depth api to do this
much simpler.
2023-10-20 07:41:53 -04:00
Matthias Clasen
b0e26873f6 gsk: Use has_bgra in more places
The glyph and icon libaries were also checking for GLES to
decide if data needs to be transformed from BGRA to RGBA.

Use the new has_bgra getter instead.

This will probably break on bigendian, because the
GL_BGRA + GL_UNSIGNED_BYTE combination is not equivalent
to the cairo format on bigendian, but this was already
broken for the gl format information that we get from
gdk_memory_format_gl_format.
2023-10-20 07:39:08 -04:00
Matthias Clasen
f4a67ebcbb Merge branch 'gles-vao' into 'main'
glcontext: Add api to check for vertex arrays

Closes #6173

See merge request GNOME/gtk!6501
2023-10-20 10:52:53 +00:00
Matthias Clasen
000c876953 gsk: Use vertex arrays when we can
Use the new has_vertex_arrays api to determine
whether we can use vertex arrays in GL.`

Fixes: #6173
2023-10-19 22:43:20 -04:00
Matthias Clasen
b8ffceaebb glcontext: Add api to check for vertex arrays
Vertex arrays are available in GL and in GLES >= 3.

We don't check for the GLES extension that provided
vertex arrays in older GLES, since that requires
using different API.

This api avoids version checks all over the place.
2023-10-19 22:43:13 -04:00
Matthias Clasen
148b8e5cd8 Merge branch 'gles-bgra' into 'main'
memoryformat: Check for BGRA support in GL

Closes #6171

See merge request GNOME/gtk!6498
2023-10-19 21:34:44 +00:00
Matthias Clasen
583ad47b03 memoryformat: Check for BGRA support
Check for whether the GL context we are using
supports uploads with GL_BGRA before returning
that memory format.

Fixes: #6171
2023-10-19 16:44:18 -04:00
Matthias Clasen
b95d8ebdd3 memoryformat: Change some private API
Make gdk_memory_format_gl_format take the GdkGLContext,
instead of just a gles boolean. This will let us
check for extensions that may be needed for certain
formats.

Update all callers.
2023-10-19 16:44:18 -04:00
Benjamin Otte
677a601d11 Merge branch 'wip/otte/for-main' into 'main'
dmabuf: Init the dmabuf subsystem before creating texture

See merge request GNOME/gtk!6499
2023-10-19 19:30:23 +00:00
Benjamin Otte
194db51fba dmabuf: Make Builder::display non-nullable
We always have a display - the default display - so there's no need to
accept NULL.

Plus, we need a display when building the texture, so accepthing NULL
wouldn't even make sense.

Includes update to defaultvalue test.
2023-10-19 20:51:51 +02:00
Matthias Clasen
d55fa0dfef glcontext: Check for GL_EXT_texture_format_BGRA8888
Check for this GLES extension and add a private getter.
2023-10-19 13:55:18 -04:00
Benjamin Otte
612b5416af dmabuf: Init the dmabuf subsystem before creating texture
We did not do that, so when the dmabuf building looked at the list of
downloaders, it was empty and the result was an error. That's not good.
2023-10-19 19:12:46 +02:00
Matthias Clasen
54637ae3b3 Merge branch 'matthiasc/for-main' into 'main'
gdk: Add an annotation

Closes #6167

See merge request GNOME/gtk!6496
2023-10-19 15:35:22 +00:00
Matthias Clasen
014adb841e gdk: Add an annotation
We are returning interned strings here, and
g-i seems to have trouble interpreting the const,
so lets help it out by being more explicit with
our annotations.

Fixes: #6167
2023-10-19 10:06:53 -04:00
Benjamin Otte
a5c6a40b3c Merge branch 'wip/otte/for-main' into 'main'
testsuite: fix "empty" linear-gradient compare test

See merge request GNOME/gtk!6493
2023-10-19 12:30:56 +00:00
Benjamin Otte
402a51b876 testsuite: Use a better opacity in the test
Using the default opacity of 0.5 makes it unclear if 0xFF should be
mapped to 0x7F or 0x80.

0.6 should hopefully map to 0x99 always.
2023-10-19 13:38:47 +02:00
Benjamin Otte
d1e091279c testsuite: fix "empty" linear-gradient compare test
We need to provide color stops to avoid rounding errors with different
shaders.

That makes the empty linear gradient somewhat less empty, but I think
it's the emptiest we can make it.
2023-10-19 13:38:47 +02:00
Matthias Clasen
7325121c63 Merge branch 'matthiasc/for-main' into 'main'
gsk: Cosmetics

See merge request GNOME/gtk!6490
2023-10-17 03:50:40 +00:00
Matthias Clasen
31abe56b7a gsk: Cosmetics 2023-10-16 23:32:37 -04:00
Matthias Clasen
ca3fd16039 Merge branch 'matthiasc/for-main' into 'main'
dmabuf: Add a display getter

See merge request GNOME/gtk!6488
2023-10-17 02:45:33 +00:00
Matthias Clasen
4417509515 dmabuf: Add a display getter
Add private api to get the display of
a dmabuf texture. We will need it in
the following commit.
2023-10-16 22:29:20 -04:00
Matthias Clasen
9dc2e554e5 dmabuf: Tweak error messages 2023-10-16 22:29:10 -04:00
Matthias Clasen
bfb01f5a4b Merge branch 'dmabuf-downloader' into 'main'
dmabuf: Split out GdkDmabuf and GdkDmabufDownloader

See merge request GNOME/gtk!6487
2023-10-16 23:31:21 +00:00
Benjamin Otte
570e80a9ff dmabuf: Split out GdkDmabuf and GdkDmabufDownloader
GdkDmabuf is a struct encapsulating all the values of a dmabuf, so
nothing to see here.

GdkDmabufDownloader is a vtable for a thing that can download dmabufs.
For now only one implementation exists, so this just looks like a ton
of work for no benefit.

The only neat thing is that gdkdmabuftexture.c got a whole lot tidier.
2023-10-16 18:56:52 -04:00
Artur S0
6d90d25a74 Update Russian translation 2023-10-16 11:57:47 +00:00
Matthias Clasen
a7f6e65291 Merge branch 'matthiasc/for-main' into 'main'
Add a dmabuf debug flag

See merge request GNOME/gtk!6486
2023-10-15 16:43:45 +00:00
Matthias Clasen
59641b3c7b docs: Sync the list of debug flags
Make the docs for GDK_DEBUG match current reality.
2023-10-15 12:00:23 -04:00
Matthias Clasen
2f842b087c dmabuf: Cosmetics 2023-10-15 12:00:23 -04:00
Matthias Clasen
699f6a7993 Add a dmabuf debug flag
Add a new debug flag for dmabuf-related information,
and use it in gdkdmabuftexture.c.

This will let us separate out dmabuf debug spew from
opengl debug spew.
2023-10-15 11:05:32 -04:00
Matthias Clasen
f04ba3bc60 Merge branch 'remove_ref_sink_on_gtk_filter' into 'main'
gtkfilechooserwidget: Replace g_object_ref_sink () with g_object_ref () on file filter

See merge request GNOME/gtk!6484
2023-10-15 11:28:29 +00:00
Matthias Clasen
09aac114d4 Merge branch 'fix-title-truncation' into 'main'
Fix window titles unexpectedly getting truncated

See merge request GNOME/gtk!6472
2023-10-15 11:27:40 +00:00
Matthias Clasen
9132600e1f Merge branch 'gbsneto/filechoosernativeportal-reverse' into 'main'
filechooserportal: Reverse file list

See merge request GNOME/gtk!6482
2023-10-15 11:26:25 +00:00
Matthias Clasen
5dcd6c7e12 Merge branch 'matthiasc/for-main' into 'main'
dmabufformatsbuilder: Make it work

See merge request GNOME/gtk!6485
2023-10-15 03:38:25 +00:00
Matthias Clasen
9f8d34ab01 dmabufformatsbuilder: Make it work
The qsort arguments were mixed up, leading to nonsense.
2023-10-14 23:04:00 -04:00
sid
7a4580fa89 gtkfilechooserwidget: Replace g_object_ref_sink () with g_object_ref () on file filter
GtkFileFilter doesn't inherit from GInitiallyUnowned anymore.
2023-10-14 21:54:49 +00:00
Matthias Clasen
45a7617cc8 Merge branch 'wip/otte/dmabuf-cleanups' into 'main'
Various dmabuf reworks

See merge request GNOME/gtk!6483
2023-10-14 20:54:27 +00:00
Benjamin Otte
57d8cc08a3 gdk: Add GDK_DEBUG=dmabuf-disable
I chose the name for consistency with gl-disable and vulkan-disable.
2023-10-14 22:30:17 +02:00
Benjamin Otte
1ca067a478 dmabuf: Add a GError to gdk_dmabuf_texture_builder_build() 2023-10-14 22:30:17 +02:00
Benjamin Otte
7a13e4f9b9 docs: Remove docs for private GdkDmabufFormat struct
This is a leftover from the design of the GdkDmabufFormats struct.
2023-10-14 22:30:17 +02:00
Benjamin Otte
d101e17608 dmabuf: Use the new FormatsBuilder to initialize formats 2023-10-14 22:30:17 +02:00
Benjamin Otte
203a4fc45e dmabufformats: Add GdkDmabufFormatsBuilder
This is a utility object that helps in constructing GdkDmabufFormats.
2023-10-14 22:29:10 +02:00
Benjamin Otte
a9823e05bb array: constify the additions array
We can only do that for by-value arrays, because compilers get confused
with const when there's too many dereferences going on.
2023-10-14 22:11:44 +02:00
Benjamin Otte
6f5833df28 dmabufformats: Mark a bunch of functions as pure 2023-10-14 22:11:44 +02:00
Sabri Ünal
5631ab6711 Update Turkish translation 2023-10-14 07:08:23 +00:00
Georges Basile Stavracas Neto
62fedf4eed filechooserportal: Reverse file list
To avoid O(n²) behaviour, GtkFileChooserNativePortal uses the
classic prepend tatict. However, it does not reverse the file
list after building it.

It's not a big deal since the portal does not specify the order
in which the files are sent. But it's nice nonetheless to send
the file list in the order in which files were passed originally.

Reversing the list has no meaningful performance impact.

Patch originally made by Bastien Nocera.

See https://github.com/flatpak/xdg-desktop-portal/issues/548
2023-10-13 16:12:12 -03:00
Emmanuele Bassi
c274d073e0 Merge branch 'mzur-main-patch-48638' into 'main'
Fix docs for gtk_color_dialog_button_get_rgba

Closes #6155

See merge request GNOME/gtk!6479
2023-10-13 09:54:56 +00:00
Martin Zurowietz
8dda753505 Fix docs for gtk_color_dialog_button_get_rgba
The signal was incorrectly called "notify::color" but
it is "notify::rgba".

Resolves https://gitlab.gnome.org/GNOME/gtk/-/issues/6155
2023-10-13 06:57:05 +00:00
Matthias Clasen
4e66df79c4 Merge branch 'michaelweghorn/a11y_send_dbus_reply_on_set_current_value' into 'main'
a11y atspi: Send proper dbus reply when (not) changing value

Closes #6150

See merge request GNOME/gtk!6476
2023-10-12 14:05:49 +00:00
Emmanuele Bassi
71c7e61162 Merge branch 'michaelweghorn/a11y_dont_confuse_char_and_byte_count' into 'main'
a11y atspi: Don't use char count as byte count

Closes #6151

See merge request GNOME/gtk!6477
2023-10-12 13:40:40 +00:00
Michael Weghorn
e39ecbf16d a11y atspi: Don't use char count as byte count
As mentioned in

    commit 368f2af634
    Author: Matthias Clasen <mclasen@redhat.com>
    Date:   Mon Oct 2 08:47:53 2023 -0400

        a11y: Be safe against non-UTF8 text

, the string insertion APIs take string + length
and only insert up to `length` bytes of the
given string.

The AT-SPI "TextChanged" event however
is using a character count, and `emit_text_changed`
also gets called with the character count
along with the string.

However, `g_strndup` used in `emit_text_changed`
so far takes a byte count, not a character count.

Adapt `emit_text_changed` to just use the
passed text as is and make it the responsibility
of the callers to pass only the actually
inserted/removed string.

Most of the callers in `gtk/a11y/gtkatspitext.c`
already did that. Adapt two missing ones to do
likewise.

Fixes: #6151
2023-10-12 11:58:32 +02:00
Michael Weghorn
0dbd2bd09e a11y atspi: Send proper dbus reply when (not) changing value
`gtk_accessible_range_default_set_current_value` needs
to return TRUE independent of whether the value was
actually changed, since that return value is required
for the proper dbus reply to be sent to AT-SPI.

Fixes a crash/assertion seen e.g. with the "Hypertext" gtk4-demo
example when trying to change "CurrentValue" for the
level bar via the AT-SPI Value interface:

    GLib-GIO:ERROR:../../../gio/gdbusconnection.c:4354:invoke_set_property_in_idle_cb: assertion failed: (error != NULL)
    Bail out! GLib-GIO:ERROR:../../../gio/gdbusconnection.c:4354:invoke_set_property_in_idle_cb: assertion failed: (error != NULL)
    Aborted

Fixes: #6150
2023-10-12 09:09:53 +02:00
Matthias Clasen
1297cc188d Merge branch 'add-six-lang' into 'main'
add hi-ja-et-fi-nb-th for gtkemojichooser

See merge request GNOME/gtk!6475
2023-10-11 22:13:54 +00:00
Benjamin Otte
e584d17aad Merge branch 'dmabuf-texture-api' into 'main'
Add API for dmabuf textures

See merge request GNOME/gtk!6463
2023-10-11 20:25:50 +00:00
Matthias Clasen
4936965fb6 display: Get supported dmabuf formats
These are the dmabuf formats that we can import
into a GL context as an EGLImage, and successfully
download.

We skip the GdkDisplay:dmabuf-formats property
in the default value tests, since the nominal
default value is NULL, but the actual value is
constructed on demand.
2023-10-11 15:43:01 -04:00
Matthias Clasen
e9cc53796e build: Error out if linux/dma-buf.h isn't found
This should always be present on Linux.
2023-10-11 15:43:01 -04:00
Matthias Clasen
c93efe85dd Add GdkDmabufTexture
Add an implementation of GdkDmabufTexture.

For now, this implementation is rather minimal,
since we need a roundtrip through GL to convert
most nottrivial formats.
2023-10-11 15:43:01 -04:00
Matthias Clasen
44daa847ff Merge branch 'michaelweghorn/a11y_convert_negative_index_on_text_deletion' into 'main'
a11y: Convert negative text deletion index to actual offset

Closes #6149

See merge request GNOME/gtk!6473
2023-10-11 19:32:11 +00:00
Matthias Clasen
d23e13aced Add GdkDmabufTextureBuilder
Add a builder for a new GdkTexture subclass that
wraps dmabuf buffers on Linux. For now, this is
just an API. The implementation will follow in
subsequent commits.
2023-10-11 14:54:21 -04:00
Matthias Clasen
40102a2b61 Add GdkDmabufFormats
This is an immutable struct containing information
about supported dma-buf formats and their properties.
2023-10-11 14:53:06 -04:00
sudip
49fbbfb6cc add hi-ja-et-fi-nb-th for gtkemojichooser 2023-10-12 00:07:59 +05:30
Michael Weghorn
fefd856d67 a11y: Convert negative text deletion index to actual offset
`gtk_editable_delete_text` can be called with a
negative `end_pos`, in which case the characters
from the start pos to the end of the text are
removed. [1]

It e.g. gets called this way from
`gtk_editable_set_text`.

So far, that negative index was not converted,
but passed as is in the AT-SPI callback
`delete_text_cb` when calling the `text_changed`
handler (`emit_text_changed` in
`gtk/a11y/gtkatspicontext.c`) which just uses the
index as is, also in it's call to `g_strndup`,
resulting in a crash when negative indices are
used.

Fix this by converting negative values to the
actual end index in `delete_text_cb` before
calling the handler.

[1] https://docs.gtk.org/gtk3/method.Editable.delete_text.html

Fixes: #6149
2023-10-11 15:51:17 +02:00
Sergey Bugaev
39dab6d7bd widget: Queue a resize on Pango context changes
Updating a Pango context can influence the layout of widget, in
particular that of a GtkLabel, not only its rendering. Make sure to
queue a resize when updating the context.

In particular, this fixes window titles getting suddenly truncated when
moving a window from a HiDPI display to a low DPI one, after
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/6190 has made font
hinting depend on the widget scale. With hinting enabled on low DPI,
the Pango layout needs ever so slightly more width to not get truncated.
There is plenty of space in the header bar that could be allocated to
the label, but for that to happen, it needs to know to queue a resize.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-10-11 15:39:37 +03:00
Matthias Clasen
7b5b78b065 Merge branch 'fix-a11y-text-signals-again' into 'main'
a11y: Avoid a crash

Closes #6146

See merge request GNOME/gtk!6470
2023-10-11 01:06:55 +00:00
Matthias Clasen
005b5042f6 Merge branch 'demo-frame-time' into 'main'
demo: Use the frame time for animation

See merge request GNOME/gtk!6468
2023-10-11 00:39:38 +00:00
Matthias Clasen
b5149a483f Merge branch 'wip/chergert/update-stb' into 'main'
gsk/gl: update stb_rect_pack()

See merge request GNOME/gtk!6466
2023-10-11 00:38:36 +00:00
Matthias Clasen
15c43e5284 a11y: Avoid a crash
It is not safe to access text[end],
if text may not be NUL-terminated.

Fixes: #6146
2023-10-10 18:54:27 -04:00
Matthias Clasen
fc4c0f769c Merge branch 'no-enums-in-bitfields' into 'main'
Stop using enums in bitfields

See merge request GNOME/gtk!6467
2023-10-10 22:48:11 +00:00
Sergey Bugaev
e8ecbb2009 demo: Use the frame time for animation
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-10-10 11:38:13 +03:00
Sergey Bugaev
964affb1cc Stop using enums in bitfields
The C standard does not specify whether the underlying type of an enum
is signed or unsigned, and until C23 there was no way to control this
explicitly. GCC appears to make enums unsigned unless there is a
negative value among cases of the enum, in which case it becomes signed.
MSCV appears to make enums signed by default.

A bitfield of an enum type (which is not specificied in the C standard
either) behaves as if it was an instance of a numeric type with a
reduced value range. Specifically, a 'signed int val : 2;' bitfield will
have the possible values of -2, -1, 0, and 1, with the usual wraparound
behavior for the values that don't fit (although this too is
implementation-defined).

This causes the following issue, if we have:

typedef enum
{
  GTK_ZERO,
  GTK_ONE,
  GTK_TWO
} GtkFoo;

struct _GtkBar
{
  GtkFoo foo : 2;
};

and then assign bar.foo = GTK_TWO and read it back, it will have the
expected value of 2 (aka GTK_TWO) on GCC, but a value of -2 (not
matching any of the enum variants) on MSVC.

There does not seem to be any way to influence signedness of an enum
prior to C23, nor is there a 'unsigned GtkFoo foo : 2;' syntax. The only
remaining options seems to be never using enums in bitfields, which is
what this change implements.

In practice, this fixes GdkPipeIOStream crashing with an assertion when
trying to copy-paste in-app in MSVC builds on GTK.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2023-10-10 11:23:08 +03:00
Christian Hergert
05b51af2d5 gsk/gl: update stb_rect_pack() 2023-10-09 22:42:57 -07:00
Emmanuele Bassi
28e51c763b Merge branch 'disable_ccache_macos' into 'main'
Disable ccache in macOS job

See merge request GNOME/gtk!6458
2023-10-09 12:23:31 +00:00
Matthias Clasen
ebf8e18319 Merge branch 'add-bn' into 'main'
add bengali language bn.data for gtkemojichooser

See merge request GNOME/gtk!6459
2023-10-09 03:03:10 +00:00
Christian Hergert
d8bbe1c296 testsuite/gsk: add render test for mask(texture|color) 2023-10-06 10:52:53 -07:00
Christian Hergert
c1417d3d4a gsk/gl: add fast path for texture masking color
This is useful for colorizing in the same fashion we do for the glyph
texture atlas. In fact, for small GdkTexture, you will end up in something
like the icon texture atlas.

The primary motivator for this optimization is to draw various glyph-like
features from VTE such as many forms of boxes, lines, arrows, etc.
2023-10-05 20:30:00 -07:00
René de Hesselle
3b4359d76d ci: Disable ccache in macOS job
As it turns out, ccache accelerates the build so much that it can
trigger a race condition in the gobject-introspection subproject. This
only surfaced recently as the introspection feature was previously
disabled due to missing build time dependencies.

The race condition surfaces as follows: the build breaks because
gobject-introspection starts to build Gdk-4.0.gir before
GdkPixbuf-2.0.gir, despite Gdk-4.0.gir depending on GdkPixbuf-2.0.gir.
2023-10-04 20:07:47 +02:00
sudip
16806294e3 add bengali language bn.data for gtkemojichooser 2023-10-04 18:52:10 +05:30
Luca Bacci
822425072b Merge branch '5724_gdk_win32_ignore_invalid_client_rect' into 'main'
Gdk4 Win32: ignore invalid client rects

Closes #5724

See merge request GNOME/gtk!6414
2023-10-04 07:58:55 +00:00
Emmanuele Bassi
7cc1283a26 Merge branch 'macos_introspec' into 'main'
Enable introspection in macOS CI

Closes Infrastructure/Infrastructure#935

See merge request GNOME/gtk!6453
2023-10-03 22:46:23 +00:00
René de Hesselle
f4198706d1 Enable introspection in macOS CI
This requires providing pkg-config and bison as well as pre-built
wheels for Pycairo and PyGObject to make it work.
2023-10-03 21:00:14 +02:00
sumibi-yakitori
37a5ad3a53 Fix coding style 2023-10-04 03:30:32 +09:00
Jordi Mas i Hernandez
8478ba66fe Update Catalan translation
(cherry picked from commit d6fecef605)
2023-10-03 06:56:01 +00:00
sumibi-yakitori
00e4dab1ef macos: change to send motion events to NSApp
This fix addresses a problem where the mouse cursor cannot be changed after it becomes a resize indicator, even in non-CSD windows
2023-10-03 08:14:27 +09:00
Matthias Clasen
1d58de6ffb Merge branch 'a11y-textview-crash' into 'main'
a11y: Be safe against non-UTF8

Closes #6131

See merge request GNOME/gtk!6448
2023-10-02 17:34:21 +00:00
Emmanuele Bassi
f5cec5c0f2 Apply 1 suggestion(s) to 1 file(s) 2023-10-02 13:16:17 +00:00
Matthias Clasen
368f2af634 a11y: Be safe against non-UTF8 text
The string we're passed here may not be zero-terminated
since our text insertion APIs take string + length. So
So be safe and copy the text we are interested in if
necessary.

Fixes: #6131
2023-10-02 08:49:41 -04:00
Matthias Clasen
66a9fee071 a11y: Emit text-changed after the insertion
This is necessary, since it is the default handler
that positions the iter at the inserted text, which
is what we assume here.
2023-10-02 08:49:31 -04:00
Matthias Clasen
6e0ac83d99 Merge branch 'print-dialog-revision' into 'main'
print dialog: Some API revisions

See merge request GNOME/gtk!6443
2023-10-01 14:01:33 +00:00
Matthias Clasen
12ad6b3157 gtk-demo: Add a demo for printing a stream
Add a Print button to the path fill demo,
and implement it using gtk_print_dialog_print.
2023-10-01 09:30:38 -04:00
Matthias Clasen
fda9fd5ced print dialog: Some API revisions
Make gtk_print_dialog_setup_finish return a GtkPrintSetup
object, which encapsulates all the data that needs to be
transferred between the setup and print calls, and make
the print_file and print methods take an extra GtkPrintSetup
argument.

Change the print call to return an output stream, rather
than take an input stream. The results are now returned
when the output stream is closed.

With some further cleanup, this makes the GtkPrintDialog
object a proper builder object - you can create multiple
print dialogs from the same GtkPrintDialog object, in
parallel, and they won't interfere with each other.
2023-10-01 09:30:38 -04:00
Matthias Clasen
029ce83a69 print dialog: Cosmetics
Some minor cleanups.
2023-09-30 21:30:22 -04:00
Matthias Clasen
5ced6be416 printjob: Work with non-seekable fds
We want to pass a pipe fd in the future,
and those aren't seekable.
2023-09-30 21:30:22 -04:00
Matthias Clasen
bbda833b01 demos: Cosmetics 2023-09-30 21:30:15 -04:00
Jonas Ådahl
c86bc00330 Merge branch 'master' into 'main'
GdkSurface: prevent popups from appearing offscreen in edge cases

See merge request GNOME/gtk!5320
2023-09-30 15:03:33 +00:00
Mazhar Hussain
8367411785 GtkProgressBar: Fix: progress can overflow trough
For visual explanation, visit https://gitlab.gnome.org/GNOME/gtk/-/issues/5751
The linked issue tracker is for GtkScale but GtkProgressBar has the exact same problem as well
2023-09-30 14:11:47 +05:00
Mazhar Hussain
17e37dc42a GtkScale: Fix: highlight can overflow trough
For visual explanation, visit https://gitlab.gnome.org/GNOME/gtk/-/issues/5751
2023-09-30 13:39:00 +05:00
Matthias Clasen
68755c0fd2 Post-release version bump 2023-09-28 10:49:46 -04:00
Matthias Clasen
9090c28125 4.13.1 2023-09-28 09:50:16 -04:00
Matthias Clasen
3a3244891e Merge branch 'wip-print-dialog' into 'main'
wip: print dialog api

See merge request GNOME/gtk!5484
2023-09-28 01:18:26 +00:00
Matthias Clasen
b55117334c gtk-demo: Add a print dialog 2023-09-27 20:50:52 -04:00
Matthias Clasen
02e5c7b9ad Add a print dialog
Add a simplified print api that only supports
printing preexisting pdf content. For now, it
only has a portal implementation.
2023-09-27 20:50:52 -04:00
Matthias Clasen
7268167f4c Merge branch 'matthiasc/for-main' into 'main'
print portal: Report errors properly

See merge request GNOME/gtk!6441
2023-09-27 21:52:13 +00:00
Matthias Clasen
93c7502cf7 printer: Add private search api 2023-09-27 17:37:11 -04:00
Matthias Clasen
789705cfe4 print portal: Report errors properly
The portal printoperation inmplementation
relies on the file printbackend to be available.
If it isn't, we should report a proper error
status insetad of running into assertions deep
inside the printoperation code.
2023-09-27 17:33:34 -04:00
Emmanuele Bassi
741471a1f8 Merge branch 'michaelweghorn/a11y_add_paragraph_role' into 'main'
a11y: Add paragraph role

See merge request GNOME/gtk!6432
2023-09-27 12:20:19 +00:00
Matthias Clasen
f8da751cc2 Merge branch 'wip/chergert/rendernode-type-checks-for-refcount' into 'main'
gsk: remove excessive type checking within GSK

See merge request GNOME/gtk!6439
2023-09-27 12:12:18 +00:00
Matthias Clasen
8174842d9f Merge branch 'wip/chergert/rendernode-type-check' into 'main'
gsk/gl: remove TypeNode conformity checking for renderjob

See merge request GNOME/gtk!6438
2023-09-27 12:10:52 +00:00
Matthias Clasen
e872952f36 Merge branch 'mcatanzaro/#6122' into 'main'
printoperation: fix case where operation may complete multiple twice

Closes #6122

See merge request GNOME/gtk!6437
2023-09-27 10:37:23 +00:00
Christian Hergert
b010e46d13 gsk/gl: remove TypeNode conformity checking for renderjob
We don't need to be calling type node conformity checking from the tight
loop of the renderjob. Hoist that into the private header and use that
intead through via the Class pointer.
2023-09-26 18:36:56 -07:00
Christian Hergert
eb646a8e8b gsk: remove excessive type checking within GSK
Anything that includes gskrendernodeprivate.h will get an alternate form
of ref/unref for render nodes which does not need to do type checking on
the parameter. We can expect that things are correct within GTK itself and
this saves excessive amounts of TypeNode conformities checking.
2023-09-26 18:28:34 -07:00
Michael Catanzaro
1e2975147d printoperation: fix some strange line spacing 2023-09-26 19:28:12 -05:00
Michael Catanzaro
653c10e8b6 printoperation: add some assertions
Let's assert that we schedule the idle callback exactly once.

These assertions are not perfect because if the callback executes before
we schedule it, then the assertion itself would be a use-after-free,
since I'm using the PrinterFinder to track whether the callback that
frees it has been scheduled. But in practice when using loupe's print
dialog, I was noticing the callback scheduled twice before it was
executed. The assertion would have caught this problem.
2023-09-26 19:25:41 -05:00
Michael Catanzaro
dfbafdf047 printoperation: fix another case where operation may complete twice
This is a little tricky. At first, I thought we had a codepath where we
fail to schedule the idle that completes the print operation: if we take
the gtk_print_backend_printer_list_is_done path for each printer
backend, then printer_list_done_cb() is never executed and we never
schedule the idle. But in fact, in this case, then backends == NULL at
the bottom of find_printer(), and we'll schedule the idle there, so it's
OK. Except it's not really OK, because we'll schedule it even if a
printer was already found, resulting in the callback completing twice
and a double free.

Simplify this. Schedule the idle in find_printer() only if there are
*initially* no backends, not also if all backends are immediately ready
and already removed from consideration. Instead, always call
printer_list_done_cb() for every backend in find_printer_init(). After
the previous commit, printer_list_done_cb() will schedule the idle when
appropriate.

printer_list_done_cb() additionally disconnects signals that we did not
connect in this codepath, but it does so using
g_signal_handlers_disconnect_by_func, which is harmless. Otherwise, the
only extra work it's doing is scheduling the idle, and that's exactly
what find_printer_init() is missing.
2023-09-26 19:08:46 -05:00
Michael Catanzaro
d8c821a851 printoperation: fix case where operation may complete multiple twice
If we are the final backend, then after removing ourselves there is no
backend remaining. We will schedule the idle even if it has already been
scheduled. This idle is required to run exactly once and executing it
twices results in a double free that crashes loupe when printing. It
also causes the user callback to execute twice, which could cause
similar problems.

Fixes #6122
2023-09-26 18:47:01 -05:00
Matthias Clasen
83376648d7 Merge branch 'wip/chergert/fix-clips-uaf' into 'main'
Fix potential UAF in renderjob clipping

See merge request GNOME/gtk!6436
2023-09-26 21:59:56 +00:00
Christian Hergert
089c34fa03 gsk/gl: use GdkArrayImpl for tracking modelview
Like the previous change, this uses GdkArrayImpl instead of GArray for
tracking modelview changes. This is less important than clip tracking
simple due to being used less, but it keeps the implementation synchronous
with the Clip tracking code.
2023-09-26 13:58:38 -07:00
Christian Hergert
c846f8d745 gsk/gl: use GdkArrayImpl for Clip tracking
We can end up spending a lot of time in g_array_maybe_expand() through the
use of g_array_set_size() for clip tracking. That is somewhat due to the
simple nature of GArray being size-dynamic. Instead, we can use
GdkArrayImpl and let the compiler do what it does best to elide some
work and hoist other work into the calling function.

This also fixes a potential UAF in gsk_gl_render_job_push_contained_clip().
2023-09-26 13:58:35 -07:00
Emmanuele Bassi
79ebd76ac8 Merge branch 'wip/chergert/fix-gdkarrayimpl-from-c++' into 'main'
gdk: add missing G_END_DECLS to gdkarrayimpl.c

See merge request GNOME/gtk!6435
2023-09-26 18:48:02 +00:00
Christian Hergert
6eb9836eb0 gdk: add missing G_END_DECLS to gdkarrayimpl.c 2023-09-26 10:46:21 -07:00
Matthias Clasen
4a8f8a6eea Merge branch 'broadway-renderer-leak' into 'main'
broadway: Plug a leak in the GSK renderer

Closes #6120

See merge request GNOME/gtk!6434
2023-09-26 15:13:38 +00:00
Emmanuele Bassi
3ea723730b broadway: Do not add an extra reference when caching textures
We just created a GdkTexture, so we don't need to acquire a reference if
we're transferring the ownership to the node cache.
2023-09-26 14:44:05 +01:00
Emmanuele Bassi
90be2baf8b broadway: Plug another leak
When getting a colorized texture we're downloading the texture as a
Cairo surface, and then feeding it to another texture, but we never drop
the reference of the new surface.
2023-09-26 14:40:37 +01:00
Emmanuele Bassi
0b64fa88a1 docs: Clarify the behaviour of gdk_texture_new_for_surface()
Cairo surfaces are not GObject instances, so we should be more explicit
in the behaviour of the memory management, to avoid leaks.
2023-09-26 12:57:52 +01:00
Emmanuele Bassi
c6cc446e63 broadway: Plug a leak in the GSK renderer
We are leaking the Cairo image surface when creating a new node.

Fixes: #6120
2023-09-26 12:49:32 +01:00
Benjamin Otte
0cad37760e Merge branch 'wip/otte/for-main' into 'main'
treeview: Fix crash in assertion

Closes #6114

See merge request GNOME/gtk!6433
2023-09-26 09:29:08 +00:00
Benjamin Otte
e720008dca glcontext: Add gdk_gl_context_get_glsl_version_string()
This is in preparation for the new renderer.
2023-09-26 11:08:59 +02:00
Benjamin Otte
9c636a6136 array: Compute new size properly
Using "1 << x" means that we are shifting a signed 32bit integer, but we
want a gsize, which is an unsigned 64bit integer.

So now we don't overflow anymore if the array reaches a size of 2GB.
2023-09-26 11:08:59 +02:00
Benjamin Otte
1e24aa425e gdk: Fix compiler warning
gcc's -Wlto-type-mismatch found the hack, where we copied the wrong
prototype.
2023-09-26 11:08:59 +02:00
Benjamin Otte
a8c597005a treeview: Fix crash in assertion
The fix in commit a267dfac5d is wrong.
The function can return FALSE in normal operation.

Instead do a check for node == NULL that gracefully returns FALSE instead.

Fixes: #6114
2023-09-26 11:08:32 +02:00
Aurimas Černius
97a781b380 Update Lithuanian translation
(cherry picked from commit 61276e9a76)
2023-09-25 19:58:12 +00:00
Rafael Fontenelle
313cadefe6 Update Brazilian Portuguese translation
(cherry picked from commit 90b8dcdf33)
2023-09-25 12:58:47 +00:00
Michael Weghorn
9f078bd5c9 a11y: Add paragraph role
Add new GTK_ACCESSIBLE_ROLE_PARAGRAPH role
for paragraphs.

ARIA has a paragraph role as well.

The paragraph role is used e.g. in document editors
like LibreOffice or web browsers like Firefox.

According to the ARIA spec [1], naming paragraphs
is forbidden (§ 5.2.8.6), and the superclass role
is section.

This role will be more useful once a way to expose
the textual data via the AT-SPI Text interface is
also available (s. issue #5912 [2]).

[1] https://www.w3.org/TR/wai-aria-1.2/
[2] https://gitlab.gnome.org/GNOME/gtk/-/issues/5912
2023-09-25 11:30:14 +02:00
Matthias Clasen
8ff4e27103 Merge branch 'wip/alice/dialog-crash' into 'main'
dialog: Check header bar type before calling track_default_decoration()

Closes #6116

See merge request GNOME/gtk!6430
2023-09-24 13:24:49 +00:00
Matthias Clasen
8389ca633d Merge branch 'matthiasc/for-main' into 'main'
tests: Split off some path utilities

See merge request GNOME/gtk!6431
2023-09-24 13:07:45 +00:00
Matthias Clasen
18fbec0fe1 Improve FOO_DEBUG=help output
Explain the all value a bit better.
2023-09-24 08:33:22 -04:00
Alice Mikhaylenko
eb0a00067d dialog: Check header bar type before calling track_default_decoration()
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/6116
2023-09-24 15:38:19 +04:00
Alice Mikhaylenko
91216408e5 header-bar: Add a precondition to track_default_decoration() 2023-09-24 15:21:55 +04:00
G.Willems
4c46f5a8f7 GdkWin32: ignore invalid client rects
Gdk-Win32 uses GetClientRect() internally to query the surfaces coordinates,
but this API may fail in some transient contexts (observed when iconifying
a maximized window).
Check if the rect area is null, and don't update the surface position in
that case. This will keep the current surface size, until Win32 notifies
the new valid window state later.
This prevents using a nulled next_layout for toplevel size computation,
which would break widgets allocation once notified on gtk side.

Fixes #5724
Closes #5724
2023-09-19 20:29:04 +02:00
Campbell Jones
5c00dc7ef4 GdkSurface: prevent popups from appearing offscreen in edge cases
This commit adds a single additional condition to the maybe_flip_position
function in gdksurface.c. If a popup's unflipped position is below the
bounds of its containing area, the popup uses its flipped position
instead. This prevents tooltips from appearing below the bounds of the
screen when a small widget is positioned very close to the bottom edge of
the screen, such as in Budgie and XFCE panel applets.
2023-01-07 11:08:33 -05:00
396 changed files with 34027 additions and 19716 deletions

View File

@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v49"
workflow:
rules:
@@ -66,7 +66,8 @@ style-check-diff:
junit:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.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:
@@ -103,8 +104,9 @@ fedora-x86_64:
${FEATURE_FLAGS}
_build
- meson compile -C _build
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build x11 gtk
# only repeat test runs that are likely affected by test setups
- .gitlab-ci/run-tests.sh _build wayland_gl gtk:gdk,gtk:gsk-gl
release-build:
extends: .build-fedora-default
@@ -129,7 +131,9 @@ release-build:
- meson install -C _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 x11
- .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
@@ -217,25 +221,32 @@ macos-x86_64:
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
CCACHE_DIR: /Users/Shared/work/ccache
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
before_script:
# Not using ccache on purpose as it accelerates the build so much that it
# can trigger race conditions in the gobject-introspection subproject.
- bash .gitlab-ci/show-info-osx.sh
- python3 -m venv .venv
- /opt/macports/bin/python3.10 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/ccache/ccache .venv/bin
- ln -s /opt/pkg-config/bin/pkg-config .venv/bin
- ln -s /opt/bison/bin/bison .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
script:
- meson setup ${COMMON_MESON_FLAGS}
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
-Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=disabled
-Dintrospection=enabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
@@ -416,11 +427,12 @@ asan-build:
-Df16c=disabled
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland gtk
artifacts:
when: always
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"

Binary file not shown.

View File

@@ -1,4 +1,4 @@
FROM fedora:38
FROM fedora:39
RUN dnf -y install \
adwaita-icon-theme \

View File

@@ -324,7 +324,7 @@ for line in args.infile:
units.append(unit)
report = {}
report['date'] = datetime.datetime.utcnow()
report['date'] = datetime.datetime.now(datetime.UTC)
report['locale_date'] = report['date'].strftime("%c")
report['project_name'] = args.project_name
report['backend'] = args.backend

View File

@@ -44,7 +44,7 @@ outfile = args.output
testsuites = ET.Element('testsuites')
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
testsuites.set('package', args.project_name)
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
testsuites.set('timestamp', datetime.datetime.now(datetime.UTC).isoformat(timespec='minutes'))
suites = {}
for line in args.infile:

View File

@@ -1,27 +1,29 @@
#!/bin/bash
set +x
set -x
set +e
srcdir=$( pwd )
builddir=$1
backend=$2
setup=$2
suite=$3
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export G_SLICE=always-malloc
case "${backend}" in
x11)
case "${setup}" in
x11*)
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=gsk-compare-broadway
@@ -42,19 +44,19 @@ case "${backend}" in
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=${backend}_failing \
--no-suite=gsk-compare-broadway
exit_code=$?
kill ${compositor}
;;
broadway)
broadway*)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
@@ -65,9 +67,10 @@ case "${backend}" in
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=gsk-compare-opengl
@@ -76,7 +79,7 @@ case "${backend}" in
;;
*)
echo "Failed to add ${backend} to .gitlab-ci/run-tests.sh"
echo "Failed to add ${setup} to .gitlab-ci/run-tests.sh"
exit 1
;;
@@ -86,17 +89,17 @@ cd ${builddir}
$srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \
--backend="${backend}" \
--backend="${setup}" \
--job-id="${CI_JOB_NAME}" \
--output="report-${backend}.xml" \
"meson-logs/testlog-${backend}.json"
--output="report-${setup}.xml" \
"meson-logs/testlog-${setup}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \
--backend="${backend}" \
--backend="${setup}" \
--job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${backend}" \
--output="report-${backend}.html" \
"meson-logs/testlog-${backend}.json"
--reftest-output-dir="testsuite/reftests/output/${setup}" \
--output="report-${setup}.html" \
"meson-logs/testlog-${setup}.json"
exit $exit_code

97
NEWS
View File

@@ -1,4 +1,71 @@
Overview of Changes in 4.13.1, xx-xx-xxxx
Overview of Changes in 4.13.4, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.3, 15-11-2023
=========================================
* GtkGraphicsOffload: A new widget to support passthrough
of dmabuf textures with subsurfaces on Wayland
* GtkListView:
- reduce tree indentation
* GtkInspector:
- Show more GL information
- Add a subsurface overlay
- Improve the fps overlay
* GDK
- Allow implicit modifiers for dmabufs
- Support more dmabuf formats: NV16, NV61, NV24, NV42
and 3-plane YUV formats
* GSK
- Fix padding of icons in the GL atlas
- Fix handling of texture-scale nodes in cairo
- Treat texture-scale nodes more faithfully in GL
* Accessibility:
- Tweak the accessible name computation for corner cases
* The GTK/GDK/GSK_DEBUG environment variables now
work in productions as well as in debug builds
* Translation updates
Catalan
French
Russian
Overview of Changes in 4.13.2, 22-10-2023
=========================================
* GtkPrintdialog:
- New async-style api to replace GtkPrintOperation
* GtkEmojiChooser:
- Add more languages: Bengali, Hindi, Japanese, Finnish,
Thai and Norwegian bokmål
* Accessibility:
- Fix some utf8 handling issues
* GDK:
- Add support for dmabuf textures, with GdkDmabufTextureBuilder
- Add a few more supported memory formats for textures
* GSK:
- Add a fast-path for masking color
- Add support for importing dmabuf textures
- Handle GLES better by using some extensions
* Translation updates:
Catalan
Russian
Turkish
Overview of Changes in 4.13.1, 28-09-2023
=========================================
* GtkTooltip:
@@ -7,20 +74,32 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
* GtkCenterLayout, GtkEntry, GtkSearchEntry:
- Fix some issues with baseline handling
* GtkColorButton, GtkFontButton:
- Propagate focus-on-click
* GtkFileChooser:
- Make "Visit file" scroll to the file
* GtkSwitch:
- Respect text direction
* GtkWindow:
- Don't assume titlebars are GtkHeaderBars
* Printing:
- Fix some problems with the portal implementation
- Add a new simple print API: GtkPrintDialog
* Paths:
- GskPathMeasure performance has been improved
- Add custom contours for circles, rounded rectangles and rectangles
- Simplify GskPathPoint handling
- gsk_path_point_get_closest_point now returns the distance as well
- Make GskPathBuilder simplify curves
* Input:
- Handle (some) single-key compose sequences
- Fix active state tracking with sensitivity changes and grabs
* GSK:
- Make the repeated gradients match between GL and cairo
@@ -29,6 +108,13 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
- Restrict an optimization to the cases where it is crrect
- Fix rendering of shadows with opacity
- The Vulkan renderer now requires Vulkan 1.2
- GL: Transition gradients unpremultiplied
- GL: Fix clipping of shadows
- GL: Some optimizations
- Broadway: Fix memory leaks in the renderer
* Wayland:
- Make activation more reliable
* macOS:
- Clamp damage regions to the surface size
@@ -43,20 +129,29 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
* Build:
- Fix build problems with C++ compilers
* Deprecations:
- gtk_window_present_with_time
* Translation updates
Brazilian Portuguese
British English
Catalan
Chinese (China)
Czech
Danish
Dutch
Esperanto
Galician
Georgian
Italian
Korean
Latvian
Lithuanian
Persian
Polish
Punjabi
Slovenian
Turkish
Overview of Changes in 4.13.0, 25-08-2023

View File

@@ -0,0 +1,41 @@
#ifndef _MSC_VER
#pragma error "This header is for Microsoft VC or clang-cl only."
#endif /* _MSC_VER */
/* Make MSVC more pedantic, this is a recommended pragma list
* from _Win32_Programming_ by Rector and Newcomer.
*/
#ifndef __clang__
#pragma warning(error:4002) /* too many actual parameters for macro */
#pragma warning(error:4003) /* not enough actual parameters for macro */
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */
#pragma warning(1:4016) /* no function return type; using int as default */
#pragma warning(error:4020) /* too many actual parameters */
#pragma warning(error:4021) /* too few actual parameters */
#pragma warning(error:4027) /* function declared without formal parameter list */
#pragma warning(error:4029) /* declared formal parameter list different from definition */
#pragma warning(error:4033) /* 'function' must return a value */
#pragma warning(error:4035) /* 'function' : no return value */
#pragma warning(error:4045) /* array bounds overflow */
#pragma warning(error:4047) /* different levels of indirection */
#pragma warning(error:4049) /* terminating line number emission */
#pragma warning(error:4053) /* An expression of type void was used as an operand */
#pragma warning(error:4071) /* no function prototype given */
#pragma warning(disable:4101) /* unreferenced local variable */
#pragma warning(error:4150)
/* G_NORETURN */
#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
#pragma warning(error:4715) /* 'function': not all control paths return a value */
#pragma warning(error:4098) /* 'void' function returning a value */
#pragma warning(disable:4244) /* No possible loss of data warnings */
#pragma warning(disable:4305) /* No truncation from int to char warnings */
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
#endif /* __clang__ */
/* work around Microsoft's premature attempt to deprecate the C-Library */
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS

View File

@@ -35,7 +35,7 @@ show_action_dialog (GSimpleAction *action)
{
GtkAlertDialog *dialog;
dialog = gtk_alert_dialog_new ("You activated action: \"%s\n",
dialog = gtk_alert_dialog_new ("You activated action: \"%s\"",
g_action_get_name (G_ACTION (action)));
gtk_alert_dialog_show (dialog, NULL);
g_object_unref (dialog);

View File

@@ -339,7 +339,6 @@
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_spinner.c</file>
<file>path_sweep.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
@@ -427,10 +426,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_sweep">
<file>path_sweep.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_walk">
<file>path_walk.ui</file>
<file compressed="true">path_world.txt</file>

View File

@@ -75,7 +75,9 @@ query_tooltip (GtkWidget *widget,
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
precision = 1;
s = NULL;
do {
g_free (s);
s = g_strdup_printf ("%.*f", precision, self->scale);
l = strlen (s) - 1;
while (s[l] == '0')

View File

@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
{
DemoWidget *self = DEMO_WIDGET (widget);
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
gint64 now = g_get_monotonic_time ();
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
gtk_widget_queue_allocate (widget);
@@ -66,11 +66,13 @@ clicked (GtkGestureClick *gesture,
gpointer data)
{
DemoWidget *self = data;
GdkFrameClock *frame_clock;
if (self->tick_id != 0)
return;
self->start_time = g_get_monotonic_time ();
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
}

View File

@@ -75,7 +75,6 @@ demos = files([
'path_fill.c',
'path_maze.c',
'path_spinner.c',
'path_sweep.c',
'path_walk.c',
'path_text.c',
'peg_solitaire.c',

View File

@@ -2,10 +2,13 @@
*
* This demo shows how to use GskPath to draw shapes that are (a bit)
* more complex than a rounded rectangle.
*
* It also demonstrates printing to a stream with GtkPrintDialog.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <cairo-pdf.h>
#include "paintable.h"
@@ -165,6 +168,89 @@ gtk_logo_paintable_new (void)
return GDK_PAINTABLE (self);
}
static cairo_status_t
write_cairo (void *closure,
const unsigned char *data,
unsigned int length)
{
GOutputStream *stream = closure;
gsize written;
GError *error = NULL;
if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
{
g_print ("Error writing pdf stream: %s\n", error->message);
g_error_free (error);
return CAIRO_STATUS_WRITE_ERROR;
}
return CAIRO_STATUS_SUCCESS;
}
static void
print_ready (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GOutputStream *stream;
GtkSnapshot *snapshot;
GdkPaintable *paintable;
GskRenderNode *node;
cairo_surface_t *surface;
cairo_t *cr;
stream = gtk_print_dialog_print_finish (dialog, result, &error);
if (stream == NULL)
{
g_print ("Failed to get output stream: %s\n", error->message);
g_error_free (error);
return;
}
snapshot = gtk_snapshot_new ();
paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
gdk_paintable_snapshot (paintable, snapshot, 100, 100);
node = gtk_snapshot_free_to_node (snapshot);
surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100, 100);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_destroy (surface);
gsk_render_node_unref (node);
if (!g_output_stream_close (stream, NULL, &error))
{
g_print ("Error from close: %s\n", error->message);
g_error_free (error);
}
g_object_unref (stream);
}
static void
print (GtkButton *button,
gpointer data)
{
GtkWidget *picture = data;
GtkPrintDialog *dialog;
dialog = gtk_print_dialog_new ();
gtk_print_dialog_print (dialog,
GTK_WINDOW (gtk_widget_get_root (picture)),
NULL,
NULL,
print_ready,
picture);
g_object_unref (dialog);
}
GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
@@ -172,12 +258,21 @@ do_path_fill (GtkWidget *do_widget)
if (!window)
{
GtkWidget *header, *button, *label;
GtkWidget *picture;
GdkPaintable *paintable;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("Fill and Stroke");
gtk_widget_add_css_class (label, "title");
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new ();
@@ -186,6 +281,8 @@ do_path_fill (GtkWidget *do_widget)
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
g_signal_connect (button, "clicked", G_CALLBACK (print), picture);
gtk_window_set_child (GTK_WINDOW (window), picture);
}

View File

@@ -1,319 +0,0 @@
/* Path/Sweep
*
* This demo shows how path intersections can be used.
*
* The world map that is used here is a path with 211 lines and 1569 cubic
* Bėzier segments in 121 contours.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_SWEEP (gtk_path_sweep_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathSweep, gtk_path_sweep, GTK, PATH_SWEEP, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_PATH,
N_PROPS
};
struct _GtkPathSweep
{
GtkWidget parent_instance;
GskPath *path;
graphene_rect_t bounds;
float y_pos;
gboolean in;
};
struct _GtkPathSweepClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathSweep, gtk_path_sweep, GTK_TYPE_WIDGET)
static gboolean
intersection_cb (GskPath *path1,
const GskPathPoint *point1,
GskPath *path2,
const GskPathPoint *point2,
GskPathIntersection kind,
gpointer data)
{
GskPathBuilder *builder = data;
graphene_point_t p;
gsk_path_point_get_position (point1, path1, &p);
gsk_path_builder_add_circle (builder, &p, 4);
return TRUE;
}
static GskPath *
get_intersection_path (GskPath *path1,
GskPath *path2)
{
GskPathBuilder *builder = gsk_path_builder_new ();
gsk_path_foreach_intersection (path1, path2, intersection_cb, builder);
return gsk_path_builder_to_path (builder);
}
static void
gtk_path_sweep_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathSweep *self = GTK_PATH_SWEEP (widget);
GskStroke *stroke;
if (self->path == NULL)
return;
gtk_snapshot_save (snapshot);
stroke = gsk_stroke_new (2.0);
gtk_snapshot_append_stroke (snapshot, self->path, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
if (self->in)
{
graphene_rect_t bounds;
GskPathBuilder *builder;
GskPath *line, *isecs;
gsk_path_get_stroke_bounds (self->path, stroke, &bounds);
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, bounds.origin.x, bounds.origin.y + self->y_pos);
gsk_path_builder_line_to (builder, bounds.origin.x + bounds.size.width, bounds.origin.y + self->y_pos);
line = gsk_path_builder_free_to_path (builder);
gtk_snapshot_append_stroke (snapshot, line, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
isecs = get_intersection_path (self->path, line);
gtk_snapshot_append_fill (snapshot, isecs, GSK_FILL_RULE_WINDING, &(GdkRGBA) { 1, 0, 0, 1 });
gtk_snapshot_append_stroke (snapshot, isecs, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
gsk_path_unref (isecs);
gsk_path_unref (line);
}
gsk_stroke_free (stroke);
gtk_snapshot_restore (snapshot);
}
static void
gtk_path_sweep_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkPathSweep *self = GTK_PATH_SWEEP (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = (int) ceilf (self->bounds.size.width);
else
*minimum = *natural = (int) ceilf (self->bounds.size.height);
}
static void
gtk_path_sweep_set_path (GtkPathSweep *self,
GskPath *path)
{
if (self->path == path)
return;
g_clear_pointer (&self->path, gsk_path_unref);
graphene_rect_init (&self->bounds, 0, 0, 0, 0);
if (path)
{
GskStroke *stroke;
self->path = gsk_path_ref (path);
stroke = gsk_stroke_new (2.0);
gsk_path_get_stroke_bounds (path, stroke, &self->bounds);
gsk_stroke_free (stroke);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PATH]);
}
static void
gtk_path_sweep_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathSweep *self = GTK_PATH_SWEEP (object);
switch (prop_id)
{
case PROP_PATH:
gtk_path_sweep_set_path (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_sweep_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathSweep *self = GTK_PATH_SWEEP (object);
switch (prop_id)
{
case PROP_PATH:
g_value_set_boxed (value, self->path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_sweep_dispose (GObject *object)
{
GtkPathSweep *self = GTK_PATH_SWEEP (object);
g_clear_pointer (&self->path, gsk_path_unref);
G_OBJECT_CLASS (gtk_path_sweep_parent_class)->dispose (object);
}
static void
gtk_path_sweep_class_init (GtkPathSweepClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_sweep_dispose;
object_class->set_property = gtk_path_sweep_set_property;
object_class->get_property = gtk_path_sweep_get_property;
widget_class->snapshot = gtk_path_sweep_snapshot;
widget_class->measure = gtk_path_sweep_measure;
properties[PROP_PATH] =
g_param_spec_boxed ("path", NULL, NULL,
GSK_TYPE_PATH,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
motion_cb (GtkEventControllerMotion *controller,
double x,
double y,
gpointer data)
{
GtkPathSweep *self = data;
self->y_pos = y;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
enter_cb (GtkEventControllerMotion *controller,
double x,
double y,
gpointer data)
{
GtkPathSweep *self = data;
self->in = TRUE;
self->y_pos = y;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
leave_cb (GtkEventControllerMotion *controller,
gpointer data)
{
GtkPathSweep *self = data;
self->in = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_sweep_init (GtkPathSweep *self)
{
GtkEventController *controller;
/* Data taken from
* https://commons.wikimedia.org/wiki/Maps_of_the_world#/media/File:Simplified_blank_world_map_without_Antartica_(no_borders).svg
*/
GBytes *data = g_resources_lookup_data ("/path_sweep/path_world.txt", 0, NULL);
GskPath *path = gsk_path_parse (g_bytes_get_data (data, NULL));
g_bytes_unref (data);
gtk_path_sweep_set_path (self, path);
gsk_path_unref (path);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), self);
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
GtkWidget *
gtk_path_sweep_new (void)
{
GtkPathSweep *self;
self = g_object_new (GTK_TYPE_PATH_SWEEP, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_sweep (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_SWEEP);
builder = gtk_builder_new_from_resource ("/path_sweep/path_sweep.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">World Map</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkPathSweep" id="view">
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</property>
</object>
</interface>

View File

@@ -1,8 +1,9 @@
/* Pickers and Launchers
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkPrintDialog, GtkFileLauncher, GtkUriLauncher
*
* The dialogs are mainly intended for use in preference dialogs.
* They allow to select colors, fonts and applications.
* They allow to select colors, fonts and files. There is also a
* print dialog.
*
* The launchers let you open files or URIs in applications that
* can handle them.
@@ -11,11 +12,13 @@
#include <gtk/gtk.h>
static GtkWidget *app_picker;
static GtkWidget *print_button;
static void
set_file (GFile *file,
gpointer data)
{
GFileInfo *info;
char *name;
if (!file)
@@ -31,6 +34,13 @@ set_file (GFile *file,
gtk_widget_set_sensitive (app_picker, TRUE);
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
info = g_file_query_info (file, "standard::content-type", 0, NULL, NULL);
if (strcmp (g_file_info_get_content_type (info), "application/pdf") == 0)
{
gtk_widget_set_sensitive (print_button, TRUE);
g_object_set_data_full (G_OBJECT (print_button), "file", g_object_ref (file), g_object_unref);
}
}
static void
@@ -47,6 +57,10 @@ file_opened (GObject *source,
{
g_print ("%s\n", error->message);
g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
gtk_widget_set_sensitive (print_button, FALSE);
g_object_set_data (G_OBJECT (print_button), "file", NULL);
}
set_file (file, data);
@@ -114,6 +128,53 @@ open_app (GtkButton *picker)
g_object_unref (launcher);
}
static void
print_file_done (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GCancellable *cancellable;
unsigned int id;
cancellable = g_task_get_cancellable (G_TASK (result));
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cancellable), "timeout"));
if (id)
g_source_remove (id);
if (!gtk_print_dialog_print_file_finish (dialog, result, &error))
{
g_print ("%s\n", error->message);
g_error_free (error);
}
}
static void
print_file (GtkButton *picker)
{
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
GtkPrintDialog *dialog;
GCancellable *cancellable;
GFile *file;
unsigned int id;
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
dialog = gtk_print_dialog_new ();
cancellable = g_cancellable_new ();
id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
20,
abort_mission, g_object_ref (cancellable), g_object_unref);
g_object_set_data (G_OBJECT (cancellable), "timeout", GUINT_TO_POINTER (id));
gtk_print_dialog_print_file (dialog, parent, NULL, file, cancellable, print_file_done, NULL);
g_object_unref (cancellable);
g_object_unref (dialog);
}
static void
open_uri_done (GObject *source,
GAsyncResult *result,
@@ -234,8 +295,14 @@ do_pickers (GtkWidget *do_widget)
gtk_widget_set_sensitive (app_picker, FALSE);
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
gtk_box_append (GTK_BOX (picker), app_picker);
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
print_button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_widget_set_tooltip_text (print_button, "Print file");
gtk_widget_set_sensitive (print_button, FALSE);
g_signal_connect (print_button, "clicked", G_CALLBACK (print_file), NULL);
gtk_box_append (GTK_BOX (picker), print_button);
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
label = gtk_label_new ("URI:");
gtk_widget_set_halign (label, GTK_ALIGN_START);

View File

@@ -139,6 +139,7 @@ do_video_player (GtkWidget *do_widget)
video = gtk_video_new ();
gtk_video_set_autoplay (GTK_VIDEO (video), TRUE);
gtk_video_set_graphics_offload (GTK_VIDEO (video), GTK_GRAPHICS_OFFLOAD_ENABLED);
gtk_window_set_child (GTK_WINDOW (window), video);
title = gtk_header_bar_new ();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M3.384 3h3.231c.213 0 .385.224.385.502v2.996C7 6.776 6.828 7 6.615 7h-3.23C3.17 7 3 6.776 3 6.498V3.502C3 3.224 3.17 3 3.384 3zm6 0h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C9.17 7 9 6.776 9 6.498V3.502C9 3.224 9.17 3 9.384 3zm-6 6h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C3.17 13 3 12.776 3 12.498V9.502C3 9.224 3.17 9 3.384 9zm6 0h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C9.17 13 9 12.776 9 12.498V9.502C9 9.224 9.17 9 9.384 9z" style="marker:none" overflow="visible" color="#000" fill="#474747"/></svg>

Before

Width:  |  Height:  |  Size: 654 B

View File

@@ -25,14 +25,12 @@
<file>icons/16x16/actions/format-justify-fill-symbolic.symbolic.png</file>
<file>icons/16x16/actions/format-justify-left-symbolic.symbolic.png</file>
<file>icons/16x16/actions/format-justify-right-symbolic.symbolic.png</file>
<file>icons/16x16/actions/insert-image.png</file>
<file>icons/16x16/actions/insert-link-symbolic.symbolic.png</file>
<file>icons/16x16/actions/send-to-symbolic.symbolic.png</file>
<file>icons/16x16/actions/star-new-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-continuous-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-dual-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-grid-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-paged-symbolic.symbolic.png</file>
<file>icons/16x16/actions/zoom-in-symbolic.symbolic.png</file>
<file>icons/16x16/actions/zoom-in.png</file>
@@ -88,7 +86,6 @@
<file>icons/scalable/actions/view-dual-symbolic.svg</file>
<file>icons/scalable/actions/view-paged-symbolic.svg</file>
<file>icons/scalable/actions/view-fullscreen-symbolic.svg</file>
<file>icons/scalable/actions/view-grid-symbolic.svg</file>
<file>icons/scalable/actions/zoom-in-symbolic.svg</file>
<file>icons/scalable/actions/zoom-original-symbolic.svg</file>
<file>icons/scalable/actions/zoom-out-symbolic.svg</file>

View File

@@ -685,6 +685,8 @@ stack-allocated using `g_newa()` or `g_alloca()`. But limit the amount
of stack memory that you consume this way, in particular in recursive
functions.
On Windows, the default stack size we have to work with is 1M.
### Macros
Try to avoid private macros unless strictly necessary. Remember to #undef

View File

@@ -1,6 +1,4 @@
----
Title: Cairo interaction
----
## Functions to support using cairo

View File

@@ -107,4 +107,5 @@ content_images = [
"images/popup-flip.png",
"images/popup-slide.png",
]
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gdk/"
urlmap_file = "urlmap.js"

View File

@@ -1,4 +1,4 @@
Title: Key Values
Title: Keyboard Codes, Groups, And Modifiers
## Functions for manipulating keyboard codes
@@ -8,19 +8,19 @@ The complete list of key values can be found in the [`gdk/gdkkeysyms.h`](https:/
file.
Key values are regularly updated from the upstream X.org X11 implementation,
so new values are added regularly. They will be prefixed with GDK_KEY_ rather
than XF86XK_ or XK_ (for older symbols).
so new values are added regularly. They will be prefixed with `GDK_KEY_` rather
than `XF86XK_` or `XK_` (for older symbols).
Key values can be converted into a string representation using
gdk_keyval_name(). The reverse function, converting a string to a key value,
is provided by gdk_keyval_from_name().
[`func@Gdk.keyval_name`]. The reverse function, converting a string to a key
value, is provided by [`func@Gdk.keyval_from_name`].
The case of key values can be determined using gdk_keyval_is_upper() and
gdk_keyval_is_lower(). Key values can be converted to upper or lower case
using gdk_keyval_to_upper() and gdk_keyval_to_lower().
The case of key values can be determined using [`func@Gdk.keyval_is_upper`]
and [`func@Gdk.keyval_is_lower`]. Key values can be converted to upper or lower
case using [`func@Gdk.keyval_to_upper`] and [`func@Gdk.keyval_to_lower`].
When it makes sense, key values can be converted to and from
Unicode characters with gdk_keyval_to_unicode() and gdk_unicode_to_keyval().
When it makes sense, key values can be converted to and from Unicode characters
with [`func@Gdk.keyval_to_unicode`] and [`func@Gdk.unicode_to_keyval`].
## Key groups
@@ -36,23 +36,23 @@ You can think of a [struct@Gdk.KeymapKey] as a representation of a symbol
printed on a physical keyboard key. That is, it contains three pieces of
information:
1. first, it contains the hardware keycode; this is an identifying number
for a physical key
1. second, it contains the “level” of the key. The level indicates which
symbol on the key will be used, in a vertical direction. So on a standard
US keyboard, the key with the number “1“ on it also has the exclamation
point (”!”) character on it. The level indicates whether to use the “1”
or the “!” symbol. The letter keys are considered to have a lowercase
letter at level 0, and an uppercase letter at level 1, though normally
only the uppercase letter is printed on the key
1. third, the [struct@Gdk.KeymapKey] contains a group; groups are not used on
standard US keyboards, but are used in many other countries. On a
keyboard with groups, there can be 3 or 4 symbols printed on a single
key. The group indicates movement in a horizontal direction. Usually
groups are used for two different languages. In group 0, a key might
have two English characters, and in group 1 it might have two Hebrew
characters. The Hebrew characters will be printed on the key next to
the English characters.
1. first, it contains the hardware keycode; this is an identifying number
for a physical key
1. second, it contains the “level” of the key. The level indicates which
symbol on the key will be used, in a vertical direction. So on a standard
US keyboard, the key with the number “1“ on it also has the exclamation
point (”!”) character on it. The level indicates whether to use the “1”
or the “!” symbol. The letter keys are considered to have a lowercase
letter at level 0, and an uppercase letter at level 1, though normally
only the uppercase letter is printed on the key
1. third, the [struct@Gdk.KeymapKey] contains a group; groups are not used on
standard US keyboards, but are used in many other countries. On a
keyboard with groups, there can be 3 or 4 symbols printed on a single
key. The group indicates movement in a horizontal direction. Usually
groups are used for two different languages. In group 0, a key might
have two English characters, and in group 1 it might have two Hebrew
characters. The Hebrew characters will be printed on the key next to
the English characters.
When GDK creates a key event in order to deliver a key press or release,
it first converts the current keyboard state into an effective group and
@@ -72,7 +72,7 @@ in the key event and can be obtained via [class@Gdk.KeyEvent] getters.
### Consumed modifiers
The `consumed_modifiers` in a key event are modifiers that should be masked
out from @state when comparing this key press to a hot key. For instance,
out from `@state` when comparing this key press to a hot key. For instance,
on a US keyboard, the `plus` symbol is shifted, so when comparing a key
press to a `<Control>plus` accelerator `<Shift>` should be masked out.
@@ -91,9 +91,8 @@ if (keyval == GDK_PLUS &&
```
An older interpretation of `consumed_modifiers` was that it contained
all modifiers that might affect the translation of the key;
this allowed accelerators to be stored with irrelevant consumed
modifiers, by doing:
all modifiers that might affect the translation of the key; this allowed
accelerators to be stored with irrelevant consumed modifiers, by doing:
```c
// XXX Dont do this XXX
@@ -102,12 +101,11 @@ if (keyval == accel_keyval &&
// Accelerator was pressed
```
However, this did not work if multi-modifier combinations were
used in the keymap, since, for instance, `<Control>` would be
masked out even if only `<Control><Alt>` was used in
the keymap. To support this usage as well as well as possible, all single
modifier combinations that could affect the key for any combination
of modifiers will be returned in `consumed_modifiers`; multi-modifier
combinations are returned only when actually found in `state`. When
you store accelerators, you should always store them with consumed
However, this did not work if multi-modifier combinations were used in the
keymap, since, for instance, `<Control>` would be masked out even if only
`<Control><Alt>` was used in the keymap. To support this usage as well as
well as possible, all single modifier combinations that could affect the key
for any combination of modifiers will be returned in `consumed_modifiers`;
multi-modifier combinations are returned only when actually found in `state`.
When you store accelerators, you should always store them with consumed
modifiers removed. Store `<Control>plus`, not `<Control><Shift>plus`.

View File

@@ -1,4 +1,4 @@
Title: Pango Interaction
Title: Pango Interaction
Pango is the text layout system used by GDK and GTK. The functions
and types in this section are used to obtain clip regions for

View File

@@ -62,4 +62,5 @@ content_images = [
"images/stroke-miter.png",
"images/stroke-round.png",
]
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gsk/"
urlmap_file = "urlmap.js"

View File

@@ -1,8 +1,6 @@
Title: Compiling the GTK Libraries
Title: Building GTK
Slug: gtk-building
## Building GTK
Before we get into the details of how to compile GTK, we should
mention that in many cases, binary packages of GTK prebuilt for
your operating system will be available, either from your

View File

@@ -1,8 +1,6 @@
Title: Coordinate systems
Title: Coordinate systems in GTK
Slug: gtk-coordinates
## Coordinate systems in GTK
All coordinate systems in GTK have the origin at the top left, with the X axis
pointing right, and the Y axis pointing down. This matches the convention used
in X11, Wayland and cairo, but differs from OpenGL and PostScript, where the origin

View File

@@ -41,7 +41,7 @@ activate (GtkApplication* app,
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show (window);
gtk_window_present (GTK_WINDOW (window));
}
int
@@ -183,7 +183,7 @@ activate (GtkApplication *app,
gtk_box_append (GTK_BOX (box), button);
gtk_widget_show (window);
gtk_window_present (GTK_WINDOW (window));
}
int
@@ -331,8 +331,7 @@ activate (GtkApplication *app,
*/
gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1);
gtk_widget_show (window);
gtk_window_present (GTK_WINDOW (window));
}
int
@@ -554,7 +553,7 @@ activate (GtkApplication *app,
g_signal_connect (press, "pressed", G_CALLBACK (pressed), drawing_area);
gtk_widget_show (window);
gtk_window_present (GTK_WINDOW (window));
}
int
@@ -631,7 +630,7 @@ activate (GtkApplication *app,
button = gtk_builder_get_object (builder, "quit");
g_signal_connect_swapped (button, "clicked", G_CALLBACK (quit_cb), window);
gtk_widget_show (GTK_WIDGET (window));
gtk_widget_set_visible (GTK_WIDGET (window), TRUE);
/* We do not need the builder any more */
g_object_unref (builder);

View File

@@ -35,6 +35,11 @@ Showing
The ``show`` command displays the rendernode.
``--undecorated``
Removes window decorations. This is meant for rendering of exactly the rendernode
without any titlebar.
Rendering
^^^^^^^^^

View File

@@ -245,4 +245,5 @@ content_images = [
"images/box-model-light.png",
"images/box-model-dark.png",
]
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gtk/"
urlmap_file = "urlmap.js"

View File

@@ -1,8 +1,6 @@
----
Title: Initialization
----
Title: Initializing GTK
# Library initialization and main loop
## Library initialization and main loop
Before using GTK, you need to initialize it using [func@Gtk.init]; this
connects to the windowing system, sets up the locale and performs other
@@ -49,7 +47,7 @@ main (int argc, char **argv)
// ...
// Show the application window
gtk_widget_show (window);
gtk_window_present (GTK_WINDOW (window));
// Enter the main event loop, and wait for user interaction
while (!done)
@@ -66,5 +64,5 @@ as spinning the main loop.
### See also
- the GLib manual, especially `GMainLoop`
- signal-related functions, such as `g_signal_connect()` in GObject
- the GLib manual, especially `GMainLoop`
- signal-related functions, such as `g_signal_connect()` in GObject

View File

@@ -2,5 +2,6 @@ Title: Migrating from GTK 2.x to GTK 4
Slug: gtk-migrating-2-to-4
If your application is still using GTK 2, you should first convert it to GTK 3,
by following the [migration guide](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
in the GTK 3 documentation, and then follow [these instructions](#gtk-migrating-3-to-4).
by following the [migration guide](https://docs.gtk.org/gtk3/migrating-2to3.html)
in the GTK 3 documentation, and then follow [the GTK 3 to 4 migration
guide](migrating-3to4.html).

View File

@@ -31,10 +31,11 @@ for GTK, available on GitLab.
If you want to discuss your approach before or after working on it,
good ways to contact the GTK developers, apart from GitLab issues,
are
are:
- the #gtk IRC channel on irc.gnome.org
- the gtk tag on the [GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
- the `#gtk:gnome.org` Matrix room
- the `#gtk` IRC channel on `irc.libera.chat`
You should not send patches by email, as they will inevitably get lost,
or forgotten. Always open a merge request.

View File

@@ -170,40 +170,46 @@ This variable can be set to a list of debug options, which cause GDK to
print out different types of debugging information. Some of these options
are only available when GTK has been configured with `-Ddebug=true`.
`cursor`
: Information about cursor objects (only win32)
`misc`
: Miscellaneous information
`events`
: Information about events
`dnd`
: Information about drag-and-drop
`input`
: Information about input (mostly Windows)
`eventloop`
: Information about event loop operation (mostly macOS)
`misc`
: Miscellaneous information
`frames`
: Information about the frame clock
`settings`
: Information about xsettings
`selection`
: Information about selections
`clipboard`
: Information about clipboards
`dnd`
: Information about drag-and-drop
`opengl`
: Information about OpenGL
`vulkan`
: Information about Vulkan
A number of options affect behavior instead of logging:
`selection`
: Information about selections
`nograbs`
: Turn off all pointer and keyboard grabs
`clipboard`
: Information about clipboards
`dmabuf`
: Information about dmabuf handling (Linux-only)
`offload`
: Information about subsurfaces and graphics offload (Wayland-only)
A number of options affect behavior instead of logging:
`portals`
: Force the use of [portals](https://docs.flatpak.org/en/latest/portals.html)
@@ -217,11 +223,17 @@ A number of options affect behavior instead of logging:
`gl-fractional`
: Enable fractional scaling for OpenGL. This is experimental
`gl-legacy`
: Use a legacy OpenGL context
`gl-debug`
: Insert debugging information in OpenGL
`gl-gles`
: Use a GLES OpenGL context
`gl-disable-gl`
: Don't allow the use of OpenGL GL API. This forces GLES to be used
`gl-disable-gles`
: Don't allow the use of OpenGL GLES API. This forces GL to be used
`gl-prefer-gl`
: Prefer OpenGL over OpenGL ES. This was the default behavior before GTK 4.14.
`gl-egl`
: Use an EGL context on X11 or Windows
@@ -244,6 +256,12 @@ A number of options affect behavior instead of logging:
`high-depth`
: Use high bit depth rendering if possible
`no-vsync`
: Repaint instantly (uses 100% CPU with animations)
`dmabuf-disable`
: Disable dmabuf support
The special value `all` can be used to turn on all debug options. The special
value `help` can be used to obtain a list of all supported debug options.
@@ -291,6 +309,9 @@ A number of options affect behavior instead of logging:
`sync`
: Sync after each frame
`offload-disable`
: Disable graphics offload to subsurfaces
`vulkan-staging-image`
: Use a staging image for Vulkan texture upload

View File

@@ -209,13 +209,11 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
timings->complete = TRUE;
#ifdef G_ENABLE_DEBUG
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
_gdk_frame_clock_debug_print_timings (clock, timings);
if (GDK_PROFILER_IS_RUNNING)
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
#endif
}
}

View File

@@ -369,14 +369,12 @@ portal_file_serializer (GdkContentSerializer *serializer)
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
g_ptr_array_add (files, g_file_get_path (file));
}
#ifdef G_ENABLE_DEBUG
else if (GDK_DEBUG_CHECK (DND))
{
char *uri = g_file_get_uri (file);
gdk_debug_message ("file transfer portal: %s has no path, dropping\n", uri);
g_free (uri);
}
#endif
g_ptr_array_add (files, NULL);
}
@@ -426,14 +424,12 @@ portal_finish (GObject *object,
return;
}
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (DND))
{
char *s = g_strjoinv (", ", files);
gdk_debug_message ("file transfer portal: Receiving files: %s", s);
g_free (s);
}
#endif
value = gdk_content_deserializer_get_value (deserializer);
if (G_VALUE_HOLDS (value, G_TYPE_FILE))

View File

@@ -117,22 +117,26 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE },
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)", TRUE },
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE },
{ "gl-gles", GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API", TRUE },
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows", TRUE },
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11", TRUE },
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows", TRUE },
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support", TRUE },
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer", TRUE },
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
{ "offload", GDK_DEBUG_OFFLOAD, "Information about subsurfaces and graphics offload" },
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals" },
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals" },
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)" },
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
{ "gl-disable-gl", GDK_DEBUG_GL_DISABLE_GL, "Only allow OpenGL GLES API" },
{ "gl-disable-gles", GDK_DEBUG_GL_DISABLE_GLES, "Don't allow OpenGL GLES API" },
{ "gl-prefer-gl", GDK_DEBUG_GL_PREFER_GL, "Prefer GL over GLES API" },
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows" },
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11" },
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows" },
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible" },
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)" },
{ "dmabuf-disable", GDK_DEBUG_DMABUF_DISABLE, "Disable dmabuf support" },
};
@@ -193,13 +197,6 @@ gdk_parse_debug_var (const char *variable,
const char *q;
gboolean invert;
gboolean help;
gboolean debug_enabled;
#ifdef G_ENABLE_DEBUG
debug_enabled = TRUE;
#else
debug_enabled = FALSE;
#endif
string = g_getenv (variable);
if (string == NULL)
@@ -231,12 +228,6 @@ gdk_parse_debug_var (const char *variable,
if (strlen (keys[i].key) == q - p &&
g_ascii_strncasecmp (keys[i].key, p, q - p) == 0)
{
if (!debug_enabled && !keys[i].always_enabled)
{
fprintf (stderr, "\"%s\" is only available when building GTK with G_ENABLE_DEBUG. See %s=help\n",
val, variable);
break;
}
result |= keys[i].value;
break;
}
@@ -260,10 +251,9 @@ gdk_parse_debug_var (const char *variable,
fprintf (stderr, "Supported %s values:\n", variable);
for (i = 0; i < nkeys; i++) {
if (debug_enabled || keys[i].always_enabled)
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
}
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values");
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values. Other given values are subtracted");
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n");
}
@@ -274,8 +264,7 @@ gdk_parse_debug_var (const char *variable,
for (i = 0; i < nkeys; i++)
{
if (debug_enabled || keys[i].always_enabled)
all_flags |= keys[i].value;
all_flags |= keys[i].value;
}
result = all_flags & (~result);

View File

@@ -42,6 +42,9 @@
#include <gdk/gdkdevicetool.h>
#include <gdk/gdkdisplay.h>
#include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdmabufformats.h>
#include <gdk/gdkdmabuftexture.h>
#include <gdk/gdkdmabuftexturebuilder.h>
#include <gdk/gdkdrag.h>
#include <gdk/gdkdragsurface.h>
#include <gdk/gdkdragsurfacesize.h>

View File

@@ -183,7 +183,7 @@ gdk_array(reserve) (GdkArray *self,
return;
size = gdk_array(get_size) (self);
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
new_size = ((gsize) 1) << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
#ifdef GDK_ARRAY_PREALLOC
if (self->start == self->preallocated)
@@ -215,7 +215,11 @@ gdk_array(splice) (GdkArray *self,
gsize pos,
gsize removed,
gboolean stolen,
#ifdef GDK_ARRAY_BY_VALUE
const _T_ *additions,
#else
_T_ *additions,
#endif
gsize added)
{
gsize size;
@@ -318,3 +322,5 @@ gdk_array(get) (const GdkArray *self,
#undef GDK_ARRAY_TYPE_NAME
#undef GDK_ARRAY_NO_MEMSET
#endif
G_END_DECLS

View File

@@ -36,23 +36,28 @@ typedef enum {
GDK_DEBUG_VULKAN = 1 << 8,
GDK_DEBUG_SELECTION = 1 << 9,
GDK_DEBUG_CLIPBOARD = 1 << 10,
GDK_DEBUG_DMABUF = 1 << 11,
GDK_DEBUG_OFFLOAD = 1 << 12,
/* flags below are influencing behavior */
GDK_DEBUG_NOGRABS = 1 << 11,
GDK_DEBUG_PORTALS = 1 << 12,
GDK_DEBUG_NO_PORTALS = 1 << 13,
GDK_DEBUG_GL_DISABLE = 1 << 14,
GDK_DEBUG_GL_FRACTIONAL = 1 << 15,
GDK_DEBUG_GL_LEGACY = 1 << 16,
GDK_DEBUG_GL_GLES = 1 << 17,
GDK_DEBUG_GL_DEBUG = 1 << 18,
GDK_DEBUG_GL_EGL = 1 << 19,
GDK_DEBUG_GL_GLX = 1 << 20,
GDK_DEBUG_GL_WGL = 1 << 21,
GDK_DEBUG_VULKAN_DISABLE = 1 << 22,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
GDK_DEBUG_NO_VSYNC = 1 << 26,
GDK_DEBUG_PORTALS = 1 << 14,
GDK_DEBUG_NO_PORTALS = 1 << 15,
GDK_DEBUG_GL_DISABLE = 1 << 16,
GDK_DEBUG_GL_FRACTIONAL = 1 << 17,
GDK_DEBUG_GL_DISABLE_GL = 1 << 19,
GDK_DEBUG_GL_DISABLE_GLES = 1 << 20,
GDK_DEBUG_GL_PREFER_GL = 1 << 21,
GDK_DEBUG_GL_DEBUG = 1 << 22,
GDK_DEBUG_GL_EGL = 1 << 23,
GDK_DEBUG_GL_GLX = 1 << 24,
GDK_DEBUG_GL_WGL = 1 << 25,
GDK_DEBUG_VULKAN_DISABLE = 1 << 26,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 27,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 28,
GDK_DEBUG_HIGH_DEPTH = 1 << 29,
GDK_DEBUG_NO_VSYNC = 1 << 30,
GDK_DEBUG_DMABUF_DISABLE = 1 << 31,
} GdkDebugFlags;
extern guint _gdk_debug_flags;
@@ -61,13 +66,24 @@ GdkDebugFlags gdk_display_get_debug_flags (GdkDisplay *display);
void gdk_display_set_debug_flags (GdkDisplay *display,
GdkDebugFlags flags);
#ifdef GLIB_USING_SYSTEM_PRINTF
#define gdk_debug_message(format, ...) fprintf (stderr, format "\n", ##__VA_ARGS__)
#else
#define gdk_debug_message(format, ...) g_fprintf (stderr, format "\n", ##__VA_ARGS__)
#endif
static inline void
gdk_debug_message (const char *format, ...) G_GNUC_PRINTF(1, 2);
static inline void
gdk_debug_message (const char *format, ...)
{
va_list args;
char *s;
#ifdef G_ENABLE_DEBUG
va_start (args, format);
s = g_strdup_vprintf (format, args);
va_end (args);
#ifdef GLIB_USING_SYSTEM_PRINTF
fprintf (stderr, "%s\n", s);
#else
g_fprintf (stderr, "%s\n", s);
#endif
g_free (s);
}
#define GDK_DISPLAY_DEBUG_CHECK(display,type) \
G_UNLIKELY (gdk_display_get_debug_flags (display) & GDK_DEBUG_##type)
@@ -78,13 +94,6 @@ void gdk_display_set_debug_flags (GdkDisplay *display,
gdk_debug_message (__VA_ARGS__); \
} G_STMT_END
#else /* !G_ENABLE_DEBUG */
#define GDK_DISPLAY_DEBUG_CHECK(display,type) 0
#define GDK_DISPLAY_DEBUG(display,type,...)
#endif /* G_ENABLE_DEBUG */
#define GDK_DEBUG_CHECK(type) GDK_DISPLAY_DEBUG_CHECK (NULL,type)
#define GDK_DEBUG(type,...) GDK_DISPLAY_DEBUG (NULL,type,__VA_ARGS__)
@@ -93,7 +102,6 @@ typedef struct
const char *key;
guint value;
const char *help;
gboolean always_enabled;
} GdkDebugKey;
guint gdk_parse_debug_var (const char *variable,

View File

@@ -31,6 +31,9 @@
#include "gdkclipboardprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdisplaymanagerprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkeventsprivate.h"
#include "gdkframeclockidleprivate.h"
#include "gdkglcontextprivate.h"
@@ -41,6 +44,11 @@
#ifdef HAVE_EGL
#include <epoxy/egl.h>
#endif
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#include <math.h>
#include <stdlib.h>
@@ -69,6 +77,7 @@ enum
PROP_COMPOSITED,
PROP_RGBA,
PROP_INPUT_SHAPES,
PROP_DMABUF_FORMATS,
LAST_PROP
};
@@ -138,6 +147,10 @@ gdk_display_get_property (GObject *object,
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
break;
case PROP_DMABUF_FORMATS:
g_value_set_boxed (value, gdk_display_get_dmabuf_formats (display));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -239,6 +252,11 @@ gdk_display_class_init (GdkDisplayClass *class)
TRUE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
props[PROP_DMABUF_FORMATS] =
g_param_spec_boxed ("dmabuf-formats", NULL, NULL,
GDK_TYPE_DMABUF_FORMATS,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, props);
/**
@@ -378,6 +396,10 @@ gdk_display_dispose (GObject *object)
g_queue_clear (&display->queued_events);
g_clear_object (&display->egl_gsk_renderer);
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
g_clear_object (&priv->gl_context);
#ifdef HAVE_EGL
g_clear_pointer (&priv->egl_display, eglTerminate);
@@ -404,6 +426,8 @@ gdk_display_finalize (GObject *object)
g_list_free_full (display->seats, g_object_unref);
g_clear_pointer (&display->dmabuf_formats, gdk_dmabuf_formats_unref);
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
}
@@ -1409,7 +1433,6 @@ gdk_display_get_gl_context (GdkDisplay *self)
}
#ifdef HAVE_EGL
#ifdef G_ENABLE_DEBUG
static int
strvcmp (gconstpointer p1,
gconstpointer p2)
@@ -1466,7 +1489,6 @@ describe_egl_config (EGLDisplay egl_display,
return g_strdup_printf ("R%dG%dB%dA%d%s", red, green, blue, alpha, type == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT ? "" : " float");
}
#endif
gpointer
gdk_display_get_egl_config (GdkDisplay *self)
@@ -1670,6 +1692,23 @@ gdk_display_check_egl_extensions (EGLDisplay egl_display,
return TRUE;
}
static const char *
find_egl_device (EGLDisplay egl_display)
{
EGLAttrib value;
EGLDeviceEXT egl_device;
eglQueryDisplayAttribEXT (egl_display, EGL_DEVICE_EXT, &value);
egl_device = (EGLDeviceEXT)value;
#ifndef EGL_DRM_RENDER_NODE_FILE_EXT
#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377
#endif
return eglQueryDeviceStringEXT (egl_device, EGL_DRM_RENDER_NODE_FILE_EXT);
}
gboolean
gdk_display_init_egl (GdkDisplay *self,
int platform,
@@ -1755,6 +1794,10 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
self->have_egl_pixel_format_float =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
self->have_egl_dma_buf_import =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_image_dma_buf_import_modifiers");
self->have_egl_dma_buf_export =
epoxy_has_egl_extension (priv->egl_display, "EGL_MESA_image_dma_buf_export");
if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
@@ -1763,15 +1806,22 @@ gdk_display_init_egl (GdkDisplay *self,
if (priv->egl_config_high_depth == NULL)
priv->egl_config_high_depth = priv->egl_config;
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (self, OPENGL))
{
char *ext = describe_extensions (priv->egl_display);
char *std_cfg = describe_egl_config (priv->egl_display, priv->egl_config);
char *hd_cfg = describe_egl_config (priv->egl_display, priv->egl_config_high_depth);
const char *path;
struct stat buf = { .st_rdev = 0, };
path = find_egl_device (priv->egl_display);
if (path)
stat (path, &buf);
gdk_debug_message ("EGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Version: %s\n"
" - Device: %s, %d %d\n"
" - Client APIs: %s\n"
" - Extensions:\n"
"\t%s\n"
@@ -1780,6 +1830,12 @@ gdk_display_init_egl (GdkDisplay *self,
major, minor,
eglQueryString (priv->egl_display, EGL_VENDOR),
eglQueryString (priv->egl_display, EGL_VERSION),
path ? path : "unknown",
#ifdef HAVE_SYS_SYSMACROS_H
major (buf.st_rdev), minor (buf.st_rdev),
#else
0, 0,
#endif
eglQueryString (priv->egl_display, EGL_CLIENT_APIS),
ext, std_cfg,
priv->egl_config_high_depth == priv->egl_config ? "none" : hd_cfg);
@@ -1787,7 +1843,6 @@ gdk_display_init_egl (GdkDisplay *self,
g_free (std_cfg);
g_free (ext);
}
#endif
gdk_profiler_end_mark (start_time, "init EGL", NULL);
@@ -1824,6 +1879,94 @@ gdk_display_get_egl_display (GdkDisplay *self)
#endif
}
#ifdef HAVE_DMABUF
static void
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
const GdkDmabufDownloader *downloader,
GdkDmabufFormatsBuilder *builder)
{
gsize i;
if (!downloader->add_formats (downloader, display, builder))
return;
/* dmabuf_downloaders is NULL-terminated */
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
{
if (display->dmabuf_downloaders[i] == NULL)
break;
}
g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders));
display->dmabuf_downloaders[i] = downloader;
}
#endif
/* To support a drm format, we must be able to import it into GL
* using the relevant EGL extensions, and download it into a memory
* texture, possibly doing format conversion with shaders (in GSK).
*/
void
gdk_display_init_dmabuf (GdkDisplay *self)
{
GdkDmabufFormatsBuilder *builder;
if (self->dmabuf_formats != NULL)
return;
GDK_DISPLAY_DEBUG (self, DMABUF,
"Beginning initialization of dmabuf support");
builder = gdk_dmabuf_formats_builder_new ();
#ifdef HAVE_DMABUF
if (!GDK_DISPLAY_DEBUG_CHECK (self, DMABUF_DISABLE))
{
gdk_display_prepare_gl (self, NULL);
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder);
#ifdef HAVE_EGL
if (gdk_display_prepare_gl (self, NULL))
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder);
#endif
}
#endif
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
GDK_DISPLAY_DEBUG (self, DMABUF,
"Initialized support for %zu dmabuf formats",
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
}
/**
* gdk_display_get_dmabuf_formats:
* @display: a `GdkDisplay`
*
* Returns the dma-buf formats that are supported on this display.
*
* GTK may use OpenGL or Vulkan to support some formats.
* Calling this function will then initialize them if they aren't yet.
*
* The formats returned by this function can be used for negotiating
* buffer formats with producers such as v4l, pipewire or GStreamer.
*
* To learn more about dma-bufs, see [class@Gdk.DmabufTextureBuilder].
*
* Returns: (transfer none): a `GdkDmabufFormats` object
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display)
{
gdk_display_init_dmabuf (display);
return display->dmabuf_formats;
}
GdkDebugFlags
gdk_display_get_debug_flags (GdkDisplay *display)
{

View File

@@ -134,6 +134,10 @@ gboolean gdk_display_get_setting (GdkDisplay *display,
const char *name,
GValue *value);
GDK_AVAILABLE_IN_4_14
GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
G_END_DECLS

View File

@@ -25,6 +25,7 @@
#include "gdksurfaceprivate.h"
#include "gdkkeysprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdmabufprivate.h"
#ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h>
@@ -113,6 +114,16 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
guint have_egl_dma_buf_import : 1;
guint have_egl_dma_buf_export : 1;
GdkDmabufFormats *dmabuf_formats;
const GdkDmabufDownloader *dmabuf_downloaders[4];
/* Cached data the EGL dmabuf downloader */
gpointer egl_gsk_renderer;
GdkDmabufFormats *egl_dmabuf_formats;
GdkDmabufFormats *egl_external_formats;
};
struct _GdkDisplayClass
@@ -207,6 +218,8 @@ gulong _gdk_display_get_next_serial (GdkDisplay *display
void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_events (GdkDisplay *display);
void gdk_display_init_dmabuf (GdkDisplay *self);
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
GError **error);

1080
gdk/gdkdmabuf.c Normal file

File diff suppressed because it is too large Load Diff

346
gdk/gdkdmabufegl.c Normal file
View File

@@ -0,0 +1,346 @@
/* gdkdmabufegl.c
*
* Copyright 2023 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 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/>.
*/
#include "config.h"
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
#include "gdkdmabufprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkglcontextprivate.h"
#include "gdktexturedownloader.h"
#include <graphene.h>
#include <epoxy/egl.h>
/* A dmabuf downloader implementation that downloads buffers via
* gsk_renderer_render_texture + GL texture download.
*/
static gboolean
gdk_dmabuf_egl_downloader_collect_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *formats,
GdkDmabufFormatsBuilder *external)
{
GdkGLContext *context = gdk_display_get_gl_context (display);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
int num_fourccs;
int *fourccs;
guint64 *modifiers;
unsigned int *external_only;
int n_mods;
if (egl_display == EGL_NO_DISPLAY ||
!display->have_egl_dma_buf_import)
return FALSE;
gdk_gl_context_make_current (context);
eglQueryDmaBufFormatsEXT (egl_display, 0, NULL, &num_fourccs);
fourccs = g_new (int, num_fourccs);
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);
for (int i = 0; i < num_fourccs; i++)
{
int num_modifiers;
gboolean all_external;
eglQueryDmaBufModifiersEXT (egl_display,
fourccs[i],
0,
NULL,
NULL,
&num_modifiers);
if (num_modifiers > n_mods)
{
n_mods = num_modifiers;
modifiers = g_renew (guint64, modifiers, n_mods);
external_only = g_renew (unsigned int, external_only, n_mods);
}
eglQueryDmaBufModifiersEXT (egl_display,
fourccs[i],
num_modifiers,
modifiers,
external_only,
&num_modifiers);
all_external = TRUE;
for (int j = 0; j < num_modifiers; j++)
{
/* All linear formats we support are already added my 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%s dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
external_only[j] ? "external " : "",
downloader->name,
(char *) &fourccs[i],
modifiers[j]);
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
}
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.
* This is a bit of a crapshot, but unfortunately needed for a bunch
* of drivers.
*
* As an extra wrinkle, treat the implicit modifier as 'external only'
* if all formats with the same fourcc are 'external only'.
*/
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);
}
g_free (modifiers);
g_free (external_only);
g_free (fourccs);
return TRUE;
}
static gboolean
gdk_dmabuf_egl_downloader_add_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder)
{
GdkDmabufFormatsBuilder *formats;
GdkDmabufFormatsBuilder *external;
gboolean retval = FALSE;
g_assert (display->egl_dmabuf_formats == NULL);
g_assert (display->egl_external_formats == NULL);
formats = gdk_dmabuf_formats_builder_new ();
external = gdk_dmabuf_formats_builder_new ();
retval = gdk_dmabuf_egl_downloader_collect_formats (downloader, display, formats, external);
display->egl_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (formats);
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_dmabuf_formats);
return retval;
}
static gboolean
gdk_dmabuf_egl_downloader_supports (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error)
{
if (gdk_dmabuf_formats_contains (display->egl_dmabuf_formats, dmabuf->fourcc, dmabuf->modifier))
{
if (!gdk_dmabuf_get_memory_format (dmabuf->fourcc, premultiplied, out_format))
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Falling back to generic ARGB for dmabuf format %.4s",
(char *) &dmabuf->fourcc);
*out_format = premultiplied ? GDK_MEMORY_R8G8B8A8_PREMULTIPLIED
: GDK_MEMORY_R8G8B8A8;
}
return TRUE;
}
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);
return FALSE;
}
/* Hack. We don't include gsk/gsk.h here to avoid a build order problem
* with the generated header gskenumtypes.h, so we need to hack around
* a bit to access the gsk api we need.
*/
typedef gpointer GskRenderer;
extern GskRenderer * gsk_gl_renderer_new (void);
extern gboolean gsk_renderer_realize (GskRenderer *renderer,
GdkSurface *surface,
GError **error);
extern GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
GdkTexture *texture);
typedef void (* InvokeFunc) (gpointer data);
typedef struct _InvokeData
{
volatile int spinlock;
InvokeFunc func;
gpointer data;
} InvokeData;
static gboolean
gdk_dmabuf_egl_downloader_invoke_callback (gpointer data)
{
InvokeData *invoke = data;
GdkGLContext *previous;
previous = gdk_gl_context_get_current ();
invoke->func (invoke->data);
if (previous)
gdk_gl_context_make_current (previous);
else
gdk_gl_context_clear_current ();
g_atomic_int_set (&invoke->spinlock, 1);
return FALSE;
}
/* Run func in the main thread, taking care not to disturb
* the current GL context of the caller.
*/
static void
gdk_dmabuf_egl_downloader_run (InvokeFunc func,
gpointer data)
{
InvokeData invoke = { 0, func, data };
g_main_context_invoke (NULL, gdk_dmabuf_egl_downloader_invoke_callback, &invoke);
while (g_atomic_int_get (&invoke.spinlock) == 0) ;
}
typedef struct _Download Download;
struct _Download
{
GdkDmabufTexture *texture;
GdkMemoryFormat format;
guchar *data;
gsize stride;
};
static GskRenderer *
get_gsk_renderer (GdkDisplay *display)
{
if (!display->egl_gsk_renderer)
{
GskRenderer *renderer;
GError *error = NULL;
renderer = gsk_gl_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, &error))
{
g_warning ("Failed to realize GL renderer: %s", error->message);
g_error_free (error);
g_object_unref (renderer);
return NULL;
}
display->egl_gsk_renderer = renderer;
}
return display->egl_gsk_renderer;
}
static void
gdk_dmabuf_egl_downloader_do_download (gpointer data)
{
Download *download = data;
GdkDisplay *display;
GskRenderer *renderer;
GdkTexture *native;
GdkTextureDownloader *downloader;
display = gdk_dmabuf_texture_get_display (download->texture);
renderer = get_gsk_renderer (display);
native = gsk_renderer_convert_texture (renderer, GDK_TEXTURE (download->texture));
downloader = gdk_texture_downloader_new (native);
gdk_texture_downloader_set_format (downloader, download->format);
gdk_texture_downloader_download_into (downloader, download->data, download->stride);
gdk_texture_downloader_free (downloader);
g_object_unref (native);
}
static void
gdk_dmabuf_egl_downloader_download (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
Download download;
const GdkDmabuf *dmabuf;
download.texture = GDK_DMABUF_TEXTURE (texture);
download.format = format;
download.data = data;
download.stride = stride;
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (download.texture), DMABUF,
"Using %s for downloading a dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
downloader->name, (char *)&dmabuf->fourcc, dmabuf->modifier);
gdk_dmabuf_egl_downloader_run (gdk_dmabuf_egl_downloader_do_download, &download);
}
const GdkDmabufDownloader *
gdk_dmabuf_get_egl_downloader (void)
{
static const GdkDmabufDownloader downloader = {
"egl",
gdk_dmabuf_egl_downloader_add_formats,
gdk_dmabuf_egl_downloader_supports,
gdk_dmabuf_egl_downloader_download,
};
return &downloader;
}
#endif /* HAVE_DMABUF && HAVE_EGL */

219
gdk/gdkdmabufformats.c Normal file
View File

@@ -0,0 +1,219 @@
/* gdkdmabufformats.c
*
* Copyright 2023 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 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/>.
*/
#include <config.h>
#include <glib-object.h>
#include "gdkdmabufformatsprivate.h"
/**
* GdkDmabufFormats:
*
* The `GdkDmabufFormats struct provides information about
* supported DMA buffer formats.
*
* You can query whether a given format is supported with
* [method@Gdk.DmabufFormats.contains] and you can iterate
* over the list of all supported formats with
* [method@Gdk.DmabufFormats.get_n_formats] and
* [method@Gdk.DmabufFormats.get_format].
*
* The list of supported formats is sorted by preference,
* with the best formats coming first.
*
* The list may contains (format, modfier) pairs where the modifier
* is `DMA_FORMAT_MOD_INVALID`, indicating that **_implicit modifiers_**
* may be used with this format.
*
* See [class@Gdk.DmabufTextureBuilder] for more information
* about DMA buffers.
*
* Note that DMA buffers only exist on Linux.
*
* Since: 4.14
*/
struct _GdkDmabufFormats
{
int ref_count;
gsize n_formats;
GdkDmabufFormat *formats;
};
G_DEFINE_BOXED_TYPE (GdkDmabufFormats, gdk_dmabuf_formats, gdk_dmabuf_formats_ref, gdk_dmabuf_formats_unref)
/**
* gdk_dmabuf_formats_ref:
* @formats: a `GdkDmabufFormats`
*
* Increases the reference count of @formats.
*
* Returns: the passed-in object
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_dmabuf_formats_ref (GdkDmabufFormats *formats)
{
formats->ref_count++;
return formats;
}
/**
* gdk_dmabuf_formats_unref:
* @formats: a `GdkDmabufFormats`
*
* Decreases the reference count of @formats.
*
* When the reference count reaches zero,
* the object is freed.
*
* Since: 4.14
*/
void
gdk_dmabuf_formats_unref (GdkDmabufFormats *formats)
{
formats->ref_count--;
if (formats->ref_count > 0)
return;
g_free (formats->formats);
g_free (formats);
}
/**
* gdk_dmabuf_formats_get_n_formats:
* @formats: a `GdkDmabufFormats`
*
* Returns the number of formats that the @formats object
* contains.
*
* Note that DMA buffers are a Linux concept, so on other
* platforms, [method@Gdk.DmabufFormats.get_n_formats] will
* always return zero.
*
* Returns: the number of formats
*
* Since: 4.14
*/
gsize
gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats)
{
return formats->n_formats;
}
/**
* gdk_dmabuf_formats_get_format:
* @formats: a `GdkDmabufFormats`
* @idx: the index of the format to return
* @fourcc: (out): return location for the format code
* @modifier: (out): return location for the format modifier
*
* Gets the fourcc code and modifier for a format
* that is contained in @formats.
*
* Since: 4.14
*/
void
gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
gsize idx,
guint32 *fourcc,
guint64 *modifier)
{
GdkDmabufFormat *format;
g_return_if_fail (idx < formats->n_formats);
g_return_if_fail (fourcc != NULL);
g_return_if_fail (modifier != NULL);
format = &formats->formats[idx];
*fourcc = format->fourcc;
*modifier = format->modifier;
}
/**
* gdk_dmabuf_format_contains:
* @formats: a `GdkDmabufFormats`
* @fourcc: a format code
* @modfier: a format modifier
*
* Returns whether a given format is contained in @formats.
*
* Returns: `TRUE` if the format specified by the arguments
* is part of @formats
*
* Since: 4.14
*/
gboolean
gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
guint32 fourcc,
guint64 modifier)
{
for (gsize i = 0; i < formats->n_formats; i++)
{
GdkDmabufFormat *format = &formats->formats[i];
if (format->fourcc == fourcc && format->modifier == modifier)
return TRUE;
}
return FALSE;
}
/*< private >
* gdk_dmabuf_formats_new:
* @formats: the formats
* @n_formats: the length of @formats
*
* Creates a new `GdkDmabufFormats struct for
* the given formats.
*
* The @formats array is expected to be sorted
* by preference.
*
* Returns: (transfer full): the new `GdkDmabufFormats`
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
gsize n_formats)
{
GdkDmabufFormats *self;
self = g_new0 (GdkDmabufFormats, 1);
self->ref_count = 1;
self->n_formats = n_formats;
self->formats = g_new (GdkDmabufFormat, n_formats);
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
return self;
}
const GdkDmabufFormat *
gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self)
{
return self->formats;
}

54
gdk/gdkdmabufformats.h Normal file
View File

@@ -0,0 +1,54 @@
/* gdkdmabufformats.h
*
* Copyright 2023 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 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/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_FORMATS (gdk_dmabuf_formats_get_type ())
GDK_AVAILABLE_IN_4_14
GType gdk_dmabuf_formats_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GdkDmabufFormats * gdk_dmabuf_formats_ref (GdkDmabufFormats *formats);
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_formats_unref (GdkDmabufFormats *formats);
GDK_AVAILABLE_IN_4_14
gsize gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
gsize idx,
guint32 *fourcc,
guint64 *modifier);
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
guint32 fourcc,
guint64 modifier) G_GNUC_PURE;
G_END_DECLS

View File

@@ -0,0 +1,134 @@
/* gdkdmabufformats.c
*
* Copyright 2023 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 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/>.
*/
#include <config.h>
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufformatsprivate.h"
#define GDK_ARRAY_NAME gdk_dmabuf_formats_builder
#define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder
#define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat
#define GDK_ARRAY_BY_VALUE 1
#define GDK_ARRAY_PREALLOC 1024
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
/* NB: We keep duplicates in the list for ease of use. Only when creating the final
* GdkDmabufFormats do we actually remove duplicates.
*/
GdkDmabufFormatsBuilder *
gdk_dmabuf_formats_builder_new (void)
{
GdkDmabufFormatsBuilder *result = g_new (GdkDmabufFormatsBuilder, 1);
gdk_dmabuf_formats_builder_init (result);
return result;
}
static int
gdk_dmabuf_format_compare (gconstpointer data_a,
gconstpointer data_b)
{
const GdkDmabufFormat *a = data_a;
const GdkDmabufFormat *b = data_b;
if (a->fourcc == b->fourcc)
return (a->modifier - b->modifier) >> 8 * (sizeof (gint64) - sizeof (gint));
else
return a->fourcc - b->fourcc;
}
static gboolean
gdk_dmabuf_format_equal (gconstpointer data_a,
gconstpointer data_b)
{
const GdkDmabufFormat *a = data_a;
const GdkDmabufFormat *b = data_b;
return a->fourcc == b->fourcc &&
a->modifier == b->modifier;
}
static void
gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
{
qsort (gdk_dmabuf_formats_builder_get_data (self),
gdk_dmabuf_formats_builder_get_size (self),
sizeof (GdkDmabufFormat),
gdk_dmabuf_format_compare);
}
/* list must be sorted */
static void
gdk_dmabuf_formats_builder_remove_duplicates (GdkDmabufFormatsBuilder *self)
{
gsize i, j;
for (i = 1, j = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
{
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i),
gdk_dmabuf_formats_builder_get (self, j)))
continue;
j++;
if (i != j)
*gdk_dmabuf_formats_builder_index (self, j) = *gdk_dmabuf_formats_builder_index (self, i);
}
}
GdkDmabufFormats *
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
{
GdkDmabufFormats *formats;
gdk_dmabuf_formats_builder_sort (self);
gdk_dmabuf_formats_builder_remove_duplicates (self);
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
gdk_dmabuf_formats_builder_get_size (self));
gdk_dmabuf_formats_builder_clear (self);
g_free (self);
return formats;
}
void
gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc,
guint64 modifier)
{
gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier });
}
void
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
GdkDmabufFormats *formats)
{
gdk_dmabuf_formats_builder_splice (self,
gdk_dmabuf_formats_builder_get_size (self),
0,
FALSE,
gdk_dmabuf_formats_peek_formats (formats),
gdk_dmabuf_formats_get_n_formats (formats));
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "gdkdmabufformats.h"
typedef struct GdkDmabufFormatsBuilder GdkDmabufFormatsBuilder;
GdkDmabufFormatsBuilder * gdk_dmabuf_formats_builder_new (void);
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc,
guint64 modifier);
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
GdkDmabufFormats *formats);

View File

@@ -0,0 +1,15 @@
#pragma once
#include "gdkdmabufformats.h"
typedef struct _GdkDmabufFormat GdkDmabufFormat;
struct _GdkDmabufFormat
{
guint32 fourcc;
guint64 modifier;
};
GdkDmabufFormats * gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
gsize n_formats);
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);

View File

@@ -0,0 +1,380 @@
#pragma once
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#ifndef fourcc_code
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
((__u32)(c) << 16) | ((__u32)(d) << 24))
#endif
#ifndef DRM_FORMAT_C1
#define DRM_FORMAT_C1 fourcc_code('C', '1', ' ', ' ')
#endif
#ifndef DRM_FORMAT_C2
#define DRM_FORMAT_C2 fourcc_code('C', '2', ' ', ' ')
#endif
#ifndef DRM_FORMAT_C4
#define DRM_FORMAT_C4 fourcc_code('C', '4', ' ', ' ')
#endif
#ifndef DRM_FORMAT_C8
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')
#endif
#ifndef DRM_FORMAT_D1
#define DRM_FORMAT_D1 fourcc_code('D', '1', ' ', ' ')
#endif
#ifndef DRM_FORMAT_D2
#define DRM_FORMAT_D2 fourcc_code('D', '2', ' ', ' ')
#endif
#ifndef DRM_FORMAT_D4
#define DRM_FORMAT_D4 fourcc_code('D', '4', ' ', ' ')
#endif
#ifndef DRM_FORMAT_D8
#define DRM_FORMAT_D8 fourcc_code('D', '8', ' ', ' ')
#endif
#ifndef DRM_FORMAT_R1
#define DRM_FORMAT_R1 fourcc_code('R', '1', ' ', ' ')
#endif
#ifndef DRM_FORMAT_R2
#define DRM_FORMAT_R2 fourcc_code('R', '2', ' ', ' ')
#endif
#ifndef DRM_FORMAT_R4
#define DRM_FORMAT_R4 fourcc_code('R', '4', ' ', ' ')
#endif
#ifndef DRM_FORMAT_R8
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
#endif
#ifndef DRM_FORMAT_R10
#define DRM_FORMAT_R10 fourcc_code('R', '1', '0', ' ')
#endif
#ifndef DRM_FORMAT_R12
#define DRM_FORMAT_R12 fourcc_code('R', '1', '2', ' ')
#endif
#ifndef DRM_FORMAT_R16
#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
#endif
#ifndef DRM_FORMAT_RG88
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
#endif
#ifndef DRM_FORMAT_GR88
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
#endif
#ifndef DRM_FORMAT_RG1616
#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2')
#endif
#ifndef DRM_FORMAT_GR1616
#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2')
#endif
#ifndef DRM_FORMAT_RGB332
#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8')
#endif
#ifndef DRM_FORMAT_BGR233
#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8')
#endif
#ifndef DRM_FORMAT_XRGB4444
#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2')
#endif
#ifndef DRM_FORMAT_XBGR4444
#define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2')
#endif
#ifndef DRM_FORMAT_RGBX4444
#define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2')
#endif
#ifndef DRM_FORMAT_BGRX4444
#define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2')
#endif
#ifndef DRM_FORMAT_ARGB4444
#define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2')
#endif
#ifndef DRM_FORMAT_ABGR4444
#define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2')
#endif
#ifndef DRM_FORMAT_RGBA4444
#define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2')
#endif
#ifndef DRM_FORMAT_BGRA4444
#define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2')
#endif
#ifndef DRM_FORMAT_XRGB1555
#define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5')
#endif
#ifndef DRM_FORMAT_XBGR1555
#define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5')
#endif
#ifndef DRM_FORMAT_RGBX5551
#define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5')
#endif
#ifndef DRM_FORMAT_BGRX5551
#define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5')
#endif
#ifndef DRM_FORMAT_ARGB1555
#define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5')
#endif
#ifndef DRM_FORMAT_ABGR1555
#define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5')
#endif
#ifndef DRM_FORMAT_RGBA5551
#define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5')
#endif
#ifndef DRM_FORMAT_BGRA5551
#define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5')
#endif
#ifndef DRM_FORMAT_RGB565
#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6')
#endif
#ifndef DRM_FORMAT_BGR565
#define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6')
#endif
#ifndef DRM_FORMAT_RGB888
#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4')
#endif
#ifndef DRM_FORMAT_BGR888
#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4')
#endif
#ifndef DRM_FORMAT_XRGB8888
#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')
#endif
#ifndef DRM_FORMAT_XBGR8888
#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4')
#endif
#ifndef DRM_FORMAT_RGBX8888
#define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4')
#endif
#ifndef DRM_FORMAT_BGRX8888
#define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4')
#endif
#ifndef DRM_FORMAT_ARGB8888
#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
#endif
#ifndef DRM_FORMAT_ABGR8888
#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')
#endif
#ifndef DRM_FORMAT_RGBA8888
#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4')
#endif
#ifndef DRM_FORMAT_BGRA8888
#define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4')
#endif
#ifndef DRM_FORMAT_XRGB2101010
#define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0')
#endif
#ifndef DRM_FORMAT_XBGR2101010
#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0')
#endif
#ifndef DRM_FORMAT_RGBX1010102
#define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0')
#endif
#ifndef DRM_FORMAT_BGRX1010102
#define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0')
#endif
#ifndef DRM_FORMAT_ARGB2101010
#define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0')
#endif
#ifndef DRM_FORMAT_ABGR2101010
#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0')
#endif
#ifndef DRM_FORMAT_RGBA1010102
#define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0')
#endif
#ifndef DRM_FORMAT_BGRA1010102
#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0')
#endif
#ifndef DRM_FORMAT_XRGB16161616
#define DRM_FORMAT_XRGB16161616 fourcc_code('X', 'R', '4', '8')
#endif
#ifndef DRM_FORMAT_XBGR16161616
#define DRM_FORMAT_XBGR16161616 fourcc_code('X', 'B', '4', '8')
#endif
#ifndef DRM_FORMAT_ARGB16161616
#define DRM_FORMAT_ARGB16161616 fourcc_code('A', 'R', '4', '8')
#endif
#ifndef DRM_FORMAT_ABGR16161616
#define DRM_FORMAT_ABGR16161616 fourcc_code('A', 'B', '4', '8')
#endif
#ifndef DRM_FORMAT_XRGB16161616F
#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H')
#endif
#ifndef DRM_FORMAT_XBGR16161616F
#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H')
#endif
#ifndef DRM_FORMAT_ARGB16161616F
#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H')
#endif
#ifndef DRM_FORMAT_ABGR16161616F
#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H')
#endif
#ifndef DRM_FORMAT_AXBXGXRX106106106106
#define DRM_FORMAT_AXBXGXRX106106106106 fourcc_code('A', 'B', '1', '0')
#endif
#ifndef DRM_FORMAT_YUYV
#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V')
#endif
#ifndef DRM_FORMAT_YVYU
#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U')
#endif
#ifndef DRM_FORMAT_UYVY
#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y')
#endif
#ifndef DRM_FORMAT_VYUY
#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y')
#endif
#ifndef DRM_FORMAT_AYUV
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V')
#endif
#ifndef DRM_FORMAT_AVUY8888
#define DRM_FORMAT_AVUY8888 fourcc_code('A', 'V', 'U', 'Y')
#endif
#ifndef DRM_FORMAT_XYUV8888
#define DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V')
#endif
#ifndef DRM_FORMAT_XVUY8888
#define DRM_FORMAT_XVUY8888 fourcc_code('X', 'V', 'U', 'Y')
#endif
#ifndef DRM_FORMAT_VUY888
#define DRM_FORMAT_VUY888 fourcc_code('V', 'U', '2', '4')
#endif
#ifndef DRM_FORMAT_VUY101010
#define DRM_FORMAT_VUY101010 fourcc_code('V', 'U', '3', '0')
#endif
#ifndef DRM_FORMAT_Y210
#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0')
#endif
#ifndef DRM_FORMAT_Y212
#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2')
#endif
#ifndef DRM_FORMAT_Y216
#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6')
#endif
#ifndef DRM_FORMAT_Y410
#define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0')
#endif
#ifndef DRM_FORMAT_Y412
#define DRM_FORMAT_Y412 fourcc_code('Y', '4', '1', '2')
#endif
#ifndef DRM_FORMAT_Y416
#define DRM_FORMAT_Y416 fourcc_code('Y', '4', '1', '6')
#endif
#ifndef DRM_FORMAT_XVYU2101010
#define DRM_FORMAT_XVYU2101010 fourcc_code('X', 'V', '3', '0')
#endif
#ifndef DRM_FORMAT_XVYU12_16161616
#define DRM_FORMAT_XVYU12_16161616 fourcc_code('X', 'V', '3', '6')
#endif
#ifndef DRM_FORMAT_XVYU16161616
#define DRM_FORMAT_XVYU16161616 fourcc_code('X', 'V', '4', '8')
#endif
#ifndef DRM_FORMAT_Y0L0
#define DRM_FORMAT_Y0L0 fourcc_code('Y', '0', 'L', '0')
#endif
#ifndef DRM_FORMAT_X0L0
#define DRM_FORMAT_X0L0 fourcc_code('X', '0', 'L', '0')
#endif
#ifndef DRM_FORMAT_Y0L2
#define DRM_FORMAT_Y0L2 fourcc_code('Y', '0', 'L', '2')
#endif
#ifndef DRM_FORMAT_X0L2
#define DRM_FORMAT_X0L2 fourcc_code('X', '0', 'L', '2')
#endif
#ifndef DRM_FORMAT_YUV420_8BIT
#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8')
#endif
#ifndef DRM_FORMAT_YUV420_10BIT
#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0')
#endif
#ifndef DRM_FORMAT_XRGB8888_A8
#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8')
#endif
#ifndef DRM_FORMAT_XBGR8888_A8
#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8')
#endif
#ifndef DRM_FORMAT_RGBX8888_A8
#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8')
#endif
#ifndef DRM_FORMAT_BGRX8888_A8
#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8')
#endif
#ifndef DRM_FORMAT_RGB888_A8
#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8')
#endif
#ifndef DRM_FORMAT_BGR888_A8
#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8')
#endif
#ifndef DRM_FORMAT_RGB565_A8
#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8')
#endif
#ifndef DRM_FORMAT_BGR565_A8
#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8')
#endif
#ifndef DRM_FORMAT_NV12
#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2')
#endif
#ifndef DRM_FORMAT_NV21
#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1')
#endif
#ifndef DRM_FORMAT_NV16
#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6')
#endif
#ifndef DRM_FORMAT_NV61
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1')
#endif
#ifndef DRM_FORMAT_NV24
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4')
#endif
#ifndef DRM_FORMAT_NV42
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2')
#endif
#ifndef DRM_FORMAT_NV15
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5')
#endif
#ifndef DRM_FORMAT_P210
#define DRM_FORMAT_P210 fourcc_code('P', '2', '1', '0')
#endif
#ifndef DRM_FORMAT_P010
#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0')
#endif
#ifndef DRM_FORMAT_P012
#define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2')
#endif
#ifndef DRM_FORMAT_P016
#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6')
#endif
#ifndef DRM_FORMAT_P030
#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0')
#endif
#ifndef DRM_FORMAT_Q410
#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0')
#endif
#ifndef DRM_FORMAT_Q401
#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
#endif
#ifndef DRM_FORMAT_YUV410
#define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9')
#endif
#ifndef DRM_FORMAT_YVU410
#define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9')
#endif
#ifndef DRM_FORMAT_YUV411
#define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1')
#endif
#ifndef DRM_FORMAT_YVU411
#define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1')
#endif
#ifndef DRM_FORMAT_YUV420
#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2')
#endif
#ifndef DRM_FORMAT_YVU420
#define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2')
#endif
#ifndef DRM_FORMAT_YUV422
#define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6')
#endif
#ifndef DRM_FORMAT_YVU422
#define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6')
#endif
#ifndef DRM_FORMAT_YUV444
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4')
#endif
#ifndef DRM_FORMAT_YVU444
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4')
#endif

69
gdk/gdkdmabufprivate.h Normal file
View File

@@ -0,0 +1,69 @@
#pragma once
#include "gdkdmabufformatsbuilderprivate.h"
#define GDK_DMABUF_MAX_PLANES 4
typedef struct _GdkDmabuf GdkDmabuf;
typedef struct _GdkDmabufDownloader GdkDmabufDownloader;
struct _GdkDmabuf
{
guint32 fourcc;
guint64 modifier;
unsigned int n_planes;
struct {
int fd;
unsigned int stride;
unsigned int offset;
} planes[GDK_DMABUF_MAX_PLANES];
};
struct _GdkDmabufDownloader
{
const char *name;
gboolean (* add_formats) (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder);
gboolean (* supports) (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error);
void (* download) (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride);
};
#ifdef HAVE_DMABUF
const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST;
const GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (void) G_GNUC_CONST;
int gdk_dmabuf_ioctl (int fd,
unsigned long request,
void *arg);
gboolean gdk_dmabuf_import_sync_file (int dmabuf_fd,
guint32 flags,
int sync_file_fd);
int gdk_dmabuf_export_sync_file (int dmabuf_fd,
guint32 flags);
gboolean gdk_dmabuf_sanitize (GdkDmabuf *dest,
gsize width,
gsize height,
const GdkDmabuf *src,
GError **error);
gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf);
gboolean gdk_dmabuf_get_memory_format (guint32 fourcc,
gboolean premultiplied,
GdkMemoryFormat *out_format);
gboolean gdk_dmabuf_get_fourcc (GdkMemoryFormat format,
guint32 *out_fourcc);
#endif

214
gdk/gdkdmabuftexture.c Normal file
View File

@@ -0,0 +1,214 @@
/* gdkdmabuftexture.c
*
* Copyright 2023 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 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/>.
*/
#include "config.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabufprivate.h"
#include "gdktextureprivate.h"
#include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdktexturedownloader.h>
/**
* GdkDmabufTexture:
*
* A `GdkTexture` representing a dma-buf object.
*
* To create a `GdkDmabufTexture`, use the auxiliary
* [class@Gdk.DmabufTextureBuilder] object.
*
* Dma-buf textures can only be created on Linux.
*/
struct _GdkDmabufTexture
{
GdkTexture parent_instance;
GdkDisplay *display;
const GdkDmabufDownloader *downloader;
GdkDmabuf dmabuf;
GDestroyNotify destroy;
gpointer data;
};
struct _GdkDmabufTextureClass
{
GdkTextureClass parent_class;
};
G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error)
G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE)
static void
gdk_dmabuf_texture_init (GdkDmabufTexture *self)
{
}
static void
gdk_dmabuf_texture_dispose (GObject *object)
{
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (object);
if (self->destroy)
self->destroy (self->data);
g_clear_object (&self->display);
G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object);
}
static void
gdk_dmabuf_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
self->downloader->download (self->downloader,
texture,
format,
data,
stride);
}
static void
gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass)
{
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
texture_class->download = gdk_dmabuf_texture_download;
gobject_class->dispose = gdk_dmabuf_texture_dispose;
}
GdkDisplay *
gdk_dmabuf_texture_get_display (GdkDmabufTexture *self)
{
return self->display;
}
const GdkDmabuf *
gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self)
{
return &self->dmabuf;
}
GdkTexture *
gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data,
GError **error)
{
#ifdef HAVE_DMABUF
GdkDmabufTexture *self;
GdkTexture *update_texture;
GdkDisplay *display;
GdkDmabuf dmabuf;
GdkMemoryFormat format;
GError *local_error = NULL;
int width, height;
gsize i;
display = gdk_dmabuf_texture_builder_get_display (builder);
width = gdk_dmabuf_texture_builder_get_width (builder);
height = gdk_dmabuf_texture_builder_get_height (builder);
if (!gdk_dmabuf_sanitize (&dmabuf,
width,
height,
gdk_dmabuf_texture_builder_get_dmabuf (builder),
error))
return NULL;
gdk_display_init_dmabuf (display);
for (i = 0; display->dmabuf_downloaders[i] != NULL; i++)
{
if (local_error && g_error_matches (local_error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT))
g_clear_error (&local_error);
if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i],
display,
&dmabuf,
gdk_dmabuf_texture_builder_get_premultiplied (builder),
&format,
local_error ? NULL : &local_error))
break;
}
if (display->dmabuf_downloaders[i] == NULL)
{
g_propagate_error (error, local_error);
return NULL;
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u, downloader %s",
(char *) &dmabuf.fourcc, dmabuf.modifier,
gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "",
dmabuf.n_planes,
format,
display->dmabuf_downloaders[i]->name);
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
"width", width,
"height", height,
NULL);
GDK_TEXTURE (self)->format = format;
g_set_object (&self->display, display);
self->downloader = display->dmabuf_downloaders[i];
self->dmabuf = dmabuf;
self->destroy = destroy;
self->data = data;
update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder);
if (update_texture)
{
cairo_region_t *update_region = gdk_dmabuf_texture_builder_get_update_region (builder);
if (update_region)
{
update_region = cairo_region_copy (update_region);
cairo_region_intersect_rectangle (update_region,
&(cairo_rectangle_int_t) {
0, 0,
update_texture->width, update_texture->height
});
gdk_texture_set_diff (GDK_TEXTURE (self), update_texture, update_region);
}
}
return GDK_TEXTURE (self);
#else /* !HAVE_DMABUF */
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
"dmabuf support disabled at compile-time.");
return NULL;
#endif
}

48
gdk/gdkdmabuftexture.h Normal file
View File

@@ -0,0 +1,48 @@
/* gdkdmabuftexture.h
*
* Copyright 2023 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 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/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
#include <gdk/gdktexture.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_TEXTURE (gdk_dmabuf_texture_get_type ())
#define GDK_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_DMABUF_TEXTURE, GdkDmabufTexture))
#define GDK_IS_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_DMABUF_TEXTURE))
#define GDK_DMABUF_ERROR (gdk_dmabuf_error_quark ())
typedef struct _GdkDmabufTexture GdkDmabufTexture;
typedef struct _GdkDmabufTextureClass GdkDmabufTextureClass;
GDK_AVAILABLE_IN_4_14
GType gdk_dmabuf_texture_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GQuark gdk_dmabuf_error_quark (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDmabufTexture, g_object_unref)
G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
/*
* Copyright © 2023 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
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_TEXTURE_BUILDER (gdk_dmabuf_texture_builder_get_type ())
GDK_AVAILABLE_IN_4_14
GDK_DECLARE_INTERNAL_TYPE (GdkDmabufTextureBuilder, gdk_dmabuf_texture_builder, GDK, DMABUF_TEXTURE_BUILDER, GObject)
GDK_AVAILABLE_IN_4_14
GdkDmabufTextureBuilder *gdk_dmabuf_texture_builder_new (void);
GDK_AVAILABLE_IN_4_14
GdkDisplay * gdk_dmabuf_texture_builder_get_display (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
GdkDisplay *display);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_width (GdkDmabufTextureBuilder *self,
unsigned int width);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_height (GdkDmabufTextureBuilder *self,
unsigned int height);
GDK_AVAILABLE_IN_4_14
guint32 gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self,
guint32 fourcc);
GDK_AVAILABLE_IN_4_14
guint64 gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier);
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_texture_builder_get_premultiplied (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
gboolean premultiplied);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes);
GDK_AVAILABLE_IN_4_14
int gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
unsigned int plane,
int fd);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
unsigned int plane,
unsigned int stride);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
unsigned int plane,
unsigned int offset);
GDK_AVAILABLE_IN_4_14
GdkTexture * gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_update_texture (GdkDmabufTextureBuilder *self,
GdkTexture *texture);
GDK_AVAILABLE_IN_4_14
cairo_region_t * gdk_dmabuf_texture_builder_get_update_region (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self,
cairo_region_t *region);
GDK_AVAILABLE_IN_4_14
GdkTexture * gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
GDestroyNotify destroy,
gpointer data,
GError **error);
G_END_DECLS

View File

@@ -0,0 +1,21 @@
#pragma once
#include "gdkdmabuftexture.h"
#include "gdkdmabuftexturebuilder.h"
#include "gdkdmabufprivate.h"
G_BEGIN_DECLS
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder);
GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data,
GError **error);
GdkDisplay * gdk_dmabuf_texture_get_display (GdkDmabufTexture *self);
const GdkDmabuf * gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self);
G_END_DECLS

View File

@@ -68,6 +68,12 @@ gdk_draw_context_default_surface_resized (GdkDrawContext *context)
{
}
static void
gdk_draw_context_default_empty_frame (GdkDrawContext *context)
{
g_warning ("FIXME: Implement");
}
static void
gdk_draw_context_dispose (GObject *gobject)
{
@@ -161,6 +167,7 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
gobject_class->dispose = gdk_draw_context_dispose;
klass->surface_resized = gdk_draw_context_default_surface_resized;
klass->empty_frame = gdk_draw_context_default_empty_frame;
/**
* GdkDrawContext:display: (attributes org.gtk.Property.get=gdk_draw_context_get_display)
@@ -470,3 +477,17 @@ gdk_draw_context_get_frame_region (GdkDrawContext *context)
return priv->frame_region;
}
void
gdk_draw_context_empty_frame (GdkDrawContext *context)
{
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
g_return_if_fail (priv->surface != NULL);
if (GDK_SURFACE_DESTROYED (priv->surface))
return;
GDK_DRAW_CONTEXT_GET_CLASS (context)->empty_frame (context);
}

View File

@@ -45,6 +45,7 @@ void gdk_draw_context_begin_frame (GdkDrawContext
const cairo_region_t *region);
GDK_AVAILABLE_IN_ALL
void gdk_draw_context_end_frame (GdkDrawContext *context);
GDK_AVAILABLE_IN_ALL
gboolean gdk_draw_context_is_in_frame (GdkDrawContext *context);
GDK_AVAILABLE_IN_ALL

View File

@@ -46,6 +46,7 @@ struct _GdkDrawContextClass
cairo_region_t *update_area);
void (* end_frame) (GdkDrawContext *context,
cairo_region_t *painted);
void (* empty_frame) (GdkDrawContext *context);
void (* surface_resized) (GdkDrawContext *context);
};
@@ -54,5 +55,9 @@ void gdk_draw_context_surface_resized (GdkDrawContext
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
GdkMemoryDepth depth,
const cairo_region_t *region);
void gdk_draw_context_empty_frame (GdkDrawContext *context);
G_END_DECLS

View File

@@ -684,7 +684,7 @@ gdk_drop_read_async (GdkDrop *self,
* gdk_drop_read_finish:
* @self: a `GdkDrop`
* @result: a `GAsyncResult`
* @out_mime_type: (out) (type utf8): return location for the used mime type
* @out_mime_type: (out) (type utf8) (transfer none): return location for the used mime type
* @error: (nullable): location to store error information on failure
*
* Finishes an async drop read operation.

View File

@@ -114,6 +114,15 @@ typedef enum
*/
typedef enum
{
/**
* GDK_NO_MODIFIER_MASK:
*
* No modifier.
*
* Since: 4.14
*/
GDK_NO_MODIFIER_MASK GDK_AVAILABLE_ENUMERATOR_IN_4_14 = 0,
GDK_SHIFT_MASK = 1 << 0,
GDK_LOCK_MASK = 1 << 1,
GDK_CONTROL_MASK = 1 << 2,
@@ -142,6 +151,22 @@ typedef enum
GDK_BUTTON4_MASK|GDK_BUTTON5_MASK)
/**
* GdkDmabufError:
* @GDK_DMABUF_ERROR_NOT_AVAILABLE: Dmabuf support is not available, because the OS
* is not Linux, or it was explicitly disabled at compile- or runtime
* @GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT: The requested format is not supported
* @GDK_DMABUF_ERROR_CREATION_FAILED: GTK failed to create the resource for other
* reasons
*
* Error enumeration for `GdkDmabufTexture`.
*/
typedef enum {
GDK_DMABUF_ERROR_NOT_AVAILABLE,
GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
GDK_DMABUF_ERROR_CREATION_FAILED,
} GdkDmabufError;
/**
* GdkGLError:
* @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available
@@ -282,10 +307,16 @@ typedef enum
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_A8B8G8R8_PREMULTIPLIED: 4 bytes; for alpha, blue, green, red,
* The color values are premultiplied with the alpha value. Since 4.14
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
* @GDK_MEMORY_A8B8G8R8: 4 bytes; for alpha, blue, green, red.
* @GDK_MEMORY_B8G8R8X8: 4 bytes; for blue, green, red, unused. Since 4.14
* @GDK_MEMORY_X8R8G8B8: 4 bytes; for unused, red, green, blue. Since 4.14
* @GDK_MEMORY_R8G8B8X8: 4 bytes; for red, green, blue, unused. Since 4.14
* @GDK_MEMORY_X8B8G8R8: 4 bytes; for unused, blue, green, red. Since 4.14
* @GDK_MEMORY_R8G8B8: 3 bytes; for red, green, blue. The data is opaque.
* @GDK_MEMORY_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
* @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since: 4.6
@@ -366,6 +397,11 @@ typedef enum {
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A16_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A32_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A8B8G8R8_PREMULTIPLIED GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_B8G8R8X8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_X8R8G8B8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_R8G8B8X8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_X8B8G8R8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_N_FORMATS
} GdkMemoryFormat;

View File

@@ -402,7 +402,6 @@ gdk_event_alloc (GdkEventType event_type,
GdkEvent *event = (GdkEvent *) g_type_create_instance (gdk_event_types[event_type]);
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (EVENTS))
{
char *str = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event_type);
@@ -410,7 +409,6 @@ gdk_event_alloc (GdkEventType event_type,
g_type_name (gdk_event_types[event_type]), str);
g_free (str);
}
#endif
event->event_type = event_type;
event->surface = surface != NULL ? g_object_ref (surface) : NULL;

View File

@@ -346,19 +346,15 @@ gdk_frame_clock_end_updating (GdkFrameClock *frame_clock)
GDK_FRAME_CLOCK_GET_CLASS (frame_clock)->end_updating (frame_clock);
}
static void
static inline void
_gdk_frame_clock_freeze (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
GDK_FRAME_CLOCK_GET_CLASS (clock)->freeze (clock);
}
static void
static inline void
_gdk_frame_clock_thaw (GdkFrameClock *clock)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
}
@@ -390,6 +386,12 @@ _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
_gdk_frame_clock_freeze (clock);
}
static inline gint64
_gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
{
return frame_clock->priv->frame_counter;
}
/**
* gdk_frame_clock_get_frame_counter:
* @frame_clock: a `GdkFrameClock`
@@ -404,13 +406,15 @@ _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
gint64
gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
{
GdkFrameClockPrivate *priv;
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (frame_clock), 0);
priv = frame_clock->priv;
return _gdk_frame_clock_get_frame_counter (frame_clock);
}
return priv->frame_counter;
static inline gint64
_gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
{
return frame_clock->priv->frame_counter + 1 - frame_clock->priv->n_timings;
}
/**
@@ -433,13 +437,9 @@ gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
gint64
gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
{
GdkFrameClockPrivate *priv;
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (frame_clock), 0);
priv = frame_clock->priv;
return priv->frame_counter + 1 - priv->n_timings;
return _gdk_frame_clock_get_history_start (frame_clock);
}
void
@@ -470,6 +470,24 @@ _gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
priv->timings[priv->current] = _gdk_frame_timings_new (priv->frame_counter);
}
static inline GdkFrameTimings *
_gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
gint64 frame_counter)
{
GdkFrameClockPrivate *priv = frame_clock->priv;
int pos;
if (frame_counter > priv->frame_counter)
return NULL;
if (frame_counter <= priv->frame_counter - priv->n_timings)
return NULL;
pos = (priv->current - (priv->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
return priv->timings[pos];
}
/**
* gdk_frame_clock_get_timings:
* @frame_clock: a `GdkFrameClock`
@@ -490,22 +508,9 @@ GdkFrameTimings *
gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
gint64 frame_counter)
{
GdkFrameClockPrivate *priv;
int pos;
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (frame_clock), NULL);
priv = frame_clock->priv;
if (frame_counter > priv->frame_counter)
return NULL;
if (frame_counter <= priv->frame_counter - priv->n_timings)
return NULL;
pos = (priv->current - (priv->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
return priv->timings[pos];
return _gdk_frame_clock_get_timings (frame_clock, frame_counter);
}
/**
@@ -528,11 +533,9 @@ gdk_frame_clock_get_current_timings (GdkFrameClock *frame_clock)
priv = frame_clock->priv;
return gdk_frame_clock_get_timings (frame_clock, priv->frame_counter);
return _gdk_frame_clock_get_timings (frame_clock, priv->frame_counter);
}
#ifdef G_ENABLE_DEBUG
void
_gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
GdkFrameTimings *timings)
@@ -541,8 +544,8 @@ _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
gint64 previous_frame_time = 0;
gint64 previous_smoothed_frame_time = 0;
GdkFrameTimings *previous_timings = gdk_frame_clock_get_timings (clock,
timings->frame_counter - 1);
GdkFrameTimings *previous_timings = _gdk_frame_clock_get_timings (clock,
timings->frame_counter - 1);
if (previous_timings != NULL)
{
@@ -579,7 +582,6 @@ _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
g_message ("%s", str->str);
g_string_free (str, TRUE);
}
#endif /* G_ENABLE_DEBUG */
#define DEFAULT_REFRESH_INTERVAL 16667 /* 16.7ms (1/60th second) */
#define MAX_HISTORY_AGE 150000 /* 150ms */
@@ -614,11 +616,11 @@ gdk_frame_clock_get_refresh_info (GdkFrameClock *frame_clock,
g_return_if_fail (GDK_IS_FRAME_CLOCK (frame_clock));
frame_counter = gdk_frame_clock_get_frame_counter (frame_clock);
frame_counter = _gdk_frame_clock_get_frame_counter (frame_clock);
while (TRUE)
{
GdkFrameTimings *timings = gdk_frame_clock_get_timings (frame_clock, frame_counter);
GdkFrameTimings *timings = _gdk_frame_clock_get_timings (frame_clock, frame_counter);
gint64 presentation_time;
gint64 refresh_interval;
@@ -730,15 +732,15 @@ guess_refresh_interval (GdkFrameClock *frame_clock)
interval = G_MAXINT64;
for (i = gdk_frame_clock_get_history_start (frame_clock);
i < gdk_frame_clock_get_frame_counter (frame_clock);
for (i = _gdk_frame_clock_get_history_start (frame_clock);
i < _gdk_frame_clock_get_frame_counter (frame_clock);
i++)
{
GdkFrameTimings *t, *before;
gint64 ts, before_ts;
t = gdk_frame_clock_get_timings (frame_clock, i);
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
t = _gdk_frame_clock_get_timings (frame_clock, i);
before = _gdk_frame_clock_get_timings (frame_clock, i - 1);
if (t == NULL || before == NULL)
continue;
@@ -773,12 +775,12 @@ gdk_frame_clock_get_fps (GdkFrameClock *frame_clock)
gint64 start_timestamp, end_timestamp;
gint64 interval;
start_counter = gdk_frame_clock_get_history_start (frame_clock);
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
start_counter = _gdk_frame_clock_get_history_start (frame_clock);
end_counter = _gdk_frame_clock_get_frame_counter (frame_clock);
start = _gdk_frame_clock_get_timings (frame_clock, start_counter);
for (end = _gdk_frame_clock_get_timings (frame_clock, end_counter);
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
end = _gdk_frame_clock_get_timings (frame_clock, end_counter))
end_counter--;
if (end_counter - start_counter < 4)
return 0.0;

View File

@@ -585,14 +585,15 @@ gdk_frame_clock_paint_idle (void *data)
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
{
int iter;
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (FRAMES))
{
if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
(priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
timings->layout_start_time = g_get_monotonic_time ();
{
if (timings)
timings->layout_start_time = g_get_monotonic_time ();
}
}
#endif
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
/* We loop in the layout phase, because we don't want to progress
@@ -616,14 +617,15 @@ gdk_frame_clock_paint_idle (void *data)
case GDK_FRAME_CLOCK_PHASE_PAINT:
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
{
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (FRAMES))
{
if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
(priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
timings->paint_start_time = g_get_monotonic_time ();
{
if (timings)
timings->paint_start_time = g_get_monotonic_time ();
}
}
#endif
priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
@@ -643,13 +645,11 @@ gdk_frame_clock_paint_idle (void *data)
*/
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
}
#ifdef G_ENABLE_DEBUG
if (GDK_DEBUG_CHECK (FRAMES))
{
if (timings)
timings->frame_end_time = g_get_monotonic_time ();
}
#endif /* G_ENABLE_DEBUG */
G_GNUC_FALLTHROUGH;
case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS:

View File

@@ -95,11 +95,9 @@ struct _GdkFrameTimings
gint64 refresh_interval;
gint64 predicted_presentation_time;
#ifdef G_ENABLE_DEBUG
gint64 layout_start_time;
gint64 paint_start_time;
gint64 frame_end_time;
#endif /* G_ENABLE_DEBUG */
guint complete : 1;
guint slept_before : 1;

View File

@@ -83,6 +83,7 @@
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
#include "gdkglversionprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkprivate.h"
@@ -95,20 +96,30 @@
#include <epoxy/egl.h>
#endif
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#include <math.h>
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
typedef struct {
typedef struct _GdkGLContextPrivate GdkGLContextPrivate;
struct _GdkGLContextPrivate
{
GdkGLVersion required;
GdkGLVersion gl_version;
GdkGLMemoryFlags memory_flags[GDK_MEMORY_N_FORMATS];
guint has_khr_debug : 1;
guint use_khr_debug : 1;
guint has_half_float : 1;
guint has_sync : 1;
guint has_unpack_subimage : 1;
guint has_debug_output : 1;
guint has_bgra : 1;
guint extensions_checked : 1;
guint debug_enabled : 1;
guint forward_compatible : 1;
@@ -123,7 +134,7 @@ typedef struct {
EGLContext egl_context;
EGLBoolean (*eglSwapBuffersWithDamage) (EGLDisplay, EGLSurface, const EGLint *, EGLint);
#endif
} GdkGLContextPrivate;
};
enum {
PROP_0,
@@ -345,6 +356,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
api == GDK_GL_API_GLES ? "yes" : "no");
supported_versions = gdk_gl_versions_get_for_api (api);
ctx = EGL_NO_CONTEXT;
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
{
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
@@ -354,11 +366,11 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
egl_config,
share ? share_priv->egl_context : EGL_NO_CONTEXT,
context_attribs);
if (ctx != NULL)
if (ctx != EGL_NO_CONTEXT)
break;
}
if (ctx == NULL)
if (ctx == EGL_NO_CONTEXT)
return 0;
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
@@ -383,17 +395,24 @@ gdk_gl_context_realize_egl (GdkGLContext *context,
{
GdkDisplay *display = gdk_gl_context_get_display (context);
GdkGLContext *share = gdk_display_get_gl_context (display);
GdkDebugFlags flags;
GdkGLAPI api, preferred_api;
gboolean prefer_legacy;
flags = gdk_display_get_debug_flags(display);
if (share && gdk_gl_context_is_api_allowed (context,
gdk_gl_context_get_api (share),
NULL))
preferred_api = gdk_gl_context_get_api (share);
else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
else if ((flags & GDK_DEBUG_GL_PREFER_GL) != 0 &&
gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
preferred_api = GDK_GL_API_GL;
else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, NULL))
preferred_api = GDK_GL_API_GLES;
else if ((flags & GDK_DEBUG_GL_PREFER_GL) == 0 &&
gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
preferred_api = GDK_GL_API_GL;
else
{
g_set_error_literal (error, GDK_GL_ERROR,
@@ -402,8 +421,7 @@ gdk_gl_context_realize_egl (GdkGLContext *context,
return 0;
}
prefer_legacy = (gdk_display_get_debug_flags(display) & GDK_DEBUG_GL_LEGACY) ||
(share != NULL && gdk_gl_context_is_legacy (share));
prefer_legacy = share != NULL && gdk_gl_context_is_legacy (share);
if (preferred_api == GDK_GL_API_GL)
{
@@ -1271,18 +1289,38 @@ gdk_gl_context_is_api_allowed (GdkGLContext *self,
GError **error)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
GdkDebugFlags flags;
GdkGLAPI allowed_apis;
if (gdk_display_get_debug_flags (gdk_gl_context_get_display (self)) & GDK_DEBUG_GL_GLES)
allowed_apis = priv->allowed_apis;
flags = gdk_display_get_debug_flags (gdk_gl_context_get_display (self));
if (flags & GDK_DEBUG_GL_DISABLE_GLES)
{
if (!(api & GDK_GL_API_GLES))
if (api == GDK_GL_API_GLES)
{
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
_("Anything but OpenGL ES disabled via GDK_DEBUG"));
_("OpenGL ES disabled via GDK_DEBUG"));
return FALSE;
}
allowed_apis &= ~GDK_GL_API_GLES;
}
if (priv->allowed_apis & api)
if (flags & GDK_DEBUG_GL_DISABLE_GL)
{
if (api == GDK_GL_API_GL)
{
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
_("OpenGL disabled via GDK_DEBUG"));
return FALSE;
}
allowed_apis &= ~GDK_GL_API_GL;
}
if (allowed_apis & api)
return TRUE;
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
@@ -1491,6 +1529,132 @@ gdk_gl_context_realize (GdkGLContext *context,
return priv->api;
}
static void
gdk_gl_context_init_memory_flags (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
gsize i;
if (!gdk_gl_context_get_use_es (self))
{
for (i = 0; i < G_N_ELEMENTS (priv->memory_flags); i++)
{
priv->memory_flags[i] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
}
return;
}
/* GLES 2.0 spec, tables 3.2 and 3.3 */
priv->memory_flags[GDK_MEMORY_R8G8B8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R8G8B8A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
#if 0
/* GLES2 can do these, but GTK can't */
priv->memory_flags[GDK_MEMORY_A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
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_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
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_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
}
}
if (epoxy_has_gl_extension ("GL_OES_rgb8_rgba8"))
{
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;
}
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;
}
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;
}
/* 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"))
{
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;
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= flags;
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;
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= flags;
}
}
}
void
gdk_gl_version_init_epoxy (GdkGLVersion *version)
{
@@ -1531,11 +1695,13 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_unpack_subimage = gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)) ||
epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
priv->has_bgra = epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888");
}
else
{
priv->has_unpack_subimage = TRUE;
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
priv->has_bgra = TRUE;
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
@@ -1555,7 +1721,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GL_APPLE_sync");
#ifdef G_ENABLE_DEBUG
gdk_gl_context_init_memory_flags (context);
{
int max_texture_size;
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
@@ -1567,7 +1734,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
" - half float: %s\n"
" - sync: %s",
" - sync: %s\n"
" - bgra: %s",
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",
@@ -1576,9 +1744,9 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "yes" : "no",
priv->has_half_float ? "yes" : "no",
priv->has_sync ? "yes" : "no");
priv->has_sync ? "yes" : "no",
priv->has_bgra ? "yes" : "no");
}
#endif
priv->extensions_checked = TRUE;
}
@@ -1715,6 +1883,56 @@ gdk_gl_context_get_version (GdkGLContext *context,
*minor = gdk_gl_version_get_minor (&priv->gl_version);
}
const char *
gdk_gl_context_get_glsl_version_string (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
if (priv->api == GDK_GL_API_GL)
{
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 6)))
return "#version 460";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 5)))
return "#version 450";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 4)))
return "#version 440";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 3)))
return "#version 430";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 2)))
return "#version 420";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 1)))
return "#version 410";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 0)))
return "#version 400";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 3)))
return "#version 330";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
return "#version 150";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 1)))
return "#version 140";
else
return "#version 130";
}
else if (priv->api == GDK_GL_API_GLES)
{
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
return "#version 320 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 1)))
return "#version 310 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
return "#version 300 es";
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
return "#version 300 es";
else
return "#version 100";
}
else
{
/* must be realized to be called */
g_assert_not_reached ();
}
}
/**
* gdk_gl_context_clear_current:
*
@@ -1788,6 +2006,15 @@ gdk_gl_context_get_current (void)
return context;
}
GdkGLMemoryFlags
gdk_gl_context_get_format_flags (GdkGLContext *self,
GdkMemoryFormat format)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->memory_flags[format];
}
gboolean
gdk_gl_context_has_debug (GdkGLContext *self)
{
@@ -1812,6 +2039,36 @@ gdk_gl_context_has_sync (GdkGLContext *self)
return priv->has_sync;
}
/* Return if GL_BGRA works with glTexImage2D */
gboolean
gdk_gl_context_has_bgra (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->has_bgra;
}
/* Return if glGenVertexArrays, glBindVertexArray and glDeleteVertexArrays
* can be used
*/
gboolean
gdk_gl_context_has_vertex_arrays (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
switch (priv->api)
{
case GDK_GL_API_GL:
return TRUE;
case GDK_GL_API_GLES:
return gdk_gl_version_get_major (&priv->gl_version) >= 3;
default:
g_return_val_if_reached (FALSE);
}
}
/* This is currently private! */
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
gboolean
@@ -1892,3 +2149,282 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
g_assert (the_gl_backend_type == backend_type);
}
static guint
gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
int target)
{
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
GdkDisplay *display = gdk_gl_context_get_display (self);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
EGLint attribs[64];
int i;
EGLImage image;
guint texture_id;
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), 0);
g_return_val_if_fail (width > 0, 0);
g_return_val_if_fail (height > 0, 0);
g_return_val_if_fail (1 <= dmabuf->n_planes && dmabuf->n_planes <= 4, 0);
g_return_val_if_fail (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES, 0);
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_import)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't import dmabufs into GL, missing EGL or EGL_EXT_image_dma_buf_import_modifiers");
return 0;
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL",
(char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes);
i = 0;
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
attribs[i++] = EGL_TRUE;
attribs[i++] = EGL_WIDTH;
attribs[i++] = width;
attribs[i++] = EGL_HEIGHT;
attribs[i++] = height;
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[i++] = dmabuf->fourcc;
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
attribs[i++] = EGL_ITU_REC601_EXT;
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
attribs[i++] = EGL_YUV_FULL_RANGE_EXT;
#define ADD_PLANE(plane) \
{ \
if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID) \
{ \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \
attribs[i++] = dmabuf->modifier & 0xFFFFFFFF; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \
attribs[i++] = dmabuf->modifier >> 32; \
} \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \
attribs[i++] = dmabuf->planes[plane].fd; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \
attribs[i++] = dmabuf->planes[plane].stride; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \
attribs[i++] = dmabuf->planes[plane].offset; \
}
ADD_PLANE (0);
if (dmabuf->n_planes > 1) ADD_PLANE (1);
if (dmabuf->n_planes > 2) ADD_PLANE (2);
if (dmabuf->n_planes > 3) ADD_PLANE (3);
attribs[i++] = EGL_NONE;
image = eglCreateImageKHR (egl_display,
EGL_NO_CONTEXT,
EGL_LINUX_DMA_BUF_EXT,
(EGLClientBuffer)NULL,
attribs);
if (image == EGL_NO_IMAGE)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating EGLImage for dmabuf failed: %#x",
eglGetError ());
return 0;
}
glGenTextures (1, &texture_id);
glBindTexture (target, texture_id);
glEGLImageTargetTexture2DOES (target, image);
glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
eglDestroyImageKHR (egl_display, image);
return texture_id;
#else
return 0;
#endif
}
guint
gdk_gl_context_import_dmabuf (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
gboolean *external)
{
GdkDisplay *display = gdk_gl_context_get_display (self);
guint texture_id;
gdk_display_init_dmabuf (display);
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);
if (texture_id == 0)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Import of external_only %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",
width, height,
(char *) &dmabuf->fourcc, dmabuf->modifier);
*external = TRUE;
return texture_id;
}
gboolean
gdk_gl_context_export_dmabuf (GdkGLContext *self,
unsigned int texture_id,
GdkDmabuf *dmabuf)
{
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
GdkDisplay *display = gdk_gl_context_get_display (self);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
EGLContext egl_context = priv->egl_context;
EGLint attribs[10];
EGLImage image;
gboolean result = FALSE;
int i;
int fourcc;
int n_planes;
guint64 modifier;
int fds[GDK_DMABUF_MAX_PLANES];
int strides[GDK_DMABUF_MAX_PLANES];
int offsets[GDK_DMABUF_MAX_PLANES];
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
g_return_val_if_fail (texture_id > 0, FALSE);
g_return_val_if_fail (dmabuf != NULL, FALSE);
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_export)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Can't export dmabufs from GL, missing EGL or EGL_EXT_image_dma_buf_export");
return 0;
}
GDK_DISPLAY_DEBUG (display, DMABUF, "Exporting GL texture to dmabuf");
i = 0;
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
attribs[i++] = EGL_TRUE;
attribs[i++] = EGL_NONE;
image = eglCreateImageKHR (egl_display,
egl_context,
EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer)GUINT_TO_POINTER (texture_id),
attribs);
if (image == EGL_NO_IMAGE)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating EGLImage for dmabuf failed: %#x", eglGetError ());
return FALSE;
}
if (!eglExportDMABUFImageQueryMESA (egl_display,
image,
&fourcc,
&n_planes,
&modifier))
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"eglExportDMABUFImageQueryMESA failed: %#x", eglGetError ());
goto out;
}
if (n_planes < 1 || n_planes > GDK_DMABUF_MAX_PLANES)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"dmabufs with %d planes are not supported", n_planes);
goto out;
}
if (!eglExportDMABUFImageMESA (egl_display,
image,
fds,
strides,
offsets))
{
g_warning ("eglExportDMABUFImage failed: %#x", eglGetError ());
goto out;
}
for (i = 0; i < n_planes; i++)
{
if (fds[i] == -1)
{
g_warning ("dmabuf plane %d has no file descriptor", i);
goto out;
}
}
dmabuf->fourcc = (guint32)fourcc;
dmabuf->modifier = modifier;
dmabuf->n_planes = n_planes;
for (i = 0; i < n_planes; i++)
{
dmabuf->planes[i].fd = fds[i];
dmabuf->planes[i].stride = (int) strides[i];
dmabuf->planes[i].offset = (int) offsets[i];
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Exported GL texture to dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %d)",
(char *)&fourcc, modifier, n_planes);
result = TRUE;
out:
eglDestroyImageKHR (egl_display, image);
return result;
#else
return FALSE;
#endif
}

View File

@@ -23,6 +23,7 @@
#include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h"
#include "gdkglversionprivate.h"
#include "gdkdmabufprivate.h"
G_BEGIN_DECLS
@@ -34,6 +35,17 @@ typedef enum {
GDK_GL_CGL
} GdkGLBackend;
typedef enum {
/* The format is supported for glTexImage2D() */
GDK_GL_FORMAT_USABLE = 1 << 0,
/* The format can be rendered to.
* GL/GLES spec term: "color-renderable" */
GDK_GL_FORMAT_RENDERABLE = 1 << 1,
/* GL_LINEAR/GL_MIPMAP_LINEAR can be used for textures in this format.
* GLES spec term: "texture-filterable" */
GDK_GL_FORMAT_FILTERABLE = 1 << 2
} GdkGLMemoryFlags;
/* The maximum amount of buffers we track update regions for.
* Note that this is equal to the max buffer age value we
* can provide a damage region for */
@@ -147,6 +159,10 @@ void gdk_gl_context_label_object_printf (GdkGLContext
const char *format,
...) G_GNUC_PRINTF (4, 5);
const char * gdk_gl_context_get_glsl_version_string (GdkGLContext *self);
GdkGLMemoryFlags gdk_gl_context_get_format_flags (GdkGLContext *self,
GdkMemoryFormat format) G_GNUC_PURE;
gboolean gdk_gl_context_has_debug (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
@@ -155,7 +171,20 @@ gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext
gboolean gdk_gl_context_has_sync (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_bgra (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext *self) G_GNUC_PURE;
double gdk_gl_context_get_scale (GdkGLContext *self);
G_END_DECLS
guint gdk_gl_context_import_dmabuf (GdkGLContext *self,
int width,
int height,
const GdkDmabuf *dmabuf,
gboolean *external);
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
unsigned int texture_id,
GdkDmabuf *dmabuf);
G_END_DECLS

View File

@@ -141,9 +141,7 @@ struct _Download
};
static gboolean
gdk_gl_texture_find_format (gboolean use_es,
guint gl_major,
guint gl_minor,
gdk_gl_texture_find_format (GdkGLContext *context,
GdkMemoryAlpha alpha,
GLint gl_format,
GLint gl_type,
@@ -153,15 +151,18 @@ gdk_gl_texture_find_format (gboolean use_es,
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
{
GLenum q_internal_format, q_format, q_type;
GLint q_internal_format;
GLenum q_format, q_type;
GLint q_swizzle[4];
if (gdk_memory_format_alpha (format) != alpha)
continue;
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type, q_swizzle))
if (!(gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_RENDERABLE))
continue;
gdk_memory_format_gl_format (format, &q_internal_format, &q_format, &q_type, q_swizzle);
if (q_format != gl_format || q_type != gl_type)
continue;
@@ -181,21 +182,19 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
GdkMemoryFormat format;
gsize expected_stride;
Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type;
GLint gl_internal_format;
GLenum gl_format, gl_type;
GLint gl_swizzle[4];
int major, minor;
format = gdk_texture_get_format (texture),
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
gdk_gl_context_get_version (context, &major, &minor);
if (!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (format,
FALSE,
major, minor,
&gl_internal_format,
&gl_format, &gl_type, gl_swizzle))
((gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
{
gdk_memory_format_gl_format (format,
&gl_internal_format,
&gl_format, &gl_type, gl_swizzle);
if (download->stride == expected_stride &&
download->format == format)
{
@@ -233,7 +232,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
else
{
GdkMemoryFormat actual_format;
GLint gl_read_format, gl_read_type;
GLenum gl_read_format, gl_read_type;
GLuint fbo;
glGenFramebuffers (1, &fbo);
@@ -241,26 +240,34 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
{
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
if (!gdk_gl_texture_find_format (TRUE, major, minor, gdk_memory_format_alpha (format), gl_read_format, gl_read_type, &actual_format))
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 = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE;
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_PREMULTIPLIED)
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
else
actual_format = GDK_MEMORY_R8G8B8A8;
gl_read_format = read_format;
gl_read_type = read_type;
}
else
{
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format));
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,
&gl_internal_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
}
else
{
gl_read_format = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE;
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_PREMULTIPLIED)
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
else
actual_format = GDK_MEMORY_R8G8B8A8;
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format));
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,
&gl_internal_format,
&gl_read_format, &gl_read_type, gl_swizzle);
}
if (download->format == actual_format &&

View File

@@ -213,7 +213,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
gobject_class->set_property = gdk_gl_texture_builder_set_property;
/**
* GdkGLTextureBuilder:context: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_context org.gdk.Property.set=gdk_gl_texture_builder_set_context)
* GdkGLTextureBuilder:context: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_context org.gtk.Property.set=gdk_gl_texture_builder_set_context)
*
* The context owning the texture.
*
@@ -225,7 +225,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:format: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_format org.gdk.Property.set=gdk_gl_texture_builder_set_format)
* GdkGLTextureBuilder:format: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_format org.gtk.Property.set=gdk_gl_texture_builder_set_format)
*
* The format when downloading the texture.
*
@@ -238,7 +238,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:has-mipmap: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gdk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
* GdkGLTextureBuilder:has-mipmap: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gtk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
*
* If the texture has a mipmap.
*
@@ -250,7 +250,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:height: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_height org.gdk.Property.set=gdk_gl_texture_builder_set_height)
* GdkGLTextureBuilder:height: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_height org.gtk.Property.set=gdk_gl_texture_builder_set_height)
*
* The height of the texture.
*
@@ -262,7 +262,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:id: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_id org.gdk.Property.set=gdk_gl_texture_builder_set_id)
* GdkGLTextureBuilder:id: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_id org.gtk.Property.set=gdk_gl_texture_builder_set_id)
*
* The texture ID to use.
*
@@ -274,7 +274,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:sync: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_sync org.gdk.Property.set=gdk_gl_texture_builder_set_sync)
* GdkGLTextureBuilder:sync: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_sync org.gtk.Property.set=gdk_gl_texture_builder_set_sync)
*
* An optional `GLSync` object.
*
@@ -287,7 +287,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_region org.gdk.Property.set=gdk_gl_texture_builder_set_update_region)
* GdkGLTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_region org.gtk.Property.set=gdk_gl_texture_builder_set_update_region)
*
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
*
@@ -299,7 +299,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_texture org.gdk.Property.set=gdk_gl_texture_builder_set_update_texture)
* GdkGLTextureBuilder:update-texture: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_texture org.gtk.Property.set=gdk_gl_texture_builder_set_update_texture)
*
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
*
@@ -311,7 +311,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:width: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_width org.gdk.Property.set=gdk_gl_texture_builder_set_width)
* GdkGLTextureBuilder:width: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_width org.gtk.Property.set=gdk_gl_texture_builder_set_width)
*
* The width of the texture.
*
@@ -347,7 +347,7 @@ gdk_gl_texture_builder_new (void)
}
/**
* gdk_gl_texture_builder_get_context: (attributes org.gdk.Method.get_property=context)
* gdk_gl_texture_builder_get_context: (attributes org.gtk.Method.get_property=context)
* @self: a `GdkGLTextureBuilder`
*
* Gets the context previously set via gdk_gl_texture_builder_set_context() or
@@ -366,7 +366,7 @@ gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_context: (attributes org.gdk.Method.set_property=context)
* gdk_gl_texture_builder_set_context: (attributes org.gtk.Method.set_property=context)
* @self: a `GdkGLTextureBuilder`
* @context: (nullable): The context the texture beongs to or %NULL to unset
*
@@ -391,7 +391,7 @@ gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
* gdk_gl_texture_builder_get_height: (attributes org.gtk.Method.get_property=height)
* @self: a `GdkGLTextureBuilder`
*
* Gets the height previously set via gdk_gl_texture_builder_set_height() or
@@ -410,7 +410,7 @@ gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
* gdk_gl_texture_builder_set_height: (attributes org.gtk.Method.set_property=height)
* @self: a `GdkGLTextureBuilder`
* @height: The texture's height or 0 to unset
*
@@ -435,7 +435,7 @@ gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_id: (attributes org.gdk.Method.get_property=id)
* gdk_gl_texture_builder_get_id: (attributes org.gtk.Method.get_property=id)
* @self: a `GdkGLTextureBuilder`
*
* Gets the texture id previously set via gdk_gl_texture_builder_set_id() or
@@ -454,7 +454,7 @@ gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_id: (attributes org.gdk.Method.set_property=id)
* gdk_gl_texture_builder_set_id: (attributes org.gtk.Method.set_property=id)
* @self: a `GdkGLTextureBuilder`
* @id: The texture id to be used for creating the texture
*
@@ -481,7 +481,7 @@ gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
* gdk_gl_texture_builder_get_width: (attributes org.gtk.Method.get_property=width)
* @self: a `GdkGLTextureBuilder`
*
* Gets the width previously set via gdk_gl_texture_builder_set_width() or
@@ -500,7 +500,7 @@ gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
* gdk_gl_texture_builder_set_width: (attributes org.gtk.Method.set_property=width)
* @self: a `GdkGLTextureBuilder`
* @width: The texture's width or 0 to unset
*
@@ -525,7 +525,7 @@ gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gdk.Method.get_property=has-mipmap)
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gtk.Method.get_property=has-mipmap)
* @self: a `GdkGLTextureBuilder`
*
* Gets whether the texture has a mipmap.
@@ -543,7 +543,7 @@ gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gdk.Method.set_property=has-mipmap)
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gtk.Method.set_property=has-mipmap)
* @self: a `GdkGLTextureBuilder`
* @has_mipmap: Whether the texture has a mipmap
*
@@ -569,7 +569,7 @@ gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_sync: (attributes org.gdk.Method.get_property=sync)
* gdk_gl_texture_builder_get_sync: (attributes org.gtk.Method.get_property=sync)
* @self: a `GdkGLTextureBuilder`
*
* Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
@@ -587,7 +587,7 @@ gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_sync: (attributes org.gdk.Method.set_property=sync)
* gdk_gl_texture_builder_set_sync: (attributes org.gtk.Method.set_property=sync)
* @self: a `GdkGLTextureBuilder`
* @sync: (nullable): the GLSync object
*
@@ -617,7 +617,7 @@ gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
* gdk_gl_texture_builder_get_format: (attributes org.gtk.Method.get_property=format)
* @self: a `GdkGLTextureBuilder`
*
* Gets the format previously set via gdk_gl_texture_builder_set_format().
@@ -635,7 +635,7 @@ gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_format: (attributes org.gdk.Method.set_property=format)
* gdk_gl_texture_builder_set_format: (attributes org.gtk.Method.set_property=format)
* @self: a `GdkGLTextureBuilder`
* @format: The texture's format
*
@@ -673,7 +673,7 @@ gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
* gdk_gl_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
* @self: a `GdkGLTextureBuilder`
*
* Gets the texture previously set via gdk_gl_texture_builder_set_update_texture() or
@@ -692,7 +692,7 @@ gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
* gdk_gl_texture_builder_set_update_texture: (attributes org.gtk.Method.set_property=update-texture)
* @self: a `GdkGLTextureBuilder`
* @texture: (nullable): the texture to update
*
@@ -715,7 +715,7 @@ gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
}
/**
* gdk_gl_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
* gdk_gl_texture_builder_get_update_region: (attributes org.gtk.Method.get_property=update-region)
* @self: a `GdkGLTextureBuilder`
*
* Gets the region previously set via gdk_gl_texture_builder_set_update_region() or
@@ -734,7 +734,7 @@ gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self)
}
/**
* gdk_gl_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
* gdk_gl_texture_builder_set_update_region: (attributes org.gtk.Method.set_property=update-region)
* @self: a `GdkGLTextureBuilder`
* @region: (nullable): the region to update
*

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,7 @@
#pragma once
#include "gdkenums.h"
#include "gdktypes.h"
#include <epoxy/gl.h>
@@ -41,18 +42,25 @@ typedef enum {
gsize gdk_memory_format_alignment (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryAlpha gdk_memory_format_alpha (GdkMemoryFormat format) G_GNUC_CONST;
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_format_get_premultiplied (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_format_get_straight (GdkMemoryFormat format) G_GNUC_CONST;
const GdkMemoryFormat * gdk_memory_format_get_fallbacks (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_format_get_depth (GdkMemoryFormat format) G_GNUC_CONST;
GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth depth1,
GdkMemoryDepth depth2) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_depth_get_format (GdkMemoryDepth depth) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type,
GLint out_gizzle[4]);
void gdk_memory_format_gl_format (GdkMemoryFormat format,
GLint *out_internal_format,
GLenum *out_format,
GLenum *out_type,
GLint out_swizzle[4]);
gboolean gdk_memory_format_gl_rgba_format (GdkMemoryFormat format,
GdkMemoryFormat *out_actual_format,
GLint *out_internal_format,
GLenum *out_format,
GLenum *out_type,
GLint out_swizzle[4]);
void gdk_memory_convert (guchar *dest_data,
gsize dest_stride,

View File

@@ -24,13 +24,16 @@
#include "gdksnapshotprivate.h"
#include "gdkprivate.h"
#include <graphene.h>
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
GdkSnapshot * gtk_snapshot_new (void);
void gtk_snapshot_push_debug (GdkSnapshot *snapshot,
const char *message,
...) G_GNUC_PRINTF (2, 3);
void gtk_snapshot_pop (GdkSnapshot *snapshot);
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot);
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot,
const graphene_size_t *size);
/**
* GdkPaintable:
@@ -118,7 +121,7 @@ gdk_paintable_default_get_current_image (GdkPaintable *paintable)
snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, width, height);
return gtk_snapshot_free_to_paintable (snapshot);
return gtk_snapshot_free_to_paintable (snapshot, NULL);
}
static GdkPaintableFlags

View File

@@ -40,7 +40,7 @@ struct _GdkIOPipe
GCond cond;
guchar *buffer;
gsize size;
GdkIOPipeState state : 2;
guint state : 2; /* GdkIOPipeState */
guint input_closed : 1;
guint output_closed : 1;
};

105
gdk/gdksubsurface.c Normal file
View File

@@ -0,0 +1,105 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2023 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 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/>.
*/
#include "config.h"
#include "gdksubsurfaceprivate.h"
#include "gdksurfaceprivate.h"
#include "gdktexture.h"
G_DEFINE_TYPE (GdkSubsurface, gdk_subsurface, G_TYPE_OBJECT)
static void
gdk_subsurface_init (GdkSubsurface *self)
{
}
static void
gdk_subsurface_finalize (GObject *object)
{
GdkSubsurface *subsurface = GDK_SUBSURFACE (object);
g_ptr_array_remove (subsurface->parent->subsurfaces, subsurface);
g_clear_object (&subsurface->parent);
G_OBJECT_CLASS (gdk_subsurface_parent_class)->finalize (object);
}
static void
gdk_subsurface_class_init (GdkSubsurfaceClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gdk_subsurface_finalize;
}
GdkSurface *
gdk_subsurface_get_parent (GdkSubsurface *subsurface)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), NULL);
return subsurface->parent;
}
gboolean
gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
g_return_val_if_fail (rect != NULL, FALSE);
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect, above, sibling);
}
void
gdk_subsurface_detach (GdkSubsurface *subsurface)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
}
GdkTexture *
gdk_subsurface_get_texture (GdkSubsurface *subsurface)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), NULL);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_texture (subsurface);
}
void
gdk_subsurface_get_rect (GdkSubsurface *subsurface,
graphene_rect_t *rect)
{
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
g_return_if_fail (rect != NULL);
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_rect (subsurface, rect);
}
gboolean
gdk_subsurface_is_above_parent (GdkSubsurface *subsurface)
{
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), TRUE);
return GDK_SUBSURFACE_GET_CLASS (subsurface)->is_above_parent (subsurface);
}

View File

@@ -0,0 +1,79 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2023 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 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/>.
*/
/* Uninstalled header defining types and functions internal to GDK */
#pragma once
#include "gdkenumtypes.h"
#include "gdksurface.h"
#include <graphene.h>
G_BEGIN_DECLS
typedef struct _GdkSubsurface GdkSubsurface;
typedef struct _GdkSubsurfaceClass GdkSubsurfaceClass;
#define GDK_TYPE_SUBSURFACE (gdk_subsurface_get_type ())
#define GDK_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SUBSURFACE, GdkSubsurface))
#define GDK_SUBSURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SUBSURFACE, GdkSubsurfaceClass))
#define GDK_IS_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SUBSURFACE))
#define GDK_SUBSURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SUBSURFACE, GdkSubsurfaceClass))
struct _GdkSubsurface
{
GObject parent_instance;
GdkSurface *parent;
int ref_count;
};
struct _GdkSubsurfaceClass
{
GObjectClass parent_class;
gboolean (* attach) (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling);
void (* detach) (GdkSubsurface *subsurface);
GdkTexture * (* get_texture) (GdkSubsurface *subsurface);
void (* get_rect) (GdkSubsurface *subsurface,
graphene_rect_t *rect);
gboolean (* is_above_parent) (GdkSubsurface *subsurface);
};
GType gdk_subsurface_get_type (void) G_GNUC_CONST;
GdkSurface * gdk_subsurface_get_parent (GdkSubsurface *subsurface);
gboolean gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *rect,
gboolean above,
GdkSubsurface *sibling);
void gdk_subsurface_detach (GdkSubsurface *subsurface);
GdkTexture * gdk_subsurface_get_texture (GdkSubsurface *subsurface);
void gdk_subsurface_get_rect (GdkSubsurface *subsurface,
graphene_rect_t *rect);
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);
G_END_DECLS

View File

@@ -43,6 +43,7 @@
#include "gdkrectangle.h"
#include "gdktoplevelprivate.h"
#include "gdkvulkancontext.h"
#include "gdksubsurfaceprivate.h"
#include <math.h>
@@ -254,7 +255,7 @@ maybe_flip_position (int bounds_pos,
*flipped = TRUE;
secondary = rect_pos + (1 - rect_sign) * rect_size / 2 - offset - (1 - surface_sign) * surface_size / 2;
if (secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size)
if ((secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size) || primary > bounds_pos + bounds_size)
return secondary;
*flipped = FALSE;
@@ -485,6 +486,8 @@ gdk_surface_init (GdkSurface *surface)
surface->device_cursor = g_hash_table_new_full (NULL, NULL,
NULL, g_object_unref);
surface->subsurfaces = g_ptr_array_new ();
}
static double
@@ -493,6 +496,14 @@ gdk_surface_real_get_scale (GdkSurface *surface)
return 1.0;
}
static GdkSubsurface *
gdk_surface_real_create_subsurface (GdkSurface *surface)
{
GDK_DISPLAY_DEBUG (gdk_surface_get_display (surface), OFFLOAD,
"Subsurfaces not supported for %s", G_OBJECT_TYPE_NAME (surface));
return NULL;
}
static void
gdk_surface_constructed (GObject *object)
{
@@ -515,6 +526,7 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
klass->beep = gdk_surface_real_beep;
klass->get_scale = gdk_surface_real_get_scale;
klass->create_subsurface = gdk_surface_real_create_subsurface;
/**
* GdkSurface:cursor: (attributes org.gtk.Property.get=gdk_surface_get_cursor org.gtk.Property.set=gdk_surface_set_cursor)
@@ -757,6 +769,10 @@ gdk_surface_finalize (GObject *object)
if (surface->parent)
surface->parent->children = g_list_remove (surface->parent->children, surface);
g_assert (surface->subsurfaces->len == 0);
g_ptr_array_unref (surface->subsurfaces);
G_OBJECT_CLASS (gdk_surface_parent_class)->finalize (object);
}
@@ -3054,3 +3070,32 @@ gdk_surface_leave_monitor (GdkSurface *surface,
{
g_signal_emit (surface, signals[LEAVE_MONITOR], 0, monitor);
}
GdkSubsurface *
gdk_surface_create_subsurface (GdkSurface *surface)
{
GdkSubsurface *subsurface;
subsurface = GDK_SURFACE_GET_CLASS (surface)->create_subsurface (surface);
if (subsurface)
{
subsurface->parent = g_object_ref (surface);
g_ptr_array_add (surface->subsurfaces, subsurface);
}
return subsurface;
}
gsize
gdk_surface_get_n_subsurfaces (GdkSurface *surface)
{
return surface->subsurfaces->len;
}
GdkSubsurface *
gdk_surface_get_subsurface (GdkSurface *surface,
gsize idx)
{
return g_ptr_array_index (surface->subsurfaces, idx);
}

View File

@@ -23,9 +23,14 @@
#include "gdkenumtypes.h"
#include "gdksurface.h"
#include "gdktoplevel.h"
#include <graphene.h>
G_BEGIN_DECLS
typedef struct _GdkSubsurface GdkSubsurface;
typedef struct _GskRenderNode GskRenderNode;
struct _GdkSurface
{
GObject parent_instance;
@@ -92,6 +97,8 @@ struct _GdkSurface
cairo_region_t *opaque_region;
GdkSeat *current_shortcuts_inhibited_seat;
GPtrArray *subsurfaces;
};
struct _GdkSurfaceClass
@@ -146,6 +153,9 @@ struct _GdkSurfaceClass
cairo_region_t *region);
void (* request_layout) (GdkSurface *surface);
gboolean (* compute_size) (GdkSurface *surface);
GdkSubsurface *
(* create_subsurface) (GdkSurface *surface);
};
#define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
@@ -334,7 +344,11 @@ void gdk_surface_request_motion (GdkSurface *surface);
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
GdkSubsurface * gdk_surface_create_subsurface (GdkSurface *surface);
void gdk_surface_destroy_subsurface (GdkSurface *surface,
GdkSubsurface *subsurface);
gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
gsize idx);
G_END_DECLS

View File

@@ -68,6 +68,33 @@ enum {
static GParamSpec *properties[N_PROPS];
static GdkTextureChain *
gdk_texture_chain_new (void)
{
GdkTextureChain *chain = g_new0 (GdkTextureChain, 1);
g_atomic_ref_count_init (&chain->ref_count);
g_mutex_init (&chain->lock);
return chain;
}
static void
gdk_texture_chain_ref (GdkTextureChain *chain)
{
g_atomic_ref_count_inc (&chain->ref_count);
}
static void
gdk_texture_chain_unref (GdkTextureChain *chain)
{
if (g_atomic_ref_count_dec (&chain->ref_count))
{
g_mutex_clear (&chain->lock);
g_free (chain);
}
}
static void
gdk_texture_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
@@ -283,7 +310,30 @@ gdk_texture_dispose (GObject *object)
{
GdkTexture *self = GDK_TEXTURE (object);
g_clear_pointer (&self->diff_to_previous, cairo_region_destroy);
if (self->chain)
{
g_mutex_lock (&self->chain->lock);
if (self->next_texture && self->previous_texture)
{
cairo_region_union (self->next_texture->diff_to_previous,
self->diff_to_previous);
self->next_texture->previous_texture = self->previous_texture;
self->previous_texture->next_texture = self->next_texture;
}
else if (self->next_texture)
self->next_texture->previous_texture = NULL;
else if (self->previous_texture)
self->previous_texture->next_texture = NULL;
self->next_texture = NULL;
self->previous_texture = NULL;
g_clear_pointer (&self->diff_to_previous, cairo_region_destroy);
g_mutex_unlock (&self->chain->lock);
g_clear_pointer (&self->chain, gdk_texture_chain_unref);
}
gdk_texture_clear_render_data (self);
@@ -345,7 +395,9 @@ gdk_texture_init (GdkTexture *self)
*
* Creates a new texture object representing the surface.
*
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
* The @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
*
* The newly created texture will acquire a reference on the @surface.
*
* Returns: a new `GdkTexture`
*/
@@ -364,7 +416,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
* cairo_image_surface_get_stride (surface),
(GDestroyNotify) cairo_surface_destroy,
cairo_surface_reference (surface));
texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
cairo_image_surface_get_height (surface),
GDK_MEMORY_DEFAULT,
@@ -677,34 +729,64 @@ gdk_texture_do_download (GdkTexture *texture,
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data, stride);
}
static gboolean
gdk_texture_has_ancestor (GdkTexture *self,
GdkTexture *other)
{
GdkTexture *texture;
for (texture = self->previous_texture;
texture != NULL;
texture = texture->previous_texture)
{
if (texture == other)
return TRUE;
}
return FALSE;
}
static void
gdk_texture_diff_from_known_ancestor (GdkTexture *self,
GdkTexture *ancestor,
cairo_region_t *region)
{
GdkTexture *texture;
for (texture = self; texture != ancestor; texture = texture->previous_texture)
cairo_region_union (region, texture->diff_to_previous);
}
void
gdk_texture_diff (GdkTexture *self,
GdkTexture *other,
cairo_region_t *region)
{
if (self == other)
cairo_rectangle_int_t fill = {
.x = 0,
.y = 0,
.width = MAX (self->width, other->width),
.height = MAX (self->height, other->height),
};
GdkTextureChain *chain;
if (other == self)
return;
if (self->previous_texture == other &&
g_atomic_pointer_get (&other->next_texture) == self)
chain = g_atomic_pointer_get (&self->chain);
if (chain == NULL || chain != g_atomic_pointer_get (&other->chain))
{
cairo_region_union (region, self->diff_to_previous);
}
else if (other->previous_texture == self &&
g_atomic_pointer_get (&self->next_texture) == other)
{
cairo_region_union (region, other->diff_to_previous);
cairo_region_union_rectangle (region, &fill);
return;
}
g_mutex_lock (&chain->lock);
if (gdk_texture_has_ancestor (self, other))
gdk_texture_diff_from_known_ancestor (self, other, region);
else if (gdk_texture_has_ancestor (other, self))
gdk_texture_diff_from_known_ancestor (other, self, region);
else
{
cairo_region_union_rectangle (region,
&(cairo_rectangle_int_t) {
0,
0,
MAX (self->width, other->width),
MAX (self->height, other->height)
});
}
cairo_region_union_rectangle (region, &fill);
g_mutex_unlock (&chain->lock);
}
void
@@ -713,10 +795,30 @@ gdk_texture_set_diff (GdkTexture *self,
cairo_region_t *diff)
{
g_assert (self->diff_to_previous == NULL);
g_assert (self->chain == NULL);
self->chain = g_atomic_pointer_get (&previous->chain);
if (self->chain == NULL)
{
self->chain = gdk_texture_chain_new ();
if (!g_atomic_pointer_compare_and_exchange (&previous->chain,
NULL,
self->chain))
gdk_texture_chain_unref (self->chain);
self->chain = previous->chain;
}
gdk_texture_chain_ref (self->chain);
g_mutex_lock (&self->chain->lock);
if (previous->next_texture)
{
previous->next_texture->previous_texture = NULL;
g_clear_pointer (&previous->next_texture->diff_to_previous, cairo_region_destroy);
}
previous->next_texture = self;
self->previous_texture = previous;
self->diff_to_previous = diff;
g_atomic_pointer_set (&previous->next_texture, self);
g_mutex_unlock (&self->chain->lock);
}
cairo_surface_t *
@@ -819,7 +921,7 @@ gdk_texture_set_render_data (GdkTexture *self,
GDestroyNotify notify)
{
g_return_val_if_fail (data != NULL, FALSE);
if (self->render_key != NULL)
return FALSE;

View File

@@ -6,6 +6,14 @@
G_BEGIN_DECLS
typedef struct _GdkTextureChain GdkTextureChain;
struct _GdkTextureChain
{
gatomicrefcount ref_count;
GMutex lock;
};
#define GDK_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_TEXTURE, GdkTextureClass))
#define GDK_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_TEXTURE))
#define GDK_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_TEXTURE, GdkTextureClass))
@@ -23,10 +31,13 @@ struct _GdkTexture
GDestroyNotify render_notify;
/* for diffing swapchain-like textures.
* Links are only valid if both textures agree on them */
gpointer next_texture; /* atomic, no reference, may be invalid pointer */
gpointer previous_texture; /* no reference, may be invalid pointer */
cairo_region_t *diff_to_previous;
* Textures in the same chain are connected in a double linked list which is
* protected using the chain's shared mutex.
*/
GdkTextureChain *chain; /* lazy, atomic, shared by all chain links */
GdkTexture *next_texture; /* no reference, guarded by chain lock */
GdkTexture *previous_texture; /* no reference, guarded by chain lock */
cairo_region_t *diff_to_previous; /* guarded by chain lock */
};
struct _GdkTextureClass {

View File

@@ -96,6 +96,8 @@ typedef struct _GdkCairoContext GdkCairoContext;
typedef struct _GdkGLContext GdkGLContext;
typedef struct _GdkVulkanContext GdkVulkanContext;
typedef struct _GdkDmabufFormats GdkDmabufFormats;
/*
* GDK_DECLARE_INTERNAL_TYPE:
* @ModuleObjName: The name of the new type, in camel case (like GtkWidget)

View File

@@ -252,7 +252,6 @@ gdk_vulkan_strerror (VkResult result)
}
}
#ifdef G_ENABLE_DEBUG
static const char *
surface_present_mode_to_string (VkPresentModeKHR present_mode)
{
@@ -275,7 +274,6 @@ surface_present_mode_to_string (VkPresentModeKHR present_mode)
return "(unknown)";
}
#endif
static const VkPresentModeKHR preferred_present_modes[] = {
VK_PRESENT_MODE_MAILBOX_KHR,
@@ -1475,6 +1473,13 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
gboolean validate = FALSE, have_debug_report = FALSE;
VkResult res;
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_VULKAN_DISABLE)
{
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
_("Vulkan support disabled via GDK_DEBUG"));
return FALSE;
}
if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL)
{
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,

View File

@@ -252,7 +252,7 @@ gdk_save_jpeg (GdkTexture *texture)
gulong size = 0;
guchar *input = NULL;
GdkTextureDownloader downloader;
GBytes *texbytes;
GBytes *texbytes = NULL;
const guchar *texdata;
gsize texstride;
guchar *row;

View File

@@ -329,6 +329,7 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
@@ -340,6 +341,10 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8B8G8R8:
format = GDK_MEMORY_R8G8B8;
png_format = PNG_COLOR_TYPE_RGB;
depth = 8;

View File

@@ -236,12 +236,17 @@ static const FormatData format_data[] = {
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8X8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_X8R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8X8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_X8B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16] = { GDK_MEMORY_R16G16B16A16, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },

View File

@@ -1265,6 +1265,14 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
_gdk_macos_display_clear_sorting (self);
}
}
else if (is_motion_event(event_type))
{
NSWindow *orig_window = [nsevent window];
if (orig_window && GDK_IS_MACOS_WINDOW (orig_window))
[NSApp sendEvent:nsevent];
}
return fill_event (self, window, nsevent, x, y);
}

View File

@@ -1005,7 +1005,7 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
}
NSEvent *
_gdk_macos_display_get_last_nsevent ()
_gdk_macos_display_get_last_nsevent (void)
{
const GdkToNSEventMap *map = g_queue_peek_tail (&event_map);
if (map)

View File

@@ -180,7 +180,6 @@ typedef enum {
POLLING_DESCRIPTORS,
} SelectThreadState;
#ifdef G_ENABLE_DEBUG
static const char *const state_names[] = {
"BEFORE_START",
"WAITING",
@@ -188,7 +187,6 @@ static const char *const state_names[] = {
"POLLING_RESTART",
"POLLING_DESCRIPTORS"
};
#endif
static SelectThreadState select_thread_state = BEFORE_START;
@@ -374,7 +372,6 @@ select_thread_start (void)
}
}
#ifdef G_ENABLE_DEBUG
static void
dump_poll_result (GPollFD *ufds,
guint nfds)
@@ -400,7 +397,6 @@ dump_poll_result (GPollFD *ufds,
gdk_debug_message ("%s", s->str);
g_string_free (s, TRUE);
}
#endif
static gboolean
pollfds_equal (GPollFD *old_pollfds,
@@ -468,13 +464,11 @@ select_thread_start_poll (GPollFD *ufds,
n_ready = old_poll_func (ufds, nfds, 0);
if (n_ready > 0 || timeout == 0)
{
#ifdef G_ENABLE_DEBUG
if ((_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) && n_ready > 0)
if (GDK_DEBUG_CHECK (EVENTLOOP) && n_ready > 0)
{
gdk_debug_message ("EventLoop: Found ready file descriptors before waiting");
dump_poll_result (ufds, nfds);
}
#endif
return n_ready;
}
@@ -612,13 +606,11 @@ select_thread_collect_poll (GPollFD *ufds, guint nfds)
}
}
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP)
if (GDK_DEBUG_CHECK (EVENTLOOP))
{
gdk_debug_message ("EventLoop: Found ready file descriptors after waiting");
dump_poll_result (ufds, nfds);
}
#endif
}
SELECT_THREAD_UNLOCK ();

View File

@@ -17,6 +17,12 @@ gdk_public_sources = files([
'gdkdevicetool.c',
'gdkdisplay.c',
'gdkdisplaymanager.c',
'gdkdmabuf.c',
'gdkdmabufegl.c',
'gdkdmabufformats.c',
'gdkdmabufformatsbuilder.c',
'gdkdmabuftexture.c',
'gdkdmabuftexturebuilder.c',
'gdkdrag.c',
'gdkdragsurface.c',
'gdkdragsurfacesize.c',
@@ -49,6 +55,7 @@ gdk_public_sources = files([
'gdktexture.c',
'gdktexturedownloader.c',
'gdkvulkancontext.c',
'gdksubsurface.c',
'gdksurface.c',
'gdkpopuplayout.c',
'gdkprofiler.c',
@@ -79,6 +86,9 @@ gdk_public_headers = files([
'gdkdisplay.h',
'gdkdisplaymanager.h',
'gdkdrag.h',
'gdkdmabufformats.h',
'gdkdmabuftexture.h',
'gdkdmabuftexturebuilder.h',
'gdkdragsurfacesize.h',
'gdkdrawcontext.h',
'gdkdrop.h',
@@ -208,6 +218,7 @@ gdk_deps = [
platform_gio_dep,
pangocairo_dep,
vulkan_dep,
dmabuf_dep,
png_dep,
tiff_dep,
jpeg_dep,

View File

@@ -194,6 +194,23 @@ gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
self->paint_surface = NULL;
}
static void
gdk_wayland_cairo_context_empty_frame (GdkDrawContext *draw_context)
{
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->has_pending_subsurface_commits)
return;
gdk_wayland_surface_sync (surface);
gdk_wayland_surface_request_frame (surface);
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
gdk_wayland_surface_commit (surface);
gdk_wayland_surface_notify_committed (surface);
}
static void
gdk_wayland_cairo_context_clear_all_cairo_surfaces (GdkWaylandCairoContext *self)
{
@@ -241,6 +258,7 @@ gdk_wayland_cairo_context_class_init (GdkWaylandCairoContextClass *klass)
draw_context_class->begin_frame = gdk_wayland_cairo_context_begin_frame;
draw_context_class->end_frame = gdk_wayland_cairo_context_end_frame;
draw_context_class->empty_frame = gdk_wayland_cairo_context_empty_frame;
draw_context_class->surface_resized = gdk_wayland_cairo_context_surface_resized;
cairo_context_class->cairo_create = gdk_wayland_cairo_context_cairo_create;

View File

@@ -225,14 +225,12 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, gdk_wayland_clipboard_read_async);
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: read for %s", cb, s);
g_free (s);
}
#endif
mime_type = gdk_content_formats_match_mime_type (formats, cb->offer_formats);
if (mime_type == NULL)
{
@@ -245,7 +243,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
g_task_set_task_data (task, (gpointer) mime_type, NULL);
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
{
g_task_return_error (task, error);
return;
@@ -322,14 +320,12 @@ gdk_wayland_clipboard_claim_remote (GdkWaylandClipboard *cb,
gdk_wayland_clipboard_discard_offer (cb);
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: remote clipboard claim for %s", cb, s);
g_free (s);
}
#endif
cb->offer_formats = formats;
cb->offer = offer;

View File

@@ -175,7 +175,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
_gdk_wayland_display_get_cursor_theme (display),
desired_scale,
gdk_cursor_get_name (cursor));
if (c)
if (c && c->image_count > 0)
{
struct wl_cursor_image *image;
int cursor_scale;

View File

@@ -24,6 +24,7 @@
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/sysmacros.h>
#ifdef HAVE_LINUX_MEMFD_H
#include <linux/memfd.h>
@@ -56,6 +57,7 @@
#include <wayland/xdg-foreign-unstable-v1-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
#include <wayland/server-decoration-client-protocol.h>
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "wm-button-layout-translation.h"
@@ -267,58 +269,119 @@ postpone_on_globals_closure (GdkWaylandDisplay *display_wayland,
g_list_append (display_wayland->on_has_globals_closures, closure);
}
#ifdef G_ENABLE_DEBUG
static const char *
get_format_name (uint32_t format,
char name[10])
{
if (format == 0)
g_strlcpy (name, "ARGB8888", 10);
else if (format == 1)
g_strlcpy (name, "XRGB8888", 10);
else
g_snprintf (name, 10, "4cc %c%c%c%c",
(char) (format & 0xff),
(char) ((format >> 8) & 0xff),
(char) ((format >> 16) & 0xff),
(char) ((format >> 24) & 0xff));
return name;
}
#endif
static void
wl_shm_format (void *data,
struct wl_shm *wl_shm,
uint32_t format)
{
#ifdef G_ENABLE_DEBUG
char buf[10];
#endif
GDK_DEBUG (MISC, "supported pixel format %s (0x%X)",
get_format_name (format, buf), (guint) format);
GDK_DEBUG (MISC, "supported shm pixel format %.4s (0x%X)",
format == 0 ? "ARGB8888"
: (format == 1 ? "XRGB8888"
: (char *) &format), format);
}
static const struct wl_shm_listener wl_shm_listener = {
wl_shm_format
};
static void
linux_dmabuf_done (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
{
GDK_DEBUG (MISC, "dmabuf feedback done");
}
static void
linux_dmabuf_format_table (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
int32_t fd,
uint32_t size)
{
GdkWaylandDisplay *display_wayland = data;
display_wayland->linux_dmabuf_n_formats = size / 16;
display_wayland->linux_dmabuf_formats = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
GDK_DEBUG (MISC, "got dmabuf format table (%lu entries)", display_wayland->linux_dmabuf_n_formats);
}
static void
linux_dmabuf_main_device (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
struct wl_array *device)
{
dev_t dev G_GNUC_UNUSED = *(dev_t *)device->data;
GDK_DEBUG (MISC, "got dmabuf main device: %u %u", major (dev), minor (dev));
}
static void
linux_dmabuf_tranche_done (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
{
GDK_DEBUG (MISC, "dmabuf feedback tranche done");
}
static void
linux_dmabuf_tranche_target_device (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
struct wl_array *device)
{
dev_t dev G_GNUC_UNUSED = *(dev_t *)device->data;
GDK_DEBUG (MISC, "got dmabuf tranche target device: %u %u", major (dev), minor (dev));
}
static void
linux_dmabuf_tranche_formats (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
struct wl_array *indices)
{
GdkWaylandDisplay *display_wayland = data;
GDK_DEBUG (MISC, "got dmabuf tranche formats (%lu entries):", indices->size / sizeof (guint16));
guint16 *pos;
wl_array_for_each (pos, indices)
{
LinuxDmabufFormat *fmt G_GNUC_UNUSED = &display_wayland->linux_dmabuf_formats[*pos];
uint32_t f G_GNUC_UNUSED = fmt->fourcc;
uint64_t m G_GNUC_UNUSED = fmt->modifier;
GDK_DEBUG (MISC, " %.4s:%#" G_GINT64_MODIFIER "x", (char *) &f, m);
}
}
static void
linux_dmabuf_tranche_flags (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
uint32_t flags)
{
GDK_DEBUG (MISC,
"got dmabuf tranche flags: %s",
flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT ? "scanout" : "");
}
static const struct zwp_linux_dmabuf_feedback_v1_listener linux_dmabuf_feedback_listener = {
linux_dmabuf_done,
linux_dmabuf_format_table,
linux_dmabuf_main_device,
linux_dmabuf_tranche_done,
linux_dmabuf_tranche_target_device,
linux_dmabuf_tranche_formats,
linux_dmabuf_tranche_flags,
};
static void
server_decoration_manager_default_mode (void *data,
struct org_kde_kwin_server_decoration_manager *manager,
uint32_t mode)
{
g_assert (mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
#ifdef G_ENABLE_DEBUG
const char *modes[] = {
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE] = "none",
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT] = "client",
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER] = "server",
};
#endif
GdkWaylandDisplay *display_wayland = data;
GDK_DISPLAY_DEBUG (GDK_DISPLAY (data), MISC, "Compositor prefers decoration mode '%s'", modes[mode]);
display_wayland->server_decoration_mode = mode;
@@ -382,6 +445,16 @@ gdk_registry_handle_global (void *data,
wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1);
wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland);
}
else if (strcmp (interface, "zwp_linux_dmabuf_v1") == 0 && version >= 4)
{
display_wayland->linux_dmabuf =
wl_registry_bind (display_wayland->wl_registry, id, &zwp_linux_dmabuf_v1_interface, version);
display_wayland->linux_dmabuf_feedback =
zwp_linux_dmabuf_v1_get_default_feedback (display_wayland->linux_dmabuf);
zwp_linux_dmabuf_feedback_v1_add_listener (display_wayland->linux_dmabuf_feedback,
&linux_dmabuf_feedback_listener, display_wayland);
_gdk_wayland_display_async_roundtrip (display_wayland);
}
else if (strcmp (interface, "xdg_wm_base") == 0)
{
display_wayland->xdg_wm_base_id = id;
@@ -726,6 +799,10 @@ gdk_wayland_display_dispose (GObject *object)
g_clear_pointer (&display_wayland->xdg_activation, xdg_activation_v1_destroy);
g_clear_pointer (&display_wayland->fractional_scale, wp_fractional_scale_manager_v1_destroy);
g_clear_pointer (&display_wayland->viewporter, wp_viewporter_destroy);
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
g_clear_pointer (&display_wayland->linux_dmabuf_feedback, zwp_linux_dmabuf_feedback_v1_destroy);
if (display_wayland->linux_dmabuf_formats)
munmap (display_wayland->linux_dmabuf_formats, display_wayland->linux_dmabuf_n_formats * 16);
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
@@ -2243,8 +2320,6 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
return FALSE;
}
#ifdef G_ENABLE_DEBUG
static const char *
subpixel_to_string (int layout)
{
@@ -2291,8 +2366,6 @@ transform_to_string (int transform)
return NULL;
}
#endif
static void
update_scale (GdkDisplay *display)
{

View File

@@ -71,6 +71,13 @@ typedef enum _GdkWaylandShellVariant
GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6
} GdkWaylandShellVariant;
typedef struct
{
uint32_t fourcc;
uint32_t padding;
uint64_t modifier;
} LinuxDmabufFormat;
struct _GdkWaylandDisplay
{
GdkDisplay parent_instance;
@@ -95,6 +102,10 @@ struct _GdkWaylandDisplay
struct wl_registry *wl_registry;
struct wl_compositor *compositor;
struct wl_shm *shm;
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback;
gsize linux_dmabuf_n_formats;
LinuxDmabufFormat *linux_dmabuf_formats;
struct xdg_wm_base *xdg_wm_base;
struct zxdg_shell_v6 *zxdg_shell_v6;
struct gtk_shell1 *gtk_shell;

View File

@@ -340,14 +340,12 @@ gdk_wayland_drag_create_data_source (GdkDrag *drag)
mimetypes = gdk_content_formats_get_mime_types (formats, &n_mimetypes);
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (gdk_drag_get_display (drag), EVENTS))
{
char *s = g_strjoinv (" ", (char **)mimetypes);
gdk_debug_message ("create data source, mime types=%s", s);
g_free (s);
}
#endif
wl_data_source_offer (drag_wayland->data_source, GDK_WAYLAND_LOCAL_DND_MIME_TYPE);
for (i = 0; i < n_mimetypes; i++)
@@ -397,7 +395,7 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
drag_wayland->data_source,
gdk_wayland_surface_get_wl_surface (surface),
gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface),
_gdk_wayland_seat_get_implicit_grab_serial (seat, NULL));
_gdk_wayland_seat_get_implicit_grab_serial (seat, device, NULL));
cursor = gdk_drag_get_cursor (drag, gdk_drag_get_selected_action (drag));
gdk_drag_set_cursor (drag, cursor);

View File

@@ -191,14 +191,12 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, gdk_wayland_drop_read_async);
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (gdk_drop_get_display (drop), DND))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: read for %s", drop, s);
g_free (s);
}
#endif
mime_type = gdk_content_formats_match_mime_type (formats,
gdk_drop_get_formats (drop));
if (mime_type == NULL)
@@ -210,7 +208,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
g_task_set_task_data (task, (gpointer) mime_type, NULL);
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
{
g_task_return_error (task, error);
return;

View File

@@ -75,7 +75,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
/* We should do ths when setting up the EGLSurface, but we don't make_current then */
/* We should do this when setting up the EGLSurface, but we don't make_current then */
eglSwapInterval (gdk_display_get_egl_display (gdk_draw_context_get_display (draw_context)), 0);
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
@@ -83,6 +83,22 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
gdk_wayland_surface_notify_committed (surface);
}
static void
gdk_wayland_gl_context_empty_frame (GdkDrawContext *draw_context)
{
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (impl->has_pending_subsurface_commits)
{
gdk_wayland_surface_sync (surface);
gdk_wayland_surface_request_frame (surface);
gdk_wayland_surface_commit (surface);
gdk_wayland_surface_notify_committed (surface);
}
}
static void
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
{
@@ -91,6 +107,7 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
draw_context_class->empty_frame = gdk_wayland_gl_context_empty_frame;
context_class->backend_type = GDK_GL_EGL;
}

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