Compare commits

...

183 Commits

Author SHA1 Message Date
Nelson Benítez León
bab2bf2596 widget-factory: add example on styling tooltip window
by using new api:
  gtk_tooltip_set_css_class()
  GtkWidget signals 'tooltip-show' and 'tooltip-hide'

Part of #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León
11b4e4a467 GtkWidget: add new signals 'tooltip-show' and 'tooltip-hide'
which are emitted when a tooltip window is about to be shown
on a widget, and when a tooltip window stopped being shown
on a widget.

These signals provide two convenient moments for where to style
our tooltip window in case we want to do so by adding a css
class to it.

The existant signal 'query-tooltip' could not be used for that
as it's triggered on motion events and we cannot distinguish
from that when the tooltip window gets shown or hidden.

Part of issue #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León
1cae0cd54c GtkToolTip: new API to add css classes to GtkTooltipWindow
we add a simple API to allow styling GtkTooltip's window
by setting a css class on it:

void gtk_tooltip_set_css_class (GtkTooltip *tooltip,
                                const char *css_class);

By passing NULL it will remove any previously set css class
by this function.

Issue #5925
2023-07-09 17:07:09 -04:00
Matthias Clasen
1f3db35271 Merge branch 'dboles/image-notify-storage-type' into 'main'
Image—Notify when :storage-type changes from EMPTY

See merge request GNOME/gtk!6170
2023-07-07 01:15:56 +00:00
Emmanuele Bassi
18cce46ed2 Merge branch 'wip/corey/listitemleak' into 'main'
gtklistitemmanager: Stop leaking item

Closes #5940

See merge request GNOME/gtk!6171
2023-07-06 23:57:16 +00:00
Corey Berla
e78148bae5 gtklistitemmanager: Stop leaking item
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5940
2023-07-06 16:24:29 -07:00
Daniel Boles
41237509ad Image—Notify when :storage-type changes from EMPTY
PROP_STORAGE_TYPE was only notified if it was changing *to* EMPTY, in
gtk_image_clear_internal(). We did not notify when it changes *from*
EMPTY to something non-empty. We should as not doing so is confusing,
e.g. if a user wants to bind :storage-type to :visible if non-empty,
which I just did! So, in functions that apply an ImageType, now notify.

Also do so in gtk_image_set_from_definition, declared in imageprivate.h,
even though none of the function there are currently used anywhere.
(Should they be removed?)
2023-07-06 23:08:20 +01:00
Yosef Or Boczko
576e8a2090 Update Hebrew translation 2023-07-06 09:38:02 +00:00
Matthias Clasen
d0f77c1db4 Merge branch 'wip/carlosg/switch-stylus-buttons' into 'main'
gdk/wayland: Switch behavior of BTN_STYLUS/STYLUS2 as middle/right click

Closes #5935

See merge request GNOME/gtk!6168
2023-07-05 23:38:38 +00:00
Carlos Garnacho
e28ff79bec gdk/wayland: Switch behavior of BTN_STYLUS/STYLUS2 as middle/right click
This mapping of stylus evdev input event codes into GDK button numbers
makes gdk/wayland inconsistent with gdk/x11, so depending on the backend
the same button middle-click pastes or right-click pops up menus.

Make the wayland backend consistent with X11, so that a GNOME wayland
session gets these buttons consistently mapped across all kinds of
clients.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5935
2023-07-05 16:54:54 +02:00
Daniel Boles
dccf6b55bd GdkTexture: Don't mention private new_from_surface
The stuff about Cairo Surfaces is in gdktextureprivate.h, & so end users
will not be able to use them; we shouldn't confuse by implying they can.
2023-07-05 12:07:33 +01:00
Daniel Boles
d5ea376e7b docs/list-widget: links, DirList, correct Sections
* Add links to various symbols.
* Mention DirectoryList in the "ready-made choices available" section.
* Don't say that GridView can display headers: it makes no attempt to.
2023-07-05 12:02:08 +01:00
Matthias Clasen
40707a6af0 Merge branch 'ebassi/issue-5934' into 'main'
Lower the Python requirement

Closes #5934

See merge request GNOME/gtk!6167
2023-07-05 10:57:45 +00:00
Emmanuele Bassi
9b71c9dfc6 Do not use bleeding edge Python
The match operator was added in Python 3.10, which is a bit too new for
some downstreams.

While at it, let's fix the flake8 errors and warnings.

Fixes: #5934
2023-07-05 10:19:18 +01:00
Emmanuele Bassi
64308317f8 Add flake8 configuration file
Ignore long lines; most of our Python scripts generate code or other
types of files, which makes long lines a necessity.

We should validate all our Python script in our CI as well.
2023-07-05 10:12:20 +01:00
Daniel Boles
f920723eae AlertDialog: Remove spurious/unmatched backtick 2023-07-04 22:42:50 +01:00
Daniel Boles
c581f4c96f ListBase: Fix a typo 2023-07-04 19:44:56 +01:00
Matthias Clasen
4998c90b10 Merge branch 'update-uac-script-format' into 'main'
tools/generate-uac-manifest.py: Fix formatting (unify with copy in GLib)

See merge request GNOME/gtk!6164
2023-07-03 23:37:36 +00:00
Benjamin Otte
412b23a146 Merge branch 'wip/otte/for-main' into 'main'
gsk: Catch values < 0 before bad things happen

See merge request GNOME/gtk!6165
2023-07-03 20:40:30 +00:00
Benjamin Otte
c179013790 testsuite: Add a test for mask out of bounds effects
Inverted alpha masks have an effect on the source, even if the mask
doesn't cover the source at all - or worse, is completely clipped out.

The GL renderer handles this fine, but Cairo and Vulkan had
optimizations that got this wrong.
2023-07-03 22:02:44 +02:00
Benjamin Otte
c6eb7fd483 gsk: Fix luminance in Cairo and GL renderer
In particular, fix the combination of luminance and alpha. We want to do
  mask = luminance * alpha
and for inverted
  mask = (1.0 - luminance) * alpha
so add a test that makes sure we do that and then fix the code and
existing tests to conform to it.
2023-07-03 22:02:44 +02:00
Benjamin Otte
7c58370673 rendernode: Work around a Cairo bug
When color-matrix modifying a clear surface, the surface would remain
clear according to Cairo.

That's very unfortunate when we prepare a mask for inverted-alpha
masking.
2023-07-03 22:02:44 +02:00
Benjamin Otte
84737a5159 build: Include the right things
If we build our own targets, we need to include those.

This is only relevant when adding new shaders because meson will
complain that the (unused) sources don't exist as it tries to include
those.
And that will make the build.ninja file not be generated which would
have build those shaders and would have allowed to copy them into the
sources.

Note that this makes builds with glslc not care about all the shader
files being included with the sources, but we have CI to check that.
2023-07-03 22:02:44 +02:00
Benjamin Otte
48804c81f3 rendernode: Mask nodes with different modes are different
So treat them as such.

Fixes the node editor not updating when I edit the mask mode.
2023-07-03 22:02:44 +02:00
Benjamin Otte
c79ec355af gsk: Catch values < 0 before bad things happen
In particular, catch radius values being < 0 by return_if_fail()ing in
the rendernode creation code, and by erroring out in the rendernode
parser.

I try too much dumb stuff in the node editor.
2023-07-03 22:02:44 +02:00
Benjamin Otte
ce5d74d7df glcontext: Fix typo in Apple extension name 2023-07-03 22:02:44 +02:00
Matthias Clasen
5bcc943ec3 Post-release version bump 2023-07-03 14:56:49 -04:00
Matthias Clasen
f5d68bb586 4.11.4 2023-07-03 14:12:53 -04:00
Chun-wei Fan
6d1537647c tools/generate-uac-manifest.py: Fix formatting
As this script is now also used in GLib, unify the formatting between
GLib and GTK. Make the formatting of the script conformant to the
Black[1] tool, as GLib requires, and add a copyright header to this
script.

[1]: https://black.readthedocs.io/en/stable/, see also
$(glibsrcroot)/.gitlab-ci/run-bash.sh
2023-07-03 12:50:55 +08:00
Matthias Clasen
ae2c10996a Merge branch 'fix_atcontext_refleaks' into 'main'
a11y: Fix some GtkATContext reference leaks

See merge request GNOME/gtk!6160
2023-07-01 18:06:19 +00:00
Barnabás Pőcze
81e9de3778 a11y: Fix some GtkATContext reference leaks
`gtk_accessible_get_at_context()` is transfer-full, so the returned
reference needs to be dropped. This was missing in a couple places.
2023-07-01 16:40:11 +02:00
Chun-wei Fan
42a704fefb Merge branch 'gdk-win32-input-fixes' into 'main'
GdkWin32 input fixes

Closes #5877

See merge request GNOME/gtk!6131
2023-06-30 04:33:08 +00:00
Matthias Clasen
e57eaf16b4 Merge branch 'wip/chergert/map-as-sectionmodel' into 'main'
maplistmodel: implement GtkSectionModel

See merge request GNOME/gtk!6154
2023-06-30 01:50:07 +00:00
Matthias Clasen
9aabb0e98d Add section model tests for GtkMapListModel 2023-06-29 21:30:11 -04:00
Matthias Clasen
9590a5f45e maplistmodel: Handle the ::sections-changed signal
Wrapper section models need to listen to and pass
on the ::sections-changed signal from the underlying
model.
2023-06-29 21:29:11 -04:00
Daniel Boles
7bee50c4f6 Image: Fix missing closing backtick 2023-06-29 14:33:29 +01:00
Matthias Clasen
bad2324318 Merge branch 'dboles/gtk-demo_dnd_dark' into 'main'
gtk-demo/dnd: Fix, generalise detecting dark theme

See merge request GNOME/gtk!6157
2023-06-29 10:26:41 +00:00
Matthias Clasen
dd15accb79 Merge branch 'matthiasc/for-main' into 'main'
build: Try harder to work with nongnu ld

See merge request GNOME/gtk!6159
2023-06-28 23:31:41 +00:00
Matthias Clasen
1d1f35576a build: Try harder to work with nongnu ld
Only try to be fast with gnu ld.
2023-06-28 16:54:34 -04:00
Daniel Boles
15458b5af3 gtk-demo/dnd: Fix, generalise detecting dark theme
Our default theme is now Default, not Adwaita, & HighContrastInverse was
renamed to Default-hc. So these checks did not work anymore. Rather than
hard-coding the new names, & possibly running into the same issue again,
we can just look for the convention of appending -dark to the theme name
and/or the Settings:prefer-dark-theme prop. The latter, we can & likely
SHOULD also apply to all themes - not just ours as before. We also check
for the :dark suffix as that means the theme variant - & before checking
GtkSettings check the GTK_THEME env var, just as GtkSettings itself does
2023-06-28 14:40:06 +01:00
Matthias Clasen
5ffe9a68ed Merge branch 'matthiasc/for-main' into 'main'
build: Move objcopy checks to one place

Closes #5672

See merge request GNOME/gtk!6156
2023-06-28 12:06:49 +00:00
Matthias Clasen
f341bd563b build: Look for ld.bfd
The objcopy+ld approach to fast resource building
relies on behavior that is specific to the binutils
linker, and does not work with the llvm one.

Therefore, check for ld.bfd. We still fall back
to trying with just ld, since I'm not 100% sure
if binutils unconditionally installs ld.bfd.

Fixes: #5672
2023-06-28 07:12:07 -04:00
Matthias Clasen
70edacc68d build: Move objcopy checks to one place
We were doing the same thing in three places.
Move it to the toplevel meson.build, so we
can change it in one place.
2023-06-28 07:11:51 -04:00
Matthias Clasen
091176ae48 Updates 2023-06-28 06:47:32 -04:00
Matthias Clasen
d9cfb94a80 Merge branch 'fix_dropdown_set_expression' into 'main'
GtkDropDown: Force redisplay of the drop-down items after expression change

See merge request GNOME/gtk!6145
2023-06-28 09:57:04 +00:00
Lukáš Tyrychtr
3c7ca28f1f dropdown: Handle expression changes
The expression is used by the default factory, so we
need to track whether we are using the default factory
and recreate it if the expression changes.
2023-06-28 08:18:01 +02:00
Matthias Clasen
25e518326c Merge branch 'matthiasc/for-main' into 'main'
Plug a memory leak in gsk_render_node_serialize

See merge request GNOME/gtk!6155
2023-06-28 02:42:47 +00:00
Matthias Clasen
a853307fb7 ci: Ignore more leaks in dependencies
libxkbcommon shows up quite a bit in leak sanitizer
reports. Ignore it.
2023-06-27 22:08:22 -04:00
Matthias Clasen
0ae541671d gsk: Plug a memory leak in mask node fallback
We were forgetting to free the mask pattern.
Found by asan.
2023-06-27 21:54:15 -04:00
Matthias Clasen
ef0d6c7290 gsk: Plug a memory leak in the gl renderer
Found by asan.
2023-06-27 21:52:08 -04:00
Matthias Clasen
2217509701 Plug a memory leak in gsk tests
Pointed out by asan.
2023-06-27 21:48:12 -04:00
Matthias Clasen
16e46a73f3 Plug a memory leak in gsk_render_node_serialize
This was introduced in 0d6a6a5997 with named
textures.
2023-06-27 21:43:17 -04:00
Christian Hergert
32a3690a3c maplistmodel: implement GtkSectionModel
This just wraps the underlying GListModel if it is a GtkSectionModel.
2023-06-27 18:08:20 -07:00
Benjamin Otte
526771751f Merge branch 'dboles/issue5922-DropTarget-reject-enter-critical' into 'main'
DropTarget: Fix critical if `reject()` drop before `::enter`

Closes #5922

See merge request GNOME/gtk!6152
2023-06-27 21:30:03 +00:00
Daniel Boles
dfa6591675 DropTarget: Fix critical if reject drop pre-enter
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5922

The docs of `Gtk.DropTarget::accept` say this:
> If the decision whether the drop will be accepted or rejected depends
> on the data, [`::accept`] should return `TRUE`, [`:preload`] should be
> set and the value should be inspected via the `::notify:value` signal,
> calling `gtk_drop_target_reject()` if required.

