Compare commits
218 Commits
3.32.1
...
wip/nielsd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e04cbddf92 | ||
![]() |
d3e789e677 | ||
![]() |
c24d8e856b | ||
![]() |
9db9793f33 | ||
![]() |
c237bc5f45 | ||
![]() |
178b975d6a | ||
![]() |
4abca411f3 | ||
![]() |
e48c7c009a | ||
![]() |
36b361617d | ||
![]() |
5eac1d696d | ||
![]() |
9b53583945 | ||
![]() |
1dbf25afa1 | ||
![]() |
e415cc538a | ||
![]() |
67a3715ded | ||
![]() |
35aa278194 | ||
![]() |
a76762a05e | ||
![]() |
ccf27e5f83 | ||
![]() |
912a9ecfba | ||
![]() |
0487d672ed | ||
![]() |
e94a0fced9 | ||
![]() |
a3b86447f7 | ||
![]() |
1d76eace1e | ||
![]() |
c1303bd642 | ||
![]() |
db11a37a68 | ||
![]() |
0d0b9da6f8 | ||
![]() |
ab0b407da4 | ||
![]() |
c33b330799 | ||
![]() |
144b24bfcc | ||
![]() |
4d21650d6d | ||
![]() |
a6fc656e91 | ||
![]() |
a38bae259e | ||
![]() |
c53aa89098 | ||
![]() |
851b7d0639 | ||
![]() |
b4c78726cf | ||
![]() |
c9cc07fd3a | ||
![]() |
f6eb2a8cf8 | ||
![]() |
08e5589836 | ||
![]() |
4f5a5e84fc | ||
![]() |
0786683189 | ||
![]() |
4887de533c | ||
![]() |
57945a730f | ||
![]() |
78254146f3 | ||
![]() |
3e2a2cf532 | ||
![]() |
04b240b50c | ||
![]() |
7810f0e276 | ||
![]() |
9b8f9b65b8 | ||
![]() |
e741cab3f4 | ||
![]() |
53748e3da7 | ||
![]() |
17c5436f6e | ||
![]() |
04fb6f7659 | ||
![]() |
e5e58f8075 | ||
![]() |
1da0355528 | ||
![]() |
e5881156f6 | ||
![]() |
60170cff70 | ||
![]() |
e2bea48073 | ||
![]() |
bbfaf8204b | ||
![]() |
b3e19ee669 | ||
![]() |
75e2bfb062 | ||
![]() |
a859d76c72 | ||
![]() |
2145333969 | ||
![]() |
1b61b9cd73 | ||
![]() |
a2c545c321 | ||
![]() |
3cd8f3b7dc | ||
![]() |
033ce2d956 | ||
![]() |
2b47e89405 | ||
![]() |
80d11287eb | ||
![]() |
f869e4d54b | ||
![]() |
c1059df7f9 | ||
![]() |
e3d3df985f | ||
![]() |
86ff3dfb3c | ||
![]() |
7e0d185120 | ||
![]() |
61c173b777 | ||
![]() |
f99cd18254 | ||
![]() |
0405786573 | ||
![]() |
b016ff29f6 | ||
![]() |
3f2e86f67c | ||
![]() |
0aa4a526c6 | ||
![]() |
85c2aef4bc | ||
![]() |
76664ef891 | ||
![]() |
b1ea768949 | ||
![]() |
ea9d8a895b | ||
![]() |
38432da328 | ||
![]() |
430f354cd9 | ||
![]() |
1cf4279745 | ||
![]() |
7713006f5b | ||
![]() |
465e13128b | ||
![]() |
86de79cfc5 | ||
![]() |
1d77641f0b | ||
![]() |
2f217109aa | ||
![]() |
5e0523cc8b | ||
![]() |
dbe6e01e12 | ||
![]() |
103c469cc9 | ||
![]() |
ef074ea510 | ||
![]() |
39bac6eabd | ||
![]() |
0200f4fcd9 | ||
![]() |
439afb3f19 | ||
![]() |
b01edc22f3 | ||
![]() |
e8bca5052a | ||
![]() |
468882ecec | ||
![]() |
be3c89d823 | ||
![]() |
7719e33e68 | ||
![]() |
deef9960a4 | ||
![]() |
9305b6d8ee | ||
![]() |
62de4b4f82 | ||
![]() |
ea0a89bde8 | ||
![]() |
4faeb12731 | ||
![]() |
91ac64bb44 | ||
![]() |
ed56edc7ba | ||
![]() |
6eeba2434a | ||
![]() |
7fb7b28cd6 | ||
![]() |
08aec58c22 | ||
![]() |
52945f383d | ||
![]() |
fecc57ddf0 | ||
![]() |
0d7a929b83 | ||
![]() |
991f9505ad | ||
![]() |
358b67871f | ||
![]() |
2b1acea1b0 | ||
![]() |
91aee3d5c4 | ||
![]() |
02812fb988 | ||
![]() |
29211c9020 | ||
![]() |
68fba458b3 | ||
![]() |
9c2fdcdbb2 | ||
![]() |
d4a0893d76 | ||
![]() |
7a6c755833 | ||
![]() |
45244852ac | ||
![]() |
e96136e418 | ||
![]() |
eae6e7a889 | ||
![]() |
a48b6cc9ca | ||
![]() |
786305f7d6 | ||
![]() |
30a2483e6e | ||
![]() |
f5f0aa1023 | ||
![]() |
b86fba2f3c | ||
![]() |
f7ecf3b618 | ||
![]() |
7a17e236f7 | ||
![]() |
df7d8e2cbf | ||
![]() |
9e82f9af25 | ||
![]() |
329c4bc5b3 | ||
![]() |
706c5a7565 | ||
![]() |
24b3467584 | ||
![]() |
9e0e35d2a7 | ||
![]() |
dae2c1d420 | ||
![]() |
01d0316fd7 | ||
![]() |
7e2a0ede16 | ||
![]() |
7738b5c00b | ||
![]() |
454651f79f | ||
![]() |
bf8bc65cc9 | ||
![]() |
6a89e7969f | ||
![]() |
3ffc4f8876 | ||
![]() |
b4d973fbe4 | ||
![]() |
da1e917b38 | ||
![]() |
160d2d56d9 | ||
![]() |
3468144847 | ||
![]() |
ae6d9e35bd | ||
![]() |
ac15a8abca | ||
![]() |
5480a3f238 | ||
![]() |
0d50a37091 | ||
![]() |
1ca0fdc928 | ||
![]() |
23a8ea2821 | ||
![]() |
ee4bb2240b | ||
![]() |
81ae886dda | ||
![]() |
63c40a9711 | ||
![]() |
8374be46d2 | ||
![]() |
5d1a87d355 | ||
![]() |
34312c272b | ||
![]() |
2b8f5e65b6 | ||
![]() |
a934fa07b8 | ||
![]() |
c6d1cf4af4 | ||
![]() |
8dbe4210b4 | ||
![]() |
02c99524bf | ||
![]() |
17d00d49d4 | ||
![]() |
634f512bb0 | ||
![]() |
5c009c20ab | ||
![]() |
535ce00abb | ||
![]() |
37144f0609 | ||
![]() |
ab76576340 | ||
![]() |
09aa82db49 | ||
![]() |
c95db7c542 | ||
![]() |
a984622cd1 | ||
![]() |
156980eff9 | ||
![]() |
736cac43e9 | ||
![]() |
3ba79961fe | ||
![]() |
7718e67f5c | ||
![]() |
ba8f5a1178 | ||
![]() |
502da973eb | ||
![]() |
eccf7b105c | ||
![]() |
bcee890434 | ||
![]() |
251fa024c4 | ||
![]() |
471b61bd14 | ||
![]() |
7df86fb246 | ||
![]() |
3f29b47809 | ||
![]() |
9ab3a02a8a | ||
![]() |
ca2be8ef5b | ||
![]() |
1783ea5af1 | ||
![]() |
862e56f01d | ||
![]() |
2b9cd50e84 | ||
![]() |
e71f44dbd6 | ||
![]() |
c881b4970d | ||
![]() |
d79f176142 | ||
![]() |
ce6acf9dca | ||
![]() |
2a15e5f16a | ||
![]() |
fb40e2eefb | ||
![]() |
fc09fa50a5 | ||
![]() |
48f04c7968 | ||
![]() |
007297f1a6 | ||
![]() |
302a171c08 | ||
![]() |
893e894fff | ||
![]() |
2aaed7bdfc | ||
![]() |
249f9a4a2e | ||
![]() |
68166f33d9 | ||
![]() |
28954e8271 | ||
![]() |
22884b0b00 | ||
![]() |
d2415da0d4 | ||
![]() |
96f7bf28f1 | ||
![]() |
db486ad897 | ||
![]() |
8180927de2 | ||
![]() |
191c31b0f0 | ||
![]() |
a94841abf1 | ||
![]() |
b624e94ab1 |
@@ -1,4 +1,4 @@
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v1
|
||||
image: registry.gitlab.gnome.org/gnome/mutter/master:v2
|
||||
|
||||
stages:
|
||||
- review
|
||||
@@ -7,6 +7,8 @@ stages:
|
||||
|
||||
check-commit-log:
|
||||
stage: review
|
||||
variables:
|
||||
GIT_DEPTH: "100"
|
||||
script:
|
||||
- ./.gitlab-ci/check-commit-log.sh
|
||||
only:
|
||||
@@ -15,7 +17,7 @@ check-commit-log:
|
||||
build-mutter:
|
||||
stage: build
|
||||
script:
|
||||
- meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror
|
||||
- meson . build -Dbuildtype=debugoptimized -Degl_device=true -Dwayland_eglstream=true --werror --prefix /usr
|
||||
- ninja -C build
|
||||
- ninja -C build install
|
||||
artifacts:
|
||||
@@ -33,12 +35,31 @@ test-mutter:
|
||||
variables:
|
||||
XDG_RUNTIME_DIR: "$CI_PROJECT_DIR/runtime-dir"
|
||||
GSETTINGS_SCHEMA_DIR: "$CI_PROJECT_DIR/build/data"
|
||||
G_SLICE: "always-malloc"
|
||||
MALLOC_CHECK_: "3"
|
||||
NO_AT_BRIDGE: "1"
|
||||
MALLOC_PERTURB_: "123"
|
||||
script:
|
||||
- dconf update
|
||||
- mkdir -m 700 $XDG_RUNTIME_DIR
|
||||
- glib-compile-schemas $GSETTINGS_SCHEMA_DIR
|
||||
- >
|
||||
dbus-run-session -- xvfb-run -s '+iglx -noreset'
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --wrap catchsegv
|
||||
meson test -C build --no-rebuild -t 10 --verbose --no-stdsplit --print-errorlogs --wrap catchsegv
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
||||
can-build-gnome-shell:
|
||||
stage: test
|
||||
dependencies:
|
||||
- build-mutter
|
||||
before_script:
|
||||
- meson install --no-rebuild -C build
|
||||
script:
|
||||
- .gitlab-ci/checkout-gnome-shell.sh
|
||||
- meson gnome-shell gnome-shell/build --prefix /usr
|
||||
- ninja -C gnome-shell/build install
|
||||
only:
|
||||
- merge_requests
|
||||
- /^.*$/
|
||||
|
@@ -1,17 +1,27 @@
|
||||
FROM fedora:29
|
||||
FROM fedora:30
|
||||
|
||||
RUN dnf -y update && dnf -y upgrade && \
|
||||
dnf install -y 'dnf-command(builddep)' && \
|
||||
dnf install -y 'dnf-command(copr)' && \
|
||||
dnf copr enable -y fmuellner/gnome-shell-ci && \
|
||||
|
||||
dnf builddep -y mutter && \
|
||||
|
||||
# Until Fedora catches up with meson build-deps
|
||||
dnf install -y meson xorg-x11-server-Xorg gnome-settings-daemon-devel egl-wayland-devel xorg-x11-server-Xwayland && \
|
||||
|
||||
# For running unit tests
|
||||
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 && \
|
||||
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs && \
|
||||
|
||||
# Unpackaged versions
|
||||
dnf install -y https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00848426-gsettings-desktop-schemas/gsettings-desktop-schemas-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00848426-gsettings-desktop-schemas/gsettings-desktop-schemas-devel-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm && \
|
||||
dnf install -y https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/jadahl/mutter-ci/fedora-29-x86_64/00834984-gsettings-desktop-schemas/gsettings-desktop-schemas-devel-3.30.1-1.20181206git918efdd69be53.fc29.x86_64.rpm && \
|
||||
dnf install -y https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/libsysprof-ui-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-cli-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-3.33.2-1.fc30.x86_64.rpm https://copr-be.cloud.fedoraproject.org/results/hergertme/sysprof-3/fedora-30-x86_64/00917385-sysprof/sysprof-devel-3.33.2-1.fc30.x86_64.rpm && \
|
||||
|
||||
dnf install -y intltool redhat-rpm-config make && \
|
||||
|
||||
# GNOME Shell
|
||||
dnf builddep -y gnome-shell --setopt=install_weak_deps=False && \
|
||||
dnf remove -y gnome-bluetooth-libs-devel dbus-glib-devel upower-devel python3-devel && \
|
||||
dnf remove -y --noautoremove mutter mutter-devel && \
|
||||
|
||||
dnf clean all
|
||||
|
35
.gitlab-ci/checkout-gnome-shell.sh
Executable file
35
.gitlab-ci/checkout-gnome-shell.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
mutter_branch=$(git describe --contains --all HEAD)
|
||||
gnome_shell_target=
|
||||
|
||||
git clone https://gitlab.gnome.org/GNOME/gnome-shell.git
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo Checkout failed
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd gnome-shell
|
||||
|
||||
if [ "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then
|
||||
merge_request_remote=${CI_MERGE_REQUEST_SOURCE_PROJECT_URL//mutter/gnome-shell}
|
||||
merge_request_branch=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
|
||||
|
||||
echo Looking for $merge_request_branch on remote ...
|
||||
if git fetch -q $merge_request_remote $merge_request_branch 2>/dev/null; then
|
||||
gnome_shell_target=FETCH_HEAD
|
||||
else
|
||||
gnome_shell_target=origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME
|
||||
echo Using $gnome_shell_target instead
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$gnome_shell_target" ]; then
|
||||
gnome_shell_target=$(git branch -r -l origin/$mutter_branch)
|
||||
gnome_shell_target=${gnome_shell_target:-$(git branch -r -l ${mutter_branch#remotes/})}
|
||||
gnome_shell_target=${gnome_shell_target:-origin/master}
|
||||
echo Using $gnome_shell_target instead
|
||||
fi
|
||||
|
||||
git checkout -q $gnome_shell_target
|
40
NEWS
40
NEWS
@@ -1,3 +1,43 @@
|
||||
3.33.2
|
||||
======
|
||||
* Fix rendering lag on Xorg [Daniel; !520, !281]
|
||||
* Misc. bug fixes and cleanups [Carlos, Marco, Jonas D., Florian, Niels,
|
||||
Daniel, Benjamin, Jonas Å., Ignacio, Vasilis; #598, !576, !547, !578,
|
||||
!583, !582, !469, !524, !119, !571, !584, !585, !586, #425]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Benjamin Berg, Jonas Dreßler, Carlos Garnacho, Niels De Graef,
|
||||
Vasilis Liaskovitis, Florian Müllner, Ignacio Casal Quinteiro,
|
||||
Marco Trevisan (Treviño), Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.33.1
|
||||
======
|
||||
* Remove unused APIs and outdated driver support
|
||||
[Adam; !481, !468, !489, !487, !546]
|
||||
* Enable EGL_IMG_context_priority [Adam; !454]
|
||||
* Disable mouse keys with Numlock on [Olivier; #530]
|
||||
* Fix crash when restarting on X11 [Marco; #576]
|
||||
* Implement clipboard manager [Carlos; !320]
|
||||
* Fix spurious idle signals that prevent session unblank [Jonas Å.; !543]
|
||||
* Fix mapping of touchscreens that don't report dimensions [Carlos; #581]
|
||||
* Fix propagating fractional scaling factor [Robert; !537]
|
||||
* Add experimental RT scheduling support [Carlos; !460]
|
||||
* Misc. bug fixes and cleanups [Robert, Carlos, Olivier, Ray, Marco, Jonas D.,
|
||||
Georges, Daniel V., Daniel M; !467, !504, !551, !552, #575, #556, !557, !442,
|
||||
!562, !535, !548, #586, !567, !396, !422, !507]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Piotr Drąg, Jonas Dreßler, Olivier Fourdan, Carlos Garnacho,
|
||||
Adam Jackson, Robert Mader, Daniel García Moreno, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Ray Strode, Marco Trevisan (Treviño),
|
||||
Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es], Fabio Tomat [fur], Kukuh Syafaat [id]
|
||||
|
||||
3.32.1
|
||||
======
|
||||
* Fix fallback app menu on wayland [Florian; #493]
|
||||
|
@@ -1044,10 +1044,8 @@ _cally_actor_clean_action_list (CallyActor *cally_actor)
|
||||
|
||||
if (priv->action_list)
|
||||
{
|
||||
g_list_foreach (priv->action_list,
|
||||
(GFunc) _cally_actor_destroy_action_info,
|
||||
NULL);
|
||||
g_list_free (priv->action_list);
|
||||
g_list_free_full (priv->action_list,
|
||||
(GDestroyNotify) _cally_actor_destroy_action_info);
|
||||
priv->action_list = NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -577,8 +577,7 @@ _clutter_meta_group_clear_metas (ClutterMetaGroup *group)
|
||||
{
|
||||
g_list_foreach (group->meta, (GFunc) _clutter_actor_meta_set_actor, NULL);
|
||||
|
||||
g_list_foreach (group->meta, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (group->meta);
|
||||
g_list_free_full (group->meta, g_object_unref);
|
||||
group->meta = NULL;
|
||||
}
|
||||
|
||||
|
@@ -807,6 +807,9 @@ struct _ClutterActorPrivate
|
||||
gpointer create_child_data;
|
||||
GDestroyNotify create_child_notify;
|
||||
|
||||
guint resolution_changed_id;
|
||||
guint font_changed_id;
|
||||
|
||||
/* bitfields: KEEP AT THE END */
|
||||
|
||||
/* fixed position and sizes */
|
||||
@@ -5983,6 +5986,7 @@ clutter_actor_dispose (GObject *object)
|
||||
{
|
||||
ClutterActor *self = CLUTTER_ACTOR (object);
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
|
||||
CLUTTER_NOTE (MISC, "Dispose actor (name='%s', ref_count:%d) of type '%s'",
|
||||
_clutter_actor_get_debug_name (self),
|
||||
@@ -6019,6 +6023,18 @@ clutter_actor_dispose (GObject *object)
|
||||
g_assert (!CLUTTER_ACTOR_IS_REALIZED (self));
|
||||
}
|
||||
|
||||
if (priv->resolution_changed_id)
|
||||
{
|
||||
g_signal_handler_disconnect (backend, priv->resolution_changed_id);
|
||||
priv->resolution_changed_id = 0;
|
||||
}
|
||||
|
||||
if (priv->font_changed_id)
|
||||
{
|
||||
g_signal_handler_disconnect (backend, priv->font_changed_id);
|
||||
priv->font_changed_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->pango_context);
|
||||
g_clear_object (&priv->actions);
|
||||
g_clear_object (&priv->constraints);
|
||||
@@ -8833,9 +8849,9 @@ _clutter_actor_queue_redraw_full (ClutterActor *self,
|
||||
*
|
||||
* later during _clutter_stage_do_update(), once relayouting is done
|
||||
* and the scenegraph has been updated we will call:
|
||||
* _clutter_stage_finish_queue_redraws().
|
||||
* clutter_stage_maybe_finish_queue_redraws().
|
||||
*
|
||||
* _clutter_stage_finish_queue_redraws() will call
|
||||
* clutter_stage_maybe_finish_queue_redraws() will call
|
||||
* _clutter_actor_finish_queue_redraw() for each listed actor.
|
||||
*
|
||||
* Note: actors *are* allowed to queue further redraws during this
|
||||
@@ -15884,10 +15900,12 @@ clutter_actor_get_pango_context (ClutterActor *self)
|
||||
{
|
||||
priv->pango_context = clutter_actor_create_pango_context (self);
|
||||
|
||||
g_signal_connect_object (backend, "resolution-changed",
|
||||
G_CALLBACK (update_pango_context), priv->pango_context, 0);
|
||||
g_signal_connect_object (backend, "font-changed",
|
||||
G_CALLBACK (update_pango_context), priv->pango_context, 0);
|
||||
priv->resolution_changed_id =
|
||||
g_signal_connect_object (backend, "resolution-changed",
|
||||
G_CALLBACK (update_pango_context), priv->pango_context, 0);
|
||||
priv->font_changed_id =
|
||||
g_signal_connect_object (backend, "font-changed",
|
||||
G_CALLBACK (update_pango_context), priv->pango_context, 0);
|
||||
}
|
||||
else
|
||||
update_pango_context (backend, priv->pango_context);
|
||||
@@ -17533,7 +17551,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
l != NULL && l->data != priv->current_effect;
|
||||
l = l->next)
|
||||
{
|
||||
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
||||
if (!_clutter_effect_modify_paint_volume (l->data, pv))
|
||||
{
|
||||
clutter_paint_volume_free (pv);
|
||||
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
|
||||
@@ -17551,7 +17569,7 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
|
||||
/* otherwise, get the cumulative volume */
|
||||
effects = _clutter_meta_group_peek_metas (priv->effects);
|
||||
for (l = effects; l != NULL; l = l->next)
|
||||
if (!_clutter_effect_get_paint_volume (l->data, pv))
|
||||
if (!_clutter_effect_modify_paint_volume (l->data, pv))
|
||||
{
|
||||
clutter_paint_volume_free (pv);
|
||||
CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
|
||||
|
@@ -235,8 +235,7 @@ clutter_binding_pool_finalize (GObject *gobject)
|
||||
|
||||
g_hash_table_destroy (pool->entries_hash);
|
||||
|
||||
g_slist_foreach (pool->entries, (GFunc) binding_entry_free, NULL);
|
||||
g_slist_free (pool->entries);
|
||||
g_slist_free_full (pool->entries, (GDestroyNotify) binding_entry_free);
|
||||
|
||||
G_OBJECT_CLASS (clutter_binding_pool_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
@@ -178,8 +178,8 @@ clutter_blur_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_blur_effect_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
clutter_blur_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
gfloat cur_width, cur_height;
|
||||
ClutterVertex origin;
|
||||
@@ -223,7 +223,7 @@ clutter_blur_effect_class_init (ClutterBlurEffectClass *klass)
|
||||
gobject_class->dispose = clutter_blur_effect_dispose;
|
||||
|
||||
effect_class->pre_paint = clutter_blur_effect_pre_paint;
|
||||
effect_class->get_paint_volume = clutter_blur_effect_get_paint_volume;
|
||||
effect_class->modify_paint_volume = clutter_blur_effect_modify_paint_volume;
|
||||
|
||||
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass);
|
||||
offscreen_class->paint_target = clutter_blur_effect_paint_target;
|
||||
@@ -249,9 +249,7 @@ clutter_blur_effect_init (ClutterBlurEffect *self)
|
||||
cogl_pipeline_add_layer_snippet (klass->base_pipeline, 0, snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
|
||||
0, /* layer number */
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
@@ -438,9 +438,7 @@ clutter_brightness_contrast_effect_init (ClutterBrightnessContrastEffect *self)
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
|
||||
0, /* layer number */
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
@@ -355,6 +355,10 @@ on_captured_event (ClutterActor *stage,
|
||||
|
||||
switch (clutter_event_type (event))
|
||||
{
|
||||
case CLUTTER_TOUCH_CANCEL:
|
||||
clutter_click_action_release (action);
|
||||
break;
|
||||
|
||||
case CLUTTER_TOUCH_END:
|
||||
has_button = FALSE;
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
|
@@ -293,9 +293,7 @@ clutter_colorize_effect_init (ClutterColorizeEffect *self)
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
|
||||
0, /* layer number */
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
@@ -282,6 +282,7 @@ clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
|
||||
/* enable depth testing */
|
||||
cogl_depth_state_init (&depth_state);
|
||||
cogl_depth_state_set_test_enabled (&depth_state, TRUE);
|
||||
cogl_depth_state_set_test_function (&depth_state, COGL_DEPTH_TEST_FUNCTION_LEQUAL);
|
||||
cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);
|
||||
|
||||
/* enable backface culling if we have a back material */
|
||||
|
@@ -297,9 +297,7 @@ clutter_desaturate_effect_init (ClutterDesaturateEffect *self)
|
||||
cogl_pipeline_add_snippet (klass->base_pipeline, snippet);
|
||||
cogl_object_unref (snippet);
|
||||
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline,
|
||||
0, /* layer number */
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_null_texture (klass->base_pipeline, 0);
|
||||
}
|
||||
|
||||
self->pipeline = cogl_pipeline_copy (klass->base_pipeline);
|
||||
|
@@ -69,6 +69,22 @@ typedef struct _ClutterTouchInfo
|
||||
gfloat current_y;
|
||||
} ClutterTouchInfo;
|
||||
|
||||
typedef struct _ClutterPtrA11yData
|
||||
{
|
||||
int n_btn_pressed;
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
float dwell_x;
|
||||
float dwell_y;
|
||||
gboolean dwell_drag_started;
|
||||
gboolean dwell_gesture_started;
|
||||
guint dwell_timer;
|
||||
|
||||
guint secondary_click_timer;
|
||||
gboolean secondary_click_triggered;
|
||||
} ClutterPtrA11yData;
|
||||
|
||||
struct _ClutterInputDevice
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -143,6 +159,10 @@ struct _ClutterInputDevice
|
||||
|
||||
guint has_cursor : 1;
|
||||
guint is_enabled : 1;
|
||||
|
||||
/* Accessiblity */
|
||||
ClutterVirtualInputDevice *accessibility_virtual_device;
|
||||
ClutterPtrA11yData *ptr_a11y_data;
|
||||
};
|
||||
|
||||
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
#include "clutter-input-device-tool.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
|
||||
struct _ClutterDeviceManagerPrivate
|
||||
{
|
||||
@@ -55,6 +56,8 @@ struct _ClutterDeviceManagerPrivate
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
/* Pointer a11y */
|
||||
ClutterPointerA11ySettings pointer_a11y_settings;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -75,6 +78,9 @@ enum
|
||||
TOOL_CHANGED,
|
||||
KBD_A11Y_MASK_CHANGED,
|
||||
KBD_A11Y_FLAGS_CHANGED,
|
||||
PTR_A11Y_DWELL_CLICK_TYPE_CHANGED,
|
||||
PTR_A11Y_TIMEOUT_STARTED,
|
||||
PTR_A11Y_TIMEOUT_STOPPED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@@ -239,6 +245,67 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::ptr-a11y-dwell-click-type-changed:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @click_type: the new #ClutterPointerA11yDwellClickType mode
|
||||
*
|
||||
* The ::ptr-a11y-dwell-click-type-changed signal is emitted each time
|
||||
* the ClutterPointerA11yDwellClickType mode is changed as the result
|
||||
* of pointer accessibility operations.
|
||||
*/
|
||||
manager_signals[PTR_A11Y_DWELL_CLICK_TYPE_CHANGED] =
|
||||
g_signal_new (I_("ptr-a11y-dwell-click-type-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__FLAGS,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_POINTER_A11Y_DWELL_CLICK_TYPE);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::ptr-a11y-timeout-started:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @device: the core pointer #ClutterInputDevice
|
||||
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
|
||||
* @delay: the delay in ms before secondary-click is triggered.
|
||||
*
|
||||
* The ::ptr-a11y-timeout-started signal is emitted when a
|
||||
* pointer accessibility timeout delay is started, so that upper
|
||||
* layers can notify the user with some visual feedback.
|
||||
*/
|
||||
manager_signals[PTR_A11Y_TIMEOUT_STARTED] =
|
||||
g_signal_new (I_("ptr-a11y-timeout-started"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT_FLAGS_UINT,
|
||||
G_TYPE_NONE, 3,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::ptr-a11y-timeout-stopped:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @device: the core pointer #ClutterInputDevice
|
||||
* @timeout_type: the type of timeout #ClutterPointerA11yTimeoutType
|
||||
*
|
||||
* The ::ptr-a11y-timeout-stopped signal is emitted when a running
|
||||
* pointer accessibility timeout delay is stopped, either because
|
||||
* it's triggered at the end of the delay or cancelled, so that
|
||||
* upper layers can notify the user with some visual feedback.
|
||||
*/
|
||||
manager_signals[PTR_A11Y_TIMEOUT_STOPPED] =
|
||||
g_signal_new (I_("ptr-a11y-timeout-stopped"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT_FLAGS,
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_POINTER_A11Y_TIMEOUT_TYPE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -579,3 +646,88 @@ clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_man
|
||||
|
||||
*settings = device_manager->priv->kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
are_pointer_a11y_settings_equal (ClutterPointerA11ySettings *a,
|
||||
ClutterPointerA11ySettings *b)
|
||||
{
|
||||
return (memcmp (a, b, sizeof (ClutterPointerA11ySettings)) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_enable_pointer_a11y (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
_clutter_input_pointer_a11y_add_device (core_pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_disable_pointer_a11y (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
_clutter_input_pointer_a11y_remove_device (core_pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_set_pointer_a11y_settings:
|
||||
* @device_manager: a #ClutterDeviceManager
|
||||
* @settings: a pointer to a #ClutterPointerA11ySettings
|
||||
*
|
||||
* Sets the pointer accessibility settings
|
||||
**/
|
||||
void
|
||||
clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
if (are_pointer_a11y_settings_equal (&device_manager->priv->pointer_a11y_settings, settings))
|
||||
return;
|
||||
|
||||
if (device_manager->priv->pointer_a11y_settings.controls == 0 && settings->controls != 0)
|
||||
clutter_device_manager_enable_pointer_a11y (device_manager);
|
||||
else if (device_manager->priv->pointer_a11y_settings.controls != 0 && settings->controls == 0)
|
||||
clutter_device_manager_disable_pointer_a11y (device_manager);
|
||||
|
||||
device_manager->priv->pointer_a11y_settings = *settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_get_pointer_a11y_settings:
|
||||
* @device_manager: a #ClutterDeviceManager
|
||||
* @settings: a pointer to a #ClutterPointerA11ySettings
|
||||
*
|
||||
* Gets the current pointer accessibility settings
|
||||
**/
|
||||
void
|
||||
clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
*settings = device_manager->priv->pointer_a11y_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_set_pointer_a11y_dwell_click_type:
|
||||
* @device_manager: a #ClutterDeviceManager
|
||||
* @click_type: type of click as #ClutterPointerA11yDwellClickType
|
||||
*
|
||||
* Sets the dwell click type
|
||||
**/
|
||||
void
|
||||
clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11yDwellClickType click_type)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
device_manager->priv->pointer_a11y_settings.dwell_click_type = click_type;
|
||||
}
|
||||
|
@@ -73,6 +73,27 @@ typedef struct _ClutterKbdA11ySettings
|
||||
gint mousekeys_accel_time;
|
||||
} ClutterKbdA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11ySettings:
|
||||
*
|
||||
* The #ClutterPointerA11ySettings structure contains pointer accessibility
|
||||
* settings
|
||||
*
|
||||
*/
|
||||
typedef struct _ClutterPointerA11ySettings
|
||||
{
|
||||
ClutterPointerA11yFlags controls;
|
||||
ClutterPointerA11yDwellClickType dwell_click_type;
|
||||
ClutterPointerA11yDwellMode dwell_mode;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_single;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_double;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_drag;
|
||||
ClutterPointerA11yDwellDirection dwell_gesture_secondary;
|
||||
gint secondary_click_delay;
|
||||
gint dwell_delay;
|
||||
gint dwell_threshold;
|
||||
} ClutterPointerA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager:
|
||||
*
|
||||
@@ -152,10 +173,23 @@ ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_typ
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_set_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_get_pointer_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11ySettings *settings);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_device_manager_set_pointer_a11y_dwell_click_type (ClutterDeviceManager *device_manager,
|
||||
ClutterPointerA11yDwellClickType click_type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */
|
||||
|
@@ -7,7 +7,7 @@ G_BEGIN_DECLS
|
||||
|
||||
gboolean _clutter_effect_pre_paint (ClutterEffect *effect);
|
||||
void _clutter_effect_post_paint (ClutterEffect *effect);
|
||||
gboolean _clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||
gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);
|
||||
void _clutter_effect_paint (ClutterEffect *effect,
|
||||
|
@@ -188,8 +188,8 @@ clutter_effect_real_post_paint (ClutterEffect *effect)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_effect_real_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ clutter_effect_class_init (ClutterEffectClass *klass)
|
||||
|
||||
klass->pre_paint = clutter_effect_real_pre_paint;
|
||||
klass->post_paint = clutter_effect_real_post_paint;
|
||||
klass->get_paint_volume = clutter_effect_real_get_paint_volume;
|
||||
klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
|
||||
klass->paint = clutter_effect_real_paint;
|
||||
klass->pick = clutter_effect_real_pick;
|
||||
}
|
||||
@@ -297,13 +297,14 @@ _clutter_effect_pick (ClutterEffect *effect,
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_effect_get_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
_clutter_effect_modify_paint_volume (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
g_return_val_if_fail (volume != NULL, FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume (effect, volume);
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume (effect,
|
||||
volume);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -311,7 +312,7 @@ _clutter_effect_has_custom_paint_volume (ClutterEffect *effect)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
|
||||
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->get_paint_volume != clutter_effect_real_get_paint_volume;
|
||||
return CLUTTER_EFFECT_GET_CLASS (effect)->modify_paint_volume != clutter_effect_real_modify_paint_volume;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -60,7 +60,7 @@ struct _ClutterEffect
|
||||
* ClutterEffectClass:
|
||||
* @pre_paint: virtual function
|
||||
* @post_paint: virtual function
|
||||
* @get_paint_volume: virtual function
|
||||
* @modify_paint_volume: virtual function
|
||||
* @paint: virtual function
|
||||
* @pick: virtual function
|
||||
*
|
||||
@@ -74,16 +74,16 @@ struct _ClutterEffectClass
|
||||
ClutterActorMetaClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
gboolean (* pre_paint) (ClutterEffect *effect);
|
||||
void (* post_paint) (ClutterEffect *effect);
|
||||
gboolean (* pre_paint) (ClutterEffect *effect);
|
||||
void (* post_paint) (ClutterEffect *effect);
|
||||
|
||||
gboolean (* get_paint_volume) (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
gboolean (* modify_paint_volume) (ClutterEffect *effect,
|
||||
ClutterPaintVolume *volume);
|
||||
|
||||
void (* paint) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* pick) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* paint) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
void (* pick) (ClutterEffect *effect,
|
||||
ClutterEffectPaintFlags flags);
|
||||
|
||||
/*< private >*/
|
||||
void (* _clutter_effect4) (void);
|
||||
|
@@ -443,6 +443,88 @@ typedef enum
|
||||
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
||||
} ClutterKeyboardA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yFlags:
|
||||
* @CLUTTER_A11Y_POINTER_ENABLED:
|
||||
* @CLUTTER_A11Y_SECONDARY_CLICK_ENABLED:
|
||||
* @CLUTTER_A11Y_DWELL_ENABLED:
|
||||
*
|
||||
* Pointer accessibility features applied to a ClutterInputDevice pointer.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_SECONDARY_CLICK_ENABLED = 1 << 0,
|
||||
CLUTTER_A11Y_DWELL_ENABLED = 1 << 1,
|
||||
} ClutterPointerA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yDwellClickType:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE: Internal use only
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
|
||||
* @CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
|
||||
*
|
||||
* Dwell click types.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE,
|
||||
CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG,
|
||||
} ClutterPointerA11yDwellClickType;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yDwellDirection:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_NONE:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_LEFT:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_RIGHT:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_UP:
|
||||
* @CLUTTER_A11Y_DWELL_DIRECTION_DOWN:
|
||||
*
|
||||
* Dwell gesture directions.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_NONE,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_LEFT,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_RIGHT,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_UP,
|
||||
CLUTTER_A11Y_DWELL_DIRECTION_DOWN,
|
||||
} ClutterPointerA11yDwellDirection;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yDwellMode:
|
||||
* @CLUTTER_A11Y_DWELL_MODE_WINDOW:
|
||||
* @CLUTTER_A11Y_DWELL_MODE_GESTURE:
|
||||
*
|
||||
* Dwell mode.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_DWELL_MODE_WINDOW,
|
||||
CLUTTER_A11Y_DWELL_MODE_GESTURE,
|
||||
} ClutterPointerA11yDwellMode;
|
||||
|
||||
/**
|
||||
* ClutterPointerA11yTimeoutType:
|
||||
* @CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK:
|
||||
* @CLUTTER_A11Y_TIMEOUT_TYPE_DWELL:
|
||||
* @CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE:
|
||||
*
|
||||
* Pointer accessibility timeout type.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
} ClutterPointerA11yTimeoutType;
|
||||
|
||||
/**
|
||||
* ClutterActorFlags:
|
||||
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
|
||||
@@ -909,7 +991,6 @@ typedef enum
|
||||
|
||||
/**
|
||||
* ClutterFeatureFlags:
|
||||
* @CLUTTER_FEATURE_TEXTURE_NPOT: Set if NPOTS textures supported.
|
||||
* @CLUTTER_FEATURE_SWAP_THROTTLE: Set if backend throttles buffer swaps.
|
||||
* @CLUTTER_FEATURE_TEXTURE_YUV: Set if YUV based textures supported.
|
||||
* @CLUTTER_FEATURE_TEXTURE_READ_PIXELS: Set if texture pixels can be read.
|
||||
@@ -928,7 +1009,6 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLUTTER_FEATURE_TEXTURE_NPOT = (1 << 2),
|
||||
CLUTTER_FEATURE_SWAP_THROTTLE = (1 << 3),
|
||||
CLUTTER_FEATURE_TEXTURE_YUV = (1 << 4),
|
||||
CLUTTER_FEATURE_TEXTURE_READ_PIXELS = (1 << 5),
|
||||
|
@@ -1021,6 +1021,9 @@ clutter_event_get_event_sequence (const ClutterEvent *event)
|
||||
event->type == CLUTTER_TOUCH_END ||
|
||||
event->type == CLUTTER_TOUCH_CANCEL)
|
||||
return event->touch.sequence;
|
||||
else if (event->type == CLUTTER_ENTER ||
|
||||
event->type == CLUTTER_LEAVE)
|
||||
return event->crossing.sequence;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -269,6 +269,7 @@ struct _ClutterCrossingEvent
|
||||
gfloat x;
|
||||
gfloat y;
|
||||
ClutterInputDevice *device;
|
||||
ClutterEventSequence *sequence;
|
||||
ClutterActor *related;
|
||||
};
|
||||
|
||||
|
@@ -64,17 +64,13 @@ clutter_features_from_cogl (guint cogl_flags)
|
||||
{
|
||||
ClutterFeatureFlags clutter_flags = 0;
|
||||
|
||||
if (cogl_flags & COGL_FEATURE_TEXTURE_NPOT)
|
||||
clutter_flags |= CLUTTER_FEATURE_TEXTURE_NPOT;
|
||||
|
||||
if (cogl_flags & COGL_FEATURE_TEXTURE_YUV)
|
||||
clutter_flags |= CLUTTER_FEATURE_TEXTURE_YUV;
|
||||
|
||||
if (cogl_flags & COGL_FEATURE_TEXTURE_READ_PIXELS)
|
||||
clutter_flags |= CLUTTER_FEATURE_TEXTURE_READ_PIXELS;
|
||||
|
||||
if (cogl_flags & COGL_FEATURE_SHADERS_GLSL)
|
||||
clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL;
|
||||
clutter_flags |= CLUTTER_FEATURE_SHADERS_GLSL;
|
||||
|
||||
if (cogl_flags & COGL_FEATURE_OFFSCREEN)
|
||||
clutter_flags |= CLUTTER_FEATURE_OFFSCREEN;
|
||||
|
@@ -107,6 +107,9 @@ clutter_input_device_dispose (GObject *gobject)
|
||||
device->associated = NULL;
|
||||
}
|
||||
|
||||
if (device->accessibility_virtual_device)
|
||||
g_clear_object (&device->accessibility_virtual_device);
|
||||
|
||||
g_clear_pointer (&device->axes, g_array_unref);
|
||||
g_clear_pointer (&device->keys, g_array_unref);
|
||||
g_clear_pointer (&device->scroll_info, g_array_unref);
|
||||
@@ -834,6 +837,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
event->crossing.x = device->current_x;
|
||||
event->crossing.y = device->current_y;
|
||||
event->crossing.related = actor;
|
||||
event->crossing.sequence = sequence;
|
||||
clutter_event_set_device (event, device);
|
||||
|
||||
/* we need to make sure that this event is processed
|
||||
@@ -870,6 +874,7 @@ _clutter_input_device_set_actor (ClutterInputDevice *device,
|
||||
event->crossing.y = device->current_y;
|
||||
event->crossing.source = actor;
|
||||
event->crossing.related = old_actor;
|
||||
event->crossing.sequence = sequence;
|
||||
clutter_event_set_device (event, device);
|
||||
|
||||
/* see above */
|
||||
@@ -1034,9 +1039,10 @@ _clutter_input_device_update (ClutterInputDevice *device,
|
||||
ClutterActor *new_cursor_actor;
|
||||
ClutterActor *old_cursor_actor;
|
||||
ClutterPoint point = { -1, -1 };
|
||||
ClutterInputDeviceType device_type = device->device_type;
|
||||
|
||||
if (device->device_type == CLUTTER_KEYBOARD_DEVICE)
|
||||
return NULL;
|
||||
g_assert (device_type != CLUTTER_KEYBOARD_DEVICE &&
|
||||
device_type != CLUTTER_PAD_DEVICE);
|
||||
|
||||
stage = device->stage;
|
||||
if (G_UNLIKELY (stage == NULL))
|
||||
|
42
clutter/clutter/clutter-input-pointer-a11y-private.h
Normal file
42
clutter/clutter/clutter-input-pointer-a11y-private.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Olivier Fourdan <ofourdan@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_POINTER_A11Y_H__
|
||||
#define __CLUTTER_INPUT_POINTER_A11Y_H__
|
||||
|
||||
#include <clutter/clutter-types.h>
|
||||
#include "clutter-enum-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _clutter_input_pointer_a11y_add_device (ClutterInputDevice *device);
|
||||
void _clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device);
|
||||
void _clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y);
|
||||
void _clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
|
||||
int button,
|
||||
gboolean pressed);
|
||||
gboolean _clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_POINTER_A11Y_H__ */
|
669
clutter/clutter/clutter-input-pointer-a11y.c
Normal file
669
clutter/clutter/clutter-input-pointer-a11y.c
Normal file
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Olivier Fourdan <ofourdan@redhat.com>
|
||||
*
|
||||
* This reimplements in Clutter the same behavior as mousetweaks original
|
||||
* implementation by Gerd Kohlberger <gerdko gmail com>
|
||||
* mousetweaks Copyright (C) 2007-2010 Gerd Kohlberger <gerdko gmail com>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-device-manager.h"
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-enum-types.h"
|
||||
#include "clutter-input-device.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
|
||||
static gboolean
|
||||
is_secondary_click_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return (settings.controls & CLUTTER_A11Y_SECONDARY_CLICK_ENABLED);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_click_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return (settings.controls & CLUTTER_A11Y_DWELL_ENABLED);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_secondary_click_delay (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.secondary_click_delay;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_dwell_delay (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.dwell_delay;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_dwell_threshold (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.dwell_threshold;
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellMode
|
||||
get_dwell_mode (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
return settings.dwell_mode;
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellClickType
|
||||
get_dwell_click_type (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
#
|
||||
return settings.dwell_click_type;
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellClickType
|
||||
get_dwell_click_type_for_direction (ClutterInputDevice *device,
|
||||
ClutterPointerA11yDwellDirection direction)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
if (direction == settings.dwell_gesture_single)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
else if (direction == settings.dwell_gesture_double)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE;
|
||||
else if (direction == settings.dwell_gesture_drag)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG;
|
||||
else if (direction == settings.dwell_gesture_secondary)
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY;
|
||||
|
||||
return CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_button_press (ClutterInputDevice *device,
|
||||
gint button)
|
||||
{
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (),
|
||||
button,
|
||||
CLUTTER_BUTTON_STATE_PRESSED);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_button_release (ClutterInputDevice *device,
|
||||
gint button)
|
||||
{
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (),
|
||||
button,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_button_click (ClutterInputDevice *device,
|
||||
gint button)
|
||||
{
|
||||
emit_button_press (device, button);
|
||||
emit_button_release (device, button);
|
||||
}
|
||||
|
||||
static void
|
||||
restore_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
clutter_virtual_input_device_notify_absolute_motion (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (),
|
||||
device->ptr_a11y_data->dwell_x,
|
||||
device->ptr_a11y_data->dwell_y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_secondary_click (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->secondary_click_triggered = TRUE;
|
||||
device->ptr_a11y_data->secondary_click_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_secondary_click_delay (device);
|
||||
|
||||
device->ptr_a11y_data->secondary_click_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_secondary_click, device);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK,
|
||||
delay);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
if (device->ptr_a11y_data->secondary_click_timer)
|
||||
{
|
||||
g_source_remove (device->ptr_a11y_data->secondary_click_timer);
|
||||
device->ptr_a11y_data->secondary_click_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_SECONDARY_CLICK);
|
||||
}
|
||||
device->ptr_a11y_data->secondary_click_triggered = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pointer_has_moved (ClutterInputDevice *device)
|
||||
{
|
||||
float dx, dy;
|
||||
gint threshold;
|
||||
|
||||
dx = device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x;
|
||||
dy = device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y;
|
||||
threshold = get_dwell_threshold (device);
|
||||
|
||||
/* Pythagorean theorem */
|
||||
return ((dx * dx) + (dy * dy)) > (threshold * threshold);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_secondary_click_pending (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->secondary_click_timer != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_secondary_click_triggered (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->secondary_click_triggered;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_click_pending (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->dwell_timer != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_dragging (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->dwell_drag_started;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_dwell_gesturing (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->dwell_gesture_started;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_button_pressed (ClutterInputDevice *device)
|
||||
{
|
||||
return device->ptr_a11y_data->n_btn_pressed > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_start_secondary_click_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
return !is_dwell_dragging (device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_start_dwell (ClutterInputDevice *device)
|
||||
{
|
||||
/* We should trigger a dwell if we've not already started one, and if
|
||||
* no button is currently pressed or we are in the middle of a dwell
|
||||
* drag action.
|
||||
*/
|
||||
return !is_dwell_click_pending (device) &&
|
||||
(is_dwell_dragging (device) ||
|
||||
!has_button_pressed (device));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_stop_dwell (ClutterInputDevice *device)
|
||||
{
|
||||
/* We should stop a dwell if the motion exceeds the threshold, unless
|
||||
* we've started a gesture, because we want to keep the original dwell
|
||||
* location to both detect a gesture and restore the original pointer
|
||||
* location once the gesture is finished.
|
||||
*/
|
||||
return pointer_has_moved (device) &&
|
||||
!is_dwell_gesturing (device);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
should_update_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
return !is_dwell_gesturing (device) &&
|
||||
!is_dwell_click_pending (device) &&
|
||||
!is_secondary_click_pending (device);
|
||||
}
|
||||
|
||||
static void
|
||||
update_dwell_click_type (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterPointerA11ySettings settings;
|
||||
ClutterPointerA11yDwellClickType dwell_click_type;
|
||||
|
||||
clutter_device_manager_get_pointer_a11y_settings (device->device_manager, &settings);
|
||||
|
||||
dwell_click_type = settings.dwell_click_type;
|
||||
switch (dwell_click_type)
|
||||
{
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
|
||||
dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
|
||||
if (!is_dwell_dragging (device))
|
||||
dwell_click_type = CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY;
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dwell_click_type != settings.dwell_click_type)
|
||||
{
|
||||
settings.dwell_click_type = dwell_click_type;
|
||||
clutter_device_manager_set_pointer_a11y_settings (device->device_manager,
|
||||
&settings);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-dwell-click-type-changed",
|
||||
dwell_click_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_dwell_click (ClutterInputDevice *device,
|
||||
ClutterPointerA11yDwellClickType dwell_click_type)
|
||||
{
|
||||
switch (dwell_click_type)
|
||||
{
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_PRIMARY:
|
||||
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DOUBLE:
|
||||
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
|
||||
emit_button_click (device, CLUTTER_BUTTON_PRIMARY);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG:
|
||||
if (is_dwell_dragging (device))
|
||||
{
|
||||
emit_button_release (device, CLUTTER_BUTTON_PRIMARY);
|
||||
device->ptr_a11y_data->dwell_drag_started = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_button_press (device, CLUTTER_BUTTON_PRIMARY);
|
||||
device->ptr_a11y_data->dwell_drag_started = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_SECONDARY:
|
||||
emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_MIDDLE:
|
||||
emit_button_click (device, CLUTTER_BUTTON_MIDDLE);
|
||||
break;
|
||||
|
||||
case CLUTTER_A11Y_DWELL_CLICK_TYPE_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterPointerA11yDwellDirection
|
||||
get_dwell_direction (ClutterInputDevice *device)
|
||||
{
|
||||
float dx, dy;
|
||||
|
||||
dx = ABS (device->ptr_a11y_data->dwell_x - device->ptr_a11y_data->current_x);
|
||||
dy = ABS (device->ptr_a11y_data->dwell_y - device->ptr_a11y_data->current_y);
|
||||
|
||||
/* The pointer hasn't moved */
|
||||
if (!pointer_has_moved (device))
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_NONE;
|
||||
|
||||
if (device->ptr_a11y_data->dwell_x < device->ptr_a11y_data->current_x)
|
||||
{
|
||||
if (dx > dy)
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dx > dy)
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_RIGHT;
|
||||
}
|
||||
|
||||
if (device->ptr_a11y_data->dwell_y < device->ptr_a11y_data->current_y)
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_UP;
|
||||
|
||||
return CLUTTER_A11Y_DWELL_DIRECTION_DOWN;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_clear_dwell_gesture (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
device->ptr_a11y_data->dwell_gesture_started = FALSE;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_dwell_gesture (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
ClutterPointerA11yDwellDirection direction;
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
|
||||
restore_dwell_position (device);
|
||||
direction = get_dwell_direction (device);
|
||||
emit_dwell_click (device,
|
||||
get_dwell_click_type_for_direction (device,
|
||||
direction));
|
||||
|
||||
/* Do not clear the gesture right away, otherwise we'll start another one */
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_clear_dwell_gesture, device);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_dwell_gesture_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_dwell_gesture, device);
|
||||
device->ptr_a11y_data->dwell_gesture_started = TRUE;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_GESTURE,
|
||||
delay);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
trigger_dwell_click (gpointer data)
|
||||
{
|
||||
ClutterInputDevice *device = data;
|
||||
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
|
||||
|
||||
if (get_dwell_mode (device) == CLUTTER_A11Y_DWELL_MODE_GESTURE)
|
||||
{
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
else
|
||||
start_dwell_gesture_timeout (device);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_dwell_click (device, get_dwell_click_type (device));
|
||||
update_dwell_click_type (device);
|
||||
}
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
start_dwell_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
unsigned int delay = get_dwell_delay (device);
|
||||
|
||||
device->ptr_a11y_data->dwell_timer =
|
||||
clutter_threads_add_timeout (delay, trigger_dwell_click, device);
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-started",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL,
|
||||
delay);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_dwell_timeout (ClutterInputDevice *device)
|
||||
{
|
||||
if (device->ptr_a11y_data->dwell_timer)
|
||||
{
|
||||
g_source_remove (device->ptr_a11y_data->dwell_timer);
|
||||
device->ptr_a11y_data->dwell_timer = 0;
|
||||
device->ptr_a11y_data->dwell_gesture_started = FALSE;
|
||||
|
||||
g_signal_emit_by_name (device->device_manager,
|
||||
"ptr-a11y-timeout-stopped",
|
||||
device,
|
||||
CLUTTER_A11Y_TIMEOUT_TYPE_DWELL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_dwell_position (ClutterInputDevice *device)
|
||||
{
|
||||
device->ptr_a11y_data->dwell_x = device->ptr_a11y_data->current_x;
|
||||
device->ptr_a11y_data->dwell_y = device->ptr_a11y_data->current_y;
|
||||
}
|
||||
|
||||
static void
|
||||
update_current_position (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
device->ptr_a11y_data->current_x = x;
|
||||
device->ptr_a11y_data->current_y = y;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_device_core_pointer (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
if (core_pointer == NULL)
|
||||
return FALSE;
|
||||
|
||||
return (core_pointer == device);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_add_device (ClutterInputDevice *device)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
device->accessibility_virtual_device =
|
||||
clutter_device_manager_create_virtual_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
device->ptr_a11y_data = g_new0 (ClutterPtrA11yData, 1);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_remove_device (ClutterInputDevice *device)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
/* Terminate a drag if started */
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
|
||||
stop_dwell_timeout (device);
|
||||
stop_secondary_click_timeout (device);
|
||||
|
||||
g_clear_pointer (&device->ptr_a11y_data, g_free);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_on_motion_event (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
if (!_clutter_is_input_pointer_a11y_enabled (device))
|
||||
return;
|
||||
|
||||
update_current_position (device, x, y);
|
||||
|
||||
if (is_secondary_click_enabled (device))
|
||||
{
|
||||
if (pointer_has_moved (device))
|
||||
stop_secondary_click_timeout (device);
|
||||
}
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
{
|
||||
if (should_stop_dwell (device))
|
||||
stop_dwell_timeout (device);
|
||||
else if (should_start_dwell (device))
|
||||
start_dwell_timeout (device);
|
||||
}
|
||||
|
||||
if (should_update_dwell_position (device))
|
||||
update_dwell_position (device);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_input_pointer_a11y_on_button_event (ClutterInputDevice *device,
|
||||
int button,
|
||||
gboolean pressed)
|
||||
{
|
||||
if (!is_device_core_pointer (device))
|
||||
return;
|
||||
|
||||
if (!_clutter_is_input_pointer_a11y_enabled (device))
|
||||
return;
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
device->ptr_a11y_data->n_btn_pressed++;
|
||||
|
||||
if (is_dwell_click_enabled (device))
|
||||
stop_dwell_timeout (device);
|
||||
|
||||
if (is_dwell_dragging (device))
|
||||
stop_dwell_timeout (device);
|
||||
|
||||
if (is_secondary_click_enabled (device))
|
||||
{
|
||||
if (button == CLUTTER_BUTTON_PRIMARY)
|
||||
{
|
||||
if (should_start_secondary_click_timeout (device))
|
||||
start_secondary_click_timeout (device);
|
||||
}
|
||||
else if (is_secondary_click_pending (device))
|
||||
{
|
||||
stop_secondary_click_timeout (device);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (has_button_pressed (device))
|
||||
device->ptr_a11y_data->n_btn_pressed--;
|
||||
|
||||
if (is_secondary_click_triggered (device))
|
||||
{
|
||||
emit_button_click (device, CLUTTER_BUTTON_SECONDARY);
|
||||
stop_secondary_click_timeout (device);
|
||||
}
|
||||
|
||||
if (is_secondary_click_pending (device))
|
||||
stop_secondary_click_timeout (device);
|
||||
|
||||
if (is_dwell_dragging (device))
|
||||
emit_dwell_click (device, CLUTTER_A11Y_DWELL_CLICK_TYPE_DRAG);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
_clutter_is_input_pointer_a11y_enabled (ClutterInputDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
|
||||
return (is_secondary_click_enabled (device) || is_dwell_click_enabled (device));
|
||||
}
|
@@ -58,6 +58,7 @@
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-feature.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-master-clock.h"
|
||||
#include "clutter-mutter.h"
|
||||
@@ -2004,6 +2005,36 @@ emit_pointer_event (ClutterEvent *event,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
emit_crossing_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterMainContext *context = _clutter_context_get_default ();
|
||||
ClutterEventSequence *sequence = clutter_event_get_event_sequence (event);
|
||||
ClutterActor *grab_actor = NULL;
|
||||
|
||||
if (_clutter_event_process_filters (event))
|
||||
return;
|
||||
|
||||
if (sequence)
|
||||
{
|
||||
if (device->sequence_grab_actors != NULL)
|
||||
grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context->pointer_grab_actor != NULL)
|
||||
grab_actor = context->pointer_grab_actor;
|
||||
else if (device != NULL && device->pointer_grab_actor != NULL)
|
||||
grab_actor = device->pointer_grab_actor;
|
||||
}
|
||||
|
||||
if (grab_actor != NULL)
|
||||
clutter_actor_event (grab_actor, event, FALSE);
|
||||
else
|
||||
emit_event_chain (event);
|
||||
}
|
||||
|
||||
static inline void
|
||||
emit_touch_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
@@ -2177,7 +2208,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
|
||||
emit_pointer_event (event, device);
|
||||
emit_crossing_event (event, device);
|
||||
|
||||
actor = _clutter_input_device_update (device, NULL, FALSE);
|
||||
if (actor != stage)
|
||||
@@ -2189,12 +2220,12 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
crossing->crossing.related = stage;
|
||||
crossing->crossing.source = actor;
|
||||
|
||||
emit_pointer_event (crossing, device);
|
||||
emit_crossing_event (crossing, device);
|
||||
clutter_event_free (crossing);
|
||||
}
|
||||
}
|
||||
else
|
||||
emit_pointer_event (event, device);
|
||||
emit_crossing_event (event, device);
|
||||
break;
|
||||
|
||||
case CLUTTER_LEAVE:
|
||||
@@ -2213,10 +2244,10 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
crossing->crossing.related = stage;
|
||||
crossing->crossing.source = device->cursor_actor;
|
||||
|
||||
emit_pointer_event (crossing, device);
|
||||
emit_crossing_event (crossing, device);
|
||||
clutter_event_free (crossing);
|
||||
}
|
||||
emit_pointer_event (event, device);
|
||||
emit_crossing_event (event, device);
|
||||
break;
|
||||
|
||||
case CLUTTER_DESTROY_NOTIFY:
|
||||
@@ -2231,6 +2262,21 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
break;
|
||||
|
||||
case CLUTTER_MOTION:
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
if (_clutter_is_input_pointer_a11y_enabled (device))
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
gfloat x, y;
|
||||
|
||||
clutter_event_get_coords (event, &x, &y);
|
||||
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
_clutter_input_pointer_a11y_on_motion_event (core_pointer, x, y);
|
||||
}
|
||||
}
|
||||
#endif /* CLUTTER_WINDOWING_X11 */
|
||||
/* only the stage gets motion events if they are enabled */
|
||||
if (!clutter_stage_get_motion_events_enabled (CLUTTER_STAGE (stage)) &&
|
||||
event->any.source == NULL)
|
||||
@@ -2269,6 +2315,22 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
/* fallthrough from motion */
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (!clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
if (_clutter_is_input_pointer_a11y_enabled (device) && (event->type != CLUTTER_MOTION))
|
||||
{
|
||||
ClutterInputDevice *core_pointer;
|
||||
|
||||
core_pointer = clutter_device_manager_get_core_device (device->device_manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
_clutter_input_pointer_a11y_on_button_event (core_pointer,
|
||||
event->button.button,
|
||||
event->type == CLUTTER_BUTTON_PRESS);
|
||||
}
|
||||
}
|
||||
#endif /* CLUTTER_WINDOWING_X11 */
|
||||
case CLUTTER_SCROLL:
|
||||
case CLUTTER_TOUCHPAD_PINCH:
|
||||
case CLUTTER_TOUCHPAD_SWIPE:
|
||||
|
@@ -23,6 +23,7 @@ VOID:FLOAT,FLOAT
|
||||
VOID:INT,INT,INT,INT
|
||||
VOID:OBJECT
|
||||
VOID:OBJECT,FLAGS
|
||||
VOID:OBJECT,FLAGS,UINT
|
||||
VOID:OBJECT,FLOAT,FLOAT
|
||||
VOID:OBJECT,FLOAT,FLOAT,FLAGS
|
||||
VOID:OBJECT,OBJECT
|
||||
|
@@ -64,9 +64,6 @@ struct _ClutterMasterClockDefault
|
||||
/* the current state of the clock, in usecs */
|
||||
gint64 cur_tick;
|
||||
|
||||
/* the previous state of the clock, in usecs, used to compute the delta */
|
||||
gint64 prev_tick;
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
gint64 frame_budget;
|
||||
gint64 remaining_budget;
|
||||
@@ -77,12 +74,6 @@ struct _ClutterMasterClockDefault
|
||||
*/
|
||||
GSource *source;
|
||||
|
||||
/* If the master clock is idle that means it has
|
||||
* fallen back to idle polling for timeline
|
||||
* progressions and it may have been some time since
|
||||
* the last real stage update.
|
||||
*/
|
||||
guint idle : 1;
|
||||
guint ensure_next_iteration : 1;
|
||||
|
||||
guint paused : 1;
|
||||
@@ -275,78 +266,12 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
|
||||
static gint
|
||||
master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
|
||||
{
|
||||
gint64 now, next;
|
||||
gint swap_delay;
|
||||
|
||||
if (!master_clock_is_running (master_clock))
|
||||
return -1;
|
||||
|
||||
/* If all of the stages are busy waiting for a swap-buffers to complete
|
||||
* then we wait for one to be ready.. */
|
||||
swap_delay = master_clock_get_swap_wait_time (master_clock);
|
||||
if (swap_delay != 0)
|
||||
return swap_delay;
|
||||
|
||||
/* When we have sync-to-vblank, we count on swap-buffer requests (or
|
||||
* swap-buffer-complete events if supported in the backend) to throttle our
|
||||
* frame rate so no additional delay is needed to start the next frame.
|
||||
*
|
||||
* If the master-clock has become idle due to no timeline progression causing
|
||||
* redraws then we can no longer rely on vblank synchronization because the
|
||||
* last real stage update/redraw may have happened a long time ago and so we
|
||||
* fallback to polling for timeline progressions every 1/frame_rate seconds.
|
||||
*
|
||||
* (NB: if there aren't even any timelines running then the master clock will
|
||||
* be completely stopped in master_clock_is_running())
|
||||
*/
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SWAP_THROTTLE) &&
|
||||
!master_clock->idle)
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "swap throttling available and updated stages");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (master_clock->prev_tick == 0)
|
||||
{
|
||||
/* If we weren't previously running, then draw the next frame
|
||||
* immediately
|
||||
*/
|
||||
CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, wait at least 1/frame_rate seconds since we last
|
||||
* started a frame
|
||||
*/
|
||||
now = g_source_get_time (master_clock->source);
|
||||
|
||||
next = master_clock->prev_tick;
|
||||
|
||||
/* If time has gone backwards then there's no way of knowing how
|
||||
long we should wait so let's just dispatch immediately */
|
||||
if (now <= next)
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
next += (1000000L / clutter_get_default_frame_rate ());
|
||||
|
||||
if (next <= now)
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
|
||||
1000000L / (gulong) clutter_get_default_frame_rate ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
|
||||
(next - now) / 1000);
|
||||
|
||||
return (next - now) / 1000;
|
||||
}
|
||||
return master_clock_get_swap_wait_time (master_clock);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -412,8 +337,7 @@ master_clock_advance_timelines (ClutterMasterClockDefault *master_clock)
|
||||
for (l = timelines; l != NULL; l = l->next)
|
||||
_clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000);
|
||||
|
||||
g_slist_foreach (timelines, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (timelines);
|
||||
g_slist_free_full (timelines, g_object_unref);
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
if (_clutter_diagnostic_enabled ())
|
||||
@@ -531,7 +455,6 @@ clutter_clock_dispatch (GSource *source,
|
||||
{
|
||||
ClutterClockSource *clock_source = (ClutterClockSource *) source;
|
||||
ClutterMasterClockDefault *master_clock = clock_source->master_clock;
|
||||
gboolean stages_updated = FALSE;
|
||||
GSList *stages;
|
||||
|
||||
CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
|
||||
@@ -551,8 +474,6 @@ clutter_clock_dispatch (GSource *source,
|
||||
*/
|
||||
stages = master_clock_list_ready_stages (master_clock);
|
||||
|
||||
master_clock->idle = FALSE;
|
||||
|
||||
/* Each frame is split into three separate phases: */
|
||||
|
||||
/* 1. process all the events; each stage goes through its events queue
|
||||
@@ -565,19 +486,11 @@ clutter_clock_dispatch (GSource *source,
|
||||
master_clock_advance_timelines (master_clock);
|
||||
|
||||
/* 3. relayout and redraw the stages */
|
||||
stages_updated = master_clock_update_stages (master_clock, stages);
|
||||
|
||||
/* The master clock goes idle if no stages were updated and falls back
|
||||
* to polling for timeline progressions... */
|
||||
if (!stages_updated)
|
||||
master_clock->idle = TRUE;
|
||||
master_clock_update_stages (master_clock, stages);
|
||||
|
||||
master_clock_reschedule_stage_updates (master_clock, stages);
|
||||
|
||||
g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (stages);
|
||||
|
||||
master_clock->prev_tick = master_clock->cur_tick;
|
||||
g_slist_free_full (stages, g_object_unref);
|
||||
|
||||
_clutter_threads_release_lock ();
|
||||
|
||||
@@ -610,7 +523,6 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
|
||||
source = clutter_clock_source_new (self);
|
||||
self->source = source;
|
||||
|
||||
self->idle = FALSE;
|
||||
self->ensure_next_iteration = FALSE;
|
||||
self->paused = FALSE;
|
||||
|
||||
|
@@ -43,6 +43,11 @@ void clutter_stage_capture_into (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterStageView * clutter_stage_get_view_at (ClutterStage *stage,
|
||||
float x,
|
||||
float y);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_stage_freeze_updates (ClutterStage *stage);
|
||||
|
||||
|
@@ -75,8 +75,7 @@ _clutter_paint_node_init_types (void)
|
||||
cogl_pipeline_set_color (default_color_pipeline, &cogl_color);
|
||||
|
||||
default_texture_pipeline = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0,
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_null_texture (default_texture_pipeline, 0);
|
||||
cogl_pipeline_set_color (default_texture_pipeline, &cogl_color);
|
||||
cogl_pipeline_set_layer_wrap_mode (default_texture_pipeline, 0,
|
||||
COGL_PIPELINE_WRAP_MODE_AUTOMATIC);
|
||||
|
@@ -295,8 +295,7 @@ clutter_path_clear (ClutterPath *path)
|
||||
{
|
||||
ClutterPathPrivate *priv = path->priv;
|
||||
|
||||
g_slist_foreach (priv->nodes, (GFunc) clutter_path_node_full_free, NULL);
|
||||
g_slist_free (priv->nodes);
|
||||
g_slist_free_full (priv->nodes, (GDestroyNotify) clutter_path_node_full_free);
|
||||
|
||||
priv->nodes = priv->nodes_tail = NULL;
|
||||
priv->nodes_dirty = TRUE;
|
||||
@@ -659,8 +658,7 @@ clutter_path_parse_description (const gchar *p,
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
g_slist_foreach (nodes, (GFunc) clutter_path_node_full_free, NULL);
|
||||
g_slist_free (nodes);
|
||||
g_slist_free_full (nodes, (GDestroyNotify) clutter_path_node_full_free);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -303,6 +303,11 @@ gboolean _clutter_util_matrix_decompose (const ClutterMatrix *src,
|
||||
ClutterVertex *translate_p,
|
||||
ClutterVertex4 *perspective_p);
|
||||
|
||||
PangoDirection _clutter_pango_unichar_direction (gunichar ch);
|
||||
|
||||
PangoDirection _clutter_pango_find_base_dir (const gchar *text,
|
||||
gint length);
|
||||
|
||||
typedef struct _ClutterPlane
|
||||
{
|
||||
float v0[3];
|
||||
|
@@ -2021,8 +2021,7 @@ add_children (ClutterScript *script,
|
||||
clutter_container_add_actor (container, CLUTTER_ACTOR (object));
|
||||
}
|
||||
|
||||
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
|
||||
g_list_free (oinfo->children);
|
||||
g_list_free_full (oinfo->children, g_free);
|
||||
|
||||
oinfo->children = unresolved;
|
||||
}
|
||||
|
@@ -346,15 +346,12 @@ object_info_free (gpointer data)
|
||||
g_free (oinfo->class_name);
|
||||
g_free (oinfo->type_func);
|
||||
|
||||
g_list_foreach (oinfo->properties, (GFunc) property_info_free, NULL);
|
||||
g_list_free (oinfo->properties);
|
||||
g_list_free_full (oinfo->properties, property_info_free);
|
||||
|
||||
g_list_foreach (oinfo->signals, (GFunc) signal_info_free, NULL);
|
||||
g_list_free (oinfo->signals);
|
||||
g_list_free_full (oinfo->signals, signal_info_free);
|
||||
|
||||
/* these are ids */
|
||||
g_list_foreach (oinfo->children, (GFunc) g_free, NULL);
|
||||
g_list_free (oinfo->children);
|
||||
g_list_free_full (oinfo->children, g_free);
|
||||
|
||||
/* we unref top-level objects and leave the actors alone,
|
||||
* unless we are unmerging in which case we have to destroy
|
||||
@@ -846,8 +843,7 @@ clutter_script_unmerge_objects (ClutterScript *script,
|
||||
for (l = data.ids; l != NULL; l = l->next)
|
||||
g_hash_table_remove (priv->objects, l->data);
|
||||
|
||||
g_slist_foreach (data.ids, (GFunc) g_free, NULL);
|
||||
g_slist_free (data.ids);
|
||||
g_slist_free_full (data.ids, g_free);
|
||||
|
||||
clutter_script_ensure_objects (script);
|
||||
}
|
||||
|
@@ -89,8 +89,8 @@ clutter_stage_manager_dispose (GObject *gobject)
|
||||
|
||||
stage_manager = CLUTTER_STAGE_MANAGER (gobject);
|
||||
|
||||
g_slist_foreach (stage_manager->stages, (GFunc) clutter_actor_destroy, NULL);
|
||||
g_slist_free (stage_manager->stages);
|
||||
g_slist_free_full (stage_manager->stages,
|
||||
(GDestroyNotify) clutter_actor_destroy);
|
||||
stage_manager->stages = NULL;
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_manager_parent_class)->dispose (gobject);
|
||||
|
@@ -75,6 +75,7 @@
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
/* <private>
|
||||
* ClutterStageHint:
|
||||
@@ -688,6 +689,8 @@ _clutter_stage_paint_view (ClutterStage *stage,
|
||||
if (!priv->impl)
|
||||
return;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
|
||||
|
||||
clutter_stage_do_paint_view (stage, view, clip);
|
||||
g_signal_emit (stage, stage_signals[AFTER_PAINT], 0);
|
||||
}
|
||||
@@ -1225,22 +1228,31 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||
return FALSE;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageDoUpdate, "Update");
|
||||
|
||||
/* NB: We need to ensure we have an up to date layout *before* we
|
||||
* check or clear the pending redraws flag since a relayout may
|
||||
* queue a redraw.
|
||||
*/
|
||||
COGL_TRACE_BEGIN (ClutterStageRelayout, "Layout");
|
||||
|
||||
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
|
||||
|
||||
COGL_TRACE_END (ClutterStageRelayout);
|
||||
|
||||
if (!priv->redraw_pending)
|
||||
return FALSE;
|
||||
|
||||
if (stage_was_relayout)
|
||||
pointers = _clutter_stage_check_updated_pointers (stage);
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
COGL_TRACE_BEGIN (ClutterStagePaint, "Paint");
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
clutter_stage_do_redraw (stage);
|
||||
|
||||
COGL_TRACE_END (ClutterStagePaint);
|
||||
|
||||
/* reset the guard, so that new redraws are possible */
|
||||
priv->redraw_pending = FALSE;
|
||||
|
||||
@@ -1254,12 +1266,16 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStagePick, "Pick");
|
||||
|
||||
while (pointers)
|
||||
{
|
||||
_clutter_input_device_update (pointers->data, NULL, TRUE);
|
||||
pointers = g_slist_delete_link (pointers, pointers);
|
||||
}
|
||||
|
||||
COGL_TRACE_END (ClutterStagePick);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1303,14 +1319,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||
return TRUE;
|
||||
|
||||
if (_clutter_stage_window_ignoring_redraw_clips (stage_window))
|
||||
{
|
||||
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
/* Convert the clip volume into stage coordinates and then into an
|
||||
* axis aligned stage coordinates bounding box...
|
||||
*/
|
||||
if (redraw_clip == NULL)
|
||||
{
|
||||
_clutter_stage_window_add_redraw_clip (stage_window, NULL);
|
||||
@@ -1320,6 +1330,8 @@ clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||
if (redraw_clip->is_empty)
|
||||
return TRUE;
|
||||
|
||||
/* Convert the clip volume into stage coordinates and then into an
|
||||
* axis aligned stage coordinates bounding box... */
|
||||
_clutter_paint_volume_get_stage_paint_box (redraw_clip,
|
||||
stage,
|
||||
&bounding_box);
|
||||
@@ -1574,10 +1586,13 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ClutterStageView *
|
||||
get_view_at (ClutterStage *stage,
|
||||
int x,
|
||||
int y)
|
||||
/**
|
||||
* clutter_stage_get_view_at: (skip)
|
||||
*/
|
||||
ClutterStageView *
|
||||
clutter_stage_get_view_at (ClutterStage *stage,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
GList *l;
|
||||
@@ -1624,7 +1639,7 @@ _clutter_stage_do_pick (ClutterStage *stage,
|
||||
if (x < 0 || x >= stage_width || y < 0 || y >= stage_height)
|
||||
return actor;
|
||||
|
||||
view = get_view_at (stage, x, y);
|
||||
view = clutter_stage_get_view_at (stage, x, y);
|
||||
if (view)
|
||||
return _clutter_stage_do_pick_on_view (stage, x, y, mode, view);
|
||||
|
||||
@@ -2949,6 +2964,8 @@ clutter_stage_read_pixels (ClutterStage *stage,
|
||||
float pixel_height;
|
||||
uint8_t *pixels;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageReadPixels, "Read Pixels");
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||
|
||||
priv = stage->priv;
|
||||
@@ -3014,7 +3031,11 @@ clutter_stage_read_pixels (ClutterStage *stage,
|
||||
* @y: Y coordinate to check
|
||||
*
|
||||
* Checks the scene at the coordinates @x and @y and returns a pointer
|
||||
* to the #ClutterActor at those coordinates.
|
||||
* to the #ClutterActor at those coordinates. The result is the actor which
|
||||
* would be at the specified location on the next redraw, and is not
|
||||
* necessarily that which was there on the previous redraw. This allows the
|
||||
* function to perform chronologically correctly after any queued changes to
|
||||
* the scene, and even if nothing has been drawn.
|
||||
*
|
||||
* By using @pick_mode it is possible to control which actors will be
|
||||
* painted and thus available.
|
||||
|
@@ -751,7 +751,7 @@ clutter_text_create_layout_no_cache (ClutterText *text,
|
||||
if (priv->password_char != 0)
|
||||
pango_dir = PANGO_DIRECTION_NEUTRAL;
|
||||
else
|
||||
pango_dir = pango_find_base_dir (contents, contents_len);
|
||||
pango_dir = _clutter_pango_find_base_dir (contents, contents_len);
|
||||
|
||||
if (pango_dir == PANGO_DIRECTION_NEUTRAL)
|
||||
{
|
||||
@@ -1975,6 +1975,7 @@ selection_paint (ClutterText *self,
|
||||
else
|
||||
{
|
||||
/* Paint selection background first */
|
||||
CoglPipeline *color_pipeline = cogl_pipeline_copy (default_color_pipeline);
|
||||
PangoLayout *layout = clutter_text_get_layout (self);
|
||||
CoglPath *selection_path = cogl_path_new ();
|
||||
CoglColor cogl_color = { 0, };
|
||||
@@ -1987,11 +1988,19 @@ selection_paint (ClutterText *self,
|
||||
else
|
||||
color = &priv->text_color;
|
||||
|
||||
cogl_color_init_from_4ub (&cogl_color,
|
||||
color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
paint_opacity * color->alpha / 255);
|
||||
cogl_color_premultiply (&cogl_color);
|
||||
cogl_pipeline_set_color (color_pipeline, &cogl_color);
|
||||
|
||||
clutter_text_foreach_selection_rectangle_prescaled (self,
|
||||
add_selection_rectangle_to_path,
|
||||
selection_path);
|
||||
|
||||
cogl_path_fill (selection_path);
|
||||
cogl_framebuffer_fill_path (fb, color_pipeline, selection_path);
|
||||
|
||||
/* Paint selected text */
|
||||
cogl_framebuffer_push_path_clip (fb, selection_path);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include <fribidi.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter-debug.h"
|
||||
@@ -105,8 +106,9 @@ _clutter_util_fully_transform_vertices (const CoglMatrix *modelview,
|
||||
}
|
||||
}
|
||||
|
||||
void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
|
||||
ClutterRect *dest)
|
||||
void
|
||||
_clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
|
||||
ClutterRect *dest)
|
||||
{
|
||||
*dest = (ClutterRect) {
|
||||
.origin = {
|
||||
@@ -120,8 +122,9 @@ void _clutter_util_rect_from_rectangle (const cairo_rectangle_int_t *src,
|
||||
};
|
||||
}
|
||||
|
||||
void _clutter_util_rectangle_int_extents (const ClutterRect *src,
|
||||
cairo_rectangle_int_t *dest)
|
||||
void
|
||||
_clutter_util_rectangle_int_extents (const ClutterRect *src,
|
||||
cairo_rectangle_int_t *dest)
|
||||
{
|
||||
ClutterRect tmp = *src;
|
||||
|
||||
@@ -135,10 +138,11 @@ void _clutter_util_rectangle_int_extents (const ClutterRect *src,
|
||||
};
|
||||
}
|
||||
|
||||
void _clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
|
||||
int x,
|
||||
int y,
|
||||
cairo_rectangle_int_t *dest)
|
||||
void
|
||||
_clutter_util_rectangle_offset (const cairo_rectangle_int_t *src,
|
||||
int x,
|
||||
int y,
|
||||
cairo_rectangle_int_t *dest)
|
||||
{
|
||||
*dest = *src;
|
||||
|
||||
@@ -696,3 +700,45 @@ clutter_interval_register_progress_func (GType value_type,
|
||||
|
||||
G_UNLOCK (progress_funcs);
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
_clutter_pango_unichar_direction (gunichar ch)
|
||||
{
|
||||
FriBidiCharType fribidi_ch_type;
|
||||
|
||||
G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar));
|
||||
|
||||
fribidi_ch_type = fribidi_get_bidi_type (ch);
|
||||
|
||||
if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
|
||||
return PANGO_DIRECTION_NEUTRAL;
|
||||
else if (FRIBIDI_IS_RTL (fribidi_ch_type))
|
||||
return PANGO_DIRECTION_RTL;
|
||||
else
|
||||
return PANGO_DIRECTION_LTR;
|
||||
}
|
||||
|
||||
PangoDirection
|
||||
_clutter_pango_find_base_dir (const gchar *text,
|
||||
gint length)
|
||||
{
|
||||
PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
|
||||
const gchar *p;
|
||||
|
||||
g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
|
||||
|
||||
p = text;
|
||||
while ((length < 0 || p < text + length) && *p)
|
||||
{
|
||||
gunichar wc = g_utf8_get_char (p);
|
||||
|
||||
dir = _clutter_pango_unichar_direction (wc);
|
||||
|
||||
if (dir != PANGO_DIRECTION_NEUTRAL)
|
||||
break;
|
||||
|
||||
p = g_utf8_next_char (p);
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
@@ -46,6 +46,8 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
|
||||
#include "cogl/cogl-trace.h"
|
||||
|
||||
typedef struct _ClutterStageViewCoglPrivate
|
||||
{
|
||||
/*
|
||||
@@ -77,6 +79,10 @@ enum
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
gint sync_delay);
|
||||
|
||||
static void
|
||||
clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@@ -122,6 +128,16 @@ _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
|
||||
}
|
||||
|
||||
_clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info);
|
||||
|
||||
if (frame_event == COGL_FRAME_EVENT_COMPLETE &&
|
||||
stage_cogl->update_time != -1)
|
||||
{
|
||||
ClutterStageWindow *stage_window = CLUTTER_STAGE_WINDOW (stage_cogl);
|
||||
|
||||
stage_cogl->update_time = -1;
|
||||
clutter_stage_cogl_schedule_update (stage_window,
|
||||
stage_cogl->last_sync_delay);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -152,10 +168,15 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
gint64 now;
|
||||
float refresh_rate;
|
||||
gint64 refresh_interval;
|
||||
int64_t min_render_time_allowed;
|
||||
int64_t max_render_time_allowed;
|
||||
int64_t next_presentation_time;
|
||||
|
||||
if (stage_cogl->update_time != -1)
|
||||
return;
|
||||
|
||||
stage_cogl->last_sync_delay = sync_delay;
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
|
||||
if (sync_delay < 0)
|
||||
@@ -164,30 +185,56 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
|
||||
return;
|
||||
}
|
||||
|
||||
/* We only extrapolate presentation times for 150ms - this is somewhat
|
||||
* arbitrary. The reasons it might not be accurate for larger times are
|
||||
* that the refresh interval might be wrong or the vertical refresh
|
||||
* might be downclocked if nothing is going on onscreen.
|
||||
*/
|
||||
if (stage_cogl->last_presentation_time == 0||
|
||||
stage_cogl->last_presentation_time < now - 150000)
|
||||
refresh_rate = stage_cogl->refresh_rate;
|
||||
if (refresh_rate <= 0.0)
|
||||
refresh_rate = clutter_get_default_frame_rate ();
|
||||
|
||||
refresh_interval = (gint64) (0.5 + G_USEC_PER_SEC / refresh_rate);
|
||||
if (refresh_interval == 0)
|
||||
{
|
||||
stage_cogl->update_time = now;
|
||||
return;
|
||||
}
|
||||
|
||||
refresh_rate = stage_cogl->refresh_rate;
|
||||
if (refresh_rate == 0.0)
|
||||
refresh_rate = 60.0;
|
||||
min_render_time_allowed = refresh_interval / 2;
|
||||
max_render_time_allowed = refresh_interval - 1000 * sync_delay;
|
||||
|
||||
refresh_interval = (gint64) (0.5 + 1000000 / refresh_rate);
|
||||
if (refresh_interval == 0)
|
||||
refresh_interval = 16667; /* 1/60th second */
|
||||
/* Be robust in the case of incredibly bogus refresh rate */
|
||||
if (max_render_time_allowed <= 0)
|
||||
{
|
||||
g_warning ("Unsupported monitor refresh rate detected. "
|
||||
"(Refresh rate: %.3f, refresh interval: %ld)",
|
||||
refresh_rate,
|
||||
refresh_interval);
|
||||
stage_cogl->update_time = now;
|
||||
return;
|
||||
}
|
||||
|
||||
stage_cogl->update_time = stage_cogl->last_presentation_time + 1000 * sync_delay;
|
||||
if (min_render_time_allowed > max_render_time_allowed)
|
||||
min_render_time_allowed = max_render_time_allowed;
|
||||
|
||||
while (stage_cogl->update_time < now)
|
||||
stage_cogl->update_time += refresh_interval;
|
||||
next_presentation_time = stage_cogl->last_presentation_time + refresh_interval;
|
||||
|
||||
/* Get next_presentation_time closer to its final value, to reduce
|
||||
* the number of while iterations below.
|
||||
*/
|
||||
if (next_presentation_time < now)
|
||||
{
|
||||
int64_t last_virtual_presentation_time = now - now % refresh_interval;
|
||||
int64_t hardware_clock_phase =
|
||||
stage_cogl->last_presentation_time % refresh_interval;
|
||||
|
||||
next_presentation_time =
|
||||
last_virtual_presentation_time + hardware_clock_phase;
|
||||
}
|
||||
|
||||
while (next_presentation_time < now + min_render_time_allowed)
|
||||
next_presentation_time += refresh_interval;
|
||||
|
||||
stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
|
||||
|
||||
if (stage_cogl->update_time == stage_cogl->last_update_time)
|
||||
stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
|
||||
}
|
||||
|
||||
static gint64
|
||||
@@ -206,6 +253,7 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
|
||||
|
||||
stage_cogl->last_update_time = stage_cogl->update_time;
|
||||
stage_cogl->update_time = -1;
|
||||
}
|
||||
|
||||
@@ -273,7 +321,7 @@ clutter_stage_cogl_ignoring_redraw_clips (ClutterStageWindow *stage_window)
|
||||
}
|
||||
|
||||
/* A redraw clip represents (in stage coordinates) the bounding box of
|
||||
* something that needs to be redraw. Typically they are added to the
|
||||
* something that needs to be redrawn. Typically they are added to the
|
||||
* StageWindow as a result of clutter_actor_queue_clipped_redraw() by
|
||||
* actors such as ClutterGLXTexturePixmap. All redraw clips are
|
||||
* discarded after the next paint.
|
||||
@@ -502,8 +550,8 @@ fill_current_damage_history_and_step (ClutterStageView *view)
|
||||
*current_fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale
|
||||
.width = ceilf (view_rect.width * fb_scale),
|
||||
.height = ceilf (view_rect.height * fb_scale)
|
||||
};
|
||||
view_priv->damage_index++;
|
||||
}
|
||||
@@ -878,26 +926,16 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
*/
|
||||
if (use_clipped_redraw)
|
||||
{
|
||||
if (use_clipped_redraw && clip_region_empty)
|
||||
if (clip_region_empty)
|
||||
{
|
||||
do_swap_buffer = FALSE;
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
else
|
||||
{
|
||||
swap_region = fb_clip_region;
|
||||
g_assert (swap_region.width > 0);
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
swap_region = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale,
|
||||
};
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -907,6 +945,9 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
|
||||
if (do_swap_buffer)
|
||||
{
|
||||
COGL_TRACE_BEGIN_SCOPED (ClutterStageCoglRedrawViewSwapFramebuffer,
|
||||
"Paint (swap framebuffer)");
|
||||
|
||||
if (clutter_stage_view_get_onscreen (view) !=
|
||||
clutter_stage_view_get_framebuffer (view))
|
||||
{
|
||||
@@ -931,6 +972,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
gboolean swap_event = FALSE;
|
||||
GList *l;
|
||||
|
||||
COGL_TRACE_BEGIN (ClutterStageCoglRedraw, "Paint (Cogl Redraw)");
|
||||
|
||||
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
@@ -954,6 +997,8 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
|
||||
stage_cogl->initialized_redraw_clip = FALSE;
|
||||
|
||||
stage_cogl->frame_count++;
|
||||
|
||||
COGL_TRACE_END (ClutterStageCoglRedraw);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -53,12 +53,15 @@ struct _ClutterStageCogl
|
||||
|
||||
gint64 last_presentation_time;
|
||||
gint64 update_time;
|
||||
int64_t last_update_time;
|
||||
|
||||
/* We only enable clipped redraws after 2 frames, since we've seen
|
||||
* a lot of drivers can struggle to get going and may output some
|
||||
* junk frames to start with. */
|
||||
unsigned int frame_count;
|
||||
|
||||
gint last_sync_delay;
|
||||
|
||||
cairo_rectangle_int_t bounding_redraw_clip;
|
||||
|
||||
guint initialized_redraw_clip : 1;
|
||||
|
@@ -1277,9 +1277,7 @@ clutter_texture_init (ClutterTexture *self)
|
||||
|
||||
texture_template_pipeline = cogl_pipeline_new (ctx);
|
||||
pipeline = COGL_PIPELINE (texture_template_pipeline);
|
||||
cogl_pipeline_set_layer_null_texture (pipeline,
|
||||
0, /* layer_index */
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_null_texture (pipeline, 0);
|
||||
}
|
||||
|
||||
g_assert (texture_template_pipeline != NULL);
|
||||
|
@@ -739,31 +739,33 @@ get_button_index (gint button)
|
||||
}
|
||||
|
||||
static void
|
||||
emulate_button_press (ClutterInputDeviceEvdev *device)
|
||||
emulate_button_press (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
gint btn = device->mousekeys_btn;
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
gint btn = device_evdev->mousekeys_btn;
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (btn)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (btn)])
|
||||
return;
|
||||
|
||||
clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device,
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (), btn,
|
||||
CLUTTER_BUTTON_STATE_PRESSED);
|
||||
device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
|
||||
device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_PRESSED;
|
||||
}
|
||||
|
||||
static void
|
||||
emulate_button_release (ClutterInputDeviceEvdev *device)
|
||||
emulate_button_release (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
gint btn = device->mousekeys_btn;
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
gint btn = device_evdev->mousekeys_btn;
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (btn)] == CLUTTER_BUTTON_STATE_RELEASED)
|
||||
return;
|
||||
|
||||
clutter_virtual_input_device_notify_button (device->mousekeys_virtual_device,
|
||||
clutter_virtual_input_device_notify_button (device->accessibility_virtual_device,
|
||||
g_get_monotonic_time (), btn,
|
||||
CLUTTER_BUTTON_STATE_RELEASED);
|
||||
device->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
|
||||
device_evdev->mousekeys_btn_states[get_button_index (btn)] = CLUTTER_BUTTON_STATE_RELEASED;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -830,17 +832,18 @@ mousekeys_get_speed_factor (ClutterInputDeviceEvdev *device,
|
||||
#undef MOUSEKEYS_CURVE
|
||||
|
||||
static void
|
||||
emulate_pointer_motion (ClutterInputDeviceEvdev *device,
|
||||
emulate_pointer_motion (ClutterInputDeviceEvdev *device_evdev,
|
||||
gint dx,
|
||||
gint dy)
|
||||
{
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
gdouble dx_motion;
|
||||
gdouble dy_motion;
|
||||
gdouble speed;
|
||||
gint64 time_us;
|
||||
|
||||
time_us = g_get_monotonic_time ();
|
||||
speed = mousekeys_get_speed_factor (device, time_us);
|
||||
speed = mousekeys_get_speed_factor (device_evdev, time_us);
|
||||
|
||||
if (dx < 0)
|
||||
dx_motion = floor (((gdouble) dx) * speed);
|
||||
@@ -852,56 +855,66 @@ emulate_pointer_motion (ClutterInputDeviceEvdev *device,
|
||||
else
|
||||
dy_motion = ceil (((gdouble) dy) * speed);
|
||||
|
||||
clutter_virtual_input_device_notify_relative_motion (device->mousekeys_virtual_device,
|
||||
clutter_virtual_input_device_notify_relative_motion (device->accessibility_virtual_device,
|
||||
time_us, dx_motion, dy_motion);
|
||||
}
|
||||
static gboolean
|
||||
is_numlock_active (ClutterInputDeviceEvdev *device)
|
||||
{
|
||||
ClutterSeatEvdev *seat = device->seat;
|
||||
return xkb_state_mod_name_is_active (seat->xkb,
|
||||
"Mod2",
|
||||
XKB_STATE_MODS_LOCKED);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_mousekeys (ClutterInputDeviceEvdev *device)
|
||||
enable_mousekeys (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
ClutterDeviceManager *manager = device->device_manager;
|
||||
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
device->move_mousekeys_timer = 0;
|
||||
device->mousekeys_first_motion_time = 0;
|
||||
device->mousekeys_last_motion_time = 0;
|
||||
device->last_mousekeys_key = 0;
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
device_evdev->move_mousekeys_timer = 0;
|
||||
device_evdev->mousekeys_first_motion_time = 0;
|
||||
device_evdev->mousekeys_last_motion_time = 0;
|
||||
device_evdev->last_mousekeys_key = 0;
|
||||
|
||||
if (device->mousekeys_virtual_device)
|
||||
if (device->accessibility_virtual_device)
|
||||
return;
|
||||
|
||||
manager = CLUTTER_INPUT_DEVICE (device)->device_manager;
|
||||
device->mousekeys_virtual_device =
|
||||
device->accessibility_virtual_device =
|
||||
clutter_device_manager_create_virtual_device (manager,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_mousekeys (ClutterInputDeviceEvdev *device)
|
||||
disable_mousekeys (ClutterInputDeviceEvdev *device_evdev)
|
||||
{
|
||||
stop_mousekeys_move (device);
|
||||
ClutterInputDevice *device = CLUTTER_INPUT_DEVICE (device_evdev);
|
||||
|
||||
stop_mousekeys_move (device_evdev);
|
||||
|
||||
/* Make sure we don't leave button pressed behind... */
|
||||
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_PRIMARY)])
|
||||
{
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
emulate_button_release (device);
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_PRIMARY;
|
||||
emulate_button_release (device_evdev);
|
||||
}
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_MIDDLE)])
|
||||
{
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
|
||||
emulate_button_release (device);
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_MIDDLE;
|
||||
emulate_button_release (device_evdev);
|
||||
}
|
||||
|
||||
if (device->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
|
||||
if (device_evdev->mousekeys_btn_states[get_button_index (CLUTTER_BUTTON_SECONDARY)])
|
||||
{
|
||||
device->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
|
||||
emulate_button_release (device);
|
||||
device_evdev->mousekeys_btn = CLUTTER_BUTTON_SECONDARY;
|
||||
emulate_button_release (device_evdev);
|
||||
}
|
||||
|
||||
if (device->mousekeys_virtual_device)
|
||||
g_clear_object (&device->mousekeys_virtual_device);
|
||||
if (device->accessibility_virtual_device)
|
||||
g_clear_object (&device->accessibility_virtual_device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1013,6 +1026,10 @@ handle_mousekeys_press (ClutterEvent *event,
|
||||
if (!(event->key.flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
|
||||
stop_mousekeys_move (device);
|
||||
|
||||
/* Do not handle mousekeys if NumLock is ON */
|
||||
if (is_numlock_active (device))
|
||||
return FALSE;
|
||||
|
||||
/* Button selection */
|
||||
switch (event->key.keyval)
|
||||
{
|
||||
@@ -1084,6 +1101,10 @@ static gboolean
|
||||
handle_mousekeys_release (ClutterEvent *event,
|
||||
ClutterInputDeviceEvdev *device)
|
||||
{
|
||||
/* Do not handle mousekeys if NumLock is ON */
|
||||
if (is_numlock_active (device))
|
||||
return FALSE;
|
||||
|
||||
switch (event->key.keyval)
|
||||
{
|
||||
case XKB_KEY_KP_0:
|
||||
|
@@ -94,7 +94,6 @@ struct _ClutterInputDeviceEvdev
|
||||
gdouble mousekeys_curve_factor;
|
||||
guint move_mousekeys_timer;
|
||||
guint16 last_mousekeys_key;
|
||||
ClutterVirtualInputDevice *mousekeys_virtual_device;
|
||||
};
|
||||
|
||||
GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
|
||||
|
@@ -133,6 +133,7 @@ clutter_sources = [
|
||||
'clutter-input-device-tool.c',
|
||||
'clutter-input-focus.c',
|
||||
'clutter-input-method.c',
|
||||
'clutter-input-pointer-a11y.c',
|
||||
'clutter-virtual-input-device.c',
|
||||
'clutter-interval.c',
|
||||
'clutter-keyframe-transition.c',
|
||||
@@ -195,6 +196,7 @@ clutter_private_headers = [
|
||||
'clutter-id-pool.h',
|
||||
'clutter-input-focus-private.h',
|
||||
'clutter-input-method-private.h',
|
||||
'clutter-input-pointer-a11y-private.h',
|
||||
'clutter-master-clock.h',
|
||||
'clutter-master-clock-default.h',
|
||||
'clutter-offscreen-effect-private.h',
|
||||
@@ -504,7 +506,12 @@ libmutter_clutter_dep = declare_dependency(
|
||||
)
|
||||
|
||||
if have_introspection
|
||||
clutter_introspection_args = introspection_args + clutter_c_args
|
||||
clutter_introspection_args = introspection_args + [
|
||||
'-DCLUTTER_SYSCONFDIR="@0@"'.format(join_paths(prefix, sysconfdir)),
|
||||
'-DCLUTTER_COMPILATION=1',
|
||||
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
|
||||
'-DG_LOG_DOMAIN="Clutter"'
|
||||
]
|
||||
|
||||
libmutter_clutter_gir = gnome.generate_gir(libmutter_clutter,
|
||||
sources: [
|
||||
|
@@ -54,6 +54,7 @@
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-settings-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterBackendX11, clutter_backend_x11, CLUTTER_TYPE_BACKEND)
|
||||
|
||||
@@ -276,6 +277,20 @@ clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
|
||||
_clutter_backend_add_event_translator (backend, translator);
|
||||
}
|
||||
|
||||
static void
|
||||
on_keymap_state_change (ClutterKeymapX11 *keymap_x11,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data);
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
|
||||
/* On keymaps state change, just reapply the current settings, it'll
|
||||
* take care of enabling/disabling mousekeys based on NumLock state.
|
||||
*/
|
||||
clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
@@ -292,6 +307,11 @@ clutter_backend_x11_create_keymap (ClutterBackendX11 *backend_x11)
|
||||
backend = CLUTTER_BACKEND (backend_x11);
|
||||
translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->keymap);
|
||||
_clutter_backend_add_event_translator (backend, translator);
|
||||
|
||||
g_signal_connect (backend_x11->keymap,
|
||||
"state-changed",
|
||||
G_CALLBACK (on_keymap_state_change),
|
||||
backend->device_manager);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "clutter-input-device-xi2.h"
|
||||
#include "clutter-input-device-tool-xi2.h"
|
||||
#include "clutter-input-pointer-a11y-private.h"
|
||||
#include "clutter-virtual-input-device-x11.h"
|
||||
#include "clutter-stage-x11.h"
|
||||
|
||||
@@ -1273,6 +1274,60 @@ translate_pad_event (ClutterEvent *event,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_raw_event (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
XEvent *xevent)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
XGenericEventCookie *cookie;
|
||||
XIEvent *xi_event;
|
||||
XIRawEvent *xev;
|
||||
float x,y;
|
||||
|
||||
cookie = &xevent->xcookie;
|
||||
xi_event = (XIEvent *) cookie->data;
|
||||
xev = (XIRawEvent *) xi_event;
|
||||
|
||||
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
if (!_clutter_is_input_pointer_a11y_enabled (device))
|
||||
return;
|
||||
|
||||
switch (cookie->evtype)
|
||||
{
|
||||
case XI_RawMotion:
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"raw motion: device:%d '%s'",
|
||||
device->id,
|
||||
device->device_name);
|
||||
/* We don't get actual pointer location with raw events, and we cannot
|
||||
* rely on `clutter_input_device_get_coords()` either because of
|
||||
* unreparented toplevels (like all client-side decoration windows),
|
||||
* so we need to explicitely query the pointer here...
|
||||
*/
|
||||
if (clutter_input_device_xi2_get_pointer_location (device, &x, &y))
|
||||
_clutter_input_pointer_a11y_on_motion_event (device, x, y);
|
||||
break;
|
||||
case XI_RawButtonPress:
|
||||
case XI_RawButtonRelease:
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"raw button %s: device:%d '%s' button %i",
|
||||
cookie->evtype == XI_RawButtonPress
|
||||
? "press "
|
||||
: "release",
|
||||
device->id,
|
||||
device->device_name,
|
||||
xev->detail);
|
||||
_clutter_input_pointer_a11y_on_button_event (device,
|
||||
xev->detail,
|
||||
(cookie->evtype == XI_RawButtonPress));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterTranslateReturn
|
||||
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
@@ -1303,6 +1358,14 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
if (!xi_event)
|
||||
return CLUTTER_TRANSLATE_REMOVE;
|
||||
|
||||
if (cookie->evtype == XI_RawMotion ||
|
||||
cookie->evtype == XI_RawButtonPress ||
|
||||
cookie->evtype == XI_RawButtonRelease)
|
||||
{
|
||||
handle_raw_event (manager_xi2, xevent);
|
||||
return CLUTTER_TRANSLATE_REMOVE;
|
||||
}
|
||||
|
||||
if (!(xi_event->evtype == XI_HierarchyChanged ||
|
||||
xi_event->evtype == XI_DeviceChanged ||
|
||||
xi_event->evtype == XI_PropertyEvent))
|
||||
@@ -2031,7 +2094,7 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
GHashTable *masters, *slaves;
|
||||
XIDeviceInfo *info;
|
||||
XIEventMask event_mask;
|
||||
unsigned char mask[2] = { 0, };
|
||||
unsigned char mask[(XI_LASTEVENT + 7) / 8] = { 0, };
|
||||
int n_devices, i;
|
||||
|
||||
backend_x11 =
|
||||
@@ -2083,6 +2146,19 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
event_mask.mask_len = sizeof (mask);
|
||||
event_mask.mask = mask;
|
||||
|
||||
clutter_device_manager_xi2_select_events (manager,
|
||||
clutter_x11_get_root_window (),
|
||||
&event_mask);
|
||||
|
||||
memset(mask, 0, sizeof (mask));
|
||||
XISetMask (mask, XI_RawMotion);
|
||||
XISetMask (mask, XI_RawButtonPress);
|
||||
XISetMask (mask, XI_RawButtonRelease);
|
||||
|
||||
event_mask.deviceid = XIAllMasterDevices;
|
||||
event_mask.mask_len = sizeof (mask);
|
||||
event_mask.mask = mask;
|
||||
|
||||
clutter_device_manager_xi2_select_events (manager,
|
||||
clutter_x11_get_root_window (),
|
||||
&event_mask);
|
||||
|
@@ -46,6 +46,11 @@ struct _ClutterInputDeviceXI2
|
||||
gint device_id;
|
||||
ClutterInputDeviceTool *current_tool;
|
||||
|
||||
guint inhibit_pointer_query_timer;
|
||||
gboolean query_status;
|
||||
float current_x;
|
||||
float current_y;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDevice *wacom_device;
|
||||
GArray *group_modes;
|
||||
@@ -112,6 +117,9 @@ clutter_input_device_xi2_finalize (GObject *object)
|
||||
|
||||
if (device_xi2->group_modes)
|
||||
g_array_unref (device_xi2->group_modes);
|
||||
|
||||
if (device_xi2->inhibit_pointer_query_timer)
|
||||
g_source_remove (device_xi2->inhibit_pointer_query_timer);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
|
||||
@@ -293,6 +301,75 @@ clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
|
||||
return device_xi2->current_tool;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_input_device_xi2_query_pointer_location (ClutterInputDeviceXI2 *device_xi2)
|
||||
{
|
||||
Window xroot_window, xchild_window;
|
||||
double xroot_x, xroot_y, xwin_x, xwin_y;
|
||||
XIButtonState button_state;
|
||||
XIModifierState mod_state;
|
||||
XIGroupState group_state;
|
||||
int result;
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
result = XIQueryPointer (clutter_x11_get_default_display (),
|
||||
device_xi2->device_id,
|
||||
clutter_x11_get_root_window (),
|
||||
&xroot_window,
|
||||
&xchild_window,
|
||||
&xroot_x, &xroot_y,
|
||||
&xwin_x, &xwin_y,
|
||||
&button_state,
|
||||
&mod_state,
|
||||
&group_state);
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
if (!result)
|
||||
return FALSE;
|
||||
|
||||
device_xi2->current_x = (float) xroot_x;
|
||||
device_xi2->current_y = (float) xroot_y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clear_inhibit_pointer_query_cb (gpointer data)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (data);
|
||||
|
||||
device_xi2->inhibit_pointer_query_timer = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
|
||||
float *x,
|
||||
float *y)
|
||||
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_XI2 (device_xi2), FALSE);
|
||||
g_return_val_if_fail (device->device_type == CLUTTER_POINTER_DEVICE, FALSE);
|
||||
|
||||
/* Throttle XServer queries and roundtrips using an idle timeout */
|
||||
if (device_xi2->inhibit_pointer_query_timer == 0)
|
||||
{
|
||||
device_xi2->query_status =
|
||||
clutter_input_device_xi2_query_pointer_location (device_xi2);
|
||||
device_xi2->inhibit_pointer_query_timer =
|
||||
clutter_threads_add_idle (clear_inhibit_pointer_query_cb, device_xi2);
|
||||
}
|
||||
|
||||
*x = device_xi2->current_x;
|
||||
*y = device_xi2->current_y;
|
||||
|
||||
return device_xi2->query_status;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void
|
||||
clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
|
@@ -48,6 +48,9 @@ void _clutter_input_device_xi2_translate_state (ClutterEvent *event,
|
||||
void clutter_input_device_xi2_update_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device);
|
||||
gboolean clutter_input_device_xi2_get_pointer_location (ClutterInputDevice *device,
|
||||
float *x,
|
||||
float *y);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
|
@@ -250,7 +250,8 @@ get_direction (XkbDescPtr xkb,
|
||||
{
|
||||
int level = 0;
|
||||
KeySym sym = XkbKeySymEntry (xkb, code, level, group);
|
||||
PangoDirection dir = pango_unichar_direction (clutter_keysym_to_unicode (sym));
|
||||
PangoDirection dir =
|
||||
_clutter_pango_unichar_direction (clutter_keysym_to_unicode (sym));
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
|
@@ -241,8 +241,13 @@ clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *devi
|
||||
}
|
||||
|
||||
/* mouse keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
||||
if (clutter_keymap_get_num_lock_state (CLUTTER_KEYMAP (backend_x11->keymap)))
|
||||
{
|
||||
/* Disable mousekeys when NumLock is ON */
|
||||
desc->ctrls->enabled_ctrls &= ~(XkbMouseKeysMask | XkbMouseKeysAccelMask);
|
||||
}
|
||||
else if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
||||
{
|
||||
gint mk_max_speed;
|
||||
gint mk_accel_time;
|
||||
|
@@ -1,7 +1,5 @@
|
||||
clutter_includesubdir = join_paths(pkgname, 'clutter')
|
||||
clutter_includedir = join_paths(includedir, clutter_includesubdir)
|
||||
clutter_srcdir = join_paths(top_srcdir, 'clutter')
|
||||
clutter_builddir = join_paths(builddir, 'clutter')
|
||||
|
||||
clutter_includepath = include_directories('.', 'clutter')
|
||||
clutter_includes = [clutter_includepath, cogl_includepath]
|
||||
@@ -14,19 +12,19 @@ clutter_c_args = [
|
||||
]
|
||||
|
||||
clutter_debug_c_args = []
|
||||
if buildtype.startswith('debug')
|
||||
clutter_debug_c_args += '-DG_DISABLE_CAST_CHECKS'
|
||||
if buildtype == 'debug'
|
||||
clutter_debug_c_args += '-DCLUTTER_ENABLE_DEBUG'
|
||||
endif
|
||||
elif buildtype == 'release'
|
||||
if get_option('debug')
|
||||
clutter_debug_c_args += [
|
||||
'-DCLUTTER_ENABLE_DEBUG',
|
||||
'-fno-omit-frame-pointer'
|
||||
]
|
||||
elif buildtype != 'plain'
|
||||
clutter_debug_c_args += [
|
||||
'-DG_DISABLE_ASSERT',
|
||||
'-DG_DISABLE_CHECKS',
|
||||
'-DG_DISABLE_CAST_CHECKS',
|
||||
]
|
||||
endif
|
||||
|
||||
supported_clutter_debug_c_args = cc.get_supported_arguments(clutter_debug_c_args)
|
||||
clutter_c_args += clutter_debug_c_args
|
||||
|
||||
clutter_pkg_deps = [
|
||||
@@ -40,6 +38,7 @@ clutter_pkg_deps = [
|
||||
]
|
||||
|
||||
clutter_pkg_private_deps = [
|
||||
fribidi_dep,
|
||||
gdk_pixbuf_dep,
|
||||
gthread_dep,
|
||||
gmodule_no_export_dep,
|
||||
|
@@ -114,12 +114,12 @@ test_destroy_destroy (ClutterActor *self)
|
||||
test->tex = NULL;
|
||||
}
|
||||
|
||||
g_list_foreach (test->children, (GFunc) clutter_actor_destroy, NULL);
|
||||
g_list_free (test->children);
|
||||
test->children = NULL;
|
||||
g_assert_nonnull (test->children);
|
||||
|
||||
if (CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy)
|
||||
CLUTTER_ACTOR_CLASS (test_destroy_parent_class)->destroy (self);
|
||||
|
||||
g_assert_null (test->children);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -1,6 +1,3 @@
|
||||
clutter_tests_conform_srcdir = join_paths(clutter_srcdir, 'tests/conform')
|
||||
clutter_tests_conform_builddir = join_paths(clutter_builddir, 'tests/conform')
|
||||
|
||||
clutter_tests_conform_c_args = [
|
||||
'-DG_LOG_DOMAIN="Clutter-Conform"',
|
||||
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
|
||||
@@ -52,8 +49,8 @@ clutter_conform_tests += clutter_conform_tests_general_tests
|
||||
clutter_conform_tests += clutter_conform_tests_deprecated_tests
|
||||
|
||||
test_env = environment()
|
||||
test_env.set('G_TEST_SRCDIR', clutter_tests_conform_srcdir)
|
||||
test_env.set('G_TEST_BUILDDIR', clutter_tests_conform_builddir)
|
||||
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
|
||||
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
|
||||
test_env.set('G_ENABLE_DIAGNOSTIC', '0')
|
||||
test_env.set('CLUTTER_ENABLE_DIAGNOSTIC', '0')
|
||||
test_env.set('CLUTTER_SCALE', '1')
|
||||
@@ -74,7 +71,8 @@ foreach test : clutter_conform_tests
|
||||
install: false,
|
||||
)
|
||||
|
||||
test('clutter/conform/@0@'.format(test), test_executable,
|
||||
test(test, test_executable,
|
||||
suite: ['clutter', 'clutter/conform'],
|
||||
env: test_env
|
||||
)
|
||||
endforeach
|
||||
|
@@ -38,8 +38,7 @@ timeline_data_init (TimelineData *data, int timeline_num)
|
||||
static void
|
||||
timeline_data_destroy (TimelineData *data)
|
||||
{
|
||||
g_slist_foreach (data->markers_hit, (GFunc) g_free, NULL);
|
||||
g_slist_free (data->markers_hit);
|
||||
g_slist_free_full (data->markers_hit, g_free);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -1,7 +1,5 @@
|
||||
clutter_tests_interactive_srcdir = join_paths(clutter_srcdir, 'tests/interactive')
|
||||
|
||||
clutter_tests_interactive_srcdir = meson.current_source_dir()
|
||||
clutter_tests_interactive_includepath = include_directories('.')
|
||||
#clutter_tests_interactive_builddir = join_paths(clutter_builddir, 'tests/interactive')
|
||||
|
||||
clutter_tests_interactive_c_args = [
|
||||
'-DTESTS_DATADIR="@0@"'.format(clutter_tests_interactive_srcdir),
|
||||
@@ -31,7 +29,6 @@ clutter_tests_interactive_test_sources = [
|
||||
'test-fbo.c',
|
||||
'test-cogl-tex-tile.c',
|
||||
'test-cogl-tex-convert.c',
|
||||
'test-cogl-tex-foreign.c',
|
||||
'test-cogl-offscreen.c',
|
||||
'test-cogl-tex-polygon.c',
|
||||
'test-cogl-multitexture.c',
|
||||
|
@@ -1,276 +0,0 @@
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#ifndef GL_UNPACK_ALIGNMENT
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#endif
|
||||
#ifndef GL_TEXTURE_BINDING_2D
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
#endif
|
||||
#ifndef GL_TEXTURE_2D
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#endif
|
||||
#ifndef GL_RGB
|
||||
#define GL_RGB 0x1907
|
||||
#endif
|
||||
#ifndef GL_UNSIGNED_BYTE
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#endif
|
||||
#ifndef GL_TEXTURE_MAG_FILTER
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#endif
|
||||
#ifndef GL_LINEAR
|
||||
#define GL_LINEAR 0x1208
|
||||
#endif
|
||||
#ifndef GL_TEXTURE_MIN_FILTER
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#endif
|
||||
|
||||
/* Coglbox declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
||||
|
||||
#define TEST_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
#define TEST_IS_COGLBOX(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_IS_COGLBOX_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
TEST_TYPE_COGLBOX))
|
||||
|
||||
#define TEST_COGLBOX_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
||||
|
||||
typedef struct _TestCoglbox TestCoglbox;
|
||||
typedef struct _TestCoglboxClass TestCoglboxClass;
|
||||
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
||||
|
||||
const char *
|
||||
test_cogl_tex_foreign_describe (void);
|
||||
|
||||
struct _TestCoglbox
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
/*< private >*/
|
||||
TestCoglboxPrivate *priv;
|
||||
};
|
||||
|
||||
struct _TestCoglboxClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_test_coglbox1) (void);
|
||||
void (*_test_coglbox2) (void);
|
||||
void (*_test_coglbox3) (void);
|
||||
void (*_test_coglbox4) (void);
|
||||
};
|
||||
|
||||
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* Coglbox private declaration
|
||||
*--------------------------------------------------*/
|
||||
|
||||
struct _TestCoglboxPrivate
|
||||
{
|
||||
guint gl_handle;
|
||||
CoglHandle cogl_handle;
|
||||
|
||||
void
|
||||
(* glGetIntegerv) (guint pname, int *params);
|
||||
void
|
||||
(* glPixelStorei) (guint pname, int param);
|
||||
void
|
||||
(* glTexParameteri) (guint target, guint pname, int param);
|
||||
void
|
||||
(* glTexImage2D) (guint target, int level,
|
||||
int internalFormat,
|
||||
int width, int height,
|
||||
int border, guint format, guint type,
|
||||
const void *pixels);
|
||||
void
|
||||
(* glGenTextures) (int n, guint *textures);
|
||||
void
|
||||
(* glDeleteTextures) (int n, const guint *textures);
|
||||
void
|
||||
(* glBindTexture) (guint target, guint texture);
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
||||
|
||||
int
|
||||
test_cogl_tex_foreign_main (int argc, char *argv[]);
|
||||
|
||||
/* Coglbox implementation
|
||||
*--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
test_coglbox_paint(ClutterActor *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
||||
gfloat texcoords[4] = { 0.3f, 0.3f, 0.7f, 0.7f };
|
||||
|
||||
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
|
||||
cogl_rectangle (0,0,400,400);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_translate (100,100,0);
|
||||
cogl_set_source_texture (priv->cogl_handle);
|
||||
cogl_rectangle_with_texture_coords (0, 0, 200, 200,
|
||||
texcoords[0], texcoords[1],
|
||||
texcoords[2], texcoords[3]);
|
||||
|
||||
cogl_pop_matrix();
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_dispose (GObject *object)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
|
||||
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
||||
|
||||
cogl_handle_unref (priv->cogl_handle);
|
||||
priv->glDeleteTextures (1, &priv->gl_handle);
|
||||
|
||||
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_init (TestCoglbox *self)
|
||||
{
|
||||
TestCoglboxPrivate *priv;
|
||||
guchar data[12];
|
||||
int prev_unpack_alignment;
|
||||
int prev_2d_texture_binding;
|
||||
|
||||
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
||||
|
||||
/* Prepare a 2x2 pixels texture */
|
||||
|
||||
data[0] = 255; data[1] = 0; data[2] = 0;
|
||||
data[3] = 0; data[4] = 255; data[5] = 0;
|
||||
data[6] = 0; data[7] = 0; data[8] = 255;
|
||||
data[9] = 0; data[10] = 0; data[11] = 0;
|
||||
|
||||
priv->glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv");
|
||||
priv->glPixelStorei = (void *) cogl_get_proc_address ("glPixelStorei");
|
||||
priv->glTexParameteri = (void *) cogl_get_proc_address ("glTexParameteri");
|
||||
priv->glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D");
|
||||
priv->glGenTextures = (void *) cogl_get_proc_address ("glGenTextures");
|
||||
priv->glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures");
|
||||
priv->glBindTexture = (void *) cogl_get_proc_address ("glBindTexture");
|
||||
|
||||
/* We are about to use OpenGL directly to create a TEXTURE_2D
|
||||
* texture so we need to save the state that we modify so we can
|
||||
* restore it afterwards and be sure not to interfere with any state
|
||||
* caching that Cogl may do internally.
|
||||
*/
|
||||
priv->glGetIntegerv (GL_UNPACK_ALIGNMENT, &prev_unpack_alignment);
|
||||
priv->glGetIntegerv (GL_TEXTURE_BINDING_2D, &prev_2d_texture_binding);
|
||||
|
||||
priv->glGenTextures (1, &priv->gl_handle);
|
||||
priv->glBindTexture (GL_TEXTURE_2D, priv->gl_handle);
|
||||
|
||||
priv->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
priv->glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
|
||||
2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
/* Now restore the original GL state as Cogl had left it */
|
||||
priv->glPixelStorei (GL_UNPACK_ALIGNMENT, prev_unpack_alignment);
|
||||
priv->glBindTexture (GL_TEXTURE_2D, prev_2d_texture_binding);
|
||||
|
||||
priv->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
priv->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
/* Create texture from foreign */
|
||||
|
||||
priv->cogl_handle =
|
||||
cogl_texture_new_from_foreign (priv->gl_handle,
|
||||
GL_TEXTURE_2D,
|
||||
2, 2, 0, 0,
|
||||
COGL_PIXEL_FORMAT_RGB_888);
|
||||
|
||||
if (priv->cogl_handle == COGL_INVALID_HANDLE)
|
||||
{
|
||||
printf ("Failed creating texture from foreign!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_coglbox_class_init (TestCoglboxClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = test_coglbox_finalize;
|
||||
gobject_class->dispose = test_coglbox_dispose;
|
||||
actor_class->paint = test_coglbox_paint;
|
||||
}
|
||||
|
||||
static ClutterActor*
|
||||
test_coglbox_new (void)
|
||||
{
|
||||
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT int
|
||||
test_cogl_tex_foreign_main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *stage;
|
||||
ClutterActor *coglbox;
|
||||
|
||||
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
|
||||
return 1;
|
||||
|
||||
/* Stage */
|
||||
stage = clutter_stage_new ();
|
||||
clutter_actor_set_size (stage, 400, 400);
|
||||
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Foreign Textures");
|
||||
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
||||
|
||||
/* Cogl Box */
|
||||
coglbox = test_coglbox_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT const char *
|
||||
test_cogl_tex_foreign_describe (void)
|
||||
{
|
||||
return "Foreign textures support in Cogl.";
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
clutter_tests_performance_c_args = [
|
||||
'-DTESTS_DATA_DIR="@0@"'.format(join_paths(clutter_srcdir, 'tests/interactive')),
|
||||
'-DTESTS_DATA_DIR="@0@"'.format(clutter_tests_interactive_srcdir),
|
||||
'-DG_DISABLE_SINGLE_INCLUDES',
|
||||
'-DGLIB_DISABLE_DEPRECATION_WARNINGS',
|
||||
'-DCOGL_DISABLE_DEPRECATION_WARNINGS',
|
||||
|
@@ -4,6 +4,9 @@
|
||||
/* Have GLES 2.0 for rendering */
|
||||
#mesondefine HAVE_COGL_GLES2
|
||||
|
||||
/* Building with Sysprof profiling suport */
|
||||
#mesondefine HAVE_TRACING
|
||||
|
||||
/* Enable unit tests */
|
||||
#mesondefine ENABLE_UNIT_TESTS
|
||||
|
||||
|
@@ -483,8 +483,8 @@ _cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node)
|
||||
void
|
||||
_cogl_pango_display_list_clear (CoglPangoDisplayList *dl)
|
||||
{
|
||||
g_slist_foreach (dl->nodes, (GFunc) _cogl_pango_display_list_node_free, NULL);
|
||||
g_slist_free (dl->nodes);
|
||||
g_slist_free_full (dl->nodes, (GDestroyNotify)
|
||||
_cogl_pango_display_list_node_free);
|
||||
dl->nodes = NULL;
|
||||
dl->last_node = NULL;
|
||||
}
|
||||
|
@@ -460,9 +460,7 @@ cogl_path_fill (CoglPath *path);
|
||||
* use while filling a path.</note>
|
||||
*
|
||||
* Stability: unstable
|
||||
* Deprecated: 1.16: Use cogl_path_fill() instead
|
||||
*/
|
||||
COGL_DEPRECATED_FOR (cogl_path_fill)
|
||||
void
|
||||
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -492,9 +490,7 @@ cogl_path_stroke (CoglPath *path);
|
||||
* regardless of the current transformation matrix.
|
||||
*
|
||||
* Stability: unstable
|
||||
* Deprecated: 1.16: Use cogl_path_stroke() instead
|
||||
*/
|
||||
COGL_DEPRECATED_FOR (cogl_path_stroke)
|
||||
void
|
||||
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -529,9 +525,7 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
|
||||
*
|
||||
* Since: 1.8
|
||||
* Stability: Unstable
|
||||
* Deprecated: 1.16: Use cogl_framebuffer_push_path_clip() instead
|
||||
*/
|
||||
COGL_DEPRECATED_FOR (cogl_framebuffer_push_path_clip)
|
||||
void
|
||||
cogl_clip_push_from_path (CoglPath *path);
|
||||
|
||||
|
@@ -1504,7 +1504,6 @@ cogl_framebuffer_push_path_clip (CoglFramebuffer *framebuffer,
|
||||
COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
}
|
||||
|
||||
/* XXX: deprecated */
|
||||
void
|
||||
cogl_clip_push_from_path (CoglPath *path)
|
||||
{
|
||||
@@ -1575,7 +1574,6 @@ _cogl_path_build_stroke_attribute_buffer (CoglPath *path)
|
||||
data->stroke_n_attributes = n_attributes;
|
||||
}
|
||||
|
||||
/* XXX: deprecated */
|
||||
void
|
||||
cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@@ -1588,7 +1586,6 @@ cogl_framebuffer_fill_path (CoglFramebuffer *framebuffer,
|
||||
_cogl_path_fill_nodes (path, framebuffer, pipeline, 0 /* flags */);
|
||||
}
|
||||
|
||||
/* XXX: deprecated */
|
||||
void
|
||||
cogl_framebuffer_stroke_path (CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
|
@@ -1013,12 +1013,6 @@ _cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx,
|
||||
g_hook_destroy_link (&ctx->atlas_reorganize_callbacks, hook);
|
||||
}
|
||||
|
||||
static CoglTextureType
|
||||
_cogl_atlas_texture_get_type (CoglTexture *tex)
|
||||
{
|
||||
return COGL_TEXTURE_TYPE_2D;
|
||||
}
|
||||
|
||||
static const CoglTextureVtable
|
||||
cogl_atlas_texture_vtable =
|
||||
{
|
||||
@@ -1040,7 +1034,6 @@ cogl_atlas_texture_vtable =
|
||||
_cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes,
|
||||
_cogl_atlas_texture_get_format,
|
||||
_cogl_atlas_texture_get_gl_format,
|
||||
_cogl_atlas_texture_get_type,
|
||||
NULL, /* is_foreign */
|
||||
NULL /* set_auto_mipmap */
|
||||
};
|
||||
|
@@ -562,29 +562,21 @@ create_migration_texture (CoglContext *ctx,
|
||||
CoglTexture *tex;
|
||||
CoglError *skip_error = NULL;
|
||||
|
||||
if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) ||
|
||||
(cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) &&
|
||||
cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP)))
|
||||
/* First try creating a fast-path non-sliced texture */
|
||||
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height));
|
||||
|
||||
_cogl_texture_set_internal_format (tex, internal_format);
|
||||
|
||||
/* TODO: instead of allocating storage here it would be better
|
||||
* if we had some api that let us just check that the size is
|
||||
* supported by the hardware so storage could be allocated
|
||||
* lazily when uploading data. */
|
||||
if (!cogl_texture_allocate (tex, &skip_error))
|
||||
{
|
||||
/* First try creating a fast-path non-sliced texture */
|
||||
tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx,
|
||||
width, height));
|
||||
|
||||
_cogl_texture_set_internal_format (tex, internal_format);
|
||||
|
||||
/* TODO: instead of allocating storage here it would be better
|
||||
* if we had some api that let us just check that the size is
|
||||
* supported by the hardware so storage could be allocated
|
||||
* lazily when uploading data. */
|
||||
if (!cogl_texture_allocate (tex, &skip_error))
|
||||
{
|
||||
cogl_error_free (skip_error);
|
||||
cogl_object_unref (tex);
|
||||
tex = NULL;
|
||||
}
|
||||
cogl_error_free (skip_error);
|
||||
cogl_object_unref (tex);
|
||||
tex = NULL;
|
||||
}
|
||||
else
|
||||
tex = NULL;
|
||||
|
||||
if (!tex)
|
||||
{
|
||||
|
@@ -43,6 +43,7 @@ typedef struct _CoglBitmap CoglBitmap;
|
||||
#include <cogl/cogl-buffer.h>
|
||||
#include <cogl/cogl-context.h>
|
||||
#include <cogl/cogl-pixel-buffer.h>
|
||||
#include <cogl/cogl-pixel-format.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
|
@@ -50,8 +50,6 @@
|
||||
#include "cogl-texture-driver.h"
|
||||
#include "cogl-pipeline-cache.h"
|
||||
#include "cogl-texture-2d.h"
|
||||
#include "cogl-texture-3d.h"
|
||||
#include "cogl-texture-rectangle.h"
|
||||
#include "cogl-sampler-cache-private.h"
|
||||
#include "cogl-gpu-info-private.h"
|
||||
#include "cogl-gl-header.h"
|
||||
@@ -103,9 +101,6 @@ struct _CoglContext
|
||||
unsigned long private_features
|
||||
[COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)];
|
||||
|
||||
gboolean needs_viewport_scissor_workaround;
|
||||
CoglFramebuffer *viewport_scissor_workaround_framebuffer;
|
||||
|
||||
CoglPipeline *default_pipeline;
|
||||
CoglPipelineLayer *default_layer_0;
|
||||
CoglPipelineLayer *default_layer_n;
|
||||
@@ -169,8 +164,6 @@ struct _CoglContext
|
||||
|
||||
/* Textures */
|
||||
CoglTexture2D *default_gl_texture_2d_tex;
|
||||
CoglTexture3D *default_gl_texture_3d_tex;
|
||||
CoglTextureRectangle *default_gl_texture_rect_tex;
|
||||
|
||||
/* Central list of all framebuffers so all journals can be flushed
|
||||
* at any time. */
|
||||
@@ -269,7 +262,6 @@ struct _CoglContext
|
||||
GLuint current_gl_program;
|
||||
|
||||
gboolean current_gl_dither_enabled;
|
||||
CoglColorMask current_gl_color_mask;
|
||||
GLenum current_gl_draw_buffer;
|
||||
|
||||
/* Clipping */
|
||||
@@ -301,8 +293,6 @@ struct _CoglContext
|
||||
gboolean buffer_map_fallback_in_use;
|
||||
size_t buffer_map_fallback_offset;
|
||||
|
||||
CoglWinsysRectangleState rectangle_state;
|
||||
|
||||
CoglSamplerCache *sampler_cache;
|
||||
|
||||
/* FIXME: remove these when we remove the last xlib based clutter
|
||||
|
@@ -40,8 +40,6 @@
|
||||
#include "cogl-journal-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-texture-2d-private.h"
|
||||
#include "cogl-texture-3d-private.h"
|
||||
#include "cogl-texture-rectangle-private.h"
|
||||
#include "cogl-pipeline-private.h"
|
||||
#include "cogl-framebuffer-private.h"
|
||||
#include "cogl-onscreen-private.h"
|
||||
@@ -106,30 +104,6 @@ _cogl_init_feature_overrides (CoglContext *ctx)
|
||||
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS)))
|
||||
COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE);
|
||||
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_GLSL)))
|
||||
{
|
||||
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL;
|
||||
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, FALSE);
|
||||
COGL_FLAGS_SET (ctx->features,
|
||||
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_NPOT_TEXTURES)))
|
||||
{
|
||||
ctx->feature_flags &= ~(COGL_FEATURE_TEXTURE_NPOT |
|
||||
COGL_FEATURE_TEXTURE_NPOT_BASIC |
|
||||
COGL_FEATURE_TEXTURE_NPOT_MIPMAP |
|
||||
COGL_FEATURE_TEXTURE_NPOT_REPEAT);
|
||||
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_NPOT, FALSE);
|
||||
COGL_FLAGS_SET (ctx->features,
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, FALSE);
|
||||
COGL_FLAGS_SET (ctx->features,
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP, FALSE);
|
||||
COGL_FLAGS_SET (ctx->features,
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
const CoglWinsysVtable *
|
||||
@@ -153,10 +127,8 @@ cogl_context_new (CoglDisplay *display,
|
||||
{
|
||||
CoglContext *context;
|
||||
uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff };
|
||||
CoglBitmap *white_pixel_bitmap;
|
||||
const CoglWinsysVtable *winsys;
|
||||
int i;
|
||||
CoglError *internal_error = NULL;
|
||||
|
||||
_cogl_init ();
|
||||
|
||||
@@ -197,9 +169,6 @@ cogl_context_new (CoglDisplay *display,
|
||||
memset (context->features, 0, sizeof (context->features));
|
||||
context->feature_flags = 0;
|
||||
memset (context->private_features, 0, sizeof (context->private_features));
|
||||
|
||||
context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;
|
||||
|
||||
memset (context->winsys_features, 0, sizeof (context->winsys_features));
|
||||
|
||||
if (!display)
|
||||
@@ -265,22 +234,6 @@ cogl_context_new (CoglDisplay *display,
|
||||
/* Initialise the driver specific state */
|
||||
_cogl_init_feature_overrides (context);
|
||||
|
||||
/* XXX: ONGOING BUG: Intel viewport scissor
|
||||
*
|
||||
* Intel gen6 drivers don't currently correctly handle offset
|
||||
* viewports, since primitives aren't clipped within the bounds of
|
||||
* the viewport. To workaround this we push our own clip for the
|
||||
* viewport that will use scissoring to ensure we clip as expected.
|
||||
*
|
||||
* TODO: file a bug upstream!
|
||||
*/
|
||||
if (context->gpu.driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA &&
|
||||
context->gpu.architecture == COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE &&
|
||||
!getenv ("COGL_DISABLE_INTEL_VIEWPORT_SCISSORT_WORKAROUND"))
|
||||
context->needs_viewport_scissor_workaround = TRUE;
|
||||
else
|
||||
context->needs_viewport_scissor_workaround = FALSE;
|
||||
|
||||
context->sampler_cache = _cogl_sampler_cache_new (context);
|
||||
|
||||
_cogl_pipeline_init_default_pipeline ();
|
||||
@@ -323,8 +276,6 @@ cogl_context_new (CoglDisplay *display,
|
||||
context->legacy_state_set = 0;
|
||||
|
||||
context->default_gl_texture_2d_tex = NULL;
|
||||
context->default_gl_texture_3d_tex = NULL;
|
||||
context->default_gl_texture_rect_tex = NULL;
|
||||
|
||||
context->framebuffers = NULL;
|
||||
context->current_draw_buffer = NULL;
|
||||
@@ -366,7 +317,6 @@ cogl_context_new (CoglDisplay *display,
|
||||
context->current_gl_program = 0;
|
||||
|
||||
context->current_gl_dither_enabled = TRUE;
|
||||
context->current_gl_color_mask = COGL_COLOR_MASK_ALL;
|
||||
|
||||
context->gl_blend_enable_cache = FALSE;
|
||||
|
||||
@@ -453,41 +403,6 @@ cogl_context_new (CoglDisplay *display,
|
||||
white_pixel,
|
||||
NULL); /* abort on error */
|
||||
|
||||
/* If 3D or rectangle textures aren't supported then these will
|
||||
* return errors that we can simply ignore. */
|
||||
internal_error = NULL;
|
||||
context->default_gl_texture_3d_tex =
|
||||
cogl_texture_3d_new_from_data (context,
|
||||
1, 1, 1, /* width, height, depth */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
0, /* rowstride */
|
||||
0, /* image stride */
|
||||
white_pixel,
|
||||
&internal_error);
|
||||
if (internal_error)
|
||||
cogl_error_free (internal_error);
|
||||
|
||||
/* TODO: add cogl_texture_rectangle_new_from_data() */
|
||||
white_pixel_bitmap =
|
||||
cogl_bitmap_new_for_data (context,
|
||||
1, 1, /* width/height */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
4, /* rowstride */
|
||||
white_pixel);
|
||||
|
||||
internal_error = NULL;
|
||||
context->default_gl_texture_rect_tex =
|
||||
cogl_texture_rectangle_new_from_bitmap (white_pixel_bitmap);
|
||||
|
||||
/* XXX: we need to allocate the texture now because the white_pixel
|
||||
* data is on the stack */
|
||||
cogl_texture_allocate (COGL_TEXTURE (context->default_gl_texture_rect_tex),
|
||||
&internal_error);
|
||||
if (internal_error)
|
||||
cogl_error_free (internal_error);
|
||||
|
||||
cogl_object_unref (white_pixel_bitmap);
|
||||
|
||||
cogl_push_source (context->opaque_color_pipeline);
|
||||
|
||||
context->atlases = NULL;
|
||||
@@ -526,10 +441,6 @@ _cogl_context_free (CoglContext *context)
|
||||
|
||||
if (context->default_gl_texture_2d_tex)
|
||||
cogl_object_unref (context->default_gl_texture_2d_tex);
|
||||
if (context->default_gl_texture_3d_tex)
|
||||
cogl_object_unref (context->default_gl_texture_3d_tex);
|
||||
if (context->default_gl_texture_rect_tex)
|
||||
cogl_object_unref (context->default_gl_texture_rect_tex);
|
||||
|
||||
if (context->opaque_color_pipeline)
|
||||
cogl_object_unref (context->opaque_color_pipeline);
|
||||
|
@@ -174,33 +174,14 @@ cogl_is_context (void *object);
|
||||
* experimental since it's only useable with experimental API... */
|
||||
/**
|
||||
* CoglFeatureID:
|
||||
* @COGL_FEATURE_ID_TEXTURE_NPOT_BASIC: The hardware supports non power
|
||||
* of two textures, but you also need to check the
|
||||
* %COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT
|
||||
* features to know if the hardware supports npot texture mipmaps
|
||||
* or repeat modes other than
|
||||
* %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE respectively.
|
||||
* @COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP: Mipmapping is supported in
|
||||
* conjuntion with non power of two textures.
|
||||
* @COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT: Repeat modes other than
|
||||
* %COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE are supported by the
|
||||
* hardware.
|
||||
* @COGL_FEATURE_ID_TEXTURE_NPOT: Non power of two textures are supported
|
||||
* by the hardware. This is a equivalent to the
|
||||
* %COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, %COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP
|
||||
* and %COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT features combined.
|
||||
* @COGL_FEATURE_ID_TEXTURE_RECTANGLE: Support for rectangular
|
||||
* textures with non-normalized texture coordinates.
|
||||
* @COGL_FEATURE_ID_TEXTURE_RG: Support for
|
||||
* %COGL_TEXTURE_COMPONENTS_RG as the internal components of a
|
||||
* texture.
|
||||
* @COGL_FEATURE_ID_TEXTURE_3D: 3D texture support
|
||||
* @COGL_FEATURE_ID_OFFSCREEN: Offscreen rendering support
|
||||
* @COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE: Multisample support for
|
||||
* offscreen framebuffers
|
||||
* @COGL_FEATURE_ID_ONSCREEN_MULTIPLE: Multiple onscreen framebuffers
|
||||
* supported.
|
||||
* @COGL_FEATURE_ID_GLSL: GLSL support
|
||||
* @COGL_FEATURE_ID_UNSIGNED_INT_INDICES: Set if
|
||||
* %COGL_INDICES_TYPE_UNSIGNED_INT is supported in
|
||||
* cogl_indices_new().
|
||||
@@ -236,13 +217,6 @@ cogl_is_context (void *object);
|
||||
*/
|
||||
typedef enum _CoglFeatureID
|
||||
{
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC = 1,
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP,
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT,
|
||||
COGL_FEATURE_ID_TEXTURE_NPOT,
|
||||
COGL_FEATURE_ID_TEXTURE_RECTANGLE,
|
||||
COGL_FEATURE_ID_TEXTURE_3D,
|
||||
COGL_FEATURE_ID_GLSL,
|
||||
COGL_FEATURE_ID_OFFSCREEN,
|
||||
COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE,
|
||||
COGL_FEATURE_ID_ONSCREEN_MULTIPLE,
|
||||
|
@@ -130,22 +130,11 @@ OPT (DISABLE_TEXTURING,
|
||||
"disable-texturing",
|
||||
N_("Disable texturing"),
|
||||
N_("Disable texturing any primitives"))
|
||||
OPT (DISABLE_GLSL,
|
||||
N_("Root Cause"),
|
||||
"disable-glsl",
|
||||
N_("Disable GLSL"),
|
||||
N_("Disable use of GLSL"))
|
||||
OPT (DISABLE_BLENDING,
|
||||
N_("Root Cause"),
|
||||
"disable-blending",
|
||||
N_("Disable blending"),
|
||||
N_("Disable use of blending"))
|
||||
OPT (DISABLE_NPOT_TEXTURES,
|
||||
N_("Root Cause"),
|
||||
"disable-npot-textures",
|
||||
N_("Disable non-power-of-two textures"),
|
||||
N_("Makes Cogl think that the GL driver doesn't support NPOT textures "
|
||||
"so that it will create sliced textures or textures with waste instead."))
|
||||
OPT (DISABLE_SOFTWARE_CLIP,
|
||||
N_("Root Cause"),
|
||||
"disable-software-clip",
|
||||
|
@@ -77,9 +77,7 @@ static const GDebugKey cogl_behavioural_debug_keys[] = {
|
||||
{ "disable-atlas", COGL_DEBUG_DISABLE_ATLAS },
|
||||
{ "disable-shared-atlas", COGL_DEBUG_DISABLE_SHARED_ATLAS },
|
||||
{ "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING},
|
||||
{ "disable-glsl", COGL_DEBUG_DISABLE_GLSL},
|
||||
{ "disable-blending", COGL_DEBUG_DISABLE_BLENDING},
|
||||
{ "disable-npot-textures", COGL_DEBUG_DISABLE_NPOT_TEXTURES},
|
||||
{ "wireframe", COGL_DEBUG_WIREFRAME},
|
||||
{ "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP},
|
||||
{ "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES},
|
||||
|
@@ -61,12 +61,10 @@ typedef enum
|
||||
COGL_DEBUG_DISABLE_SHARED_ATLAS,
|
||||
COGL_DEBUG_OPENGL,
|
||||
COGL_DEBUG_DISABLE_TEXTURING,
|
||||
COGL_DEBUG_DISABLE_GLSL,
|
||||
COGL_DEBUG_SHOW_SOURCE,
|
||||
COGL_DEBUG_DISABLE_BLENDING,
|
||||
COGL_DEBUG_TEXTURE_PIXMAP,
|
||||
COGL_DEBUG_BITMAP,
|
||||
COGL_DEBUG_DISABLE_NPOT_TEXTURES,
|
||||
COGL_DEBUG_WIREFRAME,
|
||||
COGL_DEBUG_DISABLE_SOFTWARE_CLIP,
|
||||
COGL_DEBUG_DISABLE_PROGRAM_CACHES,
|
||||
|
@@ -83,11 +83,10 @@ typedef enum _CoglFramebufferStateIndex
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 9,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_MAX = 10
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 6,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 7,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 8,
|
||||
COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9
|
||||
} CoglFramebufferStateIndex;
|
||||
|
||||
typedef enum _CoglFramebufferState
|
||||
@@ -98,10 +97,9 @@ typedef enum _CoglFramebufferState
|
||||
COGL_FRAMEBUFFER_STATE_DITHER = 1<<3,
|
||||
COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4,
|
||||
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
|
||||
COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
|
||||
COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
|
||||
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8,
|
||||
COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<9
|
||||
COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<6,
|
||||
COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<7,
|
||||
COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<8
|
||||
} CoglFramebufferState;
|
||||
|
||||
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
|
||||
@@ -155,7 +153,6 @@ struct _CoglFramebuffer
|
||||
|
||||
gboolean dither_enabled;
|
||||
gboolean depth_writing_enabled;
|
||||
CoglColorMask color_mask;
|
||||
CoglStereoMode stereo_mode;
|
||||
|
||||
/* We journal the textured rectangles we want to submit to OpenGL so
|
||||
|
@@ -123,8 +123,6 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
|
||||
|
||||
framebuffer->dirty_bitmasks = TRUE;
|
||||
|
||||
framebuffer->color_mask = COGL_COLOR_MASK_ALL;
|
||||
|
||||
framebuffer->samples_per_pixel = 0;
|
||||
|
||||
framebuffer->clip_stack = NULL;
|
||||
@@ -191,9 +189,6 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
|
||||
|
||||
cogl_object_unref (framebuffer->journal);
|
||||
|
||||
if (ctx->viewport_scissor_workaround_framebuffer == framebuffer)
|
||||
ctx->viewport_scissor_workaround_framebuffer = NULL;
|
||||
|
||||
ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer);
|
||||
|
||||
if (ctx->current_draw_buffer == framebuffer)
|
||||
@@ -260,13 +255,11 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||
float blue,
|
||||
float alpha)
|
||||
{
|
||||
CoglContext *ctx = framebuffer->context;
|
||||
CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer);
|
||||
int scissor_x0;
|
||||
int scissor_y0;
|
||||
int scissor_x1;
|
||||
int scissor_y1;
|
||||
gboolean saved_viewport_scissor_workaround;
|
||||
|
||||
if (!framebuffer->depth_buffer_clear_needed &&
|
||||
(buffers & COGL_BUFFER_BIT_DEPTH))
|
||||
@@ -361,31 +354,6 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||
|
||||
_cogl_framebuffer_flush_journal (framebuffer);
|
||||
|
||||
/* XXX: ONGOING BUG: Intel viewport scissor
|
||||
*
|
||||
* The semantics of cogl_framebuffer_clear() are that it should not
|
||||
* be affected by the current viewport and so if we are currently
|
||||
* applying a workaround for viewport scissoring we need to
|
||||
* temporarily disable the workaround before clearing so any
|
||||
* special scissoring for the workaround will be removed first.
|
||||
*
|
||||
* Note: we only need to disable the workaround if the current
|
||||
* viewport doesn't match the framebuffer's size since otherwise
|
||||
* the workaround wont affect clearing anyway.
|
||||
*/
|
||||
if (ctx->needs_viewport_scissor_workaround &&
|
||||
(framebuffer->viewport_x != 0 ||
|
||||
framebuffer->viewport_y != 0 ||
|
||||
framebuffer->viewport_width != framebuffer->width ||
|
||||
framebuffer->viewport_height != framebuffer->height))
|
||||
{
|
||||
saved_viewport_scissor_workaround = TRUE;
|
||||
ctx->needs_viewport_scissor_workaround = FALSE;
|
||||
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
}
|
||||
else
|
||||
saved_viewport_scissor_workaround = FALSE;
|
||||
|
||||
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
|
||||
* as the pipeline state) when flushing the clip stack, so should
|
||||
* always be done first when preparing to draw. */
|
||||
@@ -395,16 +363,6 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||
_cogl_framebuffer_clear_without_flush4f (framebuffer, buffers,
|
||||
red, green, blue, alpha);
|
||||
|
||||
/* XXX: ONGOING BUG: Intel viewport scissor
|
||||
*
|
||||
* See comment about temporarily disabling this workaround above
|
||||
*/
|
||||
if (saved_viewport_scissor_workaround)
|
||||
{
|
||||
ctx->needs_viewport_scissor_workaround = TRUE;
|
||||
ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
}
|
||||
|
||||
/* This is a debugging variable used to visually display the quad
|
||||
* batches from the journal. It is reset here to increase the
|
||||
* chances of getting the same colours for each frame during an
|
||||
@@ -552,12 +510,7 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer,
|
||||
framebuffer->viewport_age++;
|
||||
|
||||
if (context->current_draw_buffer == framebuffer)
|
||||
{
|
||||
context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT;
|
||||
|
||||
if (context->needs_viewport_scissor_workaround)
|
||||
context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
}
|
||||
context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT;
|
||||
}
|
||||
|
||||
float
|
||||
@@ -831,27 +784,7 @@ _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a,
|
||||
/* NB: we render upside down to offscreen framebuffers and that
|
||||
* can affect how we setup the GL viewport... */
|
||||
a->type != b->type)
|
||||
{
|
||||
unsigned long differences = COGL_FRAMEBUFFER_STATE_VIEWPORT;
|
||||
CoglContext *context = a->context;
|
||||
|
||||
/* XXX: ONGOING BUG: Intel viewport scissor
|
||||
*
|
||||
* Intel gen6 drivers don't currently correctly handle offset
|
||||
* viewports, since primitives aren't clipped within the bounds of
|
||||
* the viewport. To workaround this we push our own clip for the
|
||||
* viewport that will use scissoring to ensure we clip as expected.
|
||||
*
|
||||
* This workaround implies that a change in viewport state is
|
||||
* effectively also a change in the clipping state.
|
||||
*
|
||||
* TODO: file a bug upstream!
|
||||
*/
|
||||
if (G_UNLIKELY (context->needs_viewport_scissor_workaround))
|
||||
differences |= COGL_FRAMEBUFFER_STATE_CLIP;
|
||||
|
||||
return differences;
|
||||
}
|
||||
return COGL_FRAMEBUFFER_STATE_VIEWPORT;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -894,17 +827,6 @@ _cogl_framebuffer_compare_projection_state (CoglFramebuffer *a,
|
||||
return COGL_FRAMEBUFFER_STATE_PROJECTION;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
_cogl_framebuffer_compare_color_mask_state (CoglFramebuffer *a,
|
||||
CoglFramebuffer *b)
|
||||
{
|
||||
if (cogl_framebuffer_get_color_mask (a) !=
|
||||
cogl_framebuffer_get_color_mask (b))
|
||||
return COGL_FRAMEBUFFER_STATE_COLOR_MASK;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
_cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
|
||||
CoglFramebuffer *b)
|
||||
@@ -971,10 +893,6 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
|
||||
differences |=
|
||||
_cogl_framebuffer_compare_projection_state (a, b);
|
||||
break;
|
||||
case COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK:
|
||||
differences |=
|
||||
_cogl_framebuffer_compare_color_mask_state (a, b);
|
||||
break;
|
||||
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
|
||||
differences |=
|
||||
_cogl_framebuffer_compare_front_face_winding_state (a, b);
|
||||
@@ -1080,29 +998,6 @@ cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer)
|
||||
return framebuffer->config.stereo_enabled;
|
||||
}
|
||||
|
||||
CoglColorMask
|
||||
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
return framebuffer->color_mask;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
|
||||
CoglColorMask color_mask)
|
||||
{
|
||||
if (framebuffer->color_mask == color_mask)
|
||||
return;
|
||||
|
||||
/* XXX: Currently color mask changes don't go through the journal */
|
||||
_cogl_framebuffer_flush_journal (framebuffer);
|
||||
|
||||
framebuffer->color_mask = color_mask;
|
||||
|
||||
if (framebuffer->context->current_draw_buffer == framebuffer)
|
||||
framebuffer->context->current_draw_buffer_changes |=
|
||||
COGL_FRAMEBUFFER_STATE_COLOR_MASK;
|
||||
}
|
||||
|
||||
CoglStereoMode
|
||||
cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer)
|
||||
{
|
||||
@@ -2097,15 +1992,6 @@ get_wire_line_indices (CoglContext *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remove_layer_cb (CoglPipeline *pipeline,
|
||||
int layer_index,
|
||||
void *user_data)
|
||||
{
|
||||
cogl_pipeline_remove_layer (pipeline, layer_index);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pipeline_destroyed_cb (CoglPipeline *weak_pipeline, void *user_data)
|
||||
{
|
||||
@@ -2157,6 +2043,8 @@ draw_wireframe (CoglContext *ctx,
|
||||
|
||||
if (!wire_pipeline)
|
||||
{
|
||||
static CoglSnippet *snippet = NULL;
|
||||
|
||||
wire_pipeline =
|
||||
_cogl_pipeline_weak_copy (pipeline, pipeline_destroyed_cb, NULL);
|
||||
|
||||
@@ -2168,29 +2056,20 @@ draw_wireframe (CoglContext *ctx,
|
||||
* vertex program and since we'd like to see the results of the
|
||||
* vertex program in the wireframe we just add a final clobber
|
||||
* of the wire color leaving the rest of the state untouched. */
|
||||
if (cogl_has_feature (framebuffer->context, COGL_FEATURE_ID_GLSL))
|
||||
{
|
||||
static CoglSnippet *snippet = NULL;
|
||||
|
||||
/* The snippet is cached so that it will reuse the program
|
||||
* from the pipeline cache if possible */
|
||||
if (snippet == NULL)
|
||||
{
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
NULL,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet,
|
||||
"cogl_color_out = "
|
||||
"vec4 (0.0, 1.0, 0.0, 1.0);\n");
|
||||
}
|
||||
|
||||
cogl_pipeline_add_snippet (wire_pipeline, snippet);
|
||||
}
|
||||
else
|
||||
/* The snippet is cached so that it will reuse the program
|
||||
* from the pipeline cache if possible */
|
||||
if (snippet == NULL)
|
||||
{
|
||||
cogl_pipeline_foreach_layer (wire_pipeline, remove_layer_cb, NULL);
|
||||
cogl_pipeline_set_color4f (wire_pipeline, 0, 1, 0, 1);
|
||||
snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
|
||||
NULL,
|
||||
NULL);
|
||||
cogl_snippet_set_replace (snippet,
|
||||
"cogl_color_out = "
|
||||
"vec4 (0.0, 1.0, 0.0, 1.0);\n");
|
||||
}
|
||||
|
||||
cogl_pipeline_add_snippet (wire_pipeline, snippet);
|
||||
}
|
||||
|
||||
/* temporarily disable the wireframe to avoid recursion! */
|
||||
|
@@ -816,38 +816,6 @@ void
|
||||
cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer,
|
||||
gboolean depth_write_enabled);
|
||||
|
||||
/**
|
||||
* cogl_framebuffer_get_color_mask:
|
||||
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||
*
|
||||
* Gets the current #CoglColorMask of which channels would be written to the
|
||||
* current framebuffer. Each bit set in the mask means that the
|
||||
* corresponding color would be written.
|
||||
*
|
||||
* Returns: A #CoglColorMask
|
||||
* Since: 1.8
|
||||
* Stability: unstable
|
||||
*/
|
||||
CoglColorMask
|
||||
cogl_framebuffer_get_color_mask (CoglFramebuffer *framebuffer);
|
||||
|
||||
/**
|
||||
* cogl_framebuffer_set_color_mask:
|
||||
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||
* @color_mask: A #CoglColorMask of which color channels to write to
|
||||
* the current framebuffer.
|
||||
*
|
||||
* Defines a bit mask of which color channels should be written to the
|
||||
* given @framebuffer. If a bit is set in @color_mask that means that
|
||||
* color will be written.
|
||||
*
|
||||
* Since: 1.8
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
|
||||
CoglColorMask color_mask);
|
||||
|
||||
/**
|
||||
* cogl_framebuffer_get_stereo_mode:
|
||||
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||
@@ -1161,8 +1129,8 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
|
||||
* This drawing api doesn't support high-level meta texture types such
|
||||
* as #CoglTexture2DSliced so it is the user's responsibility to
|
||||
* ensure that only low-level textures that can be directly sampled by
|
||||
* a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D
|
||||
* are associated with layers of the given @pipeline.
|
||||
* a GPU such as #CoglTexture2D are associated with layers of the given
|
||||
* @pipeline.
|
||||
*
|
||||
* <note>This api doesn't support any of the legacy global state options such
|
||||
* as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
|
||||
@@ -1203,8 +1171,8 @@ cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
|
||||
* This drawing api doesn't support high-level meta texture types such
|
||||
* as #CoglTexture2DSliced so it is the user's responsibility to
|
||||
* ensure that only low-level textures that can be directly sampled by
|
||||
* a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D
|
||||
* are associated with layers of the given @pipeline.
|
||||
* a GPU such as #CoglTexture2D are associated with layers of the given
|
||||
* @pipeline.
|
||||
*
|
||||
* Stability: unstable
|
||||
* Since: 1.10
|
||||
@@ -1246,8 +1214,8 @@ cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer,
|
||||
* This drawing api doesn't support high-level meta texture types such
|
||||
* as #CoglTexture2DSliced so it is the user's responsibility to
|
||||
* ensure that only low-level textures that can be directly sampled by
|
||||
* a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D
|
||||
* are associated with layers of the given @pipeline.
|
||||
* a GPU such as #CoglTexture2D are associated with layers of the given
|
||||
* @pipeline.
|
||||
*
|
||||
* <note>This api doesn't support any of the legacy global state options such
|
||||
* as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
|
||||
@@ -1312,8 +1280,8 @@ cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
|
||||
* This drawing api doesn't support high-level meta texture types such
|
||||
* as #CoglTexture2DSliced so it is the user's responsibility to
|
||||
* ensure that only low-level textures that can be directly sampled by
|
||||
* a GPU such as #CoglTexture2D, #CoglTextureRectangle or
|
||||
* #CoglTexture3D are associated with layers of the given @pipeline.
|
||||
* a GPU such as #CoglTexture2D are associated with layers of the given
|
||||
* @pipeline.
|
||||
*
|
||||
* <note>This api doesn't support any of the legacy global state
|
||||
* options such as cogl_set_depth_test_enabled(),
|
||||
@@ -1380,8 +1348,8 @@ cogl_framebuffer_vdraw_indexed_attributes (CoglFramebuffer *framebuffer,
|
||||
* This drawing api doesn't support high-level meta texture types such
|
||||
* as #CoglTexture2DSliced so it is the user's responsibility to
|
||||
* ensure that only low-level textures that can be directly sampled by
|
||||
* a GPU such as #CoglTexture2D, #CoglTextureRectangle or
|
||||
* #CoglTexture3D are associated with layers of the given @pipeline.
|
||||
* a GPU such as #CoglTexture2D are associated with layers of the given
|
||||
* @pipeline.
|
||||
*
|
||||
* <note>This api doesn't support any of the legacy global state
|
||||
* options such as cogl_set_depth_test_enabled(),
|
||||
@@ -1475,11 +1443,6 @@ cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer,
|
||||
* bottom right. To map an entire texture across the rectangle pass
|
||||
* in @s_1=0, @t_1=0, @s_2=1, @t_2=1.
|
||||
*
|
||||
* <note>Even if you have associated a #CoglTextureRectangle texture
|
||||
* with one of your @pipeline layers which normally implies working
|
||||
* with non-normalized texture coordinates this api should still be
|
||||
* passed normalized texture coordinates.</note>
|
||||
*
|
||||
* Since: 1.10
|
||||
* Stability: unstable
|
||||
*/
|
||||
@@ -1532,9 +1495,7 @@ cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer,
|
||||
* <note>This api can not currently handle multiple high-level meta
|
||||
* texture layers. The first layer may be a high level meta texture
|
||||
* such as #CoglTexture2DSliced but all other layers much be low
|
||||
* level textures such as #CoglTexture2D and additionally they
|
||||
* should be textures that can be sampled using normalized coordinates
|
||||
* (so not #CoglTextureRectangle textures).</note>
|
||||
* level textures such as #CoglTexture2D.
|
||||
*
|
||||
* The top left texture coordinate for layer 0 of any pipeline will be
|
||||
* (tex_coords[0], tex_coords[1]) and the bottom right coordinate will
|
||||
@@ -1548,11 +1509,6 @@ cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer,
|
||||
* in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1,
|
||||
* tex_coords[3]=1.
|
||||
*
|
||||
* <note>Even if you have associated a #CoglTextureRectangle texture
|
||||
* which normally implies working with non-normalized texture
|
||||
* coordinates this api should still be passed normalized texture
|
||||
* coordinates.</note>
|
||||
*
|
||||
* The first pair of coordinates are for the first layer (with the
|
||||
* smallest layer index) and if you supply less texture coordinates
|
||||
* than there are layers in the current source material then default
|
||||
@@ -1656,11 +1612,6 @@ cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer,
|
||||
* in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1,
|
||||
* tex_coords[3]=1.
|
||||
*
|
||||
* <note>Even if you have associated a #CoglTextureRectangle texture
|
||||
* which normally implies working with non-normalized texture
|
||||
* coordinates this api should still be passed normalized texture
|
||||
* coordinates.</note>
|
||||
*
|
||||
* Since: 1.10
|
||||
* Stability: unstable
|
||||
*/
|
||||
|
@@ -366,9 +366,8 @@ cogl_gles2_texture_2d_new_from_handle (CoglContext *ctx,
|
||||
* GLES2 context.</note>
|
||||
*
|
||||
* <note>This function will only return %TRUE for low-level
|
||||
* #CoglTexture<!-- -->s such as #CoglTexture2D or #CoglTexture3D but
|
||||
* not for high level meta textures such as
|
||||
* #CoglTexture2DSliced</note>
|
||||
* #CoglTexture<!-- -->s such as #CoglTexture2D but not for high level
|
||||
* meta textures such as #CoglTexture2DSliced</note>
|
||||
*
|
||||
* <note>The handle returned should not be passed directly to a system
|
||||
* OpenGL ES 2.0 library, the handle is only intended to be used via
|
||||
|
@@ -100,21 +100,12 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||
strings[count] = version_string;
|
||||
lengths[count++] = -1;
|
||||
|
||||
if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_GL_EMBEDDED) &&
|
||||
cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D))
|
||||
{
|
||||
static const char texture_3d_extension[] =
|
||||
"#extension GL_OES_texture_3D : enable\n";
|
||||
strings[count] = texture_3d_extension;
|
||||
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
||||
}
|
||||
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
||||
{
|
||||
static const char texture_3d_extension[] =
|
||||
static const char image_external_extension[] =
|
||||
"#extension GL_OES_EGL_image_external : require\n";
|
||||
strings[count] = texture_3d_extension;
|
||||
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
||||
strings[count] = image_external_extension;
|
||||
lengths[count++] = sizeof (image_external_extension) - 1;
|
||||
}
|
||||
|
||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include "cogl-matrix.h"
|
||||
#include "cogl-spans.h"
|
||||
#include "cogl-meta-texture.h"
|
||||
#include "cogl-texture-rectangle-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -316,16 +316,9 @@ foreach_clamped_region (CoglMetaTexture *meta_texture,
|
||||
|
||||
if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE)
|
||||
{
|
||||
float max_s_coord;
|
||||
float max_s_coord = 1.0;
|
||||
float half_texel_width;
|
||||
|
||||
/* Consider that rectangle textures have non-normalized
|
||||
* coordinates... */
|
||||
if (cogl_is_texture_rectangle (meta_texture))
|
||||
max_s_coord = width;
|
||||
else
|
||||
max_s_coord = 1.0;
|
||||
|
||||
half_texel_width = max_s_coord / (width * 2);
|
||||
|
||||
/* Handle any left clamped region */
|
||||
@@ -375,16 +368,9 @@ foreach_clamped_region (CoglMetaTexture *meta_texture,
|
||||
if (wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE)
|
||||
{
|
||||
float height = cogl_texture_get_height (COGL_TEXTURE (meta_texture));
|
||||
float max_t_coord;
|
||||
float max_t_coord = 1.0;
|
||||
float half_texel_height;
|
||||
|
||||
/* Consider that rectangle textures have non-normalized
|
||||
* coordinates... */
|
||||
if (cogl_is_texture_rectangle (meta_texture))
|
||||
max_t_coord = height;
|
||||
else
|
||||
max_t_coord = 1.0;
|
||||
|
||||
half_texel_height = max_t_coord / (height * 2);
|
||||
|
||||
/* Handle any top clamped region */
|
||||
@@ -466,33 +452,6 @@ normalize_meta_coords_cb (CoglTexture *slice_texture,
|
||||
data->user_data);
|
||||
}
|
||||
|
||||
typedef struct _UnNormalizeData
|
||||
{
|
||||
CoglMetaTextureCallback callback;
|
||||
void *user_data;
|
||||
float width;
|
||||
float height;
|
||||
} UnNormalizeData;
|
||||
|
||||
static void
|
||||
un_normalize_slice_coords_cb (CoglTexture *slice_texture,
|
||||
const float *slice_coords,
|
||||
const float *meta_coords,
|
||||
void *user_data)
|
||||
{
|
||||
UnNormalizeData *data = user_data;
|
||||
float un_normalized_slice_coords[4] = {
|
||||
slice_coords[0] * data->width,
|
||||
slice_coords[1] * data->height,
|
||||
slice_coords[2] * data->width,
|
||||
slice_coords[3] * data->height
|
||||
};
|
||||
|
||||
data->callback (slice_texture,
|
||||
un_normalized_slice_coords, meta_coords,
|
||||
data->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture,
|
||||
float tx_1,
|
||||
@@ -539,19 +498,16 @@ cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture,
|
||||
* coordinates beyond this point and only re-normalize just before
|
||||
* calling the user's callback... */
|
||||
|
||||
if (!cogl_is_texture_rectangle (COGL_TEXTURE (meta_texture)))
|
||||
{
|
||||
normalize_data.callback = callback;
|
||||
normalize_data.user_data = user_data;
|
||||
normalize_data.s_normalize_factor = 1.0f / width;
|
||||
normalize_data.t_normalize_factor = 1.0f / height;
|
||||
callback = normalize_meta_coords_cb;
|
||||
user_data = &normalize_data;
|
||||
tx_1 *= width;
|
||||
ty_1 *= height;
|
||||
tx_2 *= width;
|
||||
ty_2 *= height;
|
||||
}
|
||||
normalize_data.callback = callback;
|
||||
normalize_data.user_data = user_data;
|
||||
normalize_data.s_normalize_factor = 1.0f / width;
|
||||
normalize_data.t_normalize_factor = 1.0f / height;
|
||||
callback = normalize_meta_coords_cb;
|
||||
user_data = &normalize_data;
|
||||
tx_1 *= width;
|
||||
ty_1 *= height;
|
||||
tx_2 *= width;
|
||||
ty_2 *= height;
|
||||
|
||||
/* XXX: at some point this wont be routed through the CoglTexture
|
||||
* vtable, instead there will be a separate CoglMetaTexture
|
||||
@@ -609,21 +565,6 @@ cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture,
|
||||
CoglSpan x_span = { 0, width, 0 };
|
||||
CoglSpan y_span = { 0, height, 0 };
|
||||
float meta_region_coords[4] = { tx_1, ty_1, tx_2, ty_2 };
|
||||
UnNormalizeData un_normalize_data;
|
||||
|
||||
/* If we are dealing with a CoglTextureRectangle then we need a shim
|
||||
* callback that un_normalizes the slice coordinates we get from
|
||||
* _cogl_texture_spans_foreach_in_region before passing them to
|
||||
* the user's callback. */
|
||||
if (cogl_is_texture_rectangle (meta_texture))
|
||||
{
|
||||
un_normalize_data.callback = callback;
|
||||
un_normalize_data.user_data = user_data;
|
||||
un_normalize_data.width = width;
|
||||
un_normalize_data.height = height;
|
||||
callback = un_normalize_slice_coords_cb;
|
||||
user_data = &un_normalize_data;
|
||||
}
|
||||
|
||||
_cogl_texture_spans_foreach_in_region (&x_span, 1,
|
||||
&y_span, 1,
|
||||
|
@@ -42,8 +42,7 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* SECTION:cogl-meta-texture
|
||||
* @short_description: Interface for high-level textures built from
|
||||
* low-level textures like #CoglTexture2D and
|
||||
* #CoglTexture3D.
|
||||
* low-level textures like #CoglTexture2D.
|
||||
*
|
||||
* Cogl helps to make it easy to deal with high level textures such
|
||||
* as #CoglAtlasTexture<!-- -->s, #CoglSubTexture<!-- -->s,
|
||||
@@ -52,12 +51,11 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* A #CoglMetaTexture is a texture that might internally be
|
||||
* represented by one or more low-level #CoglTexture<!-- -->s
|
||||
* such as #CoglTexture2D or #CoglTexture3D. These low-level textures
|
||||
* are the only ones that a GPU really understands but because
|
||||
* applications often want more high-level texture abstractions
|
||||
* (such as storing multiple textures inside one larger "atlas"
|
||||
* texture) it's desirable to be able to deal with these
|
||||
* using a common interface.
|
||||
* such as #CoglTexture2D. These low-level textures are the only ones
|
||||
* that a GPU really understands but because applications often want
|
||||
* more high-level texture abstractions (such as storing multiple
|
||||
* textures inside one larger "atlas" texture) it's desirable to be
|
||||
* able to deal with these using a common interface.
|
||||
*
|
||||
* For example the GPU is not able to automatically handle repeating a
|
||||
* texture that is part of a larger atlas texture but if you use
|
||||
|
@@ -31,7 +31,7 @@
|
||||
#ifndef __COGL_MUTTER_H___
|
||||
#define __COGL_MUTTER_H___
|
||||
|
||||
#include "cogl-mutter-config.h"
|
||||
#include "cogl-config.h"
|
||||
#include "cogl-defines.h"
|
||||
|
||||
#include <cogl/cogl-texture.h>
|
||||
|
@@ -75,8 +75,8 @@ GType cogl_offscreen_get_gtype (void);
|
||||
* destroy the offscreen buffer before you can use the @texture again.
|
||||
*
|
||||
* <note>This api only works with low-level #CoglTexture types such as
|
||||
* #CoglTexture2D, #CoglTexture3D and #CoglTextureRectangle, and not
|
||||
* with meta-texture types such as #CoglTexture2DSliced.</note>
|
||||
* #CoglTexture2D and not with meta-texture types such as
|
||||
* #CoglTexture2DSliced.</note>
|
||||
*
|
||||
* The storage for the framebuffer is actually allocated lazily
|
||||
* so this function will never return %NULL to indicate a runtime
|
||||
@@ -110,8 +110,8 @@ cogl_offscreen_new_with_texture (CoglTexture *texture);
|
||||
* you can use the @texture again.
|
||||
*
|
||||
* <note>This only works with low-level #CoglTexture types such as
|
||||
* #CoglTexture2D, #CoglTexture3D and #CoglTextureRectangle, and not
|
||||
* with meta-texture types such as #CoglTexture2DSliced.</note>
|
||||
* #CoglTexture2D and not with meta-texture types such as
|
||||
* #CoglTexture2DSliced.</note>
|
||||
*
|
||||
* Return value: (transfer full): a newly instantiated #CoglOffscreen
|
||||
* framebuffer or %NULL if it wasn't possible to create the
|
||||
|
@@ -55,7 +55,6 @@ typedef enum
|
||||
{
|
||||
/* sparse state */
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX,
|
||||
@@ -82,8 +81,6 @@ typedef enum
|
||||
{
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA =
|
||||
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
|
||||
COGL_PIPELINE_LAYER_STATE_SAMPLER =
|
||||
@@ -237,11 +234,6 @@ struct _CoglPipelineLayer
|
||||
/* Each layer is directly associated with a single texture unit */
|
||||
int unit_index;
|
||||
|
||||
/* The type of the texture. This is always set even if the texture
|
||||
is NULL and it will be used to determine what type of texture
|
||||
lookups to use in any shaders generated by the pipeline
|
||||
backends. */
|
||||
CoglTextureType texture_type;
|
||||
/* The texture for this layer, or NULL for an empty
|
||||
* layer */
|
||||
CoglTexture *texture;
|
||||
@@ -347,9 +339,6 @@ _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
|
||||
CoglTexture *
|
||||
_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer);
|
||||
|
||||
CoglTextureType
|
||||
_cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer);
|
||||
|
||||
CoglPipelineFilter
|
||||
_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer);
|
||||
|
||||
|
@@ -50,11 +50,6 @@ CoglPipelineFilter
|
||||
_cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline,
|
||||
int layer_index);
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0,
|
||||
CoglPipelineLayer *authority1,
|
||||
CoglPipelineEvalFlags flags);
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0,
|
||||
CoglPipelineLayer *authority1,
|
||||
@@ -93,11 +88,6 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority,
|
||||
CoglPipelineLayer **authorities,
|
||||
CoglPipelineHashState *state);
|
||||
|
||||
void
|
||||
_cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority,
|
||||
CoglPipelineLayer **authorities,
|
||||
CoglPipelineHashState *state);
|
||||
|
||||
void
|
||||
_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority,
|
||||
CoglPipelineLayer **authorities,
|
||||
|
@@ -136,87 +136,6 @@ cogl_pipeline_get_layer_texture (CoglPipeline *pipeline,
|
||||
return _cogl_pipeline_layer_get_texture (layer);
|
||||
}
|
||||
|
||||
CoglTextureType
|
||||
_cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer)
|
||||
{
|
||||
CoglPipelineLayer *authority =
|
||||
_cogl_pipeline_layer_get_authority (layer,
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE);
|
||||
|
||||
return authority->texture_type;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_pipeline_set_layer_texture_type (CoglPipeline *pipeline,
|
||||
int layer_index,
|
||||
CoglTextureType texture_type)
|
||||
{
|
||||
CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE;
|
||||
CoglPipelineLayer *layer;
|
||||
CoglPipelineLayer *authority;
|
||||
CoglPipelineLayer *new;
|
||||
|
||||
/* Note: this will ensure that the layer exists, creating one if it
|
||||
* doesn't already.
|
||||
*
|
||||
* Note: If the layer already existed it's possibly owned by another
|
||||
* pipeline. If the layer is created then it will be owned by
|
||||
* pipeline. */
|
||||
layer = _cogl_pipeline_get_layer (pipeline, layer_index);
|
||||
|
||||
/* Now find the ancestor of the layer that is the authority for the
|
||||
* state we want to change */
|
||||
authority = _cogl_pipeline_layer_get_authority (layer, change);
|
||||
|
||||
if (texture_type == authority->texture_type)
|
||||
return;
|
||||
|
||||
new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change);
|
||||
if (new != layer)
|
||||
layer = new;
|
||||
else
|
||||
{
|
||||
/* If the original layer we found is currently the authority on
|
||||
* the state we are changing see if we can revert to one of our
|
||||
* ancestors being the authority. */
|
||||
if (layer == authority &&
|
||||
_cogl_pipeline_layer_get_parent (authority) != NULL)
|
||||
{
|
||||
CoglPipelineLayer *parent =
|
||||
_cogl_pipeline_layer_get_parent (authority);
|
||||
CoglPipelineLayer *old_authority =
|
||||
_cogl_pipeline_layer_get_authority (parent, change);
|
||||
|
||||
if (old_authority->texture_type == texture_type)
|
||||
{
|
||||
layer->differences &= ~change;
|
||||
|
||||
g_assert (layer->owner == pipeline);
|
||||
if (layer->differences == 0)
|
||||
_cogl_pipeline_prune_empty_layer_difference (pipeline,
|
||||
layer);
|
||||
goto changed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer->texture_type = texture_type;
|
||||
|
||||
/* If we weren't previously the authority on this state then we need
|
||||
* to extended our differences mask and so it's possible that some
|
||||
* of our ancestry will now become redundant, so we aim to reparent
|
||||
* ourselves if that's true... */
|
||||
if (layer != authority)
|
||||
{
|
||||
layer->differences |= change;
|
||||
_cogl_pipeline_layer_prune_redundant_ancestry (layer);
|
||||
}
|
||||
|
||||
changed:
|
||||
|
||||
pipeline->dirty_real_blend_enable = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_pipeline_set_layer_texture_data (CoglPipeline *pipeline,
|
||||
int layer_index,
|
||||
@@ -301,69 +220,13 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
|
||||
int layer_index,
|
||||
CoglTexture *texture)
|
||||
{
|
||||
/* For the convenience of fragend code we separate texture state
|
||||
* into the "type" and the "data", and setting a layer texture
|
||||
* updates both of these properties.
|
||||
*
|
||||
* One example for why this is helpful is that the fragends may
|
||||
* cache programs they generate and want to re-use those programs
|
||||
* with all pipelines having equivalent fragment processing state.
|
||||
* For the sake of determining if pipelines have equivalent fragment
|
||||
* processing state we don't need to compare that the same
|
||||
* underlying texture objects are referenced by the pipelines but we
|
||||
* do need to see if they use the same texture types. Making this
|
||||
* distinction is much simpler if they are in different state
|
||||
* groups.
|
||||
*
|
||||
* Note: if a NULL texture is set then we leave the type unchanged
|
||||
* so we can avoid needlessly invalidating any associated fragment
|
||||
* program.
|
||||
*/
|
||||
if (texture)
|
||||
{
|
||||
CoglTextureType texture_type =
|
||||
_cogl_texture_get_type (texture);
|
||||
_cogl_pipeline_set_layer_texture_type (pipeline,
|
||||
layer_index,
|
||||
texture_type);
|
||||
}
|
||||
_cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline,
|
||||
int layer_index,
|
||||
CoglTextureType texture_type)
|
||||
int layer_index)
|
||||
{
|
||||
CoglContext *ctx = _cogl_context_get_default ();
|
||||
|
||||
/* Disallow setting texture types that aren't supported */
|
||||
switch (texture_type)
|
||||
{
|
||||
case COGL_TEXTURE_TYPE_2D:
|
||||
break;
|
||||
|
||||
case COGL_TEXTURE_TYPE_3D:
|
||||
if (ctx->default_gl_texture_3d_tex == NULL)
|
||||
{
|
||||
g_warning ("The default 3D texture was set on a pipeline but "
|
||||
"3D textures are not supported");
|
||||
texture_type = COGL_TEXTURE_TYPE_2D;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case COGL_TEXTURE_TYPE_RECTANGLE:
|
||||
if (ctx->default_gl_texture_rect_tex == NULL)
|
||||
{
|
||||
g_warning ("The default rectangle texture was set on a pipeline but "
|
||||
"rectangle textures are not supported");
|
||||
texture_type = COGL_TEXTURE_TYPE_2D;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_cogl_pipeline_set_layer_texture_type (pipeline, layer_index, texture_type);
|
||||
_cogl_pipeline_set_layer_texture_data (pipeline, layer_index, NULL);
|
||||
}
|
||||
|
||||
@@ -950,14 +813,6 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
|
||||
snippet);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0,
|
||||
CoglPipelineLayer *authority1,
|
||||
CoglPipelineEvalFlags flags)
|
||||
{
|
||||
return authority0->texture_type == authority1->texture_type;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0,
|
||||
CoglPipelineLayer *authority1,
|
||||
@@ -966,8 +821,7 @@ _cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0,
|
||||
if (authority0->texture == NULL)
|
||||
{
|
||||
if (authority1->texture == NULL)
|
||||
return (_cogl_pipeline_layer_get_texture_type (authority0) ==
|
||||
_cogl_pipeline_layer_get_texture_type (authority1));
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1647,18 +1501,6 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority,
|
||||
_cogl_util_one_at_a_time_hash (state->hash, &unit, sizeof (unit));
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority,
|
||||
CoglPipelineLayer **authorities,
|
||||
CoglPipelineHashState *state)
|
||||
{
|
||||
CoglTextureType texture_type = authority->texture_type;
|
||||
|
||||
state->hash = _cogl_util_one_at_a_time_hash (state->hash,
|
||||
&texture_type,
|
||||
sizeof (texture_type));
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority,
|
||||
CoglPipelineLayer **authorities,
|
||||
|
@@ -159,13 +159,9 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
|
||||
* cogl_pipeline_set_layer_null_texture:
|
||||
* @pipeline: A #CoglPipeline
|
||||
* @layer_index: The layer number to modify
|
||||
* @texture_type: The type of the default texture to use
|
||||
*
|
||||
* Sets the texture for this layer to be the default texture for the
|
||||
* given type. This is equivalent to calling
|
||||
* cogl_pipeline_set_layer_texture() with %NULL for the texture
|
||||
* argument except that you can also specify the type of default
|
||||
* texture to use. The default texture is a 1x1 pixel white texture.
|
||||
* given type. The default texture is a 1x1 pixel white texture.
|
||||
*
|
||||
* This function is mostly useful if you want to create a base
|
||||
* pipeline that you want to create multiple copies from using
|
||||
@@ -178,8 +174,7 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
|
||||
*/
|
||||
void
|
||||
cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline,
|
||||
int layer_index,
|
||||
CoglTextureType texture_type);
|
||||
int layer_index);
|
||||
|
||||
/**
|
||||
* cogl_pipeline_get_layer_texture:
|
||||
|
@@ -187,10 +187,6 @@ _cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest,
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
|
||||
case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX:
|
||||
dest->texture_type = src->texture_type;
|
||||
break;
|
||||
|
||||
case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX:
|
||||
dest->texture = src->texture;
|
||||
if (dest->texture)
|
||||
@@ -272,7 +268,6 @@ _cogl_pipeline_layer_init_multi_property_sparse_state (
|
||||
/* XXX: avoid using a default: label so we get a warning if we
|
||||
* don't explicitly handle a newly defined state-group here. */
|
||||
case COGL_PIPELINE_LAYER_STATE_UNIT:
|
||||
case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE:
|
||||
case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA:
|
||||
case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS:
|
||||
case COGL_PIPELINE_LAYER_STATE_USER_MATRIX:
|
||||
@@ -662,16 +657,6 @@ _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
|
||||
layers_difference,
|
||||
authorities1);
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE)
|
||||
{
|
||||
CoglPipelineLayerStateIndex state_index =
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX;
|
||||
if (!_cogl_pipeline_layer_texture_type_equal (authorities0[state_index],
|
||||
authorities1[state_index],
|
||||
flags))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA)
|
||||
{
|
||||
CoglPipelineLayerStateIndex state_index =
|
||||
@@ -767,7 +752,6 @@ _cogl_pipeline_init_default_layers (void)
|
||||
layer->unit_index = 0;
|
||||
|
||||
layer->texture = NULL;
|
||||
layer->texture_type = COGL_TEXTURE_TYPE_2D;
|
||||
|
||||
layer->sampler_cache_entry =
|
||||
_cogl_sampler_cache_get_default_entry (ctx->sampler_cache);
|
||||
|
@@ -87,7 +87,6 @@ typedef enum
|
||||
COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
||||
COGL_PIPELINE_STATE_CULL_FACE_INDEX,
|
||||
COGL_PIPELINE_STATE_UNIFORMS_INDEX,
|
||||
COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX,
|
||||
@@ -140,8 +139,6 @@ typedef enum _CoglPipelineState
|
||||
1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE =
|
||||
1L<<COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX,
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS =
|
||||
1L<<COGL_PIPELINE_STATE_LOGIC_OPS_INDEX,
|
||||
COGL_PIPELINE_STATE_CULL_FACE =
|
||||
1L<<COGL_PIPELINE_STATE_CULL_FACE_INDEX,
|
||||
COGL_PIPELINE_STATE_UNIFORMS =
|
||||
@@ -188,7 +185,6 @@ typedef enum _CoglPipelineState
|
||||
COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE | \
|
||||
COGL_PIPELINE_STATE_POINT_SIZE | \
|
||||
COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE | \
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS | \
|
||||
COGL_PIPELINE_STATE_CULL_FACE | \
|
||||
COGL_PIPELINE_STATE_UNIFORMS | \
|
||||
COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \
|
||||
@@ -200,7 +196,6 @@ typedef enum _CoglPipelineState
|
||||
COGL_PIPELINE_STATE_BLEND | \
|
||||
COGL_PIPELINE_STATE_DEPTH | \
|
||||
COGL_PIPELINE_STATE_FOG | \
|
||||
COGL_PIPELINE_STATE_LOGIC_OPS | \
|
||||
COGL_PIPELINE_STATE_CULL_FACE | \
|
||||
COGL_PIPELINE_STATE_UNIFORMS | \
|
||||
COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \
|
||||
@@ -265,11 +260,6 @@ typedef struct
|
||||
float z_far;
|
||||
} CoglPipelineFogState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglColorMask color_mask;
|
||||
} CoglPipelineLogicOpsState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CoglPipelineCullFaceMode mode;
|
||||
@@ -301,7 +291,6 @@ typedef struct
|
||||
float point_size;
|
||||
unsigned int non_zero_point_size : 1;
|
||||
unsigned int per_vertex_point_size : 1;
|
||||
CoglPipelineLogicOpsState logic_ops_state;
|
||||
CoglPipelineCullFaceState cull_face_state;
|
||||
CoglPipelineUniformsState uniforms_state;
|
||||
CoglPipelineSnippetList vertex_snippets;
|
||||
|
@@ -218,16 +218,6 @@ _cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0,
|
||||
authority1->big_state->per_vertex_point_size);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_logic_ops_state_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1)
|
||||
{
|
||||
CoglPipelineLogicOpsState *logic_ops_state0 = &authority0->big_state->logic_ops_state;
|
||||
CoglPipelineLogicOpsState *logic_ops_state1 = &authority1->big_state->logic_ops_state;
|
||||
|
||||
return logic_ops_state0->color_mask == logic_ops_state1->color_mask;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0,
|
||||
CoglPipeline *authority1)
|
||||
@@ -1203,49 +1193,6 @@ cogl_pipeline_get_depth_state (CoglPipeline *pipeline,
|
||||
*state = authority->big_state->depth_state;
|
||||
}
|
||||
|
||||
CoglColorMask
|
||||
cogl_pipeline_get_color_mask (CoglPipeline *pipeline)
|
||||
{
|
||||
CoglPipeline *authority;
|
||||
|
||||
_COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), 0);
|
||||
|
||||
authority =
|
||||
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LOGIC_OPS);
|
||||
|
||||
return authority->big_state->logic_ops_state.color_mask;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_pipeline_set_color_mask (CoglPipeline *pipeline,
|
||||
CoglColorMask color_mask)
|
||||
{
|
||||
CoglPipelineState state = COGL_PIPELINE_STATE_LOGIC_OPS;
|
||||
CoglPipeline *authority;
|
||||
CoglPipelineLogicOpsState *logic_ops_state;
|
||||
|
||||
_COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));
|
||||
|
||||
authority = _cogl_pipeline_get_authority (pipeline, state);
|
||||
|
||||
logic_ops_state = &authority->big_state->logic_ops_state;
|
||||
if (logic_ops_state->color_mask == color_mask)
|
||||
return;
|
||||
|
||||
/* - Flush journal primitives referencing the current state.
|
||||
* - Make sure the pipeline has no dependants so it may be modified.
|
||||
* - If the pipeline isn't currently an authority for the state being
|
||||
* changed, then initialize that state from the current authority.
|
||||
*/
|
||||
_cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE);
|
||||
|
||||
logic_ops_state = &pipeline->big_state->logic_ops_state;
|
||||
logic_ops_state->color_mask = color_mask;
|
||||
|
||||
_cogl_pipeline_update_authority (pipeline, authority, state,
|
||||
_cogl_pipeline_logic_ops_state_equal);
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_set_fog_state (CoglPipeline *pipeline,
|
||||
const CoglPipelineFogState *fog_state)
|
||||
@@ -1951,15 +1898,6 @@ _cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority,
|
||||
sizeof (per_vertex_point_size));
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority,
|
||||
CoglPipelineHashState *state)
|
||||
{
|
||||
CoglPipelineLogicOpsState *logic_ops_state = &authority->big_state->logic_ops_state;
|
||||
state->hash = _cogl_util_one_at_a_time_hash (state->hash, &logic_ops_state->color_mask,
|
||||
sizeof (CoglColorMask));
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority,
|
||||
CoglPipelineHashState *state)
|
||||
|
@@ -571,38 +571,6 @@ cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline,
|
||||
gboolean
|
||||
cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline);
|
||||
|
||||
/**
|
||||
* cogl_pipeline_get_color_mask:
|
||||
* @pipeline: a #CoglPipeline object.
|
||||
*
|
||||
* Gets the current #CoglColorMask of which channels would be written to the
|
||||
* current framebuffer. Each bit set in the mask means that the
|
||||
* corresponding color would be written.
|
||||
*
|
||||
* Returns: A #CoglColorMask
|
||||
* Since: 1.8
|
||||
* Stability: unstable
|
||||
*/
|
||||
CoglColorMask
|
||||
cogl_pipeline_get_color_mask (CoglPipeline *pipeline);
|
||||
|
||||
/**
|
||||
* cogl_pipeline_set_color_mask:
|
||||
* @pipeline: a #CoglPipeline object.
|
||||
* @color_mask: A #CoglColorMask of which color channels to write to
|
||||
* the current framebuffer.
|
||||
*
|
||||
* Defines a bit mask of which color channels should be written to the
|
||||
* current framebuffer. If a bit is set in @color_mask that means that
|
||||
* color will be written.
|
||||
*
|
||||
* Since: 1.8
|
||||
* Stability: unstable
|
||||
*/
|
||||
void
|
||||
cogl_pipeline_set_color_mask (CoglPipeline *pipeline,
|
||||
CoglColorMask color_mask);
|
||||
|
||||
/**
|
||||
* cogl_pipeline_get_user_program:
|
||||
* @pipeline: a #CoglPipeline object.
|
||||
@@ -658,10 +626,6 @@ cogl_pipeline_get_user_program (CoglPipeline *pipeline);
|
||||
* meantime we hope this will handle most practical GLSL and ARBfp
|
||||
* requirements.
|
||||
*
|
||||
* Also remember you need to check for either the
|
||||
* %COGL_FEATURE_SHADERS_GLSL or %COGL_FEATURE_SHADERS_ARBFP before
|
||||
* using the cogl_program or cogl_shader API.
|
||||
*
|
||||
* Since: 2.0
|
||||
* Stability: Unstable
|
||||
*/
|
||||
|
@@ -99,7 +99,6 @@ _cogl_pipeline_init_default_pipeline (void)
|
||||
CoglPipelineLightingState *lighting_state = &big_state->lighting_state;
|
||||
CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state;
|
||||
CoglPipelineBlendState *blend_state = &big_state->blend_state;
|
||||
CoglPipelineLogicOpsState *logic_ops_state = &big_state->logic_ops_state;
|
||||
CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state;
|
||||
CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state;
|
||||
|
||||
@@ -189,8 +188,6 @@ _cogl_pipeline_init_default_pipeline (void)
|
||||
|
||||
big_state->point_size = 0.0f;
|
||||
|
||||
logic_ops_state->color_mask = COGL_COLOR_MASK_ALL;
|
||||
|
||||
cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE;
|
||||
cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE;
|
||||
|
||||
@@ -455,15 +452,8 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
|
||||
_cogl_bitmask_destroy (&uniforms_state->changed_mask);
|
||||
}
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
||||
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
|
||||
{
|
||||
g_list_foreach (pipeline->layer_differences,
|
||||
(GFunc)cogl_object_unref, NULL);
|
||||
g_list_free (pipeline->layer_differences);
|
||||
}
|
||||
g_list_free_full (pipeline->layer_differences, cogl_object_unref);
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS)
|
||||
_cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets);
|
||||
@@ -471,6 +461,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
|
||||
_cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
|
||||
|
||||
if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
|
||||
g_slice_free (CoglPipelineBigState, pipeline->big_state);
|
||||
|
||||
g_list_free (pipeline->deprecated_get_layers_list);
|
||||
|
||||
recursively_free_layer_caches (pipeline);
|
||||
@@ -940,12 +933,7 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
|
||||
|
||||
if (dest->differences & COGL_PIPELINE_STATE_LAYERS &&
|
||||
dest->layer_differences)
|
||||
{
|
||||
g_list_foreach (dest->layer_differences,
|
||||
(GFunc)cogl_object_unref,
|
||||
NULL);
|
||||
g_list_free (dest->layer_differences);
|
||||
}
|
||||
g_list_free_full (dest->layer_differences, cogl_object_unref);
|
||||
|
||||
for (l = src->layer_differences; l; l = l->next)
|
||||
{
|
||||
@@ -1030,13 +1018,6 @@ _cogl_pipeline_copy_differences (CoglPipeline *dest,
|
||||
if (differences & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE)
|
||||
big_state->per_vertex_point_size = src->big_state->per_vertex_point_size;
|
||||
|
||||
if (differences & COGL_PIPELINE_STATE_LOGIC_OPS)
|
||||
{
|
||||
memcpy (&big_state->logic_ops_state,
|
||||
&src->big_state->logic_ops_state,
|
||||
sizeof (CoglPipelineLogicOpsState));
|
||||
}
|
||||
|
||||
if (differences & COGL_PIPELINE_STATE_CULL_FACE)
|
||||
{
|
||||
memcpy (&big_state->cull_face_state,
|
||||
@@ -1150,13 +1131,6 @@ _cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline,
|
||||
sizeof (CoglPipelineFogState));
|
||||
break;
|
||||
}
|
||||
case COGL_PIPELINE_STATE_LOGIC_OPS:
|
||||
{
|
||||
memcpy (&pipeline->big_state->logic_ops_state,
|
||||
&authority->big_state->logic_ops_state,
|
||||
sizeof (CoglPipelineLogicOpsState));
|
||||
break;
|
||||
}
|
||||
case COGL_PIPELINE_STATE_CULL_FACE:
|
||||
{
|
||||
memcpy (&pipeline->big_state->cull_face_state,
|
||||
@@ -1921,7 +1895,6 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
|
||||
{
|
||||
CoglPipelineFallbackState *state = user_data;
|
||||
CoglPipeline *pipeline = state->pipeline;
|
||||
CoglTextureType texture_type = _cogl_pipeline_layer_get_texture_type (layer);
|
||||
CoglTexture *texture = NULL;
|
||||
COGL_STATIC_COUNTER (layer_fallback_counter,
|
||||
"layer fallback counter",
|
||||
@@ -1936,20 +1909,7 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
|
||||
|
||||
COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter);
|
||||
|
||||
switch (texture_type)
|
||||
{
|
||||
case COGL_TEXTURE_TYPE_2D:
|
||||
texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex);
|
||||
break;
|
||||
|
||||
case COGL_TEXTURE_TYPE_3D:
|
||||
texture = COGL_TEXTURE (ctx->default_gl_texture_3d_tex);
|
||||
break;
|
||||
|
||||
case COGL_TEXTURE_TYPE_RECTANGLE:
|
||||
texture = COGL_TEXTURE (ctx->default_gl_texture_rect_tex);
|
||||
break;
|
||||
}
|
||||
texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex);
|
||||
|
||||
if (texture == NULL)
|
||||
{
|
||||
@@ -2323,11 +2283,6 @@ _cogl_pipeline_equal (CoglPipeline *pipeline0,
|
||||
authorities1[bit]))
|
||||
goto done;
|
||||
break;
|
||||
case COGL_PIPELINE_STATE_LOGIC_OPS_INDEX:
|
||||
if (!_cogl_pipeline_logic_ops_state_equal (authorities0[bit],
|
||||
authorities1[bit]))
|
||||
goto done;
|
||||
break;
|
||||
case COGL_PIPELINE_STATE_USER_SHADER_INDEX:
|
||||
if (!_cogl_pipeline_user_shader_equal (authorities0[bit],
|
||||
authorities1[bit]))
|
||||
@@ -2647,8 +2602,6 @@ _cogl_pipeline_init_layer_state_hash_functions (void)
|
||||
CoglPipelineLayerStateIndex _index;
|
||||
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] =
|
||||
_cogl_pipeline_layer_hash_unit_state;
|
||||
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX] =
|
||||
_cogl_pipeline_layer_hash_texture_type_state;
|
||||
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] =
|
||||
_cogl_pipeline_layer_hash_texture_data_state;
|
||||
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX] =
|
||||
@@ -2671,7 +2624,7 @@ _cogl_pipeline_init_layer_state_hash_functions (void)
|
||||
|
||||
{
|
||||
/* So we get a big error if we forget to update this code! */
|
||||
_COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 10,
|
||||
_COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 9,
|
||||
"Don't forget to install a hash function for new "
|
||||
"pipeline state and update assert at end of "
|
||||
"_cogl_pipeline_init_state_hash_functions");
|
||||
@@ -2776,8 +2729,6 @@ _cogl_pipeline_init_state_hash_functions (void)
|
||||
_cogl_pipeline_hash_point_size_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX] =
|
||||
_cogl_pipeline_hash_per_vertex_point_size_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_LOGIC_OPS_INDEX] =
|
||||
_cogl_pipeline_hash_logic_ops_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] =
|
||||
_cogl_pipeline_hash_uniforms_state;
|
||||
state_hash_functions[COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX] =
|
||||
@@ -2787,7 +2738,7 @@ _cogl_pipeline_init_state_hash_functions (void)
|
||||
|
||||
{
|
||||
/* So we get a big error if we forget to update this code! */
|
||||
_COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 18,
|
||||
_COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 17,
|
||||
"Make sure to install a hash function for "
|
||||
"newly added pipeline state and update assert "
|
||||
"in _cogl_pipeline_init_state_hash_functions");
|
||||
@@ -3078,15 +3029,13 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
|
||||
{
|
||||
CoglPipelineLayerState state =
|
||||
(COGL_PIPELINE_LAYER_STATE_COMBINE |
|
||||
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE |
|
||||
COGL_PIPELINE_LAYER_STATE_UNIT |
|
||||
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);
|
||||
|
||||
/* If the driver supports GLSL then we might be using gl_PointCoord
|
||||
/* Since the driver supports GLSL then we might be using gl_PointCoord
|
||||
* to implement the sprite coords. In that case the generated code
|
||||
* depends on the point sprite state */
|
||||
if (cogl_has_feature (context, COGL_FEATURE_ID_GLSL))
|
||||
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
|
||||
state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
310
cogl/cogl/cogl-pixel-format.c
Normal file
310
cogl/cogl/cogl-pixel-format.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cogl-config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cogl-pixel-format.h"
|
||||
|
||||
/* An entry to map CoglPixelFormats to their respective properties */
|
||||
typedef struct _CoglPixelFormatInfo
|
||||
{
|
||||
CoglPixelFormat cogl_format;
|
||||
const char *format_str;
|
||||
int bpp; /* Bytes per pixel */
|
||||
int aligned; /* Aligned components? (-1 if n/a) */
|
||||
} CoglPixelFormatInfo;
|
||||
|
||||
static const CoglPixelFormatInfo format_info_table[] = {
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ANY,
|
||||
.format_str = "ANY",
|
||||
.bpp = 0,
|
||||
.aligned = -1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_A_8,
|
||||
.format_str = "A_8",
|
||||
.bpp = 1,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
|
||||
.format_str = "RGB_565",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
|
||||
.format_str = "RGBA_4444",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
|
||||
.format_str = "RGBA_5551",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_YUV,
|
||||
.format_str = "YUV",
|
||||
.bpp = 0,
|
||||
.aligned = -1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_G_8,
|
||||
.format_str = "G_8",
|
||||
.bpp = 1,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
|
||||
.format_str = "RG_88",
|
||||
.bpp = 2,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
|
||||
.format_str = "RGB_888",
|
||||
.bpp = 3,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
|
||||
.format_str = "BGR_888",
|
||||
.bpp = 3,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
.format_str = "RGBA_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
|
||||
.format_str = "BGRA_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
|
||||
.format_str = "ARGB_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
|
||||
.format_str = "ABGR_8888",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
|
||||
.format_str = "RGBA_1010102",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
|
||||
.format_str = "BGRA_1010102",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
|
||||
.format_str = "ARGB_2101010",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
|
||||
.format_str = "ABGR_2101010",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
.format_str = "RGBA_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
|
||||
.format_str = "BGRA_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
|
||||
.format_str = "ARGB_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
|
||||
.format_str = "ABGR_8888_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
|
||||
.format_str = "RGBA_4444_PRE",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
|
||||
.format_str = "RGBA_5551_PRE",
|
||||
.bpp = 2,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
|
||||
.format_str = "RGBA_1010102_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
|
||||
.format_str = "BGRA_1010102_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
|
||||
.format_str = "ARGB_2101010_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
|
||||
.format_str = "ABGR_2101010_PRE",
|
||||
.bpp = 4,
|
||||
.aligned = 0
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
|
||||
.format_str = "DEPTH_16",
|
||||
.bpp = 2,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
|
||||
.format_str = "DEPTH_32",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
{
|
||||
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
|
||||
.format_str = "DEPTH_24_STENCIL_8",
|
||||
.bpp = 4,
|
||||
.aligned = 1
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns the number of bytes-per-pixel of a given format. The bpp
|
||||
* can be extracted from the least significant nibble of the pixel
|
||||
* format (see CoglPixelFormat).
|
||||
*
|
||||
* The mapping is the following (see discussion on bug #660188):
|
||||
*
|
||||
* 0 = undefined
|
||||
* 1, 8 = 1 bpp (e.g. A_8, G_8)
|
||||
* 2 = 3 bpp, aligned (e.g. 888)
|
||||
* 3 = 4 bpp, aligned (e.g. 8888)
|
||||
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
|
||||
* 7 = undefined yuv
|
||||
* 9 = 2 bpp, aligned
|
||||
* 10 = undefined
|
||||
* 11 = undefined
|
||||
* 12 = 3 bpp, not aligned
|
||||
* 13 = 4 bpp, not aligned (e.g. 2101010)
|
||||
* 14-15 = undefined
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||
{
|
||||
if (format_info_table[i].cogl_format == format)
|
||||
return format_info_table[i].bpp;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/* Note: this also refers to the mapping defined above for
|
||||
* _cogl_pixel_format_get_bytes_per_pixel() */
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
|
||||
{
|
||||
int aligned = -1;
|
||||
size_t i;
|
||||
|
||||
/* NB: currently checking whether the format components are aligned
|
||||
* or not determines whether the format is endian dependent or not.
|
||||
* In the future though we might consider adding formats with
|
||||
* aligned components that are also endian independant. */
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||
{
|
||||
if (format_info_table[i].cogl_format == format)
|
||||
{
|
||||
aligned = format_info_table[i].aligned;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_return_val_if_fail (aligned != -1, FALSE);
|
||||
|
||||
return aligned;
|
||||
}
|
||||
|
||||
const char *
|
||||
cogl_pixel_format_to_string (CoglPixelFormat format)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
|
||||
{
|
||||
if (format_info_table[i].cogl_format == format)
|
||||
return format_info_table[i].format_str;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
300
cogl/cogl/cogl-pixel-format.h
Normal file
300
cogl/cogl/cogl-pixel-format.h
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* Cogl
|
||||
*
|
||||
* A Low Level GPU Graphics and Utilities API
|
||||
*
|
||||
* Copyright (C) 2008,2009 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
|
||||
#error "Only <cogl/cogl.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __COGL_PIXEL_FORMAT_H__
|
||||
#define __COGL_PIXEL_FORMAT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cogl/cogl-defines.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* SECTION:cogl-pixel-format
|
||||
* @short_description: Pixel formats supported by Cogl
|
||||
*
|
||||
* The pixel format of an image descrbes how the bits of each pixel are
|
||||
* represented in memory. For example: an image can be laid out as one long
|
||||
* sequence of pixels, where each pixel is a sequence of 8 bits of Red, Green
|
||||
* and Blue. The amount of bits that are used can be different for each pixel
|
||||
* format, as well as the components (for example an Alpha layer to include
|
||||
* transparency, or non_RGBA).
|
||||
*
|
||||
* Other examples of factors that can influence the layout in memory are the
|
||||
* system's endianness.
|
||||
*/
|
||||
|
||||
#define COGL_A_BIT (1 << 4)
|
||||
#define COGL_BGR_BIT (1 << 5)
|
||||
#define COGL_AFIRST_BIT (1 << 6)
|
||||
#define COGL_PREMULT_BIT (1 << 7)
|
||||
#define COGL_DEPTH_BIT (1 << 8)
|
||||
#define COGL_STENCIL_BIT (1 << 9)
|
||||
|
||||
/* XXX: Notes to those adding new formats here...
|
||||
*
|
||||
* First this diagram outlines how we allocate the 32bits of a
|
||||
* CoglPixelFormat currently...
|
||||
*
|
||||
* 6 bits for flags
|
||||
* |-----|
|
||||
* enum unused 4 bits for the bytes-per-pixel
|
||||
* and component alignment info
|
||||
* |------| |-------------| |--|
|
||||
* 00000000 xxxxxxxx xxxxxxSD PFBA0000
|
||||
* ^ stencil
|
||||
* ^ depth
|
||||
* ^ premult
|
||||
* ^ alpha first
|
||||
* ^ bgr order
|
||||
* ^ has alpha
|
||||
*
|
||||
* The most awkward part about the formats is how we use the last 4
|
||||
* bits to encode the bytes per pixel and component alignment
|
||||
* information. Ideally we should have had 3 bits for the bpp and a
|
||||
* flag for alignment but we didn't plan for that in advance so we
|
||||
* instead use a small lookup table to query the bpp and whether the
|
||||
* components are byte aligned or not.
|
||||
*
|
||||
* The mapping is the following (see discussion on bug #660188):
|
||||
*
|
||||
* 0 = undefined
|
||||
* 1, 8 = 1 bpp (e.g. A_8, G_8)
|
||||
* 2 = 3 bpp, aligned (e.g. 888)
|
||||
* 3 = 4 bpp, aligned (e.g. 8888)
|
||||
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
|
||||
* 7 = YUV: undefined bpp, undefined alignment
|
||||
* 9 = 2 bpp, aligned
|
||||
* 10 = depth, aligned (8, 16, 24, 32, 32f)
|
||||
* 11 = undefined
|
||||
* 12 = 3 bpp, not aligned
|
||||
* 13 = 4 bpp, not aligned (e.g. 2101010)
|
||||
* 14-15 = undefined
|
||||
*
|
||||
* Note: the gap at 10-11 is just because we wanted to maintain that
|
||||
* all non-aligned formats have the third bit set in case that's
|
||||
* useful later.
|
||||
*
|
||||
* Since we don't want to waste bits adding more and more flags, we'd
|
||||
* like to see most new pixel formats that can't be represented
|
||||
* uniquely with the existing flags in the least significant byte
|
||||
* simply be enumerated with sequential values in the most significant
|
||||
* enum byte.
|
||||
*
|
||||
* Note: Cogl avoids exposing any padded XRGB or RGBX formats and
|
||||
* instead we leave it up to applications to decided whether they
|
||||
* consider the A component as padding or valid data. We shouldn't
|
||||
* change this policy without good reasoning.
|
||||
*
|
||||
* So to add a new format:
|
||||
* 1) Use the mapping table above to figure out what to but in
|
||||
* the lowest nibble.
|
||||
* 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and
|
||||
* COGL_BGR_BIT flags as appropriate.
|
||||
* 3) If the result is not yet unique then also combine with an
|
||||
* increment of the last sequence number in the most significant
|
||||
* byte.
|
||||
*
|
||||
* The last sequence number used was 0 (i.e. no formats currently need
|
||||
* a sequence number)
|
||||
* Update this note whenever a new sequence number is used.
|
||||
*/
|
||||
/**
|
||||
* CoglPixelFormat:
|
||||
* @COGL_PIXEL_FORMAT_ANY: Any format
|
||||
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
|
||||
* @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures
|
||||
* are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised.
|
||||
* See cogl_texture_set_components() for details.
|
||||
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_YUV: Not currently supported
|
||||
* @COGL_PIXEL_FORMAT_G_8: Single luminance component
|
||||
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc
|
||||
* @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc
|
||||
*
|
||||
* Pixel formats used by Cogl. For the formats with a byte per
|
||||
* component, the order of the components specify the order in
|
||||
* increasing memory addresses. So for example
|
||||
* %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the
|
||||
* lowest address, green in the next address and blue after that
|
||||
* regardless of the endianness of the system.
|
||||
*
|
||||
* For the formats with non byte aligned components the component
|
||||
* order specifies the order within a 16-bit or 32-bit number from
|
||||
* most significant bit to least significant. So for
|
||||
* %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits
|
||||
* 11-15, the green component would be in 6-11 and the blue component
|
||||
* would be in 1-5. Therefore the order in memory depends on the
|
||||
* endianness of the system.
|
||||
*
|
||||
* When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the
|
||||
* internal format. Cogl will try to pick the best format to use
|
||||
* internally and convert the texture data if necessary.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
|
||||
{
|
||||
COGL_PIXEL_FORMAT_ANY = 0,
|
||||
COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT,
|
||||
|
||||
COGL_PIXEL_FORMAT_RGB_565 = 4,
|
||||
COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT,
|
||||
COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT,
|
||||
COGL_PIXEL_FORMAT_YUV = 7,
|
||||
COGL_PIXEL_FORMAT_G_8 = 8,
|
||||
|
||||
COGL_PIXEL_FORMAT_RG_88 = 9,
|
||||
|
||||
COGL_PIXEL_FORMAT_RGB_888 = 2,
|
||||
COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT),
|
||||
COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
|
||||
COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
|
||||
COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
|
||||
|
||||
COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
|
||||
} CoglPixelFormat;
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_get_bytes_per_pixel:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries how many bytes a pixel of the given @format takes.
|
||||
*
|
||||
* Return value: The number of bytes taken for a pixel of the given
|
||||
* @format.
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_has_aligned_components:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries whether the ordering of the components for the given
|
||||
* @format depend on the endianness of the host CPU or if the
|
||||
* components can be accessed using bit shifting and bitmasking by
|
||||
* loading a whole pixel into a word.
|
||||
*
|
||||
* XXX: If we ever consider making something like this public we
|
||||
* should really try to think of a better name and come up with
|
||||
* much clearer documentation since it really depends on what
|
||||
* point of view you consider this from whether a format like
|
||||
* COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you
|
||||
* read an RGBA_8888 pixel into a uint32
|
||||
* it's endian dependent how you mask out the different channels.
|
||||
* But If you already have separate color components and you want
|
||||
* to write them to an RGBA_8888 pixel then the bytes can be
|
||||
* written sequentially regardless of the endianness.
|
||||
*
|
||||
* Return value: %TRUE if you need to consider the host CPU
|
||||
* endianness when dealing with the given @format
|
||||
* else %FALSE.
|
||||
*/
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format):
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Returns TRUE if the pixel format can take a premult bit. This is
|
||||
* currently true for all formats that have an alpha channel except
|
||||
* COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other
|
||||
* components to multiply by the alpha).
|
||||
*/
|
||||
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
|
||||
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
|
||||
|
||||
/**
|
||||
* cogl_pixel_format_to_string:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Returns a string representation of @format, useful for debugging purposes.
|
||||
*
|
||||
* Returns: (transfer none): A string representation of @format.
|
||||
*/
|
||||
const char *
|
||||
cogl_pixel_format_to_string (CoglPixelFormat format);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PIXEL_FORMAT_H__ */
|
@@ -42,14 +42,13 @@ G_BEGIN_DECLS
|
||||
/**
|
||||
* SECTION:cogl-primitive-texture
|
||||
* @short_description: Interface for low-level textures like
|
||||
* #CoglTexture2D and #CoglTexture3D.
|
||||
* #CoglTexture2D.
|
||||
*
|
||||
* A #CoglPrimitiveTexture is a texture that is directly represented
|
||||
* by a single texture on the GPU. For example these could be a
|
||||
* #CoglTexture2D, #CoglTexture3D or #CoglTextureRectangle. This is
|
||||
* opposed to high level meta textures which may be composed of
|
||||
* multiple primitive textures or a sub-region of another texture such
|
||||
* as #CoglAtlasTexture and #CoglTexture2DSliced.
|
||||
* by a single texture on the GPU. For example this could be a
|
||||
* #CoglTexture2D. This is opposed to high level meta textures which
|
||||
* may be composed of multiple primitive textures or a sub-region of
|
||||
* another texture such as #CoglAtlasTexture and #CoglTexture2DSliced.
|
||||
*
|
||||
* A texture that implements this interface can be directly used with
|
||||
* the low level cogl_primitive_draw() API. Other types of textures
|
||||
|
@@ -926,8 +926,8 @@ cogl_primitive_foreach_attribute (CoglPrimitive *primitive,
|
||||
* This drawing api doesn't support high-level meta texture types such
|
||||
* as #CoglTexture2DSliced so it is the user's responsibility to
|
||||
* ensure that only low-level textures that can be directly sampled by
|
||||
* a GPU such as #CoglTexture2D, #CoglTextureRectangle or #CoglTexture3D
|
||||
* are associated with layers of the given @pipeline.
|
||||
* a GPU such as #CoglTexture2D are associated with layers of the given
|
||||
* @pipeline.
|
||||
*
|
||||
* Stability: unstable
|
||||
* Since: 1.16
|
||||
|
@@ -187,8 +187,6 @@ validate_first_layer_cb (CoglPipeline *pipeline,
|
||||
* texture coordinates require repeating,
|
||||
* - CoglTexture2DAtlas: if the users given texture coordinates require
|
||||
* repeating,
|
||||
* - CoglTextureRectangle: if the users given texture coordinates require
|
||||
* repeating,
|
||||
* - CoglTexturePixmap: if the users given texture coordinates require
|
||||
* repeating
|
||||
*/
|
||||
@@ -427,11 +425,9 @@ validate_tex_coords_cb (CoglPipeline *pipeline,
|
||||
* - CoglTexture2DSliced: if only comprised of a single slice with optional
|
||||
* waste, assuming the users given texture coordinates don't require
|
||||
* repeating.
|
||||
* - CoglTexture{1D,2D,3D}: always.
|
||||
* - CoglTexture{1D,2D}: always.
|
||||
* - CoglTexture2DAtlas: assuming the users given texture coordinates don't
|
||||
* require repeating.
|
||||
* - CoglTextureRectangle: assuming the users given texture coordinates don't
|
||||
* require repeating.
|
||||
* - CoglTexturePixmap: assuming the users given texture coordinates don't
|
||||
* require repeating.
|
||||
*/
|
||||
|
@@ -116,57 +116,6 @@ _cogl_get_enable_legacy_state (void);
|
||||
#define _cogl_has_private_feature(ctx, feature) \
|
||||
COGL_FLAGS_GET ((ctx)->private_features, (feature))
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_get_bytes_per_pixel:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries how many bytes a pixel of the given @format takes.
|
||||
*
|
||||
* Return value: The number of bytes taken for a pixel of the given
|
||||
* @format.
|
||||
*/
|
||||
int
|
||||
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* _cogl_pixel_format_has_aligned_components:
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Queries whether the ordering of the components for the given
|
||||
* @format depend on the endianness of the host CPU or if the
|
||||
* components can be accessed using bit shifting and bitmasking by
|
||||
* loading a whole pixel into a word.
|
||||
*
|
||||
* XXX: If we ever consider making something like this public we
|
||||
* should really try to think of a better name and come up with
|
||||
* much clearer documentation since it really depends on what
|
||||
* point of view you consider this from whether a format like
|
||||
* COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you
|
||||
* read an RGBA_8888 pixel into a uint32
|
||||
* it's endian dependent how you mask out the different channels.
|
||||
* But If you already have separate color components and you want
|
||||
* to write them to an RGBA_8888 pixel then the bytes can be
|
||||
* written sequentially regardless of the endianness.
|
||||
*
|
||||
* Return value: %TRUE if you need to consider the host CPU
|
||||
* endianness when dealing with the given @format
|
||||
* else %FALSE.
|
||||
*/
|
||||
gboolean
|
||||
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
|
||||
|
||||
/*
|
||||
* COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format):
|
||||
* @format: a #CoglPixelFormat
|
||||
*
|
||||
* Returns TRUE if the pixel format can take a premult bit. This is
|
||||
* currently true for all formats that have an alpha channel except
|
||||
* COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other
|
||||
* components to multiply by the alpha).
|
||||
*/
|
||||
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
|
||||
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __COGL_PRIVATE_H__ */
|
||||
|
@@ -194,10 +194,8 @@ _cogl_renderer_free (CoglRenderer *renderer)
|
||||
if (renderer->libgl_module)
|
||||
g_module_close (renderer->libgl_module);
|
||||
|
||||
g_slist_foreach (renderer->event_filters,
|
||||
(GFunc) native_filter_closure_free,
|
||||
NULL);
|
||||
g_slist_free (renderer->event_filters);
|
||||
g_slist_free_full (renderer->event_filters,
|
||||
(GDestroyNotify) native_filter_closure_free);
|
||||
|
||||
g_array_free (renderer->poll_fds, TRUE);
|
||||
|
||||
@@ -784,8 +782,7 @@ cogl_renderer_get_n_fragment_texture_units (CoglRenderer *renderer)
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES2)
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_GLSL))
|
||||
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n));
|
||||
GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n));
|
||||
#endif
|
||||
|
||||
return n;
|
||||
|
@@ -40,7 +40,6 @@
|
||||
#include "cogl-context-private.h"
|
||||
#include "cogl-object.h"
|
||||
#include "cogl-texture-driver.h"
|
||||
#include "cogl-texture-rectangle-private.h"
|
||||
#include "cogl-texture-2d.h"
|
||||
#include "cogl-gtype-private.h"
|
||||
#include "driver/gl/cogl-texture-gl-private.h"
|
||||
@@ -60,30 +59,13 @@ _cogl_sub_texture_unmap_quad (CoglSubTexture *sub_tex,
|
||||
float *coords)
|
||||
{
|
||||
CoglTexture *tex = COGL_TEXTURE (sub_tex);
|
||||
float width = cogl_texture_get_width (sub_tex->full_texture);
|
||||
float height = cogl_texture_get_height (sub_tex->full_texture);
|
||||
|
||||
/* NB: coords[] come in as non-normalized if sub_tex->full_texture
|
||||
* is a CoglTextureRectangle otherwhise they are normalized. The
|
||||
* coordinates we write out though must always be normalized.
|
||||
*
|
||||
* NB: sub_tex->sub_x/y/width/height are in non-normalized
|
||||
* coordinates.
|
||||
*/
|
||||
if (cogl_is_texture_rectangle (sub_tex->full_texture))
|
||||
{
|
||||
coords[0] = (coords[0] - sub_tex->sub_x) / tex->width;
|
||||
coords[1] = (coords[1] - sub_tex->sub_y) / tex->height;
|
||||
coords[2] = (coords[2] - sub_tex->sub_x) / tex->width;
|
||||
coords[3] = (coords[3] - sub_tex->sub_y) / tex->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
float width = cogl_texture_get_width (sub_tex->full_texture);
|
||||
float height = cogl_texture_get_height (sub_tex->full_texture);
|
||||
coords[0] = (coords[0] * width - sub_tex->sub_x) / tex->width;
|
||||
coords[1] = (coords[1] * height - sub_tex->sub_y) / tex->height;
|
||||
coords[2] = (coords[2] * width - sub_tex->sub_x) / tex->width;
|
||||
coords[3] = (coords[3] * height - sub_tex->sub_y) / tex->height;
|
||||
}
|
||||
coords[0] = (coords[0] * width - sub_tex->sub_x) / tex->width;
|
||||
coords[1] = (coords[1] * height - sub_tex->sub_y) / tex->height;
|
||||
coords[2] = (coords[2] * width - sub_tex->sub_x) / tex->width;
|
||||
coords[3] = (coords[3] * height - sub_tex->sub_y) / tex->height;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -91,31 +73,13 @@ _cogl_sub_texture_map_quad (CoglSubTexture *sub_tex,
|
||||
float *coords)
|
||||
{
|
||||
CoglTexture *tex = COGL_TEXTURE (sub_tex);
|
||||
float width = cogl_texture_get_width (sub_tex->full_texture);
|
||||
float height = cogl_texture_get_height (sub_tex->full_texture);
|
||||
|
||||
/* NB: coords[] always come in as normalized coordinates but may go
|
||||
* out as non-normalized if sub_tex->full_texture is a
|
||||
* CoglTextureRectangle.
|
||||
*
|
||||
* NB: sub_tex->sub_x/y/width/height are in non-normalized
|
||||
* coordinates.
|
||||
*/
|
||||
|
||||
if (cogl_is_texture_rectangle (sub_tex->full_texture))
|
||||
{
|
||||
coords[0] = coords[0] * tex->width + sub_tex->sub_x;
|
||||
coords[1] = coords[1] * tex->height + sub_tex->sub_y;
|
||||
coords[2] = coords[2] * tex->width + sub_tex->sub_x;
|
||||
coords[3] = coords[3] * tex->height + sub_tex->sub_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
float width = cogl_texture_get_width (sub_tex->full_texture);
|
||||
float height = cogl_texture_get_height (sub_tex->full_texture);
|
||||
coords[0] = (coords[0] * tex->width + sub_tex->sub_x) / width;
|
||||
coords[1] = (coords[1] * tex->height + sub_tex->sub_y) / height;
|
||||
coords[2] = (coords[2] * tex->width + sub_tex->sub_x) / width;
|
||||
coords[3] = (coords[3] * tex->height + sub_tex->sub_y) / height;
|
||||
}
|
||||
coords[0] = (coords[0] * tex->width + sub_tex->sub_x) / width;
|
||||
coords[1] = (coords[1] * tex->height + sub_tex->sub_y) / height;
|
||||
coords[2] = (coords[2] * tex->width + sub_tex->sub_x) / width;
|
||||
coords[3] = (coords[3] * tex->height + sub_tex->sub_y) / height;
|
||||
}
|
||||
|
||||
typedef struct _CoglSubTextureForeachData
|
||||
@@ -165,8 +129,7 @@ _cogl_sub_texture_foreach_sub_texture_in_region (
|
||||
_cogl_sub_texture_map_quad (sub_tex, mapped_coords);
|
||||
|
||||
/* TODO: Add something like cogl_is_low_level_texture() */
|
||||
if (cogl_is_texture_2d (full_texture) ||
|
||||
cogl_is_texture_rectangle (full_texture))
|
||||
if (cogl_is_texture_2d (full_texture))
|
||||
{
|
||||
callback (sub_tex->full_texture,
|
||||
mapped_coords,
|
||||
@@ -452,14 +415,6 @@ _cogl_sub_texture_get_gl_format (CoglTexture *tex)
|
||||
return _cogl_texture_gl_get_format (sub_tex->full_texture);
|
||||
}
|
||||
|
||||
static CoglTextureType
|
||||
_cogl_sub_texture_get_type (CoglTexture *tex)
|
||||
{
|
||||
CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex);
|
||||
|
||||
return _cogl_texture_get_type (sub_tex->full_texture);
|
||||
}
|
||||
|
||||
static const CoglTextureVtable
|
||||
cogl_sub_texture_vtable =
|
||||
{
|
||||
@@ -481,7 +436,6 @@ cogl_sub_texture_vtable =
|
||||
_cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes,
|
||||
_cogl_sub_texture_get_format,
|
||||
_cogl_sub_texture_get_gl_format,
|
||||
_cogl_sub_texture_get_type,
|
||||
NULL, /* is_foreign */
|
||||
NULL /* set_auto_mipmap */
|
||||
};
|
||||
|
@@ -585,65 +585,6 @@ _cogl_rect_slices_for_size (int size_to_fill,
|
||||
return n_spans;
|
||||
}
|
||||
|
||||
static int
|
||||
_cogl_pot_slices_for_size (int size_to_fill,
|
||||
int max_span_size,
|
||||
int max_waste,
|
||||
GArray *out_spans)
|
||||
{
|
||||
int n_spans = 0;
|
||||
CoglSpan span;
|
||||
|
||||
/* Init first slice span */
|
||||
span.start = 0;
|
||||
span.size = max_span_size;
|
||||
span.waste = 0;
|
||||
|
||||
/* Fix invalid max_waste */
|
||||
if (max_waste < 0)
|
||||
max_waste = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* Is the whole area covered? */
|
||||
if (size_to_fill > span.size)
|
||||
{
|
||||
/* Not yet - add a span of this size */
|
||||
if (out_spans)
|
||||
g_array_append_val (out_spans, span);
|
||||
|
||||
span.start += span.size;
|
||||
size_to_fill -= span.size;
|
||||
n_spans++;
|
||||
}
|
||||
else if (span.size - size_to_fill <= max_waste)
|
||||
{
|
||||
/* Yes and waste is small enough */
|
||||
/* Pick the next power of two up from size_to_fill. This can
|
||||
sometimes be less than the span.size that would be chosen
|
||||
otherwise */
|
||||
span.size = _cogl_util_next_p2 (size_to_fill);
|
||||
span.waste = span.size - size_to_fill;
|
||||
if (out_spans)
|
||||
g_array_append_val (out_spans, span);
|
||||
|
||||
return ++n_spans;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Yes but waste is too large */
|
||||
while (span.size - size_to_fill > max_waste)
|
||||
{
|
||||
span.size /= 2;
|
||||
g_assert (span.size > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Can't get here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex,
|
||||
GLenum wrap_mode_s,
|
||||
@@ -700,18 +641,9 @@ setup_spans (CoglContext *ctx,
|
||||
int (*slices_for_size) (int, int, int, GArray*);
|
||||
|
||||
/* Initialize size of largest slice according to supported features */
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT))
|
||||
{
|
||||
max_width = width;
|
||||
max_height = height;
|
||||
slices_for_size = _cogl_rect_slices_for_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_width = _cogl_util_next_p2 (width);
|
||||
max_height = _cogl_util_next_p2 (height);
|
||||
slices_for_size = _cogl_pot_slices_for_size;
|
||||
}
|
||||
max_width = width;
|
||||
max_height = height;
|
||||
slices_for_size = _cogl_rect_slices_for_size;
|
||||
|
||||
/* Negative number means no slicing forced by the user */
|
||||
if (max_waste <= -1)
|
||||
@@ -999,9 +931,7 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
|
||||
* in GLES, hence such a function prototype.
|
||||
*/
|
||||
|
||||
/* This should only be called when the texture target is 2D. If a
|
||||
rectangle texture is used then _cogl_texture_new_from_foreign
|
||||
will create a cogl_texture_rectangle instead */
|
||||
/* This should only be called when the texture target is 2D. */
|
||||
_COGL_RETURN_VAL_IF_FAIL (gl_target == GL_TEXTURE_2D, NULL);
|
||||
|
||||
/* Assert it is a valid GL texture object */
|
||||
@@ -1512,12 +1442,6 @@ _cogl_texture_2d_sliced_get_gl_format (CoglTexture *tex)
|
||||
return _cogl_texture_gl_get_format (COGL_TEXTURE (slice_tex));
|
||||
}
|
||||
|
||||
static CoglTextureType
|
||||
_cogl_texture_2d_sliced_get_type (CoglTexture *tex)
|
||||
{
|
||||
return COGL_TEXTURE_TYPE_2D;
|
||||
}
|
||||
|
||||
static const CoglTextureVtable
|
||||
cogl_texture_2d_sliced_vtable =
|
||||
{
|
||||
@@ -1539,7 +1463,6 @@ cogl_texture_2d_sliced_vtable =
|
||||
_cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes,
|
||||
_cogl_texture_2d_sliced_get_format,
|
||||
_cogl_texture_2d_sliced_get_gl_format,
|
||||
_cogl_texture_2d_sliced_get_type,
|
||||
_cogl_texture_2d_sliced_is_foreign,
|
||||
NULL /* set_auto_mipmap */
|
||||
};
|
||||
|
@@ -505,14 +505,7 @@ _cogl_texture_2d_is_sliced (CoglTexture *tex)
|
||||
static gboolean
|
||||
_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex)
|
||||
{
|
||||
CoglContext *ctx = tex->context;
|
||||
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_REPEAT) ||
|
||||
(_cogl_util_is_pot (tex->width) &&
|
||||
_cogl_util_is_pot (tex->height)))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -674,12 +667,6 @@ _cogl_texture_2d_is_foreign (CoglTexture *tex)
|
||||
return COGL_TEXTURE_2D (tex)->is_foreign;
|
||||
}
|
||||
|
||||
static CoglTextureType
|
||||
_cogl_texture_2d_get_type (CoglTexture *tex)
|
||||
{
|
||||
return COGL_TEXTURE_TYPE_2D;
|
||||
}
|
||||
|
||||
static const CoglTextureVtable
|
||||
cogl_texture_2d_vtable =
|
||||
{
|
||||
@@ -701,7 +688,6 @@ cogl_texture_2d_vtable =
|
||||
_cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes,
|
||||
_cogl_texture_2d_get_format,
|
||||
_cogl_texture_2d_get_gl_format,
|
||||
_cogl_texture_2d_get_type,
|
||||
_cogl_texture_2d_is_foreign,
|
||||
_cogl_texture_2d_set_auto_mipmap
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user