Compare commits
571 Commits
curve-inte
...
wip/antoni
Author | SHA1 | Date | |
---|---|---|---|
|
d7922c189f | ||
|
b782f80311 | ||
|
d2d2fb4b50 | ||
|
ff9c9e05c3 | ||
|
e3f39bf0c3 | ||
|
d692243727 | ||
|
6ad9db0bf0 | ||
|
486157f6bf | ||
|
5ca4ab3aaa | ||
|
a37b3fb691 | ||
|
c414889cfa | ||
|
4dfc07ef57 | ||
|
cf4b0a27f8 | ||
|
393ee574b6 | ||
|
e3c85be53f | ||
|
0f5fda2277 | ||
|
0889037959 | ||
|
ee56ad792c | ||
|
5688b7b4bb | ||
|
df1802f756 | ||
|
84de90756d | ||
|
cb5a8a76da | ||
|
26c35c00e1 | ||
|
5d4879aae7 | ||
|
39b08b82ca | ||
|
2b6e7147d6 | ||
|
3a1349e8ef | ||
|
5485d806c5 | ||
|
6e7c499408 | ||
|
c341da32aa | ||
|
d39ec8c09e | ||
|
e3299e38df | ||
|
8fd02f6fa2 | ||
|
9bc0ad9a13 | ||
|
19171c7a89 | ||
|
abf942efe5 | ||
|
dfe7afdb04 | ||
|
1629b072fe | ||
|
0b0a5a52af | ||
|
75d259eedf | ||
|
6fec018cbd | ||
|
6d9c950b82 | ||
|
0933ea63c5 | ||
|
8cb594696e | ||
|
9d7389aea7 | ||
|
76a1f1714d | ||
|
9af08e17e0 | ||
|
276afbca92 | ||
|
0342d23dbe | ||
|
1c10837b21 | ||
|
7cc5d5c7a5 | ||
|
6a59326dbf | ||
|
1968f331d9 | ||
|
bf35836350 | ||
|
036629a491 | ||
|
8cabf59cf3 | ||
|
6a4b238641 | ||
|
d4d0239ae7 | ||
|
a30f32db8d | ||
|
6948a74d72 | ||
|
14ec255812 | ||
|
00ebd51d06 | ||
|
7de528b487 | ||
|
77f40d7508 | ||
|
b969f4649d | ||
|
f4f25e584c | ||
|
b049a3501a | ||
|
0114fad8a5 | ||
|
afafac6878 | ||
|
108eb43b01 | ||
|
6961c1fe4a | ||
|
606d150e0b | ||
|
96f7bb99a7 | ||
|
b937c17985 | ||
|
79cb370f81 | ||
|
154b73723f | ||
|
c0efed4e4a | ||
|
4402676aa2 | ||
|
9bf4a45d47 | ||
|
85ce343816 | ||
|
114d0621aa | ||
|
d595aff52d | ||
|
d72fd951e1 | ||
|
78706e3fbe | ||
|
98b796a371 | ||
|
c99f62aef1 | ||
|
8754247a90 | ||
|
fd12707162 | ||
|
34bca0ff56 | ||
|
c668519d07 | ||
|
454e6eadc6 | ||
|
e248a01fbd | ||
|
e2bd7defa4 | ||
|
855fa6d523 | ||
|
7c620ac2b7 | ||
|
d96f2f54e9 | ||
|
71c2ee3530 | ||
|
5e415ee916 | ||
|
e163021b8f | ||
|
1bf88f1d81 | ||
|
72d2b8e546 | ||
|
37f7f3d60c | ||
|
8d1443994b | ||
|
39db73dff1 | ||
|
68cf5f2cf3 | ||
|
77c4097c86 | ||
|
d7bc4c719b | ||
|
725857e15b | ||
|
50ee872978 | ||
|
b6c82c6b54 | ||
|
1bf94b045c | ||
|
13bfe188b5 | ||
|
f21175b3d0 | ||
|
d78475372f | ||
|
988b9de210 | ||
|
0c19ef6c2c | ||
|
2bfd4a88d6 | ||
|
de3eeb4970 | ||
|
5c2e2977e0 | ||
|
24f3ec0949 | ||
|
bcab0e4254 | ||
|
253955c017 | ||
|
3a8834a437 | ||
|
48ea2ecac3 | ||
|
6d0b31128b | ||
|
0b519bc353 | ||
|
bb756b35a2 | ||
|
7ba7ab1e3d | ||
|
f73a7e29ca | ||
|
2eb6e3d4c5 | ||
|
b28cf76f11 | ||
|
36314f28e2 | ||
|
b7a1b1d7ee | ||
|
57e382b59c | ||
|
a35a885902 | ||
|
5fa3a2a39f | ||
|
7f53b3d3f4 | ||
|
9b25257cbf | ||
|
a90a6c4517 | ||
|
e69f062c99 | ||
|
210c7f25ad | ||
|
9695791f7b | ||
|
ca0da0dd83 | ||
|
5a8a839921 | ||
|
eb84171cda | ||
|
5608a8978e | ||
|
efefdbd5c0 | ||
|
6bea059424 | ||
|
c99c06f0da | ||
|
bda8f5393d | ||
|
160fa969d4 | ||
|
edf33a6617 | ||
|
86587a9328 | ||
|
8691d471d0 | ||
|
463b6dd1fd | ||
|
88e1f77f90 | ||
|
1ee488f445 | ||
|
eae0e15b9d | ||
|
00d551bda8 | ||
|
2dcec44714 | ||
|
f04c819439 | ||
|
c679ba9ebf | ||
|
9aadc2b860 | ||
|
e4370cc95e | ||
|
22ceb018fb | ||
|
833d307695 | ||
|
e8afb5e210 | ||
|
b916c4dac1 | ||
|
699c6d6159 | ||
|
025b846fce | ||
|
fcdbab3f69 | ||
|
d7eac7a6ad | ||
|
52dbb3f372 | ||
|
7dc38ca12f | ||
|
e858924d03 | ||
|
852aab1576 | ||
|
5eb42815ed | ||
|
0b853f62ed | ||
|
fb969f5431 | ||
|
ef6ed31853 | ||
|
c57245b73c | ||
|
f9fd78b67e | ||
|
00a63a9fcf | ||
|
b4ae2377b3 | ||
|
392977d670 | ||
|
5a29e2704c | ||
|
ec6c52680e | ||
|
d850161b2f | ||
|
1a3504469d | ||
|
be0546bb39 | ||
|
d4a569057f | ||
|
c5727df568 | ||
|
7406cea257 | ||
|
de3f55fc5f | ||
|
010ff81b2f | ||
|
c94ec8b658 | ||
|
9c1ae5374d | ||
|
4a018de0a1 | ||
|
23e50bb21d | ||
|
a8e3e747df | ||
|
7fd90853f8 | ||
|
01aa4989f8 | ||
|
d4fee23ff6 | ||
|
b878949f00 | ||
|
3a88522a19 | ||
|
358cd28d09 | ||
|
6eb6b0cb50 | ||
|
c81954120a | ||
|
4bdc44f4af | ||
|
3ab7b2d7ce | ||
|
429056c214 | ||
|
acecf519bc | ||
|
b2fbdcda41 | ||
|
1b08fda93e | ||
|
f6b6176ec0 | ||
|
2803189afd | ||
|
ad08c1444a | ||
|
ef77a6fa73 | ||
|
667f02ecd8 | ||
|
160f632668 | ||
|
653bf46494 | ||
|
46d4c70cd7 | ||
|
4920ac4a57 | ||
|
5bdc9f71fd | ||
|
c92761b184 | ||
|
9185f15cd9 | ||
|
efec30babb | ||
|
190e7da317 | ||
|
28d38cd730 | ||
|
d7a72493ae | ||
|
7299c9baa9 | ||
|
540a83327f | ||
|
04d41eaa66 | ||
|
524d681496 | ||
|
44d977844b | ||
|
6259800f5a | ||
|
d3a5aa5304 | ||
|
d32ab7544d | ||
|
e2e7c931c5 | ||
|
e202348380 | ||
|
ba5403da17 | ||
|
904d44074f | ||
|
c636baf6f5 | ||
|
b7c2528ad1 | ||
|
48740de71a | ||
|
34c16b0df2 | ||
|
d0a675ab01 | ||
|
0e0bf8ed47 | ||
|
00d7d4b17b | ||
|
9eef566b54 | ||
|
272168c94b | ||
|
ca054bfdc9 | ||
|
59dbfb0843 | ||
|
223e27e7dc | ||
|
efe1415429 | ||
|
489723916d | ||
|
e8894ad383 | ||
|
9423d6261a | ||
|
b766f92026 | ||
|
a37aacf4e4 | ||
|
93959ef7df | ||
|
209a1a69cc | ||
|
982f965ea8 | ||
|
f7fc90daa0 | ||
|
a58424588f | ||
|
f8c9b3394b | ||
|
ce4d8cc6d9 | ||
|
c85766ac71 | ||
|
b24ae31716 | ||
|
7cf805c8b3 | ||
|
1f62c693cd | ||
|
6ae9cbfe0f | ||
|
7803aad872 | ||
|
cc2d3fa7d6 | ||
|
a9e4993184 | ||
|
33703bfe01 | ||
|
7ba5cf5309 | ||
|
bb890f6004 | ||
|
1c7a0e7a15 | ||
|
cd7e1c1387 | ||
|
a2e1e727c5 | ||
|
61207f81c3 | ||
|
f624586a75 | ||
|
1a93967e1f | ||
|
310ab7b531 | ||
|
d55801c8ba | ||
|
b1809bfd88 | ||
|
deb8a35ea0 | ||
|
c5ce24c82c | ||
|
54815e4771 | ||
|
5a99790a87 | ||
|
8aa7174bfb | ||
|
9df5e3cbd6 | ||
|
8b5194c016 | ||
|
9a63172cf5 | ||
|
3ade9ae184 | ||
|
76349ff6e5 | ||
|
dd530b45e2 | ||
|
00ce51472c | ||
|
b6bcbeae23 | ||
|
cf86cc1184 | ||
|
b503b60a49 | ||
|
5850055b68 | ||
|
b224e66a9f | ||
|
bbb0150383 | ||
|
8aef682079 | ||
|
fe4b7a5159 | ||
|
7ba4ba05e1 | ||
|
85e1088171 | ||
|
c1ed034367 | ||
|
cc3e25b163 | ||
|
bdb3e345c8 | ||
|
a30e9dcfeb | ||
|
76007c4d09 | ||
|
020ef51cb0 | ||
|
1914adc344 | ||
|
6e236b9459 | ||
|
11715760f9 | ||
|
f19c08ffda | ||
|
d0f76b6ab4 | ||
|
4c7206343a | ||
|
dfae2cb3a5 | ||
|
de74d38039 | ||
|
fb20542fcc | ||
|
a26e289d5c | ||
|
892d3b9530 | ||
|
8477dcfeff | ||
|
25835afd9c | ||
|
06dda4e12b | ||
|
26edfe6d18 | ||
|
4a749aee6e | ||
|
99a8417142 | ||
|
20e2075a10 | ||
|
d8c649b57f | ||
|
bb2b8bf2c3 | ||
|
eb048c91be | ||
|
358779dfb2 | ||
|
8f90ddb906 | ||
|
ed54aa8acf | ||
|
a90ffb117f | ||
|
29681717ed | ||
|
e0cd2b756f | ||
|
2c85060b5f | ||
|
864c5b4608 | ||
|
1ab501649e | ||
|
2d874e601c | ||
|
c9b83dfa1d | ||
|
dd7a38069f | ||
|
51a181af7a | ||
|
8fcd9bc0c4 | ||
|
e2edf693f5 | ||
|
323300e92a | ||
|
e688be1cff | ||
|
611d5cf844 | ||
|
677e78bdce | ||
|
51cb1aeb4e | ||
|
625eb508e8 | ||
|
2718e1715d | ||
|
6ddcad6b33 | ||
|
0c23997f70 | ||
|
4d1ef63009 | ||
|
30e14f73fa | ||
|
39e205aa78 | ||
|
f0ec1660c1 | ||
|
79f98f3a13 | ||
|
5f0557027d | ||
|
a579e3bc6d | ||
|
8f70f4b85e | ||
|
911198cddd | ||
|
ca5247a995 | ||
|
004a881521 | ||
|
65993ed0e0 | ||
|
a4d0a5bda5 | ||
|
33bc276639 | ||
|
06822581f7 | ||
|
976143fbe9 | ||
|
9fd4feef0c | ||
|
5eed13bd07 | ||
|
d02d45dd8d | ||
|
13d0e311b7 | ||
|
52254f755f | ||
|
494154beb6 | ||
|
adde188eca | ||
|
8fb0ab2b43 | ||
|
b8b5835fc6 | ||
|
463307655c | ||
|
d17d8e04a6 | ||
|
d8d1dfd8f3 | ||
|
f581280811 | ||
|
3a9aea44df | ||
|
e05764806a | ||
|
5ca65f04fe | ||
|
32ba1e389c | ||
|
beb9e0c906 | ||
|
98f02f6221 | ||
|
13848969f4 | ||
|
0817dfe67f | ||
|
9e3f537a15 | ||
|
612e0e29f9 | ||
|
e1cbc96b8c | ||
|
410240fe7b | ||
|
73cf3a92f9 | ||
|
dd15122ccb | ||
|
5299f1384f | ||
|
58a0e4ffaa | ||
|
7ab9056c11 | ||
|
2d9fbb16bc | ||
|
cbfd8542c6 | ||
|
7679504134 | ||
|
446d461ad2 | ||
|
5b6fcfe8c9 | ||
|
59ce7ab222 | ||
|
0992837b08 | ||
|
aca02916ad | ||
|
98e883f9b4 | ||
|
2c66aa0c15 | ||
|
8843c0d504 | ||
|
8858f1c9ec | ||
|
a1c5c20e2c | ||
|
1da674423d | ||
|
10250a0a6a | ||
|
c0a2f9fbc3 | ||
|
bd974b08b3 | ||
|
d289c0d4f1 | ||
|
f4722289f7 | ||
|
389af3591c | ||
|
008d9e5327 | ||
|
09723d79c6 | ||
|
4586af5876 | ||
|
193d9cd31a | ||
|
f29303dea7 | ||
|
4e47d0d71e | ||
|
dd8c6e9f51 | ||
|
65676150c4 | ||
|
b0e26873f6 | ||
|
f4a67ebcbb | ||
|
000c876953 | ||
|
b8ffceaebb | ||
|
148b8e5cd8 | ||
|
583ad47b03 | ||
|
b95d8ebdd3 | ||
|
677a601d11 | ||
|
194db51fba | ||
|
d55fa0dfef | ||
|
612b5416af | ||
|
54637ae3b3 | ||
|
014adb841e | ||
|
a5c6a40b3c | ||
|
402a51b876 | ||
|
d1e091279c | ||
|
7325121c63 | ||
|
31abe56b7a | ||
|
ca3fd16039 | ||
|
4417509515 | ||
|
9dc2e554e5 | ||
|
bfb01f5a4b | ||
|
570e80a9ff | ||
|
6d90d25a74 | ||
|
a7f6e65291 | ||
|
59641b3c7b | ||
|
2f842b087c | ||
|
699f6a7993 | ||
|
f04ba3bc60 | ||
|
09aac114d4 | ||
|
9132600e1f | ||
|
5dcd6c7e12 | ||
|
9f8d34ab01 | ||
|
7a4580fa89 | ||
|
45a7617cc8 | ||
|
57d8cc08a3 | ||
|
1ca067a478 | ||
|
7a13e4f9b9 | ||
|
d101e17608 | ||
|
203a4fc45e | ||
|
a9823e05bb | ||
|
6f5833df28 | ||
|
5631ab6711 | ||
|
62fedf4eed | ||
|
c274d073e0 | ||
|
8dda753505 | ||
|
4e66df79c4 | ||
|
71c7e61162 | ||
|
e39ecbf16d | ||
|
0dbd2bd09e | ||
|
1297cc188d | ||
|
e584d17aad | ||
|
4936965fb6 | ||
|
e9cc53796e | ||
|
c93efe85dd | ||
|
44daa847ff | ||
|
d23e13aced | ||
|
40102a2b61 | ||
|
49fbbfb6cc | ||
|
fefd856d67 | ||
|
39dab6d7bd | ||
|
7b5b78b065 | ||
|
005b5042f6 | ||
|
b5149a483f | ||
|
15c43e5284 | ||
|
fc4c0f769c | ||
|
e8ecbb2009 | ||
|
964affb1cc | ||
|
05b51af2d5 | ||
|
28e51c763b | ||
|
ebf8e18319 | ||
|
d8bbe1c296 | ||
|
c1417d3d4a | ||
|
3b4359d76d | ||
|
16806294e3 | ||
|
822425072b | ||
|
7cc1283a26 | ||
|
f4198706d1 | ||
|
37a5ad3a53 | ||
|
8478ba66fe | ||
|
00e4dab1ef | ||
|
1d58de6ffb | ||
|
f5cec5c0f2 | ||
|
368f2af634 | ||
|
66a9fee071 | ||
|
6e0ac83d99 | ||
|
12ad6b3157 | ||
|
fda9fd5ced | ||
|
029ce83a69 | ||
|
5ced6be416 | ||
|
bbda833b01 | ||
|
c86bc00330 | ||
|
8367411785 | ||
|
17e37dc42a | ||
|
68755c0fd2 | ||
|
9090c28125 | ||
|
3a3244891e | ||
|
b55117334c | ||
|
02e5c7b9ad | ||
|
7268167f4c | ||
|
93c7502cf7 | ||
|
789705cfe4 | ||
|
741471a1f8 | ||
|
f8da751cc2 | ||
|
8174842d9f | ||
|
e872952f36 | ||
|
b010e46d13 | ||
|
eb646a8e8b | ||
|
1e2975147d | ||
|
653c10e8b6 | ||
|
dfbafdf047 | ||
|
d8c821a851 | ||
|
83376648d7 | ||
|
089c34fa03 | ||
|
c846f8d745 | ||
|
79ebd76ac8 | ||
|
6eb9836eb0 | ||
|
4a8f8a6eea | ||
|
3ea723730b | ||
|
90be2baf8b | ||
|
0b64fa88a1 | ||
|
c6cc446e63 | ||
|
0cad37760e | ||
|
e720008dca | ||
|
9c636a6136 | ||
|
1e24aa425e | ||
|
a8c597005a | ||
|
97a781b380 | ||
|
313cadefe6 | ||
|
9f078bd5c9 | ||
|
8ff4e27103 | ||
|
8389ca633d | ||
|
18fbec0fe1 | ||
|
eb0a00067d | ||
|
91216408e5 | ||
|
4c46f5a8f7 | ||
|
5c00dc7ef4 |
@@ -26,7 +26,7 @@ variables:
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v49"
|
||||
|
||||
workflow:
|
||||
rules:
|
||||
@@ -66,7 +66,8 @@ style-check-diff:
|
||||
junit:
|
||||
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gles2.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
@@ -103,8 +104,9 @@ fedora-x86_64:
|
||||
${FEATURE_FLAGS}
|
||||
_build
|
||||
- meson compile -C _build
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gles
|
||||
- .gitlab-ci/run-tests.sh _build x11 gtk
|
||||
# only repeat test runs that are likely affected by test setups
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gl gtk:gdk,gtk:gsk-gl
|
||||
|
||||
release-build:
|
||||
extends: .build-fedora-default
|
||||
@@ -129,7 +131,9 @@ release-build:
|
||||
- meson install -C _build
|
||||
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland gtk
|
||||
# only repeat test runs that are likely affected by test setups
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gles2 gtk:gdk,gtk:gsk-gl
|
||||
|
||||
fedora-clang:
|
||||
extends: .build-fedora-default
|
||||
@@ -217,25 +221,32 @@ macos-x86_64:
|
||||
MESON_FORCE_BACKTRACKE: 1
|
||||
TMPDIR: /Users/Shared/work/tmp
|
||||
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
|
||||
CCACHE_DIR: /Users/Shared/work/ccache
|
||||
PIP_CACHE_DIR: /Users/Shared/build/cache
|
||||
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
|
||||
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
|
||||
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
|
||||
before_script:
|
||||
# Not using ccache on purpose as it accelerates the build so much that it
|
||||
# can trigger race conditions in the gobject-introspection subproject.
|
||||
- bash .gitlab-ci/show-info-osx.sh
|
||||
- python3 -m venv .venv
|
||||
- /opt/macports/bin/python3.10 -m venv .venv
|
||||
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
|
||||
- ln -s /opt/ccache/ccache .venv/bin
|
||||
- ln -s /opt/pkg-config/bin/pkg-config .venv/bin
|
||||
- ln -s /opt/bison/bin/bison .venv/bin
|
||||
- source .venv/bin/activate
|
||||
- pip3 install meson==1.2.0
|
||||
- pip3 install ninja==1.11.1
|
||||
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
|
||||
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
|
||||
script:
|
||||
- meson setup ${COMMON_MESON_FLAGS}
|
||||
- meson setup
|
||||
${COMMON_MESON_FLAGS}
|
||||
${EXTRA_MESON_FLAGS}
|
||||
-Dx11-backend=false
|
||||
-Dbroadway-backend=true
|
||||
-Dmacos-backend=true
|
||||
-Dmedia-gstreamer=disabled
|
||||
-Dintrospection=disabled
|
||||
-Dintrospection=enabled
|
||||
-Dcpp_std=c++11
|
||||
-Dpixman:tests=disabled
|
||||
-Dlibjpeg-turbo:simd=disabled
|
||||
@@ -416,11 +427,12 @@ asan-build:
|
||||
-Df16c=disabled
|
||||
_build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build wayland_gles
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland gtk
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
junit:
|
||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
|
||||
|
BIN
.gitlab-ci/.fedora.Dockerfile.swp
Normal file
BIN
.gitlab-ci/.fedora.Dockerfile.swp
Normal file
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
FROM fedora:38
|
||||
FROM fedora:39
|
||||
|
||||
RUN dnf -y install \
|
||||
adwaita-icon-theme \
|
||||
|
@@ -324,7 +324,7 @@ for line in args.infile:
|
||||
units.append(unit)
|
||||
|
||||
report = {}
|
||||
report['date'] = datetime.datetime.utcnow()
|
||||
report['date'] = datetime.datetime.now(datetime.UTC)
|
||||
report['locale_date'] = report['date'].strftime("%c")
|
||||
report['project_name'] = args.project_name
|
||||
report['backend'] = args.backend
|
||||
|
@@ -44,7 +44,7 @@ outfile = args.output
|
||||
testsuites = ET.Element('testsuites')
|
||||
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
|
||||
testsuites.set('package', args.project_name)
|
||||
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
|
||||
testsuites.set('timestamp', datetime.datetime.now(datetime.UTC).isoformat(timespec='minutes'))
|
||||
|
||||
suites = {}
|
||||
for line in args.infile:
|
||||
|
@@ -1,27 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
set +x
|
||||
set -x
|
||||
set +e
|
||||
|
||||
srcdir=$( pwd )
|
||||
builddir=$1
|
||||
backend=$2
|
||||
setup=$2
|
||||
suite=$3
|
||||
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
|
||||
export G_SLICE=always-malloc
|
||||
|
||||
case "${backend}" in
|
||||
x11)
|
||||
case "${setup}" in
|
||||
x11*)
|
||||
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
|
||||
meson test -C ${builddir} \
|
||||
--quiet \
|
||||
--timeout-multiplier "${multiplier}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--setup=${setup} \
|
||||
--suite=${suite//,/ --suite=} \
|
||||
--no-suite=failing \
|
||||
--no-suite=${setup}_failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=headless \
|
||||
--no-suite=gsk-compare-broadway
|
||||
@@ -42,19 +44,19 @@ case "${backend}" in
|
||||
--quiet \
|
||||
--timeout-multiplier "${multiplier}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--setup=${setup} \
|
||||
--suite=${suite//,/ --suite=} \
|
||||
--no-suite=failing \
|
||||
--no-suite=${setup}_failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=headless \
|
||||
--no-suite=${backend}_failing \
|
||||
--no-suite=gsk-compare-broadway
|
||||
exit_code=$?
|
||||
|
||||
kill ${compositor}
|
||||
;;
|
||||
|
||||
broadway)
|
||||
broadway*)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
|
||||
@@ -65,9 +67,10 @@ case "${backend}" in
|
||||
--quiet \
|
||||
--timeout-multiplier "${multiplier}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--setup=${setup} \
|
||||
--suite=${suite//,/ --suite=} \
|
||||
--no-suite=failing \
|
||||
--no-suite=${setup}_failing \
|
||||
--no-suite=flaky \
|
||||
--no-suite=headless \
|
||||
--no-suite=gsk-compare-opengl
|
||||
@@ -76,7 +79,7 @@ case "${backend}" in
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Failed to add ${backend} to .gitlab-ci/run-tests.sh"
|
||||
echo "Failed to add ${setup} to .gitlab-ci/run-tests.sh"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -86,17 +89,17 @@ cd ${builddir}
|
||||
|
||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
||||
--project-name=gtk \
|
||||
--backend="${backend}" \
|
||||
--backend="${setup}" \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--output="report-${backend}.xml" \
|
||||
"meson-logs/testlog-${backend}.json"
|
||||
--output="report-${setup}.xml" \
|
||||
"meson-logs/testlog-${setup}.json"
|
||||
|
||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
||||
--project-name=gtk \
|
||||
--backend="${backend}" \
|
||||
--backend="${setup}" \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--reftest-output-dir="testsuite/reftests/output/${backend}" \
|
||||
--output="report-${backend}.html" \
|
||||
"meson-logs/testlog-${backend}.json"
|
||||
--reftest-output-dir="testsuite/reftests/output/${setup}" \
|
||||
--output="report-${setup}.html" \
|
||||
"meson-logs/testlog-${setup}.json"
|
||||
|
||||
exit $exit_code
|
||||
|
97
NEWS
97
NEWS
@@ -1,4 +1,71 @@
|
||||
Overview of Changes in 4.13.1, xx-xx-xxxx
|
||||
Overview of Changes in 4.13.4, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
Overview of Changes in 4.13.3, 15-11-2023
|
||||
=========================================
|
||||
|
||||
* GtkGraphicsOffload: A new widget to support passthrough
|
||||
of dmabuf textures with subsurfaces on Wayland
|
||||
|
||||
* GtkListView:
|
||||
- reduce tree indentation
|
||||
|
||||
* GtkInspector:
|
||||
- Show more GL information
|
||||
- Add a subsurface overlay
|
||||
- Improve the fps overlay
|
||||
|
||||
* GDK
|
||||
- Allow implicit modifiers for dmabufs
|
||||
- Support more dmabuf formats: NV16, NV61, NV24, NV42
|
||||
and 3-plane YUV formats
|
||||
|
||||
* GSK
|
||||
- Fix padding of icons in the GL atlas
|
||||
- Fix handling of texture-scale nodes in cairo
|
||||
- Treat texture-scale nodes more faithfully in GL
|
||||
|
||||
* Accessibility:
|
||||
- Tweak the accessible name computation for corner cases
|
||||
|
||||
* The GTK/GDK/GSK_DEBUG environment variables now
|
||||
work in productions as well as in debug builds
|
||||
|
||||
* Translation updates
|
||||
Catalan
|
||||
French
|
||||
Russian
|
||||
|
||||
|
||||
Overview of Changes in 4.13.2, 22-10-2023
|
||||
=========================================
|
||||
|
||||
* GtkPrintdialog:
|
||||
- New async-style api to replace GtkPrintOperation
|
||||
|
||||
* GtkEmojiChooser:
|
||||
- Add more languages: Bengali, Hindi, Japanese, Finnish,
|
||||
Thai and Norwegian bokmål
|
||||
|
||||
* Accessibility:
|
||||
- Fix some utf8 handling issues
|
||||
|
||||
* GDK:
|
||||
- Add support for dmabuf textures, with GdkDmabufTextureBuilder
|
||||
- Add a few more supported memory formats for textures
|
||||
|
||||
* GSK:
|
||||
- Add a fast-path for masking color
|
||||
- Add support for importing dmabuf textures
|
||||
- Handle GLES better by using some extensions
|
||||
|
||||
* Translation updates:
|
||||
Catalan
|
||||
Russian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.13.1, 28-09-2023
|
||||
=========================================
|
||||
|
||||
* GtkTooltip:
|
||||
@@ -7,20 +74,32 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
|
||||
* GtkCenterLayout, GtkEntry, GtkSearchEntry:
|
||||
- Fix some issues with baseline handling
|
||||
|
||||
* GtkColorButton, GtkFontButton:
|
||||
- Propagate focus-on-click
|
||||
|
||||
* GtkFileChooser:
|
||||
- Make "Visit file" scroll to the file
|
||||
|
||||
* GtkSwitch:
|
||||
- Respect text direction
|
||||
|
||||
* GtkWindow:
|
||||
- Don't assume titlebars are GtkHeaderBars
|
||||
|
||||
* Printing:
|
||||
- Fix some problems with the portal implementation
|
||||
- Add a new simple print API: GtkPrintDialog
|
||||
|
||||
* Paths:
|
||||
- GskPathMeasure performance has been improved
|
||||
- Add custom contours for circles, rounded rectangles and rectangles
|
||||
- Simplify GskPathPoint handling
|
||||
- gsk_path_point_get_closest_point now returns the distance as well
|
||||
- Make GskPathBuilder simplify curves
|
||||
|
||||
* Input:
|
||||
- Handle (some) single-key compose sequences
|
||||
- Fix active state tracking with sensitivity changes and grabs
|
||||
|
||||
* GSK:
|
||||
- Make the repeated gradients match between GL and cairo
|
||||
@@ -29,6 +108,13 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
|
||||
- Restrict an optimization to the cases where it is crrect
|
||||
- Fix rendering of shadows with opacity
|
||||
- The Vulkan renderer now requires Vulkan 1.2
|
||||
- GL: Transition gradients unpremultiplied
|
||||
- GL: Fix clipping of shadows
|
||||
- GL: Some optimizations
|
||||
- Broadway: Fix memory leaks in the renderer
|
||||
|
||||
* Wayland:
|
||||
- Make activation more reliable
|
||||
|
||||
* macOS:
|
||||
- Clamp damage regions to the surface size
|
||||
@@ -43,20 +129,29 @@ Overview of Changes in 4.13.1, xx-xx-xxxx
|
||||
* Build:
|
||||
- Fix build problems with C++ compilers
|
||||
|
||||
* Deprecations:
|
||||
- gtk_window_present_with_time
|
||||
|
||||
* Translation updates
|
||||
Brazilian Portuguese
|
||||
British English
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Czech
|
||||
Danish
|
||||
Dutch
|
||||
Esperanto
|
||||
Galician
|
||||
Georgian
|
||||
Italian
|
||||
Korean
|
||||
Latvian
|
||||
Lithuanian
|
||||
Persian
|
||||
Polish
|
||||
Punjabi
|
||||
Slovenian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.13.0, 25-08-2023
|
||||
|
41
build-aux/msvc/msvc_recommended_pragmas.h
Normal file
41
build-aux/msvc/msvc_recommended_pragmas.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef _MSC_VER
|
||||
#pragma error "This header is for Microsoft VC or clang-cl only."
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* Make MSVC more pedantic, this is a recommended pragma list
|
||||
* from _Win32_Programming_ by Rector and Newcomer.
|
||||
*/
|
||||
#ifndef __clang__
|
||||
#pragma warning(error:4002) /* too many actual parameters for macro */
|
||||
#pragma warning(error:4003) /* not enough actual parameters for macro */
|
||||
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
|
||||
#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */
|
||||
#pragma warning(1:4016) /* no function return type; using int as default */
|
||||
#pragma warning(error:4020) /* too many actual parameters */
|
||||
#pragma warning(error:4021) /* too few actual parameters */
|
||||
#pragma warning(error:4027) /* function declared without formal parameter list */
|
||||
#pragma warning(error:4029) /* declared formal parameter list different from definition */
|
||||
#pragma warning(error:4033) /* 'function' must return a value */
|
||||
#pragma warning(error:4035) /* 'function' : no return value */
|
||||
#pragma warning(error:4045) /* array bounds overflow */
|
||||
#pragma warning(error:4047) /* different levels of indirection */
|
||||
#pragma warning(error:4049) /* terminating line number emission */
|
||||
#pragma warning(error:4053) /* An expression of type void was used as an operand */
|
||||
#pragma warning(error:4071) /* no function prototype given */
|
||||
#pragma warning(disable:4101) /* unreferenced local variable */
|
||||
#pragma warning(error:4150)
|
||||
|
||||
/* G_NORETURN */
|
||||
#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
|
||||
#pragma warning(error:4715) /* 'function': not all control paths return a value */
|
||||
#pragma warning(error:4098) /* 'void' function returning a value */
|
||||
|
||||
#pragma warning(disable:4244) /* No possible loss of data warnings */
|
||||
#pragma warning(disable:4305) /* No truncation from int to char warnings */
|
||||
|
||||
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
|
||||
#endif /* __clang__ */
|
||||
|
||||
/* work around Microsoft's premature attempt to deprecate the C-Library */
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_NONSTDC_NO_WARNINGS
|
@@ -35,7 +35,7 @@ show_action_dialog (GSimpleAction *action)
|
||||
{
|
||||
GtkAlertDialog *dialog;
|
||||
|
||||
dialog = gtk_alert_dialog_new ("You activated action: \"%s\n",
|
||||
dialog = gtk_alert_dialog_new ("You activated action: \"%s\"",
|
||||
g_action_get_name (G_ACTION (action)));
|
||||
gtk_alert_dialog_show (dialog, NULL);
|
||||
g_object_unref (dialog);
|
||||
|
@@ -339,7 +339,6 @@
|
||||
<file>path_fill.c</file>
|
||||
<file>path_maze.c</file>
|
||||
<file>path_spinner.c</file>
|
||||
<file>path_sweep.c</file>
|
||||
<file>path_walk.c</file>
|
||||
<file>path_text.c</file>
|
||||
<file>peg_solitaire.c</file>
|
||||
@@ -427,10 +426,6 @@
|
||||
<gresource prefix="/fontrendering">
|
||||
<file>fontrendering.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/path_sweep">
|
||||
<file>path_sweep.ui</file>
|
||||
<file compressed="true">path_world.txt</file>
|
||||
</gresource>
|
||||
<gresource prefix="/path_walk">
|
||||
<file>path_walk.ui</file>
|
||||
<file compressed="true">path_world.txt</file>
|
||||
|
@@ -75,7 +75,9 @@ query_tooltip (GtkWidget *widget,
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||
|
||||
precision = 1;
|
||||
s = NULL;
|
||||
do {
|
||||
g_free (s);
|
||||
s = g_strdup_printf ("%.*f", precision, self->scale);
|
||||
l = strlen (s) - 1;
|
||||
while (s[l] == '0')
|
||||
|
@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
|
||||
{
|
||||
DemoWidget *self = DEMO_WIDGET (widget);
|
||||
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
|
||||
gint64 now = g_get_monotonic_time ();
|
||||
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
|
||||
gtk_widget_queue_allocate (widget);
|
||||
|
||||
@@ -66,11 +66,13 @@ clicked (GtkGestureClick *gesture,
|
||||
gpointer data)
|
||||
{
|
||||
DemoWidget *self = data;
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
if (self->tick_id != 0)
|
||||
return;
|
||||
|
||||
self->start_time = g_get_monotonic_time ();
|
||||
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
|
||||
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@@ -75,7 +75,6 @@ demos = files([
|
||||
'path_fill.c',
|
||||
'path_maze.c',
|
||||
'path_spinner.c',
|
||||
'path_sweep.c',
|
||||
'path_walk.c',
|
||||
'path_text.c',
|
||||
'peg_solitaire.c',
|
||||
|
@@ -2,10 +2,13 @@
|
||||
*
|
||||
* This demo shows how to use GskPath to draw shapes that are (a bit)
|
||||
* more complex than a rounded rectangle.
|
||||
*
|
||||
* It also demonstrates printing to a stream with GtkPrintDialog.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <cairo-pdf.h>
|
||||
|
||||
#include "paintable.h"
|
||||
|
||||
@@ -165,6 +168,89 @@ gtk_logo_paintable_new (void)
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
write_cairo (void *closure,
|
||||
const unsigned char *data,
|
||||
unsigned int length)
|
||||
{
|
||||
GOutputStream *stream = closure;
|
||||
gsize written;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
|
||||
{
|
||||
g_print ("Error writing pdf stream: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return CAIRO_STATUS_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
print_ready (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
|
||||
GError *error = NULL;
|
||||
GOutputStream *stream;
|
||||
GtkSnapshot *snapshot;
|
||||
GdkPaintable *paintable;
|
||||
GskRenderNode *node;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
stream = gtk_print_dialog_print_finish (dialog, result, &error);
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_print ("Failed to get output stream: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
|
||||
gdk_paintable_snapshot (paintable, snapshot, 100, 100);
|
||||
node = gtk_snapshot_free_to_node (snapshot);
|
||||
|
||||
surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100, 100);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
gsk_render_node_draw (node, cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
cairo_surface_destroy (surface);
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
if (!g_output_stream_close (stream, NULL, &error))
|
||||
{
|
||||
g_print ("Error from close: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
print (GtkButton *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *picture = data;
|
||||
GtkPrintDialog *dialog;
|
||||
|
||||
dialog = gtk_print_dialog_new ();
|
||||
|
||||
gtk_print_dialog_print (dialog,
|
||||
GTK_WINDOW (gtk_widget_get_root (picture)),
|
||||
NULL,
|
||||
NULL,
|
||||
print_ready,
|
||||
picture);
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_fill (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -172,12 +258,21 @@ do_path_fill (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *button, *label;
|
||||
GtkWidget *picture;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
|
||||
header = gtk_header_bar_new ();
|
||||
button = gtk_button_new_from_icon_name ("printer-symbolic");
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||
label = gtk_label_new ("Fill and Stroke");
|
||||
gtk_widget_add_css_class (label, "title");
|
||||
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
paintable = gtk_logo_paintable_new ();
|
||||
@@ -186,6 +281,8 @@ do_path_fill (GtkWidget *do_widget)
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
g_object_unref (paintable);
|
||||
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (print), picture);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), picture);
|
||||
}
|
||||
|
||||
|
@@ -1,319 +0,0 @@
|
||||
/* Path/Sweep
|
||||
*
|
||||
* This demo shows how path intersections can be used.
|
||||
*
|
||||
* The world map that is used here is a path with 211 lines and 1569 cubic
|
||||
* Bėzier segments in 121 contours.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GTK_TYPE_PATH_SWEEP (gtk_path_sweep_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkPathSweep, gtk_path_sweep, GTK, PATH_SWEEP, GtkWidget)
|
||||
|
||||
#define POINT_SIZE 8
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PATH,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
struct _GtkPathSweep
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GskPath *path;
|
||||
graphene_rect_t bounds;
|
||||
float y_pos;
|
||||
gboolean in;
|
||||
};
|
||||
|
||||
struct _GtkPathSweepClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (GtkPathSweep, gtk_path_sweep, GTK_TYPE_WIDGET)
|
||||
|
||||
static gboolean
|
||||
intersection_cb (GskPath *path1,
|
||||
const GskPathPoint *point1,
|
||||
GskPath *path2,
|
||||
const GskPathPoint *point2,
|
||||
GskPathIntersection kind,
|
||||
gpointer data)
|
||||
{
|
||||
GskPathBuilder *builder = data;
|
||||
graphene_point_t p;
|
||||
|
||||
gsk_path_point_get_position (point1, path1, &p);
|
||||
gsk_path_builder_add_circle (builder, &p, 4);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GskPath *
|
||||
get_intersection_path (GskPath *path1,
|
||||
GskPath *path2)
|
||||
{
|
||||
GskPathBuilder *builder = gsk_path_builder_new ();
|
||||
|
||||
gsk_path_foreach_intersection (path1, path2, intersection_cb, builder);
|
||||
|
||||
return gsk_path_builder_to_path (builder);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkPathSweep *self = GTK_PATH_SWEEP (widget);
|
||||
GskStroke *stroke;
|
||||
|
||||
if (self->path == NULL)
|
||||
return;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
|
||||
stroke = gsk_stroke_new (2.0);
|
||||
|
||||
gtk_snapshot_append_stroke (snapshot, self->path, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
if (self->in)
|
||||
{
|
||||
graphene_rect_t bounds;
|
||||
GskPathBuilder *builder;
|
||||
GskPath *line, *isecs;
|
||||
|
||||
gsk_path_get_stroke_bounds (self->path, stroke, &bounds);
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_move_to (builder, bounds.origin.x, bounds.origin.y + self->y_pos);
|
||||
gsk_path_builder_line_to (builder, bounds.origin.x + bounds.size.width, bounds.origin.y + self->y_pos);
|
||||
line = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gtk_snapshot_append_stroke (snapshot, line, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
isecs = get_intersection_path (self->path, line);
|
||||
|
||||
gtk_snapshot_append_fill (snapshot, isecs, GSK_FILL_RULE_WINDING, &(GdkRGBA) { 1, 0, 0, 1 });
|
||||
gtk_snapshot_append_stroke (snapshot, isecs, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
gsk_path_unref (isecs);
|
||||
gsk_path_unref (line);
|
||||
}
|
||||
|
||||
gsk_stroke_free (stroke);
|
||||
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkPathSweep *self = GTK_PATH_SWEEP (widget);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
*minimum = *natural = (int) ceilf (self->bounds.size.width);
|
||||
else
|
||||
*minimum = *natural = (int) ceilf (self->bounds.size.height);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_set_path (GtkPathSweep *self,
|
||||
GskPath *path)
|
||||
{
|
||||
if (self->path == path)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&self->path, gsk_path_unref);
|
||||
graphene_rect_init (&self->bounds, 0, 0, 0, 0);
|
||||
if (path)
|
||||
{
|
||||
GskStroke *stroke;
|
||||
|
||||
self->path = gsk_path_ref (path);
|
||||
stroke = gsk_stroke_new (2.0);
|
||||
gsk_path_get_stroke_bounds (path, stroke, &self->bounds);
|
||||
gsk_stroke_free (stroke);
|
||||
}
|
||||
|
||||
gtk_widget_queue_resize (GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PATH]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
|
||||
{
|
||||
GtkPathSweep *self = GTK_PATH_SWEEP (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
gtk_path_sweep_set_path (self, g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkPathSweep *self = GTK_PATH_SWEEP (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_value_set_boxed (value, self->path);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_dispose (GObject *object)
|
||||
{
|
||||
GtkPathSweep *self = GTK_PATH_SWEEP (object);
|
||||
|
||||
g_clear_pointer (&self->path, gsk_path_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_path_sweep_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_class_init (GtkPathSweepClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_path_sweep_dispose;
|
||||
object_class->set_property = gtk_path_sweep_set_property;
|
||||
object_class->get_property = gtk_path_sweep_get_property;
|
||||
|
||||
widget_class->snapshot = gtk_path_sweep_snapshot;
|
||||
widget_class->measure = gtk_path_sweep_measure;
|
||||
|
||||
properties[PROP_PATH] =
|
||||
g_param_spec_boxed ("path", NULL, NULL,
|
||||
GSK_TYPE_PATH,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPathSweep *self = data;
|
||||
|
||||
self->y_pos = y;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
enter_cb (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPathSweep *self = data;
|
||||
|
||||
self->in = TRUE;
|
||||
self->y_pos = y;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
leave_cb (GtkEventControllerMotion *controller,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPathSweep *self = data;
|
||||
|
||||
self->in = FALSE;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_path_sweep_init (GtkPathSweep *self)
|
||||
{
|
||||
GtkEventController *controller;
|
||||
|
||||
/* Data taken from
|
||||
* https://commons.wikimedia.org/wiki/Maps_of_the_world#/media/File:Simplified_blank_world_map_without_Antartica_(no_borders).svg
|
||||
*/
|
||||
GBytes *data = g_resources_lookup_data ("/path_sweep/path_world.txt", 0, NULL);
|
||||
GskPath *path = gsk_path_parse (g_bytes_get_data (data, NULL));
|
||||
g_bytes_unref (data);
|
||||
gtk_path_sweep_set_path (self, path);
|
||||
gsk_path_unref (path);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), self);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_path_sweep_new (void)
|
||||
{
|
||||
GtkPathSweep *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_PATH_SWEEP, NULL);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_path_sweep (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
g_type_ensure (GTK_TYPE_PATH_SWEEP);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/path_sweep/path_sweep.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">World Map</property>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkPathSweep" id="view">
|
||||
<property name="hexpand">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</interface>
|
@@ -1,8 +1,9 @@
|
||||
/* Pickers and Launchers
|
||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
|
||||
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkPrintDialog, GtkFileLauncher, GtkUriLauncher
|
||||
*
|
||||
* The dialogs are mainly intended for use in preference dialogs.
|
||||
* They allow to select colors, fonts and applications.
|
||||
* They allow to select colors, fonts and files. There is also a
|
||||
* print dialog.
|
||||
*
|
||||
* The launchers let you open files or URIs in applications that
|
||||
* can handle them.
|
||||
@@ -11,11 +12,13 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *app_picker;
|
||||
static GtkWidget *print_button;
|
||||
|
||||
static void
|
||||
set_file (GFile *file,
|
||||
gpointer data)
|
||||
{
|
||||
GFileInfo *info;
|
||||
char *name;
|
||||
|
||||
if (!file)
|
||||
@@ -31,6 +34,13 @@ set_file (GFile *file,
|
||||
|
||||
gtk_widget_set_sensitive (app_picker, TRUE);
|
||||
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
|
||||
|
||||
info = g_file_query_info (file, "standard::content-type", 0, NULL, NULL);
|
||||
if (strcmp (g_file_info_get_content_type (info), "application/pdf") == 0)
|
||||
{
|
||||
gtk_widget_set_sensitive (print_button, TRUE);
|
||||
g_object_set_data_full (G_OBJECT (print_button), "file", g_object_ref (file), g_object_unref);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -47,6 +57,10 @@ file_opened (GObject *source,
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
|
||||
gtk_widget_set_sensitive (print_button, FALSE);
|
||||
g_object_set_data (G_OBJECT (print_button), "file", NULL);
|
||||
}
|
||||
|
||||
set_file (file, data);
|
||||
@@ -114,6 +128,53 @@ open_app (GtkButton *picker)
|
||||
g_object_unref (launcher);
|
||||
}
|
||||
|
||||
static void
|
||||
print_file_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
|
||||
GError *error = NULL;
|
||||
GCancellable *cancellable;
|
||||
unsigned int id;
|
||||
|
||||
cancellable = g_task_get_cancellable (G_TASK (result));
|
||||
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cancellable), "timeout"));
|
||||
if (id)
|
||||
g_source_remove (id);
|
||||
|
||||
if (!gtk_print_dialog_print_file_finish (dialog, result, &error))
|
||||
{
|
||||
g_print ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_file (GtkButton *picker)
|
||||
{
|
||||
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
|
||||
GtkPrintDialog *dialog;
|
||||
GCancellable *cancellable;
|
||||
GFile *file;
|
||||
unsigned int id;
|
||||
|
||||
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
|
||||
dialog = gtk_print_dialog_new ();
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
|
||||
id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
|
||||
20,
|
||||
abort_mission, g_object_ref (cancellable), g_object_unref);
|
||||
g_object_set_data (G_OBJECT (cancellable), "timeout", GUINT_TO_POINTER (id));
|
||||
|
||||
gtk_print_dialog_print_file (dialog, parent, NULL, file, cancellable, print_file_done, NULL);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_uri_done (GObject *source,
|
||||
GAsyncResult *result,
|
||||
@@ -234,8 +295,14 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_sensitive (app_picker, FALSE);
|
||||
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
|
||||
gtk_box_append (GTK_BOX (picker), app_picker);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
||||
|
||||
print_button = gtk_button_new_from_icon_name ("printer-symbolic");
|
||||
gtk_widget_set_tooltip_text (print_button, "Print file");
|
||||
gtk_widget_set_sensitive (print_button, FALSE);
|
||||
g_signal_connect (print_button, "clicked", G_CALLBACK (print_file), NULL);
|
||||
gtk_box_append (GTK_BOX (picker), print_button);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("URI:");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
|
@@ -139,6 +139,7 @@ do_video_player (GtkWidget *do_widget)
|
||||
|
||||
video = gtk_video_new ();
|
||||
gtk_video_set_autoplay (GTK_VIDEO (video), TRUE);
|
||||
gtk_video_set_graphics_offload (GTK_VIDEO (video), GTK_GRAPHICS_OFFLOAD_ENABLED);
|
||||
gtk_window_set_child (GTK_WINDOW (window), video);
|
||||
|
||||
title = gtk_header_bar_new ();
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 533 B |
Binary file not shown.
Before Width: | Height: | Size: 127 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M3.384 3h3.231c.213 0 .385.224.385.502v2.996C7 6.776 6.828 7 6.615 7h-3.23C3.17 7 3 6.776 3 6.498V3.502C3 3.224 3.17 3 3.384 3zm6 0h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C9.17 7 9 6.776 9 6.498V3.502C9 3.224 9.17 3 9.384 3zm-6 6h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C3.17 13 3 12.776 3 12.498V9.502C3 9.224 3.17 9 3.384 9zm6 0h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C9.17 13 9 12.776 9 12.498V9.502C9 9.224 9.17 9 9.384 9z" style="marker:none" overflow="visible" color="#000" fill="#474747"/></svg>
|
Before Width: | Height: | Size: 654 B |
@@ -25,14 +25,12 @@
|
||||
<file>icons/16x16/actions/format-justify-fill-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/format-justify-left-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/format-justify-right-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/insert-image.png</file>
|
||||
<file>icons/16x16/actions/insert-link-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/send-to-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/star-new-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-continuous-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-dual-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-grid-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-paged-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/zoom-in-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/zoom-in.png</file>
|
||||
@@ -88,7 +86,6 @@
|
||||
<file>icons/scalable/actions/view-dual-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/view-paged-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/view-fullscreen-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/view-grid-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/zoom-in-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/zoom-original-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/zoom-out-symbolic.svg</file>
|
||||
|
@@ -685,6 +685,8 @@ stack-allocated using `g_newa()` or `g_alloca()`. But limit the amount
|
||||
of stack memory that you consume this way, in particular in recursive
|
||||
functions.
|
||||
|
||||
On Windows, the default stack size we have to work with is 1M.
|
||||
|
||||
### Macros
|
||||
|
||||
Try to avoid private macros unless strictly necessary. Remember to #undef
|
||||
|
@@ -1,6 +1,4 @@
|
||||
----
|
||||
Title: Cairo interaction
|
||||
----
|
||||
|
||||
## Functions to support using cairo
|
||||
|
||||
|
@@ -107,4 +107,5 @@ content_images = [
|
||||
"images/popup-flip.png",
|
||||
"images/popup-slide.png",
|
||||
]
|
||||
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gdk/"
|
||||
urlmap_file = "urlmap.js"
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Title: Key Values
|
||||
Title: Keyboard Codes, Groups, And Modifiers
|
||||
|
||||
## Functions for manipulating keyboard codes
|
||||
|
||||
@@ -8,19 +8,19 @@ The complete list of key values can be found in the [`gdk/gdkkeysyms.h`](https:/
|
||||
file.
|
||||
|
||||
Key values are regularly updated from the upstream X.org X11 implementation,
|
||||
so new values are added regularly. They will be prefixed with GDK_KEY_ rather
|
||||
than XF86XK_ or XK_ (for older symbols).
|
||||
so new values are added regularly. They will be prefixed with `GDK_KEY_` rather
|
||||
than `XF86XK_` or `XK_` (for older symbols).
|
||||
|
||||
Key values can be converted into a string representation using
|
||||
gdk_keyval_name(). The reverse function, converting a string to a key value,
|
||||
is provided by gdk_keyval_from_name().
|
||||
[`func@Gdk.keyval_name`]. The reverse function, converting a string to a key
|
||||
value, is provided by [`func@Gdk.keyval_from_name`].
|
||||
|
||||
The case of key values can be determined using gdk_keyval_is_upper() and
|
||||
gdk_keyval_is_lower(). Key values can be converted to upper or lower case
|
||||
using gdk_keyval_to_upper() and gdk_keyval_to_lower().
|
||||
The case of key values can be determined using [`func@Gdk.keyval_is_upper`]
|
||||
and [`func@Gdk.keyval_is_lower`]. Key values can be converted to upper or lower
|
||||
case using [`func@Gdk.keyval_to_upper`] and [`func@Gdk.keyval_to_lower`].
|
||||
|
||||
When it makes sense, key values can be converted to and from
|
||||
Unicode characters with gdk_keyval_to_unicode() and gdk_unicode_to_keyval().
|
||||
When it makes sense, key values can be converted to and from Unicode characters
|
||||
with [`func@Gdk.keyval_to_unicode`] and [`func@Gdk.unicode_to_keyval`].
|
||||
|
||||
## Key groups
|
||||
|
||||
@@ -36,23 +36,23 @@ You can think of a [struct@Gdk.KeymapKey] as a representation of a symbol
|
||||
printed on a physical keyboard key. That is, it contains three pieces of
|
||||
information:
|
||||
|
||||
1. first, it contains the hardware keycode; this is an identifying number
|
||||
for a physical key
|
||||
1. second, it contains the “level” of the key. The level indicates which
|
||||
symbol on the key will be used, in a vertical direction. So on a standard
|
||||
US keyboard, the key with the number “1“ on it also has the exclamation
|
||||
point (”!”) character on it. The level indicates whether to use the “1”
|
||||
or the “!” symbol. The letter keys are considered to have a lowercase
|
||||
letter at level 0, and an uppercase letter at level 1, though normally
|
||||
only the uppercase letter is printed on the key
|
||||
1. third, the [struct@Gdk.KeymapKey] contains a group; groups are not used on
|
||||
standard US keyboards, but are used in many other countries. On a
|
||||
keyboard with groups, there can be 3 or 4 symbols printed on a single
|
||||
key. The group indicates movement in a horizontal direction. Usually
|
||||
groups are used for two different languages. In group 0, a key might
|
||||
have two English characters, and in group 1 it might have two Hebrew
|
||||
characters. The Hebrew characters will be printed on the key next to
|
||||
the English characters.
|
||||
1. first, it contains the hardware keycode; this is an identifying number
|
||||
for a physical key
|
||||
1. second, it contains the “level” of the key. The level indicates which
|
||||
symbol on the key will be used, in a vertical direction. So on a standard
|
||||
US keyboard, the key with the number “1“ on it also has the exclamation
|
||||
point (”!”) character on it. The level indicates whether to use the “1”
|
||||
or the “!” symbol. The letter keys are considered to have a lowercase
|
||||
letter at level 0, and an uppercase letter at level 1, though normally
|
||||
only the uppercase letter is printed on the key
|
||||
1. third, the [struct@Gdk.KeymapKey] contains a group; groups are not used on
|
||||
standard US keyboards, but are used in many other countries. On a
|
||||
keyboard with groups, there can be 3 or 4 symbols printed on a single
|
||||
key. The group indicates movement in a horizontal direction. Usually
|
||||
groups are used for two different languages. In group 0, a key might
|
||||
have two English characters, and in group 1 it might have two Hebrew
|
||||
characters. The Hebrew characters will be printed on the key next to
|
||||
the English characters.
|
||||
|
||||
When GDK creates a key event in order to deliver a key press or release,
|
||||
it first converts the current keyboard state into an effective group and
|
||||
@@ -72,7 +72,7 @@ in the key event and can be obtained via [class@Gdk.KeyEvent] getters.
|
||||
### Consumed modifiers
|
||||
|
||||
The `consumed_modifiers` in a key event are modifiers that should be masked
|
||||
out from @state when comparing this key press to a hot key. For instance,
|
||||
out from `@state` when comparing this key press to a hot key. For instance,
|
||||
on a US keyboard, the `plus` symbol is shifted, so when comparing a key
|
||||
press to a `<Control>plus` accelerator `<Shift>` should be masked out.
|
||||
|
||||
@@ -91,9 +91,8 @@ if (keyval == GDK_PLUS &&
|
||||
```
|
||||
|
||||
An older interpretation of `consumed_modifiers` was that it contained
|
||||
all modifiers that might affect the translation of the key;
|
||||
this allowed accelerators to be stored with irrelevant consumed
|
||||
modifiers, by doing:
|
||||
all modifiers that might affect the translation of the key; this allowed
|
||||
accelerators to be stored with irrelevant consumed modifiers, by doing:
|
||||
|
||||
```c
|
||||
// XXX Don’t do this XXX
|
||||
@@ -102,12 +101,11 @@ if (keyval == accel_keyval &&
|
||||
// Accelerator was pressed
|
||||
```
|
||||
|
||||
However, this did not work if multi-modifier combinations were
|
||||
used in the keymap, since, for instance, `<Control>` would be
|
||||
masked out even if only `<Control><Alt>` was used in
|
||||
the keymap. To support this usage as well as well as possible, all single
|
||||
modifier combinations that could affect the key for any combination
|
||||
of modifiers will be returned in `consumed_modifiers`; multi-modifier
|
||||
combinations are returned only when actually found in `state`. When
|
||||
you store accelerators, you should always store them with consumed
|
||||
However, this did not work if multi-modifier combinations were used in the
|
||||
keymap, since, for instance, `<Control>` would be masked out even if only
|
||||
`<Control><Alt>` was used in the keymap. To support this usage as well as
|
||||
well as possible, all single modifier combinations that could affect the key
|
||||
for any combination of modifiers will be returned in `consumed_modifiers`;
|
||||
multi-modifier combinations are returned only when actually found in `state`.
|
||||
When you store accelerators, you should always store them with consumed
|
||||
modifiers removed. Store `<Control>plus`, not `<Control><Shift>plus`.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Title: Pango Interaction
|
||||
Title: Pango Interaction
|
||||
|
||||
Pango is the text layout system used by GDK and GTK. The functions
|
||||
and types in this section are used to obtain clip regions for
|
||||
|
@@ -62,4 +62,5 @@ content_images = [
|
||||
"images/stroke-miter.png",
|
||||
"images/stroke-round.png",
|
||||
]
|
||||
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gsk/"
|
||||
urlmap_file = "urlmap.js"
|
||||
|
@@ -1,8 +1,6 @@
|
||||
Title: Compiling the GTK Libraries
|
||||
Title: Building GTK
|
||||
Slug: gtk-building
|
||||
|
||||
## Building GTK
|
||||
|
||||
Before we get into the details of how to compile GTK, we should
|
||||
mention that in many cases, binary packages of GTK prebuilt for
|
||||
your operating system will be available, either from your
|
||||
|
@@ -1,8 +1,6 @@
|
||||
Title: Coordinate systems
|
||||
Title: Coordinate systems in GTK
|
||||
Slug: gtk-coordinates
|
||||
|
||||
## Coordinate systems in GTK
|
||||
|
||||
All coordinate systems in GTK have the origin at the top left, with the X axis
|
||||
pointing right, and the Y axis pointing down. This matches the convention used
|
||||
in X11, Wayland and cairo, but differs from OpenGL and PostScript, where the origin
|
||||
|
@@ -41,7 +41,7 @@ activate (GtkApplication* app,
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -183,7 +183,7 @@ activate (GtkApplication *app,
|
||||
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -331,8 +331,7 @@ activate (GtkApplication *app,
|
||||
*/
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1);
|
||||
|
||||
gtk_widget_show (window);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -554,7 +553,7 @@ activate (GtkApplication *app,
|
||||
|
||||
g_signal_connect (press, "pressed", G_CALLBACK (pressed), drawing_area);
|
||||
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
int
|
||||
@@ -631,7 +630,7 @@ activate (GtkApplication *app,
|
||||
button = gtk_builder_get_object (builder, "quit");
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (quit_cb), window);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
gtk_widget_set_visible (GTK_WIDGET (window), TRUE);
|
||||
|
||||
/* We do not need the builder any more */
|
||||
g_object_unref (builder);
|
||||
|
@@ -35,6 +35,11 @@ Showing
|
||||
|
||||
The ``show`` command displays the rendernode.
|
||||
|
||||
``--undecorated``
|
||||
|
||||
Removes window decorations. This is meant for rendering of exactly the rendernode
|
||||
without any titlebar.
|
||||
|
||||
Rendering
|
||||
^^^^^^^^^
|
||||
|
||||
|
@@ -245,4 +245,5 @@ content_images = [
|
||||
"images/box-model-light.png",
|
||||
"images/box-model-dark.png",
|
||||
]
|
||||
content_base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/docs/reference/gtk/"
|
||||
urlmap_file = "urlmap.js"
|
||||
|
@@ -1,8 +1,6 @@
|
||||
----
|
||||
Title: Initialization
|
||||
----
|
||||
Title: Initializing GTK
|
||||
|
||||
# Library initialization and main loop
|
||||
## Library initialization and main loop
|
||||
|
||||
Before using GTK, you need to initialize it using [func@Gtk.init]; this
|
||||
connects to the windowing system, sets up the locale and performs other
|
||||
@@ -49,7 +47,7 @@ main (int argc, char **argv)
|
||||
// ...
|
||||
|
||||
// Show the application window
|
||||
gtk_widget_show (window);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
// Enter the main event loop, and wait for user interaction
|
||||
while (!done)
|
||||
@@ -66,5 +64,5 @@ as spinning the main loop.
|
||||
|
||||
### See also
|
||||
|
||||
- the GLib manual, especially `GMainLoop`
|
||||
- signal-related functions, such as `g_signal_connect()` in GObject
|
||||
- the GLib manual, especially `GMainLoop`
|
||||
- signal-related functions, such as `g_signal_connect()` in GObject
|
||||
|
@@ -2,5 +2,6 @@ Title: Migrating from GTK 2.x to GTK 4
|
||||
Slug: gtk-migrating-2-to-4
|
||||
|
||||
If your application is still using GTK 2, you should first convert it to GTK 3,
|
||||
by following the [migration guide](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
|
||||
in the GTK 3 documentation, and then follow [these instructions](#gtk-migrating-3-to-4).
|
||||
by following the [migration guide](https://docs.gtk.org/gtk3/migrating-2to3.html)
|
||||
in the GTK 3 documentation, and then follow [the GTK 3 to 4 migration
|
||||
guide](migrating-3to4.html).
|
||||
|
@@ -31,10 +31,11 @@ for GTK, available on GitLab.
|
||||
|
||||
If you want to discuss your approach before or after working on it,
|
||||
good ways to contact the GTK developers, apart from GitLab issues,
|
||||
are
|
||||
are:
|
||||
|
||||
- the #gtk IRC channel on irc.gnome.org
|
||||
- the gtk tag on the [GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
||||
- the `#gtk:gnome.org` Matrix room
|
||||
- the `#gtk` IRC channel on `irc.libera.chat`
|
||||
|
||||
You should not send patches by email, as they will inevitably get lost,
|
||||
or forgotten. Always open a merge request.
|
||||
|
@@ -170,40 +170,46 @@ This variable can be set to a list of debug options, which cause GDK to
|
||||
print out different types of debugging information. Some of these options
|
||||
are only available when GTK has been configured with `-Ddebug=true`.
|
||||
|
||||
`cursor`
|
||||
: Information about cursor objects (only win32)
|
||||
`misc`
|
||||
: Miscellaneous information
|
||||
|
||||
`events`
|
||||
: Information about events
|
||||
|
||||
`dnd`
|
||||
: Information about drag-and-drop
|
||||
|
||||
`input`
|
||||
: Information about input (mostly Windows)
|
||||
|
||||
`eventloop`
|
||||
: Information about event loop operation (mostly macOS)
|
||||
|
||||
`misc`
|
||||
: Miscellaneous information
|
||||
|
||||
`frames`
|
||||
: Information about the frame clock
|
||||
|
||||
`settings`
|
||||
: Information about xsettings
|
||||
|
||||
`selection`
|
||||
: Information about selections
|
||||
|
||||
`clipboard`
|
||||
: Information about clipboards
|
||||
|
||||
`dnd`
|
||||
: Information about drag-and-drop
|
||||
|
||||
`opengl`
|
||||
: Information about OpenGL
|
||||
|
||||
`vulkan`
|
||||
: Information about Vulkan
|
||||
|
||||
A number of options affect behavior instead of logging:
|
||||
`selection`
|
||||
: Information about selections
|
||||
|
||||
`nograbs`
|
||||
: Turn off all pointer and keyboard grabs
|
||||
`clipboard`
|
||||
: Information about clipboards
|
||||
|
||||
`dmabuf`
|
||||
: Information about dmabuf handling (Linux-only)
|
||||
|
||||
`offload`
|
||||
: Information about subsurfaces and graphics offload (Wayland-only)
|
||||
|
||||
A number of options affect behavior instead of logging:
|
||||
|
||||
`portals`
|
||||
: Force the use of [portals](https://docs.flatpak.org/en/latest/portals.html)
|
||||
@@ -217,11 +223,17 @@ A number of options affect behavior instead of logging:
|
||||
`gl-fractional`
|
||||
: Enable fractional scaling for OpenGL. This is experimental
|
||||
|
||||
`gl-legacy`
|
||||
: Use a legacy OpenGL context
|
||||
`gl-debug`
|
||||
: Insert debugging information in OpenGL
|
||||
|
||||
`gl-gles`
|
||||
: Use a GLES OpenGL context
|
||||
`gl-disable-gl`
|
||||
: Don't allow the use of OpenGL GL API. This forces GLES to be used
|
||||
|
||||
`gl-disable-gles`
|
||||
: Don't allow the use of OpenGL GLES API. This forces GL to be used
|
||||
|
||||
`gl-prefer-gl`
|
||||
: Prefer OpenGL over OpenGL ES. This was the default behavior before GTK 4.14.
|
||||
|
||||
`gl-egl`
|
||||
: Use an EGL context on X11 or Windows
|
||||
@@ -244,6 +256,12 @@ A number of options affect behavior instead of logging:
|
||||
`high-depth`
|
||||
: Use high bit depth rendering if possible
|
||||
|
||||
`no-vsync`
|
||||
: Repaint instantly (uses 100% CPU with animations)
|
||||
|
||||
`dmabuf-disable`
|
||||
: Disable dmabuf support
|
||||
|
||||
The special value `all` can be used to turn on all debug options. The special
|
||||
value `help` can be used to obtain a list of all supported debug options.
|
||||
|
||||
@@ -291,6 +309,9 @@ A number of options affect behavior instead of logging:
|
||||
`sync`
|
||||
: Sync after each frame
|
||||
|
||||
`offload-disable`
|
||||
: Disable graphics offload to subsurfaces
|
||||
|
||||
`vulkan-staging-image`
|
||||
: Use a staging image for Vulkan texture upload
|
||||
|
||||
|
@@ -209,13 +209,11 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
|
||||
timings->complete = TRUE;
|
||||
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||
_gdk_frame_clock_debug_print_timings (clock, timings);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -369,14 +369,12 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
else if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_debug_message ("file transfer portal: %s has no path, dropping\n", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
@@ -426,14 +424,12 @@ portal_finish (GObject *object,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *s = g_strjoinv (", ", files);
|
||||
gdk_debug_message ("file transfer portal: Receiving files: %s", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
|
57
gdk/gdk.c
57
gdk/gdk.c
@@ -117,22 +117,26 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
|
||||
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
|
||||
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
|
||||
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE },
|
||||
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)", TRUE },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE },
|
||||
{ "gl-gles", GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API", TRUE },
|
||||
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows", TRUE },
|
||||
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11", TRUE },
|
||||
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows", TRUE },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support", TRUE },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer", TRUE },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
|
||||
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
|
||||
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
|
||||
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
|
||||
{ "offload", GDK_DEBUG_OFFLOAD, "Information about subsurfaces and graphics offload" },
|
||||
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals" },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals" },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
|
||||
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)" },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
|
||||
{ "gl-disable-gl", GDK_DEBUG_GL_DISABLE_GL, "Only allow OpenGL GLES API" },
|
||||
{ "gl-disable-gles", GDK_DEBUG_GL_DISABLE_GLES, "Don't allow OpenGL GLES API" },
|
||||
{ "gl-prefer-gl", GDK_DEBUG_GL_PREFER_GL, "Prefer GL over GLES API" },
|
||||
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows" },
|
||||
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11" },
|
||||
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows" },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
|
||||
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible" },
|
||||
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)" },
|
||||
{ "dmabuf-disable", GDK_DEBUG_DMABUF_DISABLE, "Disable dmabuf support" },
|
||||
};
|
||||
|
||||
|
||||
@@ -193,13 +197,6 @@ gdk_parse_debug_var (const char *variable,
|
||||
const char *q;
|
||||
gboolean invert;
|
||||
gboolean help;
|
||||
gboolean debug_enabled;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
debug_enabled = TRUE;
|
||||
#else
|
||||
debug_enabled = FALSE;
|
||||
#endif
|
||||
|
||||
string = g_getenv (variable);
|
||||
if (string == NULL)
|
||||
@@ -231,12 +228,6 @@ gdk_parse_debug_var (const char *variable,
|
||||
if (strlen (keys[i].key) == q - p &&
|
||||
g_ascii_strncasecmp (keys[i].key, p, q - p) == 0)
|
||||
{
|
||||
if (!debug_enabled && !keys[i].always_enabled)
|
||||
{
|
||||
fprintf (stderr, "\"%s\" is only available when building GTK with G_ENABLE_DEBUG. See %s=help\n",
|
||||
val, variable);
|
||||
break;
|
||||
}
|
||||
result |= keys[i].value;
|
||||
break;
|
||||
}
|
||||
@@ -260,10 +251,9 @@ gdk_parse_debug_var (const char *variable,
|
||||
|
||||
fprintf (stderr, "Supported %s values:\n", variable);
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if (debug_enabled || keys[i].always_enabled)
|
||||
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
|
||||
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
|
||||
}
|
||||
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values");
|
||||
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values. Other given values are subtracted");
|
||||
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
|
||||
fprintf (stderr, "\nMultiple values can be given, separated by : or space.\n");
|
||||
}
|
||||
@@ -274,8 +264,7 @@ gdk_parse_debug_var (const char *variable,
|
||||
|
||||
for (i = 0; i < nkeys; i++)
|
||||
{
|
||||
if (debug_enabled || keys[i].always_enabled)
|
||||
all_flags |= keys[i].value;
|
||||
all_flags |= keys[i].value;
|
||||
}
|
||||
|
||||
result = all_flags & (~result);
|
||||
|
@@ -42,6 +42,9 @@
|
||||
#include <gdk/gdkdevicetool.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
#include <gdk/gdkdisplaymanager.h>
|
||||
#include <gdk/gdkdmabufformats.h>
|
||||
#include <gdk/gdkdmabuftexture.h>
|
||||
#include <gdk/gdkdmabuftexturebuilder.h>
|
||||
#include <gdk/gdkdrag.h>
|
||||
#include <gdk/gdkdragsurface.h>
|
||||
#include <gdk/gdkdragsurfacesize.h>
|
||||
|
@@ -183,7 +183,7 @@ gdk_array(reserve) (GdkArray *self,
|
||||
return;
|
||||
|
||||
size = gdk_array(get_size) (self);
|
||||
new_size = 1 << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
|
||||
new_size = ((gsize) 1) << g_bit_storage (MAX (GDK_ARRAY_REAL_SIZE (n), 16) - 1);
|
||||
|
||||
#ifdef GDK_ARRAY_PREALLOC
|
||||
if (self->start == self->preallocated)
|
||||
@@ -215,7 +215,11 @@ gdk_array(splice) (GdkArray *self,
|
||||
gsize pos,
|
||||
gsize removed,
|
||||
gboolean stolen,
|
||||
#ifdef GDK_ARRAY_BY_VALUE
|
||||
const _T_ *additions,
|
||||
#else
|
||||
_T_ *additions,
|
||||
#endif
|
||||
gsize added)
|
||||
{
|
||||
gsize size;
|
||||
@@ -318,3 +322,5 @@ gdk_array(get) (const GdkArray *self,
|
||||
#undef GDK_ARRAY_TYPE_NAME
|
||||
#undef GDK_ARRAY_NO_MEMSET
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -36,23 +36,28 @@ typedef enum {
|
||||
GDK_DEBUG_VULKAN = 1 << 8,
|
||||
GDK_DEBUG_SELECTION = 1 << 9,
|
||||
GDK_DEBUG_CLIPBOARD = 1 << 10,
|
||||
GDK_DEBUG_DMABUF = 1 << 11,
|
||||
GDK_DEBUG_OFFLOAD = 1 << 12,
|
||||
|
||||
/* flags below are influencing behavior */
|
||||
GDK_DEBUG_NOGRABS = 1 << 11,
|
||||
GDK_DEBUG_PORTALS = 1 << 12,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 13,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 14,
|
||||
GDK_DEBUG_GL_FRACTIONAL = 1 << 15,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 16,
|
||||
GDK_DEBUG_GL_GLES = 1 << 17,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 18,
|
||||
GDK_DEBUG_GL_EGL = 1 << 19,
|
||||
GDK_DEBUG_GL_GLX = 1 << 20,
|
||||
GDK_DEBUG_GL_WGL = 1 << 21,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 22,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
|
||||
GDK_DEBUG_NO_VSYNC = 1 << 26,
|
||||
GDK_DEBUG_PORTALS = 1 << 14,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 15,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 16,
|
||||
GDK_DEBUG_GL_FRACTIONAL = 1 << 17,
|
||||
|
||||
GDK_DEBUG_GL_DISABLE_GL = 1 << 19,
|
||||
GDK_DEBUG_GL_DISABLE_GLES = 1 << 20,
|
||||
GDK_DEBUG_GL_PREFER_GL = 1 << 21,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 22,
|
||||
GDK_DEBUG_GL_EGL = 1 << 23,
|
||||
GDK_DEBUG_GL_GLX = 1 << 24,
|
||||
GDK_DEBUG_GL_WGL = 1 << 25,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 26,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 27,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 28,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 29,
|
||||
GDK_DEBUG_NO_VSYNC = 1 << 30,
|
||||
GDK_DEBUG_DMABUF_DISABLE = 1 << 31,
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
@@ -61,13 +66,24 @@ GdkDebugFlags gdk_display_get_debug_flags (GdkDisplay *display);
|
||||
void gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
GdkDebugFlags flags);
|
||||
|
||||
#ifdef GLIB_USING_SYSTEM_PRINTF
|
||||
#define gdk_debug_message(format, ...) fprintf (stderr, format "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define gdk_debug_message(format, ...) g_fprintf (stderr, format "\n", ##__VA_ARGS__)
|
||||
#endif
|
||||
static inline void
|
||||
gdk_debug_message (const char *format, ...) G_GNUC_PRINTF(1, 2);
|
||||
static inline void
|
||||
gdk_debug_message (const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *s;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
va_start (args, format);
|
||||
s = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
#ifdef GLIB_USING_SYSTEM_PRINTF
|
||||
fprintf (stderr, "%s\n", s);
|
||||
#else
|
||||
g_fprintf (stderr, "%s\n", s);
|
||||
#endif
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
#define GDK_DISPLAY_DEBUG_CHECK(display,type) \
|
||||
G_UNLIKELY (gdk_display_get_debug_flags (display) & GDK_DEBUG_##type)
|
||||
@@ -78,13 +94,6 @@ void gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
gdk_debug_message (__VA_ARGS__); \
|
||||
} G_STMT_END
|
||||
|
||||
#else /* !G_ENABLE_DEBUG */
|
||||
|
||||
#define GDK_DISPLAY_DEBUG_CHECK(display,type) 0
|
||||
#define GDK_DISPLAY_DEBUG(display,type,...)
|
||||
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
#define GDK_DEBUG_CHECK(type) GDK_DISPLAY_DEBUG_CHECK (NULL,type)
|
||||
#define GDK_DEBUG(type,...) GDK_DISPLAY_DEBUG (NULL,type,__VA_ARGS__)
|
||||
|
||||
@@ -93,7 +102,6 @@ typedef struct
|
||||
const char *key;
|
||||
guint value;
|
||||
const char *help;
|
||||
gboolean always_enabled;
|
||||
} GdkDebugKey;
|
||||
|
||||
guint gdk_parse_debug_var (const char *variable,
|
||||
|
151
gdk/gdkdisplay.c
151
gdk/gdkdisplay.c
@@ -31,6 +31,9 @@
|
||||
#include "gdkclipboardprivate.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdisplaymanagerprivate.h"
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdkeventsprivate.h"
|
||||
#include "gdkframeclockidleprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
@@ -41,6 +44,11 @@
|
||||
#ifdef HAVE_EGL
|
||||
#include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -69,6 +77,7 @@ enum
|
||||
PROP_COMPOSITED,
|
||||
PROP_RGBA,
|
||||
PROP_INPUT_SHAPES,
|
||||
PROP_DMABUF_FORMATS,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -138,6 +147,10 @@ gdk_display_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
|
||||
break;
|
||||
|
||||
case PROP_DMABUF_FORMATS:
|
||||
g_value_set_boxed (value, gdk_display_get_dmabuf_formats (display));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -239,6 +252,11 @@ gdk_display_class_init (GdkDisplayClass *class)
|
||||
TRUE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
props[PROP_DMABUF_FORMATS] =
|
||||
g_param_spec_boxed ("dmabuf-formats", NULL, NULL,
|
||||
GDK_TYPE_DMABUF_FORMATS,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||
|
||||
/**
|
||||
@@ -378,6 +396,10 @@ gdk_display_dispose (GObject *object)
|
||||
|
||||
g_queue_clear (&display->queued_events);
|
||||
|
||||
g_clear_object (&display->egl_gsk_renderer);
|
||||
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
|
||||
|
||||
g_clear_object (&priv->gl_context);
|
||||
#ifdef HAVE_EGL
|
||||
g_clear_pointer (&priv->egl_display, eglTerminate);
|
||||
@@ -404,6 +426,8 @@ gdk_display_finalize (GObject *object)
|
||||
|
||||
g_list_free_full (display->seats, g_object_unref);
|
||||
|
||||
g_clear_pointer (&display->dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
|
||||
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -1409,7 +1433,6 @@ gdk_display_get_gl_context (GdkDisplay *self)
|
||||
}
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static int
|
||||
strvcmp (gconstpointer p1,
|
||||
gconstpointer p2)
|
||||
@@ -1466,7 +1489,6 @@ describe_egl_config (EGLDisplay egl_display,
|
||||
|
||||
return g_strdup_printf ("R%dG%dB%dA%d%s", red, green, blue, alpha, type == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT ? "" : " float");
|
||||
}
|
||||
#endif
|
||||
|
||||
gpointer
|
||||
gdk_display_get_egl_config (GdkDisplay *self)
|
||||
@@ -1670,6 +1692,23 @@ gdk_display_check_egl_extensions (EGLDisplay egl_display,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
find_egl_device (EGLDisplay egl_display)
|
||||
{
|
||||
EGLAttrib value;
|
||||
EGLDeviceEXT egl_device;
|
||||
|
||||
eglQueryDisplayAttribEXT (egl_display, EGL_DEVICE_EXT, &value);
|
||||
|
||||
egl_device = (EGLDeviceEXT)value;
|
||||
|
||||
#ifndef EGL_DRM_RENDER_NODE_FILE_EXT
|
||||
#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377
|
||||
#endif
|
||||
|
||||
return eglQueryDeviceStringEXT (egl_device, EGL_DRM_RENDER_NODE_FILE_EXT);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_display_init_egl (GdkDisplay *self,
|
||||
int platform,
|
||||
@@ -1755,6 +1794,10 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||
self->have_egl_pixel_format_float =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
||||
self->have_egl_dma_buf_import =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_image_dma_buf_import_modifiers");
|
||||
self->have_egl_dma_buf_export =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_MESA_image_dma_buf_export");
|
||||
|
||||
if (self->have_egl_no_config_context)
|
||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||
@@ -1763,15 +1806,22 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
if (priv->egl_config_high_depth == NULL)
|
||||
priv->egl_config_high_depth = priv->egl_config;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (self, OPENGL))
|
||||
{
|
||||
char *ext = describe_extensions (priv->egl_display);
|
||||
char *std_cfg = describe_egl_config (priv->egl_display, priv->egl_config);
|
||||
char *hd_cfg = describe_egl_config (priv->egl_display, priv->egl_config_high_depth);
|
||||
const char *path;
|
||||
struct stat buf = { .st_rdev = 0, };
|
||||
|
||||
path = find_egl_device (priv->egl_display);
|
||||
if (path)
|
||||
stat (path, &buf);
|
||||
|
||||
gdk_debug_message ("EGL API version %d.%d found\n"
|
||||
" - Vendor: %s\n"
|
||||
" - Version: %s\n"
|
||||
" - Device: %s, %d %d\n"
|
||||
" - Client APIs: %s\n"
|
||||
" - Extensions:\n"
|
||||
"\t%s\n"
|
||||
@@ -1780,6 +1830,12 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
major, minor,
|
||||
eglQueryString (priv->egl_display, EGL_VENDOR),
|
||||
eglQueryString (priv->egl_display, EGL_VERSION),
|
||||
path ? path : "unknown",
|
||||
#ifdef HAVE_SYS_SYSMACROS_H
|
||||
major (buf.st_rdev), minor (buf.st_rdev),
|
||||
#else
|
||||
0, 0,
|
||||
#endif
|
||||
eglQueryString (priv->egl_display, EGL_CLIENT_APIS),
|
||||
ext, std_cfg,
|
||||
priv->egl_config_high_depth == priv->egl_config ? "none" : hd_cfg);
|
||||
@@ -1787,7 +1843,6 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
g_free (std_cfg);
|
||||
g_free (ext);
|
||||
}
|
||||
#endif
|
||||
|
||||
gdk_profiler_end_mark (start_time, "init EGL", NULL);
|
||||
|
||||
@@ -1824,6 +1879,94 @@ gdk_display_get_egl_display (GdkDisplay *self)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
static void
|
||||
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
|
||||
const GdkDmabufDownloader *downloader,
|
||||
GdkDmabufFormatsBuilder *builder)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
if (!downloader->add_formats (downloader, display, builder))
|
||||
return;
|
||||
|
||||
/* dmabuf_downloaders is NULL-terminated */
|
||||
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
|
||||
{
|
||||
if (display->dmabuf_downloaders[i] == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders));
|
||||
|
||||
display->dmabuf_downloaders[i] = downloader;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* To support a drm format, we must be able to import it into GL
|
||||
* using the relevant EGL extensions, and download it into a memory
|
||||
* texture, possibly doing format conversion with shaders (in GSK).
|
||||
*/
|
||||
void
|
||||
gdk_display_init_dmabuf (GdkDisplay *self)
|
||||
{
|
||||
GdkDmabufFormatsBuilder *builder;
|
||||
|
||||
if (self->dmabuf_formats != NULL)
|
||||
return;
|
||||
|
||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||
"Beginning initialization of dmabuf support");
|
||||
|
||||
builder = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
if (!GDK_DISPLAY_DEBUG_CHECK (self, DMABUF_DISABLE))
|
||||
{
|
||||
gdk_display_prepare_gl (self, NULL);
|
||||
|
||||
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (gdk_display_prepare_gl (self, NULL))
|
||||
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||
"Initialized support for %zu dmabuf formats",
|
||||
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_dmabuf_formats:
|
||||
* @display: a `GdkDisplay`
|
||||
*
|
||||
* Returns the dma-buf formats that are supported on this display.
|
||||
*
|
||||
* GTK may use OpenGL or Vulkan to support some formats.
|
||||
* Calling this function will then initialize them if they aren't yet.
|
||||
*
|
||||
* The formats returned by this function can be used for negotiating
|
||||
* buffer formats with producers such as v4l, pipewire or GStreamer.
|
||||
*
|
||||
* To learn more about dma-bufs, see [class@Gdk.DmabufTextureBuilder].
|
||||
*
|
||||
* Returns: (transfer none): a `GdkDmabufFormats` object
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GdkDmabufFormats *
|
||||
gdk_display_get_dmabuf_formats (GdkDisplay *display)
|
||||
{
|
||||
gdk_display_init_dmabuf (display);
|
||||
|
||||
return display->dmabuf_formats;
|
||||
}
|
||||
|
||||
GdkDebugFlags
|
||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
|
@@ -134,6 +134,10 @@ gboolean gdk_display_get_setting (GdkDisplay *display,
|
||||
const char *name,
|
||||
GValue *value);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkDmabufFormats *
|
||||
gdk_display_get_dmabuf_formats (GdkDisplay *display);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdkkeysprivate.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkdmabufprivate.h"
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
#include <vulkan/vulkan.h>
|
||||
@@ -113,6 +114,16 @@ struct _GdkDisplay
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_no_config_context : 1;
|
||||
guint have_egl_pixel_format_float : 1;
|
||||
guint have_egl_dma_buf_import : 1;
|
||||
guint have_egl_dma_buf_export : 1;
|
||||
|
||||
GdkDmabufFormats *dmabuf_formats;
|
||||
const GdkDmabufDownloader *dmabuf_downloaders[4];
|
||||
|
||||
/* Cached data the EGL dmabuf downloader */
|
||||
gpointer egl_gsk_renderer;
|
||||
GdkDmabufFormats *egl_dmabuf_formats;
|
||||
GdkDmabufFormats *egl_external_formats;
|
||||
};
|
||||
|
||||
struct _GdkDisplayClass
|
||||
@@ -207,6 +218,8 @@ gulong _gdk_display_get_next_serial (GdkDisplay *display
|
||||
void _gdk_display_pause_events (GdkDisplay *display);
|
||||
void _gdk_display_unpause_events (GdkDisplay *display);
|
||||
|
||||
void gdk_display_init_dmabuf (GdkDisplay *self);
|
||||
|
||||
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
|
||||
GError **error);
|
||||
|
||||
|
1080
gdk/gdkdmabuf.c
Normal file
1080
gdk/gdkdmabuf.c
Normal file
File diff suppressed because it is too large
Load Diff
346
gdk/gdkdmabufegl.c
Normal file
346
gdk/gdkdmabufegl.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/* gdkdmabufegl.c
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
|
||||
#include "gdkdmabufprivate.h"
|
||||
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gdkdmabuffourccprivate.h"
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdktexturedownloader.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
/* A dmabuf downloader implementation that downloads buffers via
|
||||
* gsk_renderer_render_texture + GL texture download.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_collect_formats (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *formats,
|
||||
GdkDmabufFormatsBuilder *external)
|
||||
{
|
||||
GdkGLContext *context = gdk_display_get_gl_context (display);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
int num_fourccs;
|
||||
int *fourccs;
|
||||
guint64 *modifiers;
|
||||
unsigned int *external_only;
|
||||
int n_mods;
|
||||
|
||||
if (egl_display == EGL_NO_DISPLAY ||
|
||||
!display->have_egl_dma_buf_import)
|
||||
return FALSE;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
eglQueryDmaBufFormatsEXT (egl_display, 0, NULL, &num_fourccs);
|
||||
fourccs = g_new (int, num_fourccs);
|
||||
eglQueryDmaBufFormatsEXT (egl_display, num_fourccs, fourccs, &num_fourccs);
|
||||
|
||||
n_mods = 80;
|
||||
modifiers = g_new (guint64, n_mods);
|
||||
external_only = g_new (unsigned int, n_mods);
|
||||
|
||||
for (int i = 0; i < num_fourccs; i++)
|
||||
{
|
||||
int num_modifiers;
|
||||
gboolean all_external;
|
||||
|
||||
eglQueryDmaBufModifiersEXT (egl_display,
|
||||
fourccs[i],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&num_modifiers);
|
||||
|
||||
if (num_modifiers > n_mods)
|
||||
{
|
||||
n_mods = num_modifiers;
|
||||
modifiers = g_renew (guint64, modifiers, n_mods);
|
||||
external_only = g_renew (unsigned int, external_only, n_mods);
|
||||
}
|
||||
|
||||
eglQueryDmaBufModifiersEXT (egl_display,
|
||||
fourccs[i],
|
||||
num_modifiers,
|
||||
modifiers,
|
||||
external_only,
|
||||
&num_modifiers);
|
||||
|
||||
all_external = TRUE;
|
||||
|
||||
for (int j = 0; j < num_modifiers; j++)
|
||||
{
|
||||
/* All linear formats we support are already added my the mmap downloader.
|
||||
* We don't add external formats, unless we can use them (via GLES)
|
||||
*/
|
||||
if (modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
|
||||
(!external_only[j] || gdk_gl_context_get_use_es (context)))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"%s%s dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
external_only[j] ? "external " : "",
|
||||
downloader->name,
|
||||
(char *) &fourccs[i],
|
||||
modifiers[j]);
|
||||
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
|
||||
}
|
||||
if (external_only[j])
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
|
||||
else
|
||||
all_external = FALSE;
|
||||
}
|
||||
|
||||
/* Accept implicit modifiers as long as we accept the format at all.
|
||||
* This is a bit of a crapshot, but unfortunately needed for a bunch
|
||||
* of drivers.
|
||||
*
|
||||
* As an extra wrinkle, treat the implicit modifier as 'external only'
|
||||
* if all formats with the same fourcc are 'external only'.
|
||||
*/
|
||||
if (!all_external || gdk_gl_context_get_use_es (context))
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
if (all_external)
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
}
|
||||
|
||||
g_free (modifiers);
|
||||
g_free (external_only);
|
||||
g_free (fourccs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_add_formats (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *builder)
|
||||
{
|
||||
GdkDmabufFormatsBuilder *formats;
|
||||
GdkDmabufFormatsBuilder *external;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
g_assert (display->egl_dmabuf_formats == NULL);
|
||||
g_assert (display->egl_external_formats == NULL);
|
||||
|
||||
formats = gdk_dmabuf_formats_builder_new ();
|
||||
external = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
retval = gdk_dmabuf_egl_downloader_collect_formats (downloader, display, formats, external);
|
||||
|
||||
display->egl_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (formats);
|
||||
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
|
||||
|
||||
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_dmabuf_formats);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_supports (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean premultiplied,
|
||||
GdkMemoryFormat *out_format,
|
||||
GError **error)
|
||||
{
|
||||
if (gdk_dmabuf_formats_contains (display->egl_dmabuf_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
{
|
||||
if (!gdk_dmabuf_get_memory_format (dmabuf->fourcc, premultiplied, out_format))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Falling back to generic ARGB for dmabuf format %.4s",
|
||||
(char *) &dmabuf->fourcc);
|
||||
*out_format = premultiplied ? GDK_MEMORY_R8G8B8A8_PREMULTIPLIED
|
||||
: GDK_MEMORY_R8G8B8A8;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_set_error (error,
|
||||
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
|
||||
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Hack. We don't include gsk/gsk.h here to avoid a build order problem
|
||||
* with the generated header gskenumtypes.h, so we need to hack around
|
||||
* a bit to access the gsk api we need.
|
||||
*/
|
||||
|
||||
typedef gpointer GskRenderer;
|
||||
|
||||
extern GskRenderer * gsk_gl_renderer_new (void);
|
||||
extern gboolean gsk_renderer_realize (GskRenderer *renderer,
|
||||
GdkSurface *surface,
|
||||
GError **error);
|
||||
extern GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture);
|
||||
|
||||
typedef void (* InvokeFunc) (gpointer data);
|
||||
|
||||
typedef struct _InvokeData
|
||||
{
|
||||
volatile int spinlock;
|
||||
InvokeFunc func;
|
||||
gpointer data;
|
||||
} InvokeData;
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_invoke_callback (gpointer data)
|
||||
{
|
||||
InvokeData *invoke = data;
|
||||
GdkGLContext *previous;
|
||||
|
||||
previous = gdk_gl_context_get_current ();
|
||||
|
||||
invoke->func (invoke->data);
|
||||
|
||||
if (previous)
|
||||
gdk_gl_context_make_current (previous);
|
||||
else
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
g_atomic_int_set (&invoke->spinlock, 1);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Run func in the main thread, taking care not to disturb
|
||||
* the current GL context of the caller.
|
||||
*/
|
||||
static void
|
||||
gdk_dmabuf_egl_downloader_run (InvokeFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
InvokeData invoke = { 0, func, data };
|
||||
|
||||
g_main_context_invoke (NULL, gdk_dmabuf_egl_downloader_invoke_callback, &invoke);
|
||||
|
||||
while (g_atomic_int_get (&invoke.spinlock) == 0) ;
|
||||
}
|
||||
|
||||
typedef struct _Download Download;
|
||||
|
||||
struct _Download
|
||||
{
|
||||
GdkDmabufTexture *texture;
|
||||
GdkMemoryFormat format;
|
||||
guchar *data;
|
||||
gsize stride;
|
||||
};
|
||||
|
||||
static GskRenderer *
|
||||
get_gsk_renderer (GdkDisplay *display)
|
||||
{
|
||||
if (!display->egl_gsk_renderer)
|
||||
{
|
||||
GskRenderer *renderer;
|
||||
GError *error = NULL;
|
||||
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
|
||||
if (!gsk_renderer_realize (renderer, NULL, &error))
|
||||
{
|
||||
g_warning ("Failed to realize GL renderer: %s", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (renderer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display->egl_gsk_renderer = renderer;
|
||||
}
|
||||
|
||||
return display->egl_gsk_renderer;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_egl_downloader_do_download (gpointer data)
|
||||
{
|
||||
Download *download = data;
|
||||
GdkDisplay *display;
|
||||
GskRenderer *renderer;
|
||||
GdkTexture *native;
|
||||
GdkTextureDownloader *downloader;
|
||||
|
||||
display = gdk_dmabuf_texture_get_display (download->texture);
|
||||
|
||||
renderer = get_gsk_renderer (display);
|
||||
|
||||
native = gsk_renderer_convert_texture (renderer, GDK_TEXTURE (download->texture));
|
||||
|
||||
downloader = gdk_texture_downloader_new (native);
|
||||
gdk_texture_downloader_set_format (downloader, download->format);
|
||||
gdk_texture_downloader_download_into (downloader, download->data, download->stride);
|
||||
gdk_texture_downloader_free (downloader);
|
||||
|
||||
g_object_unref (native);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_egl_downloader_download (const GdkDmabufDownloader *downloader,
|
||||
GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
Download download;
|
||||
const GdkDmabuf *dmabuf;
|
||||
|
||||
download.texture = GDK_DMABUF_TEXTURE (texture);
|
||||
download.format = format;
|
||||
download.data = data;
|
||||
download.stride = stride;
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
|
||||
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (download.texture), DMABUF,
|
||||
"Using %s for downloading a dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
|
||||
downloader->name, (char *)&dmabuf->fourcc, dmabuf->modifier);
|
||||
|
||||
|
||||
gdk_dmabuf_egl_downloader_run (gdk_dmabuf_egl_downloader_do_download, &download);
|
||||
}
|
||||
|
||||
const GdkDmabufDownloader *
|
||||
gdk_dmabuf_get_egl_downloader (void)
|
||||
{
|
||||
static const GdkDmabufDownloader downloader = {
|
||||
"egl",
|
||||
gdk_dmabuf_egl_downloader_add_formats,
|
||||
gdk_dmabuf_egl_downloader_supports,
|
||||
gdk_dmabuf_egl_downloader_download,
|
||||
};
|
||||
|
||||
return &downloader;
|
||||
}
|
||||
|
||||
#endif /* HAVE_DMABUF && HAVE_EGL */
|
219
gdk/gdkdmabufformats.c
Normal file
219
gdk/gdkdmabufformats.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/* gdkdmabufformats.c
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
|
||||
|
||||
/**
|
||||
* GdkDmabufFormats:
|
||||
*
|
||||
* The `GdkDmabufFormats struct provides information about
|
||||
* supported DMA buffer formats.
|
||||
*
|
||||
* You can query whether a given format is supported with
|
||||
* [method@Gdk.DmabufFormats.contains] and you can iterate
|
||||
* over the list of all supported formats with
|
||||
* [method@Gdk.DmabufFormats.get_n_formats] and
|
||||
* [method@Gdk.DmabufFormats.get_format].
|
||||
*
|
||||
* The list of supported formats is sorted by preference,
|
||||
* with the best formats coming first.
|
||||
*
|
||||
* The list may contains (format, modfier) pairs where the modifier
|
||||
* is `DMA_FORMAT_MOD_INVALID`, indicating that **_implicit modifiers_**
|
||||
* may be used with this format.
|
||||
*
|
||||
* See [class@Gdk.DmabufTextureBuilder] for more information
|
||||
* about DMA buffers.
|
||||
*
|
||||
* Note that DMA buffers only exist on Linux.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
|
||||
struct _GdkDmabufFormats
|
||||
{
|
||||
int ref_count;
|
||||
|
||||
gsize n_formats;
|
||||
GdkDmabufFormat *formats;
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GdkDmabufFormats, gdk_dmabuf_formats, gdk_dmabuf_formats_ref, gdk_dmabuf_formats_unref)
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_formats_ref:
|
||||
* @formats: a `GdkDmabufFormats`
|
||||
*
|
||||
* Increases the reference count of @formats.
|
||||
*
|
||||
* Returns: the passed-in object
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_ref (GdkDmabufFormats *formats)
|
||||
{
|
||||
formats->ref_count++;
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_formats_unref:
|
||||
* @formats: a `GdkDmabufFormats`
|
||||
*
|
||||
* Decreases the reference count of @formats.
|
||||
*
|
||||
* When the reference count reaches zero,
|
||||
* the object is freed.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
void
|
||||
gdk_dmabuf_formats_unref (GdkDmabufFormats *formats)
|
||||
{
|
||||
formats->ref_count--;
|
||||
|
||||
if (formats->ref_count > 0)
|
||||
return;
|
||||
|
||||
g_free (formats->formats);
|
||||
g_free (formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_formats_get_n_formats:
|
||||
* @formats: a `GdkDmabufFormats`
|
||||
*
|
||||
* Returns the number of formats that the @formats object
|
||||
* contains.
|
||||
*
|
||||
* Note that DMA buffers are a Linux concept, so on other
|
||||
* platforms, [method@Gdk.DmabufFormats.get_n_formats] will
|
||||
* always return zero.
|
||||
*
|
||||
* Returns: the number of formats
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
gsize
|
||||
gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats)
|
||||
{
|
||||
return formats->n_formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_formats_get_format:
|
||||
* @formats: a `GdkDmabufFormats`
|
||||
* @idx: the index of the format to return
|
||||
* @fourcc: (out): return location for the format code
|
||||
* @modifier: (out): return location for the format modifier
|
||||
*
|
||||
* Gets the fourcc code and modifier for a format
|
||||
* that is contained in @formats.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
void
|
||||
gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
|
||||
gsize idx,
|
||||
guint32 *fourcc,
|
||||
guint64 *modifier)
|
||||
{
|
||||
GdkDmabufFormat *format;
|
||||
|
||||
g_return_if_fail (idx < formats->n_formats);
|
||||
g_return_if_fail (fourcc != NULL);
|
||||
g_return_if_fail (modifier != NULL);
|
||||
|
||||
format = &formats->formats[idx];
|
||||
|
||||
*fourcc = format->fourcc;
|
||||
*modifier = format->modifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_format_contains:
|
||||
* @formats: a `GdkDmabufFormats`
|
||||
* @fourcc: a format code
|
||||
* @modfier: a format modifier
|
||||
*
|
||||
* Returns whether a given format is contained in @formats.
|
||||
*
|
||||
* Returns: `TRUE` if the format specified by the arguments
|
||||
* is part of @formats
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
||||
guint32 fourcc,
|
||||
guint64 modifier)
|
||||
{
|
||||
for (gsize i = 0; i < formats->n_formats; i++)
|
||||
{
|
||||
GdkDmabufFormat *format = &formats->formats[i];
|
||||
|
||||
if (format->fourcc == fourcc && format->modifier == modifier)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_dmabuf_formats_new:
|
||||
* @formats: the formats
|
||||
* @n_formats: the length of @formats
|
||||
*
|
||||
* Creates a new `GdkDmabufFormats struct for
|
||||
* the given formats.
|
||||
*
|
||||
* The @formats array is expected to be sorted
|
||||
* by preference.
|
||||
*
|
||||
* Returns: (transfer full): the new `GdkDmabufFormats`
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
||||
gsize n_formats)
|
||||
{
|
||||
GdkDmabufFormats *self;
|
||||
|
||||
self = g_new0 (GdkDmabufFormats, 1);
|
||||
|
||||
self->ref_count = 1;
|
||||
self->n_formats = n_formats;
|
||||
self->formats = g_new (GdkDmabufFormat, n_formats);
|
||||
|
||||
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
const GdkDmabufFormat *
|
||||
gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self)
|
||||
{
|
||||
return self->formats;
|
||||
}
|
54
gdk/gdkdmabufformats.h
Normal file
54
gdk/gdkdmabufformats.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* gdkdmabufformats.h
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DMABUF_FORMATS (gdk_dmabuf_formats_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GType gdk_dmabuf_formats_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkDmabufFormats * gdk_dmabuf_formats_ref (GdkDmabufFormats *formats);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_formats_unref (GdkDmabufFormats *formats);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gsize gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats) G_GNUC_PURE;
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
|
||||
gsize idx,
|
||||
guint32 *fourcc,
|
||||
guint64 *modifier);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
|
||||
guint32 fourcc,
|
||||
guint64 modifier) G_GNUC_PURE;
|
||||
|
||||
G_END_DECLS
|
134
gdk/gdkdmabufformatsbuilder.c
Normal file
134
gdk/gdkdmabufformatsbuilder.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* gdkdmabufformats.c
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
|
||||
|
||||
#define GDK_ARRAY_NAME gdk_dmabuf_formats_builder
|
||||
#define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder
|
||||
#define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat
|
||||
#define GDK_ARRAY_BY_VALUE 1
|
||||
#define GDK_ARRAY_PREALLOC 1024
|
||||
#define GDK_ARRAY_NO_MEMSET 1
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
/* NB: We keep duplicates in the list for ease of use. Only when creating the final
|
||||
* GdkDmabufFormats do we actually remove duplicates.
|
||||
*/
|
||||
|
||||
GdkDmabufFormatsBuilder *
|
||||
gdk_dmabuf_formats_builder_new (void)
|
||||
{
|
||||
GdkDmabufFormatsBuilder *result = g_new (GdkDmabufFormatsBuilder, 1);
|
||||
|
||||
gdk_dmabuf_formats_builder_init (result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
gdk_dmabuf_format_compare (gconstpointer data_a,
|
||||
gconstpointer data_b)
|
||||
{
|
||||
const GdkDmabufFormat *a = data_a;
|
||||
const GdkDmabufFormat *b = data_b;
|
||||
|
||||
if (a->fourcc == b->fourcc)
|
||||
return (a->modifier - b->modifier) >> 8 * (sizeof (gint64) - sizeof (gint));
|
||||
else
|
||||
return a->fourcc - b->fourcc;
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_format_equal (gconstpointer data_a,
|
||||
gconstpointer data_b)
|
||||
{
|
||||
const GdkDmabufFormat *a = data_a;
|
||||
const GdkDmabufFormat *b = data_b;
|
||||
|
||||
return a->fourcc == b->fourcc &&
|
||||
a->modifier == b->modifier;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
|
||||
{
|
||||
qsort (gdk_dmabuf_formats_builder_get_data (self),
|
||||
gdk_dmabuf_formats_builder_get_size (self),
|
||||
sizeof (GdkDmabufFormat),
|
||||
gdk_dmabuf_format_compare);
|
||||
}
|
||||
|
||||
/* list must be sorted */
|
||||
static void
|
||||
gdk_dmabuf_formats_builder_remove_duplicates (GdkDmabufFormatsBuilder *self)
|
||||
{
|
||||
gsize i, j;
|
||||
|
||||
for (i = 1, j = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
|
||||
{
|
||||
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i),
|
||||
gdk_dmabuf_formats_builder_get (self, j)))
|
||||
continue;
|
||||
|
||||
j++;
|
||||
if (i != j)
|
||||
*gdk_dmabuf_formats_builder_index (self, j) = *gdk_dmabuf_formats_builder_index (self, i);
|
||||
}
|
||||
}
|
||||
|
||||
GdkDmabufFormats *
|
||||
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
|
||||
{
|
||||
GdkDmabufFormats *formats;
|
||||
|
||||
gdk_dmabuf_formats_builder_sort (self);
|
||||
gdk_dmabuf_formats_builder_remove_duplicates (self);
|
||||
|
||||
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
|
||||
gdk_dmabuf_formats_builder_get_size (self));
|
||||
gdk_dmabuf_formats_builder_clear (self);
|
||||
g_free (self);
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
guint64 modifier)
|
||||
{
|
||||
gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier });
|
||||
}
|
||||
|
||||
void
|
||||
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||
GdkDmabufFormats *formats)
|
||||
{
|
||||
gdk_dmabuf_formats_builder_splice (self,
|
||||
gdk_dmabuf_formats_builder_get_size (self),
|
||||
0,
|
||||
FALSE,
|
||||
gdk_dmabuf_formats_peek_formats (formats),
|
||||
gdk_dmabuf_formats_get_n_formats (formats));
|
||||
}
|
14
gdk/gdkdmabufformatsbuilderprivate.h
Normal file
14
gdk/gdkdmabufformatsbuilderprivate.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkdmabufformats.h"
|
||||
|
||||
typedef struct GdkDmabufFormatsBuilder GdkDmabufFormatsBuilder;
|
||||
|
||||
GdkDmabufFormatsBuilder * gdk_dmabuf_formats_builder_new (void);
|
||||
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
|
||||
|
||||
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
|
||||
guint32 fourcc,
|
||||
guint64 modifier);
|
||||
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
|
||||
GdkDmabufFormats *formats);
|
15
gdk/gdkdmabufformatsprivate.h
Normal file
15
gdk/gdkdmabufformatsprivate.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkdmabufformats.h"
|
||||
|
||||
typedef struct _GdkDmabufFormat GdkDmabufFormat;
|
||||
struct _GdkDmabufFormat
|
||||
{
|
||||
guint32 fourcc;
|
||||
guint64 modifier;
|
||||
};
|
||||
|
||||
GdkDmabufFormats * gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
|
||||
gsize n_formats);
|
||||
|
||||
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);
|
380
gdk/gdkdmabuffourccprivate.h
Normal file
380
gdk/gdkdmabuffourccprivate.h
Normal file
@@ -0,0 +1,380 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <drm_fourcc.h>
|
||||
#endif
|
||||
|
||||
#ifndef fourcc_code
|
||||
#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \
|
||||
((__u32)(c) << 16) | ((__u32)(d) << 24))
|
||||
#endif
|
||||
|
||||
#ifndef DRM_FORMAT_C1
|
||||
#define DRM_FORMAT_C1 fourcc_code('C', '1', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_C2
|
||||
#define DRM_FORMAT_C2 fourcc_code('C', '2', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_C4
|
||||
#define DRM_FORMAT_C4 fourcc_code('C', '4', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_C8
|
||||
#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_D1
|
||||
#define DRM_FORMAT_D1 fourcc_code('D', '1', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_D2
|
||||
#define DRM_FORMAT_D2 fourcc_code('D', '2', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_D4
|
||||
#define DRM_FORMAT_D4 fourcc_code('D', '4', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_D8
|
||||
#define DRM_FORMAT_D8 fourcc_code('D', '8', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R1
|
||||
#define DRM_FORMAT_R1 fourcc_code('R', '1', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R2
|
||||
#define DRM_FORMAT_R2 fourcc_code('R', '2', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R4
|
||||
#define DRM_FORMAT_R4 fourcc_code('R', '4', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R8
|
||||
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R10
|
||||
#define DRM_FORMAT_R10 fourcc_code('R', '1', '0', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R12
|
||||
#define DRM_FORMAT_R12 fourcc_code('R', '1', '2', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_R16
|
||||
#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RG88
|
||||
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_GR88
|
||||
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RG1616
|
||||
#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_GR1616
|
||||
#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGB332
|
||||
#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGR233
|
||||
#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB4444
|
||||
#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR4444
|
||||
#define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBX4444
|
||||
#define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRX4444
|
||||
#define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ARGB4444
|
||||
#define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ABGR4444
|
||||
#define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBA4444
|
||||
#define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRA4444
|
||||
#define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB1555
|
||||
#define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR1555
|
||||
#define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBX5551
|
||||
#define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRX5551
|
||||
#define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ARGB1555
|
||||
#define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ABGR1555
|
||||
#define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBA5551
|
||||
#define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRA5551
|
||||
#define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGB565
|
||||
#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGR565
|
||||
#define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGB888
|
||||
#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGR888
|
||||
#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB8888
|
||||
#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR8888
|
||||
#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBX8888
|
||||
#define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRX8888
|
||||
#define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ARGB8888
|
||||
#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ABGR8888
|
||||
#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBA8888
|
||||
#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRA8888
|
||||
#define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB2101010
|
||||
#define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR2101010
|
||||
#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBX1010102
|
||||
#define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRX1010102
|
||||
#define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ARGB2101010
|
||||
#define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ABGR2101010
|
||||
#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBA1010102
|
||||
#define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRA1010102
|
||||
#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB16161616
|
||||
#define DRM_FORMAT_XRGB16161616 fourcc_code('X', 'R', '4', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR16161616
|
||||
#define DRM_FORMAT_XBGR16161616 fourcc_code('X', 'B', '4', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ARGB16161616
|
||||
#define DRM_FORMAT_ARGB16161616 fourcc_code('A', 'R', '4', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ABGR16161616
|
||||
#define DRM_FORMAT_ABGR16161616 fourcc_code('A', 'B', '4', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB16161616F
|
||||
#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR16161616F
|
||||
#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ARGB16161616F
|
||||
#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_ABGR16161616F
|
||||
#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_AXBXGXRX106106106106
|
||||
#define DRM_FORMAT_AXBXGXRX106106106106 fourcc_code('A', 'B', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUYV
|
||||
#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YVYU
|
||||
#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_UYVY
|
||||
#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_VYUY
|
||||
#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_AYUV
|
||||
#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_AVUY8888
|
||||
#define DRM_FORMAT_AVUY8888 fourcc_code('A', 'V', 'U', 'Y')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XYUV8888
|
||||
#define DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XVUY8888
|
||||
#define DRM_FORMAT_XVUY8888 fourcc_code('X', 'V', 'U', 'Y')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_VUY888
|
||||
#define DRM_FORMAT_VUY888 fourcc_code('V', 'U', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_VUY101010
|
||||
#define DRM_FORMAT_VUY101010 fourcc_code('V', 'U', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y210
|
||||
#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y212
|
||||
#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y216
|
||||
#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y410
|
||||
#define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y412
|
||||
#define DRM_FORMAT_Y412 fourcc_code('Y', '4', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y416
|
||||
#define DRM_FORMAT_Y416 fourcc_code('Y', '4', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XVYU2101010
|
||||
#define DRM_FORMAT_XVYU2101010 fourcc_code('X', 'V', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XVYU12_16161616
|
||||
#define DRM_FORMAT_XVYU12_16161616 fourcc_code('X', 'V', '3', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XVYU16161616
|
||||
#define DRM_FORMAT_XVYU16161616 fourcc_code('X', 'V', '4', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y0L0
|
||||
#define DRM_FORMAT_Y0L0 fourcc_code('Y', '0', 'L', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_X0L0
|
||||
#define DRM_FORMAT_X0L0 fourcc_code('X', '0', 'L', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Y0L2
|
||||
#define DRM_FORMAT_Y0L2 fourcc_code('Y', '0', 'L', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_X0L2
|
||||
#define DRM_FORMAT_X0L2 fourcc_code('X', '0', 'L', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV420_8BIT
|
||||
#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV420_10BIT
|
||||
#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XRGB8888_A8
|
||||
#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_XBGR8888_A8
|
||||
#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGBX8888_A8
|
||||
#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGRX8888_A8
|
||||
#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGB888_A8
|
||||
#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGR888_A8
|
||||
#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_RGB565_A8
|
||||
#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_BGR565_A8
|
||||
#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV12
|
||||
#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV21
|
||||
#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV16
|
||||
#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV61
|
||||
#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV24
|
||||
#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV42
|
||||
#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_NV15
|
||||
#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_P210
|
||||
#define DRM_FORMAT_P210 fourcc_code('P', '2', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_P010
|
||||
#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_P012
|
||||
#define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_P016
|
||||
#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_P030
|
||||
#define DRM_FORMAT_P030 fourcc_code('P', '0', '3', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Q410
|
||||
#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_Q401
|
||||
#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV410
|
||||
#define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YVU410
|
||||
#define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV411
|
||||
#define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YVU411
|
||||
#define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV420
|
||||
#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YVU420
|
||||
#define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV422
|
||||
#define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YVU422
|
||||
#define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YUV444
|
||||
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4')
|
||||
#endif
|
||||
#ifndef DRM_FORMAT_YVU444
|
||||
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4')
|
||||
#endif
|
69
gdk/gdkdmabufprivate.h
Normal file
69
gdk/gdkdmabufprivate.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
|
||||
#define GDK_DMABUF_MAX_PLANES 4
|
||||
|
||||
typedef struct _GdkDmabuf GdkDmabuf;
|
||||
typedef struct _GdkDmabufDownloader GdkDmabufDownloader;
|
||||
|
||||
struct _GdkDmabuf
|
||||
{
|
||||
guint32 fourcc;
|
||||
guint64 modifier;
|
||||
unsigned int n_planes;
|
||||
struct {
|
||||
int fd;
|
||||
unsigned int stride;
|
||||
unsigned int offset;
|
||||
} planes[GDK_DMABUF_MAX_PLANES];
|
||||
};
|
||||
|
||||
struct _GdkDmabufDownloader
|
||||
{
|
||||
const char *name;
|
||||
gboolean (* add_formats) (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *builder);
|
||||
gboolean (* supports) (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean premultiplied,
|
||||
GdkMemoryFormat *out_format,
|
||||
GError **error);
|
||||
void (* download) (const GdkDmabufDownloader *downloader,
|
||||
GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
guchar *data,
|
||||
gsize stride);
|
||||
};
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
|
||||
const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST;
|
||||
const GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (void) G_GNUC_CONST;
|
||||
|
||||
int gdk_dmabuf_ioctl (int fd,
|
||||
unsigned long request,
|
||||
void *arg);
|
||||
gboolean gdk_dmabuf_import_sync_file (int dmabuf_fd,
|
||||
guint32 flags,
|
||||
int sync_file_fd);
|
||||
int gdk_dmabuf_export_sync_file (int dmabuf_fd,
|
||||
guint32 flags);
|
||||
|
||||
gboolean gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
gsize width,
|
||||
gsize height,
|
||||
const GdkDmabuf *src,
|
||||
GError **error);
|
||||
|
||||
gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf);
|
||||
|
||||
gboolean gdk_dmabuf_get_memory_format (guint32 fourcc,
|
||||
gboolean premultiplied,
|
||||
GdkMemoryFormat *out_format);
|
||||
gboolean gdk_dmabuf_get_fourcc (GdkMemoryFormat format,
|
||||
guint32 *out_fourcc);
|
||||
|
||||
#endif
|
214
gdk/gdkdmabuftexture.c
Normal file
214
gdk/gdkdmabuftexture.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* gdkdmabuftexture.c
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
#include "gdkdmabuffourccprivate.h"
|
||||
#include "gdkdmabufprivate.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include <gdk/gdkglcontext.h>
|
||||
#include <gdk/gdkgltexturebuilder.h>
|
||||
#include <gdk/gdktexturedownloader.h>
|
||||
|
||||
/**
|
||||
* GdkDmabufTexture:
|
||||
*
|
||||
* A `GdkTexture` representing a dma-buf object.
|
||||
*
|
||||
* To create a `GdkDmabufTexture`, use the auxiliary
|
||||
* [class@Gdk.DmabufTextureBuilder] object.
|
||||
*
|
||||
* Dma-buf textures can only be created on Linux.
|
||||
*/
|
||||
|
||||
struct _GdkDmabufTexture
|
||||
{
|
||||
GdkTexture parent_instance;
|
||||
|
||||
GdkDisplay *display;
|
||||
const GdkDmabufDownloader *downloader;
|
||||
|
||||
GdkDmabuf dmabuf;
|
||||
|
||||
GDestroyNotify destroy;
|
||||
gpointer data;
|
||||
};
|
||||
|
||||
struct _GdkDmabufTextureClass
|
||||
{
|
||||
GdkTextureClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error)
|
||||
|
||||
G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE)
|
||||
|
||||
static void
|
||||
gdk_dmabuf_texture_init (GdkDmabufTexture *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_texture_dispose (GObject *object)
|
||||
{
|
||||
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (object);
|
||||
|
||||
if (self->destroy)
|
||||
self->destroy (self->data);
|
||||
|
||||
g_clear_object (&self->display);
|
||||
|
||||
G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_texture_download (GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
|
||||
|
||||
self->downloader->download (self->downloader,
|
||||
texture,
|
||||
format,
|
||||
data,
|
||||
stride);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass)
|
||||
{
|
||||
GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
texture_class->download = gdk_dmabuf_texture_download;
|
||||
|
||||
gobject_class->dispose = gdk_dmabuf_texture_dispose;
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
gdk_dmabuf_texture_get_display (GdkDmabufTexture *self)
|
||||
{
|
||||
return self->display;
|
||||
}
|
||||
|
||||
const GdkDmabuf *
|
||||
gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self)
|
||||
{
|
||||
return &self->dmabuf;
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_DMABUF
|
||||
GdkDmabufTexture *self;
|
||||
GdkTexture *update_texture;
|
||||
GdkDisplay *display;
|
||||
GdkDmabuf dmabuf;
|
||||
GdkMemoryFormat format;
|
||||
GError *local_error = NULL;
|
||||
int width, height;
|
||||
gsize i;
|
||||
|
||||
display = gdk_dmabuf_texture_builder_get_display (builder);
|
||||
width = gdk_dmabuf_texture_builder_get_width (builder);
|
||||
height = gdk_dmabuf_texture_builder_get_height (builder);
|
||||
|
||||
if (!gdk_dmabuf_sanitize (&dmabuf,
|
||||
width,
|
||||
height,
|
||||
gdk_dmabuf_texture_builder_get_dmabuf (builder),
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
gdk_display_init_dmabuf (display);
|
||||
|
||||
for (i = 0; display->dmabuf_downloaders[i] != NULL; i++)
|
||||
{
|
||||
if (local_error && g_error_matches (local_error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT))
|
||||
g_clear_error (&local_error);
|
||||
|
||||
if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i],
|
||||
display,
|
||||
&dmabuf,
|
||||
gdk_dmabuf_texture_builder_get_premultiplied (builder),
|
||||
&format,
|
||||
local_error ? NULL : &local_error))
|
||||
break;
|
||||
}
|
||||
|
||||
if (display->dmabuf_downloaders[i] == NULL)
|
||||
{
|
||||
g_propagate_error (error, local_error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u, downloader %s",
|
||||
(char *) &dmabuf.fourcc, dmabuf.modifier,
|
||||
gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "",
|
||||
dmabuf.n_planes,
|
||||
format,
|
||||
display->dmabuf_downloaders[i]->name);
|
||||
|
||||
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
|
||||
"width", width,
|
||||
"height", height,
|
||||
NULL);
|
||||
|
||||
GDK_TEXTURE (self)->format = format;
|
||||
g_set_object (&self->display, display);
|
||||
self->downloader = display->dmabuf_downloaders[i];
|
||||
self->dmabuf = dmabuf;
|
||||
self->destroy = destroy;
|
||||
self->data = data;
|
||||
|
||||
update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder);
|
||||
if (update_texture)
|
||||
{
|
||||
cairo_region_t *update_region = gdk_dmabuf_texture_builder_get_update_region (builder);
|
||||
if (update_region)
|
||||
{
|
||||
update_region = cairo_region_copy (update_region);
|
||||
cairo_region_intersect_rectangle (update_region,
|
||||
&(cairo_rectangle_int_t) {
|
||||
0, 0,
|
||||
update_texture->width, update_texture->height
|
||||
});
|
||||
gdk_texture_set_diff (GDK_TEXTURE (self), update_texture, update_region);
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_TEXTURE (self);
|
||||
|
||||
#else /* !HAVE_DMABUF */
|
||||
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
|
||||
"dmabuf support disabled at compile-time.");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
48
gdk/gdkdmabuftexture.h
Normal file
48
gdk/gdkdmabuftexture.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* gdkdmabuftexture.h
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdktexture.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DMABUF_TEXTURE (gdk_dmabuf_texture_get_type ())
|
||||
|
||||
#define GDK_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_DMABUF_TEXTURE, GdkDmabufTexture))
|
||||
#define GDK_IS_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_DMABUF_TEXTURE))
|
||||
|
||||
#define GDK_DMABUF_ERROR (gdk_dmabuf_error_quark ())
|
||||
|
||||
typedef struct _GdkDmabufTexture GdkDmabufTexture;
|
||||
typedef struct _GdkDmabufTextureClass GdkDmabufTextureClass;
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GType gdk_dmabuf_texture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GQuark gdk_dmabuf_error_quark (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDmabufTexture, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
1006
gdk/gdkdmabuftexturebuilder.c
Normal file
1006
gdk/gdkdmabuftexturebuilder.c
Normal file
File diff suppressed because it is too large
Load Diff
122
gdk/gdkdmabuftexturebuilder.h
Normal file
122
gdk/gdkdmabuftexturebuilder.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright © 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DMABUF_TEXTURE_BUILDER (gdk_dmabuf_texture_builder_get_type ())
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GDK_DECLARE_INTERNAL_TYPE (GdkDmabufTextureBuilder, gdk_dmabuf_texture_builder, GDK, DMABUF_TEXTURE_BUILDER, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkDmabufTextureBuilder *gdk_dmabuf_texture_builder_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkDisplay * gdk_dmabuf_texture_builder_get_display (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
|
||||
GdkDisplay *display);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
unsigned int gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_width (GdkDmabufTextureBuilder *self,
|
||||
unsigned int width);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
unsigned int gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_height (GdkDmabufTextureBuilder *self,
|
||||
unsigned int height);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
guint32 gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self,
|
||||
guint32 fourcc);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
guint64 gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
|
||||
guint64 modifier);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_texture_builder_get_premultiplied (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
|
||||
gboolean premultiplied);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
unsigned int gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
|
||||
unsigned int n_planes);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
int gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
|
||||
unsigned int plane) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
|
||||
unsigned int plane,
|
||||
int fd);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
unsigned int gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
|
||||
unsigned int plane) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
|
||||
unsigned int plane,
|
||||
unsigned int stride);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
unsigned int gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
|
||||
unsigned int plane) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
|
||||
unsigned int plane,
|
||||
unsigned int offset);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkTexture * gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_update_texture (GdkDmabufTextureBuilder *self,
|
||||
GdkTexture *texture);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
cairo_region_t * gdk_dmabuf_texture_builder_get_update_region (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self,
|
||||
cairo_region_t *region);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkTexture * gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
21
gdk/gdkdmabuftextureprivate.h
Normal file
21
gdk/gdkdmabuftextureprivate.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkdmabuftexture.h"
|
||||
|
||||
#include "gdkdmabuftexturebuilder.h"
|
||||
#include "gdkdmabufprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder);
|
||||
|
||||
GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
GDestroyNotify destroy,
|
||||
gpointer data,
|
||||
GError **error);
|
||||
|
||||
GdkDisplay * gdk_dmabuf_texture_get_display (GdkDmabufTexture *self);
|
||||
const GdkDmabuf * gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -68,6 +68,12 @@ gdk_draw_context_default_surface_resized (GdkDrawContext *context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_draw_context_default_empty_frame (GdkDrawContext *context)
|
||||
{
|
||||
g_warning ("FIXME: Implement");
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_draw_context_dispose (GObject *gobject)
|
||||
{
|
||||
@@ -161,6 +167,7 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
||||
gobject_class->dispose = gdk_draw_context_dispose;
|
||||
|
||||
klass->surface_resized = gdk_draw_context_default_surface_resized;
|
||||
klass->empty_frame = gdk_draw_context_default_empty_frame;
|
||||
|
||||
/**
|
||||
* GdkDrawContext:display: (attributes org.gtk.Property.get=gdk_draw_context_get_display)
|
||||
@@ -470,3 +477,17 @@ gdk_draw_context_get_frame_region (GdkDrawContext *context)
|
||||
|
||||
return priv->frame_region;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_draw_context_empty_frame (GdkDrawContext *context)
|
||||
{
|
||||
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
|
||||
g_return_if_fail (priv->surface != NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (priv->surface))
|
||||
return;
|
||||
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (context)->empty_frame (context);
|
||||
}
|
||||
|
@@ -45,6 +45,7 @@ void gdk_draw_context_begin_frame (GdkDrawContext
|
||||
const cairo_region_t *region);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_draw_context_end_frame (GdkDrawContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_draw_context_is_in_frame (GdkDrawContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
@@ -46,6 +46,7 @@ struct _GdkDrawContextClass
|
||||
cairo_region_t *update_area);
|
||||
void (* end_frame) (GdkDrawContext *context,
|
||||
cairo_region_t *painted);
|
||||
void (* empty_frame) (GdkDrawContext *context);
|
||||
void (* surface_resized) (GdkDrawContext *context);
|
||||
};
|
||||
|
||||
@@ -54,5 +55,9 @@ void gdk_draw_context_surface_resized (GdkDrawContext
|
||||
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
|
||||
GdkMemoryDepth depth,
|
||||
const cairo_region_t *region);
|
||||
|
||||
void gdk_draw_context_empty_frame (GdkDrawContext *context);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -684,7 +684,7 @@ gdk_drop_read_async (GdkDrop *self,
|
||||
* gdk_drop_read_finish:
|
||||
* @self: a `GdkDrop`
|
||||
* @result: a `GAsyncResult`
|
||||
* @out_mime_type: (out) (type utf8): return location for the used mime type
|
||||
* @out_mime_type: (out) (type utf8) (transfer none): return location for the used mime type
|
||||
* @error: (nullable): location to store error information on failure
|
||||
*
|
||||
* Finishes an async drop read operation.
|
||||
|
@@ -114,6 +114,15 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* GDK_NO_MODIFIER_MASK:
|
||||
*
|
||||
* No modifier.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
GDK_NO_MODIFIER_MASK GDK_AVAILABLE_ENUMERATOR_IN_4_14 = 0,
|
||||
|
||||
GDK_SHIFT_MASK = 1 << 0,
|
||||
GDK_LOCK_MASK = 1 << 1,
|
||||
GDK_CONTROL_MASK = 1 << 2,
|
||||
@@ -142,6 +151,22 @@ typedef enum
|
||||
GDK_BUTTON4_MASK|GDK_BUTTON5_MASK)
|
||||
|
||||
|
||||
/**
|
||||
* GdkDmabufError:
|
||||
* @GDK_DMABUF_ERROR_NOT_AVAILABLE: Dmabuf support is not available, because the OS
|
||||
* is not Linux, or it was explicitly disabled at compile- or runtime
|
||||
* @GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT: The requested format is not supported
|
||||
* @GDK_DMABUF_ERROR_CREATION_FAILED: GTK failed to create the resource for other
|
||||
* reasons
|
||||
*
|
||||
* Error enumeration for `GdkDmabufTexture`.
|
||||
*/
|
||||
typedef enum {
|
||||
GDK_DMABUF_ERROR_NOT_AVAILABLE,
|
||||
GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
|
||||
GDK_DMABUF_ERROR_CREATION_FAILED,
|
||||
} GdkDmabufError;
|
||||
|
||||
/**
|
||||
* GdkGLError:
|
||||
* @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available
|
||||
@@ -282,10 +307,16 @@ typedef enum
|
||||
* The color values are premultiplied with the alpha value.
|
||||
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
|
||||
* The color values are premultiplied with the alpha value.
|
||||
* @GDK_MEMORY_A8B8G8R8_PREMULTIPLIED: 4 bytes; for alpha, blue, green, red,
|
||||
* The color values are premultiplied with the alpha value. Since 4.14
|
||||
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
|
||||
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
|
||||
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
|
||||
* @GDK_MEMORY_A8B8G8R8: 4 bytes; for alpha, blue, green, red.
|
||||
* @GDK_MEMORY_B8G8R8X8: 4 bytes; for blue, green, red, unused. Since 4.14
|
||||
* @GDK_MEMORY_X8R8G8B8: 4 bytes; for unused, red, green, blue. Since 4.14
|
||||
* @GDK_MEMORY_R8G8B8X8: 4 bytes; for red, green, blue, unused. Since 4.14
|
||||
* @GDK_MEMORY_X8B8G8R8: 4 bytes; for unused, blue, green, red. Since 4.14
|
||||
* @GDK_MEMORY_R8G8B8: 3 bytes; for red, green, blue. The data is opaque.
|
||||
* @GDK_MEMORY_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
|
||||
* @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since: 4.6
|
||||
@@ -366,6 +397,11 @@ typedef enum {
|
||||
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A16_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A32_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
|
||||
GDK_MEMORY_A8B8G8R8_PREMULTIPLIED GDK_AVAILABLE_ENUMERATOR_IN_4_14,
|
||||
GDK_MEMORY_B8G8R8X8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
|
||||
GDK_MEMORY_X8R8G8B8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
|
||||
GDK_MEMORY_R8G8B8X8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
|
||||
GDK_MEMORY_X8B8G8R8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
|
||||
|
||||
GDK_MEMORY_N_FORMATS
|
||||
} GdkMemoryFormat;
|
||||
|
@@ -402,7 +402,6 @@ gdk_event_alloc (GdkEventType event_type,
|
||||
|
||||
GdkEvent *event = (GdkEvent *) g_type_create_instance (gdk_event_types[event_type]);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (EVENTS))
|
||||
{
|
||||
char *str = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event_type);
|
||||
@@ -410,7 +409,6 @@ gdk_event_alloc (GdkEventType event_type,
|
||||
g_type_name (gdk_event_types[event_type]), str);
|
||||
g_free (str);
|
||||
}
|
||||
#endif
|
||||
|
||||
event->event_type = event_type;
|
||||
event->surface = surface != NULL ? g_object_ref (surface) : NULL;
|
||||
|
@@ -346,19 +346,15 @@ gdk_frame_clock_end_updating (GdkFrameClock *frame_clock)
|
||||
GDK_FRAME_CLOCK_GET_CLASS (frame_clock)->end_updating (frame_clock);
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
_gdk_frame_clock_freeze (GdkFrameClock *clock)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
|
||||
|
||||
GDK_FRAME_CLOCK_GET_CLASS (clock)->freeze (clock);
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
_gdk_frame_clock_thaw (GdkFrameClock *clock)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
|
||||
|
||||
GDK_FRAME_CLOCK_GET_CLASS (clock)->thaw (clock);
|
||||
}
|
||||
|
||||
@@ -390,6 +386,12 @@ _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
|
||||
_gdk_frame_clock_freeze (clock);
|
||||
}
|
||||
|
||||
static inline gint64
|
||||
_gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
|
||||
{
|
||||
return frame_clock->priv->frame_counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_frame_clock_get_frame_counter:
|
||||
* @frame_clock: a `GdkFrameClock`
|
||||
@@ -404,13 +406,15 @@ _gdk_frame_clock_uninhibit_freeze (GdkFrameClock *clock)
|
||||
gint64
|
||||
gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
|
||||
{
|
||||
GdkFrameClockPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (frame_clock), 0);
|
||||
|
||||
priv = frame_clock->priv;
|
||||
return _gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
}
|
||||
|
||||
return priv->frame_counter;
|
||||
static inline gint64
|
||||
_gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
|
||||
{
|
||||
return frame_clock->priv->frame_counter + 1 - frame_clock->priv->n_timings;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -433,13 +437,9 @@ gdk_frame_clock_get_frame_counter (GdkFrameClock *frame_clock)
|
||||
gint64
|
||||
gdk_frame_clock_get_history_start (GdkFrameClock *frame_clock)
|
||||
{
|
||||
GdkFrameClockPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (frame_clock), 0);
|
||||
|
||||
priv = frame_clock->priv;
|
||||
|
||||
return priv->frame_counter + 1 - priv->n_timings;
|
||||
return _gdk_frame_clock_get_history_start (frame_clock);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -470,6 +470,24 @@ _gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
|
||||
priv->timings[priv->current] = _gdk_frame_timings_new (priv->frame_counter);
|
||||
}
|
||||
|
||||
static inline GdkFrameTimings *
|
||||
_gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
|
||||
gint64 frame_counter)
|
||||
{
|
||||
GdkFrameClockPrivate *priv = frame_clock->priv;
|
||||
int pos;
|
||||
|
||||
if (frame_counter > priv->frame_counter)
|
||||
return NULL;
|
||||
|
||||
if (frame_counter <= priv->frame_counter - priv->n_timings)
|
||||
return NULL;
|
||||
|
||||
pos = (priv->current - (priv->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
|
||||
|
||||
return priv->timings[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_frame_clock_get_timings:
|
||||
* @frame_clock: a `GdkFrameClock`
|
||||
@@ -490,22 +508,9 @@ GdkFrameTimings *
|
||||
gdk_frame_clock_get_timings (GdkFrameClock *frame_clock,
|
||||
gint64 frame_counter)
|
||||
{
|
||||
GdkFrameClockPrivate *priv;
|
||||
int pos;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (frame_clock), NULL);
|
||||
|
||||
priv = frame_clock->priv;
|
||||
|
||||
if (frame_counter > priv->frame_counter)
|
||||
return NULL;
|
||||
|
||||
if (frame_counter <= priv->frame_counter - priv->n_timings)
|
||||
return NULL;
|
||||
|
||||
pos = (priv->current - (priv->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
|
||||
|
||||
return priv->timings[pos];
|
||||
return _gdk_frame_clock_get_timings (frame_clock, frame_counter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,11 +533,9 @@ gdk_frame_clock_get_current_timings (GdkFrameClock *frame_clock)
|
||||
|
||||
priv = frame_clock->priv;
|
||||
|
||||
return gdk_frame_clock_get_timings (frame_clock, priv->frame_counter);
|
||||
return _gdk_frame_clock_get_timings (frame_clock, priv->frame_counter);
|
||||
}
|
||||
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
void
|
||||
_gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
GdkFrameTimings *timings)
|
||||
@@ -541,8 +544,8 @@ _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
|
||||
gint64 previous_frame_time = 0;
|
||||
gint64 previous_smoothed_frame_time = 0;
|
||||
GdkFrameTimings *previous_timings = gdk_frame_clock_get_timings (clock,
|
||||
timings->frame_counter - 1);
|
||||
GdkFrameTimings *previous_timings = _gdk_frame_clock_get_timings (clock,
|
||||
timings->frame_counter - 1);
|
||||
|
||||
if (previous_timings != NULL)
|
||||
{
|
||||
@@ -579,7 +582,6 @@ _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
g_message ("%s", str->str);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
#define DEFAULT_REFRESH_INTERVAL 16667 /* 16.7ms (1/60th second) */
|
||||
#define MAX_HISTORY_AGE 150000 /* 150ms */
|
||||
@@ -614,11 +616,11 @@ gdk_frame_clock_get_refresh_info (GdkFrameClock *frame_clock,
|
||||
|
||||
g_return_if_fail (GDK_IS_FRAME_CLOCK (frame_clock));
|
||||
|
||||
frame_counter = gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
frame_counter = _gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
GdkFrameTimings *timings = gdk_frame_clock_get_timings (frame_clock, frame_counter);
|
||||
GdkFrameTimings *timings = _gdk_frame_clock_get_timings (frame_clock, frame_counter);
|
||||
gint64 presentation_time;
|
||||
gint64 refresh_interval;
|
||||
|
||||
@@ -730,15 +732,15 @@ guess_refresh_interval (GdkFrameClock *frame_clock)
|
||||
|
||||
interval = G_MAXINT64;
|
||||
|
||||
for (i = gdk_frame_clock_get_history_start (frame_clock);
|
||||
i < gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
for (i = _gdk_frame_clock_get_history_start (frame_clock);
|
||||
i < _gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
i++)
|
||||
{
|
||||
GdkFrameTimings *t, *before;
|
||||
gint64 ts, before_ts;
|
||||
|
||||
t = gdk_frame_clock_get_timings (frame_clock, i);
|
||||
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
|
||||
t = _gdk_frame_clock_get_timings (frame_clock, i);
|
||||
before = _gdk_frame_clock_get_timings (frame_clock, i - 1);
|
||||
if (t == NULL || before == NULL)
|
||||
continue;
|
||||
|
||||
@@ -773,12 +775,12 @@ gdk_frame_clock_get_fps (GdkFrameClock *frame_clock)
|
||||
gint64 start_timestamp, end_timestamp;
|
||||
gint64 interval;
|
||||
|
||||
start_counter = gdk_frame_clock_get_history_start (frame_clock);
|
||||
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
|
||||
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
|
||||
start_counter = _gdk_frame_clock_get_history_start (frame_clock);
|
||||
end_counter = _gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
start = _gdk_frame_clock_get_timings (frame_clock, start_counter);
|
||||
for (end = _gdk_frame_clock_get_timings (frame_clock, end_counter);
|
||||
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
|
||||
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
|
||||
end = _gdk_frame_clock_get_timings (frame_clock, end_counter))
|
||||
end_counter--;
|
||||
if (end_counter - start_counter < 4)
|
||||
return 0.0;
|
||||
|
@@ -585,14 +585,15 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
|
||||
{
|
||||
int iter;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
|
||||
timings->layout_start_time = g_get_monotonic_time ();
|
||||
{
|
||||
if (timings)
|
||||
timings->layout_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
/* We loop in the layout phase, because we don't want to progress
|
||||
@@ -616,14 +617,15 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
||||
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
|
||||
timings->paint_start_time = g_get_monotonic_time ();
|
||||
{
|
||||
if (timings)
|
||||
timings->paint_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
|
||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
|
||||
@@ -643,13 +645,11 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
*/
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (timings)
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS:
|
||||
|
@@ -95,11 +95,9 @@ struct _GdkFrameTimings
|
||||
gint64 refresh_interval;
|
||||
gint64 predicted_presentation_time;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gint64 layout_start_time;
|
||||
gint64 paint_start_time;
|
||||
gint64 frame_end_time;
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
guint complete : 1;
|
||||
guint slept_before : 1;
|
||||
|
@@ -83,6 +83,7 @@
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdkglversionprivate.h"
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
|
||||
#include "gdkprivate.h"
|
||||
|
||||
@@ -95,20 +96,30 @@
|
||||
#include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <drm_fourcc.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
|
||||
|
||||
typedef struct {
|
||||
typedef struct _GdkGLContextPrivate GdkGLContextPrivate;
|
||||
|
||||
struct _GdkGLContextPrivate
|
||||
{
|
||||
GdkGLVersion required;
|
||||
GdkGLVersion gl_version;
|
||||
|
||||
GdkGLMemoryFlags memory_flags[GDK_MEMORY_N_FORMATS];
|
||||
|
||||
guint has_khr_debug : 1;
|
||||
guint use_khr_debug : 1;
|
||||
guint has_half_float : 1;
|
||||
guint has_sync : 1;
|
||||
guint has_unpack_subimage : 1;
|
||||
guint has_debug_output : 1;
|
||||
guint has_bgra : 1;
|
||||
guint extensions_checked : 1;
|
||||
guint debug_enabled : 1;
|
||||
guint forward_compatible : 1;
|
||||
@@ -123,7 +134,7 @@ typedef struct {
|
||||
EGLContext egl_context;
|
||||
EGLBoolean (*eglSwapBuffersWithDamage) (EGLDisplay, EGLSurface, const EGLint *, EGLint);
|
||||
#endif
|
||||
} GdkGLContextPrivate;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@@ -345,6 +356,7 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||
api == GDK_GL_API_GLES ? "yes" : "no");
|
||||
|
||||
supported_versions = gdk_gl_versions_get_for_api (api);
|
||||
ctx = EGL_NO_CONTEXT;
|
||||
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
|
||||
{
|
||||
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
|
||||
@@ -354,11 +366,11 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||
egl_config,
|
||||
share ? share_priv->egl_context : EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
if (ctx != NULL)
|
||||
if (ctx != EGL_NO_CONTEXT)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx == NULL)
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
return 0;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
|
||||
@@ -383,17 +395,24 @@ gdk_gl_context_realize_egl (GdkGLContext *context,
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
GdkDebugFlags flags;
|
||||
GdkGLAPI api, preferred_api;
|
||||
gboolean prefer_legacy;
|
||||
|
||||
flags = gdk_display_get_debug_flags(display);
|
||||
|
||||
if (share && gdk_gl_context_is_api_allowed (context,
|
||||
gdk_gl_context_get_api (share),
|
||||
NULL))
|
||||
preferred_api = gdk_gl_context_get_api (share);
|
||||
else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
|
||||
else if ((flags & GDK_DEBUG_GL_PREFER_GL) != 0 &&
|
||||
gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
|
||||
preferred_api = GDK_GL_API_GL;
|
||||
else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, NULL))
|
||||
preferred_api = GDK_GL_API_GLES;
|
||||
else if ((flags & GDK_DEBUG_GL_PREFER_GL) == 0 &&
|
||||
gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
|
||||
preferred_api = GDK_GL_API_GL;
|
||||
else
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
@@ -402,8 +421,7 @@ gdk_gl_context_realize_egl (GdkGLContext *context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
prefer_legacy = (gdk_display_get_debug_flags(display) & GDK_DEBUG_GL_LEGACY) ||
|
||||
(share != NULL && gdk_gl_context_is_legacy (share));
|
||||
prefer_legacy = share != NULL && gdk_gl_context_is_legacy (share);
|
||||
|
||||
if (preferred_api == GDK_GL_API_GL)
|
||||
{
|
||||
@@ -1271,18 +1289,38 @@ gdk_gl_context_is_api_allowed (GdkGLContext *self,
|
||||
GError **error)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
GdkDebugFlags flags;
|
||||
GdkGLAPI allowed_apis;
|
||||
|
||||
if (gdk_display_get_debug_flags (gdk_gl_context_get_display (self)) & GDK_DEBUG_GL_GLES)
|
||||
allowed_apis = priv->allowed_apis;
|
||||
|
||||
flags = gdk_display_get_debug_flags (gdk_gl_context_get_display (self));
|
||||
|
||||
if (flags & GDK_DEBUG_GL_DISABLE_GLES)
|
||||
{
|
||||
if (!(api & GDK_GL_API_GLES))
|
||||
if (api == GDK_GL_API_GLES)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Anything but OpenGL ES disabled via GDK_DEBUG"));
|
||||
_("OpenGL ES disabled via GDK_DEBUG"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
allowed_apis &= ~GDK_GL_API_GLES;
|
||||
}
|
||||
|
||||
if (priv->allowed_apis & api)
|
||||
if (flags & GDK_DEBUG_GL_DISABLE_GL)
|
||||
{
|
||||
if (api == GDK_GL_API_GL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("OpenGL disabled via GDK_DEBUG"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
allowed_apis &= ~GDK_GL_API_GL;
|
||||
}
|
||||
|
||||
if (allowed_apis & api)
|
||||
return TRUE;
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
@@ -1491,6 +1529,132 @@ gdk_gl_context_realize (GdkGLContext *context,
|
||||
return priv->api;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_context_init_memory_flags (GdkGLContext *self)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
gsize i;
|
||||
|
||||
if (!gdk_gl_context_get_use_es (self))
|
||||
{
|
||||
for (i = 0; i < G_N_ELEMENTS (priv->memory_flags); i++)
|
||||
{
|
||||
priv->memory_flags[i] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* GLES 2.0 spec, tables 3.2 and 3.3 */
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
#if 0
|
||||
/* GLES2 can do these, but GTK can't */
|
||||
priv->memory_flags[GDK_MEMORY_A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8] = GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
#endif
|
||||
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
{
|
||||
/* GLES 3.0.6 spec, table 3.13 */
|
||||
priv->memory_flags[GDK_MEMORY_G8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_USABLE;
|
||||
|
||||
/* no changes in GLES 3.1 spec, table 8.13 */
|
||||
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
{
|
||||
/* GLES 3.2 spec, table 8.10 */
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (epoxy_has_gl_extension ("GL_OES_rgb8_rgba8"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
priv->memory_flags[GDK_MEMORY_R8G8B8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_EXT_abgr"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
priv->memory_flags[GDK_MEMORY_X8B8G8R8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8A8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
priv->memory_flags[GDK_MEMORY_B8G8R8X8] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
|
||||
/* Technically, those extensions are supported on GLES2.
|
||||
* However, GTK uses the wrong format/type pairs with them, so we don't enable them.
|
||||
*/
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
{
|
||||
if (epoxy_has_gl_extension ("GL_EXT_texture_norm16"))
|
||||
{
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16A16_PREMULTIPLIED] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_G16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_A16] |= GDK_GL_FORMAT_USABLE | GDK_GL_FORMAT_RENDERABLE | GDK_GL_FORMAT_FILTERABLE;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_half_float"))
|
||||
{
|
||||
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_half_float"))
|
||||
flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_half_float_linear"))
|
||||
flags |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16A16_FLOAT] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R16G16B16_FLOAT] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_A16_FLOAT] |= flags;
|
||||
}
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_float"))
|
||||
{
|
||||
GdkGLMemoryFlags flags = GDK_GL_FORMAT_USABLE;
|
||||
if (epoxy_has_gl_extension ("GL_EXT_color_buffer_float"))
|
||||
flags |= GDK_GL_FORMAT_RENDERABLE;
|
||||
if (epoxy_has_gl_extension ("GL_OES_texture_float_linear"))
|
||||
flags |= GDK_GL_FORMAT_FILTERABLE;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32A32_FLOAT] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_R32G32B32_FLOAT] |= flags;
|
||||
priv->memory_flags[GDK_MEMORY_A32_FLOAT] |= flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gdk_gl_version_init_epoxy (GdkGLVersion *version)
|
||||
{
|
||||
@@ -1531,11 +1695,13 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_unpack_subimage = gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)) ||
|
||||
epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
|
||||
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
priv->has_bgra = epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888");
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->has_unpack_subimage = TRUE;
|
||||
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
|
||||
priv->has_bgra = TRUE;
|
||||
|
||||
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
|
||||
if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
@@ -1555,7 +1721,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
epoxy_has_gl_extension ("GL_ARB_sync") ||
|
||||
epoxy_has_gl_extension ("GL_APPLE_sync");
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gdk_gl_context_init_memory_flags (context);
|
||||
|
||||
{
|
||||
int max_texture_size;
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
@@ -1567,7 +1734,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
" - GL_KHR_debug: %s\n"
|
||||
" - GL_EXT_unpack_subimage: %s\n"
|
||||
" - half float: %s\n"
|
||||
" - sync: %s",
|
||||
" - sync: %s\n"
|
||||
" - bgra: %s",
|
||||
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
|
||||
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
|
||||
priv->is_legacy ? "legacy" : "core",
|
||||
@@ -1576,9 +1744,9 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_khr_debug ? "yes" : "no",
|
||||
priv->has_unpack_subimage ? "yes" : "no",
|
||||
priv->has_half_float ? "yes" : "no",
|
||||
priv->has_sync ? "yes" : "no");
|
||||
priv->has_sync ? "yes" : "no",
|
||||
priv->has_bgra ? "yes" : "no");
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
@@ -1715,6 +1883,56 @@ gdk_gl_context_get_version (GdkGLContext *context,
|
||||
*minor = gdk_gl_version_get_minor (&priv->gl_version);
|
||||
}
|
||||
|
||||
const char *
|
||||
gdk_gl_context_get_glsl_version_string (GdkGLContext *self)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
if (priv->api == GDK_GL_API_GL)
|
||||
{
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 6)))
|
||||
return "#version 460";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 5)))
|
||||
return "#version 450";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 4)))
|
||||
return "#version 440";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 3)))
|
||||
return "#version 430";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 2)))
|
||||
return "#version 420";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 1)))
|
||||
return "#version 410";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (4, 0)))
|
||||
return "#version 400";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 3)))
|
||||
return "#version 330";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
return "#version 150";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 1)))
|
||||
return "#version 140";
|
||||
else
|
||||
return "#version 130";
|
||||
}
|
||||
else if (priv->api == GDK_GL_API_GLES)
|
||||
{
|
||||
if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
|
||||
return "#version 320 es";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 1)))
|
||||
return "#version 310 es";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
return "#version 300 es";
|
||||
else if (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)))
|
||||
return "#version 300 es";
|
||||
else
|
||||
return "#version 100";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* must be realized to be called */
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_context_clear_current:
|
||||
*
|
||||
@@ -1788,6 +2006,15 @@ gdk_gl_context_get_current (void)
|
||||
return context;
|
||||
}
|
||||
|
||||
GdkGLMemoryFlags
|
||||
gdk_gl_context_get_format_flags (GdkGLContext *self,
|
||||
GdkMemoryFormat format)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
return priv->memory_flags[format];
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_has_debug (GdkGLContext *self)
|
||||
{
|
||||
@@ -1812,6 +2039,36 @@ gdk_gl_context_has_sync (GdkGLContext *self)
|
||||
return priv->has_sync;
|
||||
}
|
||||
|
||||
/* Return if GL_BGRA works with glTexImage2D */
|
||||
gboolean
|
||||
gdk_gl_context_has_bgra (GdkGLContext *self)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
return priv->has_bgra;
|
||||
}
|
||||
|
||||
/* Return if glGenVertexArrays, glBindVertexArray and glDeleteVertexArrays
|
||||
* can be used
|
||||
*/
|
||||
gboolean
|
||||
gdk_gl_context_has_vertex_arrays (GdkGLContext *self)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
|
||||
switch (priv->api)
|
||||
{
|
||||
case GDK_GL_API_GL:
|
||||
return TRUE;
|
||||
|
||||
case GDK_GL_API_GLES:
|
||||
return gdk_gl_version_get_major (&priv->gl_version) >= 3;
|
||||
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is currently private! */
|
||||
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
|
||||
gboolean
|
||||
@@ -1892,3 +2149,282 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
|
||||
|
||||
g_assert (the_gl_backend_type == backend_type);
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int target)
|
||||
{
|
||||
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
EGLint attribs[64];
|
||||
int i;
|
||||
EGLImage image;
|
||||
guint texture_id;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), 0);
|
||||
g_return_val_if_fail (width > 0, 0);
|
||||
g_return_val_if_fail (height > 0, 0);
|
||||
g_return_val_if_fail (1 <= dmabuf->n_planes && dmabuf->n_planes <= 4, 0);
|
||||
g_return_val_if_fail (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
|
||||
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_import)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import dmabufs into GL, missing EGL or EGL_EXT_image_dma_buf_import_modifiers");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes);
|
||||
|
||||
i = 0;
|
||||
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
|
||||
attribs[i++] = EGL_TRUE;
|
||||
attribs[i++] = EGL_WIDTH;
|
||||
attribs[i++] = width;
|
||||
attribs[i++] = EGL_HEIGHT;
|
||||
attribs[i++] = height;
|
||||
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
attribs[i++] = dmabuf->fourcc;
|
||||
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[i++] = EGL_ITU_REC601_EXT;
|
||||
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
|
||||
attribs[i++] = EGL_YUV_FULL_RANGE_EXT;
|
||||
|
||||
#define ADD_PLANE(plane) \
|
||||
{ \
|
||||
if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID) \
|
||||
{ \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \
|
||||
attribs[i++] = dmabuf->modifier & 0xFFFFFFFF; \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \
|
||||
attribs[i++] = dmabuf->modifier >> 32; \
|
||||
} \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \
|
||||
attribs[i++] = dmabuf->planes[plane].fd; \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \
|
||||
attribs[i++] = dmabuf->planes[plane].stride; \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \
|
||||
attribs[i++] = dmabuf->planes[plane].offset; \
|
||||
}
|
||||
|
||||
ADD_PLANE (0);
|
||||
|
||||
if (dmabuf->n_planes > 1) ADD_PLANE (1);
|
||||
if (dmabuf->n_planes > 2) ADD_PLANE (2);
|
||||
if (dmabuf->n_planes > 3) ADD_PLANE (3);
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
image = eglCreateImageKHR (egl_display,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_LINUX_DMA_BUF_EXT,
|
||||
(EGLClientBuffer)NULL,
|
||||
attribs);
|
||||
|
||||
if (image == EGL_NO_IMAGE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating EGLImage for dmabuf failed: %#x",
|
||||
eglGetError ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (target, texture_id);
|
||||
glEGLImageTargetTexture2DOES (target, image);
|
||||
glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
eglDestroyImageKHR (egl_display, image);
|
||||
|
||||
return texture_id;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean *external)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
guint texture_id;
|
||||
|
||||
gdk_display_init_dmabuf (display);
|
||||
|
||||
if (!gdk_dmabuf_formats_contains (display->egl_external_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
{
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
GL_TEXTURE_2D);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Import of %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_2D texture",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
*external = FALSE;
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
if (!gdk_gl_context_get_use_es (self))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import external_only %.4s:%#" G_GINT64_MODIFIER "x outside of GLES",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
GL_TEXTURE_EXTERNAL_OES);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Import of external_only %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_EXTERNAL_OES texture",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
*external = TRUE;
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_export_dmabuf (GdkGLContext *self,
|
||||
unsigned int texture_id,
|
||||
GdkDmabuf *dmabuf)
|
||||
{
|
||||
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
EGLContext egl_context = priv->egl_context;
|
||||
EGLint attribs[10];
|
||||
EGLImage image;
|
||||
gboolean result = FALSE;
|
||||
int i;
|
||||
int fourcc;
|
||||
int n_planes;
|
||||
guint64 modifier;
|
||||
int fds[GDK_DMABUF_MAX_PLANES];
|
||||
int strides[GDK_DMABUF_MAX_PLANES];
|
||||
int offsets[GDK_DMABUF_MAX_PLANES];
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (texture_id > 0, FALSE);
|
||||
g_return_val_if_fail (dmabuf != NULL, FALSE);
|
||||
|
||||
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_export)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't export dmabufs from GL, missing EGL or EGL_EXT_image_dma_buf_export");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF, "Exporting GL texture to dmabuf");
|
||||
|
||||
i = 0;
|
||||
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
|
||||
attribs[i++] = EGL_TRUE;
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
image = eglCreateImageKHR (egl_display,
|
||||
egl_context,
|
||||
EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer)GUINT_TO_POINTER (texture_id),
|
||||
attribs);
|
||||
|
||||
if (image == EGL_NO_IMAGE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating EGLImage for dmabuf failed: %#x", eglGetError ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!eglExportDMABUFImageQueryMESA (egl_display,
|
||||
image,
|
||||
&fourcc,
|
||||
&n_planes,
|
||||
&modifier))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"eglExportDMABUFImageQueryMESA failed: %#x", eglGetError ());
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (n_planes < 1 || n_planes > GDK_DMABUF_MAX_PLANES)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"dmabufs with %d planes are not supported", n_planes);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!eglExportDMABUFImageMESA (egl_display,
|
||||
image,
|
||||
fds,
|
||||
strides,
|
||||
offsets))
|
||||
{
|
||||
g_warning ("eglExportDMABUFImage failed: %#x", eglGetError ());
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_planes; i++)
|
||||
{
|
||||
if (fds[i] == -1)
|
||||
{
|
||||
g_warning ("dmabuf plane %d has no file descriptor", i);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
dmabuf->fourcc = (guint32)fourcc;
|
||||
dmabuf->modifier = modifier;
|
||||
dmabuf->n_planes = n_planes;
|
||||
|
||||
for (i = 0; i < n_planes; i++)
|
||||
{
|
||||
dmabuf->planes[i].fd = fds[i];
|
||||
dmabuf->planes[i].stride = (int) strides[i];
|
||||
dmabuf->planes[i].offset = (int) offsets[i];
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Exported GL texture to dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %d)",
|
||||
(char *)&fourcc, modifier, n_planes);
|
||||
|
||||
result = TRUE;
|
||||
|
||||
out:
|
||||
eglDestroyImageKHR (egl_display, image);
|
||||
|
||||
return result;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "gdkglcontext.h"
|
||||
#include "gdkdrawcontextprivate.h"
|
||||
#include "gdkglversionprivate.h"
|
||||
#include "gdkdmabufprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -34,6 +35,17 @@ typedef enum {
|
||||
GDK_GL_CGL
|
||||
} GdkGLBackend;
|
||||
|
||||
typedef enum {
|
||||
/* The format is supported for glTexImage2D() */
|
||||
GDK_GL_FORMAT_USABLE = 1 << 0,
|
||||
/* The format can be rendered to.
|
||||
* GL/GLES spec term: "color-renderable" */
|
||||
GDK_GL_FORMAT_RENDERABLE = 1 << 1,
|
||||
/* GL_LINEAR/GL_MIPMAP_LINEAR can be used for textures in this format.
|
||||
* GLES spec term: "texture-filterable" */
|
||||
GDK_GL_FORMAT_FILTERABLE = 1 << 2
|
||||
} GdkGLMemoryFlags;
|
||||
|
||||
/* The maximum amount of buffers we track update regions for.
|
||||
* Note that this is equal to the max buffer age value we
|
||||
* can provide a damage region for */
|
||||
@@ -147,6 +159,10 @@ void gdk_gl_context_label_object_printf (GdkGLContext
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (4, 5);
|
||||
|
||||
const char * gdk_gl_context_get_glsl_version_string (GdkGLContext *self);
|
||||
|
||||
GdkGLMemoryFlags gdk_gl_context_get_format_flags (GdkGLContext *self,
|
||||
GdkMemoryFormat format) G_GNUC_PURE;
|
||||
gboolean gdk_gl_context_has_debug (GdkGLContext *self) G_GNUC_PURE;
|
||||
|
||||
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
|
||||
@@ -155,7 +171,20 @@ gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext
|
||||
|
||||
gboolean gdk_gl_context_has_sync (GdkGLContext *self) G_GNUC_PURE;
|
||||
|
||||
gboolean gdk_gl_context_has_bgra (GdkGLContext *self) G_GNUC_PURE;
|
||||
|
||||
gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext *self) G_GNUC_PURE;
|
||||
|
||||
double gdk_gl_context_get_scale (GdkGLContext *self);
|
||||
|
||||
G_END_DECLS
|
||||
guint gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean *external);
|
||||
|
||||
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
|
||||
unsigned int texture_id,
|
||||
GdkDmabuf *dmabuf);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -141,9 +141,7 @@ struct _Download
|
||||
};
|
||||
|
||||
static gboolean
|
||||
gdk_gl_texture_find_format (gboolean use_es,
|
||||
guint gl_major,
|
||||
guint gl_minor,
|
||||
gdk_gl_texture_find_format (GdkGLContext *context,
|
||||
GdkMemoryAlpha alpha,
|
||||
GLint gl_format,
|
||||
GLint gl_type,
|
||||
@@ -153,15 +151,18 @@ gdk_gl_texture_find_format (gboolean use_es,
|
||||
|
||||
for (format = 0; format < GDK_MEMORY_N_FORMATS; format++)
|
||||
{
|
||||
GLenum q_internal_format, q_format, q_type;
|
||||
GLint q_internal_format;
|
||||
GLenum q_format, q_type;
|
||||
GLint q_swizzle[4];
|
||||
|
||||
if (gdk_memory_format_alpha (format) != alpha)
|
||||
continue;
|
||||
|
||||
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type, q_swizzle))
|
||||
if (!(gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_RENDERABLE))
|
||||
continue;
|
||||
|
||||
gdk_memory_format_gl_format (format, &q_internal_format, &q_format, &q_type, q_swizzle);
|
||||
|
||||
if (q_format != gl_format || q_type != gl_type)
|
||||
continue;
|
||||
|
||||
@@ -181,21 +182,19 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
GdkMemoryFormat format;
|
||||
gsize expected_stride;
|
||||
Download *download = download_;
|
||||
GLenum gl_internal_format, gl_format, gl_type;
|
||||
GLint gl_internal_format;
|
||||
GLenum gl_format, gl_type;
|
||||
GLint gl_swizzle[4];
|
||||
int major, minor;
|
||||
|
||||
format = gdk_texture_get_format (texture),
|
||||
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
|
||||
if (!gdk_gl_context_get_use_es (context) &&
|
||||
gdk_memory_format_gl_format (format,
|
||||
FALSE,
|
||||
major, minor,
|
||||
&gl_internal_format,
|
||||
&gl_format, &gl_type, gl_swizzle))
|
||||
((gdk_gl_context_get_format_flags (context, format) & GDK_GL_FORMAT_USABLE) == GDK_GL_FORMAT_USABLE))
|
||||
{
|
||||
gdk_memory_format_gl_format (format,
|
||||
&gl_internal_format,
|
||||
&gl_format, &gl_type, gl_swizzle);
|
||||
if (download->stride == expected_stride &&
|
||||
download->format == format)
|
||||
{
|
||||
@@ -233,7 +232,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
else
|
||||
{
|
||||
GdkMemoryFormat actual_format;
|
||||
GLint gl_read_format, gl_read_type;
|
||||
GLenum gl_read_format, gl_read_type;
|
||||
GLuint fbo;
|
||||
|
||||
glGenFramebuffers (1, &fbo);
|
||||
@@ -241,26 +240,34 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
|
||||
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
|
||||
{
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
|
||||
if (!gdk_gl_texture_find_format (TRUE, major, minor, gdk_memory_format_alpha (format), gl_read_format, gl_read_type, &actual_format))
|
||||
GLint read_format, read_type;
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
|
||||
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
|
||||
if (gdk_gl_texture_find_format (context, gdk_memory_format_alpha (format), read_format, read_type, &actual_format))
|
||||
{
|
||||
gl_read_format = GL_RGBA;
|
||||
gl_read_type = GL_UNSIGNED_BYTE;
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_PREMULTIPLIED)
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
else
|
||||
actual_format = GDK_MEMORY_R8G8B8A8;
|
||||
gl_read_format = read_format;
|
||||
gl_read_type = read_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format));
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
&gl_internal_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_read_format = GL_RGBA;
|
||||
gl_read_type = GL_UNSIGNED_BYTE;
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_PREMULTIPLIED)
|
||||
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
|
||||
else
|
||||
actual_format = GDK_MEMORY_R8G8B8A8;
|
||||
actual_format = gdk_memory_depth_get_format (gdk_memory_format_get_depth (format));
|
||||
if (gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT)
|
||||
actual_format = gdk_memory_format_get_straight (actual_format);
|
||||
|
||||
gdk_memory_format_gl_format (actual_format,
|
||||
&gl_internal_format,
|
||||
&gl_read_format, &gl_read_type, gl_swizzle);
|
||||
}
|
||||
|
||||
if (download->format == actual_format &&
|
||||
|
@@ -213,7 +213,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
gobject_class->set_property = gdk_gl_texture_builder_set_property;
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:context: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_context org.gdk.Property.set=gdk_gl_texture_builder_set_context)
|
||||
* GdkGLTextureBuilder:context: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_context org.gtk.Property.set=gdk_gl_texture_builder_set_context)
|
||||
*
|
||||
* The context owning the texture.
|
||||
*
|
||||
@@ -225,7 +225,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:format: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_format org.gdk.Property.set=gdk_gl_texture_builder_set_format)
|
||||
* GdkGLTextureBuilder:format: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_format org.gtk.Property.set=gdk_gl_texture_builder_set_format)
|
||||
*
|
||||
* The format when downloading the texture.
|
||||
*
|
||||
@@ -238,7 +238,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:has-mipmap: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gdk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
|
||||
* GdkGLTextureBuilder:has-mipmap: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gtk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
|
||||
*
|
||||
* If the texture has a mipmap.
|
||||
*
|
||||
@@ -250,7 +250,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:height: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_height org.gdk.Property.set=gdk_gl_texture_builder_set_height)
|
||||
* GdkGLTextureBuilder:height: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_height org.gtk.Property.set=gdk_gl_texture_builder_set_height)
|
||||
*
|
||||
* The height of the texture.
|
||||
*
|
||||
@@ -262,7 +262,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:id: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_id org.gdk.Property.set=gdk_gl_texture_builder_set_id)
|
||||
* GdkGLTextureBuilder:id: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_id org.gtk.Property.set=gdk_gl_texture_builder_set_id)
|
||||
*
|
||||
* The texture ID to use.
|
||||
*
|
||||
@@ -274,7 +274,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:sync: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_sync org.gdk.Property.set=gdk_gl_texture_builder_set_sync)
|
||||
* GdkGLTextureBuilder:sync: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_sync org.gtk.Property.set=gdk_gl_texture_builder_set_sync)
|
||||
*
|
||||
* An optional `GLSync` object.
|
||||
*
|
||||
@@ -287,7 +287,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_region org.gdk.Property.set=gdk_gl_texture_builder_set_update_region)
|
||||
* GdkGLTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_region org.gtk.Property.set=gdk_gl_texture_builder_set_update_region)
|
||||
*
|
||||
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
|
||||
*
|
||||
@@ -299,7 +299,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_texture org.gdk.Property.set=gdk_gl_texture_builder_set_update_texture)
|
||||
* GdkGLTextureBuilder:update-texture: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_texture org.gtk.Property.set=gdk_gl_texture_builder_set_update_texture)
|
||||
*
|
||||
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
|
||||
*
|
||||
@@ -311,7 +311,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:width: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_width org.gdk.Property.set=gdk_gl_texture_builder_set_width)
|
||||
* GdkGLTextureBuilder:width: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_width org.gtk.Property.set=gdk_gl_texture_builder_set_width)
|
||||
*
|
||||
* The width of the texture.
|
||||
*
|
||||
@@ -347,7 +347,7 @@ gdk_gl_texture_builder_new (void)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_context: (attributes org.gdk.Method.get_property=context)
|
||||
* gdk_gl_texture_builder_get_context: (attributes org.gtk.Method.get_property=context)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the context previously set via gdk_gl_texture_builder_set_context() or
|
||||
@@ -366,7 +366,7 @@ gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_context: (attributes org.gdk.Method.set_property=context)
|
||||
* gdk_gl_texture_builder_set_context: (attributes org.gtk.Method.set_property=context)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @context: (nullable): The context the texture beongs to or %NULL to unset
|
||||
*
|
||||
@@ -391,7 +391,7 @@ gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
|
||||
* gdk_gl_texture_builder_get_height: (attributes org.gtk.Method.get_property=height)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the height previously set via gdk_gl_texture_builder_set_height() or
|
||||
@@ -410,7 +410,7 @@ gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
|
||||
* gdk_gl_texture_builder_set_height: (attributes org.gtk.Method.set_property=height)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @height: The texture's height or 0 to unset
|
||||
*
|
||||
@@ -435,7 +435,7 @@ gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_id: (attributes org.gdk.Method.get_property=id)
|
||||
* gdk_gl_texture_builder_get_id: (attributes org.gtk.Method.get_property=id)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the texture id previously set via gdk_gl_texture_builder_set_id() or
|
||||
@@ -454,7 +454,7 @@ gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_id: (attributes org.gdk.Method.set_property=id)
|
||||
* gdk_gl_texture_builder_set_id: (attributes org.gtk.Method.set_property=id)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @id: The texture id to be used for creating the texture
|
||||
*
|
||||
@@ -481,7 +481,7 @@ gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
|
||||
* gdk_gl_texture_builder_get_width: (attributes org.gtk.Method.get_property=width)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the width previously set via gdk_gl_texture_builder_set_width() or
|
||||
@@ -500,7 +500,7 @@ gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
|
||||
* gdk_gl_texture_builder_set_width: (attributes org.gtk.Method.set_property=width)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @width: The texture's width or 0 to unset
|
||||
*
|
||||
@@ -525,7 +525,7 @@ gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gdk.Method.get_property=has-mipmap)
|
||||
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gtk.Method.get_property=has-mipmap)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets whether the texture has a mipmap.
|
||||
@@ -543,7 +543,7 @@ gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gdk.Method.set_property=has-mipmap)
|
||||
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gtk.Method.set_property=has-mipmap)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @has_mipmap: Whether the texture has a mipmap
|
||||
*
|
||||
@@ -569,7 +569,7 @@ gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_sync: (attributes org.gdk.Method.get_property=sync)
|
||||
* gdk_gl_texture_builder_get_sync: (attributes org.gtk.Method.get_property=sync)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
|
||||
@@ -587,7 +587,7 @@ gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_sync: (attributes org.gdk.Method.set_property=sync)
|
||||
* gdk_gl_texture_builder_set_sync: (attributes org.gtk.Method.set_property=sync)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @sync: (nullable): the GLSync object
|
||||
*
|
||||
@@ -617,7 +617,7 @@ gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
|
||||
* gdk_gl_texture_builder_get_format: (attributes org.gtk.Method.get_property=format)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the format previously set via gdk_gl_texture_builder_set_format().
|
||||
@@ -635,7 +635,7 @@ gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_format: (attributes org.gdk.Method.set_property=format)
|
||||
* gdk_gl_texture_builder_set_format: (attributes org.gtk.Method.set_property=format)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @format: The texture's format
|
||||
*
|
||||
@@ -673,7 +673,7 @@ gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
|
||||
* gdk_gl_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the texture previously set via gdk_gl_texture_builder_set_update_texture() or
|
||||
@@ -692,7 +692,7 @@ gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
|
||||
* gdk_gl_texture_builder_set_update_texture: (attributes org.gtk.Method.set_property=update-texture)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @texture: (nullable): the texture to update
|
||||
*
|
||||
@@ -715,7 +715,7 @@ gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
|
||||
* gdk_gl_texture_builder_get_update_region: (attributes org.gtk.Method.get_property=update-region)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the region previously set via gdk_gl_texture_builder_set_update_region() or
|
||||
@@ -734,7 +734,7 @@ gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
|
||||
* gdk_gl_texture_builder_set_update_region: (attributes org.gtk.Method.set_property=update-region)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @region: (nullable): the region to update
|
||||
*
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdkenums.h"
|
||||
#include "gdktypes.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
@@ -41,18 +42,25 @@ typedef enum {
|
||||
gsize gdk_memory_format_alignment (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
GdkMemoryAlpha gdk_memory_format_alpha (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_format_get_premultiplied (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_format_get_straight (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
const GdkMemoryFormat * gdk_memory_format_get_fallbacks (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
GdkMemoryDepth gdk_memory_format_get_depth (GdkMemoryFormat format) G_GNUC_CONST;
|
||||
GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth depth1,
|
||||
GdkMemoryDepth depth2) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_depth_get_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
|
||||
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
gboolean gles,
|
||||
guint gl_major,
|
||||
guint gl_minor,
|
||||
guint *out_internal_format,
|
||||
guint *out_format,
|
||||
guint *out_type,
|
||||
GLint out_gizzle[4]);
|
||||
void gdk_memory_format_gl_format (GdkMemoryFormat format,
|
||||
GLint *out_internal_format,
|
||||
GLenum *out_format,
|
||||
GLenum *out_type,
|
||||
GLint out_swizzle[4]);
|
||||
gboolean gdk_memory_format_gl_rgba_format (GdkMemoryFormat format,
|
||||
GdkMemoryFormat *out_actual_format,
|
||||
GLint *out_internal_format,
|
||||
GLenum *out_format,
|
||||
GLenum *out_type,
|
||||
GLint out_swizzle[4]);
|
||||
|
||||
void gdk_memory_convert (guchar *dest_data,
|
||||
gsize dest_stride,
|
||||
|
@@ -24,13 +24,16 @@
|
||||
#include "gdksnapshotprivate.h"
|
||||
#include "gdkprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
|
||||
GdkSnapshot * gtk_snapshot_new (void);
|
||||
void gtk_snapshot_push_debug (GdkSnapshot *snapshot,
|
||||
const char *message,
|
||||
...) G_GNUC_PRINTF (2, 3);
|
||||
void gtk_snapshot_pop (GdkSnapshot *snapshot);
|
||||
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot);
|
||||
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot,
|
||||
const graphene_size_t *size);
|
||||
|
||||
/**
|
||||
* GdkPaintable:
|
||||
@@ -118,7 +121,7 @@ gdk_paintable_default_get_current_image (GdkPaintable *paintable)
|
||||
|
||||
snapshot = gtk_snapshot_new ();
|
||||
gdk_paintable_snapshot (paintable, snapshot, width, height);
|
||||
return gtk_snapshot_free_to_paintable (snapshot);
|
||||
return gtk_snapshot_free_to_paintable (snapshot, NULL);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
|
@@ -40,7 +40,7 @@ struct _GdkIOPipe
|
||||
GCond cond;
|
||||
guchar *buffer;
|
||||
gsize size;
|
||||
GdkIOPipeState state : 2;
|
||||
guint state : 2; /* GdkIOPipeState */
|
||||
guint input_closed : 1;
|
||||
guint output_closed : 1;
|
||||
};
|
||||
|
105
gdk/gdksubsurface.c
Normal file
105
gdk/gdksubsurface.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktexture.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkSubsurface, gdk_subsurface, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_subsurface_init (GdkSubsurface *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_subsurface_finalize (GObject *object)
|
||||
{
|
||||
GdkSubsurface *subsurface = GDK_SUBSURFACE (object);
|
||||
|
||||
g_ptr_array_remove (subsurface->parent->subsurfaces, subsurface);
|
||||
g_clear_object (&subsurface->parent);
|
||||
|
||||
G_OBJECT_CLASS (gdk_subsurface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_subsurface_class_init (GdkSubsurfaceClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_subsurface_finalize;
|
||||
}
|
||||
|
||||
GdkSurface *
|
||||
gdk_subsurface_get_parent (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), NULL);
|
||||
|
||||
return subsurface->parent;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect,
|
||||
gboolean above,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
||||
g_return_val_if_fail (rect != NULL, FALSE);
|
||||
g_return_val_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling), FALSE);
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect, above, sibling);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_subsurface_detach (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_subsurface_get_texture (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), NULL);
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_texture (subsurface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_subsurface_get_rect (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
g_return_if_fail (rect != NULL);
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_rect (subsurface, rect);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_subsurface_is_above_parent (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), TRUE);
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->is_above_parent (subsurface);
|
||||
}
|
79
gdk/gdksubsurfaceprivate.h
Normal file
79
gdk/gdksubsurfaceprivate.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Uninstalled header defining types and functions internal to GDK */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdksurface.h"
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkSubsurface GdkSubsurface;
|
||||
typedef struct _GdkSubsurfaceClass GdkSubsurfaceClass;
|
||||
|
||||
#define GDK_TYPE_SUBSURFACE (gdk_subsurface_get_type ())
|
||||
#define GDK_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SUBSURFACE, GdkSubsurface))
|
||||
#define GDK_SUBSURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SUBSURFACE, GdkSubsurfaceClass))
|
||||
#define GDK_IS_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SUBSURFACE))
|
||||
#define GDK_SUBSURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SUBSURFACE, GdkSubsurfaceClass))
|
||||
|
||||
struct _GdkSubsurface
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkSurface *parent;
|
||||
|
||||
int ref_count;
|
||||
};
|
||||
|
||||
|
||||
struct _GdkSubsurfaceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* attach) (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect,
|
||||
gboolean above,
|
||||
GdkSubsurface *sibling);
|
||||
void (* detach) (GdkSubsurface *subsurface);
|
||||
GdkTexture * (* get_texture) (GdkSubsurface *subsurface);
|
||||
void (* get_rect) (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect);
|
||||
gboolean (* is_above_parent) (GdkSubsurface *subsurface);
|
||||
};
|
||||
|
||||
GType gdk_subsurface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkSurface * gdk_subsurface_get_parent (GdkSubsurface *subsurface);
|
||||
gboolean gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect,
|
||||
gboolean above,
|
||||
GdkSubsurface *sibling);
|
||||
void gdk_subsurface_detach (GdkSubsurface *subsurface);
|
||||
GdkTexture * gdk_subsurface_get_texture (GdkSubsurface *subsurface);
|
||||
void gdk_subsurface_get_rect (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect);
|
||||
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -43,6 +43,7 @@
|
||||
#include "gdkrectangle.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkvulkancontext.h"
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -254,7 +255,7 @@ maybe_flip_position (int bounds_pos,
|
||||
*flipped = TRUE;
|
||||
secondary = rect_pos + (1 - rect_sign) * rect_size / 2 - offset - (1 - surface_sign) * surface_size / 2;
|
||||
|
||||
if (secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size)
|
||||
if ((secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size) || primary > bounds_pos + bounds_size)
|
||||
return secondary;
|
||||
|
||||
*flipped = FALSE;
|
||||
@@ -485,6 +486,8 @@ gdk_surface_init (GdkSurface *surface)
|
||||
|
||||
surface->device_cursor = g_hash_table_new_full (NULL, NULL,
|
||||
NULL, g_object_unref);
|
||||
|
||||
surface->subsurfaces = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
static double
|
||||
@@ -493,6 +496,14 @@ gdk_surface_real_get_scale (GdkSurface *surface)
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
static GdkSubsurface *
|
||||
gdk_surface_real_create_subsurface (GdkSurface *surface)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (surface), OFFLOAD,
|
||||
"Subsurfaces not supported for %s", G_OBJECT_TYPE_NAME (surface));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_constructed (GObject *object)
|
||||
{
|
||||
@@ -515,6 +526,7 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
|
||||
klass->beep = gdk_surface_real_beep;
|
||||
klass->get_scale = gdk_surface_real_get_scale;
|
||||
klass->create_subsurface = gdk_surface_real_create_subsurface;
|
||||
|
||||
/**
|
||||
* GdkSurface:cursor: (attributes org.gtk.Property.get=gdk_surface_get_cursor org.gtk.Property.set=gdk_surface_set_cursor)
|
||||
@@ -757,6 +769,10 @@ gdk_surface_finalize (GObject *object)
|
||||
if (surface->parent)
|
||||
surface->parent->children = g_list_remove (surface->parent->children, surface);
|
||||
|
||||
g_assert (surface->subsurfaces->len == 0);
|
||||
|
||||
g_ptr_array_unref (surface->subsurfaces);
|
||||
|
||||
G_OBJECT_CLASS (gdk_surface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -3054,3 +3070,32 @@ gdk_surface_leave_monitor (GdkSurface *surface,
|
||||
{
|
||||
g_signal_emit (surface, signals[LEAVE_MONITOR], 0, monitor);
|
||||
}
|
||||
|
||||
GdkSubsurface *
|
||||
gdk_surface_create_subsurface (GdkSurface *surface)
|
||||
{
|
||||
GdkSubsurface *subsurface;
|
||||
|
||||
subsurface = GDK_SURFACE_GET_CLASS (surface)->create_subsurface (surface);
|
||||
|
||||
if (subsurface)
|
||||
{
|
||||
subsurface->parent = g_object_ref (surface);
|
||||
g_ptr_array_add (surface->subsurfaces, subsurface);
|
||||
}
|
||||
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
gsize
|
||||
gdk_surface_get_n_subsurfaces (GdkSurface *surface)
|
||||
{
|
||||
return surface->subsurfaces->len;
|
||||
}
|
||||
|
||||
GdkSubsurface *
|
||||
gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
gsize idx)
|
||||
{
|
||||
return g_ptr_array_index (surface->subsurfaces, idx);
|
||||
}
|
||||
|
@@ -23,9 +23,14 @@
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdktoplevel.h"
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkSubsurface GdkSubsurface;
|
||||
|
||||
typedef struct _GskRenderNode GskRenderNode;
|
||||
|
||||
struct _GdkSurface
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -92,6 +97,8 @@ struct _GdkSurface
|
||||
cairo_region_t *opaque_region;
|
||||
|
||||
GdkSeat *current_shortcuts_inhibited_seat;
|
||||
|
||||
GPtrArray *subsurfaces;
|
||||
};
|
||||
|
||||
struct _GdkSurfaceClass
|
||||
@@ -146,6 +153,9 @@ struct _GdkSurfaceClass
|
||||
cairo_region_t *region);
|
||||
void (* request_layout) (GdkSurface *surface);
|
||||
gboolean (* compute_size) (GdkSurface *surface);
|
||||
|
||||
GdkSubsurface *
|
||||
(* create_subsurface) (GdkSurface *surface);
|
||||
};
|
||||
|
||||
#define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
|
||||
@@ -334,7 +344,11 @@ void gdk_surface_request_motion (GdkSurface *surface);
|
||||
|
||||
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
|
||||
|
||||
|
||||
GdkSubsurface * gdk_surface_create_subsurface (GdkSurface *surface);
|
||||
void gdk_surface_destroy_subsurface (GdkSurface *surface,
|
||||
GdkSubsurface *subsurface);
|
||||
gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
|
||||
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
gsize idx);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
148
gdk/gdktexture.c
148
gdk/gdktexture.c
@@ -68,6 +68,33 @@ enum {
|
||||
|
||||
static GParamSpec *properties[N_PROPS];
|
||||
|
||||
static GdkTextureChain *
|
||||
gdk_texture_chain_new (void)
|
||||
{
|
||||
GdkTextureChain *chain = g_new0 (GdkTextureChain, 1);
|
||||
|
||||
g_atomic_ref_count_init (&chain->ref_count);
|
||||
g_mutex_init (&chain->lock);
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_texture_chain_ref (GdkTextureChain *chain)
|
||||
{
|
||||
g_atomic_ref_count_inc (&chain->ref_count);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_texture_chain_unref (GdkTextureChain *chain)
|
||||
{
|
||||
if (g_atomic_ref_count_dec (&chain->ref_count))
|
||||
{
|
||||
g_mutex_clear (&chain->lock);
|
||||
g_free (chain);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_texture_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
@@ -283,7 +310,30 @@ gdk_texture_dispose (GObject *object)
|
||||
{
|
||||
GdkTexture *self = GDK_TEXTURE (object);
|
||||
|
||||
g_clear_pointer (&self->diff_to_previous, cairo_region_destroy);
|
||||
if (self->chain)
|
||||
{
|
||||
g_mutex_lock (&self->chain->lock);
|
||||
|
||||
if (self->next_texture && self->previous_texture)
|
||||
{
|
||||
cairo_region_union (self->next_texture->diff_to_previous,
|
||||
self->diff_to_previous);
|
||||
self->next_texture->previous_texture = self->previous_texture;
|
||||
self->previous_texture->next_texture = self->next_texture;
|
||||
}
|
||||
else if (self->next_texture)
|
||||
self->next_texture->previous_texture = NULL;
|
||||
else if (self->previous_texture)
|
||||
self->previous_texture->next_texture = NULL;
|
||||
|
||||
self->next_texture = NULL;
|
||||
self->previous_texture = NULL;
|
||||
g_clear_pointer (&self->diff_to_previous, cairo_region_destroy);
|
||||
|
||||
g_mutex_unlock (&self->chain->lock);
|
||||
|
||||
g_clear_pointer (&self->chain, gdk_texture_chain_unref);
|
||||
}
|
||||
|
||||
gdk_texture_clear_render_data (self);
|
||||
|
||||
@@ -345,7 +395,9 @@ gdk_texture_init (GdkTexture *self)
|
||||
*
|
||||
* Creates a new texture object representing the surface.
|
||||
*
|
||||
* @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
|
||||
* The @surface must be an image surface with format `CAIRO_FORMAT_ARGB32`.
|
||||
*
|
||||
* The newly created texture will acquire a reference on the @surface.
|
||||
*
|
||||
* Returns: a new `GdkTexture`
|
||||
*/
|
||||
@@ -364,7 +416,7 @@ gdk_texture_new_for_surface (cairo_surface_t *surface)
|
||||
* cairo_image_surface_get_stride (surface),
|
||||
(GDestroyNotify) cairo_surface_destroy,
|
||||
cairo_surface_reference (surface));
|
||||
|
||||
|
||||
texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface),
|
||||
cairo_image_surface_get_height (surface),
|
||||
GDK_MEMORY_DEFAULT,
|
||||
@@ -677,34 +729,64 @@ gdk_texture_do_download (GdkTexture *texture,
|
||||
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data, stride);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_texture_has_ancestor (GdkTexture *self,
|
||||
GdkTexture *other)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
|
||||
for (texture = self->previous_texture;
|
||||
texture != NULL;
|
||||
texture = texture->previous_texture)
|
||||
{
|
||||
if (texture == other)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_texture_diff_from_known_ancestor (GdkTexture *self,
|
||||
GdkTexture *ancestor,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
|
||||
for (texture = self; texture != ancestor; texture = texture->previous_texture)
|
||||
cairo_region_union (region, texture->diff_to_previous);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_texture_diff (GdkTexture *self,
|
||||
GdkTexture *other,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
if (self == other)
|
||||
cairo_rectangle_int_t fill = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = MAX (self->width, other->width),
|
||||
.height = MAX (self->height, other->height),
|
||||
};
|
||||
GdkTextureChain *chain;
|
||||
|
||||
if (other == self)
|
||||
return;
|
||||
|
||||
if (self->previous_texture == other &&
|
||||
g_atomic_pointer_get (&other->next_texture) == self)
|
||||
chain = g_atomic_pointer_get (&self->chain);
|
||||
if (chain == NULL || chain != g_atomic_pointer_get (&other->chain))
|
||||
{
|
||||
cairo_region_union (region, self->diff_to_previous);
|
||||
}
|
||||
else if (other->previous_texture == self &&
|
||||
g_atomic_pointer_get (&self->next_texture) == other)
|
||||
{
|
||||
cairo_region_union (region, other->diff_to_previous);
|
||||
cairo_region_union_rectangle (region, &fill);
|
||||
return;
|
||||
}
|
||||
|
||||
g_mutex_lock (&chain->lock);
|
||||
if (gdk_texture_has_ancestor (self, other))
|
||||
gdk_texture_diff_from_known_ancestor (self, other, region);
|
||||
else if (gdk_texture_has_ancestor (other, self))
|
||||
gdk_texture_diff_from_known_ancestor (other, self, region);
|
||||
else
|
||||
{
|
||||
cairo_region_union_rectangle (region,
|
||||
&(cairo_rectangle_int_t) {
|
||||
0,
|
||||
0,
|
||||
MAX (self->width, other->width),
|
||||
MAX (self->height, other->height)
|
||||
});
|
||||
}
|
||||
cairo_region_union_rectangle (region, &fill);
|
||||
g_mutex_unlock (&chain->lock);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -713,10 +795,30 @@ gdk_texture_set_diff (GdkTexture *self,
|
||||
cairo_region_t *diff)
|
||||
{
|
||||
g_assert (self->diff_to_previous == NULL);
|
||||
g_assert (self->chain == NULL);
|
||||
|
||||
self->chain = g_atomic_pointer_get (&previous->chain);
|
||||
if (self->chain == NULL)
|
||||
{
|
||||
self->chain = gdk_texture_chain_new ();
|
||||
if (!g_atomic_pointer_compare_and_exchange (&previous->chain,
|
||||
NULL,
|
||||
self->chain))
|
||||
gdk_texture_chain_unref (self->chain);
|
||||
self->chain = previous->chain;
|
||||
}
|
||||
gdk_texture_chain_ref (self->chain);
|
||||
|
||||
g_mutex_lock (&self->chain->lock);
|
||||
if (previous->next_texture)
|
||||
{
|
||||
previous->next_texture->previous_texture = NULL;
|
||||
g_clear_pointer (&previous->next_texture->diff_to_previous, cairo_region_destroy);
|
||||
}
|
||||
previous->next_texture = self;
|
||||
self->previous_texture = previous;
|
||||
self->diff_to_previous = diff;
|
||||
g_atomic_pointer_set (&previous->next_texture, self);
|
||||
g_mutex_unlock (&self->chain->lock);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
@@ -819,7 +921,7 @@ gdk_texture_set_render_data (GdkTexture *self,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
|
||||
|
||||
if (self->render_key != NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@@ -6,6 +6,14 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkTextureChain GdkTextureChain;
|
||||
|
||||
struct _GdkTextureChain
|
||||
{
|
||||
gatomicrefcount ref_count;
|
||||
GMutex lock;
|
||||
};
|
||||
|
||||
#define GDK_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_TEXTURE, GdkTextureClass))
|
||||
#define GDK_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_TEXTURE))
|
||||
#define GDK_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_TEXTURE, GdkTextureClass))
|
||||
@@ -23,10 +31,13 @@ struct _GdkTexture
|
||||
GDestroyNotify render_notify;
|
||||
|
||||
/* for diffing swapchain-like textures.
|
||||
* Links are only valid if both textures agree on them */
|
||||
gpointer next_texture; /* atomic, no reference, may be invalid pointer */
|
||||
gpointer previous_texture; /* no reference, may be invalid pointer */
|
||||
cairo_region_t *diff_to_previous;
|
||||
* Textures in the same chain are connected in a double linked list which is
|
||||
* protected using the chain's shared mutex.
|
||||
*/
|
||||
GdkTextureChain *chain; /* lazy, atomic, shared by all chain links */
|
||||
GdkTexture *next_texture; /* no reference, guarded by chain lock */
|
||||
GdkTexture *previous_texture; /* no reference, guarded by chain lock */
|
||||
cairo_region_t *diff_to_previous; /* guarded by chain lock */
|
||||
};
|
||||
|
||||
struct _GdkTextureClass {
|
||||
|
@@ -96,6 +96,8 @@ typedef struct _GdkCairoContext GdkCairoContext;
|
||||
typedef struct _GdkGLContext GdkGLContext;
|
||||
typedef struct _GdkVulkanContext GdkVulkanContext;
|
||||
|
||||
typedef struct _GdkDmabufFormats GdkDmabufFormats;
|
||||
|
||||
/*
|
||||
* GDK_DECLARE_INTERNAL_TYPE:
|
||||
* @ModuleObjName: The name of the new type, in camel case (like GtkWidget)
|
||||
|
@@ -252,7 +252,6 @@ gdk_vulkan_strerror (VkResult result)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *
|
||||
surface_present_mode_to_string (VkPresentModeKHR present_mode)
|
||||
{
|
||||
@@ -275,7 +274,6 @@ surface_present_mode_to_string (VkPresentModeKHR present_mode)
|
||||
|
||||
return "(unknown)";
|
||||
}
|
||||
#endif
|
||||
|
||||
static const VkPresentModeKHR preferred_present_modes[] = {
|
||||
VK_PRESENT_MODE_MAILBOX_KHR,
|
||||
@@ -1475,6 +1473,13 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
gboolean validate = FALSE, have_debug_report = FALSE;
|
||||
VkResult res;
|
||||
|
||||
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_VULKAN_DISABLE)
|
||||
{
|
||||
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
_("Vulkan support disabled via GDK_DEBUG"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL)
|
||||
{
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
|
||||
|
@@ -252,7 +252,7 @@ gdk_save_jpeg (GdkTexture *texture)
|
||||
gulong size = 0;
|
||||
guchar *input = NULL;
|
||||
GdkTextureDownloader downloader;
|
||||
GBytes *texbytes;
|
||||
GBytes *texbytes = NULL;
|
||||
const guchar *texdata;
|
||||
gsize texstride;
|
||||
guchar *row;
|
||||
|
@@ -329,6 +329,7 @@ gdk_save_png (GdkTexture *texture)
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_B8G8R8A8:
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
@@ -340,6 +341,10 @@ gdk_save_png (GdkTexture *texture)
|
||||
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
case GDK_MEMORY_R8G8B8X8:
|
||||
case GDK_MEMORY_X8R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8X8:
|
||||
case GDK_MEMORY_X8B8G8R8:
|
||||
format = GDK_MEMORY_R8G8B8;
|
||||
png_format = PNG_COLOR_TYPE_RGB;
|
||||
depth = 8;
|
||||
|
@@ -236,12 +236,17 @@ static const FormatData format_data[] = {
|
||||
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_B8G8R8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R8G8B8X8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_X8R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_B8G8R8X8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_X8B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
|
||||
[GDK_MEMORY_R16G16B16A16] = { GDK_MEMORY_R16G16B16A16, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
|
||||
|
@@ -1265,6 +1265,14 @@ _gdk_macos_display_translate (GdkMacosDisplay *self,
|
||||
_gdk_macos_display_clear_sorting (self);
|
||||
}
|
||||
}
|
||||
else if (is_motion_event(event_type))
|
||||
{
|
||||
NSWindow *orig_window = [nsevent window];
|
||||
|
||||
if (orig_window && GDK_IS_MACOS_WINDOW (orig_window))
|
||||
[NSApp sendEvent:nsevent];
|
||||
}
|
||||
|
||||
return fill_event (self, window, nsevent, x, y);
|
||||
}
|
||||
|
||||
|
@@ -1005,7 +1005,7 @@ _gdk_macos_display_get_nsevent (GdkEvent *event)
|
||||
}
|
||||
|
||||
NSEvent *
|
||||
_gdk_macos_display_get_last_nsevent ()
|
||||
_gdk_macos_display_get_last_nsevent (void)
|
||||
{
|
||||
const GdkToNSEventMap *map = g_queue_peek_tail (&event_map);
|
||||
if (map)
|
||||
|
@@ -180,7 +180,6 @@ typedef enum {
|
||||
POLLING_DESCRIPTORS,
|
||||
} SelectThreadState;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *const state_names[] = {
|
||||
"BEFORE_START",
|
||||
"WAITING",
|
||||
@@ -188,7 +187,6 @@ static const char *const state_names[] = {
|
||||
"POLLING_RESTART",
|
||||
"POLLING_DESCRIPTORS"
|
||||
};
|
||||
#endif
|
||||
|
||||
static SelectThreadState select_thread_state = BEFORE_START;
|
||||
|
||||
@@ -374,7 +372,6 @@ select_thread_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static void
|
||||
dump_poll_result (GPollFD *ufds,
|
||||
guint nfds)
|
||||
@@ -400,7 +397,6 @@ dump_poll_result (GPollFD *ufds,
|
||||
gdk_debug_message ("%s", s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
pollfds_equal (GPollFD *old_pollfds,
|
||||
@@ -468,13 +464,11 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
n_ready = old_poll_func (ufds, nfds, 0);
|
||||
if (n_ready > 0 || timeout == 0)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) && n_ready > 0)
|
||||
if (GDK_DEBUG_CHECK (EVENTLOOP) && n_ready > 0)
|
||||
{
|
||||
gdk_debug_message ("EventLoop: Found ready file descriptors before waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
#endif
|
||||
|
||||
return n_ready;
|
||||
}
|
||||
@@ -612,13 +606,11 @@ select_thread_collect_poll (GPollFD *ufds, guint nfds)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP)
|
||||
if (GDK_DEBUG_CHECK (EVENTLOOP))
|
||||
{
|
||||
gdk_debug_message ("EventLoop: Found ready file descriptors after waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SELECT_THREAD_UNLOCK ();
|
||||
|
@@ -17,6 +17,12 @@ gdk_public_sources = files([
|
||||
'gdkdevicetool.c',
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdmabuf.c',
|
||||
'gdkdmabufegl.c',
|
||||
'gdkdmabufformats.c',
|
||||
'gdkdmabufformatsbuilder.c',
|
||||
'gdkdmabuftexture.c',
|
||||
'gdkdmabuftexturebuilder.c',
|
||||
'gdkdrag.c',
|
||||
'gdkdragsurface.c',
|
||||
'gdkdragsurfacesize.c',
|
||||
@@ -49,6 +55,7 @@ gdk_public_sources = files([
|
||||
'gdktexture.c',
|
||||
'gdktexturedownloader.c',
|
||||
'gdkvulkancontext.c',
|
||||
'gdksubsurface.c',
|
||||
'gdksurface.c',
|
||||
'gdkpopuplayout.c',
|
||||
'gdkprofiler.c',
|
||||
@@ -79,6 +86,9 @@ gdk_public_headers = files([
|
||||
'gdkdisplay.h',
|
||||
'gdkdisplaymanager.h',
|
||||
'gdkdrag.h',
|
||||
'gdkdmabufformats.h',
|
||||
'gdkdmabuftexture.h',
|
||||
'gdkdmabuftexturebuilder.h',
|
||||
'gdkdragsurfacesize.h',
|
||||
'gdkdrawcontext.h',
|
||||
'gdkdrop.h',
|
||||
@@ -208,6 +218,7 @@ gdk_deps = [
|
||||
platform_gio_dep,
|
||||
pangocairo_dep,
|
||||
vulkan_dep,
|
||||
dmabuf_dep,
|
||||
png_dep,
|
||||
tiff_dep,
|
||||
jpeg_dep,
|
||||
|
@@ -194,6 +194,23 @@ gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
self->paint_surface = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_cairo_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->has_pending_subsurface_commits)
|
||||
return;
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
|
||||
gdk_wayland_surface_commit (surface);
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_cairo_context_clear_all_cairo_surfaces (GdkWaylandCairoContext *self)
|
||||
{
|
||||
@@ -241,6 +258,7 @@ gdk_wayland_cairo_context_class_init (GdkWaylandCairoContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_wayland_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_wayland_cairo_context_end_frame;
|
||||
draw_context_class->empty_frame = gdk_wayland_cairo_context_empty_frame;
|
||||
draw_context_class->surface_resized = gdk_wayland_cairo_context_surface_resized;
|
||||
|
||||
cairo_context_class->cairo_create = gdk_wayland_cairo_context_cairo_create;
|
||||
|
@@ -225,14 +225,12 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_clipboard_read_async);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: read for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, cb->offer_formats);
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
@@ -245,7 +243,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
|
||||
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
|
||||
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
|
||||
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
@@ -322,14 +320,12 @@ gdk_wayland_clipboard_claim_remote (GdkWaylandClipboard *cb,
|
||||
|
||||
gdk_wayland_clipboard_discard_offer (cb);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: remote clipboard claim for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
cb->offer_formats = formats;
|
||||
cb->offer = offer;
|
||||
|
||||
|
@@ -175,7 +175,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
||||
_gdk_wayland_display_get_cursor_theme (display),
|
||||
desired_scale,
|
||||
gdk_cursor_get_name (cursor));
|
||||
if (c)
|
||||
if (c && c->image_count > 0)
|
||||
{
|
||||
struct wl_cursor_image *image;
|
||||
int cursor_scale;
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#ifdef HAVE_LINUX_MEMFD_H
|
||||
#include <linux/memfd.h>
|
||||
@@ -56,6 +57,7 @@
|
||||
#include <wayland/xdg-foreign-unstable-v1-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
#include <wayland/server-decoration-client-protocol.h>
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
#include "wm-button-layout-translation.h"
|
||||
|
||||
@@ -267,58 +269,119 @@ postpone_on_globals_closure (GdkWaylandDisplay *display_wayland,
|
||||
g_list_append (display_wayland->on_has_globals_closures, closure);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
get_format_name (uint32_t format,
|
||||
char name[10])
|
||||
{
|
||||
if (format == 0)
|
||||
g_strlcpy (name, "ARGB8888", 10);
|
||||
else if (format == 1)
|
||||
g_strlcpy (name, "XRGB8888", 10);
|
||||
else
|
||||
g_snprintf (name, 10, "4cc %c%c%c%c",
|
||||
(char) (format & 0xff),
|
||||
(char) ((format >> 8) & 0xff),
|
||||
(char) ((format >> 16) & 0xff),
|
||||
(char) ((format >> 24) & 0xff));
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
wl_shm_format (void *data,
|
||||
struct wl_shm *wl_shm,
|
||||
uint32_t format)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
char buf[10];
|
||||
#endif
|
||||
|
||||
GDK_DEBUG (MISC, "supported pixel format %s (0x%X)",
|
||||
get_format_name (format, buf), (guint) format);
|
||||
GDK_DEBUG (MISC, "supported shm pixel format %.4s (0x%X)",
|
||||
format == 0 ? "ARGB8888"
|
||||
: (format == 1 ? "XRGB8888"
|
||||
: (char *) &format), format);
|
||||
}
|
||||
|
||||
static const struct wl_shm_listener wl_shm_listener = {
|
||||
wl_shm_format
|
||||
};
|
||||
|
||||
static void
|
||||
linux_dmabuf_done (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
|
||||
{
|
||||
GDK_DEBUG (MISC, "dmabuf feedback done");
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_format_table (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
int32_t fd,
|
||||
uint32_t size)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
|
||||
display_wayland->linux_dmabuf_n_formats = size / 16;
|
||||
display_wayland->linux_dmabuf_formats = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf format table (%lu entries)", display_wayland->linux_dmabuf_n_formats);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_main_device (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
struct wl_array *device)
|
||||
{
|
||||
dev_t dev G_GNUC_UNUSED = *(dev_t *)device->data;
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf main device: %u %u", major (dev), minor (dev));
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_done (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
|
||||
{
|
||||
GDK_DEBUG (MISC, "dmabuf feedback tranche done");
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_target_device (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
struct wl_array *device)
|
||||
{
|
||||
dev_t dev G_GNUC_UNUSED = *(dev_t *)device->data;
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf tranche target device: %u %u", major (dev), minor (dev));
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_formats (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
struct wl_array *indices)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf tranche formats (%lu entries):", indices->size / sizeof (guint16));
|
||||
guint16 *pos;
|
||||
|
||||
wl_array_for_each (pos, indices)
|
||||
{
|
||||
LinuxDmabufFormat *fmt G_GNUC_UNUSED = &display_wayland->linux_dmabuf_formats[*pos];
|
||||
uint32_t f G_GNUC_UNUSED = fmt->fourcc;
|
||||
uint64_t m G_GNUC_UNUSED = fmt->modifier;
|
||||
GDK_DEBUG (MISC, " %.4s:%#" G_GINT64_MODIFIER "x", (char *) &f, m);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_flags (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
uint32_t flags)
|
||||
{
|
||||
GDK_DEBUG (MISC,
|
||||
"got dmabuf tranche flags: %s",
|
||||
flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT ? "scanout" : "");
|
||||
}
|
||||
|
||||
static const struct zwp_linux_dmabuf_feedback_v1_listener linux_dmabuf_feedback_listener = {
|
||||
linux_dmabuf_done,
|
||||
linux_dmabuf_format_table,
|
||||
linux_dmabuf_main_device,
|
||||
linux_dmabuf_tranche_done,
|
||||
linux_dmabuf_tranche_target_device,
|
||||
linux_dmabuf_tranche_formats,
|
||||
linux_dmabuf_tranche_flags,
|
||||
};
|
||||
|
||||
static void
|
||||
server_decoration_manager_default_mode (void *data,
|
||||
struct org_kde_kwin_server_decoration_manager *manager,
|
||||
uint32_t mode)
|
||||
{
|
||||
g_assert (mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *modes[] = {
|
||||
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE] = "none",
|
||||
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT] = "client",
|
||||
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER] = "server",
|
||||
};
|
||||
#endif
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
GDK_DISPLAY_DEBUG (GDK_DISPLAY (data), MISC, "Compositor prefers decoration mode '%s'", modes[mode]);
|
||||
display_wayland->server_decoration_mode = mode;
|
||||
@@ -382,6 +445,16 @@ gdk_registry_handle_global (void *data,
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1);
|
||||
wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland);
|
||||
}
|
||||
else if (strcmp (interface, "zwp_linux_dmabuf_v1") == 0 && version >= 4)
|
||||
{
|
||||
display_wayland->linux_dmabuf =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &zwp_linux_dmabuf_v1_interface, version);
|
||||
display_wayland->linux_dmabuf_feedback =
|
||||
zwp_linux_dmabuf_v1_get_default_feedback (display_wayland->linux_dmabuf);
|
||||
zwp_linux_dmabuf_feedback_v1_add_listener (display_wayland->linux_dmabuf_feedback,
|
||||
&linux_dmabuf_feedback_listener, display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
else if (strcmp (interface, "xdg_wm_base") == 0)
|
||||
{
|
||||
display_wayland->xdg_wm_base_id = id;
|
||||
@@ -726,6 +799,10 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
g_clear_pointer (&display_wayland->xdg_activation, xdg_activation_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->fractional_scale, wp_fractional_scale_manager_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->viewporter, wp_viewporter_destroy);
|
||||
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->linux_dmabuf_feedback, zwp_linux_dmabuf_feedback_v1_destroy);
|
||||
if (display_wayland->linux_dmabuf_formats)
|
||||
munmap (display_wayland->linux_dmabuf_formats, display_wayland->linux_dmabuf_n_formats * 16);
|
||||
|
||||
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
|
||||
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
|
||||
@@ -2243,8 +2320,6 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
subpixel_to_string (int layout)
|
||||
{
|
||||
@@ -2291,8 +2366,6 @@ transform_to_string (int transform)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
update_scale (GdkDisplay *display)
|
||||
{
|
||||
|
@@ -71,6 +71,13 @@ typedef enum _GdkWaylandShellVariant
|
||||
GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6
|
||||
} GdkWaylandShellVariant;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t fourcc;
|
||||
uint32_t padding;
|
||||
uint64_t modifier;
|
||||
} LinuxDmabufFormat;
|
||||
|
||||
struct _GdkWaylandDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
@@ -95,6 +102,10 @@ struct _GdkWaylandDisplay
|
||||
struct wl_registry *wl_registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
|
||||
struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback;
|
||||
gsize linux_dmabuf_n_formats;
|
||||
LinuxDmabufFormat *linux_dmabuf_formats;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct zxdg_shell_v6 *zxdg_shell_v6;
|
||||
struct gtk_shell1 *gtk_shell;
|
||||
|
@@ -340,14 +340,12 @@ gdk_wayland_drag_create_data_source (GdkDrag *drag)
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (formats, &n_mimetypes);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_drag_get_display (drag), EVENTS))
|
||||
{
|
||||
char *s = g_strjoinv (" ", (char **)mimetypes);
|
||||
gdk_debug_message ("create data source, mime types=%s", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
wl_data_source_offer (drag_wayland->data_source, GDK_WAYLAND_LOCAL_DND_MIME_TYPE);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
@@ -397,7 +395,7 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
|
||||
drag_wayland->data_source,
|
||||
gdk_wayland_surface_get_wl_surface (surface),
|
||||
gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface),
|
||||
_gdk_wayland_seat_get_implicit_grab_serial (seat, NULL));
|
||||
_gdk_wayland_seat_get_implicit_grab_serial (seat, device, NULL));
|
||||
|
||||
cursor = gdk_drag_get_cursor (drag, gdk_drag_get_selected_action (drag));
|
||||
gdk_drag_set_cursor (drag, cursor);
|
||||
|
@@ -191,14 +191,12 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drop_read_async);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_drop_get_display (drop), DND))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: read for %s", drop, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
gdk_drop_get_formats (drop));
|
||||
if (mime_type == NULL)
|
||||
@@ -210,7 +208,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
|
||||
g_task_set_task_data (task, (gpointer) mime_type, NULL);
|
||||
|
||||
if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
|
||||
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
|
@@ -75,7 +75,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
|
||||
|
||||
/* We should do ths when setting up the EGLSurface, but we don't make_current then */
|
||||
/* We should do this when setting up the EGLSurface, but we don't make_current then */
|
||||
eglSwapInterval (gdk_display_get_egl_display (gdk_draw_context_get_display (draw_context)), 0);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
@@ -83,6 +83,22 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (impl->has_pending_subsurface_commits)
|
||||
{
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_wayland_surface_commit (surface);
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
{
|
||||
@@ -91,6 +107,7 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
|
||||
draw_context_class->empty_frame = gdk_wayland_gl_context_empty_frame;
|
||||
|
||||
context_class->backend_type = GDK_GL_EGL;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user