But this pattern causes a CRITICAL, given these steps:
* Create a `DragSource` and `DropTarget`
* Keep the default `::accept` handler and set `:preload` to `TRUE`
* Connect to `notify::value` and therein call `DropTarget.reject()`
* CRITICAL at `DropTarget.enter()`→`Drop.get_actions()` on NULL instance

We should let the documented case work without a CRITICAL or worse, null
deref. And per @otte on the bug, we should bail earlier before `::enter`
& setting `GTK_STATE_FLAG_DROP_ACTIVE`; neither should occur if rejected

This fixes that, by checking after `start_drop()` when notifications are
thawed, whether any handler has `reject()`ed & set our `drop` to `NULL`.
2023-06-27 21:37:32 +01:00
Daniel Boles
6252517aac DropTarget: Fix if block indented 1 step too far 2023-06-27 21:37:20 +01:00
Matthias Clasen
51e440fa03 Merge branch 'fix-asan-ifunc' into 'main'
Fix fp16 with asan

See merge request GNOME/gtk!6153
2023-06-27 19:55:28 +00:00
Matthias Clasen
d82fb6f20a Fix fp16 with asan
The IFUNC resolvers that we are using here get
run early, before asan had a chance to set up its
plumbing, and therefore things go badly if they
are compiled with asan. Turning it off makes things
work again.

The gcc bug tracking this problem:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110442

Thanks to Jakub Jelinek and Florian Weimer for
analyzing this and recommending the workaround.
2023-06-27 15:17:56 -04:00
Matthias Clasen
44de6a6cbe Merge branch 'wip/sadiq/fix-use-after-free' into 'main'
gldriver: Fix a possible use-after-free

See merge request GNOME/gtk!6151
2023-06-27 18:46:28 +00:00
Mohammed Sadiq
64e27cd87d gldriver: Fix a possible use-after-free
g_hash_table_insert() frees the given key if it already exists
in the hashtable.  But since we use the same pointer in the
following line, it will result in use-after-free.

So instead, insert the key only if it doesn't exist.
2023-06-27 22:45:07 +05:30
Benjamin Otte
60e75f8a2a Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Generate vertex array headers from shaders

See merge request GNOME/gtk!6149
2023-06-27 16:20:29 +00:00
Matthias Clasen
57eda94dde Merge branch 'matthiasc/for-main' into 'main'
gtk4-builder-tool: Fix naming

See merge request GNOME/gtk!6150
2023-06-27 11:24:08 +00:00
Matthias Clasen
723fb6c8be gtk4-builder-tool: Fix naming
We install the tool as gtk4-builder-tool, so that
is what it should call itself.

String change.
2023-06-27 07:09:04 -04:00
Benjamin Otte
6c85ed1ba1 vulkan: Generate vertex array headers from shaders
The script is pretty dumb but it does its job.
2023-06-27 07:11:48 +02:00
Benjamin Otte
2e58274f23 vulkan: Rename crossfade => cross-fade
Preparation for the future.
2023-06-27 06:46:57 +02:00
Benjamin Otte
4ade0afe03 vulkan: Rename blendmode to blend-mode
Preparation for future changes, nothing to see here.
2023-06-27 06:46:57 +02:00
Benjamin Otte
93fb45c689 Merge branch 'wip/otte/vulkan-for-main' into 'main'
vulkan: Add a pipeline cache

See merge request GNOME/gtk!6148
2023-06-26 18:52:48 +00:00
Benjamin Otte
684a015c98 vulkan: Add a pipeline cache
Make the display handle the cache, because we only need one.

We store the cache in
  $CACHE_DIR/gtk-4.0/vulkan-pipeline-cache/$UUID.$VERSION
so we regenerate caches for each different device (different UUID) and
each different driver version.

We also keep track of the etag of the cache file, so if 2 different
applications update the cache, we can detect that.
Vulkan allows merging caches, so the 2nd app reloads the new cache file
and merges it into its cache before saving.
2023-06-26 20:28:11 +02:00
Matthias Clasen
f7fcd2e425 Merge branch 'main' into 'main'
Add settable search match mode in dropdown

See merge request GNOME/gtk!6146
2023-06-26 18:18:14 +00:00
Matthias Clasen
c6c637fe21 Merge branch 'matthiasc/for-main' into 'main'
buildertool: Make render an alias for screenshot

See merge request GNOME/gtk!6147
2023-06-26 15:38:32 +00:00
Matthias Clasen
33fc4d6495 buildertool: Make render an alias for screenshot
Its a more neutral name and will align better with
other tools.
2023-06-26 10:58:35 -04:00
al_SeveR
33ff927522 Add settable search match mode in dropdown 2023-06-26 14:14:39 +00:00
Leônidas Araújo
2d39cdbff8 Update Brazilian Portuguese translation
(cherry picked from commit 98a2aae5ac)
2023-06-26 13:08:53 +00:00
Daniel Boles
8d675810e8 GtkText: Link to descendents/monospace CSS nodes
Change the descendent classes from `monospace`-without-links to links.
Add `monospace` around the names of CSS nodes and classes for clarity.
2023-06-26 13:05:39 +01:00
Matthias Clasen
8b25481c26 widget-factory: Set a11y labels on scale buttons
Just to check that this works now.
2023-06-25 22:28:23 -04:00
Ekaterine Papava
5fdf96f496 Update Georgian translation 2023-06-25 13:39:03 +00:00
Matthias Clasen
b61991a023 Merge branch 'gtkstack_fix_pages_param_check' into 'main'
stack: fix pages list bounds check

See merge request GNOME/gtk!6141
2023-06-24 12:08:18 +00:00
G.Willems
91d302a201 stack: fix pages list bounds check
Fix integer underflow when children->len is 0.
Add missing bounds check in select_item()
2023-06-24 03:05:37 +02:00
Matthias Clasen
35a1a62d50 Merge branch 'ebassi/builder-docs' into 'main'
docs: Clean up section on UI definitions

See merge request GNOME/gtk!6139
2023-06-23 23:45:05 +00:00
Matthias Clasen
ac7a4cb94c Merge branch 'wip/chergert/gdatetime-from-gtkbuilder' into 'main'
builder: add support for parsing GDateTime

See merge request GNOME/gtk!6140
2023-06-23 23:43:28 +00:00
Christian Hergert
bacd7ef92f builder: add support for parsing GDateTime
This will parse a <property/> containing the ISO 8601 format for a date
for use in GDateTime properties. For example:

  <property name="sampled-at">2023-06-23T00:00:00.00</property>
2023-06-23 14:11:37 -07:00
Emmanuele Bassi
980dc44f4a docs: Clean up section on UI definitions
The current documentation is narrative, but it lacks examples and proper
formatting, which makes it harder to read and visually scan.

Let's split off paragraphs and sections, so they can be easily linkend,
and add a few examples for each description.
2023-06-23 14:31:57 +01:00
Daniel Boles
2d648f84a9 docs/ref/gtk/running: Mention GDK_DEBUG=no-portals
It was omitted from !5336
2023-06-23 14:24:47 +01:00
Daniel Boles
aef0943f61 FileDialog: Fix typos of "inital" to "initial" 2023-06-23 13:50:53 +01:00
Matthias Clasen
3e146171cb Merge branch 'dboles/FileDialog_initial-folder_from_initial-file' into 'main'
Fix FileDialog: initial-file doesnʼt set initial-folder

See merge request GNOME/gtk!6137
2023-06-23 01:14:15 +00:00
Matthias Clasen
24bbaceaa4 Merge branch 'always-more-a11y-fixes' into 'main'
scalebutton: Use the group role

See merge request GNOME/gtk!6138
2023-06-23 01:06:57 +00:00
Matthias Clasen
318cf132e9 a11y: Extend the nested button hack to volume buttons 2023-06-22 18:37:10 -04:00
Matthias Clasen
8bbc143ed1 scalebutton: Use the group role
This is needed for accessible labels to work.
2023-06-22 18:36:39 -04:00
Daniel Boles
220d130c0f FileDialog: initial-file didnʼt set initial-folder
We always set :initial-folder to NULL and then notified about that,
instead of setting it to the folder of the :initial-file as we say.
2023-06-22 22:33:14 +01:00
Jordi Mas
e28a32a7c7 Update Catalan translation 2023-06-22 21:00:28 +02:00
Matthias Clasen
88f8b77d77 Merge branch 'matthiasc/for-main' into 'main'
docs: Mention GtkAccessibleRange

See merge request GNOME/gtk!6136
2023-06-22 02:40:08 +00:00
Matthias Clasen
1066374909 docs: Mention GtkAccessibleRange
In the accessibility docs about custom widgets,
mention GtkAccessibleRange as the best way to
implement custom range widgets.
2023-06-21 22:15:59 -04:00
Matthias Clasen
34a2595dfb Merge branch 'more-a11y-fixes' into 'main'
widget: Don't let abstract role slip through

See merge request GNOME/gtk!6135
2023-06-22 00:47:03 +00:00
Matthias Clasen
76fcd5cf25 Add another a11y test
This one catches the lingering 'widget' role
that only happens when widgets are realized
and rooted.
2023-06-21 19:55:46 -04:00
Matthias Clasen
32e6ed4eca a11y: Use group role for color and font buttons
This is needed since generic does not allow naming.
2023-06-21 19:55:46 -04:00
Matthias Clasen
2983c0be70 widget: Don't let abstract role slip through
When there isn't an accessible role set on the
instance or in class_init, we want to default
to 'generic'. There was one place where we
failed to do so.
2023-06-21 16:18:33 -04:00
Matthias Clasen
e0bf6585de Cosmetics: typo fix 2023-06-21 16:18:33 -04:00
Daniel Boles
c045b0be4c Settings: prop typo => "No description available."
Fix the typo so that we'll actually get documentation for
gtk-entry-select-on-focus.
2023-06-21 20:48:17 +01:00
Matthias Clasen
d8c094944a Merge branch 'more-a11y-fixes' into 'main'
a11y: Don't forget to space-separate computed names

See merge request GNOME/gtk!6134
2023-06-21 18:52:35 +00:00
Matthias Clasen
510bf86268 Add another a11y test
Test that roles come out right for custom widgets.
2023-06-21 14:24:52 -04:00
Matthias Clasen
f3bea027a0 Dropdown: Explicitly set a role
For some reason I haven't been able to track down,
the listitemwidget comes up wit the abstract widget
role otherwise.
2023-06-21 14:17:52 -04:00
Matthias Clasen
bce3b6f34a aboutdialog: Fix roles one more time
We are more picky about generic, so use group.
2023-06-21 13:47:59 -04:00
Matthias Clasen
01274dfbb9 shortcutswindow: Fix up roles and labels again 2023-06-21 13:18:58 -04:00
Matthias Clasen
533a2cf9ec a11y: Don't forget to space-separate computed names
This was overlooked in one place.
2023-06-21 13:18:07 -04:00
Luca Bacci
43af0ee514 Define this_module with (void) argument
Fixes a compiler warning about K&R (old-style) function definition
2023-06-21 16:18:40 +02:00
Luca Bacci
3912d6aba9 GdkWin32: Fix keyboard state for WinPointer input
The dwKeyStates field of the POINTER_INFO structure
is always set to 0, no matter what. Use GetKeyState
instead.

Forward-port of !4327 to GTK4
2023-06-21 16:18:01 +02:00
Luca Bacci
871685e271 GdkWin32: Use double coordinates for mouse events
Mouse coordinates reported by the system are still integers,
but go sub-pixel when dividing by the window scale factor.
2023-06-21 16:07:55 +02:00
Luca Bacci
5e9daa9728 GdkWin32: Unscaled coordinates in current_root_x, current_root_y
Also modify gdk_win32_surface_do_move_resize_drag() to take
unscaled root coordinates.

Fixes #5877
2023-06-21 16:01:42 +02:00
Luca Bacci
412bc1713a GdkWin32: Keep track of the last cursor position in move / resize contexts
...and avoid doing any work if the position hasn't changed.
2023-06-21 15:31:48 +02:00
Matthias Clasen
5dbc5bbf22 Merge branch 'wip/antoniof/my-mistake' into 'main'
Fix my a mistake

See merge request GNOME/gtk!6130
2023-06-21 12:01:00 +00:00
António Fernandes
79c999cf76 columnviewrowwidget: Reset roles on teardown
This was added to the wrong file in e245883f91

Fix the mistake.
2023-06-21 12:23:39 +01:00
Matthias Clasen
e375bc8838 Merge branch 'wip/antoniof/columnviewrow-accessible-label' into 'main'
columnviewrow: Add accessible-label and -description

Closes #5903

See merge request GNOME/gtk!6129
2023-06-21 10:22:41 +00:00
Matthias Clasen
79505f940b Merge branch 'always-more-a11y-fixes' into 'main'
range: Don't use an abstract role

See merge request GNOME/gtk!6127
2023-06-21 10:07:57 +00:00
Matthias Clasen
0f087deb2a Merge branch 'bump-glib' into 'main'
Bump GLib requirement to 2.76.0

See merge request GNOME/gtk!6128
2023-06-21 10:07:40 +00:00
António Fernandes
e245883f91 columnviewrow: Add accessible-label and -description
Echoing the same changes introduced for GtkListItem by these commits:
* df8d28f5fe
* f2b682dd9c

Resolves https://gitlab.gnome.org/GNOME/gtk/-/issues/5903
2023-06-21 10:27:39 +01:00
Chun-wei Fan
4e9bd13892 Visual Studio: Remove workarounds for <= glib-2.74.x
We now need glib-2.76.0 or later, which removes our needs for the workarounds
that we need to build the media backends against GLib-2.74.x or earlier, so
clean up things a bit.
2023-06-21 12:29:38 +08:00
Chun-wei Fan
65e9b8fe66 glib.wrap: Use 2.76.0
We are now using APIs that were introduced in 2.75.x, so let's use glib-2.76.0
here for our glib subproject.

