Compare commits

..

2 Commits

Author SHA1 Message Date
Matthias Clasen 40ad95cb5d Add gtk_widget_add_tick_callback_with_flags
For now, the only flag we have is when-mapped.
This avoids a typical use case for the ::map
and ::unmap signals, which we eventually want
to get rid of.
2023-04-09 10:43:16 -04:00
Matthias Clasen d0467675db widget: Small refactor
Break out the tick cb management into functions,
since we will be calling this in more than one place
in the future.
2023-04-09 10:19:40 -04:00
303 changed files with 8213 additions and 11323 deletions
+29 -6
View File
@@ -26,7 +26,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Ddemos=false -Dbuild-examples=false -Dbuild-tests=false -Dbuild-testsuite=true"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v42"
workflow:
rules:
@@ -57,9 +57,15 @@ style-check-diff:
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-x11_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_smalltexture_unstable.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway_unstable.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
@@ -70,7 +76,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
cache:
key: "$CI_JOB_NAME"
@@ -86,6 +91,7 @@ fedora-x86_64:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson subprojects download
- meson subprojects update --reset
- mkdir _install
@@ -103,6 +109,7 @@ fedora-x86_64:
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build wayland_smalltexture
- .gitlab-ci/run-tests.sh _build broadway
release-build:
@@ -114,6 +121,7 @@ release-build:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson subprojects download
- meson subprojects update --reset
- meson setup
@@ -144,11 +152,23 @@ fedora-mingw64:
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=1.0
- pip3 install --user meson~=0.64
- meson subprojects download
- meson subprojects update --reset
- meson -Dintrospection=disabled -Dgraphene:introspection=disabled _build
- meson compile -C _build
# Test that mingw64-meson still fails. If it has stopped failing, the CI
# will fail and now you should remove the hack that follows this.
- FAILED=false
- mingw64-meson --version || FAILED=true
- test $FAILED = false && echo "mingw64-meson works now, remove the hack" && exit 1
# HACK: Running mingw64-meson directly fails on the CI with:
# /usr/bin/mingw64-meson: line 92: fg: no job control
# Because rpm is not evaluating %__meson and it gets interpreted as a job
# specifier. So we fix that and run it ourselves.
- rpm --eval "%{mingw64_meson}" > mingw64-meson.sh
- sed -i -e 's/%__meson/meson/' mingw64-meson.sh
- chmod +x mingw64-meson.sh
- ./mingw64-meson.sh -Dintrospection=disabled -Dgraphene:introspection=disabled _build
- ninja -C _build
.mingw-defaults:
stage: build
@@ -190,7 +210,7 @@ macos:
needs: []
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson~=1.0
- pip3 install --user meson~=0.64
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
@@ -348,6 +368,7 @@ static-scan:
EXTRA_MESON_FLAGS: "--buildtype=debug"
script:
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
@@ -369,6 +390,7 @@ asan-build:
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- CC=clang meson setup --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled -Df16c=disabled _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
@@ -383,6 +405,7 @@ reference:
needs: []
script:
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=0.64
- meson setup
${COMMON_MESON_FLAGS}
--buildtype=release
+1 -6
View File
@@ -32,6 +32,7 @@ RUN dnf -y install \
glib2-static \
glibc-devel \
glibc-headers \
gnome-desktop-testing \
gnupg2 \
gobject-introspection-devel \
graphene-devel \
@@ -72,14 +73,10 @@ RUN dnf -y install \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libGLES-devel \
meson \
mutter \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
pipewire \
pipewire-gstreamer \
python3 \
python3-docutils \
python3-gobject \
@@ -87,7 +84,6 @@ RUN dnf -y install \
python3-markdown \
python3-packaging \
python3-pip \
python3-pydbus \
python3-pygments \
python3-typogrify \
python3-wheel \
@@ -99,7 +95,6 @@ RUN dnf -y install \
weston \
weston-libs \
which \
wireplumber \
xorg-x11-server-Xvfb \
&& dnf clean all
+1 -2
View File
@@ -138,8 +138,7 @@ if [ $run == 1 ]; then
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
${CMD} run \
--rm \
--userns=keep-id \
--volume "$(pwd)/..:/home/user/app:rw,z" \
--volume "$(pwd)/..:/home/user/app" \
--workdir "/home/user/app" \
--tty \
--interactive "${TAG}" \
+36 -18
View File
@@ -6,7 +6,6 @@ set +e
srcdir=$( pwd )
builddir=$1
backend=$2
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:verbosity=1:log_threads=1
@@ -16,8 +15,7 @@ case "${backend}" in
x11)
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -28,6 +26,14 @@ case "${backend}" in
# Store the exit code for the CI run, but always
# generate the reports
exit_code=$?
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
;;
wayland*)
@@ -38,17 +44,22 @@ case "${backend}" in
export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--no-suite=${backend}_failing \
--no-suite=gsk-compare-broadway
exit_code=$?
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
kill ${compositor}
;;
@@ -60,8 +71,7 @@ case "${backend}" in
export BROADWAY_DISPLAY=:5
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
@@ -72,6 +82,13 @@ case "${backend}" in
# don't let Broadway failures fail the run, for now
exit_code=0
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend}_unstable \
--suite=flaky \
--suite=failing || true
kill ${server}
;;
@@ -84,19 +101,20 @@ esac
cd ${builddir}
$srcdir/.gitlab-ci/meson-junit-report.py \
for suffix in "" "_unstable"; do
$srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \
--backend="${backend}" \
--backend="${backend}${suffix}" \
--job-id="${CI_JOB_NAME}" \
--output="report-${backend}.xml" \
"meson-logs/testlog-${backend}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
--output="report-${backend}${suffix}.xml" \
"meson-logs/testlog-${backend}${suffix}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \
--backend="${backend}" \
--backend="${backend}${suffix}" \
--job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${backend}" \
--output="report-${backend}.html" \
"meson-logs/testlog-${backend}.json"
--reftest-output-dir="testsuite/reftests/output/${backend}${suffix}" \
--output="report-${backend}${suffix}.html" \
"meson-logs/testlog-${backend}${suffix}.json"
done
exit $exit_code
-68
View File
@@ -1,74 +1,6 @@
Overview of Changes in 4.11.2, xx-xx-xxxx
=========================================
* GtkGLArea:
- Add an allowed-apis property
* GtkListBox:
- Fix a problem with gtk_list_box_remove_all
* GtkCenterBox:
- Add a shrink-center-last property
* GtkButton, GtkMenuButton:
- Add a can-shrink property
* GtkPopover:
- Fix problems with grabs
* GtkFileChooser:
- Fix a problem with removing files
- Make the date, time and location columns work
- Fix filtering in the save entry popup
- A few memory leak fixes
- Handle webdav in the pathbar
* Dialogs:
- Destroy windows promptly when the async callback finishes
- Detect absence of the OpenURI portal and fall back
* Theme:
- Add explicit style classes to a number of widgets
- Fix some contrast issues in the dark theme
* Accessibility:
- Fix alert dialogs in the a11y tree
* Layout:
- Some fixes to baseline alignment
* GL:
- Add GdkGLTextureBuilder, a more flexible api for creating textures
- Ensure that we work with GLES 2
* Vulkan:
- More fixes to the experimental Vulkan renderer
- Rework glyph caching
* Wayland:
- Don't destroy wl_surfaces on hide
- Plug leaks of compositor-side resources
* Inspector:
- Improve the action list
- Fix a crash
* Tools:
- gtk4-node-editor: Improve scaling
- gtk4-node-editor: Preserve aspect ratio of textures
- gtk4-demo: Make the stylus demo work with mice
* Translation updates
Bulgarian
Chinese (China)
Galician
Hebrew
Polish
Portuguese
Russian
Turkish
Overview of Changes in 4.11.1, 03-04-2023
=========================================
+12 -5
View File
@@ -116,12 +116,19 @@ docs/reference/gtk/html/gtk-building.html
Or [online](https://docs.gtk.org/gtk4/building.html)
Building from git
-----------------
Default branch renamed to `main`
--------------------------------
The GTK sources are hosted on [gitlab.gnome.org](http://gitlab.gnome.org). The main
development branch is called `main`, and stable branches are named after their minor
version, for example `gtk-4-10`.
The default development branch of GTK has been renamed to `main`.
To update your local checkout, use:
```sh
git checkout master
git branch -m master main
git fetch
git branch --unset-upstream
git branch -u origin/main
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
```
How to report bugs
------------------
+4 -10
View File
@@ -109,21 +109,15 @@ static void
apply_transform (CanvasItem *item)
{
GskTransform *transform;
graphene_rect_t bounds;
double x, y;
/* Add css padding and margin */
if (!gtk_widget_compute_bounds (item->label, item->label, &bounds))
return;
x = bounds.size.width / 2.;
y = bounds.size.height / 2.;
item->r = sqrt (x * x + y * y);
x = gtk_widget_get_allocated_width (item->label) / 2.0;
y = gtk_widget_get_allocated_height (item->label) / 2.0;
item->r = sqrt (x*x + y*y);
transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r });
transform = gsk_transform_rotate (transform, item->angle + item->delta);
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-x, -y));
transform = gsk_transform_translate (transform, &(graphene_point_t) { -x, -y });
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
gsk_transform_unref (transform);
+6 -6
View File
@@ -42,8 +42,8 @@ val_to_xy (GtkFontPlane *plane,
double u, v;
int width, height;
width = gtk_widget_get_width (GTK_WIDGET (plane));
height = gtk_widget_get_height (GTK_WIDGET (plane));
width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
u = adjustment_get_normalized_value (plane->width_adj);
v = adjustment_get_normalized_value (plane->weight_adj);
@@ -62,8 +62,8 @@ plane_snapshot (GtkWidget *widget,
cairo_t *cr;
val_to_xy (plane, &x, &y);
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height));
@@ -131,8 +131,8 @@ update_value (GtkFontPlane *plane,
GtkWidget *widget = GTK_WIDGET (plane);
double u, v;
u = CLAMP (x * (1.0 / gtk_widget_get_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_height (widget)), 0, 1);
u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
adjustment_set_normalized_value (plane->width_adj, u);
adjustment_set_normalized_value (plane->weight_adj, v);
-2
View File
@@ -64,8 +64,6 @@
</child>
<child>
<object class="GtkLabel" id="short_time_label">
<property name="hexpand">1</property>
<property name="xalign">1</property>
<property name="valign">baseline</property>
<property name="label" translatable="yes">38m</property>
<style>
+8 -26
View File
@@ -24,7 +24,6 @@ typedef struct
GdkRGBA draw_color;
GtkPadController *pad_controller;
double brush_size;
GtkGesture *gesture;
} DrawingArea;
typedef struct
@@ -261,7 +260,7 @@ drawing_area_apply_stroke (DrawingArea *area,
double y,
double pressure)
{
if (tool && gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
{
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
@@ -312,9 +311,7 @@ stylus_gesture_motion (GtkGestureStylus *gesture,
drawing_area_apply_stroke (area, tool,
backlog[i].axes[GDK_AXIS_X],
backlog[i].axes[GDK_AXIS_Y],
backlog[i].flags & GDK_AXIS_FLAG_PRESSURE
? backlog[i].axes[GDK_AXIS_PRESSURE]
: 1);
backlog[i].axes[GDK_AXIS_PRESSURE]);
}
g_free (backlog);
@@ -344,8 +341,6 @@ drawing_area_init (DrawingArea *area)
area->draw_color = (GdkRGBA) { 0, 0, 0, 1 };
area->brush_size = 1;
area->gesture = gesture;
}
static GtkWidget *
@@ -384,12 +379,6 @@ drawing_area_color_set (DrawingArea *area,
gtk_color_dialog_button_set_rgba (button, color);
}
static GtkGesture *
drawing_area_get_gesture (DrawingArea *area)
{
return area->gesture;
}
GtkWidget *
do_paint (GtkWidget *toplevel)
{
@@ -397,7 +386,7 @@ do_paint (GtkWidget *toplevel)
if (!window)
{
GtkWidget *draw_area, *headerbar, *button;
GtkWidget *draw_area, *headerbar, *colorbutton;
window = gtk_window_new ();
@@ -406,22 +395,15 @@ do_paint (GtkWidget *toplevel)
headerbar = gtk_header_bar_new ();
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
g_signal_connect (button, "notify::rgba",
colorbutton = gtk_color_dialog_button_new (gtk_color_dialog_new ());
g_signal_connect (colorbutton, "notify::rgba",
G_CALLBACK (color_button_color_set), draw_area);
g_signal_connect (draw_area, "color-set",
G_CALLBACK (drawing_area_color_set), button);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (button),
G_CALLBACK (drawing_area_color_set), colorbutton);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (colorbutton),
&(GdkRGBA) { 0, 0, 0, 1 });
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), button);
button = gtk_check_button_new_with_label ("Stylus only");
g_object_bind_property (button, "active",
drawing_area_get_gesture ((DrawingArea *)draw_area), "stylus-only",
G_BINDING_SYNC_CREATE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (headerbar), button);
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_title (GTK_WINDOW (window), "Paint");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+1 -1
View File
@@ -471,7 +471,7 @@ suggestion_entry_size_allocate (GtkWidget *widget,
&(GtkAllocation) { width - arrow_nat, 0, arrow_nat, height },
baseline);
gtk_widget_set_size_request (self->popup, gtk_widget_get_width (GTK_WIDGET (self)), -1);
gtk_widget_set_size_request (self->popup, gtk_widget_get_allocated_width (GTK_WIDGET (self)), -1);
gtk_widget_queue_resize (self->popup);
gtk_popover_present (GTK_POPOVER (self->popup));
-2
View File
@@ -78,8 +78,6 @@ gtk_renderer_paintable_paintable_snapshot (GdkPaintable *paintable,
gdk_paintable_snapshot (GDK_PAINTABLE (texture), snapshot, width, height);
g_object_unref (texture);
gsk_render_node_unref (node);
}
static int
+10 -30
View File
@@ -64,7 +64,6 @@ struct _NodeEditorWindow
GListStore *renderers;
GskRenderNode *node;
GFile *file;
GFileMonitor *file_monitor;
GArray *errors;
@@ -545,14 +544,12 @@ node_editor_window_load (NodeEditorWindow *self,
{
GError *error = NULL;
g_clear_object (&self->file);
g_clear_object (&self->file_monitor);
if (!load_file_contents (self, file))
return FALSE;
self->file = g_object_ref (file);
self->file_monitor = g_file_monitor_file (self->file, G_FILE_MONITOR_NONE, NULL, &error);
self->file_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
if (error)
{
@@ -589,21 +586,13 @@ static void
show_open_filechooser (NodeEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Open node file");
if (self->file)
{
gtk_file_dialog_set_initial_file (dialog, self->file);
}
else
{
GFile *cwd;
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd);
}
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
g_object_unref (cwd);
gtk_file_dialog_open (dialog, GTK_WINDOW (self),
NULL, open_response_cb, self);
g_object_unref (dialog);
@@ -661,21 +650,14 @@ save_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Save node");
if (self->file)
{
gtk_file_dialog_set_initial_file (dialog, self->file);
}
else
{
GFile *cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
gtk_file_dialog_set_initial_name (dialog, "demo.node");
g_object_unref (cwd);
}
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
gtk_file_dialog_set_initial_name (dialog, "demo.node");
g_object_unref (cwd);
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL,
@@ -1109,8 +1091,6 @@ node_editor_window_finalize (GObject *object)
g_clear_pointer (&self->node, gsk_render_node_unref);
g_clear_object (&self->renderers);
g_clear_object (&self->file_monitor);
g_clear_object (&self->file);
G_OBJECT_CLASS (node_editor_window_parent_class)->finalize (object);
}
+2 -2
View File
@@ -2,7 +2,7 @@
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the parsing APIs.
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the aprsing APIs.
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
**document**: `<node>\*`
@@ -23,7 +23,7 @@ Nodes can be given a name by adding a string after the `<node-type>` in their de
### Textures
Just like nodes, textures can be referenced by name. When defining a named texture, the name has to be placed in front of the URL.
Just like nodes, textures can be referenced by name. When definining the named texture, the name has to be placed in front of the URL.
# Nodes
-4
View File
@@ -44,10 +44,6 @@ widgets (although most of the time, the transformation will be a simple 2D trans
The transform to go from one widgets coordinate system to another one can be obtained
with [method@Gtk.Widget.compute_transform].
In addition to a size, widgets can optionally have a **_baseline_** to position text on.
Containers such as [class@Gtk.Box] may position their children to match up their baselines.
[method@Gtk.Widget.get_baseline] returns the y position of the baseline in widget coordinates.
When widget APIs expect positions or areas, they need to be expressed in this coordinate
system, typically called **_widget coordinates_**. GTK provides a number of APIs to translate
between different widgets' coordinate systems, such as [method@Gtk.Widget.compute_point]
-1
View File
@@ -68,7 +68,6 @@ ui_files = [
'stackswitcher.ui',
'statusbar.ui',
'switch.ui',
'switch-state.ui',
'toggle-button.ui',
'video.ui',
'volumebutton.ui',
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkSwitch">
<property name="active">1</property>
<property name="state">0</property>
</object>
</child>
<child>
<object class="GtkSwitch">
<property name="active">0</property>
<property name="state">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
+5 -5
View File
@@ -258,7 +258,7 @@ Instead of implementing GtkWidget.destroy, you can implement GObject.dispose.
GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there
is not always a replacement for `gtk_container_remove()` in GTK 3, you can
replace many uses of `gtk_container_add()` with equivalent container-specific
APIs such as `gtk_grid_attach()`, and thereby reduce
APIs such as `gtk_box_pack_start()` or `gtk_grid_attach()`, and thereby reduce
the amount of work you have to do at the time of the switch.
### Review your use of icon resources
@@ -402,9 +402,9 @@ is open, use the [property@Gtk.Window:modal] property of the dialog.
### Adapt to coordinate API changes
A number of coordinate APIs in GTK 3 had variants taking `int` arguments:
A number of coordinate APIs in GTK 3 had `double` variants:
`gdk_device_get_surface_at_position()`, `gdk_surface_get_device_position()`.
These have been changed to use `double` arguments, and the `int` variants
These have been changed to use doubles, and the `double` variants
have been removed. Update your code accordingly.
Any APIs that deal with global (or root) coordinates have been
@@ -875,10 +875,10 @@ reference.
### Adapt to coordinate API changes
A number of APIs that are accepting or returning coordinates have
been changed from `int`s to `double`s: `gtk_widget_translate_coordinates()`,
been changed from ints to doubles: `gtk_widget_translate_coordinates()`,
`gtk_fixed_put()`, `gtk_fixed_move()`. This change is mostly transparent,
except for cases where out parameters are involved: you need to
pass `double*` now, instead of `int*`.
pass double* now, instead of int*.
### Adapt to GtkStyleContext API changes
-14
View File
@@ -119,17 +119,3 @@ it no longer has a resize handle for the window.
These are very specialized widgets that should better live with the application
where they are used.
## Widget size api changes
The functions gtk_widget_get_allocated_width() and gtk_widget_get_allocated_height()
are going away. In most cases, [method@Gtk.Widget.get_width] and [method@Gtk.Widget.get_height]
are suitable replacements. Note that the semantics are slightly different though:
the old functions return the size of the CSS border area, while the new functions return
the size of the widgets content area. In places where this difference matters, you can
use `gtk_widget_compute_bounds (widget, widget, &bounds)` instead.
The function gtk_widget_get_allocation() is also going away. It does not have a direct
replacement, but the previously mentioned alternatives can be used for it too.
The function gtk_widget_get_allocated_baseline() has been renamed to [method@Gtk.Widget.get_baseline].
+1 -2
View File
@@ -477,8 +477,6 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
object_class->dispose = gdk_broadway_display_dispose;
object_class->finalize = gdk_broadway_display_finalize;
display_class->toplevel_type = GDK_TYPE_BROADWAY_TOPLEVEL;
display_class->popup_type = GDK_TYPE_BROADWAY_POPUP;
display_class->cairo_context_type = GDK_TYPE_BROADWAY_CAIRO_CONTEXT;
display_class->get_name = gdk_broadway_display_get_name;
@@ -490,6 +488,7 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
display_class->get_next_serial = gdk_broadway_display_get_next_serial;
display_class->notify_startup_complete = gdk_broadway_display_notify_startup_complete;
display_class->create_surface = _gdk_broadway_display_create_surface;
display_class->get_keymap = _gdk_broadway_display_get_keymap;
display_class->get_monitors = gdk_broadway_display_get_monitors;
+7
View File
@@ -103,6 +103,13 @@ void _gdk_broadway_display_get_default_cursor_size (GdkDisplay *display,
void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
guint *width,
guint *height);
GdkSurface * _gdk_broadway_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkKeymap* _gdk_broadway_display_get_keymap (GdkDisplay *display);
void _gdk_broadway_display_consume_all_input (GdkDisplay *display);
BroadwayInputMsg * _gdk_broadway_display_block_for_input (GdkDisplay *display,
+174 -148
View File
@@ -47,8 +47,19 @@
#include <stdio.h>
#include <string.h>
/* Forward declarations */
static void gdk_broadway_surface_finalize (GObject *object);
G_DEFINE_TYPE (GdkBroadwaySurface, gdk_broadway_surface, GDK_TYPE_SURFACE)
GType gdk_broadway_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_broadway_popup_get_type (void) G_GNUC_CONST;
GType gdk_broadway_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_BROADWAY_TOPLEVEL (gdk_broadway_toplevel_get_type ())
#define GDK_TYPE_BROADWAY_POPUP (gdk_broadway_popup_get_type ())
#define GDK_TYPE_BROADWAY_DRAG_SURFACE (gdk_broadway_drag_surface_get_type ())
/* We need to flush in an idle rather than AFTER_PAINT, as the clock
is frozen during e.g. surface resizes so the paint will not happen
and the surface resize request is never flushed. */
@@ -63,93 +74,6 @@ gdk_broadway_surface_init (GdkBroadwaySurface *impl)
{
}
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
_gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial (display));
gdk_display_flush (display);
}
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
if (surface->update_freeze_count > 0)
return;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static void
connect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
static void
disconnect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
static void
gdk_broadway_surface_constructed (GObject *object)
{
GdkBroadwaySurface *self = GDK_BROADWAY_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (object);
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, self);
self->id = _gdk_broadway_server_new_surface (broadway_display->server,
self->root_x,
self->root_y,
1, 1);
g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER (self->id), surface);
g_object_ref (self);
G_OBJECT_CLASS (gdk_broadway_surface_parent_class)->constructed (object);
connect_frame_clock (surface);
}
static void
gdk_broadway_surface_finalize (GObject *object)
{
@@ -219,6 +143,164 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
}
}
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkDisplay *display = gdk_surface_get_display (surface);
GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
GdkBroadwayDisplay *broadway_display;
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
gdk_surface_freeze_updates (surface);
broadway_display = GDK_BROADWAY_DISPLAY (display);
_gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial (display));
gdk_display_flush (display);
}
static void
on_frame_clock_before_paint (GdkFrameClock *clock,
GdkSurface *surface)
{
GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
gint64 presentation_time;
gint64 refresh_interval;
if (surface->update_freeze_count > 0)
return;
gdk_frame_clock_get_refresh_info (clock,
timings->frame_time,
&refresh_interval, &presentation_time);
if (presentation_time != 0)
{
timings->predicted_presentation_time = presentation_time + refresh_interval;
}
else
{
timings->predicted_presentation_time = timings->frame_time + refresh_interval / 2 + refresh_interval;
}
}
static void
connect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_connect (frame_clock, "before-paint",
G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), surface);
}
static void
disconnect_frame_clock (GdkSurface *surface)
{
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock,
on_frame_clock_after_paint, surface);
}
GdkSurface *
_gdk_broadway_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkBroadwayDisplay *broadway_display;
GdkFrameClock *frame_clock;
GdkSurface *surface;
GdkBroadwaySurface *impl;
GType type;
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
type = GDK_TYPE_BROADWAY_TOPLEVEL;
break;
case GDK_SURFACE_POPUP:
type = GDK_TYPE_BROADWAY_POPUP;
break;
case GDK_SURFACE_DRAG:
type = GDK_TYPE_BROADWAY_DRAG_SURFACE;
break;
default:
g_assert_not_reached ();
break;
}
surface = g_object_new (type,
"display", display,
"frame-clock", frame_clock,
NULL);
g_object_unref (frame_clock);
surface->parent = parent;
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
broadway_display = GDK_BROADWAY_DISPLAY (display);
impl = GDK_BROADWAY_SURFACE (surface);
impl->root_x = x;
impl->root_y = y;
if (parent)
{
impl->root_x += GDK_BROADWAY_SURFACE (parent)->root_x;
impl->root_y += GDK_BROADWAY_SURFACE (parent)->root_y;
}
impl->id = _gdk_broadway_server_new_surface (broadway_display->server,
impl->root_x,
impl->root_y,
surface->width,
surface->height);
g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), surface);
g_object_ref (surface);
if (!surface->parent)
broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
connect_frame_clock (surface);
/* We treat the real parent as a default transient for to get stacking right */
if (parent)
{
impl->transient_for = GDK_BROADWAY_SURFACE (parent)->id;
_gdk_broadway_server_surface_set_transient_for (broadway_display->server, impl->id, impl->transient_for);
}
return surface;
}
static cairo_surface_t *
gdk_broadway_surface_ref_cairo_surface (GdkSurface *surface)
{
if (GDK_IS_BROADWAY_SURFACE (surface) &&
GDK_SURFACE_DESTROYED (surface))
return NULL;
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
}
static void
_gdk_broadway_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy)
@@ -1025,14 +1107,6 @@ _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
return TRUE;
}
static GdkSurface *
gdk_broadway_drag_surface_new (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_BROADWAY_DRAG_SURFACE,
"display", display,
NULL);
}
static void
create_moveresize_surface (MoveResizeData *mv_resize,
guint32 timestamp)
@@ -1044,9 +1118,11 @@ create_moveresize_surface (MoveResizeData *mv_resize,
g_assert (mv_resize->moveresize_emulation_surface == NULL);
mv_resize->moveresize_emulation_surface =
gdk_broadway_drag_surface_new (mv_resize->display);
_gdk_broadway_display_create_surface (mv_resize->display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 1, 1);
gdk_broadway_surface_move_resize_internal (mv_resize->moveresize_emulation_surface, TRUE, -100, -100, 1, 1);
gdk_broadway_surface_show (mv_resize->moveresize_emulation_surface, FALSE);
seat = gdk_display_get_default_seat (mv_resize->display);
@@ -1176,9 +1252,9 @@ gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = gdk_broadway_surface_constructed;
object_class->finalize = gdk_broadway_surface_finalize;
impl_class->ref_cairo_surface = gdk_broadway_surface_ref_cairo_surface;
impl_class->hide = gdk_broadway_surface_hide;
impl_class->get_geometry = gdk_broadway_surface_get_geometry;
impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
@@ -1214,25 +1290,6 @@ gdk_broadway_popup_init (GdkBroadwayPopup *popup)
{
}
static void
gdk_broadway_popup_constructed (GObject *object)
{
GdkBroadwaySurface *self = GDK_BROADWAY_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
self->root_x = GDK_BROADWAY_SURFACE (surface->parent)->root_x;
self->root_y = GDK_BROADWAY_SURFACE (surface->parent)->root_y;
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (surface->parent));
G_OBJECT_CLASS (gdk_broadway_popup_parent_class)->constructed (object);
/* We treat the real parent as a default transient for to get stacking right */
self->transient_for = GDK_BROADWAY_SURFACE (surface->parent)->id;
_gdk_broadway_server_surface_set_transient_for (broadway_display->server, self->id, self->transient_for);
}
static void
gdk_broadway_popup_get_property (GObject *object,
guint prop_id,
@@ -1288,7 +1345,6 @@ gdk_broadway_popup_class_init (GdkBroadwayPopupClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_popup_constructed;
object_class->get_property = gdk_broadway_popup_get_property;
object_class->set_property = gdk_broadway_popup_set_property;
@@ -1359,19 +1415,6 @@ gdk_broadway_toplevel_init (GdkBroadwayToplevel *toplevel)
{
}
static void
gdk_broadway_toplevel_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_broadway_toplevel_parent_class)->constructed (object);
}
static void
gdk_broadway_toplevel_set_property (GObject *object,
guint prop_id,
@@ -1475,7 +1518,6 @@ gdk_broadway_toplevel_class_init (GdkBroadwayToplevelClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_toplevel_constructed;
object_class->get_property = gdk_broadway_toplevel_get_property;
object_class->set_property = gdk_broadway_toplevel_set_property;
@@ -1636,25 +1678,9 @@ gdk_broadway_drag_surface_init (GdkBroadwayDragSurface *surface)
{
}
static void
gdk_broadway_drag_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_broadway_drag_surface_parent_class)->constructed (object);
}
static void
gdk_broadway_drag_surface_class_init (GdkBroadwayDragSurfaceClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_broadway_drag_surface_constructed;
}
static gboolean
-8
View File
@@ -32,14 +32,6 @@ G_BEGIN_DECLS
/* Surface implementation for Broadway
*/
GType gdk_broadway_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_broadway_popup_get_type (void) G_GNUC_CONST;
GType gdk_broadway_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_BROADWAY_TOPLEVEL (gdk_broadway_toplevel_get_type ())
#define GDK_TYPE_BROADWAY_POPUP (gdk_broadway_popup_get_type ())
#define GDK_TYPE_BROADWAY_DRAG_SURFACE (gdk_broadway_drag_surface_get_type ())
struct _GdkBroadwaySurface
{
GdkSurface parent_instance;
-1
View File
@@ -54,7 +54,6 @@
#include <gdk/gdkframetimings.h>
#include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexture.h>
#include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdkkeys.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkmemorytexture.h>
+17
View File
@@ -1196,6 +1196,21 @@ _gdk_display_unpause_events (GdkDisplay *display)
display->event_pause_count--;
}
GdkSurface *
gdk_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
return GDK_DISPLAY_GET_CLASS (display)->create_surface (display,
surface_type,
parent,
x, y, width, height);
}
/*< private >
* gdk_display_get_keymap:
* @display: the `GdkDisplay`
@@ -1708,6 +1723,8 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
self->have_egl_pixel_format_float =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
self->have_egl_win32_libangle =
epoxy_has_egl_extension (priv->egl_display, "EGL_ANGLE_d3d_share_handle_client_buffer");
if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
+2 -2
View File
@@ -369,7 +369,7 @@ gdk_display_manager_list_displays (GdkDisplayManager *manager)
/**
* gdk_display_manager_open_display:
* @manager: a `GdkDisplayManager`
* @name: (nullable): the name of the display to open
* @name: the name of the display to open
*
* Opens a display.
*
@@ -437,7 +437,7 @@ gdk_display_manager_open_display (GdkDisplayManager *manager,
}
}
if (!found && !any && !display)
if (!found && !display)
g_warning ("No such backend: %s", backend);
}
+17 -3
View File
@@ -108,14 +108,13 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
guint have_egl_win32_libangle : 1;
};
struct _GdkDisplayClass
{
GObjectClass parent_class;
GType toplevel_type; /* Type for GdkToplevel, must be set */
GType popup_type; /* Type for GdkPopup, must be set */
GType cairo_context_type; /* type for GdkCairoContext, must be set */
GType vk_context_type; /* type for GdkVulkanContext, must be set if vk_extension_name != NULL */
const char *vk_extension_name; /* Name of required windowing vulkan extension or %NULL (default) if Vulkan isn't supported */
@@ -136,7 +135,15 @@ struct _GdkDisplayClass
const char *startup_id);
const char * (*get_startup_notification_id) (GdkDisplay *display);
GdkKeymap * (*get_keymap) (GdkDisplay *display);
GdkSurface * (*create_surface) (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkKeymap * (*get_keymap) (GdkDisplay *display);
GdkGLContext * (* init_gl) (GdkDisplay *display,
GError **error);
@@ -201,6 +208,13 @@ void _gdk_display_pointer_info_foreach (GdkDisplay *display
gulong _gdk_display_get_next_serial (GdkDisplay *display);
void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_events (GdkDisplay *display);
GdkSurface * gdk_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
-14
View File
@@ -32,20 +32,6 @@
G_BEGIN_DECLS
/**
* GdkGLAPI:
* @GDK_GL_API_GL: The OpenGL API
* @GDK_GL_API_GLES: The OpenGL ES API
*
* The list of the different APIs that GdkGLContext can potentially support.
*
* Since: 4.6
*/
typedef enum { /*< underscore_name=GDK_GL_API >*/
GDK_GL_API_GL = 1 << 0,
GDK_GL_API_GLES = 1 << 1
} GdkGLAPI;
/* Currently, these are the same values numerically as in the
* X protocol. If you change that, gdksurface-x11.c/gdk_surface_set_geometry_hints()
* will need fixing.
+98 -95
View File
@@ -82,7 +82,6 @@
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
#include "gdkglversionprivate.h"
#include "gdkprivate.h"
@@ -100,13 +99,13 @@
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
typedef struct {
GdkGLVersion required;
GdkGLVersion gl_version;
int major;
int minor;
int gl_version;
guint has_khr_debug : 1;
guint use_khr_debug : 1;
guint has_half_float : 1;
guint has_sync : 1;
guint has_unpack_subimage : 1;
guint has_debug_output : 1;
guint extensions_checked : 1;
@@ -288,11 +287,8 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
EGLConfig egl_config;
EGLContext ctx;
EGLint context_attribs[N_EGL_ATTRS], i = 0, flags = 0;
gsize major_idx, minor_idx;
gboolean debug_bit, forward_bit;
GdkGLVersion version;
const GdkGLVersion* supported_versions;
gsize j;
int min_major, min_minor, major = 0, minor = 0;
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
@@ -300,7 +296,12 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
/* We will use the default version matching the context status
* unless the user requested a version which makes sense */
gdk_gl_context_get_matching_version (context, api, legacy, &version);
gdk_gl_context_get_matching_version (api, legacy,
display->have_egl_win32_libangle,
&min_major, &min_minor);
gdk_gl_context_get_clipped_version (context,
min_major, min_minor,
&major, &minor);
if (!eglBindAPI (gdk_api_to_egl_api (api)))
return 0;
@@ -331,9 +332,9 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
flags &= ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
major_idx = i++;
context_attribs[i++] = major;
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
minor_idx = i++;
context_attribs[i++] = minor;
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
context_attribs[i++] = flags;
@@ -342,33 +343,23 @@ gdk_gl_context_create_egl_context (GdkGLContext *context,
GDK_DISPLAY_DEBUG (display, OPENGL,
"Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version),
major, minor,
debug_bit ? "yes" : "no",
forward_bit ? "yes" : "no",
legacy ? "yes" : "no",
api == GDK_GL_API_GLES ? "yes" : "no");
supported_versions = gdk_gl_versions_get_for_api (api);
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
{
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
ctx = eglCreateContext (egl_display,
egl_config,
share ? share_priv->egl_context : EGL_NO_CONTEXT,
context_attribs);
if (ctx != NULL)
break;
}
ctx = eglCreateContext (egl_display,
egl_config,
share ? share_priv->egl_context : EGL_NO_CONTEXT,
context_attribs);
if (ctx == NULL)
return 0;
return 0;
GDK_DISPLAY_DEBUG (display, OPENGL, "Created EGL context[%p]", ctx);
priv->egl_context = ctx;
gdk_gl_context_set_version (context, &supported_versions[j]);
gdk_gl_context_set_is_legacy (context, legacy);
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
@@ -630,7 +621,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
glViewport (0, 0, ww, wh);
#ifdef HAVE_EGL
if (priv->egl_context && gdk_gl_context_check_version (context, NULL, "3.0"))
if (priv->egl_context && gdk_gl_context_check_version (context, 0, 0, 3, 0))
glDrawBuffers (1, (GLenum[1]) { gdk_gl_context_get_use_es (context) ? GL_BACK : GL_BACK_LEFT });
#endif
}
@@ -996,33 +987,45 @@ gdk_gl_context_get_forward_compatible (GdkGLContext *context)
}
void
gdk_gl_context_get_matching_version (GdkGLContext *context,
GdkGLAPI api,
gboolean legacy,
GdkGLVersion *out_version)
gdk_gl_context_get_matching_version (GdkGLAPI api,
gboolean legacy,
gboolean win32_libangle,
int *major,
int *minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
GdkGLVersion min_version;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
int maj, min;
if (api == GDK_GL_API_GL)
{
if (legacy)
min_version = GDK_GL_MIN_GL_LEGACY_VERSION;
{
maj = GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR;
min = GDK_GL_MIN_GL_LEGACY_VERSION_MINOR;
}
else
min_version = GDK_GL_MIN_GL_VERSION;
{
maj = GDK_GL_MIN_GL_VERSION_MAJOR;
min = GDK_GL_MIN_GL_VERSION_MINOR;
}
}
else
{
min_version = GDK_GL_MIN_GLES_VERSION;
if (win32_libangle)
{
maj = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR;
min = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR;
}
else
{
maj = GDK_GL_MIN_GLES_VERSION_MAJOR;
min = GDK_GL_MIN_GLES_VERSION_MINOR;
}
}
if (gdk_gl_version_greater_equal (&priv->required, &min_version))
*out_version = priv->required;
else
*out_version = min_version;
if (major != NULL)
*major = maj;
if (minor != NULL)
*minor = min;
}
/**
@@ -1051,17 +1054,22 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
g_return_if_fail (!gdk_gl_context_is_realized (context));
priv->required = GDK_GL_VERSION_INIT (major, minor);
priv->major = major;
priv->minor = minor;
}
gboolean
gdk_gl_context_check_gl_version (GdkGLContext *self,
const GdkGLVersion *required_gl,
const GdkGLVersion *required_gles)
gdk_gl_context_check_version (GdkGLContext *self,
int required_gl_major,
int required_gl_minor,
int required_gles_major,
int required_gles_minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
g_return_val_if_fail (required_gl_minor < 10, FALSE);
g_return_val_if_fail (required_gles_minor < 10, FALSE);
if (!gdk_gl_context_is_realized (self))
return FALSE;
@@ -1069,10 +1077,10 @@ gdk_gl_context_check_gl_version (GdkGLContext *self,
switch (priv->api)
{
case GDK_GL_API_GL:
return required_gl == NULL || gdk_gl_version_greater_equal (&priv->gl_version, required_gl);
return priv->gl_version >= required_gl_major * 10 + required_gl_minor;
case GDK_GL_API_GLES:
return required_gles == NULL || gdk_gl_version_greater_equal (&priv->gl_version, required_gles);
return priv->gl_version >= required_gles_major * 10 + required_gles_minor;
default:
g_return_val_if_reached (FALSE);
@@ -1103,9 +1111,33 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (major != NULL)
*major = gdk_gl_version_get_major (&priv->required);
*major = priv->major;
if (minor != NULL)
*minor = gdk_gl_version_get_minor (&priv->required);
*minor = priv->minor;
}
void
gdk_gl_context_get_clipped_version (GdkGLContext *context,
int min_major,
int min_minor,
int *major,
int *minor)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
int maj = min_major, min = min_minor;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (priv->major > maj || (priv->major == maj && priv->minor > min))
{
maj = priv->major;
min = priv->minor;
}
if (major != NULL)
*major = maj;
if (minor != NULL)
*minor = min;
}
/**
@@ -1142,15 +1174,6 @@ gdk_gl_context_is_legacy (GdkGLContext *context)
return priv->is_legacy;
}
void
gdk_gl_context_set_version (GdkGLContext *context,
const GdkGLVersion *version)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
priv->gl_version = *version;
}
void
gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy)
@@ -1486,23 +1509,11 @@ gdk_gl_context_realize (GdkGLContext *context,
priv->api = GDK_GL_CONTEXT_GET_CLASS (context)->realize (context, error);
if (priv->api)
{
g_assert (gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (0, 0)));
g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_API]);
}
g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_API]);
return priv->api;
}
void
gdk_gl_version_init_epoxy (GdkGLVersion *version)
{
int epoxy_version = epoxy_gl_version ();
*version = GDK_GL_VERSION_INIT (epoxy_version / 10, epoxy_version % 10);
}
static void
gdk_gl_context_check_extensions (GdkGLContext *context)
{
@@ -1516,6 +1527,8 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
if (priv->extensions_checked)
return;
priv->gl_version = epoxy_gl_version ();
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
epoxy_has_gl_extension ("GL_KHR_debug");
@@ -1541,7 +1554,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
if (priv->gl_version < 32)
priv->is_legacy = TRUE;
}
@@ -1551,13 +1564,9 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
glGetIntegerv (GL_MAX_LABEL_LENGTH, &priv->max_debug_label_length);
}
priv->has_half_float = gdk_gl_context_check_version (context, "3.0", "3.0") ||
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
epoxy_has_gl_extension ("OES_vertex_half_float");
priv->has_sync = gdk_gl_context_check_version (context, "3.2", "3.0") ||
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GK_APPLE_sync");
#ifdef G_ENABLE_DEBUG
{
int max_texture_size;
@@ -1569,17 +1578,15 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
"* Extensions checked:\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
" - half float: %s\n"
" - sync: %s",
" - OES_vertex_half_float: %s",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
priv->gl_version / 10, priv->gl_version % 10,
priv->is_legacy ? "legacy" : "core",
glGetString (GL_SHADING_LANGUAGE_VERSION),
max_texture_size,
priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "yes" : "no",
priv->has_half_float ? "yes" : "no",
priv->has_sync ? "yes" : "no");
priv->has_half_float ? "yes" : "no");
}
#endif
@@ -1701,6 +1708,10 @@ gdk_gl_context_get_shared_context (GdkGLContext *context)
* Retrieves the OpenGL version of the @context.
*
* The @context must be realized prior to calling this function.
*
* If the @context has never been made current, the version cannot
* be known and it will return 0 for both @major and @minor.
*
*/
void
gdk_gl_context_get_version (GdkGLContext *context,
@@ -1713,9 +1724,9 @@ gdk_gl_context_get_version (GdkGLContext *context,
g_return_if_fail (gdk_gl_context_is_realized (context));
if (major != NULL)
*major = gdk_gl_version_get_major (&priv->gl_version);
*major = priv->gl_version / 10;
if (minor != NULL)
*minor = gdk_gl_version_get_minor (&priv->gl_version);
*minor = priv->gl_version % 10;
}
/**
@@ -1807,14 +1818,6 @@ gdk_gl_context_has_vertex_half_float (GdkGLContext *self)
return priv->has_half_float;
}
gboolean
gdk_gl_context_has_sync (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->has_sync;
}
/* This is currently private! */
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
gboolean
+15 -2
View File
@@ -24,12 +24,25 @@
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkversionmacros.h>
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
/**
* GdkGLAPI:
* @GDK_GL_API_GL: The OpenGL API
* @GDK_GL_API_GLES: The OpenGL ES API
*
* The list of the different APIs that GdkGLContext can potentially support.
*
* Since: 4.6
*/
typedef enum { /*< underscore_name=GDK_GL_API >*/
GDK_GL_API_GL = 1 << 0,
GDK_GL_API_GLES = 1 << 1
} GdkGLAPI;
#define GDK_TYPE_GL_CONTEXT (gdk_gl_context_get_type ())
#define GDK_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContext))
#define GDK_IS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_GL_CONTEXT))
+44 -27
View File
@@ -22,10 +22,32 @@
#include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h"
#include "gdkglversionprivate.h"
G_BEGIN_DECLS
/* Version requirements for EGL contexts.
*
* If you add support for EGL to your backend, please require this.
*/
#define GDK_EGL_MIN_VERSION_MAJOR (1)
#define GDK_EGL_MIN_VERSION_MINOR (4)
/* Minimum OpenGL versions supported by GTK.
* Backends should make sure to never create a context of a previous version.
*
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
* OPENGL_PROFILE_MASK; OpenGL ES; and OpenGL ES win32 Angle implementation,
* respectively
*/
#define GDK_GL_MIN_GL_VERSION_MAJOR (3)
#define GDK_GL_MIN_GL_VERSION_MINOR (2)
#define GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR (3)
#define GDK_GL_MIN_GL_LEGACY_VERSION_MINOR (0)
#define GDK_GL_MIN_GLES_VERSION_MAJOR (2)
#define GDK_GL_MIN_GLES_VERSION_MINOR (0)
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR (3)
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR (0)
typedef enum {
GDK_GL_NONE = 0,
GDK_GL_EGL,
@@ -78,6 +100,7 @@ typedef struct {
} GdkGLContextProgram;
typedef struct {
guint vertex_array_object;
guint tmp_framebuffer;
guint tmp_vertex_buffer;
@@ -99,31 +122,27 @@ void gdk_gl_context_clear_current_if_surface (GdkSurface
GdkGLContext * gdk_gl_context_new (GdkDisplay *display,
GdkSurface *surface);
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
GdkGLAPI api,
GError **error);
void gdk_gl_context_set_version (GdkGLContext *context,
const GdkGLVersion *version);
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy);
gboolean gdk_gl_context_check_gl_version (GdkGLContext *context,
const GdkGLVersion *gl_version,
const GdkGLVersion *gles_version);
gboolean gdk_gl_context_is_api_allowed (GdkGLContext *self,
GdkGLAPI api,
GError **error);
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
gboolean is_legacy);
static inline gboolean
gdk_gl_context_check_version (GdkGLContext *context,
const char *gl_version,
const char *gles_version)
{
return gdk_gl_context_check_gl_version (context,
gl_version ? &GDK_GL_VERSION_STRING (gl_version) : NULL,
gles_version ? &GDK_GL_VERSION_STRING (gles_version) : NULL);
}
void gdk_gl_context_get_matching_version (GdkGLContext *context,
GdkGLAPI api,
gboolean legacy,
GdkGLVersion *out_version);
gboolean gdk_gl_context_check_version (GdkGLContext *context,
int required_gl_major,
int required_gl_minor,
int required_gles_major,
int required_gles_minor);
void gdk_gl_context_get_clipped_version (GdkGLContext *context,
int min_major,
int min_minor,
int *major,
int *minor);
void gdk_gl_context_get_matching_version (GdkGLAPI api,
gboolean legacy,
gboolean win32_libangle,
int *major,
int *minor);
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
void gdk_gl_context_push_debug_group (GdkGLContext *context,
@@ -148,8 +167,6 @@ gboolean gdk_gl_context_use_es_bgra (GdkGLContext
gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_sync (GdkGLContext *self) G_GNUC_PURE;
double gdk_gl_context_get_scale (GdkGLContext *self);
G_END_DECLS
+5 -65
View File
@@ -39,7 +39,6 @@ struct _GdkGLTexture {
GdkGLContext *context;
guint id;
gboolean has_mipmap;
gpointer sync;
GdkTexture *saved;
@@ -100,10 +99,6 @@ gdk_gl_texture_invoke_callback (gpointer data)
context = gdk_display_get_gl_context (gdk_gl_context_get_display (invoke->self->context));
gdk_gl_context_make_current (context);
if (invoke->self->sync && context != invoke->self->context)
glWaitSync (invoke->self->sync, 0, GL_TIMEOUT_IGNORED);
glBindTexture (GL_TEXTURE_2D, invoke->self->id);
invoke->func (invoke->self, context, invoke->data);
@@ -136,8 +131,6 @@ struct _Download
static gboolean
gdk_gl_texture_find_format (gboolean use_es,
guint gl_major,
guint gl_minor,
GLint gl_format,
GLint gl_type,
GdkMemoryFormat *out_format)
@@ -148,7 +141,7 @@ gdk_gl_texture_find_format (gboolean use_es,
{
GLenum q_internal_format, q_format, q_type;
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type))
if (!gdk_memory_format_gl_format (format, use_es, &q_internal_format, &q_format, &q_type))
continue;
if (q_format != gl_format || q_type != gl_type)
@@ -170,14 +163,12 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
gsize expected_stride;
Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type;
int major, minor;
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
gdk_gl_context_get_version (context, &major, &minor);
if (download->stride == expected_stride &&
!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (download->format, TRUE, major, minor, &gl_internal_format, &gl_format, &gl_type))
gdk_memory_format_gl_format (download->format, TRUE, &gl_internal_format, &gl_format, &gl_type))
{
glGetTexImage (GL_TEXTURE_2D,
0,
@@ -194,12 +185,11 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
glGenFramebuffers (1, &fbo);
glBindFramebuffer (GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->id, 0);
if (gdk_gl_context_check_version (context, "4.3", "3.1"))
if (gdk_gl_context_check_version (context, 4, 3, 3, 1))
{
gdk_gl_context_get_version (context, &major, &minor);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), major, minor, gl_read_format, gl_read_type, &actual_format))
if (!gdk_gl_texture_find_format (gdk_gl_context_get_use_es (context), gl_read_format, gl_read_type, &actual_format))
actual_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; /* pray */
}
else
@@ -301,12 +291,6 @@ gdk_gl_texture_has_mipmap (GdkGLTexture *self)
return self->has_mipmap;
}
gpointer
gdk_gl_texture_get_sync (GdkGLTexture *self)
{
return self->sync;
}
/**
* gdk_gl_texture_release:
* @self: a `GdkTexture` wrapping a GL texture
@@ -332,47 +316,6 @@ gdk_gl_texture_release (GdkGLTexture *self)
drop_gl_resources (self);
}
GdkTexture *
gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data)
{
GdkGLTexture *self;
GdkTexture *update_texture;
self = g_object_new (GDK_TYPE_GL_TEXTURE,
"width", gdk_gl_texture_builder_get_width (builder),
"height", gdk_gl_texture_builder_get_height (builder),
NULL);
self->context = g_object_ref (gdk_gl_texture_builder_get_context (builder));
self->id = gdk_gl_texture_builder_get_id (builder);
GDK_TEXTURE (self)->format = gdk_gl_texture_builder_get_format (builder);
self->has_mipmap = gdk_gl_texture_builder_get_has_mipmap (builder);
if (gdk_gl_context_has_sync (self->context))
self->sync = gdk_gl_texture_builder_get_sync (builder);
self->destroy = destroy;
self->data = data;
update_texture = gdk_gl_texture_builder_get_update_texture (builder);
if (update_texture)
{
cairo_region_t *update_region = gdk_gl_texture_builder_get_update_region (builder);
if (update_region)
{
update_region = cairo_region_copy (update_region);
cairo_region_intersect_rectangle (update_region,
&(cairo_rectangle_int_t) {
0, 0,
update_texture->width, update_texture->height
});
gdk_texture_set_diff (GDK_TEXTURE (self), update_texture, update_region);
}
}
return GDK_TEXTURE (self);
}
static void
gdk_gl_texture_determine_format (GdkGLTexture *self)
{
@@ -387,7 +330,7 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
if (context == NULL ||
!gdk_gl_context_is_shared (self->context, context) ||
/* ... or glGetTexLevelParameter() isn't supported */
!gdk_gl_context_check_version (context, NULL, "3.1"))
!gdk_gl_context_check_version (context, 0, 0, 3, 1))
{
texture->format = GDK_MEMORY_DEFAULT;
self->has_mipmap = FALSE;
@@ -515,9 +458,6 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
*
* Return value: (transfer full) (type GdkGLTexture): A newly-created
* `GdkTexture`
*
* Deprecated: 4.12: [class@Gdk.GLTextureBuilder] supercedes this function
* and provides extended functionality for creating GL textures.
*/
GdkTexture *
gdk_gl_texture_new (GdkGLContext *context,
+1 -1
View File
@@ -38,7 +38,7 @@ typedef struct _GdkGLTextureClass GdkGLTextureClass;
GDK_AVAILABLE_IN_ALL
GType gdk_gl_texture_get_type (void) G_GNUC_CONST;
GDK_DEPRECATED_IN_4_12_FOR(GdkGLTextureBuilder)
GDK_AVAILABLE_IN_ALL
GdkTexture * gdk_gl_texture_new (GdkGLContext *context,
guint id,
int width,
-802
View File
@@ -1,802 +0,0 @@
/*
* Copyright © 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gdkgltexturebuilder.h"
#include "gdkenumtypes.h"
#include "gdkglcontext.h"
#include "gdkgltextureprivate.h"
#include <cairo-gobject.h>
struct _GdkGLTextureBuilder
{
GObject parent_instance;
GdkGLContext *context;
guint id;
int width;
int height;
GdkMemoryFormat format;
gboolean has_mipmap;
gpointer sync;
GdkTexture *update_texture;
cairo_region_t *update_region;
};
struct _GdkGLTextureBuilderClass
{
GObjectClass parent_class;
};
/**
* GdkGLTextureBuilder:
*
* `GdkGLTextureBuilder` is a buider used to construct [class@Gdk.Texture] objects from
* GL textures.
*
* The operation is quite simple: Create a texture builder, set all the necessary
* properties - keep in mind that the properties [property@Gdk.GLTextureBuilder:context],
* [property@Gdk.GLTextureBuilder:id], [property@Gdk.GLTextureBuilder:width], and
* [property@Gdk.GLTextureBuilder:height] are mandatory - and then call
* [method@Gdk.GLTextureBuilder.build] to create the new texture.
*
* `GdkGLTextureBuilder` can be used for quick one-shot construction of
* textures as well as kept around and reused to construct multiple textures.
*
* Since: 4.12
*/
enum
{
PROP_0,
PROP_CONTEXT,
PROP_FORMAT,
PROP_HAS_MIPMAP,
PROP_HEIGHT,
PROP_ID,
PROP_SYNC,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
PROP_WIDTH,
N_PROPS
};
G_DEFINE_TYPE (GdkGLTextureBuilder, gdk_gl_texture_builder, G_TYPE_OBJECT)
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gdk_gl_texture_builder_dispose (GObject *object)
{
GdkGLTextureBuilder *self = GDK_GL_TEXTURE_BUILDER (object);
g_clear_object (&self->context);
g_clear_object (&self->update_texture);
g_clear_pointer (&self->update_region, cairo_region_destroy);
G_OBJECT_CLASS (gdk_gl_texture_builder_parent_class)->dispose (object);
}
static void
gdk_gl_texture_builder_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GdkGLTextureBuilder *self = GDK_GL_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_CONTEXT:
g_value_set_object (value, self->context);
break;
case PROP_FORMAT:
g_value_set_enum (value, self->format);
break;
case PROP_HAS_MIPMAP:
g_value_set_boolean (value, self->has_mipmap);
break;
case PROP_HEIGHT:
g_value_set_int (value, self->height);
break;
case PROP_ID:
g_value_set_uint (value, self->id);
break;
case PROP_SYNC:
g_value_set_pointer (value, self->sync);
break;
case PROP_UPDATE_REGION:
g_value_set_boxed (value, self->update_region);
break;
case PROP_UPDATE_TEXTURE:
g_value_set_object (value, self->update_texture);
break;
case PROP_WIDTH:
g_value_set_int (value, self->width);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_gl_texture_builder_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GdkGLTextureBuilder *self = GDK_GL_TEXTURE_BUILDER (object);
switch (property_id)
{
case PROP_CONTEXT:
gdk_gl_texture_builder_set_context (self, g_value_get_object (value));
break;
case PROP_FORMAT:
gdk_gl_texture_builder_set_format (self, g_value_get_enum (value));
break;
case PROP_HAS_MIPMAP:
gdk_gl_texture_builder_set_has_mipmap (self, g_value_get_boolean (value));
break;
case PROP_HEIGHT:
gdk_gl_texture_builder_set_height (self, g_value_get_int (value));
break;
case PROP_ID:
gdk_gl_texture_builder_set_id (self, g_value_get_uint (value));
break;
case PROP_SYNC:
gdk_gl_texture_builder_set_sync (self, g_value_get_pointer (value));
break;
case PROP_UPDATE_REGION:
gdk_gl_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
case PROP_UPDATE_TEXTURE:
gdk_gl_texture_builder_set_update_texture (self, g_value_get_object (value));
break;
case PROP_WIDTH:
gdk_gl_texture_builder_set_width (self, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = gdk_gl_texture_builder_dispose;
gobject_class->get_property = gdk_gl_texture_builder_get_property;
gobject_class->set_property = gdk_gl_texture_builder_set_property;
/**
* GdkGLTextureBuilder:context: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_context org.gdk.Property.set=gdk_gl_texture_builder_set_context)
*
* The context owning the texture.
*
* Since: 4.12
*/
properties[PROP_CONTEXT] =
g_param_spec_object ("context", NULL, NULL,
GDK_TYPE_GL_CONTEXT,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:format: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_format org.gdk.Property.set=gdk_gl_texture_builder_set_format)
*
* The format when downloading the texture.
*
* Since: 4.12
*/
properties[PROP_FORMAT] =
g_param_spec_enum ("format", NULL, NULL,
GDK_TYPE_MEMORY_FORMAT,
GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:has-mipmap: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gdk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
*
* If the texture has a mipmap.
*
* Since: 4.12
*/
properties[PROP_HAS_MIPMAP] =
g_param_spec_boolean ("has-mipmap", NULL, NULL,
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:height: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_height org.gdk.Property.set=gdk_gl_texture_builder_set_height)
*
* The height of the texture.
*
* Since: 4.12
*/
properties[PROP_HEIGHT] =
g_param_spec_int ("height", NULL, NULL,
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:id: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_id org.gdk.Property.set=gdk_gl_texture_builder_set_id)
*
* The texture ID to use.
*
* Since: 4.12
*/
properties[PROP_ID] =
g_param_spec_uint ("id", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:sync: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_sync org.gdk.Property.set=gdk_gl_texture_builder_set_sync)
*
* An optional `GLSync` object.
*
* If this is set, GTK will wait on it before using the texture.
*
* Since: 4.12
*/
properties[PROP_SYNC] =
g_param_spec_pointer ("sync", NULL, NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_region org.gdk.Property.set=gdk_gl_texture_builder_set_update_region)
*
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
*
* Since: 4.12
*/
properties[PROP_UPDATE_REGION] =
g_param_spec_boxed ("update-region", NULL, NULL,
CAIRO_GOBJECT_TYPE_REGION,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_texture org.gdk.Property.set=gdk_gl_texture_builder_set_update_texture)
*
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
*
* Since: 4.12
*/
properties[PROP_UPDATE_TEXTURE] =
g_param_spec_object ("update-texture", NULL, NULL,
GDK_TYPE_TEXTURE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkGLTextureBuilder:width: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_width org.gdk.Property.set=gdk_gl_texture_builder_set_width)
*
* The width of the texture.
*
* Since: 4.12
*/
properties[PROP_WIDTH] =
g_param_spec_int ("width", NULL, NULL,
G_MININT, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gdk_gl_texture_builder_init (GdkGLTextureBuilder *self)
{
self->format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
/**
* gdk_gl_texture_builder_new: (constructor):
*
* Creates a new texture builder.
*
* Returns: the new `GdkTextureBuilder`
*
* Since: 4.12
**/
GdkGLTextureBuilder *
gdk_gl_texture_builder_new (void)
{
return g_object_new (GDK_TYPE_GL_TEXTURE_BUILDER, NULL);
}
/**
* gdk_gl_texture_builder_get_context: (attributes org.gdk.Method.get_property=context)
* @self: a `GdkGLTextureBuilder`
*
* Gets the context previously set via gdk_gl_texture_builder_set_context() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The context
*
* Since: 4.12
*/
GdkGLContext *
gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->context;
}
/**
* gdk_gl_texture_builder_set_context: (attributes org.gdk.Method.set_property=context)
* @self: a `GdkGLTextureBuilder`
* @context: (nullable): The context the texture beongs to or %NULL to unset
*
* Sets the context to be used for the texture. This is the context that owns
* the texture.
*
* The context must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
GdkGLContext *context)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
g_return_if_fail (context == NULL || GDK_IS_GL_CONTEXT (context));
if (!g_set_object (&self->context, context))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CONTEXT]);
}
/**
* gdk_gl_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
* @self: a `GdkGLTextureBuilder`
*
* Gets the height previously set via gdk_gl_texture_builder_set_height() or
* 0 if the height wasn't set.
*
* Returns: The height
*
* Since: 4.12
*/
int
gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), 0);
return self->height;
}
/**
* gdk_gl_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
* @self: a `GdkGLTextureBuilder`
* @height: The texture's height or 0 to unset
*
* Sets the height of the texture.
*
* The height must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
int height)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->height == height)
return;
self->height = height;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEIGHT]);
}
/**
* gdk_gl_texture_builder_get_id: (attributes org.gdk.Method.get_property=id)
* @self: a `GdkGLTextureBuilder`
*
* Gets the texture id previously set via gdk_gl_texture_builder_set_id() or
* 0 if the id wasn't set.
*
* Returns: The id
*
* Since: 4.12
*/
guint
gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), 0);
return self->id;
}
/**
* gdk_gl_texture_builder_set_id: (attributes org.gdk.Method.set_property=id)
* @self: a `GdkGLTextureBuilder`
* @id: The texture id to be used for creating the texture
*
* Sets the texture id of the texture. The texture id must remain unmodified
* until the texture was finalized. See [method@Gdk.GLTextureBuilder.build]
* for a longer discussion.
*
* The id must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
guint id)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->id == id)
return;
self->id = id;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ID]);
}
/**
* gdk_gl_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
* @self: a `GdkGLTextureBuilder`
*
* Gets the width previously set via gdk_gl_texture_builder_set_width() or
* 0 if the width wasn't set.
*
* Returns: The width
*
* Since: 4.12
*/
int
gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), 0);
return self->width;
}
/**
* gdk_gl_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
* @self: a `GdkGLTextureBuilder`
* @width: The texture's width or 0 to unset
*
* Sets the width of the texture.
*
* The width must be set before calling [method@Gdk.GLTextureBuilder.build].
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
int width)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->width == width)
return;
self->width = width;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_WIDTH]);
}
/**
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gdk.Method.get_property=has-mipmap)
* @self: a `GdkGLTextureBuilder`
*
* Gets whether the texture has a mipmap.
*
* Returns: Whether the texture has a mipmap
*
* Since: 4.12
*/
gboolean
gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), FALSE);
return self->has_mipmap;
}
/**
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gdk.Method.set_property=has-mipmap)
* @self: a `GdkGLTextureBuilder`
* @has_mipmap: Whether the texture has a mipmap
*
* Sets whether the texture has a mipmap. This allows the renderer and other users of the
* generated texture to use a higher quality downscaling.
*
* Typically, the `glGenerateMipmap` function is used to generate a mimap.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
gboolean has_mipmap)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->has_mipmap == has_mipmap)
return;
self->has_mipmap = has_mipmap;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_MIPMAP]);
}
/**
* gdk_gl_texture_builder_get_sync: (attributes org.gdk.Method.get_property=sync)
* @self: a `GdkGLTextureBuilder`
*
* Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
*
* Returns: (nullable): the `GLSync`
*
* Since: 4.12
*/
gpointer
gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->sync;
}
/**
* gdk_gl_texture_builder_set_sync: (attributes org.gdk.Method.set_property=sync)
* @self: a `GdkGLTextureBuilder`
* @sync: (nullable): the GLSync object
*
* Sets the GLSync object to use for the texture.
*
* GTK will wait on this object before using the created `GdkTexture`.
*
* The `destroy` function that is passed to [method@Gdk.GLTextureBuilder.build]
* is responsible for freeing the sync object when it is no longer needed.
* The texture builder does not destroy it and it is the callers
* responsibility to make sure it doesn't leak.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
gpointer sync)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->sync == sync)
return;
self->sync = sync;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SYNC]);
}
/**
* gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
* @self: a `GdkGLTextureBuilder`
*
* Gets the format previously set via gdk_gl_texture_builder_set_format().
*
* Returns: The format
*
* Since: 4.12
*/
GdkMemoryFormat
gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), GDK_MEMORY_R8G8B8A8_PREMULTIPLIED);
return self->format;
}
/**
* gdk_gl_texture_builder_set_format: (attributes org.gdk.Method.set_property=format)
* @self: a `GdkGLTextureBuilder`
* @format: The texture's format
*
* Sets the format of the texture. The default is `GDK_MEMORY_R8G8B8A8_PREMULTIPLIED`.
*
* The format is the preferred format the texture data should be downloaded to. The
* format must be supported by the GL version of [property@Gdk.GLTextureBuilder:context].
*
* Setting the right format is particularly useful when using high bit depth textures
* to preserve the bit depth, to set the correct value for unpremultiplied textures
* and to make sure opaque textures are treated as such.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
GdkMemoryFormat format)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->format == format)
return;
self->format = format;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FORMAT]);
}
/**
* gdk_gl_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
* @self: a `GdkGLTextureBuilder`
*
* Gets the texture previously set via gdk_gl_texture_builder_set_update_texture() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The texture
*
* Since: 4.12
*/
GdkTexture *
gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->update_texture;
}
/**
* gdk_gl_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
* @self: a `GdkGLTextureBuilder`
* @texture: (nullable): the texture to update
*
* Sets the texture to be updated by this texture. See
* [method@Gdk.GLTextureBuilder.set_update_region] for an explanation.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
GdkTexture *texture)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture));
if (!g_set_object (&self->update_texture, texture))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_TEXTURE]);
}
/**
* gdk_gl_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
* @self: a `GdkGLTextureBuilder`
*
* Gets the region previously set via gdk_gl_texture_builder_set_update_region() or
* %NULL if none was set.
*
* Returns: (transfer none) (nullable): The region
*
* Since: 4.12
*/
cairo_region_t *
gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
return self->update_region;
}
/**
* gdk_gl_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
* @self: a `GdkGLTextureBuilder`
* @region: (nullable): the region to update
*
* Sets the region to be updated by this texture. Together with
* [property@Gdk.GLTextureBuilder:update-texture] this describes an
* update of a previous texture.
*
* When rendering animations of large textures, it is possible that
* consecutive textures are only updating contents in parts of the texture.
* It is then possible to describe this update via these two properties,
* so that GTK can avoid rerendering parts that did not change.
*
* An example would be a screen recording where only the mouse pointer moves.
*
* Since: 4.12
*/
void
gdk_gl_texture_builder_set_update_region (GdkGLTextureBuilder *self,
cairo_region_t *region)
{
g_return_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self));
if (self->update_region == region)
return;
g_clear_pointer (&self->update_region, cairo_region_destroy);
if (region)
self->update_region = cairo_region_reference (region);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UPDATE_REGION]);
}
/**
* gdk_gl_texture_builder_build:
* @self: a `GdkGLTextureBuilder`
* @destroy: (nullable): destroy function to be called when the texture is
* released
* @data: user data to pass to the destroy function
*
* Builds a new `GdkTexture` with the values set up in the builder.
*
* The `destroy` function gets called when the returned texture gets released;
* either when the texture is finalized or by an explicit call to
* [method@Gdk.GLTexture.release]. It should release all GL resources associated
* with the texture, such as the [property@Gdk.GLTextureBuilder:id] and the
* [property@Gdk.GLTextureBuilder:sync].
*
* Note that it is a programming error to call this function if any mandatory
* property has not been set.
*
* It is possible to call this function multiple times to create multiple textures,
* possibly with changing properties in between.
*
* Returns: (transfer full): a newly built `GdkTexture`
*
* Since: 4.12
*/
GdkTexture *
gdk_gl_texture_builder_build (GdkGLTextureBuilder *self,
GDestroyNotify destroy,
gpointer data)
{
g_return_val_if_fail (GDK_IS_GL_TEXTURE_BUILDER (self), NULL);
g_return_val_if_fail (destroy == NULL || data != NULL, NULL);
g_return_val_if_fail (self->context != NULL, NULL);
g_return_val_if_fail (self->id != 0, NULL);
g_return_val_if_fail (self->width > 0, NULL);
g_return_val_if_fail (self->height > 0, NULL);
return gdk_gl_texture_new_from_builder (self, destroy, data);
}
-99
View File
@@ -1,99 +0,0 @@
/*
* Copyright © 2023 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdkenums.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkversionmacros.h>
G_BEGIN_DECLS
#define GDK_TYPE_GL_TEXTURE_BUILDER (gdk_gl_texture_builder_get_type ())
GDK_AVAILABLE_IN_4_12
GDK_DECLARE_INTERNAL_TYPE (GdkGLTextureBuilder, gdk_gl_texture_builder, GDK, GL_TEXTURE_BUILDER, GObject)
GDK_AVAILABLE_IN_4_12
GdkGLTextureBuilder * gdk_gl_texture_builder_new (void);
GDK_AVAILABLE_IN_4_12
GdkGLContext * gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
GdkGLContext *context);
GDK_AVAILABLE_IN_4_12
guint gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
guint id);
GDK_AVAILABLE_IN_4_12
int gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
int width);
GDK_AVAILABLE_IN_4_12
int gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
int height);
GDK_AVAILABLE_IN_4_12
GdkMemoryFormat gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
GdkMemoryFormat format);
GDK_AVAILABLE_IN_4_12
gboolean gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
gboolean has_mipmap);
GDK_AVAILABLE_IN_4_12
gpointer gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
gpointer sync);
GDK_AVAILABLE_IN_4_12
GdkTexture * gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
GdkTexture *texture);
GDK_AVAILABLE_IN_4_12
cairo_region_t * gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_12
void gdk_gl_texture_builder_set_update_region (GdkGLTextureBuilder *self,
cairo_region_t *region);
GDK_AVAILABLE_IN_4_12
GdkTexture * gdk_gl_texture_builder_build (GdkGLTextureBuilder *self,
GDestroyNotify destroy,
gpointer data);
G_END_DECLS
-7
View File
@@ -2,20 +2,13 @@
#include "gdkgltexture.h"
#include "gdkgltexturebuilder.h"
#include "gdktextureprivate.h"
G_BEGIN_DECLS
GdkTexture * gdk_gl_texture_new_from_builder (GdkGLTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data);
GdkGLContext * gdk_gl_texture_get_context (GdkGLTexture *self);
guint gdk_gl_texture_get_id (GdkGLTexture *self);
gboolean gdk_gl_texture_has_mipmap (GdkGLTexture *self);
gpointer gdk_gl_texture_get_sync (GdkGLTexture *self);
G_END_DECLS
-138
View File
@@ -1,138 +0,0 @@
/* GDK - The GIMP Drawing Kit
*
* gdkglcontextprivate.h: GL context abstraction
*
* Copyright © 2014 Emmanuele Bassi
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gdkenums.h>
G_BEGIN_DECLS
/* Version requirements for EGL contexts.
*
* If you add support for EGL to your backend, please require this.
*/
#define GDK_EGL_MIN_VERSION_MAJOR (1)
#define GDK_EGL_MIN_VERSION_MINOR (4)
/* Minimum OpenGL versions supported by GTK.
* Backends should make sure to never create a context of a previous version.
*
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
* OPENGL_PROFILE_MASK; and OpenGL ES respectively
*/
#define GDK_GL_MIN_GL_VERSION GDK_GL_VERSION_INIT (3, 2)
#define GDK_GL_MIN_GL_LEGACY_VERSION GDK_GL_VERSION_INIT (3, 0)
#define GDK_GL_MIN_GLES_VERSION GDK_GL_VERSION_INIT (2, 0)
typedef struct _GdkGLVersion GdkGLVersion;
struct _GdkGLVersion
{
int major;
int minor;
};
#define GDK_GL_VERSION_INIT(maj,min) { maj, min }
static const GdkGLVersion supported_gl_versions[] = {
GDK_GL_VERSION_INIT (4, 6),
GDK_GL_VERSION_INIT (4, 5),
GDK_GL_VERSION_INIT (4, 4),
GDK_GL_VERSION_INIT (4, 3),
GDK_GL_VERSION_INIT (4, 2),
GDK_GL_VERSION_INIT (4, 1),
GDK_GL_VERSION_INIT (4, 0),
GDK_GL_VERSION_INIT (3, 3),
GDK_GL_VERSION_INIT (3, 2),
GDK_GL_VERSION_INIT (3, 1),
GDK_GL_VERSION_INIT (3, 0),
GDK_GL_VERSION_INIT (0, 0)
};
static const GdkGLVersion supported_gles_versions[] = {
GDK_GL_VERSION_INIT (3, 2),
GDK_GL_VERSION_INIT (3, 1),
GDK_GL_VERSION_INIT (3, 0),
GDK_GL_VERSION_INIT (2, 0),
GDK_GL_VERSION_INIT (0, 0)
};
#undef GDK_GL_VERSION_INIT
#define GDK_GL_VERSION_INIT(maj,min) (GdkGLVersion) { maj, min }
#define GDK_GL_VERSION_STRING(str) GDK_GL_VERSION_INIT(str[0] - '0', str[2] - '0')
static inline const GdkGLVersion *
gdk_gl_versions_get_for_api (GdkGLAPI api)
{
switch (api)
{
case GDK_GL_API_GL:
return supported_gl_versions;
case GDK_GL_API_GLES:
return supported_gles_versions;
default:
g_assert_not_reached ();
return NULL;
}
}
static inline int
gdk_gl_version_get_major (const GdkGLVersion *self)
{
return self->major;
}
static inline int
gdk_gl_version_get_minor (const GdkGLVersion *self)
{
return self->minor;
}
static inline int
gdk_gl_version_compare (const GdkGLVersion *a,
const GdkGLVersion *b)
{
if (a->major > b->major)
return 1;
if (a->major < b->major)
return -1;
if (a->minor > b->minor)
return 1;
if (a->minor < b->minor)
return -1;
return 0;
}
static inline gboolean
gdk_gl_version_greater_equal (const GdkGLVersion *a,
const GdkGLVersion *b)
{
return gdk_gl_version_compare (a, b) >= 0;
}
/* in gdkglcontext.c */
void gdk_gl_version_init_epoxy (GdkGLVersion *version);
G_END_DECLS
+21 -40
View File
@@ -220,12 +220,7 @@ struct _GdkMemoryFormatDescription
gsize bytes_per_pixel;
gsize alignment;
gboolean prefers_high_depth;
struct {
guint gl_major;
guint gl_minor;
guint gles_major;
guint gles_minor;
} min_gl_version;
gboolean supports_gles;
struct {
guint internal_format;
guint format;
@@ -250,7 +245,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
FALSE,
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
b8g8r8a8_premultiplied_to_float,
b8g8r8a8_premultiplied_from_float,
@@ -260,7 +255,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
FALSE,
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
a8r8g8b8_premultiplied_to_float,
a8r8g8b8_premultiplied_from_float,
@@ -270,7 +265,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, 0, 0 },
TRUE,
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
r8g8b8a8_premultiplied_to_float,
r8g8b8a8_premultiplied_from_float,
@@ -280,7 +275,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
FALSE,
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE },
b8g8r8a8_to_float,
b8g8r8a8_from_float,
@@ -290,7 +285,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
FALSE,
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
a8r8g8b8_to_float,
a8r8g8b8_from_float,
@@ -300,7 +295,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, 0, 0 },
TRUE,
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE },
r8g8b8a8_to_float,
r8g8b8a8_from_float,
@@ -310,7 +305,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
4,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
FALSE,
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED },
a8b8g8r8_to_float,
a8b8g8r8_from_float,
@@ -320,7 +315,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
3,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, 0, 0 },
TRUE,
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE },
r8g8b8_to_float,
r8g8b8_from_float,
@@ -330,7 +325,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
3,
G_ALIGNOF (guchar),
FALSE,
{ 0, 0, G_MAXUINT, G_MAXUINT },
FALSE,
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE },
b8g8r8_to_float,
b8g8r8_from_float,
@@ -340,7 +335,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
6,
G_ALIGNOF (guint16),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT },
r16g16b16_to_float,
r16g16b16_from_float,
@@ -350,7 +345,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
r16g16b16a16_to_float,
r16g16b16a16_from_float,
@@ -360,7 +355,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT },
r16g16b16a16_to_float,
r16g16b16a16_from_float,
@@ -370,7 +365,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
6,
G_ALIGNOF (guint16),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT },
r16g16b16_float_to_float,
r16g16b16_float_from_float,
@@ -380,7 +375,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
r16g16b16a16_float_to_float,
r16g16b16a16_float_from_float,
@@ -390,7 +385,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
8,
G_ALIGNOF (guint16),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT },
r16g16b16a16_float_to_float,
r16g16b16a16_float_from_float,
@@ -400,7 +395,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
12,
G_ALIGNOF (float),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGB32F, GL_RGB, GL_FLOAT },
r32g32b32_float_to_float,
r32g32b32_float_from_float,
@@ -410,7 +405,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
16,
G_ALIGNOF (float),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
r32g32b32a32_float_to_float,
r32g32b32a32_float_from_float,
@@ -420,7 +415,7 @@ static const GdkMemoryFormatDescription memory_formats[GDK_MEMORY_N_FORMATS] = {
16,
G_ALIGNOF (float),
TRUE,
{ 0, 0, 3, 0 },
TRUE,
{ GL_RGBA32F, GL_RGBA, GL_FLOAT },
r32g32b32a32_float_to_float,
r32g32b32a32_float_from_float,
@@ -468,8 +463,6 @@ gdk_memory_format_prefers_high_depth (GdkMemoryFormat format)
gboolean
gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type)
@@ -481,20 +474,8 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
if (memory_formats[format].alpha == GDK_MEMORY_ALPHA_STRAIGHT)
return FALSE;
if (gles)
{
if (memory_formats[format].min_gl_version.gles_major > gl_major ||
(memory_formats[format].min_gl_version.gles_major == gl_major &&
memory_formats[format].min_gl_version.gles_minor > gl_minor))
return FALSE;
}
else
{
if (memory_formats[format].min_gl_version.gl_major > gl_major ||
(memory_formats[format].min_gl_version.gl_major == gl_major &&
memory_formats[format].min_gl_version.gl_minor > gl_minor))
return FALSE;
}
if (gles && !memory_formats[format].supports_gles)
return FALSE;
return TRUE;
}
-2
View File
@@ -35,8 +35,6 @@ gsize gdk_memory_format_bytes_per_pixel (GdkMemoryFormat
gboolean gdk_memory_format_prefers_high_depth(GdkMemoryFormat format) G_GNUC_CONST;
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type);
-57
View File
@@ -1,57 +0,0 @@
#pragma once
#include "gdkrectangle.h"
#include <math.h>
G_BEGIN_DECLS
/*
* gdk_rectangle_transform_affine:
* @src: the rectangle to transform
* @scale_x: scale factor in the X direction. The scale factor
* may be negative or 0.
* @scale_y: scale factor in the Y direction. The scale factor
* may be negative or 0.
* @offset_x: offset of result in X direction.
* @offset_y: offset of result in Y direction.
* @dest: (out caller-allocates): destination rectangle, may be
* identical to @src
*
* Does an affine transform of the source rectangle and stores the
* result in the dest rectangle. If the destination rectangle does
* not fit on integer bounds, the result will be enlarged to make it
* fit.
* (Fun fact: This means with a scale of 0 and an offset of 0.5,
* the resulting rect will have a width of 1.)
*
* The width and height of the result will be positive, even if the
* src rectangle or the scale were negative.
*
* This function can be used with the output of
* gsk_transform_to_affine().
**/
static inline void
gdk_rectangle_transform_affine (const GdkRectangle *src,
float scale_x,
float scale_y,
float offset_x,
float offset_y,
GdkRectangle *dest)
{
float x1, x2, y1, y2;
x1 = offset_x + src->x * scale_x;
x2 = offset_x + (src->x + src->width) * scale_x;
y1 = offset_y + src->y * scale_y;
y2 = offset_y + (src->y + src->height) * scale_y;
dest->x = floorf (MIN (x1, x2));
dest->y = floorf (MIN (y1, y2));
dest->width = ceilf (MAX (x1, x2)) - dest->x;
dest->height = ceilf (MAX (y1, y2)) - dest->y;
}
G_END_DECLS
+113 -39
View File
@@ -115,6 +115,9 @@ static void gdk_surface_get_property (GObject *object,
static void update_cursor (GdkDisplay *display,
GdkDevice *device);
static void gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock);
static void gdk_surface_queue_set_is_mapped (GdkSurface *surface,
gboolean is_mapped);
@@ -493,22 +496,11 @@ gdk_surface_real_get_scale (GdkSurface *surface)
return 1.0;
}
static void
gdk_surface_constructed (GObject *object)
{
G_GNUC_UNUSED GdkSurface *surface = GDK_SURFACE (object);
g_assert (surface->frame_clock != NULL);
G_OBJECT_CLASS (gdk_surface_parent_class)->constructed (object);
}
static void
gdk_surface_class_init (GdkSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gdk_surface_constructed;
object_class->finalize = gdk_surface_finalize;
object_class->set_property = gdk_surface_set_property;
object_class->get_property = gdk_surface_get_property;
@@ -853,6 +845,21 @@ _gdk_surface_update_size (GdkSurface *surface)
g_object_notify (G_OBJECT (surface), "height");
}
static GdkSurface *
gdk_surface_new (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
return gdk_display_create_surface (display,
surface_type,
parent,
x, y, width, height);
}
/**
* gdk_surface_new_toplevel: (constructor)
* @display: the display to create the surface on
@@ -866,9 +873,8 @@ gdk_surface_new_toplevel (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return g_object_new (GDK_DISPLAY_GET_CLASS (display)->toplevel_type,
"display", display,
NULL);
return gdk_surface_new (display, GDK_SURFACE_TOPLEVEL,
NULL, 0, 0, 1, 1);
}
/**
@@ -888,16 +894,11 @@ gdk_surface_new_popup (GdkSurface *parent,
gboolean autohide)
{
GdkSurface *surface;
GdkDisplay *display;
g_return_val_if_fail (GDK_IS_SURFACE (parent), NULL);
display = gdk_surface_get_display (parent);
surface = g_object_new (GDK_DISPLAY_GET_CLASS (display)->popup_type,
"display", display,
"parent", parent,
NULL);
surface = gdk_surface_new (parent->display, GDK_SURFACE_POPUP,
parent, 0, 0, 100, 100);
surface->autohide = autohide;
@@ -1269,6 +1270,40 @@ gdk_surface_create_vulkan_context (GdkSurface *surface,
NULL);
}
/* Code for dirty-region queueing
*/
static GSList *update_surfaces = NULL;
static void
gdk_surface_add_update_surface (GdkSurface *surface)
{
GSList *tmp;
/* Check whether "surface" is already in "update_surfaces" list.
* It could be added during execution of gtk_widget_destroy() when
* setting focus widget to NULL and redrawing old focus widget.
* See bug 711552.
*/
tmp = g_slist_find (update_surfaces, surface);
if (tmp != NULL)
return;
update_surfaces = g_slist_prepend (update_surfaces, g_object_ref (surface));
}
static void
gdk_surface_remove_update_surface (GdkSurface *surface)
{
GSList *link;
link = g_slist_find (update_surfaces, surface);
if (link != NULL)
{
update_surfaces = g_slist_delete_link (update_surfaces, link);
g_object_unref (surface);
}
}
static gboolean
gdk_surface_is_toplevel_frozen (GdkSurface *surface)
{
@@ -1297,6 +1332,46 @@ gdk_surface_schedule_update (GdkSurface *surface)
GDK_FRAME_CLOCK_PHASE_PAINT);
}
static void
gdk_surface_process_updates_internal (GdkSurface *surface)
{
/* Ensure the surface lives while updating it */
g_object_ref (surface);
surface->in_update = TRUE;
/* If an update got queued during update processing, we can get a
* surface in the update queue that has an empty update_area.
* just ignore it.
*/
if (surface->update_area)
{
g_assert (surface->active_update_area == NULL); /* No reentrancy */
surface->active_update_area = surface->update_area;
surface->update_area = NULL;
if (GDK_SURFACE_IS_MAPPED (surface))
{
cairo_region_t *expose_region;
gboolean handled;
expose_region = cairo_region_copy (surface->active_update_area);
g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
cairo_region_destroy (expose_region);
}
cairo_region_destroy (surface->active_update_area);
surface->active_update_area = NULL;
}
surface->in_update = FALSE;
g_object_unref (surface);
}
static void
gdk_surface_layout_on_clock (GdkFrameClock *clock,
void *data)
@@ -1354,32 +1429,28 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
void *data)
{
GdkSurface *surface = GDK_SURFACE (data);
cairo_region_t *expose_region;
g_return_if_fail (GDK_IS_SURFACE (surface));
if (GDK_SURFACE_DESTROYED (surface) ||
!surface->update_area ||
surface->update_freeze_count ||
gdk_surface_is_toplevel_frozen (surface))
if (GDK_SURFACE_DESTROYED (surface))
return;
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
expose_region = surface->update_area;
surface->update_area = NULL;
g_object_ref (surface);
if (GDK_SURFACE_IS_MAPPED (surface))
if (surface->update_area &&
!surface->update_freeze_count &&
!gdk_surface_is_toplevel_frozen (surface) &&
/* Don't recurse into process_updates_internal, we'll
* do the update later when idle instead. */
!surface->in_update)
{
gboolean handled;
g_object_ref (surface);
g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
g_object_unref (surface);
surface->pending_phases &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
gdk_surface_process_updates_internal (surface);
gdk_surface_remove_update_surface (surface);
}
cairo_region_destroy (expose_region);
g_object_unref (surface);
}
/*
@@ -1427,6 +1498,7 @@ impl_surface_add_update_area (GdkSurface *impl_surface,
cairo_region_union (impl_surface->update_area, region);
else
{
gdk_surface_add_update_surface (impl_surface);
impl_surface->update_area = cairo_region_copy (region);
gdk_surface_schedule_update (impl_surface);
}
@@ -1510,6 +1582,8 @@ _gdk_surface_clear_update_area (GdkSurface *surface)
if (surface->update_area)
{
gdk_surface_remove_update_surface (surface);
cairo_region_destroy (surface->update_area);
surface->update_area = NULL;
}
@@ -2456,7 +2530,7 @@ gdk_surface_resume_events (GdkFrameClock *clock,
}
}
void
static void
gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock)
{
+14 -2
View File
@@ -26,6 +26,13 @@
G_BEGIN_DECLS
typedef enum
{
GDK_SURFACE_TOPLEVEL,
GDK_SURFACE_POPUP,
GDK_SURFACE_DRAG
} GdkSurfaceType;
struct _GdkSurface
{
GObject parent_instance;
@@ -48,6 +55,10 @@ struct _GdkSurface
cairo_region_t *update_area;
guint update_freeze_count;
GdkFrameClockPhase pending_phases;
/* This is the update_area that was in effect when the current expose
started. It may be smaller than the expose area if we'e painting
more than we have to, but it represents the "true" damage. */
cairo_region_t *active_update_area;
GdkToplevelState pending_set_flags;
GdkToplevelState pending_unset_flags;
@@ -60,6 +71,7 @@ struct _GdkSurface
guint modal_hint : 1;
guint destroyed : 2;
guint in_update : 1;
guint frame_clock_events_paused : 1;
guint autohide : 1;
guint shortcuts_inhibited : 1;
@@ -98,6 +110,8 @@ struct _GdkSurfaceClass
{
GObjectClass parent_class;
cairo_surface_t *
(* ref_cairo_surface) (GdkSurface *surface);
void (* hide) (GdkSurface *surface);
void (* get_geometry) (GdkSurface *surface,
int *x,
@@ -278,8 +292,6 @@ void gdk_surface_get_geometry (GdkSurface *surface,
int *width,
int *height);
void gdk_surface_set_frame_clock (GdkSurface *surface,
GdkFrameClock *clock);
void gdk_surface_set_egl_native_window (GdkSurface *self,
gpointer native_window);
void gdk_surface_ensure_egl_surface (GdkSurface *self,
+1 -43
View File
@@ -282,8 +282,6 @@ gdk_texture_dispose (GObject *object)
{
GdkTexture *self = GDK_TEXTURE (object);
g_clear_pointer (&self->diff_to_previous, cairo_region_destroy);
gdk_texture_clear_render_data (self);
G_OBJECT_CLASS (gdk_texture_parent_class)->dispose (object);
@@ -673,47 +671,7 @@ gdk_texture_do_download (GdkTexture *texture,
guchar *data,
gsize stride)
{
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data, stride);
}
void
gdk_texture_diff (GdkTexture *self,
GdkTexture *other,
cairo_region_t *region)
{
if (self == other)
return;
if (self->previous_texture == other &&
g_atomic_pointer_get (&other->next_texture) == self)
{
cairo_region_union (region, self->diff_to_previous);
}
else if (other->previous_texture == self &&
g_atomic_pointer_get (&self->next_texture) == other)
{
cairo_region_union (region, other->diff_to_previous);
}
else
{
cairo_region_union_rectangle (region,
&(cairo_rectangle_int_t) {
0,
0,
MAX (self->width, other->width),
MAX (self->height, other->height)
});
}
}
void
gdk_texture_set_diff (GdkTexture *self,
GdkTexture *previous,
cairo_region_t *diff)
{
self->previous_texture = previous;
self->diff_to_previous = diff;
g_atomic_pointer_set (&previous->next_texture, self);
GDK_TEXTURE_GET_CLASS (texture)->download (texture, format, data,stride);
}
cairo_surface_t *
-14
View File
@@ -21,12 +21,6 @@ struct _GdkTexture
gpointer render_key;
gpointer render_data;
GDestroyNotify render_notify;
/* for diffing swapchain-like textures.
* Links are only valid if both textures agree on them */
gpointer next_texture; /* atomic, no reference, may be invalid pointer */
gpointer previous_texture; /* no reference, may be invalid pointer */
cairo_region_t *diff_to_previous;
};
struct _GdkTextureClass {
@@ -48,14 +42,6 @@ void gdk_texture_do_download (GdkTexture
GdkMemoryFormat format,
guchar *data,
gsize stride);
void gdk_texture_diff (GdkTexture *self,
GdkTexture *other,
cairo_region_t *region);
void gdk_texture_set_diff (GdkTexture *self,
GdkTexture *previous,
cairo_region_t *diff);
gboolean gdk_texture_set_render_data (GdkTexture *self,
gpointer key,
gpointer data,
+2 -76
View File
@@ -223,7 +223,7 @@ gdk_vulkan_strerror (VkResult result)
#if VK_HEADER_VERSION < 140
case VK_RESULT_RANGE_SIZE:
#endif
#if VK_HEADER_VERSION >= 238
#if VK_HEADER_VERSION >= 218
case VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR:
return "The requested VkImageUsageFlags are not supported. (VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR:
@@ -243,74 +243,6 @@ gdk_vulkan_strerror (VkResult result)
}
}
#ifdef G_ENABLE_DEBUG
static const char *
surface_present_mode_to_string (VkPresentModeKHR present_mode)
{
switch (present_mode)
{
case VK_PRESENT_MODE_MAILBOX_KHR:
return "VK_PRESENT_MODE_MAILBOX_KHR";
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return "VK_PRESENT_MODE_IMMEDIATE_KHR";
case VK_PRESENT_MODE_FIFO_KHR:
return "VK_PRESENT_MODE_FIFO_KHR";
case VK_PRESENT_MODE_FIFO_RELAXED_KHR:
return "VK_PRESENT_MODE_FIFO_RELAXED_KHR";
case VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR:
case VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR:
case VK_PRESENT_MODE_MAX_ENUM_KHR:
default:
return "(invalid)";
}
return "(unknown)";
}
#endif
static const VkPresentModeKHR preferred_present_modes[] = {
VK_PRESENT_MODE_MAILBOX_KHR,
VK_PRESENT_MODE_IMMEDIATE_KHR,
};
static VkPresentModeKHR
find_best_surface_present_mode (GdkVulkanContext *context)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
VkPresentModeKHR *available_present_modes;
uint32_t n_present_modes;
VkResult res;
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfacePresentModesKHR, gdk_vulkan_context_get_physical_device (context),
priv->surface,
&n_present_modes,
NULL);
if (res != VK_SUCCESS)
goto fallback_present_mode;
available_present_modes = g_alloca (sizeof (VkPresentModeKHR) * n_present_modes);
res = GDK_VK_CHECK (vkGetPhysicalDeviceSurfacePresentModesKHR, gdk_vulkan_context_get_physical_device (context),
priv->surface,
&n_present_modes,
available_present_modes);
if (res != VK_SUCCESS)
goto fallback_present_mode;
for (uint32_t i = 0; i < G_N_ELEMENTS (preferred_present_modes); i++)
{
for (uint32_t j = 0; j < n_present_modes; j++)
{
if (preferred_present_modes[i] == available_present_modes[j])
return available_present_modes[j];
}
}
fallback_present_mode:
return VK_PRESENT_MODE_FIFO_KHR;
}
static void
gdk_vulkan_context_dispose (GObject *gobject)
{
@@ -370,7 +302,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
VkSurfaceCapabilitiesKHR capabilities;
VkCompositeAlphaFlagBitsKHR composite_alpha;
VkPresentModeKHR present_mode;
VkSwapchainKHR new_swapchain;
VkResult res;
VkDevice device;
@@ -402,11 +333,6 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
}
present_mode = find_best_surface_present_mode (context);
GDK_DEBUG (VULKAN, "Using surface present mode %s",
surface_present_mode_to_string (present_mode));
/*
* Per https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#VkSurfaceCapabilitiesKHR
* the current extent may assume a special value, meaning that the extent should assume whatever
@@ -441,7 +367,7 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
},
.preTransform = capabilities.currentTransform,
.compositeAlpha = composite_alpha,
.presentMode = present_mode,
.presentMode = VK_PRESENT_MODE_FIFO_KHR,
.clipped = VK_FALSE,
.oldSwapchain = priv->swapchain
},
-2
View File
@@ -121,8 +121,6 @@ GdkMonitor *_gdk_macos_display_get_monitor_at_coords (GdkMacosDisp
GdkMonitor *_gdk_macos_display_get_monitor_at_display_coords (GdkMacosDisplay *self,
int x,
int y);
void _gdk_macos_display_surface_added (GdkMacosDisplay *self,
GdkMacosSurface *surface);
GdkEvent *_gdk_macos_display_translate (GdkMacosDisplay *self,
NSEvent *event);
void _gdk_macos_display_feedback_init (GdkMacosDisplay *self);
+25 -5
View File
@@ -36,10 +36,8 @@
#include "gdkmacosglcontext-private.h"
#include "gdkmacoskeymap-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacosseat-private.h"
#include "gdkmacossurface-private.h"
#include "gdkmacostoplevelsurface-private.h"
#include "gdkmacosutils-private.h"
G_DEFINE_TYPE (GdkMacosDisplay, gdk_macos_display, GDK_TYPE_DISPLAY)
@@ -335,7 +333,7 @@ gdk_macos_display_queue_events (GdkDisplay *display)
}
}
void
static void
_gdk_macos_display_surface_added (GdkMacosDisplay *self,
GdkMacosSurface *surface)
{
@@ -541,6 +539,29 @@ _gdk_macos_display_surface_resigned_main (GdkMacosDisplay *self,
_gdk_macos_display_clear_sorting (self);
}
static GdkSurface *
gdk_macos_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkMacosDisplay *self = (GdkMacosDisplay *)display;
GdkMacosSurface *surface;
g_assert (GDK_IS_MACOS_DISPLAY (self));
g_assert (!parent || GDK_IS_MACOS_SURFACE (parent));
surface = _gdk_macos_surface_new (self, surface_type, parent, x, y, width, height);
if (surface != NULL)
_gdk_macos_display_surface_added (self, surface);
return GDK_SURFACE (surface);
}
static GdkKeymap *
gdk_macos_display_get_keymap (GdkDisplay *display)
{
@@ -596,11 +617,10 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
object_class->finalize = gdk_macos_display_finalize;
display_class->toplevel_type = GDK_TYPE_MACOS_TOPLEVEL_SURFACE;
display_class->popup_type = GDK_TYPE_MACOS_POPUP_SURFACE;
display_class->cairo_context_type = GDK_TYPE_MACOS_CAIRO_CONTEXT;
display_class->beep = gdk_macos_display_beep;
display_class->create_surface = gdk_macos_display_create_surface;
display_class->flush = gdk_macos_display_flush;
display_class->get_keymap = gdk_macos_display_get_keymap;
display_class->get_monitors = gdk_macos_display_get_monitors;
+6 -1
View File
@@ -31,7 +31,12 @@ typedef struct _GdkMacosDragSurfaceClass GdkMacosDragSurfaceClass;
#define GDK_IS_MACOS_DRAG_SURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_MACOS_DRAG_SURFACE))
GType _gdk_macos_drag_surface_get_type (void);
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display);
GdkMacosSurface *_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height);
G_END_DECLS
+28 -38
View File
@@ -25,8 +25,6 @@
#include "gdkmacosdisplay-private.h"
#include "gdkmacosutils-private.h"
#include "gdk/gdkframeclockidleprivate.h"
struct _GdkMacosDragSurface
{
GdkMacosSurface parent_instance;
@@ -64,15 +62,27 @@ G_DEFINE_TYPE_WITH_CODE (GdkMacosDragSurface, _gdk_macos_drag_surface, GDK_TYPE_
G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE, drag_surface_iface_init))
static void
_gdk_macos_drag_surface_constructed (GObject *object)
_gdk_macos_drag_surface_class_init (GdkMacosDragSurfaceClass *klass)
{
}
static void
_gdk_macos_drag_surface_init (GdkMacosDragSurface *self)
{
}
GdkMacosSurface *
_gdk_macos_drag_surface_new (GdkMacosDisplay *display,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosSurface *self = GDK_MACOS_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self)));
GdkFrameClock *frame_clock;
GdkMacosSurface *self;
NSScreen *screen;
NSUInteger style_mask;
NSRect content_rect;
@@ -80,15 +90,18 @@ _gdk_macos_drag_surface_constructed (GObject *object)
int nx;
int ny;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
style_mask = NSWindowStyleMaskBorderless;
_gdk_macos_display_to_display_coords (display, 0, 0, &nx, &ny);
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
screen_rect = [screen frame];
nx -= screen_rect.origin.x;
ny -= screen_rect.origin.y;
content_rect = NSMakeRect (nx, ny - 1, 1, 1);
content_rect = NSMakeRect (nx, ny - height, width, height);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
@@ -100,36 +113,13 @@ _gdk_macos_drag_surface_constructed (GObject *object)
[window setBackgroundColor:[NSColor clearColor]];
[window setDecorated:NO];
_gdk_macos_surface_set_native (self, window);
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
self = g_object_new (GDK_TYPE_MACOS_DRAG_SURFACE,
"display", display,
"frame-clock", frame_clock,
"native", window,
NULL);
GDK_END_MACOS_ALLOC_POOL;
G_OBJECT_CLASS (_gdk_macos_drag_surface_parent_class)->constructed (object);
}
static void
_gdk_macos_drag_surface_class_init (GdkMacosDragSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = _gdk_macos_drag_surface_constructed;
}
static void
_gdk_macos_drag_surface_init (GdkMacosDragSurface *self)
{
}
GdkMacosSurface *
_gdk_macos_drag_surface_new (GdkMacosDisplay *display)
{
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
return g_object_new (GDK_TYPE_MACOS_DRAG_SURFACE,
"display", display,
NULL);
return g_steal_pointer (&self);
}
+15 -40
View File
@@ -323,12 +323,12 @@ gdk_macos_gl_context_release (GdkMacosGLContext *self)
}
static CGLPixelFormatObj
create_pixel_format (GdkGLVersion *version,
gboolean *out_legacy,
GError **error)
create_pixel_format (int major,
int minor,
GError **error)
{
CGLPixelFormatAttribute attrs[] = {
kCGLPFAOpenGLProfile, 0,
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy,
kCGLPFAAllowOfflineRenderers, /* allow sharing across GPUs */
kCGLPFADepthSize, 0,
kCGLPFAStencilSize, 0,
@@ -339,28 +339,14 @@ create_pixel_format (GdkGLVersion *version,
CGLPixelFormatObj format = NULL;
GLint n_format = 1;
*out_legacy = FALSE;
if (major == 3 && minor == 2)
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
else if (major == 4 && minor == 1)
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
if (gdk_gl_version_get_major (version) >= 4)
{
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL4_Core;
if (CGLChoosePixelFormat (attrs, &format, &n_format))
return g_steal_pointer (&format);
}
if (gdk_gl_version_greater_equal (version, &GDK_GL_MIN_GL_VERSION))
{
attrs[1] = (CGLPixelFormatAttribute)kCGLOGLPVersion_GL3_Core;
if (CGLChoosePixelFormat (attrs, &format, &n_format))
return g_steal_pointer (&format);
}
attrs[1] = (CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy;
if (!CHECK (error, CGLChoosePixelFormat (attrs, &format, &n_format)))
return NULL;
*out_legacy = TRUE;
return g_steal_pointer (&format);
}
@@ -380,8 +366,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GLint validate = 0;
GLint renderer_id = 0;
GLint swapRect[4];
GdkGLVersion min_version, version;
gboolean legacy;
int major, minor;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
@@ -393,10 +378,10 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
existing = CGLGetCurrentContext ();
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
FALSE,
&version);
gdk_gl_context_get_clipped_version (context,
GDK_GL_MIN_GL_VERSION_MAJOR,
GDK_GL_MIN_GL_VERSION_MINOR,
&major, &minor);
display = gdk_gl_context_get_display (context);
shared = gdk_display_get_gl_context (display);
@@ -415,9 +400,9 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GDK_DISPLAY_DEBUG (display, OPENGL,
"Creating CGLContextObj (version %d.%d)",
gdk_gl_version_get_major (&min_version), gdk_gl_version_get_minor (&min_version));
major, minor);
if (!(pixelFormat = create_pixel_format (&min_version, &legacy, error)))
if (!(pixelFormat = create_pixel_format (major, minor, error)))
return 0;
if (!CHECK (error, CGLCreateContext (pixelFormat, shared_gl_context, &cgl_context)))
@@ -429,13 +414,6 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
CGLSetCurrentContext (cgl_context);
CGLReleasePixelFormat (pixelFormat);
gdk_gl_version_init_epoxy (&version);
if (!gdk_gl_version_greater_equal (&version, &min_version))
{
CGLReleaseContext (cgl_context);
return 0;
}
if (validate)
CHECK (NULL, CGLEnable (cgl_context, kCGLCEStateValidation));
@@ -467,9 +445,6 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
cgl_context,
get_renderer_name (renderer_id));
gdk_gl_context_set_version (context, &version);
gdk_gl_context_set_is_legacy (context, legacy);
self->cgl_context = g_steal_pointer (&cgl_context);
if (existing != NULL)
+5 -1
View File
@@ -33,7 +33,11 @@ typedef struct _GdkMacosPopupSurfaceClass GdkMacosPopupSurfaceClass;
GType _gdk_macos_popup_surface_get_type (void);
GdkMacosSurface *_gdk_macos_popup_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock);
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height);
void _gdk_macos_popup_surface_attach_to_parent (GdkMacosPopupSurface *self);
void _gdk_macos_popup_surface_detach_from_parent (GdkMacosPopupSurface *self);
void _gdk_macos_popup_surface_reposition (GdkMacosPopupSurface *self);
+41 -31
View File
@@ -284,14 +284,38 @@ _gdk_macos_popup_surface_set_property (GObject *object,
}
static void
_gdk_macos_popup_surface_constructed (GObject *object)
_gdk_macos_popup_surface_class_init (GdkMacosPopupSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
object_class->finalize = _gdk_macos_popup_surface_finalize;
object_class->get_property = _gdk_macos_popup_surface_get_property;
object_class->set_property = _gdk_macos_popup_surface_set_property;
surface_class->hide = _gdk_macos_popup_surface_hide;
gdk_popup_install_properties (object_class, LAST_PROP);
}
static void
_gdk_macos_popup_surface_init (GdkMacosPopupSurface *self)
{
}
GdkMacosSurface *
_gdk_macos_popup_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosPopupSurface *self = GDK_MACOS_POPUP_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self)));
GdkMacosSurface *self;
NSScreen *screen;
NSUInteger style_mask;
NSRect content_rect;
@@ -299,15 +323,19 @@ _gdk_macos_popup_surface_constructed (GObject *object)
int nx;
int ny;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
style_mask = NSWindowStyleMaskBorderless;
_gdk_macos_display_to_display_coords (display, 0, 0, &nx, &ny);
_gdk_macos_display_to_display_coords (display, x, y, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
screen_rect = [screen frame];
nx -= screen_rect.origin.x;
ny -= screen_rect.origin.y;
content_rect = NSMakeRect (nx, ny - 100, 100, 100);
content_rect = NSMakeRect (nx, ny - height, width, height);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
@@ -321,34 +349,16 @@ _gdk_macos_popup_surface_constructed (GObject *object)
[window setExcludedFromWindowsMenu:YES];
[window setLevel:NSPopUpMenuWindowLevel];
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (surface->parent));
self = g_object_new (GDK_TYPE_MACOS_POPUP_SURFACE,
"display", display,
"frame-clock", frame_clock,
"native", window,
"parent", parent,
NULL);
GDK_END_MACOS_ALLOC_POOL;
G_OBJECT_CLASS (_gdk_macos_popup_surface_parent_class)->constructed (object);
}
static void
_gdk_macos_popup_surface_class_init (GdkMacosPopupSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = _gdk_macos_popup_surface_constructed;
object_class->finalize = _gdk_macos_popup_surface_finalize;
object_class->get_property = _gdk_macos_popup_surface_get_property;
object_class->set_property = _gdk_macos_popup_surface_set_property;
surface_class->hide = _gdk_macos_popup_surface_hide;
gdk_popup_install_properties (object_class, LAST_PROP);
}
static void
_gdk_macos_popup_surface_init (GdkMacosPopupSurface *self)
{
return g_steal_pointer (&self);
}
void
+7 -2
View File
@@ -84,9 +84,14 @@ struct _GdkMacosSurfaceClass
GdkSurfaceClass parent_class;
};
GdkMacosSurface *_gdk_macos_surface_new (GdkMacosDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
NSWindow *_gdk_macos_surface_get_native (GdkMacosSurface *self);
void _gdk_macos_surface_set_native (GdkMacosSurface *self,
GdkMacosWindow *window);
CGDirectDisplayID _gdk_macos_surface_get_screen_id (GdkMacosSurface *self);
const char *_gdk_macos_surface_get_title (GdkMacosSurface *self);
void _gdk_macos_surface_set_title (GdkMacosSurface *self,
+83 -20
View File
@@ -31,7 +31,7 @@
#include "gdkdeviceprivate.h"
#include "gdkdisplay.h"
#include "gdkeventsprivate.h"
#include "gdkframeclockprivate.h"
#include "gdkframeclockidleprivate.h"
#include "gdkseatprivate.h"
#include "gdksurfaceprivate.h"
@@ -43,8 +43,8 @@
#include "gdkmacosglcontext-private.h"
#include "gdkmacosmonitor-private.h"
#include "gdkmacospopupsurface-private.h"
#include "gdkmacosutils-private.h"
#include "gdkmacostoplevelsurface-private.h"
#include "gdkmacosutils-private.h"
G_DEFINE_ABSTRACT_TYPE (GdkMacosSurface, gdk_macos_surface, GDK_TYPE_SURFACE)
@@ -416,6 +416,10 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
GdkMacosSurface *drag_surface;
GdkMacosDrag *drag;
GdkCursor *cursor;
double px;
double py;
int sx;
int sy;
g_assert (GDK_IS_MACOS_SURFACE (self));
g_assert (GDK_IS_MACOS_TOPLEVEL_SURFACE (self) ||
@@ -423,7 +427,12 @@ gdk_macos_surface_drag_begin (GdkSurface *surface,
g_assert (GDK_IS_MACOS_DEVICE (device));
g_assert (GDK_IS_CONTENT_PROVIDER (content));
drag_surface = _gdk_macos_drag_surface_new (GDK_MACOS_DISPLAY (surface->display));
gdk_macos_device_query_state (device, surface, NULL, &px, &py, NULL);
_gdk_macos_surface_get_root_coords (GDK_MACOS_SURFACE (surface), &sx, &sy);
drag_surface = _gdk_macos_surface_new (GDK_MACOS_DISPLAY (surface->display),
GDK_SURFACE_DRAG,
NULL,
sx, sy, 1, 1);
drag = g_object_new (GDK_TYPE_MACOS_DRAG,
"drag-surface", drag_surface,
"surface", surface,
@@ -518,14 +527,8 @@ gdk_macos_surface_constructed (GObject *object)
G_CONNECT_SWAPPED);
}
gdk_surface_freeze_updates (GDK_SURFACE (self));
_gdk_macos_surface_monitor_changed (self);
if (self->window != NULL)
_gdk_macos_surface_configure (self);
_gdk_macos_display_surface_added (GDK_MACOS_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self))),
self);
}
static void
@@ -547,6 +550,26 @@ gdk_macos_surface_get_property (GObject *object,
}
}
static void
gdk_macos_surface_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GdkMacosSurface *self = GDK_MACOS_SURFACE (object);
switch (prop_id)
{
case PROP_NATIVE:
self->window = g_value_get_pointer (value);
[self->window setGdkSurface:self];
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
{
@@ -555,6 +578,7 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
object_class->constructed = gdk_macos_surface_constructed;
object_class->get_property = gdk_macos_surface_get_property;
object_class->set_property = gdk_macos_surface_set_property;
surface_class->destroy = gdk_macos_surface_destroy;
surface_class->drag_begin = gdk_macos_surface_drag_begin;
@@ -573,7 +597,7 @@ gdk_macos_surface_class_init (GdkMacosSurfaceClass *klass)
*/
properties [PROP_NATIVE] =
g_param_spec_pointer ("native", NULL, NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, properties);
}
@@ -587,6 +611,55 @@ gdk_macos_surface_init (GdkMacosSurface *self)
self->monitors = g_ptr_array_new_with_free_func (g_object_unref);
}
GdkMacosSurface *
_gdk_macos_surface_new (GdkMacosDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkFrameClock *frame_clock;
GdkMacosSurface *ret;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
if (parent != NULL)
frame_clock = g_object_ref (parent->frame_clock);
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
ret = _gdk_macos_toplevel_surface_new (display, parent, frame_clock, x, y, width, height);
break;
case GDK_SURFACE_POPUP:
ret = _gdk_macos_popup_surface_new (display, parent, frame_clock, x, y, width, height);
break;
case GDK_SURFACE_DRAG:
ret = _gdk_macos_drag_surface_new (display, frame_clock, x, y, width, height);
break;
default:
g_warn_if_reached ();
ret = NULL;
}
if (ret != NULL)
{
gdk_surface_freeze_updates (GDK_SURFACE (ret));
_gdk_macos_surface_monitor_changed (ret);
}
g_object_unref (frame_clock);
return g_steal_pointer (&ret);
}
void
_gdk_macos_surface_get_shadow (GdkMacosSurface *self,
int *top,
@@ -682,16 +755,6 @@ _gdk_macos_surface_get_native (GdkMacosSurface *self)
return (NSWindow *)self->window;
}
void
_gdk_macos_surface_set_native (GdkMacosSurface *self,
GdkMacosWindow *window)
{
g_assert (self->window == NULL);
self->window = window;
[self->window setGdkSurface:self];
}
/**
* gdk_macos_surface_get_native_window: (attributes org.gtk.Method.get_property=native)
* @self: a #GdkMacosSurface
@@ -45,6 +45,13 @@ struct _GdkMacosToplevelSurfaceClass
};
GType _gdk_macos_toplevel_surface_get_type (void);
GdkMacosSurface *_gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height);
void _gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self);
void _gdk_macos_toplevel_surface_detach_from_parent (GdkMacosToplevelSurface *self);
+60 -49
View File
@@ -23,7 +23,6 @@
#include "gdkmacostoplevelsurface-private.h"
#include "gdkframeclockidleprivate.h"
#include "gdkseatprivate.h"
#include "gdktoplevelprivate.h"
@@ -626,60 +625,12 @@ _gdk_macos_toplevel_surface_set_property (GObject *object,
}
}
static void
_gdk_macos_toplevel_surface_constructed (GObject *object)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosToplevelSurface *self = GDK_MACOS_TOPLEVEL_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (self);
GdkMacosDisplay *display = GDK_MACOS_DISPLAY (gdk_surface_get_display (surface));
GdkFrameClock *frame_clock;
NSUInteger style_mask;
NSRect content_rect;
NSRect visible_frame;
NSScreen *screen;
int nx;
int ny;
style_mask = (NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable |
NSWindowStyleMaskResizable);
_gdk_macos_display_to_display_coords (display, 0, 100, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
visible_frame = [screen visibleFrame];
content_rect = NSMakeRect (nx - visible_frame.origin.x, ny - visible_frame.origin.y, 100, 100);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO
screen:screen];
/* Allow NSWindow to go fullscreen */
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
_gdk_macos_surface_set_native (GDK_MACOS_SURFACE (self), window);
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
GDK_END_MACOS_ALLOC_POOL;
G_OBJECT_CLASS (_gdk_macos_toplevel_surface_parent_class)->constructed (object);
}
static void
_gdk_macos_toplevel_surface_class_init (GdkMacosToplevelSurfaceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (klass);
object_class->constructed = _gdk_macos_toplevel_surface_constructed;
object_class->get_property = _gdk_macos_toplevel_surface_get_property;
object_class->set_property = _gdk_macos_toplevel_surface_set_property;
@@ -697,6 +648,66 @@ _gdk_macos_toplevel_surface_init (GdkMacosToplevelSurface *self)
self->decorated = TRUE;
}
GdkMacosSurface *
_gdk_macos_toplevel_surface_new (GdkMacosDisplay *display,
GdkSurface *parent,
GdkFrameClock *frame_clock,
int x,
int y,
int width,
int height)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkMacosWindow *window;
GdkMacosSurface *self;
NSUInteger style_mask;
NSRect content_rect;
NSRect visible_frame;
NSScreen *screen;
int nx;
int ny;
g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
g_return_val_if_fail (!frame_clock || GDK_IS_FRAME_CLOCK (frame_clock), NULL);
g_return_val_if_fail (!parent || GDK_IS_MACOS_SURFACE (parent), NULL);
style_mask = (NSWindowStyleMaskTitled |
NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable |
NSWindowStyleMaskResizable);
if (parent != NULL)
{
x += GDK_MACOS_SURFACE (parent)->root_x;
y += GDK_MACOS_SURFACE (parent)->root_y;
}
_gdk_macos_display_to_display_coords (display, x, y + height, &nx, &ny);
screen = _gdk_macos_display_get_screen_at_display_coords (display, nx, ny);
visible_frame = [screen visibleFrame];
content_rect = NSMakeRect (nx - visible_frame.origin.x, ny - visible_frame.origin.y, width, height);
window = [[GdkMacosWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO
screen:screen];
/* Allow NSWindow to go fullscreen */
[window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
self = g_object_new (GDK_TYPE_MACOS_TOPLEVEL_SURFACE,
"display", display,
"frame-clock", frame_clock,
"native", window,
NULL);
GDK_END_MACOS_ALLOC_POOL;
return g_steal_pointer (&self);
}
void
_gdk_macos_toplevel_surface_attach_to_parent (GdkMacosToplevelSurface *self)
{
-2
View File
@@ -29,7 +29,6 @@ gdk_public_sources = files([
'gdkglcontext.c',
'gdkglobals.c',
'gdkgltexture.c',
'gdkgltexturebuilder.c',
'gdkhsla.c',
'gdkkeys.c',
'gdkkeyuni.c',
@@ -87,7 +86,6 @@ gdk_public_headers = files([
'gdkframetimings.h',
'gdkglcontext.h',
'gdkgltexture.h',
'gdkgltexturebuilder.h',
'gdkkeys.h',
'gdkkeysyms.h',
'gdkmemorytexture.h',
+1 -2
View File
@@ -967,8 +967,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
object_class->dispose = gdk_wayland_display_dispose;
object_class->finalize = gdk_wayland_display_finalize;
display_class->toplevel_type = GDK_TYPE_WAYLAND_TOPLEVEL;
display_class->popup_type = GDK_TYPE_WAYLAND_POPUP;
display_class->cairo_context_type = GDK_TYPE_WAYLAND_CAIRO_CONTEXT;
#ifdef GDK_RENDERING_VULKAN
@@ -989,6 +987,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
G_GNUC_END_IGNORE_DEPRECATIONS
display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
display_class->create_surface = _gdk_wayland_display_create_surface;
display_class->get_keymap = _gdk_wayland_display_get_keymap;
display_class->init_gl = gdk_wayland_display_init_gl;
+4 -5
View File
@@ -24,7 +24,6 @@
#include "gdkdisplay-wayland.h"
#include <glib/gi18n-lib.h>
#include "gdkseat-wayland.h"
#include "gdksurface-wayland-private.h"
#include "gdkdeviceprivate.h"
@@ -47,6 +46,7 @@ struct _GdkWaylandDrag
{
GdkDrag drag;
GdkSurface *dnd_surface;
struct wl_surface *dnd_wl_surface;
struct wl_data_source *data_source;
struct wl_data_offer *offer;
uint32_t serial;
@@ -382,9 +382,8 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
drag = GDK_DRAG (drag_wayland);
drag_wayland->dnd_surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
"display", display,
NULL);
drag_wayland->dnd_surface = _gdk_wayland_display_create_surface (display, GDK_SURFACE_DRAG, NULL, 0, 0, 100, 100);
drag_wayland->dnd_wl_surface = gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface);
gdk_wayland_drag_create_data_source (drag);
@@ -396,7 +395,7 @@ _gdk_wayland_surface_drag_begin (GdkSurface *surface,
wl_data_device_start_drag (gdk_wayland_device_get_data_device (device),
drag_wayland->data_source,
gdk_wayland_surface_get_wl_surface (surface),
gdk_wayland_surface_get_wl_surface (drag_wayland->dnd_surface),
drag_wayland->dnd_wl_surface,
_gdk_wayland_seat_get_implicit_grab_serial (seat, NULL));
cursor = gdk_drag_get_cursor (drag, gdk_drag_get_selected_action (drag));
+3 -16
View File
@@ -101,27 +101,11 @@ gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
return FALSE;
}
static void
gdk_wayland_drag_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
G_OBJECT_CLASS (gdk_wayland_drag_surface_parent_class)->constructed (object);
}
static void
gdk_wayland_drag_surface_class_init (GdkWaylandDragSurfaceClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class);
object_class->constructed = gdk_wayland_drag_surface_constructed;
surface_class->compute_size = gdk_wayland_drag_surface_compute_size;
}
@@ -143,6 +127,9 @@ gdk_wayland_drag_surface_present (GdkDragSurface *drag_surface,
GdkSurface *surface = GDK_SURFACE (drag_surface);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->display_server.wl_surface)
gdk_wayland_surface_create_wl_surface (surface);
impl->next_layout.configured_width = width;
impl->next_layout.configured_height = height;
impl->next_layout.surface_geometry_dirty = TRUE;
-3
View File
@@ -75,9 +75,6 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
/* We should do ths when setting up the EGLSurface, but we don't make_current then */
eglSwapInterval (gdk_display_get_egl_display (gdk_draw_context_get_display (draw_context)), 0);
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
gdk_wayland_surface_notify_committed (surface);
+5 -12
View File
@@ -1040,17 +1040,6 @@ gdk_wayland_popup_init (GdkWaylandPopup *popup)
{
}
static void
gdk_wayland_popup_constructed (GObject *object)
{
GdkWaylandPopup *self = GDK_WAYLAND_POPUP (object);
GdkSurface *surface = GDK_SURFACE (self);
gdk_surface_set_frame_clock (surface, gdk_surface_get_frame_clock (gdk_popup_get_parent (GDK_POPUP (self))));
G_OBJECT_CLASS (gdk_wayland_popup_parent_class)->constructed (object);
}
static void
gdk_wayland_popup_get_property (GObject *object,
guint prop_id,
@@ -1108,7 +1097,6 @@ gdk_wayland_popup_class_init (GdkWaylandPopupClass *class)
GdkSurfaceClass *surface_class = GDK_SURFACE_CLASS (class);
GdkWaylandSurfaceClass *wayland_surface_class = GDK_WAYLAND_SURFACE_CLASS (class);
object_class->constructed = gdk_wayland_popup_constructed;
object_class->get_property = gdk_wayland_popup_get_property;
object_class->set_property = gdk_wayland_popup_set_property;
@@ -1301,6 +1289,11 @@ show_popup (GdkWaylandPopup *wayland_popup,
int height,
GdkPopupLayout *layout)
{
GdkWaylandSurface *wayland_surface = GDK_WAYLAND_SURFACE (wayland_popup);
if (!wayland_surface->display_server.wl_surface)
gdk_wayland_surface_create_wl_surface (GDK_SURFACE (wayland_popup));
if (wayland_popup->thaw_upon_show)
{
wayland_popup->thaw_upon_show = FALSE;
+4 -11
View File
@@ -99,7 +99,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
if (cb->source)
{
GDK_DISPLAY_DEBUG (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, "%p: Ignoring primary offer for self", cb);
GDK_DISPLAY_DEBUG (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD, "%p: Ignoring clipboard offer for self", cb);
gdk_content_formats_unref (formats);
g_clear_pointer (&offer, zwp_primary_selection_offer_v1_destroy);
return;
@@ -111,7 +111,7 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: remote primary claim for %s", cb, s);
gdk_debug_message ("%p: remote clipboard claim for %s", cb, s);
g_free (s);
}
#endif
@@ -119,7 +119,8 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
cb->offer_formats = formats;
cb->offer = offer;
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb), cb->offer_formats);
gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb),
cb->offer_formats);
}
static void
@@ -270,14 +271,6 @@ gdk_wayland_primary_claim (GdkClipboard *clipboard,
{
GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (clipboard);
#ifdef G_ENABLE_DEBUG
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (clipboard), CLIPBOARD))
{
char *s = gdk_content_formats_to_string (formats);
gdk_debug_message ("%p: claim primary (%s) for %s", cb, local ? "local" : "remote", s);
g_free (s);
}
#endif
if (local)
{
GdkWaylandDisplay *wdisplay = GDK_WAYLAND_DISPLAY (gdk_clipboard_get_display (clipboard));
+8
View File
@@ -157,6 +157,14 @@ void gdk_wayland_drop_set_source_actions (GdkDrop
void gdk_wayland_drop_set_action (GdkDrop *drop,
uint32_t action);
GdkSurface * _gdk_wayland_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
void _gdk_wayland_display_create_seat (GdkWaylandDisplay *display,
guint32 id,
struct wl_seat *seat);
+2 -1
View File
@@ -42,11 +42,11 @@ struct _GdkWaylandSurface
} display_server;
struct wl_event_queue *event_queue;
struct wl_callback *frame_callback;
unsigned int initial_configure_received : 1;
unsigned int has_uncommitted_ack_configure : 1;
unsigned int mapped : 1;
unsigned int awaiting_frame : 1;
unsigned int awaiting_frame_frozen : 1;
int pending_buffer_offset_x;
@@ -104,6 +104,7 @@ struct _GdkWaylandSurfaceClass
#define GDK_WAYLAND_SURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SURFACE, GdkWaylandSurfaceClass))
void gdk_wayland_surface_create_wl_surface (GdkSurface *surface);
void gdk_wayland_surface_update_size (GdkSurface *surface,
int32_t width,
int32_t height,
+237 -121
View File
@@ -28,7 +28,6 @@
#include "gdkmonitor-wayland.h"
#include "gdkpopupprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkrectangleprivate.h"
#include "gdkseat-wayland.h"
#include "gdksurfaceprivate.h"
#include "gdktoplevelprivate.h"
@@ -108,6 +107,20 @@ fill_presentation_time_from_frame_time (GdkFrameTimings *timings,
}
}
static const char *
get_default_title (void)
{
const char *title;
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
if (!title)
title = "";
return title;
}
static gboolean
is_realized_shell_surface (GdkWaylandSurface *impl)
{
@@ -185,6 +198,38 @@ gdk_wayland_surface_thaw_state (GdkSurface *surface)
gdk_wayland_surface_configure (surface);
}
static void
gdk_wayland_surface_maybe_resize (GdkSurface *surface,
int width,
int height,
const GdkFractionalScale *scale)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
gboolean hide_temporarily;
if (surface->width == width &&
surface->height == height &&
gdk_fractional_scale_equal (&impl->scale, scale))
return;
/* For xdg_popup using an xdg_positioner, there is a race condition if
* the application tries to change the size after it's mapped, but before
* the initial configure is received, so hide and show the surface again
* force the new size onto the compositor. See bug #772505.
*/
hide_temporarily = GDK_IS_WAYLAND_POPUP (surface) &&
gdk_surface_get_mapped (surface) &&
!impl->initial_configure_received;
if (hide_temporarily)
gdk_surface_hide (surface);
gdk_wayland_surface_update_size (surface, width, height, scale);
if (hide_temporarily)
gdk_wayland_surface_create_wl_surface (surface);
}
static inline void
get_egl_window_size (GdkSurface *surface,
int *width,
@@ -273,13 +318,17 @@ frame_callback (void *data,
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "frame event");
GDK_DISPLAY_DEBUG (GDK_DISPLAY (display_wayland), EVENTS, "frame %p", surface);
g_assert (impl->frame_callback == callback);
g_assert (!GDK_SURFACE_DESTROYED (surface));
wl_callback_destroy (callback);
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
if (GDK_SURFACE_DESTROYED (surface))
return;
if (!impl->awaiting_frame)
return;
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->handle_frame (impl);
impl->awaiting_frame = FALSE;
if (impl->awaiting_frame_frozen)
{
impl->awaiting_frame_frozen = FALSE;
@@ -367,17 +416,20 @@ gdk_wayland_surface_request_layout (GdkSurface *surface)
void
gdk_wayland_surface_request_frame (GdkSurface *surface)
{
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
struct wl_callback *callback;
GdkFrameClock *clock;
g_assert (self->frame_callback == NULL);
if (impl->awaiting_frame)
return;
clock = gdk_surface_get_frame_clock (surface);
self->frame_callback = wl_surface_frame (self->display_server.wl_surface);
wl_proxy_set_queue ((struct wl_proxy *) self->frame_callback, NULL);
wl_callback_add_listener (self->frame_callback, &frame_listener, surface);
self->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
callback = wl_surface_frame (impl->display_server.wl_surface);
wl_proxy_set_queue ((struct wl_proxy *) callback, NULL);
wl_callback_add_listener (callback, &frame_listener, surface);
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
impl->awaiting_frame = TRUE;
}
gboolean
@@ -416,10 +468,9 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
gdk_wayland_surface_notify_committed (surface);
}
if (impl->frame_callback &&
if (impl->awaiting_frame &&
impl->pending_frame_counter == gdk_frame_clock_get_frame_counter (clock))
{
g_assert (!impl->awaiting_frame_frozen);
impl->awaiting_frame_frozen = TRUE;
gdk_surface_freeze_updates (surface);
}
@@ -457,9 +508,105 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
}
/* Notify app that scale changed */
gdk_wayland_surface_update_size (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT_INT (scale));
}
GdkSurface *
_gdk_wayland_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GdkSurface *surface;
GdkFrameClock *frame_clock;
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
g_warn_if_fail (parent == NULL);
surface = g_object_new (GDK_TYPE_WAYLAND_TOPLEVEL,
"display", display,
"frame-clock", frame_clock,
"title", get_default_title (),
NULL);
display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
break;
case GDK_SURFACE_POPUP:
g_warn_if_fail (parent != NULL);
surface = g_object_new (GDK_TYPE_WAYLAND_POPUP,
"parent", parent,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
case GDK_SURFACE_DRAG:
g_warn_if_fail (parent == NULL);
surface = g_object_new (GDK_TYPE_WAYLAND_DRAG_SURFACE,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
default:
g_assert_not_reached ();
break;
}
if (width > 65535)
{
g_warning ("Native Surfaces wider than 65535 pixels are not supported");
width = 65535;
}
if (height > 65535)
{
g_warning ("Native Surfaces taller than 65535 pixels are not supported");
height = 65535;
}
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
g_object_ref (surface);
/* More likely to be right than just assuming 1 */
if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
{
GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
if (monitor)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
if (monitor_scale != 1)
{
impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
impl->buffer_scale_dirty = TRUE;
}
g_object_unref (monitor);
}
}
gdk_wayland_surface_create_wl_surface (surface);
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
g_object_unref (frame_clock);
return surface;
}
void
@@ -469,7 +616,6 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
cairo_rectangle_int_t rect;
uint32_t wl_surface_version;
int i, n;
if (GDK_SURFACE_DESTROYED (surface))
@@ -477,15 +623,14 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
g_assert (_gdk_wayland_is_shm_surface (cairo_surface));
wl_surface_version = wl_surface_get_version (impl->display_server.wl_surface);
/* Attach this new buffer to the surface */
wl_surface_attach (impl->display_server.wl_surface,
_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface),
0, 0);
if ((impl->pending_buffer_offset_x || impl->pending_buffer_offset_y) &&
wl_surface_version >= WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_get_version (impl->display_server.wl_surface) >=
WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface,
impl->pending_buffer_offset_x,
impl->pending_buffer_offset_y);
@@ -496,16 +641,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface,
for (i = 0; i < n; i++)
{
cairo_region_get_rectangle (damage, i, &rect);
if (wl_surface_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
{
float scale = gdk_surface_get_scale (surface);
gdk_rectangle_transform_affine (&rect, scale, scale, 0, 0, &rect);
wl_surface_damage_buffer (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
}
else
{
wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
}
wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height);
}
}
@@ -517,6 +653,21 @@ gdk_wayland_surface_beep (GdkSurface *surface)
return TRUE;
}
static void
gdk_wayland_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->constructed (object);
impl->event_queue = wl_display_create_queue (display_wayland->wl_display);
display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
impl->event_queue);
}
static void
gdk_wayland_surface_dispose (GObject *object)
{
@@ -533,7 +684,7 @@ gdk_wayland_surface_dispose (GObject *object)
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
display_wayland->event_queues =
g_list_remove (display_wayland->event_queues, impl->event_queue);
g_list_remove (display_wayland->event_queues, surface);
g_clear_pointer (&impl->event_queue, wl_event_queue_destroy);
}
@@ -707,9 +858,9 @@ gdk_wayland_surface_fractional_scale_preferred_scale_cb (void *data,
GdkSurface *surface = GDK_SURFACE (self);
/* Notify app that scale changed */
gdk_wayland_surface_update_size (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT (scale));
gdk_wayland_surface_maybe_resize (surface,
surface->width, surface->height,
&GDK_FRACTIONAL_SCALE_INIT (scale));
}
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
@@ -764,7 +915,7 @@ static const struct wl_surface_listener surface_listener = {
surface_leave
};
static void
void
gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
{
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
@@ -791,62 +942,6 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
self->display_server.wl_surface = wl_surface;
}
static void
gdk_wayland_surface_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
self->event_queue = wl_display_create_queue (display_wayland->wl_display);
display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
self->event_queue);
/* More likely to be right than just assuming 1 */
if (wl_compositor_get_version (display_wayland->compositor) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
{
GdkMonitor *monitor = g_list_model_get_item (gdk_display_get_monitors (display), 0);
if (monitor)
{
guint32 monitor_scale = gdk_monitor_get_scale_factor (monitor);
if (monitor_scale != 1)
{
self->scale = GDK_FRACTIONAL_SCALE_INIT_INT (monitor_scale);
self->buffer_scale_dirty = TRUE;
}
g_object_unref (monitor);
}
}
gdk_wayland_surface_create_wl_surface (surface);
g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->constructed (object);
}
static void
gdk_wayland_surface_destroy_wl_surface (GdkWaylandSurface *self)
{
if (self->display_server.egl_window)
{
gdk_surface_set_egl_native_window (GDK_SURFACE (self), NULL);
g_clear_pointer (&self->display_server.egl_window, wl_egl_window_destroy);
}
g_clear_pointer (&self->display_server.viewport, wp_viewport_destroy);
g_clear_pointer (&self->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
g_clear_pointer (&self->display_server.wl_surface, wl_surface_destroy);
g_clear_pointer (&self->display_server.outputs, g_slist_free);
}
static void
maybe_notify_mapped (GdkSurface *surface)
{
@@ -974,42 +1069,59 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
if (!impl->mapped)
return;
unmap_popups_for_surface (surface);
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
if (impl->awaiting_frame_frozen)
if (impl->display_server.wl_surface)
{
impl->awaiting_frame_frozen = FALSE;
gdk_surface_thaw_updates (surface);
}
if (impl->display_server.egl_window)
{
gdk_surface_set_egl_native_window (surface, NULL);
wl_egl_window_destroy (impl->display_server.egl_window);
impl->display_server.egl_window = NULL;
}
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
impl->awaiting_frame = FALSE;
if (impl->awaiting_frame_frozen)
{
impl->awaiting_frame_frozen = FALSE;
gdk_surface_thaw_updates (surface);
}
if (impl->display_server.xdg_surface)
{
xdg_surface_destroy (impl->display_server.xdg_surface);
impl->display_server.xdg_surface = NULL;
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
if (impl->display_server.zxdg_surface_v6)
{
g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
wl_surface_attach (impl->display_server.wl_surface, NULL, 0, 0);
wl_surface_commit (impl->display_server.wl_surface);
if (impl->display_server.xdg_surface)
{
xdg_surface_destroy (impl->display_server.xdg_surface);
impl->display_server.xdg_surface = NULL;
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
if (impl->display_server.zxdg_surface_v6)
{
g_clear_pointer (&impl->display_server.zxdg_surface_v6, zxdg_surface_v6_destroy);
if (!impl->initial_configure_received)
gdk_surface_thaw_updates (surface);
else
impl->initial_configure_received = FALSE;
}
g_clear_pointer (&impl->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
g_clear_pointer (&impl->display_server.viewport, wp_viewport_destroy);
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
g_slist_free (impl->display_server.outputs);
impl->display_server.outputs = NULL;
}
impl->has_uncommitted_ack_configure = FALSE;
impl->input_region_dirty = TRUE;
impl->opaque_region_dirty = TRUE;
impl->viewport_dirty = TRUE;
if (!gdk_fractional_scale_equal (&impl->scale, &GDK_FRACTIONAL_SCALE_INIT_INT (1)))
impl->buffer_scale_dirty = TRUE;
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
impl->mapped = FALSE;
@@ -1043,7 +1155,7 @@ gdk_wayland_surface_move_resize (GdkSurface *surface,
surface->x = x;
surface->y = y;
gdk_wayland_surface_update_size (surface, width, height, &impl->scale);
gdk_wayland_surface_maybe_resize (surface, width, height, &impl->scale);
}
static void
@@ -1138,8 +1250,11 @@ static void
gdk_wayland_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy)
{
GdkWaylandDisplay *display;
GdkFrameClock *frame_clock;
g_return_if_fail (GDK_IS_SURFACE (surface));
/* Wayland surfaces can't be externally destroyed; we may possibly
* eventually want to use this path at display close-down
*/
@@ -1147,11 +1262,12 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
gdk_wayland_surface_hide_surface (surface);
gdk_wayland_surface_destroy_wl_surface (GDK_WAYLAND_SURFACE(surface));
frame_clock = gdk_surface_get_frame_clock (surface);
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_before_paint, surface);
g_signal_handlers_disconnect_by_func (frame_clock, on_frame_clock_after_paint, surface);
display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
display->toplevels = g_list_remove (display->toplevels, surface);
}
static void
+17 -46
View File
@@ -823,20 +823,6 @@ gdk_wayland_surface_create_xdg_toplevel (GdkWaylandToplevel *wayland_toplevel)
wl_surface_commit (wayland_surface->display_server.wl_surface);
}
static const char *
get_default_title (void)
{
const char *title;
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
if (!title)
title = "";
return title;
}
static void
gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel)
{
@@ -844,8 +830,6 @@ gdk_wayland_toplevel_init (GdkWaylandToplevel *toplevel)
toplevel->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
toplevel->saved_width = -1;
toplevel->saved_height = -1;
toplevel->title = g_strdup (get_default_title ());
}
static void
@@ -1275,43 +1259,28 @@ gdk_wayland_toplevel_get_property (GObject *object,
static void
gdk_wayland_toplevel_finalize (GObject *object)
{
GdkWaylandToplevel *self = GDK_WAYLAND_TOPLEVEL (object);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (object)));
GdkWaylandToplevel *wayland_toplevel;
display_wayland->toplevels = g_list_remove (display_wayland->toplevels, self);
g_return_if_fail (GDK_IS_WAYLAND_TOPLEVEL (object));
if (gdk_wayland_toplevel_is_exported (self))
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (self));
wayland_toplevel = GDK_WAYLAND_TOPLEVEL (object);
g_free (self->application.application_id);
g_free (self->application.app_menu_path);
g_free (self->application.menubar_path);
g_free (self->application.window_object_path);
g_free (self->application.application_object_path);
g_free (self->application.unique_bus_name);
if (gdk_wayland_toplevel_is_exported (wayland_toplevel))
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (wayland_toplevel));
g_free (self->title);
g_clear_pointer (&self->shortcuts_inhibitors, g_hash_table_unref);
g_free (wayland_toplevel->application.application_id);
g_free (wayland_toplevel->application.app_menu_path);
g_free (wayland_toplevel->application.menubar_path);
g_free (wayland_toplevel->application.window_object_path);
g_free (wayland_toplevel->application.application_object_path);
g_free (wayland_toplevel->application.unique_bus_name);
g_free (wayland_toplevel->title);
g_clear_pointer (&wayland_toplevel->shortcuts_inhibitors, g_hash_table_unref);
G_OBJECT_CLASS (gdk_wayland_toplevel_parent_class)->finalize (object);
}
static void
gdk_wayland_toplevel_constructed (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkFrameClock *frame_clock;
frame_clock = _gdk_frame_clock_idle_new ();
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, object);
G_OBJECT_CLASS (gdk_wayland_toplevel_parent_class)->constructed (object);
}
static void
gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
{
@@ -1322,7 +1291,6 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
object_class->get_property = gdk_wayland_toplevel_get_property;
object_class->set_property = gdk_wayland_toplevel_set_property;
object_class->finalize = gdk_wayland_toplevel_finalize;
object_class->constructed = gdk_wayland_toplevel_constructed;
surface_class->compute_size = gdk_wayland_toplevel_compute_size;
@@ -1558,6 +1526,9 @@ gdk_wayland_toplevel_show (GdkWaylandToplevel *toplevel)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (toplevel);
if (!impl->display_server.wl_surface)
gdk_wayland_surface_create_wl_surface (GDK_SURFACE (impl));
if (impl->mapped)
return;
+3 -1
View File
@@ -2546,11 +2546,13 @@ transmute_cf_shell_id_list_to_text_uri_list (const guchar *data,
ILFree (file_id_full);
}
*set_data = (guchar *) result->str;
if (set_data_length)
*set_data_length = result->len;
*set_data = (guchar *) g_string_free (result, FALSE);
if (set_data_destroy)
*set_data_destroy = g_free;
g_string_free (result, FALSE);
}
void
+5 -1
View File
@@ -427,7 +427,11 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
ndevices, ncursors));
#endif
/* Create a dummy window to receive wintab events */
wintab_window = gdk_win32_drag_surface_new (display);
wintab_window =
_gdk_win32_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 2, 2);
g_object_ref (wintab_window);
+7 -8
View File
@@ -28,7 +28,6 @@
#include "gdkdisplay-win32.h"
#include "gdkdevicemanager-win32.h"
#include "gdkglcontext-win32.h"
#include "gdksurface-win32.h"
#include "gdkwin32display.h"
#include "gdkwin32screen.h"
#include "gdkwin32surface.h"
@@ -1182,7 +1181,6 @@ gdk_win32_display_init_gl (GdkDisplay *display,
{
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
HDC init_gl_hdc = NULL;
GdkGLContext *context;
if (display_win32->dummy_context_wgl.hdc == NULL)
display_win32->dummy_context_wgl.hdc = GetDC (display_win32->hwnd);
@@ -1209,7 +1207,6 @@ gdk_win32_display_init_gl (GdkDisplay *display,
{
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_EGL,
"display", display,
"allowed-apis", GDK_GL_API_GLES,
NULL);
}
else
@@ -1217,9 +1214,12 @@ gdk_win32_display_init_gl (GdkDisplay *display,
}
#endif
context = gdk_win32_display_init_wgl (display, error);
if (context)
return context;
if (gdk_win32_display_init_wgl (display, error))
{
return g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
"display", display,
NULL);
}
#ifdef HAVE_EGL
g_clear_error (error);
@@ -1267,8 +1267,6 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
object_class->dispose = gdk_win32_display_dispose;
object_class->finalize = gdk_win32_display_finalize;
display_class->toplevel_type = GDK_TYPE_WIN32_TOPLEVEL;
display_class->popup_type = GDK_TYPE_WIN32_POPUP;
display_class->cairo_context_type = GDK_TYPE_WIN32_CAIRO_CONTEXT;
display_class->get_name = gdk_win32_display_get_name;
@@ -1282,6 +1280,7 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
display_class->get_next_serial = gdk_win32_display_get_next_serial;
display_class->notify_startup_complete = gdk_win32_display_notify_startup_complete;
display_class->create_surface = _gdk_win32_display_create_surface;
display_class->get_keymap = _gdk_win32_display_get_keymap;
+1 -2
View File
@@ -24,8 +24,6 @@
#include "gdkwin32screen.h"
#include "gdkwin32cursor.h"
#include "gdkglversionprivate.h"
#ifdef HAVE_EGL
# include <epoxy/egl.h>
#endif
@@ -126,6 +124,7 @@ struct _GdkWin32Display
/* WGL/OpenGL Items */
GdkWin32GLDummyContextWGL dummy_context_wgl;
guint gl_version;
GListModel *monitors;
+41 -1
View File
@@ -37,6 +37,8 @@
#include <math.h>
#include <string.h>
#define GDK_NOTE(a,b)
/*
* Support for OLE-2 drag and drop added at Archaeopteryx Software, 2001
* For more information, do not contact Stephan R.A. Deibel (sdeibel@archaeopteryx.com),
@@ -1644,6 +1646,19 @@ _gdk_win32_dnd_exit (void)
CoUninitialize ();
}
static GdkSurface *
create_drag_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = _gdk_win32_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
0, 0, 100, 100);
return surface;
}
GdkDrag *
_gdk_win32_surface_drag_begin (GdkSurface *surface,
GdkDevice *device,
@@ -1683,7 +1698,7 @@ _gdk_win32_surface_drag_begin (GdkSurface *surface,
g_set_object (&drag_win32->grab_surface, surface);
drag_win32->drag_surface = gdk_win32_drag_surface_new (gdk_surface_get_display (surface));
drag_win32->drag_surface = create_drag_surface (gdk_surface_get_display (surface));
if (!drag_context_grab (drag))
{
@@ -1867,6 +1882,11 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
GdkDragAnim *anim;
GdkWin32Clipdrop *clipdrop;
gpointer ddd;
/*
cairo_surface_t *win_surface;
cairo_surface_t *surface;
cairo_t *cr;
*/
guint id;
GDK_NOTE (DND, g_print ("gdk_win32_drag_drop_done: 0x%p %s\n",
@@ -1896,6 +1916,26 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
return;
}
/*
win_surface = _gdk_surface_ref_cairo_surface (drag_win32->drag_surface);
surface = gdk_surface_create_similar_surface (drag_win32->drag_surface,
cairo_surface_get_content (win_surface),
gdk_surface_get_width (drag_win32->drag_surface),
gdk_surface_get_height (drag_win32->drag_surface));
cr = cairo_create (surface);
cairo_set_source_surface (cr, win_surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (win_surface);
pattern = cairo_pattern_create_for_surface (surface);
gdk_surface_set_background_pattern (drag_win32->drag_surface, pattern);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
*/
anim = g_new0 (GdkDragAnim, 1);
g_set_object (&anim->drag, drag_win32);
anim->frame_clock = gdk_surface_get_frame_clock (drag_win32->drag_surface);
+7
View File
@@ -83,13 +83,20 @@ gdk_win32_gl_context_egl_end_frame (GdkDrawContext *draw_context,
cairo_region_t *painted)
{
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
GdkWin32GLContextEGL *context_egl = GDK_WIN32_GL_CONTEXT_EGL (context);
GdkSurface *surface = gdk_gl_context_get_surface (context);
GdkDisplay *display = gdk_gl_context_get_display (context);
cairo_rectangle_int_t whole_window;
EGLSurface egl_surface;
GDK_DRAW_CONTEXT_CLASS (gdk_win32_gl_context_egl_parent_class)->end_frame (draw_context, painted);
gdk_gl_context_make_current (context);
whole_window =
(GdkRectangle) { 0, 0,
gdk_surface_get_width (surface),
gdk_surface_get_height (surface)
};
egl_surface = gdk_surface_get_egl_surface (surface);
+192 -197
View File
@@ -247,17 +247,16 @@ gdk_init_dummy_wgl_context (GdkWin32Display *display_win32)
return best_idx;
}
GdkGLContext *
gboolean
gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error)
{
int best_idx = 0;
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
GdkGLContext *context;
HDC hdc;
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
return NULL;
return FALSE;
/* acquire and cache dummy Window (HWND & HDC) and
* dummy GL Context, it is used to query functions
@@ -276,7 +275,25 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
GDK_GL_ERROR_NOT_AVAILABLE,
_("No GL implementation is available"));
return NULL;
return FALSE;
}
display_win32->gl_version = epoxy_gl_version ();
/* We must have OpenGL/WGL 2.0 or later, or have the GL_ARB_shader_objects extension */
if (display_win32->gl_version < 20)
{
if (!epoxy_has_gl_extension ("GL_ARB_shader_objects"))
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (display_win32->dummy_context_wgl.hglrc);
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("No GL implementation is available"));
return FALSE;
}
}
display_win32->hasWglARBCreateContext =
@@ -290,92 +307,45 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
display_win32->hasWglARBmultisample =
epoxy_has_wgl_extension (hdc, "WGL_ARB_multisample");
context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
"display", display,
NULL);
if (!gdk_gl_context_realize (context, error))
{
g_object_unref (context);
return NULL;
}
#if G_ENABLE_DEBUG
{
int major, minor;
gdk_gl_context_get_version (context, &major, &minor);
GDK_NOTE (OPENGL, g_print ("WGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Checked extensions:\n"
"\t* WGL_ARB_pixel_format: %s\n"
"\t* WGL_ARB_create_context: %s\n"
"\t* WGL_EXT_swap_control: %s\n"
"\t* WGL_OML_sync_control: %s\n"
"\t* WGL_ARB_multisample: %s\n",
major, minor,
glGetString (GL_VENDOR),
display_win32->hasWglARBPixelFormat ? "yes" : "no",
display_win32->hasWglARBCreateContext ? "yes" : "no",
display_win32->hasWglEXTSwapControl ? "yes" : "no",
display_win32->hasWglOMLSyncControl ? "yes" : "no",
display_win32->hasWglARBmultisample ? "yes" : "no"));
}
#endif
GDK_NOTE (OPENGL,
g_print ("WGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Checked extensions:\n"
"\t* WGL_ARB_pixel_format: %s\n"
"\t* WGL_ARB_create_context: %s\n"
"\t* WGL_EXT_swap_control: %s\n"
"\t* WGL_OML_sync_control: %s\n"
"\t* WGL_ARB_multisample: %s\n",
display_win32->gl_version / 10,
display_win32->gl_version % 10,
glGetString (GL_VENDOR),
display_win32->hasWglARBPixelFormat ? "yes" : "no",
display_win32->hasWglARBCreateContext ? "yes" : "no",
display_win32->hasWglEXTSwapControl ? "yes" : "no",
display_win32->hasWglOMLSyncControl ? "yes" : "no",
display_win32->hasWglARBmultisample ? "yes" : "no"));
wglMakeCurrent (NULL, NULL);
return context;
return TRUE;
}
/* Setup the legacy context after creating it */
static gboolean
ensure_legacy_wgl_context (HDC hdc,
HGLRC hglrc_legacy,
GdkGLContext *share,
GdkGLVersion *version,
GError **error)
ensure_legacy_wgl_context (HDC hdc,
HGLRC hglrc_legacy,
GdkGLContext *share)
{
GdkWin32GLContextWGL *context_wgl;
GdkGLVersion legacy_version;
GDK_NOTE (OPENGL,
g_print ("Creating legacy WGL context (version:%d.%d)\n",
gdk_gl_version_get_major (version),
gdk_gl_version_get_minor (version)));
if (!wglMakeCurrent (hdc, hglrc_legacy))
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return FALSE;
}
gdk_gl_version_init_epoxy (&legacy_version);
if (!gdk_gl_version_greater_equal (&legacy_version, version))
{
g_set_error (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("WGL version %d.%d is too low, need at least %d.%d"),
gdk_gl_version_get_major (&legacy_version),
gdk_gl_version_get_minor (&legacy_version),
gdk_gl_version_get_major (version),
gdk_gl_version_get_minor (version));
return FALSE;
}
*version = legacy_version;
return FALSE;
if (share != NULL)
{
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
if (!wglShareLists (hglrc_legacy, context_wgl->wgl_context))
{
g_set_error (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
_("GL implementation cannot share GL contexts"));
return FALSE;
}
return wglShareLists (hglrc_legacy, context_wgl->wgl_context);
}
return TRUE;
@@ -386,138 +356,130 @@ create_wgl_context_with_attribs (HDC hdc,
HGLRC hglrc_base,
GdkGLContext *share,
int flags,
gboolean is_legacy,
GdkGLVersion *version)
int major,
int minor,
gboolean *is_legacy)
{
HGLRC hglrc;
GdkWin32GLContextWGL *context_wgl;
const GdkGLVersion *supported_versions = gdk_gl_versions_get_for_api (GDK_GL_API_GL);
guint i;
GDK_NOTE (OPENGL,
g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s)\n",
is_legacy ? "core" : "compat",
gdk_gl_version_get_major (version),
gdk_gl_version_get_minor (version),
(flags & WGL_CONTEXT_DEBUG_BIT_ARB) ? "yes" : "no",
(flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) ? "yes" : "no"));
/* if we have wglCreateContextAttribsARB(), create a
* context with the compatibility profile if a legacy
* context is requested, or when we go into fallback mode
*/
int profile = *is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
for (i = 0; gdk_gl_version_greater_equal (&supported_versions[i], version); i++)
{
/* if we have wglCreateContextAttribsARB(), create a
* context with the compatibility profile if a legacy
* context is requested, or when we go into fallback mode
*/
int profile = is_legacy ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :
WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
int attribs[] = {
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
WGL_CONTEXT_MAJOR_VERSION_ARB, *is_legacy ? 3 : major,
WGL_CONTEXT_MINOR_VERSION_ARB, *is_legacy ? 0 : minor,
WGL_CONTEXT_FLAGS_ARB, flags,
0
};
int attribs[] = {
WGL_CONTEXT_PROFILE_MASK_ARB, profile,
WGL_CONTEXT_MAJOR_VERSION_ARB, gdk_gl_version_get_major (&supported_versions[i]),
WGL_CONTEXT_MINOR_VERSION_ARB, gdk_gl_version_get_minor (&supported_versions[i]),
WGL_CONTEXT_FLAGS_ARB, flags,
0
};
if (share != NULL)
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
if (share != NULL)
context_wgl = GDK_WIN32_GL_CONTEXT_WGL (share);
hglrc = wglCreateContextAttribsARB (hdc,
share != NULL ? context_wgl->wgl_context : NULL,
attribs);
hglrc = wglCreateContextAttribsARB (hdc,
share != NULL ? context_wgl->wgl_context : NULL,
attribs);
if (hglrc)
{
*version = supported_versions[i];
return hglrc;
}
}
return NULL;
return hglrc;
}
static HGLRC
create_wgl_context (GdkGLContext *context,
HDC hdc,
gboolean hasWglARBCreateContext,
GdkGLContext *share,
int flags,
gboolean legacy,
GError **error)
create_wgl_context (HDC hdc,
GdkGLContext *share,
int flags,
int major,
int minor,
gboolean *is_legacy,
gboolean hasWglARBCreateContext)
{
/* We need a legacy context for *all* cases */
HGLRC hglrc_base, hglrc;
GdkGLVersion version;
HGLRC hglrc_base = wglCreateContext (hdc);
gboolean success = TRUE;
/* Save up the HDC and HGLRC that we are currently using, to restore back to it when we are done here */
HDC hdc_current = wglGetCurrentDC ();
HGLRC hglrc_current = wglGetCurrentContext ();
hglrc_base = wglCreateContext (hdc);
if (hglrc_base == NULL ||
!wglMakeCurrent (hdc, hglrc_base))
/* if we have no wglCreateContextAttribsARB(), return the legacy context when all is set */
if (*is_legacy && !hasWglARBCreateContext)
{
g_clear_pointer (&hglrc_base, wglDeleteContext);
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return 0;
}
hglrc = NULL;
if (hasWglARBCreateContext)
{
if (!legacy)
if (ensure_legacy_wgl_context (hdc, hglrc_base, share))
{
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
FALSE,
&version);
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
FALSE,
&version);
wglMakeCurrent (hdc_current, hglrc_current);
return hglrc_base;
}
success = FALSE;
goto gl_fail;
}
else
{
HGLRC hglrc = NULL;
if (!wglMakeCurrent (hdc, hglrc_base))
{
success = FALSE;
goto gl_fail;
}
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
major,
minor,
is_legacy);
/* return the legacy context we have if it could be setup properly, in case the 3.0+ context creation failed */
if (hglrc == NULL)
{
legacy = TRUE;
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
TRUE,
&version);
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
TRUE,
&version);
if (!(*is_legacy))
{
/* If we aren't using a legacy context in the beginning, try again with a compatibility profile 3.0 context */
hglrc = create_wgl_context_with_attribs (hdc,
hglrc_base,
share,
flags,
0, 0,
is_legacy);
*is_legacy = TRUE;
}
if (hglrc == NULL)
{
if (!ensure_legacy_wgl_context (hdc, hglrc_base, share))
success = FALSE;
}
if (success)
GDK_NOTE (OPENGL, g_print ("Using legacy context as fallback\n"));
}
}
if (hglrc == NULL)
{
legacy = TRUE;
gdk_gl_context_get_matching_version (context,
GDK_GL_API_GL,
TRUE,
&version);
if (ensure_legacy_wgl_context (hdc, hglrc_base, share, &version, error))
hglrc = g_steal_pointer (&hglrc_base);
}
gl_fail:
if (hglrc)
{
gdk_gl_context_set_version (context, &version);
gdk_gl_context_set_is_legacy (context, legacy);
}
if (!success)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hglrc_base);
return NULL;
}
g_clear_pointer (&hglrc_base, wglDeleteContext);
wglMakeCurrent (hdc_current, hglrc_current);
wglMakeCurrent (hdc_current, hglrc_current);
if (hglrc != NULL)
{
wglDeleteContext (hglrc_base);
return hglrc;
}
return hglrc;
return hglrc_base;
}
}
static gboolean
@@ -563,6 +525,8 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
/* request flags and specific versions for core (3.2+) WGL context */
int flags = 0;
int major = 0;
int minor = 0;
HGLRC hglrc;
int pixel_format;
HDC hdc;
@@ -578,6 +542,24 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
debug_bit = gdk_gl_context_get_debug_enabled (context);
compat_bit = gdk_gl_context_get_forward_compatible (context);
/*
* We may need a Core GL 4.1+ context in order to use the GL support in
* the GStreamer media widget backend (such as on Intel drivers), but
* wglCreateContextAttribsARB() may only give us the GL context version
* that we ask for here, and nothing more. So, improve things here by
* asking for the GL version that is reported to us via epoxy_gl_version(),
* rather than the default GL core 3.2 context.
*/
gdk_gl_context_get_clipped_version (context,
display_win32->gl_version / 10,
display_win32->gl_version % 10,
&major, &minor);
if (surface != NULL)
hdc = GDK_WIN32_SURFACE (surface)->hdc;
else
hdc = display_win32->dummy_context_wgl.hdc;
/*
* A legacy context cannot be shared with core profile ones, so this means we
* must stick to a legacy context if the shared context is a legacy context
@@ -586,11 +568,6 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
? TRUE
: share != NULL && gdk_gl_context_is_legacy (share);
if (surface != NULL)
hdc = GDK_WIN32_SURFACE (surface)->hdc;
else
hdc = display_win32->dummy_context_wgl.hdc;
if (!set_wgl_pixformat_for_hdc (hdc,
&pixel_format,
display_win32))
@@ -610,15 +587,30 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
if (compat_bit)
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
hglrc = create_wgl_context (context,
hdc,
display_win32->hasWglARBCreateContext,
GDK_NOTE (OPENGL,
g_print ("Creating %s WGL context (version:%d.%d, debug:%s, forward:%s, legacy: %s)\n",
compat_bit ? "core" : "compat",
major,
minor,
debug_bit ? "yes" : "no",
compat_bit ? "yes" : "no",
legacy_bit ? "yes" : "no"));
hglrc = create_wgl_context (hdc,
share,
flags,
legacy_bit,
error);
major,
minor,
&legacy_bit,
display_win32->hasWglARBCreateContext);
if (hglrc == NULL)
return 0;
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
return 0;
}
GDK_NOTE (OPENGL,
g_print ("Created WGL context[%p], pixel_format=%d\n",
@@ -627,6 +619,9 @@ gdk_win32_gl_context_wgl_realize (GdkGLContext *context,
context_wgl->wgl_context = hglrc;
/* Ensure that any other context is created with a legacy bit set */
gdk_gl_context_set_is_legacy (context, legacy_bit);
return GDK_GL_API_GL;
}
@@ -720,11 +715,10 @@ gdk_win32_gl_context_wgl_init (GdkWin32GLContextWGL *wgl_context)
*/
gboolean
gdk_win32_display_get_wgl_version (GdkDisplay *display,
int *major,
int *minor)
int *major,
int *minor)
{
GdkGLContext *context;
GdkWin32Display *display_win32;
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
if (!GDK_IS_WIN32_DISPLAY (display))
@@ -733,11 +727,12 @@ gdk_win32_display_get_wgl_version (GdkDisplay *display,
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, NULL))
return FALSE;
context = gdk_display_get_gl_context (display);
if (context == NULL)
return FALSE;
display_win32 = GDK_WIN32_DISPLAY (display);
gdk_gl_context_get_version (context, major, minor);
if (major != NULL)
*major = display_win32->gl_version / 10;
if (minor != NULL)
*minor = display_win32->gl_version % 10;
return TRUE;
}
+4 -4
View File
@@ -64,10 +64,10 @@ struct _GdkWin32GLContextClass
typedef struct _GdkWin32GLContextWGL GdkWin32GLContextWGL;
GdkGLContext * gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error);
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
GdkWin32Surface *win32_surface);
gboolean gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error);
void gdk_win32_gl_context_wgl_bind_surface (GdkWin32GLContextWGL *ctx,
GdkWin32Surface *win32_surface);
GType gdk_win32_gl_context_wgl_get_type (void) G_GNUC_CONST;
+6 -7
View File
@@ -354,13 +354,12 @@ reset_viewport (IDirectManipulationViewport *viewport)
HRESULT hr;
hr = IDirectManipulationViewport_GetPrimaryContent (viewport, iid, (void**)&content);
HR_CHECK_GOTO (hr, failed);
HR_CHECK (hr);
hr = IDirectManipulationContent_SyncContentTransform (content, identity,
G_N_ELEMENTS (identity));
HR_CHECK_GOTO (hr, failed);
HR_CHECK (hr);
failed:
IUnknown_Release (content);
}
@@ -385,7 +384,7 @@ create_viewport (GdkSurface *surface,
{
DIRECTMANIPULATION_CONFIGURATION configuration = 0;
HWND hwnd = GDK_SURFACE_HWND (surface);
IDirectManipulationViewportEventHandler *handler = NULL;
IDirectManipulationViewportEventHandler *handler;
DWORD cookie = 0;
HRESULT hr;
@@ -501,7 +500,7 @@ void gdk_dmanipulation_initialize_surface (GdkSurface *surface)
hr = IDirectManipulationManager_Activate (dmanipulation_manager,
GDK_SURFACE_HWND (surface));
HR_CHECK_RETURN (hr);
HR_CHECK (hr);
}
void gdk_dmanipulation_finalize_surface (GdkSurface *surface)
@@ -537,11 +536,11 @@ void gdk_dmanipulation_maybe_add_contact (GdkSurface *surface,
hr = IDirectManipulationViewport_SetContact (surface_win32->dmanipulation_viewport_pan,
pointer_id);
HR_CHECK_RETURN (hr);
HR_CHECK (hr);
hr = IDirectManipulationViewport_SetContact (surface_win32->dmanipulation_viewport_zoom,
pointer_id);
HR_CHECK_RETURN (hr);
HR_CHECK (hr);
}
}
+20
View File
@@ -109,6 +109,16 @@ gdk_win32_ensure_com (void)
return co_initialized;
}
static void
gdk_win32_finalize_com (void)
{
if (co_initialized)
{
CoUninitialize ();
co_initialized = FALSE;
}
}
gboolean
gdk_win32_ensure_ole (void)
{
@@ -132,6 +142,16 @@ gdk_win32_ensure_ole (void)
return ole_initialized;
}
static void
gdk_win32_finalize_ole (void)
{
if (ole_initialized)
{
OleUninitialize ();
ole_initialized = FALSE;
}
}
void
_gdk_win32_api_failed (const char *where,
const char *api)
+9
View File
@@ -276,6 +276,7 @@ void _gdk_other_api_failed (const char *where,
#define HR_CHECK_RETURN(hr) { if G_UNLIKELY (FAILED (hr)) return; }
#define HR_CHECK_RETURN_VAL(hr, val) { if G_UNLIKELY (FAILED (hr)) return val; }
#define HR_CHECK(hr)
#define HR_CHECK_GOTO(hr, label) { if G_UNLIKELY (FAILED (hr)) goto label; }
extern LRESULT CALLBACK _gdk_win32_surface_procedure (HWND, UINT, WPARAM, LPARAM);
@@ -381,6 +382,14 @@ GdkModifierType _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap);
GdkKeymap *_gdk_win32_display_get_keymap (GdkDisplay *display);
GdkSurface *_gdk_win32_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
/* stray GdkSurfaceImplWin32 members */
void _gdk_win32_surface_register_dnd (GdkSurface *window);
void _gdk_win32_surface_unregister_dnd (GdkSurface *window);
+191 -89
View File
@@ -135,6 +135,14 @@ static void gdk_win32_impl_frame_clock_after_paint (GdkFrameClock *clock,
G_DEFINE_TYPE (GdkWin32Surface, gdk_win32_surface, GDK_TYPE_SURFACE)
GType gdk_win32_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_win32_popup_get_type (void) G_GNUC_CONST;
GType gdk_win32_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_WIN32_TOPLEVEL (gdk_win32_toplevel_get_type ())
#define GDK_TYPE_WIN32_POPUP (gdk_win32_popup_get_type ())
#define GDK_TYPE_WIN32_DRAG_SURFACE (gdk_win32_drag_surface_get_type ())
static void
gdk_win32_surface_init (GdkWin32Surface *impl)
{
@@ -204,6 +212,10 @@ gdk_surface_win32_finalize (GObject *object)
g_assert (surface->transient_owner == NULL);
g_assert (surface->transient_children == NULL);
g_signal_handlers_disconnect_by_func (GDK_SURFACE (object),
gdk_win32_toplevel_state_callback,
NULL);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -322,7 +334,7 @@ get_default_title (void)
* get its own class
*/
static ATOM
RegisterGdkClass (GType wtype)
RegisterGdkClass (GdkSurfaceType wtype)
{
static ATOM klassTOPLEVEL = 0;
static ATOM klassTEMP = 0;
@@ -395,8 +407,10 @@ RegisterGdkClass (GType wtype)
/* MSDN: CS_OWNDC is needed for OpenGL contexts */
wcl.style |= CS_OWNDC;
if (wtype != GDK_TYPE_WIN32_DRAG_SURFACE)
switch (wtype)
{
case GDK_SURFACE_TOPLEVEL:
case GDK_SURFACE_POPUP:
if (0 == klassTOPLEVEL)
{
wcl.lpszClassName = L"gdkSurfaceToplevel";
@@ -405,9 +419,9 @@ RegisterGdkClass (GType wtype)
klassTOPLEVEL = RegisterClassExW (&wcl);
}
klass = klassTOPLEVEL;
}
else
{
break;
case GDK_SURFACE_DRAG:
if (klassTEMP == 0)
{
wcl.lpszClassName = L"gdkSurfaceTemp";
@@ -417,6 +431,12 @@ RegisterGdkClass (GType wtype)
}
klass = klassTEMP;
break;
default:
g_assert_not_reached ();
break;
}
if (klass == 0)
@@ -427,20 +447,86 @@ RegisterGdkClass (GType wtype)
return klass;
}
static void
gdk_win32_surface_constructed (GObject *object)
/*
* Create native windows.
*
* With the default Gdk the created windows are mostly toplevel windows.
*
* Placement of the window is derived from the passed in window,
* except for toplevel window where OS/Window Manager placement
* is used.
*
* [1] http://mail.gnome.org/archives/gtk-devel-list/2010-August/msg00214.html
*/
GdkSurface *
_gdk_win32_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height)
{
GdkWin32Surface *impl = GDK_WIN32_SURFACE (object);
GdkSurface *surface = GDK_SURFACE (impl);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
GdkFrameClock *frame_clock;
HWND hwndNew;
HANDLE owner;
ATOM klass = 0;
DWORD dwStyle = 0, dwExStyle;
RECT rect;
GdkWin32Surface *impl;
GdkWin32Display *display_win32;
GdkSurface *surface;
const char *title;
wchar_t *wtitle;
int window_width, window_height;
int window_x, window_y;
int real_x = 0, real_y = 0;
GdkFrameClock *frame_clock;
g_return_val_if_fail (display == _gdk_display, NULL);
GDK_NOTE (MISC,
g_print ("_gdk_surface_new: %s\n", (surface_type == GDK_SURFACE_TOPLEVEL ? "TOPLEVEL" :
(surface_type == GDK_SURFACE_DRAG? "TEMP" :
(surface_type == GDK_SURFACE_DRAG ? "POPUP" : "???")))));
display_win32 = GDK_WIN32_DISPLAY (display);
if (parent)
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
else
frame_clock = _gdk_frame_clock_idle_new ();
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
impl = g_object_new (GDK_TYPE_WIN32_TOPLEVEL,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
case GDK_SURFACE_POPUP:
impl = g_object_new (GDK_TYPE_WIN32_POPUP,
"parent", parent,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
case GDK_SURFACE_DRAG:
impl = g_object_new (GDK_TYPE_WIN32_DRAG_SURFACE,
"display", display,
"frame-clock", frame_clock,
NULL);
break;
default:
g_assert_not_reached ();
break;
}
surface = GDK_SURFACE (impl);
surface->x = x;
surface->y = y;
surface->width = width;
surface->height = height;
impl->surface_scale = gdk_win32_display_get_monitor_scale_factor (display_win32, NULL, NULL);
@@ -450,60 +536,86 @@ gdk_win32_surface_constructed (GObject *object)
/* MSDN: We need WS_CLIPCHILDREN and WS_CLIPSIBLINGS for GL Context Creation */
dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
if (G_OBJECT_TYPE (impl) == GDK_TYPE_WIN32_TOPLEVEL)
switch (surface_type)
{
case GDK_SURFACE_TOPLEVEL:
dwStyle |= WS_OVERLAPPEDWINDOW;
frame_clock = _gdk_frame_clock_idle_new ();
}
else if (G_OBJECT_TYPE (impl) == GDK_TYPE_WIN32_DRAG_SURFACE)
{
break;
case GDK_SURFACE_DRAG:
dwExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
/* fall through */
case GDK_SURFACE_POPUP:
dwStyle |= WS_POPUP;
frame_clock = _gdk_frame_clock_idle_new ();
}
else if (G_OBJECT_TYPE (impl) == GDK_TYPE_WIN32_POPUP)
{
GdkSurface *parent = gdk_popup_get_parent (GDK_POPUP (impl));
dwStyle |= WS_POPUP;
owner = GDK_SURFACE_HWND (parent);
frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
}
else
{
/* Only popup and temp windows are fit to use the Owner Window mechanism */
if (parent != NULL)
owner = GDK_SURFACE_HWND (parent);
break;
default:
g_assert_not_reached ();
}
gdk_surface_set_frame_clock (surface, frame_clock);
g_object_unref (frame_clock);
rect.left = x * impl->surface_scale;
rect.top = y * impl->surface_scale;
rect.right = rect.left + width * impl->surface_scale;
rect.bottom = rect.top + height * impl->surface_scale;
AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
real_x = x * impl->surface_scale;
real_y = y * impl->surface_scale;
if (surface_type == GDK_SURFACE_TOPLEVEL)
{
/* We initially place it at default so that we can get the
default window positioning if we want */
window_x = window_y = CW_USEDEFAULT;
}
else
{
/* TEMP: Put these where requested */
window_x = real_x;
window_y = real_y;
}
window_width = rect.right - rect.left;
window_height = rect.bottom - rect.top;
title = get_default_title ();
if (!title || !*title)
title = "";
klass = RegisterGdkClass (G_OBJECT_TYPE (impl));
klass = RegisterGdkClass (surface_type);
wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
impl->handle = CreateWindowExW (dwExStyle,
MAKEINTRESOURCEW (klass),
wtitle,
dwStyle,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
owner,
NULL,
_gdk_dll_hinstance,
surface);
if (impl->handle == NULL)
{
WIN32_API_FAILED ("CreateWindowExW");
g_error ("Fatal error: CreateWindowExW failed.");
}
hwndNew = CreateWindowExW (dwExStyle,
MAKEINTRESOURCEW (klass),
wtitle,
dwStyle,
window_x, window_y,
window_width, window_height,
owner,
NULL,
_gdk_dll_hinstance,
surface);
impl->handle = hwndNew;
GetWindowRect (impl->handle, &rect);
GetWindowRect (hwndNew, &rect);
impl->initial_x = rect.left;
impl->initial_y = rect.top;
/* Now we know the initial position, move to actually specified position */
if (real_x != window_x || real_y != window_y)
{
API_CALL (SetWindowPos, (hwndNew,
SWP_NOZORDER_SPECIFIED,
real_x, real_y, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
}
g_object_ref (impl);
/* Take note: we're inserting a pointer into a heap-allocated
* object (impl). Inserting a pointer to a stack variable
@@ -515,11 +627,26 @@ gdk_win32_surface_constructed (GObject *object)
*/
gdk_win32_handle_table_insert (&GDK_SURFACE_HWND (impl), impl);
GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
title,
window_width, window_height,
surface->x,
surface->y,
owner,
hwndNew));
g_free (wtitle);
if (impl->handle == NULL)
{
WIN32_API_FAILED ("CreateWindowExW");
g_object_unref (impl);
return NULL;
}
gdk_surface_set_egl_native_window (surface, (void *) impl->handle);
if (G_OBJECT_TYPE (impl) != GDK_TYPE_WIN32_DRAG_SURFACE)
if (surface_type != GDK_SURFACE_DRAG)
{
if (display_win32->tablet_input_api == GDK_WIN32_TABLET_INPUT_API_WINPOINTER)
gdk_winpointer_initialize_surface (surface);
@@ -536,10 +663,18 @@ gdk_win32_surface_constructed (GObject *object)
G_CALLBACK (gdk_win32_impl_frame_clock_after_paint),
impl);
g_object_unref (frame_clock);
impl->hdc = GetDC (impl->handle);
impl->inhibit_configure = TRUE;
G_OBJECT_CLASS (parent_class)->constructed (object);
if (surface_type == GDK_SURFACE_TOPLEVEL)
{
g_signal_connect (surface, "notify::state",
G_CALLBACK (gdk_win32_toplevel_state_callback),
NULL);
}
return surface;
}
static void
@@ -4501,7 +4636,6 @@ gdk_win32_surface_class_init (GdkWin32SurfaceClass *klass)
parent_class = g_type_class_peek_parent (klass);
object_class->constructed = gdk_win32_surface_constructed;
object_class->dispose = gdk_surface_win32_dispose;
object_class->finalize = gdk_surface_win32_finalize;
@@ -4690,20 +4824,15 @@ G_DEFINE_TYPE_WITH_CODE (GdkWin32Toplevel, gdk_win32_toplevel, GDK_TYPE_WIN32_SU
gdk_win32_toplevel_iface_init))
static void
gdk_win32_toplevel_constructed (GObject *object)
gdk_win32_toplevel_init (GdkWin32Toplevel *toplevel)
{
g_signal_connect (object, "notify::state",
G_CALLBACK (gdk_win32_toplevel_state_callback),
NULL);
G_OBJECT_CLASS (gdk_win32_toplevel_parent_class)->constructed (object);
}
static void
gdk_win32_toplevel_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GdkSurface *surface = GDK_SURFACE (object);
@@ -4762,9 +4891,9 @@ gdk_win32_toplevel_set_property (GObject *object,
static void
gdk_win32_toplevel_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GdkSurface *surface = GDK_SURFACE (object);
@@ -4813,36 +4942,17 @@ gdk_win32_toplevel_get_property (GObject *object,
}
}
static void
gdk_win32_toplevel_finalize (GObject *object)
{
GdkWin32Surface *self = GDK_WIN32_SURFACE (object);
g_signal_handlers_disconnect_by_func (self,
gdk_win32_toplevel_state_callback,
NULL);
G_OBJECT_CLASS (gdk_win32_toplevel_parent_class)->finalize (object);
}
static void
gdk_win32_toplevel_class_init (GdkWin32ToplevelClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->constructed = gdk_win32_toplevel_constructed;
object_class->finalize = gdk_win32_toplevel_finalize;
object_class->get_property = gdk_win32_toplevel_get_property;
object_class->set_property = gdk_win32_toplevel_set_property;
gdk_toplevel_install_properties (object_class, 1);
}
static void
gdk_win32_toplevel_init (GdkWin32Toplevel *toplevel)
{
}
static void
gdk_win32_toplevel_present (GdkToplevel *toplevel,
GdkToplevelLayout *layout)
@@ -5118,11 +5228,3 @@ _gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface)
}
#endif
}
GdkSurface *
gdk_win32_drag_surface_new (GdkDisplay *display)
{
return g_object_new (GDK_TYPE_WIN32_DRAG_SURFACE,
"display", display,
NULL);
}
-10
View File
@@ -39,14 +39,6 @@
G_BEGIN_DECLS
GType gdk_win32_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_win32_popup_get_type (void) G_GNUC_CONST;
GType gdk_win32_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_WIN32_TOPLEVEL (gdk_win32_toplevel_get_type ())
#define GDK_TYPE_WIN32_POPUP (gdk_win32_popup_get_type ())
#define GDK_TYPE_WIN32_DRAG_SURFACE (gdk_win32_drag_surface_get_type ())
typedef enum
{
GDK_DECOR_ALL = 1 << 0,
@@ -372,8 +364,6 @@ void gdk_win32_surface_move_resize (GdkSurface *window,
int width,
int height);
GdkSurface *gdk_win32_drag_surface_new (GdkDisplay *display);
RECT
gdk_win32_surface_handle_queued_move_resize (GdkDrawContext *draw_context);
+6 -3
View File
@@ -1391,7 +1391,11 @@ gdk_x11_display_init_leader_surface (GdkX11Display *self)
gdk_event_init (display);
self->leader_gdk_surface = gdk_x11_drag_surface_new (display);
self->leader_gdk_surface =
_gdk_x11_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
-100, -100, 1, 1);
(_gdk_x11_surface_get_toplevel (self->leader_gdk_surface))->is_leader = TRUE;
self->leader_window = GDK_SURFACE_XID (self->leader_gdk_surface);
@@ -3028,8 +3032,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
object_class->dispose = gdk_x11_display_dispose;
object_class->finalize = gdk_x11_display_finalize;
display_class->toplevel_type = GDK_TYPE_X11_TOPLEVEL;
display_class->popup_type = GDK_TYPE_X11_POPUP;
display_class->cairo_context_type = GDK_TYPE_X11_CAIRO_CONTEXT;
#ifdef GDK_RENDERING_VULKAN
display_class->vk_context_type = GDK_TYPE_X11_VULKAN_CONTEXT;
@@ -3050,6 +3052,7 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
display_class->get_startup_notification_id = gdk_x11_display_get_startup_notification_id;
G_GNUC_END_IGNORE_DEPRECATIONS
display_class->notify_startup_complete = gdk_x11_display_notify_startup_complete;
display_class->create_surface = _gdk_x11_display_create_surface;
display_class->get_keymap = gdk_x11_display_get_keymap;
display_class->init_gl = gdk_x11_display_init_gl;
+43 -2
View File
@@ -1255,6 +1255,19 @@ gdk_drag_do_leave (GdkX11Drag *drag_x11)
}
}
static GdkSurface *
create_drag_surface (GdkDisplay *display)
{
GdkSurface *surface;
surface = _gdk_x11_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
0, 0, 100, 100);
return surface;
}
static Window
_gdk_x11_display_get_drag_protocol (GdkDisplay *display,
Window xid,
@@ -1830,6 +1843,11 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
{
GdkX11Drag *x11_drag = GDK_X11_DRAG (drag);
GdkDragAnim *anim;
/*
cairo_surface_t *win_surface;
cairo_surface_t *surface;
cairo_t *cr;
*/
guint id;
gdk_x11_drag_release_selection (drag);
@@ -1844,6 +1862,26 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
return;
}
/*
win_surface = _gdk_surface_ref_cairo_surface (x11_drag->drag_surface);
surface = gdk_surface_create_similar_surface (x11_drag->drag_surface,
cairo_surface_get_content (win_surface),
gdk_surface_get_width (x11_drag->drag_surface),
gdk_surface_get_height (x11_drag->drag_surface));
cr = cairo_create (surface);
cairo_set_source_surface (cr, win_surface, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (win_surface);
pattern = cairo_pattern_create_for_surface (surface);
gdk_surface_set_background_pattern (x11_drag->drag_surface, pattern);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
*/
anim = g_new0 (GdkDragAnim, 1);
anim->drag = g_object_ref (x11_drag);
anim->frame_clock = gdk_surface_get_frame_clock (x11_drag->drag_surface);
@@ -1988,7 +2026,10 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
display = gdk_surface_get_display (surface);
ipc_surface = gdk_x11_drag_surface_new (display);
ipc_surface = _gdk_x11_display_create_surface (display,
GDK_SURFACE_DRAG,
NULL,
-99, -99, 1, 1);
drag = (GdkDrag *) g_object_new (GDK_TYPE_X11_DRAG,
"surface", ipc_surface,
@@ -2022,7 +2063,7 @@ _gdk_x11_surface_drag_begin (GdkSurface *surface,
gdk_surface_set_is_mapped (x11_drag->ipc_surface, TRUE);
gdk_x11_surface_show (x11_drag->ipc_surface, FALSE);
x11_drag->drag_surface = gdk_x11_drag_surface_new (display);
x11_drag->drag_surface = create_drag_surface (display);
if (!drag_grab (drag))
{
+25 -45
View File
@@ -477,11 +477,8 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
GdkSurface *surface = gdk_gl_context_get_surface (context);
GLXContext ctx;
int context_attribs[N_GLX_ATTRS], i = 0, flags = 0;
gsize major_idx, minor_idx;
GdkGLVersion version;
const GdkGLVersion* supported_versions;
int min_major, min_minor, major, minor;
gboolean debug_bit, compat_bit;
gsize j;
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
return 0;
@@ -491,7 +488,10 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
/* We will use the default version matching the context status
* unless the user requested a version which makes sense */
gdk_gl_context_get_matching_version (context, api, legacy, &version);
gdk_gl_context_get_matching_version (api, legacy, 0,
&min_major, &min_minor);
gdk_gl_context_get_clipped_version (context, min_major, min_minor,
&major, &minor);
debug_bit = gdk_gl_context_get_debug_enabled (context);
compat_bit = gdk_gl_context_get_forward_compatible (context);
@@ -511,9 +511,9 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
context_attribs[i++] = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
context_attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB;
major_idx = i++;
context_attribs[i++] = major;
context_attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB;
minor_idx = i++;
context_attribs[i++] = minor;
context_attribs[i++] = GLX_CONTEXT_FLAGS_ARB;
context_attribs[i++] = flags;
@@ -522,7 +522,7 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
GDK_DISPLAY_DEBUG (display, OPENGL,
"Creating GLX context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
gdk_gl_version_get_major (&version), gdk_gl_version_get_minor (&version),
major, minor,
debug_bit ? "yes" : "no",
compat_bit ? "yes" : "no",
legacy ? "yes" : "no",
@@ -533,44 +533,25 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
gdk_x11_display_error_trap_push (display);
supported_versions = gdk_gl_versions_get_for_api (api);
for (j = 0; gdk_gl_version_greater_equal (&supported_versions[j], &version); j++)
{
context_attribs [major_idx] = gdk_gl_version_get_major (&supported_versions[j]);
context_attribs [minor_idx] = gdk_gl_version_get_minor (&supported_versions[j]);
/* If we don't have access to GLX_ARB_create_context_profile, then
* we have to fall back to the old GLX 1.3 API.
*/
if (legacy && !display_x11->has_glx_create_context)
ctx = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
GLX_RGBA_TYPE,
share_glx != NULL ? share_glx->glx_context : NULL,
TRUE);
/* If we don't have access to GLX_ARB_create_context_profile, then
* we have to fall back to the old GLX 1.3 API.
*/
if (legacy && !display_x11->has_glx_create_context)
ctx = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
GLX_RGBA_TYPE,
share_glx != NULL ? share_glx->glx_context : NULL,
TRUE);
else
ctx = glXCreateContextAttribsARB (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
share_glx != NULL ? share_glx->glx_context : NULL,
True,
context_attribs);
else
ctx = glXCreateContextAttribsARB (gdk_x11_display_get_xdisplay (display),
display_x11->glx_config,
share_glx != NULL ? share_glx->glx_context : NULL,
True,
context_attribs);
if (ctx)
break;
}
if (ctx == NULL)
{
gdk_x11_display_error_trap_pop_ignored (display);
return 0;
}
if (gdk_x11_display_error_trap_pop (display))
{
glXDestroyContext (dpy, ctx);
return 0;
}
if (gdk_x11_display_error_trap_pop (display) || ctx == NULL)
return 0;
GDK_DISPLAY_DEBUG (display, OPENGL,
"Realized GLX context[%p], %s, version: %d.%d",
@@ -580,7 +561,6 @@ gdk_x11_context_create_glx_context (GdkGLContext *context,
display_x11->glx_version % 10);
context_glx->glx_context = ctx;
gdk_gl_context_set_version (context, &supported_versions[j]);
gdk_gl_context_set_is_legacy (context, legacy);
#ifdef HAVE_XDAMAGE
+7
View File
@@ -173,6 +173,13 @@ void _gdk_x11_display_get_maximal_cursor_size (GdkDisplay *display,
guint *width,
guint *height);
GdkSurface * _gdk_x11_display_create_surface (GdkDisplay *display,
GdkSurfaceType surface_type,
GdkSurface *parent,
int x,
int y,
int width,
int height);
GList * gdk_x11_display_get_toplevel_windows (GdkDisplay *display);
void _gdk_x11_precache_atoms (GdkDisplay *display,
+464 -452
View File
File diff suppressed because it is too large Load Diff
-10
View File
@@ -36,14 +36,6 @@
G_BEGIN_DECLS
GType gdk_x11_toplevel_get_type (void) G_GNUC_CONST;
GType gdk_x11_popup_get_type (void) G_GNUC_CONST;
GType gdk_x11_drag_surface_get_type (void) G_GNUC_CONST;
#define GDK_TYPE_X11_TOPLEVEL (gdk_x11_toplevel_get_type ())
#define GDK_TYPE_X11_POPUP (gdk_x11_popup_get_type ())
#define GDK_TYPE_X11_DRAG_SURFACE (gdk_x11_drag_surface_get_type ())
typedef struct _GdkToplevelX11 GdkToplevelX11;
typedef struct _GdkXPositionInfo GdkXPositionInfo;
@@ -199,8 +191,6 @@ struct _GdkToplevelX11
#endif
};
GdkSurface *gdk_x11_drag_surface_new (GdkDisplay *display);
GdkToplevelX11 *_gdk_x11_surface_get_toplevel (GdkSurface *window);
GdkCursor *_gdk_x11_surface_get_cursor (GdkSurface *window);
-1
View File
@@ -78,7 +78,6 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
target == GL_TEXTURE_2D ||
target == GL_TEXTURE_3D);
g_assert (texture >= GL_TEXTURE0 && texture <= GL_TEXTURE16);
g_assert (texture - GL_TEXTURE0 < G_N_ELEMENTS (self->textures));
attach = &self->textures[texture - GL_TEXTURE0];
+2 -4
View File
@@ -73,13 +73,11 @@ struct _GskGLBindFramebuffer
G_STATIC_ASSERT (sizeof (GskGLBindFramebuffer) == 4);
/* Increase if shaders add more textures */
#define GSK_GL_MAX_TEXTURES_PER_PROGRAM 4
struct _GskGLAttachmentState
{
GskGLBindFramebuffer fbo;
GskGLBindTexture textures[GSK_GL_MAX_TEXTURES_PER_PROGRAM];
/* Increase if shaders add more textures */
GskGLBindTexture textures[4];
guint n_changed;
};
+27 -66
View File
@@ -427,7 +427,6 @@ gsk_gl_command_queue_dispose (GObject *object)
gsk_gl_command_batches_clear (&self->batches);
gsk_gl_command_binds_clear (&self->batch_binds);
gsk_gl_command_uniforms_clear (&self->batch_uniforms);
gsk_gl_syncs_clear (&self->syncs);
gsk_gl_buffer_destroy (&self->vertices);
@@ -450,7 +449,6 @@ gsk_gl_command_queue_init (GskGLCommandQueue *self)
gsk_gl_command_batches_init (&self->batches, 128);
gsk_gl_command_binds_init (&self->batch_binds, 1024);
gsk_gl_command_uniforms_init (&self->batch_uniforms, 2048);
gsk_gl_syncs_init (&self->syncs, 10);
gsk_gl_buffer_init (&self->vertices, GL_ARRAY_BUFFER, sizeof (GskGLDrawVertex));
}
@@ -493,7 +491,7 @@ gsk_gl_command_queue_new (GdkGLContext *context,
}
}
self->has_samplers = gdk_gl_context_check_version (context, "3.3", "3.0");
self->has_samplers = gdk_gl_context_check_version (context, 3, 3, 3, 0);
/* create the samplers */
if (self->has_samplers)
@@ -1022,14 +1020,14 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
guint program = 0;
guint width = 0;
guint height = 0;
G_GNUC_UNUSED unsigned int n_binds = 0;
G_GNUC_UNUSED unsigned int n_fbos = 0;
G_GNUC_UNUSED unsigned int n_uniforms = 0;
G_GNUC_UNUSED unsigned int n_programs = 0;
G_GNUC_UNUSED guint n_binds = 0;
guint n_fbos = 0;
G_GNUC_UNUSED guint n_uniforms = 0;
guint n_programs = 0;
guint vao_id;
guint vbo_id;
int textures[GSK_GL_MAX_TEXTURES_PER_PROGRAM];
int samplers[GSK_GL_MAX_TEXTURES_PER_PROGRAM];
int textures[4];
int samplers[4];
int framebuffer = -1;
int next_batch_index;
int active = -1;
@@ -1062,11 +1060,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation (GL_FUNC_ADD);
if (!gdk_gl_context_get_use_es (self->context))
{
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
}
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
vbo_id = gsk_gl_buffer_submit (&self->vertices);
@@ -1162,26 +1157,16 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
{
const GskGLCommandBind *bind = &self->batch_binds.items[batch->draw.bind_offset];
g_assert (bind->texture < G_N_ELEMENTS (textures));
for (guint i = 0; i < batch->draw.bind_count; i++)
{
if (textures[bind->texture] != bind->id)
{
GskGLSync *s;
if (active != bind->texture)
{
active = bind->texture;
glActiveTexture (GL_TEXTURE0 + bind->texture);
}
s = gsk_gl_syncs_get_sync (&self->syncs, bind->id);
if (s && s->sync)
{
glWaitSync ((GLsync) s->sync, 0, GL_TIMEOUT_IGNORED);
s->sync = NULL;
}
glBindTexture (GL_TEXTURE_2D, bind->id);
textures[bind->texture] = bind->id;
if (!self->has_samplers)
@@ -1249,8 +1234,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
}
glDeleteBuffers (1, &vbo_id);
if (!gdk_gl_context_get_use_es (self->context))
glDeleteVertexArrays (1, &vao_id);
glDeleteVertexArrays (1, &vao_id);
gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds);
gdk_profiler_set_int_counter (self->metrics.n_uniforms, n_uniforms);
@@ -1327,7 +1311,6 @@ gsk_gl_command_queue_end_frame (GskGLCommandQueue *self)
self->batches.len = 0;
self->batch_binds.len = 0;
self->batch_uniforms.len = 0;
self->syncs.len = 0;
self->n_uploads = 0;
self->tail_batch_index = -1;
self->in_frame = FALSE;
@@ -1442,44 +1425,28 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
static GdkMemoryFormat
memory_format_gl_format (GdkMemoryFormat data_format,
gboolean use_es,
guint major,
guint minor,
guint *gl_internalformat,
guint *gl_format,
guint *gl_type)
{
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
return data_format;
if (gdk_memory_format_prefers_high_depth (data_format))
{
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
return data_format;
}
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type))
{
g_assert_not_reached ();
if (gdk_memory_format_prefers_high_depth (data_format))
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
else
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
use_es,
gl_internalformat,
gl_format,
gl_type))
{
g_assert_not_reached ();
}
}
return data_format;
@@ -1491,6 +1458,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
int x,
int y)
{
GdkGLContext *context;
const guchar *data;
gsize stride;
GBytes *bytes;
@@ -1502,18 +1470,15 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
GLenum gl_type;
gsize bpp;
gboolean use_es;
int major, minor;
use_es = gdk_gl_context_get_use_es (self->context);
gdk_gl_context_get_version (self->context, &major, &minor);
context = gdk_gl_context_get_current ();
use_es = gdk_gl_context_get_use_es (context);
data_format = gdk_texture_get_format (texture);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
data_format = memory_format_gl_format (data_format,
use_es,
major,
minor,
&gl_internalformat,
&gl_format,
&gl_type);
@@ -1535,7 +1500,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, data);
}
else if (stride % bpp == 0 &&
(gdk_gl_context_check_version (self->context, NULL, "3.0") || gdk_gl_context_has_unpack_subimage (self->context)))
(gdk_gl_context_check_version (context, 0, 0, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
@@ -1567,7 +1532,6 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
GLenum gl_type;
gboolean use_es;
int texture_id;
int major, minor;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
@@ -1600,13 +1564,10 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
glBindTexture (GL_TEXTURE_2D, texture_id);
/* Initialize the texture */
use_es = gdk_gl_context_get_use_es (self->context);
gdk_gl_context_get_version (self->context, &major, &minor);
use_es = gdk_gl_context_get_use_es (gdk_gl_context_get_current ());
data_format = gdk_texture_get_format (chunks[0].texture);
memory_format_gl_format (data_format,
use_es,
major,
minor,
&gl_internalformat,
&gl_format,
&gl_type);
-41
View File
@@ -168,15 +168,9 @@ typedef union _GskGLCommandBatch
G_STATIC_ASSERT (sizeof (GskGLCommandBatch) == 32);
typedef struct _GskGLSync {
guint id;
gpointer sync;
} GskGLSync;
DEFINE_INLINE_ARRAY (GskGLCommandBatches, gsk_gl_command_batches, GskGLCommandBatch)
DEFINE_INLINE_ARRAY (GskGLCommandBinds, gsk_gl_command_binds, GskGLCommandBind)
DEFINE_INLINE_ARRAY (GskGLCommandUniforms, gsk_gl_command_uniforms, GskGLCommandUniform)
DEFINE_INLINE_ARRAY (GskGLSyncs, gsk_gl_syncs, GskGLSync)
struct _GskGLCommandQueue
{
@@ -239,10 +233,6 @@ struct _GskGLCommandQueue
*/
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
/* Array of sync objects to wait on.
*/
GskGLSyncs syncs;
/* Discovered max texture size when loading the command queue so that we
* can either scale down or slice textures to fit within this size. Assumed
* to be both height and width.
@@ -381,36 +371,5 @@ gsk_gl_command_queue_bind_framebuffer (GskGLCommandQueue *self,
return ret;
}
static inline GskGLSync *
gsk_gl_syncs_get_sync (GskGLSyncs *syncs,
guint id)
{
for (unsigned int i = 0; i < syncs->len; i++)
{
GskGLSync *sync = &syncs->items[i];
if (sync->id == id)
return sync;
}
return NULL;
}
static inline void
gsk_gl_syncs_add_sync (GskGLSyncs *syncs,
guint id,
gpointer sync)
{
GskGLSync *s;
s = gsk_gl_syncs_get_sync (syncs, id);
if (s)
g_assert (s->sync == sync);
else
{
s = gsk_gl_syncs_append (syncs);
s->id = id;
s->sync = sync;
}
}
G_END_DECLS
+18 -36
View File
@@ -1121,27 +1121,19 @@ gsk_gl_driver_lookup_shader (GskGLDriver *self,
}
#ifdef G_ENABLE_DEBUG
void
gsk_gl_driver_save_texture_to_png (GskGLDriver *driver,
int texture_id,
int width,
int height,
const char *filename)
static void
write_atlas_to_png (GskGLDriver *driver,
GskGLTextureAtlas *atlas,
const char *filename)
{
GdkGLTextureBuilder *builder;
GdkTexture *texture;
builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, gsk_gl_driver_get_context (driver));
gdk_gl_texture_builder_set_id (builder, texture_id);
gdk_gl_texture_builder_set_width (builder, width);
gdk_gl_texture_builder_set_height (builder, height);
texture = gdk_gl_texture_builder_build (builder, NULL, NULL);
texture = gdk_gl_texture_new (gsk_gl_driver_get_context (driver),
atlas->texture_id,
atlas->width, atlas->height,
NULL, NULL);
gdk_texture_save_to_png (texture, filename);
g_object_unref (texture);
g_object_unref (builder);
}
void
@@ -1170,7 +1162,7 @@ gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
G_DIR_SEPARATOR_S,
(int)self->current_frame_id,
atlas->texture_id);
gsk_gl_driver_save_texture_to_png (self, atlas->texture_id, atlas->width, atlas->height, filename);
write_atlas_to_png (self, atlas, filename);
g_free (filename);
}
@@ -1565,7 +1557,6 @@ typedef struct _GskGLTextureState
{
GdkGLContext *context;
GLuint texture_id;
GLsync sync;
} GskGLTextureState;
static void
@@ -1578,8 +1569,6 @@ create_texture_from_texture_destroy (gpointer data)
gdk_gl_context_make_current (state->context);
glDeleteTextures (1, &state->texture_id);
if (state->sync)
glDeleteSync (state->sync);
g_clear_object (&state->context);
g_free (state);
}
@@ -1589,9 +1578,8 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id)
{
GskGLTextureState *state;
GdkGLTextureBuilder *builder;
GskGLTexture *texture;
GdkTexture *result;
int width, height;
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL);
g_return_val_if_fail (self->command_queue != NULL, NULL);
@@ -1606,25 +1594,19 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
state = g_new0 (GskGLTextureState, 1);
state->texture_id = texture_id;
state->context = g_object_ref (self->command_queue->context);
if (gdk_gl_context_has_sync (self->command_queue->context))
state->sync = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
g_hash_table_steal (self->textures, GUINT_TO_POINTER (texture_id));
builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, self->command_queue->context);
gdk_gl_texture_builder_set_id (builder, texture_id);
gdk_gl_texture_builder_set_width (builder, texture->width);
gdk_gl_texture_builder_set_height (builder, texture->height);
gdk_gl_texture_builder_set_sync (builder, state->sync);
result = gdk_gl_texture_builder_build (builder,
create_texture_from_texture_destroy,
state);
width = texture->width;
height = texture->height;
texture->texture_id = 0;
gsk_gl_texture_free (texture);
g_object_unref (builder);
return result;
return gdk_gl_texture_new (self->command_queue->context,
texture_id,
width,
height,
create_texture_from_texture_destroy,
state);
}
+1 -6
View File
@@ -176,13 +176,8 @@ GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *s
GError **error);
#ifdef G_ENABLE_DEBUG
void gsk_gl_driver_save_texture_to_png (GskGLDriver *self,
int texture_id,
int width,
int height,
const char *filename);
void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
const char *filename);
const char *directory);
#endif
static inline GskGLTexture *
+3 -3
View File
@@ -18,9 +18,9 @@ struct _GskGLProfiler
GLuint gl_queries[N_QUERIES];
GLuint active_query;
unsigned int has_queries : 1;
unsigned int has_timer : 1;
unsigned int first_frame : 1;
gboolean has_queries : 1;
gboolean has_timer : 1;
gboolean first_frame : 1;
};
enum {
-16
View File
@@ -285,22 +285,6 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
GL_LINEAR);
}
static inline void
gsk_gl_program_set_uniform_texture_with_sync (GskGLProgram *self,
guint key,
guint stamp,
GLenum texture_target,
GLenum texture_slot,
guint texture_id,
GLint min_filter,
GLint max_filter,
gpointer sync)
{
gsk_gl_program_set_uniform_texture_with_filter (self, key, stamp, texture_target, texture_slot, texture_id,
min_filter, max_filter);
gsk_gl_syncs_add_sync (&self->driver->command_queue->syncs, texture_id, sync);
}
static inline void
gsk_gl_program_set_uniform_matrix (GskGLProgram *self,
guint key,
+2 -7
View File
@@ -356,8 +356,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
for (x = 0; x < width; x += max_size)
{
texture = gsk_gl_renderer_render_texture (renderer, root,
&GRAPHENE_RECT_INIT (viewport->origin.x + x,
viewport->origin.y + y,
&GRAPHENE_RECT_INIT (x, y,
MIN (max_size, viewport->size.width - x),
MIN (max_size, viewport->size.height - y)));
gdk_texture_download (texture,
@@ -373,11 +372,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
return texture;
}
if (gsk_render_node_prefers_high_depth (root) &&
gdk_gl_context_check_version (self->context, "3.0", "3.0"))
format = GL_RGBA32F;
else
format = GL_RGBA8;
format = gsk_render_node_prefers_high_depth (root) ? GL_RGBA32F : GL_RGBA8;
gdk_gl_context_make_current (self->context);
+184 -226
View File
@@ -54,6 +54,27 @@
/* Make sure gradient stops fits in packed array_count */
G_STATIC_ASSERT ((MAX_GRADIENT_STOPS * 5) < (1 << GSK_GL_UNIFORM_ARRAY_BITS));
#define rounded_rect_top_left(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x, \
r->bounds.origin.y, \
r->corner[0].width, r->corner[0].height))
#define rounded_rect_top_right(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[1].width, \
r->bounds.origin.y, \
r->corner[1].width, r->corner[1].height))
#define rounded_rect_bottom_right(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[2].width, \
r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
r->corner[2].width, r->corner[2].height))
#define rounded_rect_bottom_left(r) \
(GRAPHENE_RECT_INIT(r->bounds.origin.x, \
r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
r->corner[3].width, r->corner[3].height))
#define rounded_rect_corner0(r) rounded_rect_top_left(r)
#define rounded_rect_corner1(r) rounded_rect_top_right(r)
#define rounded_rect_corner2(r) rounded_rect_bottom_right(r)
#define rounded_rect_corner3(r) rounded_rect_bottom_left(r)
#define rounded_rect_corner(r, i) (rounded_rect_corner##i(r))
#define ALPHA_IS_CLEAR(alpha) ((alpha) < ((float) 0x00ff / (float) 0xffff))
#define RGBA_IS_CLEAR(rgba) ALPHA_IS_CLEAR((rgba)->alpha)
@@ -170,7 +191,6 @@ typedef struct _GskGLRenderOffscreen
/* Return location for texture ID */
guint texture_id;
gpointer sync;
/* Whether to force creating a new texture, even if the
* input already is a texture
@@ -235,7 +255,7 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
static inline gboolean G_GNUC_PURE
node_supports_2d_transform (const GskRenderNode *node)
{
switch (gsk_render_node_get_node_type (node))
switch ((int)gsk_render_node_get_node_type (node))
{
case GSK_COLOR_NODE:
case GSK_OPACITY_NODE:
@@ -253,7 +273,6 @@ node_supports_2d_transform (const GskRenderNode *node)
case GSK_CAIRO_NODE:
case GSK_BLEND_NODE:
case GSK_BLUR_NODE:
case GSK_MASK_NODE:
return TRUE;
case GSK_SHADOW_NODE:
@@ -270,18 +289,8 @@ node_supports_2d_transform (const GskRenderNode *node)
}
return TRUE;
case GSK_BORDER_NODE:
case GSK_INSET_SHADOW_NODE:
case GSK_OUTSET_SHADOW_NODE:
case GSK_REPEAT_NODE:
case GSK_CLIP_NODE:
case GSK_ROUNDED_CLIP_NODE:
case GSK_GL_SHADER_NODE:
return FALSE;
case GSK_NOT_A_RENDER_NODE:
default:
g_assert_not_reached ();
return FALSE;
}
}
@@ -295,7 +304,7 @@ node_supports_transform (const GskRenderNode *node)
* opacity or color matrix.
*/
switch (gsk_render_node_get_node_type (node))
switch ((int)gsk_render_node_get_node_type (node))
{
case GSK_COLOR_NODE:
case GSK_OPACITY_NODE:
@@ -316,25 +325,8 @@ node_supports_transform (const GskRenderNode *node)
case GSK_TRANSFORM_NODE:
return node_supports_transform (gsk_transform_node_get_child (node));
case GSK_CONTAINER_NODE:
case GSK_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_RADIAL_GRADIENT_NODE:
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
case GSK_CONIC_GRADIENT_NODE:
case GSK_BORDER_NODE:
case GSK_INSET_SHADOW_NODE:
case GSK_OUTSET_SHADOW_NODE:
case GSK_REPEAT_NODE:
case GSK_CLIP_NODE:
case GSK_ROUNDED_CLIP_NODE:
case GSK_GL_SHADER_NODE:
case GSK_TEXTURE_SCALE_NODE:
return FALSE;
case GSK_NOT_A_RENDER_NODE:
default:
g_assert_not_reached ();
return FALSE;
}
}
@@ -408,6 +400,70 @@ rect_intersects (const graphene_rect_t *r1,
return TRUE;
}
static inline gboolean
rounded_rect_has_corner (const GskRoundedRect *r,
guint i)
{
return r->corner[i].width > 0 && r->corner[i].height > 0;
}
/* Current clip is NOT rounded but new one is definitely! */
static inline gboolean
intersect_rounded_rectilinear (const graphene_rect_t *non_rounded,
const GskRoundedRect *rounded,
GskRoundedRect *result)
{
gboolean corners[4];
/* Intersects with top left corner? */
corners[0] = rounded_rect_has_corner (rounded, 0) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 0));
if (corners[0] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 0)))
return FALSE;
/* top right ? */
corners[1] = rounded_rect_has_corner (rounded, 1) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 1));
if (corners[1] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 1)))
return FALSE;
/* bottom right ? */
corners[2] = rounded_rect_has_corner (rounded, 2) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 2));
if (corners[2] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 2)))
return FALSE;
/* bottom left ? */
corners[3] = rounded_rect_has_corner (rounded, 3) &&
rect_intersects (non_rounded,
&rounded_rect_corner (rounded, 3));
if (corners[3] && !rect_contains_rect (non_rounded,
&rounded_rect_corner (rounded, 3)))
return FALSE;
/* We do intersect with at least one of the corners, but in such a way that the
* intersection between the two clips can still be represented by a single rounded
* rect in a trivial way. do that.
*/
graphene_rect_intersection (non_rounded, &rounded->bounds, &result->bounds);
for (guint i = 0; i < 4; i++)
{
if (corners[i])
result->corner[i] = rounded->corner[i];
else
result->corner[i].width = result->corner[i].height = 0;
}
return TRUE;
}
static inline void
init_projection_matrix (graphene_matrix_t *projection,
const graphene_rect_t *viewport)
@@ -466,14 +522,13 @@ extract_matrix_metadata (GskGLRenderModelview *modelview)
case GSK_TRANSFORM_CATEGORY_2D:
{
float skew_x, skew_y, angle, dx, dy;
float xx, xy, yx, yy, dx, dy;
gsk_transform_to_2d_components (modelview->transform,
&skew_x, &skew_y,
&modelview->scale_x, &modelview->scale_y,
&angle, &dx, &dy);
modelview->dx = 0;
modelview->dy = 0;
gsk_transform_to_2d (modelview->transform,
&xx, &xy, &yx, &yy, &dx, &dy);
modelview->scale_x = sqrtf (xx * xx + xy * xy);
modelview->scale_y = sqrtf (yx * yx + yy * yy);
}
break;
@@ -834,10 +889,10 @@ gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
}
static inline void
gsk_gl_render_job_translate_rounded_rect (GskGLRenderJob *job,
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
const GskRoundedRect *rect,
GskRoundedRect *out_rect)
{
{
out_rect->bounds.origin.x = job->offset_x + rect->bounds.origin.x;
out_rect->bounds.origin.y = job->offset_y + rect->bounds.origin.y;
out_rect->bounds.size.width = rect->bounds.size.width;
@@ -845,52 +900,6 @@ gsk_gl_render_job_translate_rounded_rect (GskGLRenderJob *job,
memcpy (out_rect->corner, rect->corner, sizeof rect->corner);
}
static inline void
rounded_rect_scale_corners (const GskRoundedRect *rect,
GskRoundedRect *out_rect,
float scale_x,
float scale_y)
{
for (guint i = 0; i < G_N_ELEMENTS (out_rect->corner); i++)
{
out_rect->corner[i].width = rect->corner[i].width * fabs (scale_x);
out_rect->corner[i].height = rect->corner[i].height * fabs (scale_y);
}
if (scale_x < 0)
{
graphene_size_t p;
p = out_rect->corner[GSK_CORNER_TOP_LEFT];
out_rect->corner[GSK_CORNER_TOP_LEFT] = out_rect->corner[GSK_CORNER_TOP_RIGHT];
out_rect->corner[GSK_CORNER_TOP_RIGHT] = p;
p = out_rect->corner[GSK_CORNER_BOTTOM_LEFT];
out_rect->corner[GSK_CORNER_BOTTOM_LEFT] = out_rect->corner[GSK_CORNER_BOTTOM_RIGHT];
out_rect->corner[GSK_CORNER_BOTTOM_RIGHT] = p;
}
if (scale_y < 0)
{
graphene_size_t p;
p = out_rect->corner[GSK_CORNER_TOP_LEFT];
out_rect->corner[GSK_CORNER_TOP_LEFT] = out_rect->corner[GSK_CORNER_BOTTOM_LEFT];
out_rect->corner[GSK_CORNER_BOTTOM_LEFT] = p;
p = out_rect->corner[GSK_CORNER_TOP_RIGHT];
out_rect->corner[GSK_CORNER_TOP_RIGHT] = out_rect->corner[GSK_CORNER_BOTTOM_RIGHT];
out_rect->corner[GSK_CORNER_BOTTOM_RIGHT] = p;
}
}
static inline void
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
const GskRoundedRect *rect,
GskRoundedRect *out_rect)
{
gsk_gl_render_job_transform_bounds (job, &rect->bounds, &out_rect->bounds);
rounded_rect_scale_corners (rect, out_rect, job->scale_x, job->scale_y);
}
static inline void
rounded_rect_get_inner (const GskRoundedRect *rect,
graphene_rect_t *inner)
@@ -1193,12 +1202,13 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
{
float scale_x = job->scale_x;
float scale_y = job->scale_y;
int surface_width = ceilf (node->bounds.size.width * fabs (scale_x));
int surface_height = ceilf (node->bounds.size.height * fabs (scale_y));
int surface_width = ceilf (node->bounds.size.width * scale_x);
int surface_height = ceilf (node->bounds.size.height * scale_y);
GdkTexture *texture;
cairo_surface_t *surface;
cairo_surface_t *rendered_surface;
cairo_t *cr;
int cached_id;
int texture_id;
GskTextureKey key;
@@ -1210,10 +1220,18 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
key.scale_x = scale_x;
key.scale_y = scale_y;
texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
if (texture_id != 0)
goto done;
if (cached_id != 0)
{
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D, GL_TEXTURE0, cached_id);
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
gsk_gl_render_job_end_draw (job);
return;
}
/* We first draw the recording surface on an image surface,
* just because the scaleY(-1) later otherwise screws up the
@@ -1223,7 +1241,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
surface_width,
surface_height);
cairo_surface_set_device_scale (rendered_surface, fabs (scale_x), fabs (scale_y));
cairo_surface_set_device_scale (rendered_surface, scale_x, scale_y);
cr = cairo_create (rendered_surface);
cairo_save (cr);
@@ -1237,16 +1255,15 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
surface_width,
surface_height);
cairo_surface_set_device_scale (surface, fabs (scale_x), fabs (scale_y));
cairo_surface_set_device_scale (surface, scale_x, scale_y);
cr = cairo_create (surface);
/* We draw upside down here, so it matches what GL does. */
cairo_save (cr);
cairo_scale (cr, scale_x < 0 ? -1 : 1, scale_y < 0 ? 1 : -1);
cairo_translate (cr, scale_x < 0 ? - surface_width / fabs (scale_x) : 0,
scale_y < 0 ? 0 : - surface_height / fabs (scale_y));
cairo_scale (cr, 1, -1);
cairo_translate (cr, 0, - surface_height / scale_y);
cairo_set_source_surface (cr, rendered_surface, 0, 0);
cairo_rectangle (cr, 0, 0, surface_width / fabs (scale_x), surface_height / fabs (scale_y));
cairo_rectangle (cr, 0, 0, surface_width / scale_x, surface_height / scale_y);
cairo_fill (cr);
cairo_restore (cr);
@@ -1285,16 +1302,6 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
gsk_gl_driver_cache_texture (job->driver, &key, texture_id);
done:
if (scale_x < 0 || scale_y < 0)
{
GskTransform *transform = gsk_transform_translate (NULL,
&GRAPHENE_POINT_INIT (scale_x < 0 ? - surface_width : 0,
scale_y < 0 ? - surface_height : 0));
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
}
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -1303,9 +1310,6 @@ done:
texture_id);
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
gsk_gl_render_job_end_draw (job);
if (scale_x < 0 || scale_y < 0)
gsk_gl_render_job_pop_modelview (job);
}
static guint
@@ -1460,10 +1464,10 @@ blur_node (GskGLRenderJob *job,
offscreen->texture_id = blur_offscreen (job,
offscreen,
texture_width * fabs (scale_x),
texture_height * fabs (scale_y),
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
texture_width * scale_x,
texture_height * scale_y,
blur_radius * scale_x,
blur_radius * scale_y);
init_full_texture_region (offscreen);
}
@@ -1645,7 +1649,6 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
{
graphene_rect_t transformed_clip;
GskRoundedRect intersection;
GskRoundedRectIntersection result;
gsk_gl_render_job_transform_bounds (job, clip, &transformed_clip);
@@ -1659,17 +1662,10 @@ gsk_gl_render_job_visit_clipped_child (GskGLRenderJob *job,
gsk_gl_render_job_push_clip (job, &intersection);
gsk_gl_render_job_visit_node (job, child);
gsk_gl_render_job_pop_clip (job);
return;
}
result = gsk_rounded_rect_intersect_with_rect (&job->current_clip->rect,
&transformed_clip,
&intersection);
if (result == GSK_INTERSECTION_EMPTY)
return;
if (result == GSK_INTERSECTION_NONEMPTY)
else if (intersect_rounded_rectilinear (&transformed_clip,
&job->current_clip->rect,
&intersection))
{
gsk_gl_render_job_push_clip (job, &intersection);
gsk_gl_render_job_visit_node (job, child);
@@ -1716,26 +1712,28 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
const GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
const GskRoundedRect *clip = gsk_rounded_clip_node_get_clip (node);
GskRoundedRect transformed_clip;
float scale_x = job->scale_x;
float scale_y = job->scale_y;
gboolean need_offscreen;
if (node_is_invisible (child))
return;
gsk_gl_render_job_transform_rounded_rect (job, clip, &transformed_clip);
gsk_gl_render_job_transform_bounds (job, &clip->bounds, &transformed_clip.bounds);
for (guint i = 0; i < G_N_ELEMENTS (transformed_clip.corner); i++)
{
transformed_clip.corner[i].width = clip->corner[i].width * scale_x;
transformed_clip.corner[i].height = clip->corner[i].height * scale_y;
}
if (job->current_clip->is_rectilinear)
{
GskRoundedRect intersected_clip;
GskRoundedRectIntersection result;
result = gsk_rounded_rect_intersect_with_rect (&transformed_clip,
&job->current_clip->rect.bounds,
&intersected_clip);
if (result == GSK_INTERSECTION_EMPTY)
return;
if (result == GSK_INTERSECTION_NONEMPTY)
if (intersect_rounded_rectilinear (&job->current_clip->rect.bounds,
&transformed_clip,
&intersected_clip))
{
gsk_gl_render_job_push_clip (job, &intersected_clip);
gsk_gl_render_job_visit_node (job, child);
@@ -1750,13 +1748,22 @@ gsk_gl_render_job_visit_rounded_clip_node (GskGLRenderJob *job,
if (job->clip->len <= 1)
need_offscreen = FALSE;
else if (gsk_rounded_rect_contains_rect (&job->current_clip->rect, &transformed_clip.bounds))
else if (rounded_inner_rect_contains_rect (&job->current_clip->rect, &transformed_clip.bounds))
need_offscreen = FALSE;
else
need_offscreen = TRUE;
if (!need_offscreen)
{
/* If the new clip entirely contains the current clip, the intersection is simply
* the current clip, so we can ignore the new one.
*/
if (rounded_inner_rect_contains_rect (&transformed_clip, &job->current_clip->rect.bounds))
{
gsk_gl_render_job_visit_node (job, child);
return;
}
gsk_gl_render_job_push_clip (job, &transformed_clip);
gsk_gl_render_job_visit_node (job, child);
gsk_gl_render_job_pop_clip (job);
@@ -1878,7 +1885,7 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
sizes[3].w = MAX (widths[3], rounded_outline->corner[3].width);
}
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, border));
@@ -1982,7 +1989,7 @@ gsk_gl_render_job_visit_css_background (GskGLRenderJob *job,
rgba_to_half (&gsk_border_node_get_colors (node2)[0], color);
rgba_to_half (gsk_color_node_get_color (child), color2);
gsk_gl_render_job_translate_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, filled_border));
@@ -2123,7 +2130,6 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
scale = gsk_transform_translate (gsk_transform_scale (NULL, sx, sy), &GRAPHENE_POINT_INIT (tx, ty));
gsk_gl_render_job_push_modelview (job, scale);
transform = gsk_transform_transform (gsk_transform_invert (scale), transform);
gsk_transform_unref (scale);
}
}
@@ -2174,7 +2180,7 @@ gsk_gl_render_job_visit_unblurred_inset_shadow_node (GskGLRenderJob *job,
GskRoundedRect transformed_outline;
guint16 color[4];
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow));
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
@@ -2274,7 +2280,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
gsk_gl_render_job_translate_rounded_rect (job, &outline_to_blur, &transformed_outline);
gsk_gl_render_job_transform_rounded_rect (job, &outline_to_blur, &transformed_outline);
/* Actual inset shadow outline drawing */
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, inset_shadow));
@@ -2307,8 +2313,8 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
&offscreen,
texture_width,
texture_height,
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
blur_radius * scale_x,
blur_radius * scale_y);
gsk_gl_driver_release_render_target (job->driver, render_target, TRUE);
@@ -2330,7 +2336,14 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
{
GskRoundedRect node_clip;
gsk_gl_render_job_translate_rounded_rect (job, node_outline, &node_clip);
gsk_gl_render_job_transform_bounds (job, &node_outline->bounds, &node_clip.bounds);
for (guint i = 0; i < 4; i ++)
{
node_clip.corner[i].width = node_outline->corner[i].width * scale_x;
node_clip.corner[i].height = node_outline->corner[i].height * scale_y;
}
gsk_gl_render_job_push_clip (job, &node_clip);
}
@@ -2380,7 +2393,7 @@ gsk_gl_render_job_visit_unblurred_outset_shadow_node (GskGLRenderJob *job,
rgba_to_half (gsk_outset_shadow_node_get_color (node), color);
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, unblurred_outset_shadow));
gsk_gl_program_set_uniform_rounded_rect (job->current_program,
@@ -2573,8 +2586,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
&offscreen,
texture_width,
texture_height,
blur_radius * fabs (scale_x),
blur_radius * fabs (scale_y));
blur_radius * scale_x,
blur_radius * scale_y);
gsk_gl_shadow_library_insert (job->driver->shadows_library,
&scaled_outline,
@@ -2588,7 +2601,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
blurred_texture_id = cached_tid;
}
gsk_gl_render_job_translate_rounded_rect (job, outline, &transformed_outline);
gsk_gl_render_job_transform_rounded_rect (job, outline, &transformed_outline);
if (!do_slicing)
{
@@ -2824,12 +2837,8 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
offscreen_end.reset_clip = TRUE;
offscreen_end.bounds = &node->bounds;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
if (!gsk_gl_render_job_visit_node_with_offscreen (job, start_node, &offscreen_start))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_visit_node (job, end_node);
return;
}
@@ -2838,18 +2847,12 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_visit_node_with_offscreen (job, end_node, &offscreen_end))
{
float prev_alpha;
gsk_gl_render_job_pop_modelview (job);
prev_alpha = gsk_gl_render_job_set_alpha (job, job->alpha * progress);
float prev_alpha = gsk_gl_render_job_set_alpha (job, job->alpha * progress);
gsk_gl_render_job_visit_node (job, start_node);
gsk_gl_render_job_set_alpha (job, prev_alpha);
return;
}
gsk_gl_render_job_pop_modelview (job);
g_assert (offscreen_end.texture_id);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, cross_fade));
@@ -3243,14 +3246,10 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
bottom_offscreen.force_offscreen = TRUE;
bottom_offscreen.reset_clip = TRUE;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
/* TODO: We create 2 textures here as big as the blend node, but both the
* start and the end node might be a lot smaller than that. */
if (!gsk_gl_render_job_visit_node_with_offscreen (job, bottom_child, &bottom_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_visit_node (job, top_child);
return;
}
@@ -3259,8 +3258,6 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_visit_node_with_offscreen (job, top_child, &top_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -3274,8 +3271,6 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
g_assert (top_offscreen.was_offscreen);
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blend));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -3312,14 +3307,11 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
mask_offscreen.reset_clip = TRUE;
mask_offscreen.do_not_cache = TRUE;
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
/* TODO: We create 2 textures here as big as the mask node, but both
* nodes might be a lot smaller than that.
*/
if (!gsk_gl_render_job_visit_node_with_offscreen (job, source, &source_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_visit_node (job, source);
return;
}
@@ -3328,14 +3320,11 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
if (!gsk_gl_render_job_visit_node_with_offscreen (job, mask, &mask_offscreen))
{
gsk_gl_render_job_pop_modelview (job);
return;
}
g_assert (mask_offscreen.was_offscreen);
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, mask));
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -3553,9 +3542,6 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
init_full_texture_region (offscreen);
offscreen->has_mipmap = ensure_mipmap;
if (gl_texture && offscreen->texture_id == gdk_gl_texture_get_id (gl_texture))
offscreen->sync = gdk_gl_texture_get_sync (gl_texture);
}
}
@@ -3569,8 +3555,8 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
float scale_y = bounds->size.height / texture->height;
gboolean use_mipmap;
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
(scale_y * fabs (job->scale_y)) < 0.5;
use_mipmap = (scale_x * job->scale_x) < 0.5 ||
(scale_y * job->scale_y) < 0.5;
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
@@ -3583,15 +3569,13 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
g_assert (offscreen.was_offscreen == FALSE);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR,
offscreen.sync);
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR);
gsk_gl_render_job_draw_offscreen (job, bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -3721,29 +3705,21 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
{
gpointer sync;
texture_id = gsk_gl_driver_load_texture (job->driver, texture, filter == GSK_SCALING_FILTER_TRILINEAR);
if (GDK_IS_GL_TEXTURE (texture) && texture_id == gdk_gl_texture_get_id (GDK_GL_TEXTURE (texture)))
sync = gdk_gl_texture_get_sync (GDK_GL_TEXTURE (texture));
else
sync = NULL;
u0 = (clip_rect.origin.x - bounds->origin.x) / bounds->size.width;
v0 = (clip_rect.origin.y - bounds->origin.y) / bounds->size.height;
u1 = (clip_rect.origin.x + clip_rect.size.width - bounds->origin.x) / bounds->size.width;
v1 = (clip_rect.origin.y + clip_rect.size.height - bounds->origin.y) / bounds->size.height;
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id,
min_filter,
mag_filter,
sync);
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
texture_id,
min_filter,
mag_filter);
gsk_gl_render_job_draw_coords (job,
0, 0, clip_rect.size.width, clip_rect.size.height,
u0, v0, u1, v1,
@@ -4102,7 +4078,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
}
if (gsk_render_node_get_node_type (node) == GSK_TEXTURE_NODE &&
!offscreen->force_offscreen)
offscreen->force_offscreen == FALSE)
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
gsk_gl_render_job_upload_texture (job, texture, FALSE, offscreen);
@@ -4120,7 +4096,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
gboolean flipped_x = job->scale_x < 0;
gboolean flipped_y = job->scale_y < 0;
graphene_rect_t viewport;
gboolean reset_clip = FALSE;
if (flipped_x || flipped_y)
{
@@ -4128,7 +4103,6 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
flipped_x ? -1 : 1,
flipped_y ? -1 : 1);
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
}
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
@@ -4166,9 +4140,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
{
GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y);
gsk_gl_render_job_push_modelview (job, transform);
gsk_transform_unref (transform);
gsk_gl_render_job_transform_bounds (job, offscreen->bounds, &viewport);
graphene_rect_scale (&viewport, downscale_x, downscale_y, &viewport);
}
if (downscale_x == 1)
@@ -4252,25 +4224,11 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
if (offscreen->reset_clip)
{
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
reset_clip = TRUE;
}
else if (flipped_x || flipped_y || downscale_x != 1 || downscale_y != 1)
{
GskRoundedRect new_clip;
float scale_x = flipped_x ? - downscale_x : downscale_x;
float scale_y = flipped_y ? - downscale_y : downscale_y;
graphene_rect_scale (&job->current_clip->rect.bounds, scale_x, scale_y, &new_clip.bounds);
rounded_rect_scale_corners (&job->current_clip->rect, &new_clip, scale_x, scale_y);
gsk_gl_render_job_push_clip (job, &new_clip);
reset_clip = TRUE;
}
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (job->viewport));
gsk_gl_render_job_visit_node (job, node);
if (reset_clip)
if (offscreen->reset_clip)
gsk_gl_render_job_pop_clip (job);
if (downscale_x != 1 || downscale_y != 1)
@@ -4422,7 +4380,7 @@ get_framebuffer_format (GdkGLContext *context,
{
int size;
if (!gdk_gl_context_check_version (context, NULL, "3.0"))
if (!gdk_gl_context_check_version (context, 0, 0, 3, 0))
return GL_RGBA8;
glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+4 -6
View File
@@ -19,9 +19,6 @@ void main() {
gsk_rounded_rect_transform(outside, u_modelview);
gsk_rounded_rect_transform(inside, u_modelview);
gsk_rounded_rect_normalize(outside);
gsk_rounded_rect_normalize(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
}
@@ -37,9 +34,10 @@ _IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec2 frag = gsk_get_frag_coord();
float outer_coverage = gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag);
float inner_coverage = gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag);
float alpha = clamp(outer_coverage - inner_coverage, 0.0, 1.0);
float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
0.0, 1.0);
gskSetScaledOutputColor(final_color, alpha);
}
-3
View File
@@ -21,9 +21,6 @@ void main() {
gsk_rounded_rect_transform(outside, u_modelview);
gsk_rounded_rect_transform(inside, u_modelview);
gsk_rounded_rect_normalize(outside);
gsk_rounded_rect_normalize(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
}
-3
View File
@@ -22,9 +22,6 @@ void main() {
gsk_rounded_rect_transform(outside, u_modelview);
gsk_rounded_rect_transform(inside, u_modelview);
gsk_rounded_rect_normalize(outside);
gsk_rounded_rect_normalize(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
}

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