Update the build and gobject-introspection items accordingly
2023-06-21 12:27:41 +08:00
Matthias Clasen
e9f870fee6 Make generic really the default role
If nothing else has been set for the instance
or the class, return GTK_ACCESSIBLE_ROLE_GENERIC.
2023-06-20 22:02:37 -04:00
Matthias Clasen
e5e5966934 frame: Use the group role 2023-06-20 21:58:55 -04:00
Matthias Clasen
5c407365e3 ci: Use the current build options for flatpaks
These were changed a while ago.
2023-06-20 20:49:29 -04:00
Matthias Clasen
7e251d81c2 a11y: Fix the stack switcher selection implementation
This was listening for signals on the wrong object.
2023-06-20 20:49:29 -04:00
Matthias Clasen
92d1d52c59 NEWS: updates 2023-06-20 20:49:29 -04:00
Matthias Clasen
ef436e4dce range: Don't use an abstract role
This snuck through, because the range wasn't
setting any role at all, it just ends up using
the initial, abstract role of widget.
2023-06-20 20:49:29 -04:00
Benjamin Otte
1a07e336bf Merge branch 'wip/otte/for-vulkan' into 'main'
vulkan: Fix a bunch of validation-layer complaints

See merge request GNOME/gtk!6126
2023-06-20 18:38:41 +00:00
Benjamin Otte
169355f771 vulkan: Rebuild the precompiled shaders
We forgot that with all the changes.
2023-06-20 20:17:06 +02:00
Benjamin Otte
299c6a3d6f vulkan: Take offscreen fromat from context
We want to create offscreens in compatible formats, and in particular we
want to ideally use the same format as rendering would use.
2023-06-20 20:15:12 +02:00
Benjamin Otte
17698bfd2e vulkan: Use 3 descriptor sets, not 3 bindings
It turns out variable length is only supported for the last binding in
a set, not for every binding.
So we need to create one set for each of our arrays.

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004 ] Object 0: handle = 0x33a9f10, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xd3f353a | vkCreateDescriptorSetLayout(): pBindings[0] has VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT but 0 is the largest value of all the bindings. The Vulkan spec states: If an element of pBindingFlags includes VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, then all other elements of VkDescriptorSetLayoutCreateInfo::pBindings must have a smaller value of binding (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-pBindingFlags-03004)
2023-06-20 20:15:12 +02:00
Benjamin Otte
377592cb62 vulkan: Use the right flags
Somebody (me) had flipped the 2 flags in commit ba28971a18:

[ VUID-vkCmdCopyBufferToImage-srcBuffer-00174 ] Object 0: handle = 0x3cfaac0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x430000000043, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xe1b276a1 | Invalid usage flag for VkBuffer 0x430000000043[] used by vkCmdCopyBufferToImage. In this case, VkBuffer should have VK_BUFFER_USAGE_TRANSFER_SRC_BIT set during creation. The Vulkan spec states: srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdCopyBufferToImage-srcBuffer-00174)
2023-06-20 20:15:12 +02:00
Benjamin Otte
015cebc046 vulkan: Set descriptorBindingStorageBufferUpdateAfterBind
It's necessary now that we use storage buffers for gradients:

[ VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008 ] Object 0: handle = 0x1e72d70, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x943cc552 | vkCreateDescriptorSetLayout(): pBindings[0] can't have VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT for VK_DESCRIPTOR_TYPE_STORAGE_BUFFER since descriptorBindingStorageBufferUpdateAfterBind is not enabled. The Vulkan spec states: If VkPhysicalDeviceDescriptorIndexingFeatures::descriptorBindingStorageBufferUpdateAfterBind is not enabled, all bindings with descriptor type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER must not use VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorSetLayoutBindingFlagsCreateInfo-descriptorBindingStorageBufferUpdateAfterBind-03008)
2023-06-20 20:15:12 +02:00
Benjamin Otte
0a5e5023a8 vulkan: Remove unused declaration from shader 2023-06-20 20:15:12 +02:00
Matthias Clasen
a9b8ad6181 Merge branch 'always-more-a11y-fixes' into 'main'
Add a comment about accessible naming

See merge request GNOME/gtk!6125
2023-06-20 17:13:51 +00:00
Matthias Clasen
7331683c01 a11y: Improve name computation
We only want to settle on subtree content
if it provides nonempty text. Otherwise,
the tooltip should still win.

This was clarified in the current Editor Draft
of the accessible name computation spec.
2023-06-20 12:34:51 -04:00
Matthias Clasen
cca6a66518 a11y: Fix tests
The change to make hidden follow mappedness
means that we now need to arrange for our
test cases to be mapped.
2023-06-20 12:33:02 -04:00
Matthias Clasen
891462e5af Add some more a11y tests
Check that the hidden state is as it should be.
2023-06-20 11:05:22 -04:00
Matthias Clasen
95cd6fe206 menubutton: Remove all the labelled-by relations
This was a bit much, and should not be necessary anymore,
now that our name computation handles nested buttons.
2023-06-20 10:58:18 -04:00
Matthias Clasen
63534fd9eb widget: Fix accessible hidden state
Make this track the widgets' mapped state
instead of visible. Also, set hidden to FALSE
initially, since the accessible name computation
checks for hidden==FALSE.
2023-06-20 10:40:12 -04:00
Matthias Clasen
e836e3380e Add a comment about accessible naming
Put a note on why there are a few differences
to ARIA.
2023-06-20 06:54:59 -04:00
Matthias Clasen
f693beab57 NEWS: Updates 2023-06-20 06:54:40 -04:00
Matthias Clasen
2d2df42a94 Merge branch 'listitem-a11y' into 'main'
listitem: Add accessible-label and -description

See merge request GNOME/gtk!6123
2023-06-20 09:55:58 +00:00
Matthias Clasen
fb0a4fa457 a11y: Stop recommending tab list labels
There is no good way to set an explicit label
on the tab list of a GtkNotebook, so showing
a blue overlay on it is annoying more than
helpful.

This is another little deviation from the ARIA
authoring guidelines.
2023-06-19 22:20:05 -04:00
Matthias Clasen
be0003c108 a11y: Stop recommending against listitem labels
Due to the way listviews are set up, there is not
much of an alternative to setting labels on the
listitems, so don't recommend against doing it.

This is a little deviation from the ARIA authoring
guidelines.
2023-06-19 22:20:05 -04:00
Matthias Clasen
eb1e24a5bf gizmo: Stop using abstract roles
This was overlooked.
2023-06-19 22:20:05 -04:00
Matthias Clasen
a3e98558d3 gtk-demo: Some a11y improvements
Add missing labels to the applauncher demo
and the clocks demo.
2023-06-19 22:19:54 -04:00
Matthias Clasen
f2b682dd9c listitemwidget: Clean up in teardown 2023-06-19 21:50:45 -04:00
Matthias Clasen
b826ef4f4d Merge branch 'a11y-work' into 'main'
A11y role changes

See merge request GNOME/gtk!6101
2023-06-20 01:23:13 +00:00
Matthias Clasen
a2fdeb99e0 gtk-demo: Improve a11y for applauncher
Use the new listitem properties to make
orca read the selected item in the applauncher
demo.
2023-06-19 21:21:55 -04:00
Matthias Clasen
df8d28f5fe listitem: Add accessible-label and -description
Add properties to GtkListItem to set the accessible
label and description of the listitem widget. This
is important, since orca will read these if the
listitem widget ends up with the focus.
2023-06-19 21:21:55 -04:00
Matthias Clasen
838c51cc92 a11y: Add the ARIA ontology
Add a helper function to find out which roles are
superclasses of each other.

This isn't used yet (apart from the existing use for
ranges), but it might be in the future.
2023-06-19 18:38:58 -04:00
Matthias Clasen
315ded687c Docs: update 2023-06-19 18:38:58 -04:00
Matthias Clasen
6855346269 a11y: Treat widget and window as abstract roles
We no longer use these, so we can enforce
that they are abstract.
2023-06-19 18:38:58 -04:00
Matthias Clasen
c2d6f900d9 window: Use application as accessible role
ARIA deems the window role to be abstract,
so lets use the application role instead.

Update affected tests.
2023-06-19 18:38:58 -04:00
Matthias Clasen
85c2d5f14e Add the application role
ARIA has this role. We left it out initially, but
it is an ok fit for toplevel windows, and better
than window, since that is meant to be abstract.
2023-06-19 18:38:58 -04:00
Matthias Clasen
b3eb912cf3 Use generic as default accessible role
The ARIA specs want widget to be abstract role.
We should respect that and use 'generic' instead.
2023-06-19 18:38:58 -04:00
Matthias Clasen
81d9205369 widget: Warn for abstract accessible roles
These should not be used for widgets, so warn if
they are passed to gtk_widget_set_accessible_role()
or gtk_widget_class_set_accessible_role().
2023-06-19 18:38:32 -04:00
Matthias Clasen
152a335cee Add gtk_accessible_role_is_abstract
Move this code from the a11y overlay in the inspector.
It will be used more widely, going forward.
2023-06-19 18:30:41 -04:00
Matthias Clasen
b84650c2a3 Add another a11y test 2023-06-19 18:30:41 -04:00
Matthias Clasen
722bea2943 Merge branch 'a11y-defeat' into 'main'
Give up on warning ATs into submission

See merge request GNOME/gtk!6121
2023-06-19 21:06:13 +00:00
Matthias Clasen
6c337b949d Merge branch 'fix-issue-5899' into 'main'
GtkFileChooserWidget: Fix condition on visit action

Closes #5899

See merge request GNOME/gtk!6103
2023-06-19 20:52:15 +00:00
Matthias Clasen
db97a35dc7 a11y: Remove the unrealized warning
This warning triggers quite a lot when opening
a window while orca is running, which clearly
shows that what it warns about happens in
practice. But fixing it is reentry hell, and
not a battle I'm up for today.
2023-06-19 16:41:39 -04:00
Matthias Clasen
c2fda63b0d Give up on warning ATs into submission
Its been more than a decade since Wayland
has not supported screen coordinates. Clearly
spamming every apps stderr with warnings is
never going to make ATs stop asking for screen
coordinates.

Just give up. Go home
2023-06-19 16:41:20 -04:00
Benjamin Otte
5da64e9e34 Merge branch 'unaligned-access' into 'main'
gtk: Align key_size up to key_align

Closes #5907

See merge request GNOME/gtk!6120
2023-06-19 20:26:18 +00:00
Matt Turner
3f360aa883 gtk: Align key_size up to key_align
Avoids unaligned accesses when e.g. the key_size is 12 and key_align is
8. We need to round the key size up to 16 to ensure that all keys are
appropriately aligned.

This manifested as a failure in the `gtk:gtk / sorter` unit test on
sparc.

Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5907
2023-06-19 15:55:09 -04:00
Matt Turner
a444045386 gtk: Pass G_ALIGNOF (...) to gtk_sort_keys_new
The sizeof and G_ALIGNOF are often, but not always, identical.
2023-06-19 15:54:51 -04:00
Daniel Boles
584a807ed6 Widget: Also mention get_height in get_alloc depʼn
The deprecation notice seems to have been copied from
get_allocated_width(), but for get_allocation() height is also relevant.
2023-06-19 20:29:23 +01:00
Matthias Clasen
72e5697804 Merge branch 'redo-a11y-name-computation' into 'main'
Reimplement a11y name computation

See merge request GNOME/gtk!6119
2023-06-19 17:49:22 +00:00
Matthias Clasen
93aff8a129 Add more name computation tests
Test the fallback for range values.

This was not working at all before
the previous commit.
2023-06-19 12:40:33 -04:00
Matthias Clasen
c3cfaab479 a11y: Fix name computation for ranges
There were two problems here:

First, the code was checking for the abstract
range role, instead of its subclasses.

Second, the code was calling a string value
getter on a number value. Oops.
2023-06-19 12:40:32 -04:00
Matthias Clasen
663e3d0811 Add tests for accessible name computation 2023-06-19 12:38:51 -04:00
Matthias Clasen
2dc35ec0c1 a11y: Quietly allow realizing unrooted at context
We can't set the display if we don't have a root,
but the default display is more than good enough
for the tests which otherwise would need to do
quite a bit more setup work to make their test
widgets rooted.
2023-06-19 12:38:51 -04:00
Matthias Clasen
a791f235e6 a11y: Only allow get_name/description when realized
These functions rely on self->accessible_role
being set, and that is only the case for realized
contexts.

In practice, this is not a problem. Contexts are
realized before ATs can get their names or descriptions,
and the inspector realizes contexts too, nowadays.

The only place where this caused a hickup is the
testsuite.
2023-06-19 12:38:51 -04:00
Matthias Clasen
7df9cc1b47 label: Stop overriding accessible label
There's no need to, the accessible name computation
picks the content up where it is allowed (and not
overridden by explicit attributes).
2023-06-19 12:38:51 -04:00
Matthias Clasen
4449344fad a11y: Reimplement name computation
Reimplement the name computation to follow the spec
(https://www.w3.org/TR/accname-1.2) more closely.

Also, unify the functions for name and description,
since their only difference is which property/relation
they use.
2023-06-19 12:38:51 -04:00
Matthias Clasen
e1c9f50d26 a11y: Cosmetics
No need to have two code paths doing the same.
2023-06-19 12:38:51 -04:00
Matthias Clasen
1f029229dc Merge branch 'a11y-inspector-tweaks' into 'main'
Move the a11y naming data into gtk proper

See merge request GNOME/gtk!6118
2023-06-19 16:21:31 +00:00
Matthias Clasen
a80dd28e35 a11y: Move naming data to gtkatcontext.c
This is in preparation for using this information
in the name computation.
2023-06-19 11:17:47 -04:00
Matthias Clasen
16077fbdac inspector: Tweak the a11y overlay
Shorten the warnings, and lower some of the
errors to 'not recommended' (where the authoring
guidelines say 'do not label', but aria doesn't
prohibit labels outright).
2023-06-19 11:17:47 -04:00
Matthias Clasen
1906bb5263 a11y: Update the name-prohibited list
ARIA has the time role in this as well.

It does not matter in practice since we don't
have a widget with this role, but lets match
the specs.
2023-06-19 11:17:47 -04:00
Matthias Clasen
a8b907a33c a11y: Cover the printer option widget case too
This is another case of nested control, in this
case it goes two levels deep. Since we already
have this hack, lets use it for all the cases.
This avoids some more complicated workaround.
2023-06-19 11:17:47 -04:00
Matthias Clasen
f2a2e97004 docs: Add guidance on container roles
Provide some guidance on whether group or generic
is a more suitable role for containers.
2023-06-19 11:17:47 -04:00
Matthias Clasen
a86923de94 a11y: Change the role for many containers
The group role that we've used before has some
implications of semantic grouping, whereas these
containers are mainly about layout, so use the
generic role instead.

This should not affect the translation to AT-SPI
at all.

The affected containers are: box, grid, centerbox,
scrolledwindow, viewport, windowhandle, aspectframe.

The role of GtkTreeExpander has been changed to
button instead, since it acts as a button.
2023-06-19 11:15:48 -04:00
Matthias Clasen
4412f25c9f a11y: Treat none and presentation the same
ARIA says these roles are aliases, so treat them
the same.
2023-06-19 11:15:48 -04:00
Luca Bacci
16bdaa11ce GtkFileChooserWidget: Use GTK_INVALID_LIST_POSITION
...instead of G_MAXUINT
2023-06-17 15:51:22 +02:00
Luca Bacci
46afb4a9a4 GtkFileChooserWidget: Fix condition on visit action
Fixes #5899
2023-06-17 15:50:50 +02:00
241 changed files with 5973 additions and 4026 deletions

2
.flake8 Normal file
View File

@@ -0,0 +1,2 @@
[flake8]
ignore = E501

View File

@@ -23,8 +23,8 @@ flatpak build ${builddir} meson \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \
-Dprofile=devel \
-Dbuild-demos=true \
-Ddemo-profile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install

88
NEWS
View File

@@ -1,6 +1,92 @@
Overview of Changes in 4.11.4, xx-xx-xxxx
Overview of Changes in 4.11.5, xx-xx-xxxx
=========================================
Overview of Changes in 4.11.4, 03-07-2023
=========================================
* GtkFileChooser:
- Default to sorting folders first
- Fix a crash when visiting recent files
* GtkTextView:
- Fix corner cases in word navigation
* GtkMenuButton:
- Normalize label layout
* GtkDropDown:
- Add support for sections
* GtkVideo:
- Make the overlay icon clickable
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* GtkFileDialog:
- Always set initial-folder
* GtkDropDown:
- Update on expression changes
* GtkMapListModel:
- Implement GtkSectionModel
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkStackSwitcher, GtkMediaControls, GtkColorDialogButton, GtkDropDown,
GtkInfoBar, GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Adapt name computation for the common 'nested button' scenario
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
- Add properties for accessible names of not directly exposed
widgets in GtkListView, GtkGridView and GtkColumnView
* DND:
- Fix criticals when drops are rejected
* X11:
- Fix regressions in GLX setup
* Windows:
- Center newly created transient windows
* Vulkan:
- Add antialising for gradients
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
- Add a pipeline cache
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
* Tools:
- gtk4-builder-tool: Make render an alias screenshot
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay with warnings and recommendations
- Limit the width of the a11y tab
* Build:
- Require GLib 2.76
- Make asan builds work again
- Fix the build if ld is not ld.bdf
* Translation updates:
Brazilian Portuguese
Catalan
Czech
Georgian
Overview of Changes in 4.11.3, 05-06-2023
=========================================

View File

@@ -162,27 +162,39 @@ click_done (GtkGesture *gesture)
gtk_widget_insert_after (item, canvas, last_child);
}
/* GtkSettings treats `GTK_THEME=foo:dark` as theme name `foo`, variant `dark`,
* and our embedded CSS files let `foo-dark` work as an alias for `foo:dark`. */
static gboolean
has_dark_suffix (const char *theme)
{
return g_str_has_suffix (theme, ":dark") ||
g_str_has_suffix (theme, "-dark");
}
/* So we can make a good guess whether the current theme is dark by checking for
* either: it is suffixed `[:-]dark`, or Settings:…prefer-dark-theme is TRUE. */
static gboolean
theme_is_dark (void)
{
const char *env_theme;
GtkSettings *settings;
char *theme;
gboolean prefer_dark;
gboolean dark;
/* Like GtkSettings, 1st see if theme is overridden by environment variable */
env_theme = g_getenv ("GTK_THEME");
if (env_theme != NULL)
return has_dark_suffix (env_theme);
/* If not, test Settings:…theme-name in the same way OR :…prefer-dark-theme */
settings = gtk_settings_get_default ();
g_object_get (settings,
"gtk-theme-name", &theme,
"gtk-application-prefer-dark-theme", &prefer_dark,
NULL);
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
dark = TRUE;
else
dark = FALSE;
dark = prefer_dark || has_dark_suffix (theme);
g_free (theme);
return dark;
}

View File

@@ -52,6 +52,10 @@ setup_listitem_cb (GtkListItemFactory *factory,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
image = gtk_image_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_PROPERTY_LABEL,
"App icon",
-1);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), image);
label = gtk_label_new ("");
@@ -79,6 +83,7 @@ bind_listitem_cb (GtkListItemFactory *factory,
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
gtk_list_item_set_accessible_label (list_item, g_app_info_get_display_name (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown

View File

@@ -431,6 +431,9 @@ setup_listitem_cb (GtkListItemFactory *factory,
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_box_append (GTK_BOX (box), picture);
gtk_accessible_update_relation (GTK_ACCESSIBLE (picture),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, location_label, NULL,
-1);
/* And finally, everything comes together.
@@ -487,6 +490,9 @@ do_listview_clocks (GtkWidget *do_widget)
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_clocks_model ()));
gridview = gtk_grid_view_new (model, factory);
gtk_accessible_update_property (GTK_ACCESSIBLE (gridview),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Clocks",
-1);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);

View File

@@ -158,17 +158,7 @@ demos_h = custom_target('gtk4 demo header',
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',

View File

@@ -1,16 +1,6 @@
# demos/widget-factory
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
if can_use_objcopy_for_resources
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',

View File

@@ -153,6 +153,35 @@ get_busy (GSimpleAction *action,
gtk_widget_set_sensitive (window, FALSE);
}
static void
search_button_tooltip_show (GtkWidget *self,
GtkTooltip *tooltip)
{
static int style = 0;
if (style == 0)
{
gtk_tooltip_set_css_class (tooltip, "red-tooltip");
style++;
}
else if (style == 1)
{
gtk_tooltip_set_css_class (tooltip, "yellow-tooltip");
style++;
}
else
{
style = 0;
}
}
static void
search_button_tooltip_hide (GtkWidget *self,
GtkTooltip *tooltip)
{
gtk_tooltip_set_css_class (tooltip, NULL);
}
static int current_page = 0;
static gboolean
on_page (int i)
@@ -2221,6 +2250,8 @@ activate (GApplication *app)
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_cscope_add_callback (scope, reset_icon_size);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_show);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_hide);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))

View File

@@ -6,3 +6,12 @@
.toolbar {
-gtk-icon-style: symbolic;
}
.red-tooltip {
background-color: red;
}
.yellow-tooltip {
background-color: yellow;
color: black;
}

View File

@@ -257,7 +257,9 @@
</object>
<object class="GtkTextBuffer" id="textbuffer1">
<property name="tag-table">tags</property>
<property name="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<property name="text">Search button above will display its tooltip in an alternating red, yellow and default style.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam fringilla, est ut feugiat ultrices, elit lacus ultricies nibh, id commodo tortor nisi id elit.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Morbi vel elit erat. Maecenas dignissim, dui et pharetra rutrum, tellus lectus rutrum mi, a convallis libero nisi quis tellus.
@@ -1572,6 +1574,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="valign">3</property>
<child>
<object class="GtkVolumeButton">
<accessibility>
<property name="label" translatable="1">Volume</property>
</accessibility>
<property name="orientation">1</property>
<property name="valign">3</property>
<property name="value">.5</property>
@@ -1584,6 +1589,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</child>
<child>
<object class="GtkScaleButton" id="mic-button">
<accessibility>
<property name="label" translatable="1">Microphone gain</property>
</accessibility>
<property name="has-tooltip">1</property>
<property name="icons">microphone-sensitivity-muted-symbolic
microphone-sensitivity-high-symbolic
@@ -1915,6 +1923,8 @@ microphone-sensitivity-medium-symbolic</property>
<property name="icon-name">edit-find</property>
<property name="action-name">win.search</property>
<property name="tooltip-text" translatable="1">Search for it</property>
<signal name="tooltip-show" handler="search_button_tooltip_show"/>
<signal name="tooltip-hide" handler="search_button_tooltip_hide"/>
</object>
</child>
<child>

View File

@@ -16,6 +16,7 @@ SYNOPSIS
| **gtk4-builder-tool** enumerate [OPTIONS...] <FILE>
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
| **gtk4-builder-tool** render [OPTIONS...] <FILE>
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
DESCRIPTION
@@ -69,12 +70,11 @@ file to use.
Load style information from the given CSS file.
Screenshot
^^^^^^^^^^
Render
^^^^^^
The ``screenshot`` command saves a rendering of the UI definition file
as a png image or node file. The name of the file to write can be specified as
a second FILE argument.
The ``render`` command saves a rendering of the UI definition file as a png image
or node file. The name of the file to write can be specified as a second FILE argument.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
@@ -96,6 +96,11 @@ file to use.
Overwrite an existing file.
Screenshot
^^^^^^^^^^
The ``screenshot`` command is an alias for ``render``.
Simplification
^^^^^^^^^^^^^^

View File

@@ -211,6 +211,9 @@ A number of options affect behavior instead of logging:
`portals`
: Force the use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`no-portals`
: Disable use of [portals](https://docs.flatpak.org/en/latest/portals.html)
`gl-disable`
: Disable OpenGL support

View File

@@ -31,7 +31,7 @@ described by a set of *attributes*.
Roles define the taxonomy and semantics of a UI control to any assistive
technology application; for instance, a button will have a role of
`GTK_ACCESSIBLE_ROLE_BUTTON`; an entry will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a toggle button will have a role of
`GTK_ACCESSIBLE_ROLE_TEXTBOX`; a check button will have a role of
`GTK_ACCESSIBLE_ROLE_CHECKBOX`; etc.
Each role is part of the widget's instance, and **cannot** be changed over
@@ -46,6 +46,7 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| Role name | Description | Related GTK widget |
|-----------|-------------|--------------------|
| `APPLICATION` | An application window | [class@Gtk.Window] |
| `BUTTON` | A control that performs an action when pressed | [class@Gtk.Button], [class@Gtk.LinkButton], [class@Gtk.Expander] |
| `CHECKBOX` | A control that has three possible value: `true`, `false`, or `undefined` | [class@Gtk.CheckButton] |
| `COMBOBOX` | A control that can be expanded to show a list of possible values to select | [class@Gtk.ComboBox] |
@@ -78,7 +79,6 @@ Each role name is part of the #GtkAccessibleRole enumeration.
| `TAB_PANEL` | A page in a notebook or stack | [class@Gtk.Stack] |
| `TEXT_BOX` | A type of input that allows free-form text as its value. | [class@Gtk.Entry], [class@Gtk.PasswordEntry], [class@Gtk.TextView] |
| `TREE_GRID` | A treeview-like columned list | [class@Gtk.ColumnView] |
| `WINDOW` | An application window | [class@Gtk.Window] |
| `...` | … |
See the [WAI-ARIA](https://www.w3.org/WAI/PF/aria/appendices#quickref) list
@@ -216,6 +216,16 @@ are accessible as part of the development process. The GTK Inspector shows
the accessible attributes of each widget, and also provides an overlay that
can highlight accessibility issues.
It is possible to set accessible attributes in UI files as well:
```xml
<object class="GtkButton" id="button1">
<accessibility>
<property name="label">Download</property>
<relation name="labelled-by">label1</relation>
/accessibility>
</object>
```
## Implementations
Each UI control implements the `GtkAccessible` interface to allow widget and
@@ -257,6 +267,13 @@ turn automatically any widget into a `GtkButton`; but if your widget behaves
like a button, using the %GTK_ACCESSIBLE_ROLE_BUTTON will allow any
assistive technology to handle it like they would a `GtkButton`.
For widgets that act as containers of other widgets, you should use
%GTK_ACCESSIBLE_ROLE_GROUP if the grouping of the children is semantic
in nature; for instance, the children of a [class@Gtk.HeaderBar] are
grouped together on the header of a window. For generic containers that
only impose a layout on their children, you should use
%GTK_ACCESSIBLE_ROLE_GENERIC instead.
### Attributes can both hide and enhance
Accessible attributes can be used to override the content of a UI element,
@@ -365,3 +382,6 @@ To allow changing the value via accessible technologies, you can export
actions. Since the accessibility interfaces only support actions
without parameters, you should provide actions such as `increase-value`
and `decrease-value`.
Since GTK 4.10, the best way to suppose changing the value is by implementing
the [iface@Gtk.AccessibleRange] interface.

View File

@@ -30,12 +30,12 @@ Views display data from a **_model_**. Models implement the [`iface@Gio.ListMode
interface and can be provided in a variety of ways:
* List model implementations for many specific types of data already exist, for
example `GtkDirectoryList` or `GtkStringList`.
example [`class@Gtk.DirectoryList`] or [`class@Gtk.StringList`].
* There are generic list model implementations like`GListStore` that allow building
* There are generic list model implementations like [`class@Gio.ListStore`] that allow building
lists of arbitrary objects.
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
* Wrapping list models like [`class@Gtk.FilterListModel`] or [`class@Gtk.SortListModel`]
modify, adapt or combine other models.
* Last but not least, developers are encouraged to create their own `GListModel`
@@ -133,8 +133,8 @@ tradeoffs of those and experiment with them.
GTK offers a wide variety of wrapping models which change or supplement an
existing model (or models) in some way. But when it comes to storing your
actual data, there are only a few ready-made choices available: [`class@Gio.ListStore`]
and [`class@Gtk.StringList`].
actual data, there are only a few ready-made choices available:
[`class@Gio.ListStore`], [`class@Gtk.StringList`], and [`class@Gtk.DirectoryList`].
`GListStore` is backed by a balanced tree and has performance characteristics
that are expected for that data structure. It works reasonably well for dataset
@@ -147,6 +147,10 @@ that are expected for that data structure. `GtkStringList` is a good fit for any
place where you would otherwise use `char*[]` and works best if the dataset
is not very dynamic.
`GtkDirectoryList` is a list model that wraps [`method@Gio.File.enumerate_children_async`].
It presents a `GListModel` and fills it asynchronously with the [`iface@Gio.File`]s
returned from that function.
If these models don't fit your use case or scalability requirements, you
should make a custom `GListModel` implementation. It is a small interface and
not very hard to implement.
@@ -199,7 +203,7 @@ the `.data-table` style class.
## Sections
List models can optionally group their items into **_sections_**, by implementing
the `GtkSectionModel` interface. Both `GtkListView` and `GtkGridView` can
the `GtkSectionModel` interface. `GtkListView` can
display headers for sections, by installing a separate **_header factory_**.
Many GTK list models support section inherently, or they pass through the

View File

@@ -100,6 +100,10 @@ struct _GdkDisplay
VkDevice vk_device;
VkQueue vk_queue;
uint32_t vk_queue_family_index;
VkPipelineCache vk_pipeline_cache;
gsize vk_pipeline_cache_size;
char *vk_pipeline_cache_etag;
guint vk_save_pipeline_cache_source;
guint vulkan_refcount;
#endif /* GDK_RENDERING_VULKAN */

View File

@@ -1552,7 +1552,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GK_APPLE_sync");
epoxy_has_gl_extension ("GL_APPLE_sync");
#ifdef G_ENABLE_DEBUG
{

View File

@@ -25,7 +25,8 @@
* multiple frames, and will be used for a long time.
*
* There are various ways to create `GdkTexture` objects from a
* [class@GdkPixbuf.Pixbuf], or a Cairo surface, or other pixel data.
* [class@GdkPixbuf.Pixbuf], or from bytes stored in memory, a file, or a
* [struct@Gio.Resource].
*
* The ownership of the pixel data is transferred to the `GdkTexture`
* instance; you can only make a copy of it, via [method@Gdk.Texture.download].

View File

@@ -52,6 +52,7 @@ struct _GdkVulkanContextPrivate {
GdkMemoryFormat gdk_format;
} formats[4];
GdkMemoryDepth current_format;
GdkMemoryFormat offscreen_formats[4];
VkSwapchainKHR swapchain;
VkSemaphore draw_semaphore;
@@ -693,6 +694,11 @@ gdk_vulkan_context_real_init (GInitable *initable,
if (!priv->vulkan_ref)
return FALSE;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U16] = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT16] = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_FLOAT32] = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (surface == NULL)
{
for (i = 0; i < G_N_ELEMENTS (priv->formats); i++)
@@ -748,6 +754,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
{
priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
priv->offscreen_formats[GDK_MEMORY_U8] = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
};
break;
@@ -827,6 +834,15 @@ out_surface:
return FALSE;
}
GdkMemoryFormat
gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
return priv->offscreen_formats[depth];
}
static void
gdk_vulkan_context_initable_init (GInitableIface *iface)
{
@@ -915,6 +931,216 @@ gdk_vulkan_context_get_queue_family_index (GdkVulkanContext *context)
return gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context))->vk_queue_family_index;
}
static char *
gdk_vulkan_get_pipeline_cache_dirname (void)
{
return g_build_filename (g_get_user_cache_dir (), "gtk-4.0", "vulkan-pipeline-cache", NULL);
}
static GFile *
gdk_vulkan_get_pipeline_cache_file (GdkDisplay *display)
{
VkPhysicalDeviceProperties props;
char *dirname, *basename, *path;
GFile *result;
vkGetPhysicalDeviceProperties (display->vk_physical_device, &props);
dirname = gdk_vulkan_get_pipeline_cache_dirname ();
basename = g_strdup_printf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x"
"-%02x%02x%02x%02x%02x%02x.%u",
props.pipelineCacheUUID[0], props.pipelineCacheUUID[1],
props.pipelineCacheUUID[2], props.pipelineCacheUUID[3],
props.pipelineCacheUUID[4], props.pipelineCacheUUID[5],
props.pipelineCacheUUID[6], props.pipelineCacheUUID[7],
props.pipelineCacheUUID[8], props.pipelineCacheUUID[9],
props.pipelineCacheUUID[10], props.pipelineCacheUUID[11],
props.pipelineCacheUUID[12], props.pipelineCacheUUID[13],
props.pipelineCacheUUID[14], props.pipelineCacheUUID[15],
props.driverVersion);
path = g_build_filename (dirname, basename, NULL);
result = g_file_new_for_path (path);
g_free (path);
g_free (basename);
g_free (dirname);
return result;
}
static VkPipelineCache
gdk_display_load_pipeline_cache (GdkDisplay *display)
{
GError *error = NULL;
VkPipelineCache result;
GFile *cache_file;
char *etag, *data;
gsize size;
cache_file = gdk_vulkan_get_pipeline_cache_file (display);
if (!g_file_load_contents (cache_file, NULL, &data, &size, &etag, &error))
{
GDK_DEBUG (VULKAN, "failed to load Vulkan pipeline cache file '%s': %s\n",
g_file_peek_path (cache_file), error->message);
g_object_unref (cache_file);
g_clear_error (&error);
return VK_NULL_HANDLE;
}
if (GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
.initialDataSize = size,
.pInitialData = data,
},
NULL,
&result) != VK_SUCCESS)
result = VK_NULL_HANDLE;
g_free (data);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
display->vk_pipeline_cache_size = size;
return result;
}
static gboolean
gdk_vulkan_save_pipeline_cache (GdkDisplay *display)
{
GError *error = NULL;
VkDevice device;
VkPipelineCache cache;
GFile *file;
char *path;
size_t size;
char *data, *etag;
device = display->vk_device;
cache = display->vk_pipeline_cache;
GDK_VK_CHECK (vkGetPipelineCacheData, device, cache, &size, NULL);
if (size == 0)
return TRUE;
if (size == display->vk_pipeline_cache_size)
{
GDK_DEBUG (VULKAN, "pipeline cache size (%zu bytes) unchanged, skipping save", size);
return TRUE;
}
data = g_malloc (size);
if (GDK_VK_CHECK (vkGetPipelineCacheData, device, cache, &size, data) != VK_SUCCESS)
{
g_free (data);
return FALSE;
}
path = gdk_vulkan_get_pipeline_cache_dirname ();
if (g_mkdir_with_parents (path, 0755) != 0)
{
g_warning_once ("Failed to create pipeline cache directory");
g_free (path);
return FALSE;
}
g_free (path);
file = gdk_vulkan_get_pipeline_cache_file (display);
GDK_DEBUG (VULKAN, "Saving pipeline cache to %s", g_file_peek_path (file));
if (!g_file_replace_contents (file,
data,
size,
display->vk_pipeline_cache_etag,
FALSE,
0,
&etag,
NULL,
&error))
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WRONG_ETAG))
{
VkPipelineCache new_cache;
GDK_DEBUG (VULKAN, "Pipeline cache file modified, merging into current");
new_cache = gdk_display_load_pipeline_cache (display);
if (new_cache)
{
GDK_VK_CHECK (vkMergePipelineCaches, device, cache, 1, &new_cache);
vkDestroyPipelineCache (device, new_cache, NULL);
}
else
{
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
}
g_clear_error (&error);
g_object_unref (file);
/* try again */
return gdk_vulkan_save_pipeline_cache (display);
}
g_warning ("Failed to save pipeline cache: %s", error->message);
g_clear_error (&error);
g_object_unref (file);
return FALSE;
}
g_object_unref (file);
g_free (display->vk_pipeline_cache_etag);
display->vk_pipeline_cache_etag = etag;
return TRUE;
}
static gboolean
gdk_vulkan_save_pipeline_cache_cb (gpointer data)
{
GdkDisplay *display = data;
gdk_vulkan_save_pipeline_cache (display);
display->vk_save_pipeline_cache_source = 0;
return G_SOURCE_REMOVE;
}
void
gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self)
{
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self));
g_clear_handle_id (&display->vk_save_pipeline_cache_source, g_source_remove);
display->vk_save_pipeline_cache_source = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE - 10,
10, /* random choice that is not now */
gdk_vulkan_save_pipeline_cache_cb,
display,
NULL);
}
static void
gdk_display_create_pipeline_cache (GdkDisplay *display)
{
display->vk_pipeline_cache = gdk_display_load_pipeline_cache (display);
GDK_VK_CHECK (vkCreatePipelineCache, display->vk_device,
&(VkPipelineCacheCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
},
NULL,
&display->vk_pipeline_cache);
}
VkPipelineCache
gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self)
{
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (self), NULL);
return gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self))->vk_pipeline_cache;
}
/**
* gdk_vulkan_context_get_image_format:
* @context: a `GdkVulkanContext`
@@ -1168,6 +1394,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
.descriptorBindingPartiallyBound = VK_TRUE,
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE,
.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE,
}
},
NULL,
@@ -1364,6 +1591,8 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
return FALSE;
}
gdk_display_create_pipeline_cache (display);
return TRUE;
}
@@ -1392,6 +1621,16 @@ gdk_display_unref_vulkan (GdkDisplay *display)
if (display->vulkan_refcount > 0)
return;
if (display->vk_save_pipeline_cache_source)
{
gdk_vulkan_save_pipeline_cache_cb (display);
g_assert (display->vk_save_pipeline_cache_source == 0);
}
vkDestroyPipelineCache (display->vk_device, display->vk_pipeline_cache, NULL);
display->vk_device = VK_NULL_HANDLE;
g_clear_pointer (&display->vk_pipeline_cache_etag, g_free);
display->vk_pipeline_cache_size = 0;
vkDestroyDevice (display->vk_device, NULL);
display->vk_device = VK_NULL_HANDLE;
if (display->vk_debug_callback != VK_NULL_HANDLE)

View File

@@ -69,9 +69,15 @@ gdk_vulkan_handle_result (VkResult res,
#define GDK_VK_CHECK(func, ...) gdk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func))
gboolean gdk_display_ref_vulkan (GdkDisplay *display,
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
gboolean gdk_display_ref_vulkan (GdkDisplay *display,
GError **error);
void gdk_display_unref_vulkan (GdkDisplay *display);
VkPipelineCache gdk_vulkan_context_get_pipeline_cache (GdkVulkanContext *self);
void gdk_vulkan_context_pipeline_cache_updated (GdkVulkanContext *self);
GdkMemoryFormat gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context,
GdkMemoryDepth depth);
#else /* !GDK_RENDERING_VULKAN */

View File

@@ -3064,9 +3064,9 @@ tablet_tool_handle_button (void *data,
tablet->pointer_info.press_serial = serial;
if (button == BTN_STYLUS)
n_button = GDK_BUTTON_SECONDARY;
else if (button == BTN_STYLUS2)
n_button = GDK_BUTTON_MIDDLE;
else if (button == BTN_STYLUS2)
n_button = GDK_BUTTON_SECONDARY;
else if (button == BTN_STYLUS3)
n_button = 8; /* Back */
else

View File

@@ -139,7 +139,6 @@ static GSourceFuncs event_funcs = {
static GdkSurface *mouse_window = NULL;
static GdkSurface *mouse_window_ignored_leave = NULL;
static int current_x, current_y;
static int current_root_x, current_root_y;
static UINT got_gdk_events_message;
@@ -1522,14 +1521,15 @@ generate_button_event (GdkEventType type,
GdkEvent *event;
GdkDeviceManagerWin32 *device_manager;
GdkWin32Surface *impl = GDK_WIN32_SURFACE (window);
double x, y;
if (_gdk_input_ignore_core > 0)
return;
device_manager = GDK_DEVICE_MANAGER_WIN32 (_gdk_device_manager);
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
_gdk_device_manager->system_pointer);
@@ -1541,10 +1541,10 @@ generate_button_event (GdkEventType type,
_gdk_win32_get_next_tick (msg->time),
build_pointer_event_state (msg),
button,
current_x,
current_y,
x,
y,
NULL);
_gdk_win32_append_event (event);
}
@@ -2350,19 +2350,19 @@ gdk_event_translate (MSG *msg,
* sends WM_MOUSEMOVE messages after a new window is shown under
* the mouse, even if the mouse hasn't moved. This disturbs gtk.
*/
if (msg->pt.x / impl->surface_scale == current_root_x &&
msg->pt.y / impl->surface_scale == current_root_y)
if (msg->pt.x == current_root_x &&
msg->pt.y == current_root_y)
break;
current_root_x = msg->pt.x / impl->surface_scale;
current_root_y = msg->pt.y / impl->surface_scale;
current_root_x = msg->pt.x;
current_root_y = msg->pt.y;
if (impl->drag_move_resize_context.op != GDK_WIN32_DRAGOP_NONE)
gdk_win32_surface_do_move_resize_drag (window, current_root_x, current_root_y);
gdk_win32_surface_do_move_resize_drag (window, msg->pt.x, msg->pt.y);
else if (_gdk_input_ignore_core == 0)
{
current_x = (gint16) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
current_y = (gint16) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
double x = (double) GET_X_LPARAM (msg->lParam) / impl->surface_scale;
double y = (double) GET_Y_LPARAM (msg->lParam) / impl->surface_scale;
_gdk_device_virtual_set_active (_gdk_device_manager->core_pointer,
_gdk_device_manager->system_pointer);
@@ -2372,8 +2372,8 @@ gdk_event_translate (MSG *msg,
NULL,
_gdk_win32_get_next_tick (msg->time),
build_pointer_event_state (msg),
current_x,
current_y,
x,
y,
NULL);
_gdk_win32_append_event (event);

View File

@@ -271,9 +271,10 @@ winpointer_make_event (GdkDeviceWinpointer *device,
y /= impl->surface_scale;
state = 0;
if (info->dwKeyStates & POINTER_MOD_CTRL)
/* Note that info->dwKeyStates is not reliable, use GetKeyState() */
if (GetKeyState (VK_CONTROL) < 0)
state |= GDK_CONTROL_MASK;
if (info->dwKeyStates & POINTER_MOD_SHIFT)
if (GetKeyState (VK_SHIFT) < 0)
state |= GDK_SHIFT_MASK;
if (GetKeyState (VK_MENU) < 0)
state |= GDK_ALT_MASK;

View File

@@ -3535,6 +3535,8 @@ setup_drag_move_resize_context (GdkSurface *surface,
context->button = button;
context->start_root_x = root_x;
context->start_root_y = root_y;
context->current_root_x = root_x;
context->current_root_y = root_y;
context->timestamp = timestamp;
context->start_rect = rect;
@@ -3650,6 +3652,16 @@ gdk_win32_surface_do_move_resize_drag (GdkSurface *window,
if (!_gdk_win32_get_window_rect (window, &rect))
return;
x /= impl->surface_scale;
y /= impl->surface_scale;
if (context->current_root_x == x &&
context->current_root_y == y)
return;
context->current_root_x = x;
context->current_root_y = y;
new_rect = context->start_rect;
diffx = (x - context->start_root_x) * impl->surface_scale;
diffy = (y - context->start_root_y) * impl->surface_scale;

View File

@@ -137,6 +137,12 @@ struct _GdkW32DragMoveResizeContext
int start_root_x;
int start_root_y;
/* Last processed cursor position. Values are divided by the window
* scale.
*/
int current_root_x;
int current_root_y;
/* Initial window rectangle (position and size).
* The window is resized/moved relative to this (see start_root_*).
*/

View File

@@ -165,7 +165,7 @@ void half_to_float4 (const guint16 h[4], float f[4]) __attribute__((ifunc ("reso
void float_to_half (const float *f, guint16 *h, int n) __attribute__((ifunc ("resolve_float_to_half")));
void half_to_float (const guint16 *h, float *f, int n) __attribute__((ifunc ("resolve_half_to_float")));
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half4 (void)
{
__builtin_cpu_init ();
@@ -175,7 +175,7 @@ resolve_float_to_half4 (void)
return float_to_half4_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float4 (void)
{
__builtin_cpu_init ();
@@ -185,7 +185,7 @@ resolve_half_to_float4 (void)
return half_to_float4_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_float_to_half (void)
{
__builtin_cpu_init ();
@@ -195,7 +195,7 @@ resolve_float_to_half (void)
return float_to_half_c;
}
static void *
static void * __attribute__ ((no_sanitize_address))
resolve_half_to_float (void)
{
__builtin_cpu_init ();

View File

@@ -686,17 +686,21 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
const GskTextureKey *key,
guint texture_id)
{
GskTextureKey *k;
g_assert (GSK_IS_GL_DRIVER (self));
g_assert (key != NULL);
g_assert (texture_id > 0);
g_assert (g_hash_table_contains (self->textures, GUINT_TO_POINTER (texture_id)));
k = g_memdup (key, sizeof *key);
if (!g_hash_table_contains (self->key_to_texture_id, key))
{
GskTextureKey *k;
g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
k = g_memdup (key, sizeof *key);
g_assert (!g_hash_table_contains (self->texture_id_to_key, GUINT_TO_POINTER (texture_id)));
g_hash_table_insert (self->key_to_texture_id, k, GUINT_TO_POINTER (texture_id));
g_hash_table_insert (self->texture_id_to_key, GUINT_TO_POINTER (texture_id), k);
}
}
/**

View File

@@ -803,6 +803,8 @@ gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
out_rect->origin.x -= job->offset_x;
out_rect->origin.y -= job->offset_y;
gsk_transform_unref (transform);
}
static inline void

View File

@@ -13,6 +13,12 @@ void main() {
uniform int u_mode;
uniform sampler2D u_mask;
float
luminance (vec3 color)
{
return dot (vec3 (0.2126, 0.7152, 0.0722), color);
}
void main() {
vec4 source = GskTexture(u_source, vUv);
vec4 mask = GskTexture(u_mask, vUv);
@@ -23,9 +29,9 @@ void main() {
else if (u_mode == 1)
mask_value = 1.0 - mask.a;
else if (u_mode == 2)
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
mask_value = luminance (mask.rgb);
else if (u_mode == 3)
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
mask_value = mask.a - luminance (mask.rgb);
else
mask_value = 0.0;

View File

@@ -2421,6 +2421,7 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
node = (GskRenderNode *) self;
@@ -2696,7 +2697,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1,
static void
gsk_outset_shadow_node_class_init (gpointer g_class,
gpointer class_data)
gpointer class_data)
{
GskRenderNodeClass *node_class = g_class;
@@ -2734,6 +2735,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
g_return_val_if_fail (outline != NULL, NULL);
g_return_val_if_fail (color != NULL, NULL);
g_return_val_if_fail (blur_radius >= 0, NULL);
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
node = (GskRenderNode *) self;
@@ -3700,8 +3702,7 @@ gsk_color_matrix_node_finalize (GskRenderNode *node)
static void
apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset,
gboolean multiply_alpha)
const graphene_vec4_t *color_offset)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
@@ -3739,13 +3740,6 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
graphene_matrix_transform_vec4 (color_matrix, &pixel, &pixel);
}
if (multiply_alpha)
graphene_vec4_init (&pixel,
graphene_vec4_get_x (&pixel),
graphene_vec4_get_y (&pixel),
graphene_vec4_get_z (&pixel),
alpha * graphene_vec4_get_w (&pixel));
graphene_vec4_add (&pixel, color_offset, &pixel);
alpha = graphene_vec4_get_w (&pixel);
@@ -3768,6 +3762,8 @@ apply_color_matrix_to_pattern (cairo_pattern_t *pattern,
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}
static void
@@ -3789,7 +3785,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
pattern = cairo_pop_group (cr);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset, FALSE);
apply_color_matrix_to_pattern (pattern, &self->color_matrix, &self->color_offset);
cairo_set_source (cr, pattern);
cairo_paint (cr);
@@ -5650,6 +5646,50 @@ gsk_mask_node_finalize (GskRenderNode *node)
parent_class->finalize (node);
}
static void
apply_luminance_to_pattern (cairo_pattern_t *pattern,
gboolean invert_luminance)
{
cairo_surface_t *surface, *image_surface;
guchar *data;
gsize x, y, width, height, stride;
int red, green, blue, alpha, luminance;
guint32* pixel_data;
cairo_pattern_get_surface (pattern, &surface);
image_surface = cairo_surface_map_to_image (surface, NULL);
data = cairo_image_surface_get_data (image_surface);
width = cairo_image_surface_get_width (image_surface);
height = cairo_image_surface_get_height (image_surface);
stride = cairo_image_surface_get_stride (image_surface);
for (y = 0; y < height; y++)
{
pixel_data = (guint32 *) data;
for (x = 0; x < width; x++)
{
alpha = (pixel_data[x] >> 24) & 0xFF;
red = (pixel_data[x] >> 16) & 0xFF;
green = (pixel_data[x] >> 8) & 0xFF;
blue = (pixel_data[x] >> 0) & 0xFF;
luminance = 2126 * red + 7152 * green + 722 * blue;
if (invert_luminance)
luminance = 10000 * alpha - luminance;
luminance = (luminance + 5000) / 10000;
pixel_data[x] = luminance * 0x1010101;
}
data += stride;
}
cairo_surface_mark_dirty (image_surface);
cairo_surface_unmap_image (surface, image_surface);
/* https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/487 */
cairo_surface_mark_dirty (surface);
}
static void
gsk_mask_node_draw (GskRenderNode *node,
cairo_t *cr)
@@ -5672,28 +5712,18 @@ gsk_mask_node_draw (GskRenderNode *node,
case GSK_MASK_MODE_ALPHA:
break;
case GSK_MASK_MODE_INVERTED_ALPHA:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, -1 });
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, FALSE);
graphene_matrix_init_from_float (&color_matrix, (float[]){ 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
-1, -1, -1, -1 });
graphene_vec4_init (&color_offset, 1, 1, 1, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset);
break;
case GSK_MASK_MODE_LUMINANCE:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, 0.2126,
0, 1, 0, 0.7152,
0, 0, 1, 0.0722,
0, 0, 0, 0 });
graphene_vec4_init (&color_offset, 0, 0, 0, 0);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
apply_luminance_to_pattern (mask_pattern, FALSE);
break;
case GSK_MASK_MODE_INVERTED_LUMINANCE:
graphene_matrix_init_from_float (&color_matrix, (float[]){ 1, 0, 0, -0.2126,
0, 1, 0, -0.7152,
0, 0, 1, -0.0722,
0, 0, 0, 0 });
graphene_vec4_init (&color_offset, 0, 0, 0, 1);
apply_color_matrix_to_pattern (mask_pattern, &color_matrix, &color_offset, TRUE);
apply_luminance_to_pattern (mask_pattern, TRUE);
break;
default:
g_assert_not_reached ();
@@ -5703,6 +5733,8 @@ gsk_mask_node_draw (GskRenderNode *node,
cairo_clip (cr);
cairo_mask (cr, mask_pattern);
cairo_pattern_destroy (mask_pattern);
}
static void
@@ -5713,6 +5745,12 @@ gsk_mask_node_diff (GskRenderNode *node1,
GskMaskNode *self1 = (GskMaskNode *) node1;
GskMaskNode *self2 = (GskMaskNode *) node2;
if (self1->mask_mode != self2->mask_mode)
{
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
gsk_render_node_diff (self1->source, self2->source, region);
gsk_render_node_diff (self1->mask, self2->mask, region);
}

View File

@@ -453,6 +453,21 @@ parse_double (GtkCssParser *parser,
return gtk_css_parser_consume_number (parser, out_double);
}
static gboolean
parse_positive_double (GtkCssParser *parser,
Context *context,
gpointer out_double)
{
if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_NUMBER)
|| gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNED_INTEGER))
{
gtk_css_parser_error_syntax (parser, "Expected a positive number");
return FALSE;
}
return gtk_css_parser_consume_number (parser, out_double);
}
static gboolean
parse_point (GtkCssParser *parser,
Context *context,
@@ -1242,10 +1257,10 @@ parse_radial_gradient_node_internal (GtkCssParser *parser,
const Declaration declarations[] = {
{ "bounds", parse_rect, NULL, &bounds },
{ "center", parse_point, NULL, &center },
{ "hradius", parse_double, NULL, &hradius },
{ "vradius", parse_double, NULL, &vradius },
{ "start", parse_double, NULL, &start },
{ "end", parse_double, NULL, &end },
{ "hradius", parse_positive_double, NULL, &hradius },
{ "vradius", parse_positive_double, NULL, &vradius },
{ "start", parse_positive_double, NULL, &start },
{ "end", parse_positive_double, NULL, &end },
{ "stops", parse_stops, clear_stops, &stops },
};
GskRenderNode *result;
@@ -1335,7 +1350,7 @@ parse_inset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_double, NULL, &blur }
{ "blur", parse_positive_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -1737,7 +1752,7 @@ parse_outset_shadow_node (GtkCssParser *parser,
{ "dx", parse_double, NULL, &dx },
{ "dy", parse_double, NULL, &dy },
{ "spread", parse_double, NULL, &spread },
{ "blur", parse_double, NULL, &blur }
{ "blur", parse_positive_double, NULL, &blur }
};
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
@@ -2017,7 +2032,7 @@ parse_blur_node (GtkCssParser *parser,
GskRenderNode *child = NULL;
double blur_radius = 1.0;
const Declaration declarations[] = {
{ "blur", parse_double, NULL, &blur_radius },
{ "blur", parse_positive_double, NULL, &blur_radius },
{ "child", parse_node, clear_node, &child },
};
GskRenderNode *result;
@@ -2477,6 +2492,15 @@ printer_init (Printer *self,
printer_init_duplicates_for_node (self, node);
}
static void
printer_clear (Printer *self)
{
if (self->str)
g_string_free (self->str, TRUE);
g_hash_table_unref (self->named_nodes);
g_hash_table_unref (self->named_textures);
}
#define IDENT_LEVEL 2 /* Spaces per level */
static void
_indent (Printer *self)
@@ -3686,6 +3710,7 @@ GBytes *
gsk_render_node_serialize (GskRenderNode *node)
{
Printer p;
GBytes *res;
printer_init (&p, node);
@@ -3705,5 +3730,9 @@ gsk_render_node_serialize (GskRenderNode *node)
render_node_print (&p, node);
}
return g_string_free_to_bytes (p.str);
res = g_string_free_to_bytes (g_steal_pointer (&p.str));
printer_clear (&p);
return res;
}

View File

@@ -103,6 +103,7 @@ gsk_private_vulkan_shaders = []
# on constantly regenerated files.
gsk_private_vulkan_compiled_shaders = []
gsk_private_vulkan_compiled_shaders_deps = []
gsk_private_vulkan_shader_headers = []
if have_vulkan
gsk_private_sources += files([
@@ -197,6 +198,7 @@ libgsk = static_library('gsk',
gsk_private_sources,
gsk_enums,
gskresources,
gsk_private_vulkan_shader_headers,
],
dependencies: gsk_deps,
include_directories: [ confinc, ],

View File

@@ -2,6 +2,8 @@
#include "gskvulkanblendmodepipelineprivate.h"
#include "vulkan/resources/blend-mode.vert.h"
struct _GskVulkanBlendModePipeline
{
GObject parent_instance;
@@ -9,89 +11,12 @@ struct _GskVulkanBlendModePipeline
typedef struct _GskVulkanBlendModeInstance GskVulkanBlendModeInstance;
struct _GskVulkanBlendModeInstance
{
float rect[4];
float top_rect[4];
float bottom_rect[4];
float top_tex_rect[4];
float bottom_tex_rect[4];
guint32 top_tex_id[2];
guint32 bottom_tex_id[2];
guint32 blend_mode;
};
G_DEFINE_TYPE (GskVulkanBlendModePipeline, gsk_vulkan_blend_mode_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_blend_mode_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBlendModeInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, top_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, bottom_rect),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, top_tex_rect),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, bottom_tex_rect),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, top_tex_id),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, bottom_tex_id),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlendModeInstance, blend_mode),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_blend_mode_info;
}
static void

View File

@@ -2,68 +2,19 @@
#include "gskvulkanblurpipelineprivate.h"
#include "vulkan/resources/blur.vert.h"
struct _GskVulkanBlurPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanBlurInstance GskVulkanBlurInstance;
struct _GskVulkanBlurInstance
{
float rect[4];
float tex_rect[4];
float blur_radius;
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanBlurPipeline, gsk_vulkan_blur_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_blur_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBlurInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, blur_radius),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanBlurInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_blur_info;
}
static void
@@ -105,7 +56,7 @@ gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline,
const graphene_point_t *offset,
const graphene_rect_t *rect,
const graphene_rect_t *tex_rect,
double blur_radius)
double radius)
{
GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) data;
@@ -117,7 +68,7 @@ gsk_vulkan_blur_pipeline_collect_vertex_data (GskVulkanBlurPipeline *pipeline,
instance->tex_rect[1] = tex_rect->origin.y;
instance->tex_rect[2] = tex_rect->size.width;
instance->tex_rect[3] = tex_rect->size.height;
instance->blur_radius = blur_radius;
instance->radius = radius;
instance->tex_id[0] = tex_id[0];
instance->tex_id[1] = tex_id[1];
}

View File

@@ -4,91 +4,19 @@
#include "gskroundedrectprivate.h"
#include "vulkan/resources/border.vert.h"
struct _GskVulkanBorderPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanBorderInstance GskVulkanBorderInstance;
struct _GskVulkanBorderInstance
{
float rect[12];
float widths[4];
float colors[16];
};
G_DEFINE_TYPE (GskVulkanBorderPipeline, gsk_vulkan_border_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_border_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBorderInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, rect) + 4 * sizeof (float),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, rect) + 8 * sizeof (float),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, widths),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors) + 4 * sizeof (float),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors) + 8 * sizeof (float),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBorderInstance, colors) + 12 * sizeof (float),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_border_info;
}
static void
@@ -137,11 +65,11 @@ gsk_vulkan_border_pipeline_collect_vertex_data (GskVulkanBorderPipeline *pipelin
gsk_rounded_rect_to_float (rect, offset, instance->rect);
for (i = 0; i < 4; i++)
{
instance->widths[i] = widths[i];
instance->colors[4 * i + 0] = colors[i].red;
instance->colors[4 * i + 1] = colors[i].green;
instance->colors[4 * i + 2] = colors[i].blue;
instance->colors[4 * i + 3] = colors[i].alpha;
instance->border_widths[i] = widths[i];
instance->border_colors[4 * i + 0] = colors[i].red;
instance->border_colors[4 * i + 1] = colors[i].green;
instance->border_colors[4 * i + 2] = colors[i].blue;
instance->border_colors[4 * i + 3] = colors[i].alpha;
}
}

View File

@@ -2,6 +2,8 @@
#include "gskvulkanboxshadowpipelineprivate.h"
#include "vulkan/resources/inset-shadow.vert.h"
#include "gskroundedrectprivate.h"
struct _GskVulkanBoxShadowPipeline
@@ -9,82 +11,12 @@ struct _GskVulkanBoxShadowPipeline
GObject parent_instance;
};
typedef struct _GskVulkanBoxShadowInstance GskVulkanBoxShadowInstance;
struct _GskVulkanBoxShadowInstance
{
float outline[12];
float color[4];
float offset[2];
float spread;
float blur_radius;
};
G_DEFINE_TYPE (GskVulkanBoxShadowPipeline, gsk_vulkan_box_shadow_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_box_shadow_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanBoxShadowInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, outline),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, outline) + 4 * sizeof (float),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, outline) + 8 * sizeof (float),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, color),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, offset),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, spread),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanBoxShadowInstance, blur_radius),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_inset_shadow_info;
}
static void
@@ -130,7 +62,7 @@ gsk_vulkan_box_shadow_pipeline_collect_vertex_data (GskVulkanBoxShadowPipeline *
float spread,
float blur_radius)
{
GskVulkanBoxShadowInstance *instance = (GskVulkanBoxShadowInstance *) data;
GskVulkanInsetShadowInstance *instance = (GskVulkanInsetShadowInstance *) data;
gsk_rounded_rect_to_float (outline, offset, instance->outline);
instance->color[0] = color->red;

View File

@@ -78,8 +78,8 @@ gsk_vulkan_buffer_new_map (GdkVulkanContext *context,
{
return gsk_vulkan_buffer_new_internal (context,
size,
(mode & GSK_VULKAN_READ ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0) |
(mode & GSK_VULKAN_WRITE ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0));
(mode & GSK_VULKAN_READ ? VK_BUFFER_USAGE_TRANSFER_DST_BIT : 0) |
(mode & GSK_VULKAN_WRITE ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT : 0));
}
void

View File

@@ -2,54 +2,19 @@
#include "gskvulkancolorpipelineprivate.h"
#include "vulkan/resources/color.vert.h"
struct _GskVulkanColorPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanColorInstance GskVulkanColorInstance;
struct _GskVulkanColorInstance
{
float rect[4];
float color[4];
};
G_DEFINE_TYPE (GskVulkanColorPipeline, gsk_vulkan_color_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_color_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanColorInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanColorInstance, color),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_color_info;
}
static void

View File

@@ -2,61 +2,19 @@
#include "gskvulkancolortextpipelineprivate.h"
#include "vulkan/resources/texture.vert.h"
struct _GskVulkanColorTextPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanColorTextInstance GskVulkanColorTextInstance;
struct _GskVulkanColorTextInstance
{
float rect[4];
float tex_rect[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanColorTextPipeline, gsk_vulkan_color_text_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_color_text_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanColorTextInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanColorTextInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_texture_info;
}
static void
@@ -105,7 +63,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
guint num_glyphs,
float scale)
{
GskVulkanColorTextInstance *instances = (GskVulkanColorTextInstance *) data;
GskVulkanTextureInstance *instances = (GskVulkanTextureInstance *) data;
int i;
int count = 0;
int x_position = 0;
@@ -121,7 +79,7 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanTextureInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,

View File

@@ -2,96 +2,19 @@
#include "gskvulkancrossfadepipelineprivate.h"
#include "vulkan/resources/cross-fade.vert.h"
struct _GskVulkanCrossFadePipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanCrossFadeInstance GskVulkanCrossFadeInstance;
struct _GskVulkanCrossFadeInstance
{
float rect[4];
float start_rect[4];
float end_rect[4];
float start_tex_rect[4];
float end_tex_rect[4];
guint32 start_tex_id[2];
guint32 end_tex_id[2];
float progress;
};
G_DEFINE_TYPE (GskVulkanCrossFadePipeline, gsk_vulkan_cross_fade_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_cross_fade_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanCrossFadeInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_rect),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_tex_rect),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_tex_rect),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, start_tex_id),
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, end_tex_id),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanCrossFadeInstance, progress),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_cross_fade_info;
}
static void

View File

@@ -2,93 +2,19 @@
#include "gskvulkaneffectpipelineprivate.h"
#include "vulkan/resources/color-matrix.vert.h"
struct _GskVulkanEffectPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanEffectInstance GskVulkanEffectInstance;
struct _GskVulkanEffectInstance
{
float rect[4];
float tex_rect[4];
float color_matrix[16];
float color_offset[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanEffectPipeline, gsk_vulkan_effect_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_effect_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanEffectInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 4,
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 8,
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_matrix) + sizeof (float) * 12,
},
{
.location = 6,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, color_offset),
},
{
.location = 7,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanEffectInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_color_matrix_info;
}
static void
@@ -133,7 +59,7 @@ gsk_vulkan_effect_pipeline_collect_vertex_data (GskVulkanEffectPipeline *pipelin
const graphene_matrix_t *color_matrix,
const graphene_vec4_t *color_offset)
{
GskVulkanEffectInstance *instance = (GskVulkanEffectInstance *) data;
GskVulkanColorMatrixInstance *instance = (GskVulkanColorMatrixInstance *) data;
instance->rect[0] = rect->origin.x + offset->x;
instance->rect[1] = rect->origin.y + offset->y;

View File

@@ -488,24 +488,6 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
}
}
GdkMemoryFormat
gsk_render_node_get_preferred_vulkan_format (GskRenderNode *node)
{
switch (gsk_render_node_get_preferred_depth (node))
{
case GDK_MEMORY_U8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_U16:
return GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
case GDK_MEMORY_FLOAT16:
return GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
case GDK_MEMORY_FLOAT32:
return GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
default:
g_return_val_if_reached (GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
}
}
static gboolean
gsk_vulkan_context_supports_format (GdkVulkanContext *context,
VkFormat format)

View File

@@ -1,7 +1,6 @@
#pragma once
#include <gdk/gdk.h>
#include <gsk/gskrendernode.h>
#include "gskvulkanbufferprivate.h"
#include "gskvulkancommandpoolprivate.h"
@@ -22,8 +21,6 @@ void gsk_vulkan_uploader_free (GskVulk
void gsk_vulkan_uploader_reset (GskVulkanUploader *self);
void gsk_vulkan_uploader_upload (GskVulkanUploader *self);
GdkMemoryFormat gsk_render_node_get_preferred_vulkan_format (GskRenderNode *node);
GskVulkanImage * gsk_vulkan_image_new_for_swapchain (GdkVulkanContext *context,
VkImage image,
VkFormat format,

View File

@@ -2,82 +2,19 @@
#include "gskvulkanlineargradientpipelineprivate.h"
#include "vulkan/resources/linear.vert.h"
struct _GskVulkanLinearGradientPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanLinearGradientInstance GskVulkanLinearGradientInstance;
struct _GskVulkanLinearGradientInstance
{
float rect[4];
float start[2];
float end[2];
gint32 repeating;
gint32 offset;
gint32 stop_count;
};
G_DEFINE_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanLinearGradientInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = 0,
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, start),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, end),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, repeating),
},
{
.location = 4,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offset),
},
{
.location = 5,
.binding = 0,
.format = VK_FORMAT_R32_SINT,
.offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_linear_info;
}
static void
@@ -123,7 +60,7 @@ gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradient
gsize gradient_offset,
gsize n_stops)
{
GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
GskVulkanLinearInstance *instance = (GskVulkanLinearInstance *) data;
instance->rect[0] = rect->origin.x + offset->x;
instance->rect[1] = rect->origin.y + offset->y;
@@ -134,7 +71,7 @@ gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradient
instance->end[0] = end->x + offset->x;
instance->end[1] = end->y + offset->y;
instance->repeating = repeating;
instance->offset = gradient_offset;
instance->stop_offset = gradient_offset;
instance->stop_count = n_stops;
}

View File

@@ -5,6 +5,8 @@
#include "gskvulkanpushconstantsprivate.h"
#include "gskvulkanshaderprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#include <graphene.h>
typedef struct _GskVulkanPipelinePrivate GskVulkanPipelinePrivate;
@@ -87,7 +89,7 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
priv->vertex_stride = vertex_input_state->pVertexBindingDescriptions[0].stride;
GSK_VK_CHECK (vkCreateGraphicsPipelines, device,
VK_NULL_HANDLE,
gdk_vulkan_context_get_pipeline_cache (context),
1,
&(VkGraphicsPipelineCreateInfo) {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
@@ -160,6 +162,8 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
NULL,
&priv->pipeline);
gdk_vulkan_context_pipeline_cache_updated (context);
return self;
}

View File

@@ -41,6 +41,8 @@
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
#define N_DESCRIPTOR_SETS 3
struct _GskVulkanRender
{
GskRenderer *renderer;
@@ -52,7 +54,7 @@ struct _GskVulkanRender
GskVulkanCommandPool *command_pool;
VkFence fence;
VkDescriptorSetLayout descriptor_set_layout;
VkDescriptorSetLayout descriptor_set_layouts[N_DESCRIPTOR_SETS];
VkPipelineLayout pipeline_layout;
GskVulkanUploader *uploader;
@@ -60,7 +62,7 @@ struct _GskVulkanRender
GskDescriptorImageInfos descriptor_samplers;
GskDescriptorBufferInfos descriptor_buffers;
VkDescriptorPool descriptor_pool;
VkDescriptorSet descriptor_set;
VkDescriptorSet descriptor_sets[N_DESCRIPTOR_SETS];
GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES];
GskVulkanImage *target;
@@ -148,9 +150,9 @@ gsk_vulkan_render_new (GskRenderer *renderer,
&(VkDescriptorPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
.maxSets = 1,
.poolSizeCount = 3,
.pPoolSizes = (VkDescriptorPoolSize[3]) {
.maxSets = N_DESCRIPTOR_SETS,
.poolSizeCount = N_DESCRIPTOR_SETS,
.pPoolSizes = (VkDescriptorPoolSize[N_DESCRIPTOR_SETS]) {
{
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS
@@ -171,7 +173,7 @@ gsk_vulkan_render_new (GskRenderer *renderer,
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
&(VkDescriptorSetLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 3,
.bindingCount = 1,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pBindings = (VkDescriptorSetLayoutBinding[3]) {
{
@@ -179,30 +181,12 @@ gsk_vulkan_render_new (GskRenderer *renderer,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
{
.binding = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
{
.binding = 2,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
}
},
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = 3,
.pBindingFlags = (VkDescriptorBindingFlags[3]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
.bindingCount = 1,
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
@@ -210,15 +194,65 @@ gsk_vulkan_render_new (GskRenderer *renderer,
}
},
NULL,
&self->descriptor_set_layout);
&self->descriptor_set_layouts[0]);
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
&(VkDescriptorSetLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pBindings = (VkDescriptorSetLayoutBinding[1]) {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
}
},
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = 1,
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
},
}
},
NULL,
&self->descriptor_set_layouts[1]);
GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
&(VkDescriptorSetLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = 1,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pBindings = (VkDescriptorSetLayoutBinding[1]) {
{
.binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = DESCRIPTOR_POOL_MAXITEMS,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
},
},
.pNext = &(VkDescriptorSetLayoutBindingFlagsCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = 1,
.pBindingFlags = (VkDescriptorBindingFlags[1]) {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT
| VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT
| VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
},
}
},
NULL,
&self->descriptor_set_layouts[2]);
GSK_VK_CHECK (vkCreatePipelineLayout, device,
&(VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = 1,
.pSetLayouts = (VkDescriptorSetLayout[1]) {
self->descriptor_set_layout
},
.setLayoutCount = G_N_ELEMENTS (self->descriptor_set_layouts),
.pSetLayouts = self->descriptor_set_layouts,
.pushConstantRangeCount = gsk_vulkan_push_constants_get_range_count (),
.pPushConstantRanges = gsk_vulkan_push_constants_get_ranges ()
},
@@ -384,12 +418,12 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
{ "texture", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip", 1, gsk_vulkan_color_text_pipeline_new },
{ "texture-clip-rounded", 1, gsk_vulkan_color_text_pipeline_new },
{ "crossfade", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "crossfade-clip", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "crossfade-clip-rounded", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "blendmode", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blendmode-clip", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blendmode-clip-rounded", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "cross-fade", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "cross-fade-clip", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "cross-fade-clip-rounded", 2, gsk_vulkan_cross_fade_pipeline_new },
{ "blend-mode", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blend-mode-clip", 2, gsk_vulkan_blend_mode_pipeline_new },
{ "blend-mode-clip-rounded", 2, gsk_vulkan_blend_mode_pipeline_new },
};
g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
@@ -403,10 +437,18 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
return self->pipelines[type];
}
VkDescriptorSet
gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self)
void
gsk_vulkan_render_bind_descriptor_sets (GskVulkanRender *self,
VkCommandBuffer command_buffer)
{
return self->descriptor_set;
vkCmdBindDescriptorSets (command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
self->pipeline_layout,
0,
3,
self->descriptor_sets,
0,
NULL);
}
gsize
@@ -537,11 +579,6 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
gsk_vulkan_render_pass_reserve_descriptor_sets (pass, self);
}
if (gsk_descriptor_image_infos_get_size (&self->descriptor_samplers) == 0 &&
gsk_descriptor_image_infos_get_size (&self->descriptor_images) == 0 &&
gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers) == 0)
return;
if (self->storage_buffer_memory)
{
gsk_vulkan_buffer_unmap (self->storage_buffer);
@@ -553,26 +590,26 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
&(VkDescriptorSetAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = self->descriptor_pool,
.descriptorSetCount = 1,
.pSetLayouts = &self->descriptor_set_layout,
.descriptorSetCount = N_DESCRIPTOR_SETS,
.pSetLayouts = self->descriptor_set_layouts,
.pNext = &(VkDescriptorSetVariableDescriptorCountAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.descriptorSetCount = 1,
.pDescriptorCounts = (uint32_t[1]) {
gsk_descriptor_image_infos_get_size (&self->descriptor_images)
+ gsk_descriptor_image_infos_get_size (&self->descriptor_samplers)
+ gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers)
.descriptorSetCount = N_DESCRIPTOR_SETS,
.pDescriptorCounts = (uint32_t[N_DESCRIPTOR_SETS]) {
MAX (1, gsk_descriptor_image_infos_get_size (&self->descriptor_images)),
MAX (1, gsk_descriptor_image_infos_get_size (&self->descriptor_samplers)),
MAX (1, gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers))
}
}
},
&self->descriptor_set);
self->descriptor_sets);
n_descriptor_sets = 0;
if (gsk_descriptor_image_infos_get_size (&self->descriptor_images) > 0)
{
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = self->descriptor_set,
.dstSet = self->descriptor_sets[0],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_images),
@@ -584,8 +621,8 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
{
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = self->descriptor_set,
.dstBinding = 1,
.dstSet = self->descriptor_sets[1],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = gsk_descriptor_image_infos_get_size (&self->descriptor_samplers),
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
@@ -596,8 +633,8 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self)
{
descriptor_sets[n_descriptor_sets++] = (VkWriteDescriptorSet) {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = self->descriptor_set,
.dstBinding = 2,
.dstSet = self->descriptor_sets[2],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorCount = gsk_descriptor_buffer_infos_get_size (&self->descriptor_buffers),
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
@@ -741,9 +778,10 @@ gsk_vulkan_render_free (GskVulkanRender *self)
gsk_descriptor_image_infos_clear (&self->descriptor_samplers);
gsk_descriptor_buffer_infos_clear (&self->descriptor_buffers);
vkDestroyDescriptorSetLayout (device,
self->descriptor_set_layout,
NULL);
for (i = 0; i < N_DESCRIPTOR_SETS; i++)
vkDestroyDescriptorSetLayout (device,
self->descriptor_set_layouts[i],
NULL);
vkDestroyFence (device,
self->fence,

View File

@@ -14,8 +14,9 @@
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkdrawcontextprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkprofilerprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#include <graphene.h>
@@ -286,7 +287,8 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
ceil (viewport->size.width),
ceil (viewport->size.height));
image = gsk_vulkan_image_new_for_offscreen (self->vulkan,
gsk_render_node_get_preferred_vulkan_format (root),
gdk_vulkan_context_get_offscreen_format (self->vulkan,
gsk_render_node_get_preferred_depth (root)),
rounded_viewport.size.width,
rounded_viewport.size.height);

View File

@@ -26,6 +26,8 @@
#include "gskvulkanrendererprivate.h"
#include "gskprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
@@ -1275,7 +1277,8 @@ gsk_vulkan_render_pass_render_offscreen (GdkVulkanContext *vulkan,
ceil (scale_y * viewport->size.height));
result = gsk_vulkan_image_new_for_offscreen (vulkan,
gsk_render_node_get_preferred_vulkan_format (node),
gdk_vulkan_context_get_offscreen_format (vulkan,
gsk_render_node_get_preferred_depth (node)),
view.size.width, view.size.height);
#ifdef G_ENABLE_DEBUG
@@ -2436,7 +2439,6 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
VkPipelineLayout pipeline_layout,
VkCommandBuffer command_buffer)
{
VkDescriptorSet descriptor_set;
cairo_rectangle_int_t rect;
vkCmdSetViewport (command_buffer,
@@ -2469,16 +2471,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
},
VK_SUBPASS_CONTENTS_INLINE);
descriptor_set = gsk_vulkan_render_get_descriptor_set (render);
if (descriptor_set)
vkCmdBindDescriptorSets (command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout,
0,
1,
&descriptor_set,
0,
NULL);
gsk_vulkan_render_bind_descriptor_sets (render, command_buffer);
gsk_vulkan_render_pass_draw_rect (self, render, pipeline_layout, command_buffer);

View File

@@ -93,7 +93,8 @@ guchar * gsk_vulkan_render_get_buffer_memory (GskVulk
gsize size,
gsize alignment,
gsize *out_offset);
VkDescriptorSet gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self);
void gsk_vulkan_render_bind_descriptor_sets (GskVulkanRender *self,
VkCommandBuffer command_buffer);
void gsk_vulkan_render_draw (GskVulkanRender *self);

View File

@@ -2,68 +2,19 @@
#include "gskvulkantextpipelineprivate.h"
#include "vulkan/resources/mask.vert.h"
struct _GskVulkanTextPipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanTextInstance GskVulkanTextInstance;
struct _GskVulkanTextInstance
{
float rect[4];
float tex_rect[4];
float color[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanTextPipeline, gsk_vulkan_text_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_text_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanTextInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, color),
},
{
.location = 3,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanTextInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_mask_info;
}
static void
@@ -113,7 +64,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
guint num_glyphs,
float scale)
{
GskVulkanTextInstance *instances = (GskVulkanTextInstance *) data;
GskVulkanMaskInstance *instances = (GskVulkanMaskInstance *) data;
int i;
int count = 0;
int x_position = 0;
@@ -129,7 +80,7 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline,
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
GskVulkanTextInstance *instance = &instances[count];
GskVulkanMaskInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;
glyph = gsk_vulkan_renderer_get_cached_glyph (renderer,

View File

@@ -2,61 +2,19 @@
#include "gskvulkantexturepipelineprivate.h"
#include "vulkan/resources/texture.vert.h"
struct _GskVulkanTexturePipeline
{
GObject parent_instance;
};
typedef struct _GskVulkanTextureInstance GskVulkanTextureInstance;
struct _GskVulkanTextureInstance
{
float rect[4];
float tex_rect[4];
guint32 tex_id[2];
};
G_DEFINE_TYPE (GskVulkanTexturePipeline, gsk_vulkan_texture_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static const VkPipelineVertexInputStateCreateInfo *
gsk_vulkan_texture_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
{
static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
{
.binding = 0,
.stride = sizeof (GskVulkanTextureInstance),
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
}
};
static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
{
.location = 0,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, rect),
},
{
.location = 1,
.binding = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, tex_rect),
},
{
.location = 2,
.binding = 0,
.format = VK_FORMAT_R32G32_UINT,
.offset = G_STRUCT_OFFSET (GskVulkanTextureInstance, tex_id),
}
};
static const VkPipelineVertexInputStateCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
.pVertexBindingDescriptions = vertexBindingDescriptions,
.vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
.pVertexAttributeDescriptions = vertexInputAttributeDescription
};
return &info;
return &gsk_vulkan_texture_info;
}
static void

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -3,9 +3,7 @@
#include "clip.vert.glsl"
#include "rounded-rect.glsl"
layout(location = 0) in vec4 inRect;
layout(location = 1) in vec4 inCornerWidths;
layout(location = 2) in vec4 inCornerHeights;
layout(location = 0) in mat3x4 inRect;
layout(location = 3) in vec4 inBorderWidths;
layout(location = 4) in mat4 inBorderColors;
@@ -44,47 +42,47 @@ void main() {
int slice_index = gl_VertexIndex / 6;
int vert_index = gl_VertexIndex % 6;
vec4 corner_widths = max (inCornerWidths, inBorderWidths.wyyw);
vec4 corner_heights = max (inCornerHeights, inBorderWidths.xxzz);
vec4 corner_widths = max (inRect[1], inBorderWidths.wyyw);
vec4 corner_heights = max (inRect[2], inBorderWidths.xxzz);
Rect rect;
switch (slice_index)
{
case SLICE_TOP_LEFT:
rect = rect_from_gsk (vec4(inRect.xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
rect = rect_from_gsk (vec4(inRect[0].xy, corner_widths[TOP_LEFT], corner_heights[TOP_LEFT]));
rect = rect_round_larger (rect);
vert_index = (vert_index + 3) % 6;
break;
case SLICE_TOP:
rect = rect_from_gsk (vec4(inRect.x + corner_widths[TOP_LEFT], inRect.y, inRect.z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]));
rect = rect_from_gsk (vec4(inRect[0].x + corner_widths[TOP_LEFT], inRect[0].y, inRect[0].z - corner_widths[TOP_LEFT] - corner_widths[TOP_RIGHT], inBorderWidths[TOP]));
rect = rect_round_smaller_larger (rect);
outColor = inBorderColors[TOP];
break;
case SLICE_TOP_RIGHT:
rect = rect_from_gsk (vec4(inRect.x + inRect.z - corner_widths[TOP_RIGHT], inRect.y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]));
rect = rect_from_gsk (vec4(inRect[0].x + inRect[0].z - corner_widths[TOP_RIGHT], inRect[0].y, corner_widths[TOP_RIGHT], corner_heights[TOP_RIGHT]));
rect = rect_round_larger (rect);
break;
case SLICE_RIGHT:
rect = rect_from_gsk (vec4(inRect.x + inRect.z - inBorderWidths[RIGHT], inRect.y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect.w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]));
rect = rect_from_gsk (vec4(inRect[0].x + inRect[0].z - inBorderWidths[RIGHT], inRect[0].y + corner_heights[TOP_RIGHT], inBorderWidths[RIGHT], inRect[0].w - corner_heights[TOP_RIGHT] - corner_heights[BOTTOM_RIGHT]));
rect = rect_round_larger_smaller (rect);
outColor = inBorderColors[RIGHT];
break;
case SLICE_BOTTOM_RIGHT:
rect = rect_from_gsk (vec4(inRect.x + inRect.z - corner_widths[BOTTOM_RIGHT], inRect.y + inRect.w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]));
rect = rect_from_gsk (vec4(inRect[0].x + inRect[0].z - corner_widths[BOTTOM_RIGHT], inRect[0].y + inRect[0].w - corner_heights[BOTTOM_RIGHT], corner_widths[BOTTOM_RIGHT], corner_heights[BOTTOM_RIGHT]));
rect = rect_round_larger (rect);
break;
case SLICE_BOTTOM:
rect = rect_from_gsk (vec4(inRect.x + corner_widths[BOTTOM_LEFT], inRect.y + inRect.w - inBorderWidths[BOTTOM], inRect.z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]));
rect = rect_from_gsk (vec4(inRect[0].x + corner_widths[BOTTOM_LEFT], inRect[0].y + inRect[0].w - inBorderWidths[BOTTOM], inRect[0].z - corner_widths[BOTTOM_LEFT] - corner_widths[BOTTOM_RIGHT], inBorderWidths[BOTTOM]));
rect = rect_round_smaller_larger (rect);
break;
case SLICE_BOTTOM_LEFT:
rect = rect_from_gsk (vec4(inRect.x, inRect.y + inRect.w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]));
rect = rect_from_gsk (vec4(inRect[0].x, inRect[0].y + inRect[0].w - corner_heights[BOTTOM_LEFT], corner_widths[BOTTOM_LEFT], corner_heights[BOTTOM_LEFT]));
vert_index = (vert_index + 3) % 6;
rect = rect_round_larger (rect);
break;
case SLICE_LEFT:
rect = rect_from_gsk (vec4(inRect.x, inRect.y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect.w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]));
rect = rect_from_gsk (vec4(inRect[0].x, inRect[0].y + corner_heights[TOP_LEFT], inBorderWidths[LEFT], inRect[0].w - corner_heights[TOP_LEFT] - corner_heights[BOTTOM_LEFT]));
rect = rect_round_larger_smaller (rect);
break;
}
@@ -99,7 +97,7 @@ void main() {
gl_Position = push.mvp * vec4 (pos, 0.0, 1.0);
outColor = inBorderColors[((gl_VertexIndex / 3 + 15) / 4) % 4];
outPos = pos;
outRect = RoundedRect(inRect.xyxy + vec4(0,0,inRect.zw), inCornerWidths, inCornerHeights);
outRect = RoundedRect(inRect[0].xyxy + vec4(0,0,inRect[0].zw), inRect[1], inRect[2]);
outRect = rounded_rect_scale (outRect, push.scale);
outBorderWidths = inBorderWidths * push.scale.yxyx;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,6 @@
layout(set = 0, binding = 0) uniform texture2D textures[50000];
layout(set = 0, binding = 1) uniform sampler samplers[50000];
layout(set = 0, binding = 2) readonly buffer FloatBuffers {
layout(set = 1, binding = 0) uniform sampler samplers[50000];
layout(set = 2, binding = 0) readonly buffer FloatBuffers {
float floats[];
} buffers[50000];

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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