Compare commits

..

3 Commits

Author SHA1 Message Date
Matthias Clasen 49e93f6ee4 textview: Don't validate during snapshot
Do it during size_allocate, and go back there
if needed.
2023-02-21 15:04:30 -05:00
Matthias Clasen 4ec2234537 widget: Warn for invalidation during paint 2023-02-21 15:04:30 -05:00
Matthias Clasen 5a3755b233 frameclock: Add a debug helper
Begin able to query the current phase
is useful for debugging purposes.
2023-02-21 15:04:30 -05:00
326 changed files with 20852 additions and 25264 deletions
+2 -7
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:v42"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v41"
workflow:
rules:
@@ -60,10 +60,6 @@ style-check-diff:
- "${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}"
@@ -108,8 +104,7 @@ fedora-x86_64:
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build wayland_smalltexture
- .gitlab-ci/run-tests.sh _build waylandgles
- .gitlab-ci/run-tests.sh _build broadway
release-build:
+1 -1
View File
@@ -1,4 +1,4 @@
FROM fedora:38
FROM fedora:37
RUN dnf -y install \
adwaita-icon-theme \
-1
View File
@@ -20,7 +20,6 @@ flatpak build ${builddir} meson \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dbuild-tests=false \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Ddemos=true \
+28 -1
View File
@@ -36,7 +36,7 @@ case "${backend}" in
--suite=failing || true
;;
wayland*)
wayland)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
@@ -63,6 +63,33 @@ case "${backend}" in
kill ${compositor}
;;
waylandgles)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-6 --idle-time=0 &
compositor=$!
export WAYLAND_DISPLAY=wayland-6
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--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}
;;
broadway)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
+2 -108
View File
@@ -1,111 +1,5 @@
Overview of Changes in 4.11.1, xx-xx-xxxx
=========================================
Overview of Changes in 4.10.1, 14-03-2023
=========================================
* GtkFileChooser
- Improve search performance
- Be safe against pathless files
- Fix memory leaks
- Only show local files in recent files
- Show most recent files first
- Make files non-selectable in selet_folder mode
* GtkListView / GtkColumnView / GtkGridView
- Fix scrolling problems
- Support CSS border-spacing
* GtkComboBox
- Fix a size allocation problem
* gtk
- Size allocation fixes
* Accessibility
- Miscellaneous property fixes and improvements
* Wayland
- Fix an ordering problem in surface disposal
* Windows
- Fix Visual Studio build with older GLib
* Translation updates
Basque
Bulgarian
Catalan
Czech
Danish
Finnish
Friulian
Galician
Georgian
Hungarian
Lithuanian
Polish
Portuguese
Swedish
Turkish
Ukrainian
Overview of Changes in 4.10.0, 04-03-2023
=========================================
* GtkTextView
- Document hanging indentation
* GtkListView
- Fix a size allocation problem
* GtkFileChooser
- Fix paned behavior
- Fix a crash
* GtkText
- Fix various problems with undo
* Accessibility
- Make some getters transfer-full
- Allow setting accessible parents and siblings
- Add a role for toggle buttons
- Miscellaneous property fixes and improvements
* gtk
- Improve the handling resize-during-size-allocate
* gdk
- Introduce GdkTextureDownloader and use it
- Make gdk_texture_get_format public
* gsk
- Make mask nodes more versatile
- Improve the GL implementation for texture scale nodes
* X11
- Fix key handling during DND
* Tools
- gtk-builder-tool: Try harder to handle templates
- gtk-builder-tool: Prefer properties over <child>
* Translation updates
Basque
Belarusian
Bulgarian
Indonesian
Galician
Georgian
German
Hebrew
Lithuanian
Portuguese
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.9.5, xx-xx-xxxx
========================================
Overview of Changes in 4.9.4, 12-02-2023
========================================
+1 -1
View File
@@ -9,7 +9,7 @@ constraint_editor_sources = [
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
executable('gtk4-constraint-editor',
+24 -171
View File
@@ -5,8 +5,7 @@ enum
{
PROP_TEXTURE = 1,
PROP_FILTER,
PROP_SCALE,
PROP_ANGLE,
PROP_SCALE
};
struct _Demo3Widget
@@ -15,7 +14,6 @@ struct _Demo3Widget
GdkTexture *texture;
float scale;
float angle;
GskScalingFilter filter;
GtkWidget *menu;
@@ -28,85 +26,10 @@ struct _Demo3WidgetClass
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
static gboolean
query_tooltip (GtkWidget *widget,
int x,
int y,
gboolean keyboard_mode,
GtkTooltip *tooltip,
gpointer data)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
GtkWidget *grid;
GtkWidget *label;
char *s, *s2;
const char *filter[] = { "Linear", "Nearest", "Trilinear" };
int precision, l;
grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
label = gtk_label_new ("Texture");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
s = g_strdup_printf ("%d\342\200\206\303\227\342\200\206%d",
gdk_texture_get_width (self->texture),
gdk_texture_get_height (self->texture));
label = gtk_label_new (s);
g_free (s);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
label = gtk_label_new ("Rotation");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
s = g_strdup_printf ("%.1f", self->angle);
if (g_str_has_suffix (s, ".0"))
s[strlen (s) - 2] = '\0';
s2 = g_strconcat (s, "\302\260", NULL);
label = gtk_label_new (s2);
g_free (s2);
g_free (s);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
label = gtk_label_new ("Scale");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
precision = 1;
do {
s = g_strdup_printf ("%.*f", precision, self->scale);
l = strlen (s) - 1;
while (s[l] == '0')
l--;
if (s[l] == '.')
s[l] = '\0';
precision++;
} while (strcmp (s, "0") == 0);
label = gtk_label_new (s);
g_free (s);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
label = gtk_label_new ("Filter");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
label = gtk_label_new (filter[self->filter]);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
gtk_tooltip_set_custom (tooltip, grid);
return TRUE;
}
static void
demo3_widget_init (Demo3Widget *self)
{
self->scale = 1.f;
self->angle = 0.f;
self->filter = GSK_SCALING_FILTER_LINEAR;
gtk_widget_init_template (GTK_WIDGET (self));
}
@@ -129,35 +52,26 @@ demo3_widget_snapshot (GtkWidget *widget,
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int x, y, width, height;
double w, h, w2, h2;
double w, h;
GskRenderNode *node;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
w2 = w = self->scale * gdk_texture_get_width (self->texture);
h2 = h = self->scale * gdk_texture_get_height (self->texture);
w = self->scale * gdk_texture_get_width (self->texture);
h = self->scale * gdk_texture_get_height (self->texture);
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
{
double s = w2;
w2 = h2;
h2 = s;
}
x = (width - ceil (w2)) / 2;
y = (height - ceil (h2)) / 2;
x = MAX (0, (width - ceil (w)) / 2);
y = MAX (0, (height - ceil (h)) / 2);
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (w2 / 2, h2 / 2));
gtk_snapshot_rotate (snapshot, self->angle);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- w / 2, - h / 2));
gtk_snapshot_append_scaled_texture (snapshot,
self->texture,
self->filter,
&GRAPHENE_RECT_INIT (0, 0, w, h));
node = gsk_texture_scale_node_new (self->texture,
&GRAPHENE_RECT_INIT (0, 0, w, h),
self->filter);
gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
gtk_snapshot_restore (snapshot);
gtk_snapshot_pop (snapshot);
}
@@ -172,26 +86,14 @@ demo3_widget_measure (GtkWidget *widget,
int *natural_baseline)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int width, height;
int size;
width = gdk_texture_get_width (self->texture);
height = gdk_texture_get_height (self->texture);
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
{
int s = width;
width = height;
height = s;
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
size = width;
size = gdk_texture_get_width (self->texture);
else
size = height;
size = gdk_texture_get_height (self->texture);
*minimum = *natural = (int) ceil (self->scale * size);
*minimum = *natural = self->scale * size;
}
static void
@@ -209,8 +111,6 @@ demo3_widget_size_allocate (GtkWidget *widget,
gtk_popover_present (GTK_POPOVER (self->menu));
}
static void update_actions (Demo3Widget *self);
static void
demo3_widget_set_property (GObject *object,
guint prop_id,
@@ -224,24 +124,11 @@ demo3_widget_set_property (GObject *object,
case PROP_TEXTURE:
g_clear_object (&self->texture);
self->texture = g_value_dup_object (value);
self->scale = 1.f;
self->angle = 0.f;
self->filter = GSK_SCALING_FILTER_LINEAR;
update_actions (self);
gtk_widget_queue_resize (GTK_WIDGET (object));
g_object_notify (object, "scale");
g_object_notify (object, "angle");
g_object_notify (object, "filter");
break;
case PROP_SCALE:
self->scale = g_value_get_float (value);
update_actions (self);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
case PROP_ANGLE:
self->angle = fmodf (g_value_get_float (value), 360.f);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
@@ -274,10 +161,6 @@ demo3_widget_get_property (GObject *object,
g_value_set_float (value, self->scale);
break;
case PROP_ANGLE:
g_value_set_float (value, self->angle);
break;
case PROP_FILTER:
g_value_set_enum (value, self->filter);
break;
@@ -303,14 +186,6 @@ pressed_cb (GtkGestureClick *gesture,
gtk_popover_popup (GTK_POPOVER (self->menu));
}
static void
update_actions (Demo3Widget *self)
{
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
}
static void
zoom_cb (GtkWidget *widget,
const char *action_name,
@@ -320,30 +195,19 @@ zoom_cb (GtkWidget *widget,
float scale;
if (g_str_equal (action_name, "zoom.in"))
scale = MIN (1024., self->scale * M_SQRT2);
scale = MIN (10, self->scale * M_SQRT2);
else if (g_str_equal (action_name, "zoom.out"))
scale = MAX (1./1024., self->scale / M_SQRT2);
else if (g_str_equal (action_name, "zoom.reset"))
scale = 1.0;
scale = MAX (0.01, self->scale / M_SQRT2);
else
g_assert_not_reached ();
scale = 1.0;
gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
g_object_set (widget, "scale", scale, NULL);
}
static void
rotate_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int angle;
g_variant_get (parameter, "i", &angle);
g_object_set (widget, "angle", fmodf (self->angle + angle, 360.f), NULL);
}
static void
demo3_widget_class_init (Demo3WidgetClass *class)
{
@@ -365,12 +229,7 @@ demo3_widget_class_init (Demo3WidgetClass *class)
g_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_float ("scale", NULL, NULL,
1./1024., 1024., 1.0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_ANGLE,
g_param_spec_float ("angle", NULL, NULL,
0.0, 360.0, 0.0,
0.0, 10.0, 1.0,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_FILTER,
@@ -382,7 +241,6 @@ demo3_widget_class_init (Demo3WidgetClass *class)
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.reset", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "rotate", "i", rotate_cb);
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
@@ -397,12 +255,7 @@ demo3_widget_new (const char *resource)
texture = gdk_texture_new_from_resource (resource);
self = g_object_new (DEMO3_TYPE_WIDGET,
"texture", texture,
"has-tooltip", TRUE,
NULL);
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
self = g_object_new (DEMO3_TYPE_WIDGET, "texture", texture, NULL);
g_object_unref (texture);
-5
View File
@@ -12,11 +12,6 @@
<attribute name="label">11</attribute>
<attribute name="action">zoom.reset</attribute>
</item>
<item>
<attribute name="label">Rotate</attribute>
<attribute name="action">rotate</attribute>
<attribute name="target" type="i">90</attribute>
</item>
</menu>
<template class="Demo3Widget">
<child>
+203 -195
View File
@@ -30,86 +30,90 @@
</object>
</child>
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<signal name="row-activated" handler="row_activated"/>
<style>
<class name="rich-list"/>
<class name="boxed-list"/>
</style>
<object class="GtkFrame">
<child>
<object class="GtkListBoxRow">
<object class="GtkListBox">
<property name="selection-mode">none</property>
<property name="show-separators">1</property>
<signal name="row-activated" handler="row_activated"/>
<style>
<class name="rich-list"/>
</style>
<child>
<object class="GtkBox">
<object class="GtkListBoxRow">
<child>
<object class="GtkLabel" id="switch_label">
<property name="label" translatable="yes">Switch</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="switch">
<property name="halign">end</property>
<property name="valign">center</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="switch_label">
<property name="label" translatable="yes">Switch</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSwitch" id="switch">
<property name="halign">end</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<child>
<object class="GtkBox">
<object class="GtkListBoxRow">
<child>
<object class="GtkLabel" id="check_label">
<property name="label" translatable="yes">Check</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="check">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="active">1</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="check_label">
<property name="label" translatable="yes">Check</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="check">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="active">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<child>
<object class="GtkBox">
<object class="GtkListBoxRow">
<child>
<object class="GtkLabel" id="image_label">
<property name="label" translatable="yes">Click here!</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkImage" id="image">
<property name="icon-name">object-select-symbolic</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="opacity">0</property>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="image_label">
<property name="label" translatable="yes">Click here!</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkImage" id="image">
<property name="icon-name">object-select-symbolic</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="opacity">0</property>
</object>
</child>
</object>
</child>
</object>
@@ -130,142 +134,146 @@
</style>
</object>
</child>
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<style>
<class name="rich-list"/>
<class name="boxed-list"/>
</style>
<child>
<object class="GtkFrame">
<child>
<object class="GtkListBox">
<property name="selection-mode">none</property>
<property name="show-separators">1</property>
<style>
<class name="rich-list"/>
</style>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="scale_label">
<property name="label" translatable="yes">Scale</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">0</property>
<property name="width-request">150</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="scale_label">
<property name="label" translatable="yes">Scale</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkScale">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="draw-value">0</property>
<property name="width-request">150</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="spin_label">
<property name="label" translatable="yes">Spinbutton</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSpinButton">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="dropdown_label">
<property name="label" translatable="yes">Dropdown</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkDropDown">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Choice 1</item>
<item>Choice 2</item>
<item>Choice 3</item>
<item>Choice 4</item>
</items>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="spin_label">
<property name="label" translatable="yes">Spinbutton</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkSpinButton">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="dropdown_label">
<property name="label" translatable="yes">Dropdown</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkDropDown">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Choice 1</item>
<item>Choice 2</item>
<item>Choice 3</item>
<item>Choice 4</item>
</items>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="entry_label">
<property name="label" translatable="yes">Entry</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="placeholder-text">Type here…</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkListBoxRow">
<property name="activatable">0</property>
<child>
<object class="GtkBox">
<child>
<object class="GtkLabel" id="entry_label">
<property name="label" translatable="yes">Entry</property>
<property name="xalign">0</property>
<property name="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkEntry">
<property name="halign">end</property>
<property name="valign">center</property>
<property name="placeholder-text">Type here…</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
+14 -133
View File
@@ -1,120 +1,18 @@
/* Image Scaling
* #Keywords: zoom, scale, filter, action, menu
/* Menu
* #Keywords: action, zoom
*
* Demonstrates how to add a context menu to a custom widget
* and connect it with widget actions.
*
* The custom widget we create here is similar to a GtkPicture,
* but allows setting a zoom level and filtering mode for the
* displayed paintable.
* but allows setting a zoom level for the displayed paintable.
*
* It also demonstrates how to add a context menu to a custom
* widget and connect it with widget actions.
*
* The context menu has items to change the zoom level.
* Our context menu has items to change the zoom level.
*/
#include <gtk/gtk.h>
#include "demo3widget.h"
static void
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
GdkTexture *texture;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
texture = gdk_texture_new_from_file (file, &error);
g_object_unref (file);
if (!texture)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
g_object_set (G_OBJECT (data), "texture", texture, NULL);
g_object_unref (texture);
}
static void
open_file (GtkWidget *picker,
GtkWidget *demo)
{
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (picker));
GtkFileDialog *dialog;
GtkFileFilter *filter;
GListStore *filters;
dialog = gtk_file_dialog_new ();
filter = gtk_file_filter_new ();
gtk_file_filter_set_name (filter, "Images");
gtk_file_filter_add_pixbuf_formats (filter);
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
g_list_store_append (filters, filter);
g_object_unref (filter);
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
g_object_unref (filters);
gtk_file_dialog_open (dialog, parent, NULL, file_opened, demo);
g_object_unref (dialog);
}
static void
rotate (GtkWidget *button,
GtkWidget *demo)
{
float angle;
g_object_get (demo, "angle", &angle, NULL);
angle = fmodf (angle + 90.f, 360.f);
g_object_set (demo, "angle", angle, NULL);
}
static gboolean
transform_to (GBinding *binding,
const GValue *src,
GValue *dest,
gpointer user_data)
{
double from;
float to;
from = g_value_get_double (src);
to = (float) pow (2., from);
g_value_set_float (dest, to);
return TRUE;
}
static gboolean
transform_from (GBinding *binding,
const GValue *src,
GValue *dest,
gpointer user_data)
{
float to;
double from;
to = g_value_get_float (src);
from = log2 (to);
g_value_set_double (dest, from);
return TRUE;
}
GtkWidget *
do_menu (GtkWidget *do_widget)
@@ -129,10 +27,9 @@ do_menu (GtkWidget *do_widget)
GtkWidget *widget;
GtkWidget *scale;
GtkWidget *dropdown;
GtkWidget *button;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
gtk_window_set_title (GTK_WINDOW (window), "Menu");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
@@ -151,35 +48,19 @@ do_menu (GtkWidget *do_widget)
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (box), box2);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
gtk_widget_set_tooltip_text (button, "Open File");
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
gtk_widget_set_tooltip_text (button, "Rotate");
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
gtk_box_append (GTK_BOX (box2), button);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, -10., 10., 0.1);
gtk_scale_add_mark (GTK_SCALE (scale), 0., GTK_POS_TOP, NULL);
gtk_widget_set_tooltip_text (scale, "Zoom");
gtk_range_set_value (GTK_RANGE (scale), 0.);
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0.01, 10.0, 0.1);
gtk_range_set_value (GTK_RANGE (scale), 1.0);
gtk_widget_set_hexpand (scale, TRUE);
gtk_box_append (GTK_BOX (box2), scale);
dropdown = gtk_drop_down_new (G_LIST_MODEL (gtk_string_list_new ((const char *[]){ "Linear", "Nearest", "Trilinear", NULL })), NULL);
gtk_widget_set_tooltip_text (dropdown, "Filter");
gtk_box_append (GTK_BOX (box2), dropdown);
g_object_bind_property (dropdown, "selected", widget, "filter", G_BINDING_DEFAULT);
g_object_bind_property_full (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL,
transform_to,
transform_from,
NULL, NULL);
g_object_bind_property (gtk_range_get_adjustment (GTK_RANGE (scale)), "value",
widget, "scale",
G_BINDING_BIDIRECTIONAL);
}
if (!gtk_widget_get_visible (window))
+1 -1
View File
@@ -225,7 +225,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else
gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
'demo.gresource.xml',
source_dir: meson.current_source_dir()
source_dir: '.',
)
endif
+9 -44
View File
@@ -13,13 +13,20 @@
static GtkWidget *app_picker;
static void
set_file (GFile *file,
gpointer data)
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
char *name;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
return;
@@ -33,25 +40,6 @@ set_file (GFile *file,
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
}
static void
file_opened (GObject *source,
GAsyncResult *result,
void *data)
{
GFile *file;
GError *error = NULL;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
if (!file)
{
g_print ("%s\n", error->message);
g_error_free (error);
}
set_file (file, data);
}
static gboolean
abort_mission (gpointer data)
{
@@ -142,28 +130,11 @@ launch_uri (GtkButton *picker)
g_object_unref (launcher);
}
static gboolean
on_drop (GtkDropTarget *target,
const GValue *value,
double x,
double y,
gpointer data)
{
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
set_file (g_value_get_object (value), data);
return TRUE;
}
return FALSE;
}
GtkWidget *
do_pickers (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *table, *label, *picker, *button;
GtkDropTarget *drop_target;
if (!window)
{
@@ -208,13 +179,7 @@ do_pickers (GtkWidget *do_widget)
picker = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_button_new_from_icon_name ("document-open-symbolic");
label = gtk_label_new ("None");
drop_target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
g_signal_connect (drop_target, "drop", G_CALLBACK (on_drop), label);
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (drop_target));
gtk_label_set_xalign (GTK_LABEL (label), 0.);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_hexpand (label, TRUE);
-1
View File
@@ -22,7 +22,6 @@ show_shortcuts (GtkWidget *window,
gtk_window_set_transient_for (GTK_WINDOW (overlay), GTK_WINDOW (window));
g_object_set (overlay, "view-name", view, NULL);
g_object_unref (builder);
gtk_window_present (GTK_WINDOW (overlay));
}
G_MODULE_EXPORT void
+1 -1
View File
@@ -8,7 +8,7 @@ iconbrowser_sources = [
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
'iconbrowser.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
executable('gtk4-icon-browser',
+1 -1
View File
@@ -7,7 +7,7 @@ node_editor_sources = [
node_editor_resources = gnome.compile_resources('node_editor_resources',
'node-editor.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
executable('gtk4-node-editor',
+16 -187
View File
@@ -32,11 +32,6 @@
#include "gsk/vulkan/gskvulkanrenderer.h"
#endif
#include <cairo.h>
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
#endif
typedef struct
{
gsize start_chars;
@@ -648,34 +643,23 @@ save_cb (GtkWidget *button,
g_object_unref (dialog);
}
static GskRenderNode *
create_node (NodeEditorWindow *self)
static GdkTexture *
create_texture (NodeEditorWindow *self)
{
GdkPaintable *paintable;
GtkSnapshot *snapshot;
GskRenderer *renderer;
GskRenderNode *node;
GdkTexture *texture;
paintable = gtk_picture_get_paintable (GTK_PICTURE (self->picture));
if (paintable == NULL ||
gdk_paintable_get_intrinsic_width (paintable) <= 0 ||
gdk_paintable_get_intrinsic_height (paintable) <= 0)
return NULL;
snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, gdk_paintable_get_intrinsic_width (paintable), gdk_paintable_get_intrinsic_height (paintable));
node = gtk_snapshot_free_to_node (snapshot);
return node;
}
static GdkTexture *
create_texture (NodeEditorWindow *self)
{
GskRenderer *renderer;
GskRenderNode *node;
GdkTexture *texture;
node = create_node (self);
if (node == NULL)
return NULL;
@@ -686,58 +670,6 @@ create_texture (NodeEditorWindow *self)
return texture;
}
#ifdef CAIRO_HAS_SVG_SURFACE
static cairo_status_t
cairo_serializer_write (gpointer user_data,
const unsigned char *data,
unsigned int length)
{
g_byte_array_append (user_data, data, length);
return CAIRO_STATUS_SUCCESS;
}
static GBytes *
create_svg (GskRenderNode *node,
GError **error)
{
cairo_surface_t *surface;
cairo_t *cr;
graphene_rect_t bounds;
GByteArray *array;
gsk_render_node_get_bounds (node, &bounds);
array = g_byte_array_new ();
surface = cairo_svg_surface_create_for_stream (cairo_serializer_write,
array,
bounds.size.width,
bounds.size.height);
cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX);
cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_finish (surface);
if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
{
cairo_surface_destroy (surface);
return g_byte_array_free_to_bytes (array);
}
else
{
g_set_error (error,
G_IO_ERROR, G_IO_ERROR_FAILED,
"%s", cairo_status_to_string (cairo_surface_status (surface)));
cairo_surface_destroy (surface);
g_byte_array_unref (array);
return NULL;
}
}
#endif
static GdkTexture *
create_cairo_texture (NodeEditorWindow *self)
{
@@ -770,140 +702,50 @@ create_cairo_texture (NodeEditorWindow *self)
}
static void
export_image_saved_cb (GObject *source,
GAsyncResult *result,
void *user_data)
{
GError *error = NULL;
if (!g_file_replace_contents_finish (G_FILE (source), result, NULL, &error))
{
GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Exporting to image failed");
gtk_alert_dialog_set_detail (alert, error->message);
gtk_alert_dialog_show (alert, NULL);
g_object_unref (alert);
g_clear_error (&error);
}
}
static void
export_image_response_cb (GObject *source,
export_image_response_cb (GObject *source,
GAsyncResult *result,
void *user_data)
void *user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GskRenderNode *node = user_data;
GdkTexture *texture = user_data;
GFile *file;
char *uri;
GBytes *bytes;
file = gtk_file_dialog_save_finish (dialog, result, NULL);
if (file == NULL)
if (file)
{
gsk_render_node_unref (node);
return;
}
uri = g_file_get_uri (file);
#ifdef CAIRO_HAS_SVG_SURFACE
if (g_str_has_suffix (uri, "svg"))
{
GError *error = NULL;
bytes = create_svg (node, &error);
if (bytes == NULL)
if (!gdk_texture_save_to_png (texture, g_file_peek_path (file)))
{
GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Exporting to image failed");
gtk_alert_dialog_set_detail (alert, error->message);
gtk_alert_dialog_show (alert, NULL);
gtk_alert_dialog_show (alert, GTK_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog))));
g_object_unref (alert);
g_clear_error (&error);
}
}
else
#endif
{
GdkTexture *texture;
GskRenderer *renderer;
renderer = gsk_gl_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
g_object_unref (renderer);
renderer = gsk_cairo_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
g_assert_not_reached ();
}
}
texture = gsk_renderer_render_texture (renderer, node, NULL);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
if (g_str_has_suffix (uri, "tiff"))
bytes = gdk_texture_save_to_tiff_bytes (texture);
else
bytes = gdk_texture_save_to_png_bytes (texture);
g_object_unref (texture);
g_object_unref (file);
}
g_free (uri);
if (bytes)
{
g_file_replace_contents_bytes_async (file,
bytes,
NULL,
FALSE,
0,
NULL,
export_image_saved_cb,
NULL);
g_bytes_unref (bytes);
}
gsk_render_node_unref (node);
g_object_unref (file);
g_object_unref (texture);
}
static void
export_image_cb (GtkWidget *button,
NodeEditorWindow *self)
{
GskRenderNode *node;
GdkTexture *texture;
GtkFileDialog *dialog;
GtkFileFilter *filter;
GListStore *filters;
node = create_node (self);
if (node == NULL)
texture = create_texture (self);
if (texture == NULL)
return;
filters = g_list_store_new (GTK_TYPE_FILE_FILTER);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/png");
g_list_store_append (filters, filter);
g_object_unref (filter);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/svg+xml");
g_list_store_append (filters, filter);
g_object_unref (filter);
filter = gtk_file_filter_new ();
gtk_file_filter_add_mime_type (filter, "image/tiff");
g_list_store_append (filters, filter);
g_object_unref (filter);
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "");
gtk_file_dialog_set_initial_name (dialog, "example.png");
gtk_file_dialog_set_filters (dialog, G_LIST_MODEL (filters));
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL,
export_image_response_cb, node);
g_object_unref (filters);
export_image_response_cb, texture);
g_object_unref (dialog);
}
@@ -1017,19 +859,6 @@ testcase_save_clicked_cb (GtkWidget *button,
}
text = get_current_text (self->text_buffer);
{
GBytes *bytes;
GskRenderNode *node;
gsize size;
bytes = g_bytes_new_take (text, strlen (text) + 1);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
bytes = gsk_render_node_serialize (node);
gsk_render_node_unref (node);
text = g_bytes_unref_to_data (bytes, &size);
}
if (!g_file_set_contents (node_file, text, -1, &error))
{
gtk_label_set_label (GTK_LABEL (self->testcase_error_label), error->message);
+1 -1
View File
@@ -69,7 +69,7 @@ if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_
else
widgetfactory_resources = gnome.compile_resources('widgetfactory_resources',
'widget-factory.gresource.xml',
source_dir: meson.current_source_dir(),
source_dir: '.',
)
endif
+3 -2
View File
@@ -678,10 +678,11 @@ Interfaces must have the following macros:
### Memory allocation
When dynamically allocating data on the heap use `g_new()`.
When dynamically allocating data on the heap either use `g_new()` or,
if allocating multiple small data structures, `g_slice_new()`.
Public structure types should always be returned after being zero-ed,
either explicitly for each member, or by using `g_new0()`.
either explicitly for each member, or by using `g_new0()` or `g_slice_new0()`.
### Macros
+11 -6
View File
@@ -6,15 +6,22 @@ Slug: broadway
The GDK Broadway backend provides support for displaying GTK applications in
a web browser, using HTML5 and web sockets.
To run your application in this way, first run the broadway server,
`gtk-broadwayd`, that ships with GTK:
To run your application in this way, select the Broadway backend by setting
`GDK_BACKEND=broadway`. Then you can make your application appear in a web
browser by pointing it at `http://127.0.0.1:8080`. Note that you need to
enable web sockets in your web browser.
You can choose a different port from the default 8080 by setting the
`BROADWAY_DISPLAY` environment variable to the port that you want to use.
It is also possible to use multiple GTK applications in the same web browser
window, by using the Broadway server, `gtk4-broadwayd`, that ships with GTK.
To start the Broadway server use:
```
gtk4-broadwayd :5
```
The server expects the colon-prefixed display number as a commandline argument.
Then point your web browser at `http://127.0.0.1:8085`.
Once the Broadway server is running, you can start your applications like
@@ -24,8 +31,6 @@ this:
GDK_BACKEND=broadway BROADWAY_DISPLAY=:5 gtk4-demo
```
Multiple applications can be presented in the same web browser window.
## Broadway-specific environment variables
### `BROADWAY_DISPLAY`
-4
View File
@@ -66,10 +66,6 @@ You can compile the program above with GCC using:
gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 )
```
**Note**: If the above compilation does not work due to an error regarding `G_APPLICATION_DEFAULT_FLAGS`
this could be due to your OS providing an older version of GLib. For GLib versions older than 2.74 you
will need to replace `G_APPLICATION_DEFAULT_FLAGS` with `G_APPLICATION_FLAGS_NONE` in this example, and
others in this documentation.
For more information on how to compile a GTK application, please
refer to the [Compiling GTK Applications](compiling.html)
section in this reference.
@@ -128,7 +128,6 @@ Each state name is part of the `GtkAccessibleState` enumeration.
| %GTK_ACCESSIBLE_STATE_INVALID | “aria-invalid” | `GtkAccessibleInvalidState` | Set when a widget is showing an error |
| %GTK_ACCESSIBLE_STATE_PRESSED | “aria-pressed” | `GtkAccessibleTristate` | Indicates the current state of a [class@Gtk.ToggleButton] |
| %GTK_ACCESSIBLE_STATE_SELECTED | “aria-selected” | boolean or undefined | Set when a widget is selected |
| %GTK_ACCESSIBLE_STATE_VISITED | N/A | boolean or undefined | Set when a link-like widget is visited |
#### List of accessible properties
+46 -46
View File
@@ -9,9 +9,9 @@ Lists are intended to be used whenever developers want to display many objects
in roughly the same way.
Lists are perfectly fine to be used for very short list of only 2 or 3 elements,
but generally scale to millions of items. Of course, the larger the list grows,
the more care needs to be taken to choose the right data structures to keep things
running well.
but generally scale fine to millions of items. Of course, the larger the list
grows, the more care needs to be taken to choose the right data structures to
keep things running well.
Lists are meant to be used with changing data, both with the items itself changing
as well as the list adding and removing items. Of course, they work just as well
@@ -26,14 +26,12 @@ have a specific meaning in this context.
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists.
Examples of these widgets would be [`class@Gtk.ListView`] or [`class@Gtk.GridView`].
Views display data from a **_model_**. Models implement the [`iface@Gio.ListModel`]
interface and can be provided in a variety of ways:
Views display data from a **_model_**. A model is a [`iface@Gio.ListModel`] and
models can be provided in 3 ways or combinations thereof:
* List model implementations for many specific types of data already exist, for
example `GtkDirectoryList` or `GtkStringList`.
* There are generic list model implementations like`GListStore` that allow building
lists of arbitrary objects.
* Many list models implementations already exist. There are models that provide
specific data, like `GtkDirectoryList`. And there are models like `GListStore`
that allow building lists manually.
* Wrapping list models like `GtkFilterListModel` or `GtkSortListModel`
modify, adapt or combine other models.
@@ -49,8 +47,8 @@ The elements in a model are called **_items_**. All items are
Every item in a model has a **_position_** which is the unsigned integer that
describes where in the model the item is located. The first item in a model is
at position 0. The position of an item can change as other items are added or
removed from the model.
at position 0. The position of an item can of course change as other items are
added or removed from the model.
It is important to be aware of the difference between items and positions
because the mapping from position to item is not permanent, so developers
@@ -73,10 +71,10 @@ with the item managed by the listitem. Finding a suitable factory implementation
for the data displayed, the programming language and development environment
is an important task that can simplify setting up the view tremendously.
Views support selections via a **_selection model_**. A selection model is
an implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
[`iface@Gio.ListModel`] interface that allows marking each item in a model as
either selected or not selected. Just like regular models, this can be implemented
Views support selections via a **_selection model_**. A selection model is an
implementation of the [`iface@Gtk.SelectionModel`] interface on top of the
[`iface@Gio.ListModel`] interface that allows marking each item in a model as either
selected or not selected. Just like regular models, this can be implemented
either by implementing `GtkSelectionModel` directly or by wrapping a model with
one of the GTK models provided for this purposes, such as [`class@Gtk.NoSelection`]
or [`class@Gtk.SingleSelection`].
@@ -89,18 +87,19 @@ item is exposed in the listitem via the [`property@Gtk.ListItem:selected`] prope
Views and listitems also support activation. Activation means that double
clicking or pressing enter while inside a focused row will cause the view
to emit a signal such as [`signal@Gtk.ListView::activate`]. This provides an
easy way to set up lists, but can also be turned off on listitems if undesired.
to emit and activation signal such as [`signal@Gtk.ListView::activate`]. This
provides an easy way to set up lists, but can also be turned off on listitems
if undesired.
Both selections and activation are supported among other things via widget
[actions](#actions-overview). This allows developers to add widgets to their
lists that cause selections to change or to trigger activation via the
[`iface@Gtk.Actionable`] interface. For a list of all supported actions
see the relevant documentation.
lists that cause selections to change or to trigger activation via
the [`iface@Gtk.Actionable`] interface. For a list of all supported actions see
the relevant documentation.
## Behind the scenes
While it is not a problem for short lists to instantiate widgets for every
While for short lists it is not a problem to instantiate widgets for every
item in the model, once lists grow to thousands or millions of elements, this
gets less feasible. Because of this, the views only create a limited amount of
listitems and recycle them by binding them to new items. In general, views try
@@ -108,7 +107,7 @@ to keep listitems available only for the items that can actually be seen on
screen.
While this behavior allows views to scale effortlessly to huge lists, it has a
few implications for what can be done with views. For example, it is not possible
few implication on what can be done with views. For example, it is not possible
to query a view for a listitem used for a certain position - there might not be
one and even if there is, that listitem might soon be recycled for a new
position.
@@ -162,9 +161,9 @@ in particular `GListModel` do not. This was a design choice because the common
use case is displaying lists and not trees and it greatly simplifies the API
interface provided.
However, GTK provides functionality to make lists look and behave like trees
for use cases that require trees. This is achieved by using the
[`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
However, GTK provides functionality to make trees look and behave like lists
for the people who still want to display lists. This is achieved by using
the [`class@Gtk.TreeListModel`] model to flatten a tree into a list. The
[`class@Gtk.TreeExpander`] widget can then be used inside a listitem to allow
users to expand and collapse rows and provide a similar experience to
`GtkTreeView`.
@@ -175,26 +174,26 @@ on the topic.
## List styles
One of the advantages of the new list widgets over `GtkTreeView` and cell
renderers is that they are styleable using GTK CSS. This provides a lot of
flexibility. The themes that ship with GTK provide a few predefined list
styles that can be used in many situations:
renderers is that they are fully themable using GTK CSS. This provides a
lot of flexibility. The themes that ship with GTK provide a few predefined
list styles that can be used in many situations:
![Rich list](rich-list.png)
This _rich list_ style is low density, spacious and uses an outline focus
ring. It is suitable for lists of controls, e.g. in preference dialogs or
This style of list is low density, spacious and uses an outline focus ring.
It is suitable for lists of controls, e.g. in preference dialogs or
settings panels. Use the `.rich-list` style class.
![Navigation sidebar](navigation-sidebar.png)
The _sidebar_ style of list is medium density, using a full background to
indicate focus and selection. Use the `.navigation-sidebar` style class.
This style of list is medium density, using a full background to indicate
focus and selection. Use the `.navigation-sidebar` style class.
![Data table](data-table.png)
The _data table_ style of list is a high density table, similar in style to a
traditional treeview. Individual cells can be selectable and editable. Use
the `.data-table` style class.
This style of list is a high density table, similar in style to a traditional
treeview. Individual cells can be selectable and editable. Use the `.data-table`
style class.
## Comparison to GtkTreeView
@@ -203,19 +202,20 @@ compares to the way they know. This section will try to outline the similarities
and differences between the two.
This new approach tries to provide roughly the same functionality as the old
approach but often uses a very different way to achieve these goals.
approach but often uses a very different approach to achieve these goals.
The main difference and one of the primary reasons for this new development is
that items can be displayed using regular widgets and the separate cell renderer
machinery is no longer necessary. This allows all benefits that widgets provide,
such as complex layout, animations and CSS styling.
that items can be displayed using regular widgets and `GtkCellRenderer` is no
longer necessary. This allows all benefits that widgets provide, such as complex
layout and animating widgets and not only makes cell renderers obsolete, but
also `GtkCellArea`.
The other big difference is the massive change to the data model. `GtkTreeModel`
was a rather complex interface for a tree data structure. `GListModel` is
deliberately designed to be a very simple data structure for lists only. (See
was a rather complex interface for a tree data structure and `GListModel` was
deliberately designed to be a simple data structure for lists only. (See
[above](#displaying-trees)) for how to still do trees with this new model.)
Another big change is that the new model allows for bulk changes via the
`GListModel::items-changed` signal while `GtkTreeModel` only allows a single
Another big change is that the new model allows for bulk changes via
the `GListModel::items-changed` signal while `GtkTreeModel` only allows a single
item to change at once. The goal here is of course to encourage implementation
of custom list models.
@@ -231,8 +231,8 @@ via custom code in each widget, selection state is now meant to be managed by
the selection models. In particular this allows for complex use cases with
specialized requirements.
Finally here's a quick comparison chart of equivalent functionality to look for
when transitioning code:
Finally here's a quick list of equivalent functionality to look for when
transitioning code for easy lookup:
| Old | New |
| -------------------- | ------------------------------------------------------- |
+1 -1
View File
@@ -1,6 +1,6 @@
app2_resources = gnome.compile_resources('exampleapp2_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('exampleapp2',
'exampleapp.c', 'exampleappwin.c', 'main.c', app2_resources,
+1 -1
View File
@@ -1,6 +1,6 @@
app3_resources = gnome.compile_resources('exampleapp3_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('exampleapp3',
'exampleapp.c', 'exampleappwin.c', 'main.c', app3_resources,
+1 -1
View File
@@ -1,6 +1,6 @@
app4_resources = gnome.compile_resources('exampleapp4_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('exampleapp4',
'exampleapp.c', 'exampleappwin.c', 'main.c', app4_resources,
+1 -1
View File
@@ -1,6 +1,6 @@
app5_resources = gnome.compile_resources('exampleapp5_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app5_schemas = gnome.compile_schemas()
+1 -1
View File
@@ -1,6 +1,6 @@
app6_resources = gnome.compile_resources('exampleapp6_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app6_schemas = gnome.compile_schemas()
+1 -1
View File
@@ -1,6 +1,6 @@
app7_resources = gnome.compile_resources('exampleapp7_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app7_schemas = gnome.compile_schemas()
+1 -1
View File
@@ -1,6 +1,6 @@
app8_resources = gnome.compile_resources('exampleapp8 resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app8_schemas = gnome.compile_schemas()
+1 -1
View File
@@ -1,6 +1,6 @@
app9_resources = gnome.compile_resources('exampleapp9_resources',
'exampleapp.gresource.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
app9_schemas = gnome.compile_schemas()
+1 -1
View File
@@ -1,5 +1,5 @@
bp_resources = gnome.compile_resources('bloatpad_resources',
'bloatpad.gresources.xml',
source_dir: meson.current_source_dir())
source_dir: '.')
executable('bloatpad', 'bloatpad.c', bp_resources, dependencies: libgtk_dep, c_args: common_cflags)
+4 -4
View File
@@ -1574,8 +1574,7 @@ broadway_server_query_mouse (BroadwayServer *server,
void
broadway_server_destroy_surface (BroadwayServer *server,
int id,
gboolean disconnected)
int id)
{
BroadwaySurface *surface;
gint32 transient_for = -1;
@@ -1590,7 +1589,8 @@ broadway_server_destroy_surface (BroadwayServer *server,
server->pointer_grab_surface_id = -1;
if (server->output)
broadway_output_destroy_surface (server->output, id);
broadway_output_destroy_surface (server->output,
id);
surface = broadway_server_lookup_surface (server, id);
if (surface != NULL)
@@ -1604,7 +1604,7 @@ broadway_server_destroy_surface (BroadwayServer *server,
broadway_surface_free (server, surface);
}
if (transient_for != -1 && !disconnected)
if (transient_for != -1)
{
surface = broadway_server_lookup_surface (server, transient_for);
if (surface != NULL)
+1 -2
View File
@@ -93,8 +93,7 @@ guint32 broadway_server_new_surface (BroadwayServer *
int width,
int height);
void broadway_server_destroy_surface (BroadwayServer *server,
int id,
gboolean disconnected);
int id);
gboolean broadway_server_surface_show (BroadwayServer *server,
int id);
gboolean broadway_server_surface_hide (BroadwayServer *server,
+3 -2
View File
@@ -101,7 +101,8 @@ client_disconnected (BroadwayClient *client)
}
for (l = client->surfaces; l != NULL; l = l->next)
broadway_server_destroy_surface (server, GPOINTER_TO_UINT (l->data), TRUE);
broadway_server_destroy_surface (server,
GPOINTER_TO_UINT (l->data));
g_list_free (client->surfaces);
client->surfaces = NULL;
@@ -267,7 +268,7 @@ client_handle_request (BroadwayClient *client,
client->surfaces =
g_list_remove (client->surfaces,
GUINT_TO_POINTER (request->destroy_surface.id));
broadway_server_destroy_surface (server, request->destroy_surface.id, FALSE);
broadway_server_destroy_surface (server, request->destroy_surface.id);
break;
case BROADWAY_REQUEST_SHOW_SURFACE:
broadway_server_surface_show (server, request->show_surface.id);
-1
View File
@@ -45,7 +45,6 @@
#include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdrag.h>
#include <gdk/gdkdragsurface.h>
#include <gdk/gdkdragsurfacesize.h>
#include <gdk/gdkdrawcontext.h>
#include <gdk/gdkdrop.h>
#include <gdk/gdkenums.h>
+2 -2
View File
@@ -750,7 +750,7 @@ static void
free_value (gpointer value)
{
g_value_unset (value);
g_free (value);
g_slice_free (GValue, value);
}
static void
@@ -771,7 +771,7 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
task = g_task_new (clipboard, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, source_tag);
value = g_new0 (GValue, 1);
value = g_slice_new0 (GValue);
g_value_init (value, type);
g_task_set_task_data (task, value, free_value);
+1 -1
View File
@@ -410,7 +410,7 @@ gdk_content_register_deserializer (const char *mime_type,
g_return_if_fail (mime_type != NULL);
g_return_if_fail (deserialize != NULL);
deserializer = g_new0 (Deserializer, 1);
deserializer = g_slice_new0 (Deserializer);
deserializer->mime_type = g_intern_string (mime_type);
deserializer->type = type;
+4 -4
View File
@@ -112,7 +112,7 @@ gdk_content_formats_new_take (GType * gtypes,
const char **mime_types,
gsize n_mime_types)
{
GdkContentFormats *result = g_new0 (GdkContentFormats, 1);
GdkContentFormats *result = g_slice_new0 (GdkContentFormats);
result->ref_count = 1;
result->gtypes = gtypes;
@@ -287,7 +287,7 @@ gdk_content_formats_unref (GdkContentFormats *formats)
g_free (formats->gtypes);
g_free (formats->mime_types);
g_free (formats);
g_slice_free (GdkContentFormats, formats);
}
/**
@@ -611,7 +611,7 @@ gdk_content_formats_builder_new (void)
{
GdkContentFormatsBuilder *builder;
builder = g_new0 (GdkContentFormatsBuilder, 1);
builder = g_slice_new0 (GdkContentFormatsBuilder);
builder->ref_count = 1;
return builder;
@@ -665,7 +665,7 @@ gdk_content_formats_builder_unref (GdkContentFormatsBuilder *builder)
return;
gdk_content_formats_builder_clear (builder);
g_free (builder);
g_slice_free (GdkContentFormatsBuilder, builder);
}
/**
+1 -1
View File
@@ -416,7 +416,7 @@ gdk_content_register_serializer (GType type,
g_return_if_fail (mime_type != NULL);
g_return_if_fail (serialize != NULL);
serializer = g_new0 (Serializer, 1);
serializer = g_slice_new0 (Serializer);
serializer->mime_type = g_intern_string (mime_type);
serializer->type = type;
+2 -2
View File
@@ -322,7 +322,7 @@ static void
free_pointer_info (GdkPointerSurfaceInfo *info)
{
g_clear_object (&info->surface_under_pointer);
g_free (info);
g_slice_free (GdkPointerSurfaceInfo, info);
}
static void
@@ -834,7 +834,7 @@ _gdk_display_get_pointer_info (GdkDisplay *display,
if (G_UNLIKELY (!info))
{
info = g_new0 (GdkPointerSurfaceInfo, 1);
info = g_slice_new0 (GdkPointerSurfaceInfo);
g_hash_table_insert (display->pointers_info, device, info);
}
-45
View File
@@ -37,22 +37,6 @@
G_DEFINE_INTERFACE (GdkDragSurface, gdk_drag_surface, GDK_TYPE_SURFACE)
enum
{
COMPUTE_SIZE,
N_SIGNALS
};
static guint signals[N_SIGNALS] = { 0 };
void
gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
GdkDragSurfaceSize *size)
{
g_signal_emit (surface, signals[COMPUTE_SIZE], 0, size);
}
static gboolean
gdk_drag_surface_default_present (GdkDragSurface *drag_surface,
int width,
@@ -65,35 +49,6 @@ static void
gdk_drag_surface_default_init (GdkDragSurfaceInterface *iface)
{
iface->present = gdk_drag_surface_default_present;
/**
* GdkDragSurface::compute-size:
* @surface: a `GdkDragSurface`
* @size: (type Gdk.DragSurfaceSize) (out caller-allocates): a
* `GdkDragSurfaceSize`
*
* Emitted when the size for the surface needs to be computed, when it is
* present.
*
* It will normally be emitted during the native surface layout cycle when the
* surface size needs to be recomputed.
*
* It is the responsibility of the drag surface user to handle this signal and
* compute the desired size of the surface, storing the computed size in the
* [struct@Gdk.DragSurfaceSize] object. Failing to do so will result in an
* arbitrary size being used as a result.
*
* Since: 4.12
*/
signals[COMPUTE_SIZE] =
g_signal_new (I_("compute-size"),
GDK_TYPE_DRAG_SURFACE,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 1,
GDK_TYPE_DRAG_SURFACE_SIZE);
}
/**
-4
View File
@@ -2,7 +2,6 @@
#define __GDK_DRAG_SURFACE_PRIVATE_H__
#include "gdkdragsurface.h"
#include "gdkdragsurfacesize.h"
G_BEGIN_DECLS
@@ -16,9 +15,6 @@ struct _GdkDragSurfaceInterface
int height);
};
void gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
GdkDragSurfaceSize *size);
G_END_DECLS
#endif /* __GDK_DRAG_SURFACE_PRIVATE_H__ */
-57
View File
@@ -1,57 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2023 Red Hat
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "gdkdragsurfacesizeprivate.h"
/**
* GdkDragSurfaceSize:
*
* The `GdkDragSurfaceSize` struct contains information that is useful
* to compute the size of a drag surface.
*
* Since: 4.12
*/
G_DEFINE_POINTER_TYPE (GdkDragSurfaceSize, gdk_drag_surface_size)
void
gdk_drag_surface_size_init (GdkDragSurfaceSize *size)
{
*size = (GdkDragSurfaceSize) { 0 };
}
/**
* gdk_drag_surface_size_set_size:
* @size: a `GdkDragSurfaceSize`
* @width: the width
* @height: the height
*
* Sets the size the drag surface prefers to be resized to.
*
* Since: 4.12
*/
void
gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
int width,
int height)
{
size->width = width;
size->height = height;
}
-42
View File
@@ -1,42 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2023 Red Hat
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#if !defined(__GDK_H_INSIDE__) && !defined(GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
#include <gdk/gdkversionmacros.h>
G_BEGIN_DECLS
typedef struct _GdkDragSurfaceSize GdkDragSurfaceSize;
#define GDK_TYPE_DRAG_SURFACE_SIZE (gdk_drag_surface_size_get_type ())
GDK_AVAILABLE_IN_4_12
GType gdk_drag_surface_size_get_type (void);
GDK_AVAILABLE_IN_4_12
void gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
int width,
int height);
G_END_DECLS
-29
View File
@@ -1,29 +0,0 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2023 Red Hat
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "gdkdragsurfacesize.h"
struct _GdkDragSurfaceSize
{
int width;
int height;
};
void gdk_drag_surface_size_init (GdkDragSurfaceSize *size);
+2 -2
View File
@@ -767,7 +767,7 @@ static void
free_value (gpointer value)
{
g_value_unset (value);
g_free (value);
g_slice_free (GValue, value);
}
static void
@@ -790,7 +790,7 @@ gdk_drop_read_value_internal (GdkDrop *self,
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_priority (task, io_priority);
g_task_set_source_tag (task, source_tag);
value = g_new0 (GValue, 1);
value = g_slice_new0 (GValue);
g_value_init (value, type);
g_task_set_task_data (task, value, free_value);
+11
View File
@@ -584,6 +584,8 @@ gdk_frame_clock_paint_idle (void *data)
{
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
_gdk_frame_clock_emit_layout (clock);
if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
g_print ("looping in layout %d\n", iter);
}
if (iter == 5)
g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
@@ -809,3 +811,12 @@ _gdk_frame_clock_idle_new (void)
return GDK_FRAME_CLOCK (clock);
}
GdkFrameClockPhase
gdk_frame_clock_get_current_phase (GdkFrameClock *clock)
{
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
return priv->phase;
}
+2
View File
@@ -127,6 +127,8 @@ void _gdk_frame_clock_emit_paint (GdkFrameClock *frame_clock);
void _gdk_frame_clock_emit_after_paint (GdkFrameClock *frame_clock);
void _gdk_frame_clock_emit_resume_events (GdkFrameClock *frame_clock);
GdkFrameClockPhase gdk_frame_clock_get_current_phase (GdkFrameClock *frame_clock);
G_END_DECLS
#endif /* __GDK_FRAME_CLOCK_PRIVATE_H__ */
+4 -2
View File
@@ -43,7 +43,7 @@ _gdk_frame_timings_new (gint64 frame_counter)
{
GdkFrameTimings *timings;
timings = g_new0 (GdkFrameTimings, 1);
timings = g_slice_new0 (GdkFrameTimings);
timings->ref_count = 1;
timings->frame_counter = frame_counter;
@@ -99,7 +99,9 @@ gdk_frame_timings_unref (GdkFrameTimings *timings)
timings->ref_count--;
if (timings->ref_count == 0)
g_free (timings);
{
g_slice_free (GdkFrameTimings, timings);
}
}
/**
+14 -22
View File
@@ -1546,28 +1546,20 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_half_float = gdk_gl_context_check_version (context, 3, 0, 3, 0) ||
epoxy_has_gl_extension ("OES_vertex_half_float");
#ifdef G_ENABLE_DEBUG
{
int max_texture_size;
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
GDK_DISPLAY_DEBUG (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
"%s version: %d.%d (%s)\n"
"* GLSL version: %s\n"
"* Max texture size: %d\n"
"* Extensions checked:\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
" - OES_vertex_half_float: %s",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
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");
}
#endif
GDK_DISPLAY_DEBUG (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), OPENGL,
"%s version: %d.%d (%s)\n"
"* GLSL version: %s\n"
"* Extensions checked:\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
" - OES_vertex_half_float: %s",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
priv->gl_version / 10, priv->gl_version % 10,
priv->is_legacy ? "legacy" : "core",
glGetString (GL_SHADING_LANGUAGE_VERSION),
priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "yes" : "no",
priv->has_half_float ? "yes" : "no");
priv->extensions_checked = TRUE;
}
-1
View File
@@ -335,7 +335,6 @@ gdk_gl_texture_determine_format (GdkGLTexture *self)
switch (internal_format)
{
case GL_RGB8:
case GL_RGB:
texture->format = GDK_MEMORY_R8G8B8;
break;
+4 -4
View File
@@ -178,10 +178,10 @@ gdk_memory_texture_new_subtexture (GdkMemoryTexture *source,
GBytes *bytes;
g_return_val_if_fail (GDK_IS_MEMORY_TEXTURE (source), NULL);
g_return_val_if_fail (x >= 0 && x < GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (y >= 0 && y < GDK_TEXTURE (source)->height, NULL);
g_return_val_if_fail (width > 0 && x + width <= GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (height > 0 && y + height <= GDK_TEXTURE (source)->height, NULL);
g_return_val_if_fail (x >= 0 || x < GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (y >= 0 || y < GDK_TEXTURE (source)->height, NULL);
g_return_val_if_fail (width > 0 || x + width <= GDK_TEXTURE (source)->width, NULL);
g_return_val_if_fail (height > 0 || y + height <= GDK_TEXTURE (source)->height, NULL);
texture = GDK_TEXTURE (source);
bpp = gdk_memory_format_bytes_per_pixel (texture->format);
+2 -2
View File
@@ -50,7 +50,7 @@ gdk_io_pipe_new (void)
{
GdkIOPipe *pipe;
pipe = g_new0 (GdkIOPipe, 1);
pipe = g_slice_new0 (GdkIOPipe);
pipe->ref_count = 1;
g_mutex_init (&pipe->mutex);
@@ -76,7 +76,7 @@ gdk_io_pipe_unref (GdkIOPipe *pipe)
g_cond_clear (&pipe->cond);
g_mutex_clear (&pipe->mutex);
g_free (pipe);
g_slice_free (GdkIOPipe, pipe);
}
static void
+2 -7
View File
@@ -67,12 +67,7 @@ G_DEFINE_BOXED_TYPE (GdkRGBA, gdk_rgba,
GdkRGBA *
gdk_rgba_copy (const GdkRGBA *rgba)
{
GdkRGBA *copy;
copy = g_new (GdkRGBA, 1);
memcpy (copy, rgba, sizeof (GdkRGBA));
return copy;
return g_slice_dup (GdkRGBA, rgba);
}
/**
@@ -84,7 +79,7 @@ gdk_rgba_copy (const GdkRGBA *rgba)
void
gdk_rgba_free (GdkRGBA *rgba)
{
g_free (rgba);
g_slice_free (GdkRGBA, rgba);
}
/**
+1 -1
View File
@@ -395,7 +395,7 @@ gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf)
bytes = g_bytes_new_with_free_func (gdk_pixbuf_get_pixels (pixbuf),
gdk_pixbuf_get_height (pixbuf)
* (gsize) gdk_pixbuf_get_rowstride (pixbuf),
* gdk_pixbuf_get_rowstride (pixbuf),
g_object_unref,
g_object_ref (pixbuf));
texture = gdk_memory_texture_new (gdk_pixbuf_get_width (pixbuf),
+2 -2
View File
@@ -76,7 +76,7 @@ gdk_texture_downloader_new (GdkTexture *texture)
g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL);
self = g_new (GdkTextureDownloader, 1);
self = g_slice_new (GdkTextureDownloader);
gdk_texture_downloader_init (self, texture);
return self;
@@ -121,7 +121,7 @@ gdk_texture_downloader_free (GdkTextureDownloader *self)
g_return_if_fail (self != NULL);
gdk_texture_downloader_finish (self);
g_free (self);
g_slice_free (GdkTextureDownloader, self);
}
/**
-24
View File
@@ -128,16 +128,6 @@
*/
#define GDK_VERSION_4_10 (G_ENCODE_VERSION (4, 10))
/**
* GDK_VERSION_4_12:
*
* A macro that evaluates to the 4.12 version of GDK, in a format
* that can be used by the C pre-processor.
*
* Since: 4.12
*/
#define GDK_VERSION_4_12 (G_ENCODE_VERSION (4, 12))
/* evaluates to the current stable version; for development cycles,
* this means the next stable target, with a hard backstop to the
@@ -307,18 +297,4 @@
# define GDK_DEPRECATED_IN_4_10_FOR(f) _GDK_EXTERN
#endif
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_4_12
# define GDK_AVAILABLE_IN_4_12 GDK_UNAVAILABLE(4, 12)
#else
# define GDK_AVAILABLE_IN_4_12 _GDK_EXTERN
#endif
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_12
# define GDK_DEPRECATED_IN_4_12 GDK_DEPRECATED
# define GDK_DEPRECATED_IN_4_12_FOR(f) GDK_DEPRECATED_FOR(f)
#else
# define GDK_DEPRECATED_IN_4_12 _GDK_EXTERN
# define GDK_DEPRECATED_IN_4_12_FOR(f) _GDK_EXTERN
#endif
#endif /* __GDK_VERSION_MACROS_H__ */
-14
View File
@@ -221,20 +221,6 @@ gdk_vulkan_strerror (VkResult result)
#endif
#if VK_HEADER_VERSION < 140
case VK_RESULT_RANGE_SIZE:
#endif
#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:
return "The requested video picture layout is not supported. (VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR:
return "A video profile operation specified via VkVideoProfileInfoKHR::videoCodecOperation is not supported. (VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR:
return "Format parameters in a requested VkVideoProfileInfoKHR chain are not supported. (VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR:
return "Codec-specific parameters in a requested (VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR)";
case VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR:
return "The specified video Std header version is not supported. (VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR)";
#endif
case VK_RESULT_MAX_ENUM:
default:
+2 -2
View File
@@ -283,7 +283,7 @@ static void
push_nsevent (GdkEvent *gdk_event,
NSEvent *nsevent)
{
GdkToNSEventMap *map = g_new0 (GdkToNSEventMap, 1);
GdkToNSEventMap *map = g_slice_new0 (GdkToNSEventMap);
map->link.data = map;
map->gdk_event = gdk_event_ref (gdk_event);
@@ -297,7 +297,7 @@ push_nsevent (GdkEvent *gdk_event,
gdk_event_unref (map->gdk_event);
[map->nsevent release];
g_free (map);
g_slice_free (GdkToNSEventMap, map);
}
}
+2 -2
View File
@@ -66,7 +66,7 @@ gdk_macos_zoomback_destroy (GdkMacosZoomback *zb)
{
gdk_surface_hide (GDK_SURFACE (zb->drag->drag_surface));
g_clear_object (&zb->drag);
g_free (zb);
g_slice_free (GdkMacosZoomback, zb);
}
static gboolean
@@ -157,7 +157,7 @@ gdk_macos_drag_drop_done (GdkDrag *drag,
/* Apple HIG suggests doing a "zoomback" animation of the surface back
* towards the original position.
*/
zb = g_new0 (GdkMacosZoomback, 1);
zb = g_slice_new0 (GdkMacosZoomback);
zb->drag = g_object_ref (self);
zb->frame_clock = gdk_surface_get_frame_clock (GDK_SURFACE (self->drag_surface));
zb->start_time = gdk_frame_clock_get_frame_time (zb->frame_clock);
+2 -2
View File
@@ -423,7 +423,7 @@ write_request_free (WriteRequest *wr)
g_clear_pointer (&wr->main_context, g_main_context_unref);
g_clear_object (&wr->stream);
[wr->item release];
g_free (wr);
g_slice_free (WriteRequest, wr);
}
static void
@@ -491,7 +491,7 @@ on_data_ready_cb (GObject *object,
return;
}
wr = g_new0 (WriteRequest, 1);
wr = g_slice_new0 (WriteRequest);
wr->item = [item retain];
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
wr->type = type;
+2 -4
View File
@@ -16,8 +16,6 @@ gdk_public_sources = files([
'gdkdisplay.c',
'gdkdisplaymanager.c',
'gdkdrag.c',
'gdkdragsurface.c',
'gdkdragsurfacesize.c',
'gdkdrawcontext.c',
'gdkdrop.c',
'gdkevents.c',
@@ -54,6 +52,7 @@ gdk_public_sources = files([
'gdktoplevellayout.c',
'gdktoplevelsize.c',
'gdktoplevel.c',
'gdkdragsurface.c',
'loaders/gdkpng.c',
'loaders/gdktiff.c',
'loaders/gdkjpeg.c',
@@ -77,7 +76,6 @@ gdk_public_headers = files([
'gdkdisplay.h',
'gdkdisplaymanager.h',
'gdkdrag.h',
'gdkdragsurfacesize.h',
'gdkdrawcontext.h',
'gdkdrop.h',
'gdkenums.h',
@@ -133,7 +131,7 @@ gdk_gresource_xml = configure_file(output: 'gdk.gresource.xml',
gdkresources = gnome.compile_resources('gdkresources',
gdk_gresource_xml,
source_dir: meson.current_source_dir(),
source_dir: '.',
c_name: '_gdk',
extra_args: '--manual-register',
)
-12
View File
@@ -33,7 +33,6 @@
#include "gdksurfaceprivate.h"
#include "gdktoplevelprivate.h"
#include "gdkdevice-wayland-private.h"
#include "gdkdragsurfacesizeprivate.h"
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
@@ -79,17 +78,6 @@ gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
if (impl->next_layout.surface_geometry_dirty)
{
GdkDragSurfaceSize size;
gdk_drag_surface_size_init (&size);
size.width = impl->next_layout.configured_width;
size.height = impl->next_layout.configured_height;
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
impl->next_layout.configured_width = size.width;
impl->next_layout.configured_height = size.height;
gdk_wayland_surface_update_size (surface,
impl->next_layout.configured_width,
impl->next_layout.configured_height,
+1 -4
View File
@@ -65,9 +65,6 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
int dx = impl->pending_buffer_offset_x;
int dy = impl->pending_buffer_offset_y;
impl->pending_buffer_offset_x = 0;
impl->pending_buffer_offset_y = 0;
gdk_wayland_surface_sync (surface);
gdk_wayland_surface_request_frame (surface);
@@ -121,7 +118,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
{
GdkWaylandDisplay *self = GDK_WAYLAND_DISPLAY (display);
if (!gdk_display_init_egl (display,
if (!gdk_display_init_egl (display,
EGL_PLATFORM_WAYLAND_EXT,
self->wl_display,
TRUE,
+11 -17
View File
@@ -561,14 +561,8 @@ gdk_wayland_surface_attach_image (GdkSurface *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_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);
impl->pending_buffer_offset_x,
impl->pending_buffer_offset_y);
impl->pending_buffer_offset_x = 0;
impl->pending_buffer_offset_y = 0;
@@ -977,15 +971,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
impl->display_server.egl_window = NULL;
}
impl->awaiting_frame = FALSE;
if (impl->awaiting_frame_frozen)
{
impl->awaiting_frame_frozen = FALSE;
gdk_surface_thaw_updates (surface);
}
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
if (impl->display_server.xdg_surface)
{
xdg_surface_destroy (impl->display_server.xdg_surface);
@@ -1004,6 +989,15 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
impl->initial_configure_received = FALSE;
}
impl->awaiting_frame = FALSE;
if (impl->awaiting_frame_frozen)
{
impl->awaiting_frame_frozen = FALSE;
gdk_surface_thaw_updates (surface);
}
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->hide_surface (impl);
g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
g_slist_free (impl->display_server.outputs);
+4 -5
View File
@@ -1005,8 +1005,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
} bmi;
HDC hdc;
uint8_t *pixels, *bits;
int x, y, w, h;
gsize rowstride;
int rowstride, x, y, w, h;
if (!GDI_CALL (GetIconInfo, (hicon, &ii)))
return NULL;
@@ -1058,7 +1057,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
no_alpha = FALSE;
pixels += 4;
}
pixels += rowstride - w * 4;
pixels += (w * 4 - rowstride);
}
/* mask */
@@ -1073,7 +1072,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
pixels[3] = 255 - bits[(x + y * w) * 4];
pixels += 4;
}
pixels += rowstride - w * 4;
pixels += (w * 4 - rowstride);
}
}
}
@@ -1147,7 +1146,7 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
xorp++;
}
}
pixels += rowstride - w * 4;
pixels += (w * 4 - rowstride);
}
}
+2 -2
View File
@@ -1836,7 +1836,7 @@ static void
gdk_drag_anim_destroy (GdkDragAnim *anim)
{
g_object_unref (anim->drag);
g_free (anim);
g_slice_free (GdkDragAnim, anim);
}
static gboolean
@@ -1936,7 +1936,7 @@ gdk_win32_drag_drop_done (GdkDrag *drag,
cairo_surface_destroy (surface);
*/
anim = g_new0 (GdkDragAnim, 1);
anim = g_slice_new0 (GdkDragAnim);
g_set_object (&anim->drag, drag_win32);
anim->frame_clock = gdk_surface_get_frame_clock (drag_win32->drag_surface);
anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
+3 -3
View File
@@ -1975,7 +1975,7 @@ gdk_x11_display_finalize (GObject *object)
if (trap->end_sequence == 0)
g_warning ("Display finalized with an unpopped error trap");
g_free (trap);
g_slice_free (GdkErrorTrap, trap);
}
g_free (display_x11->program_class);
@@ -2499,7 +2499,7 @@ delete_outdated_error_traps (GdkX11Display *display_x11)
tmp_list = tmp_list->next;
display_x11->error_traps =
g_slist_delete_link (display_x11->error_traps, free_me);
g_free (trap);
g_slice_free (GdkErrorTrap, trap);
}
else
{
@@ -2531,7 +2531,7 @@ gdk_x11_display_error_trap_push (GdkDisplay *display)
/* set up the Xlib callback to tell us about errors */
_gdk_x11_error_handler_push ();
trap = g_new0 (GdkErrorTrap, 1);
trap = g_slice_new0 (GdkErrorTrap);
trap->start_sequence = XNextRequest (display_x11->xdisplay);
trap->error_code = Success;
+2 -2
View File
@@ -1783,7 +1783,7 @@ gdk_drag_anim_destroy (GdkDragAnim *anim)
{
gdk_surface_hide (anim->drag->drag_surface);
g_object_unref (anim->drag);
g_free (anim);
g_slice_free (GdkDragAnim, anim);
}
static gboolean
@@ -1882,7 +1882,7 @@ gdk_x11_drag_drop_done (GdkDrag *drag,
cairo_surface_destroy (surface);
*/
anim = g_new0 (GdkDragAnim, 1);
anim = g_slice_new0 (GdkDragAnim);
anim->drag = g_object_ref (x11_drag);
anim->frame_clock = gdk_surface_get_frame_clock (x11_drag->drag_surface);
anim->start_time = gdk_frame_clock_get_frame_time (anim->frame_clock);
+4 -4
View File
@@ -79,7 +79,7 @@ gdk_x11_pending_selection_notify_new (Window window,
{
GdkX11PendingSelectionNotify *pending;
pending = g_new0 (GdkX11PendingSelectionNotify, 1);
pending = g_slice_new0 (GdkX11PendingSelectionNotify);
pending->n_pending = 1;
pending->xevent.type = SelectionNotify;
@@ -97,7 +97,7 @@ gdk_x11_pending_selection_notify_new (Window window,
static void
gdk_x11_pending_selection_notify_free (GdkX11PendingSelectionNotify *notify)
{
g_free (notify);
g_slice_free (GdkX11PendingSelectionNotify, notify);
}
static void
@@ -731,7 +731,7 @@ handle_timestamp_done (GObject *stream,
g_error_free (error);
}
g_free (user_data);
g_slice_free (gulong, user_data);
}
static void
@@ -747,7 +747,7 @@ handle_timestamp (GOutputStream *stream,
{
gulong *time_;
time_ = g_new (gulong, 1);
time_ = g_slice_new (gulong);
*time_ = timestamp;
g_output_stream_write_all_async (stream,
+2 -52
View File
@@ -40,7 +40,6 @@
#include "gdkglcontext-x11.h"
#include "gdkprivate-x11.h"
#include "gdktextureprivate.h"
#include "gdkdragsurfacesizeprivate.h"
#include "gdkseatprivate.h"
#include "gdkprivate.h"
@@ -346,36 +345,6 @@ compute_toplevel_size (GdkSurface *surface,
return FALSE;
}
static gboolean
compute_drag_surface_size (GdkSurface *surface,
int *width,
int *height)
{
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
GdkDragSurfaceSize size;
gdk_drag_surface_size_init (&size);
size.width = impl->next_layout.configured_width;
size.height = impl->next_layout.configured_height;
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
if ((impl->last_computed_width != size.width ||
impl->last_computed_height != size.height) &&
(impl->next_layout.configured_width != size.width ||
impl->next_layout.configured_height != size.height))
{
*width = size.width;
*height = size.height;
impl->last_computed_width = size.width;
impl->last_computed_height = size.height;
return TRUE;
}
return FALSE;
}
static gboolean
compute_size_idle (gpointer user_data)
{
@@ -425,24 +394,6 @@ gdk_x11_surface_compute_size (GdkSurface *surface)
impl->surface_scale);
}
impl->next_layout.surface_geometry_dirty = FALSE;
impl->next_layout.configure_pending = FALSE;
}
else if (GDK_IS_DRAG_SURFACE (surface))
{
int width, height;
if (compute_drag_surface_size (surface, &width, &height))
gdk_x11_surface_toplevel_resize (surface, width, height);
if (surface->resize_count == 0)
{
gdk_x11_surface_update_size (impl,
impl->next_layout.configured_width,
impl->next_layout.configured_height,
impl->surface_scale);
}
impl->next_layout.surface_geometry_dirty = FALSE;
impl->next_layout.configure_pending = FALSE;
}
@@ -836,7 +787,7 @@ free_pixmap (gpointer datap)
}
g_object_unref (data->display);
g_free (data);
g_slice_free (FreePixmapData, data);
}
static void
@@ -847,7 +798,7 @@ attach_free_pixmap_handler (cairo_surface_t *surface,
static const cairo_user_data_key_t key;
FreePixmapData *data;
data = g_new (FreePixmapData, 1);
data = g_slice_new (FreePixmapData);
data->display = g_object_ref (display);
data->pixmap = pixmap;
@@ -1407,7 +1358,6 @@ gdk_x11_surface_destroy (GdkSurface *surface,
unhook_surface_changed (surface);
disconnect_frame_clock (surface);
g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
if (impl->cairo_surface)
{
+2 -10
View File
@@ -44,7 +44,6 @@ gsk_gl_attachment_state_new (void)
self->textures[i].id = 0;
self->textures[i].changed = FALSE;
self->textures[i].initial = TRUE;
self->textures[i].sampler = sampler_index (GL_LINEAR, GL_LINEAR);
}
return self;
@@ -66,12 +65,9 @@ void
gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
GLenum target,
GLenum texture,
guint id,
GLint min_filter,
GLint mag_filter)
guint id)
{
GskGLBindTexture *attach;
unsigned int sampler;
g_assert (self != NULL);
g_assert (target == GL_TEXTURE_1D ||
@@ -81,16 +77,12 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
attach = &self->textures[texture - GL_TEXTURE0];
sampler = sampler_index (min_filter, mag_filter);
if (attach->target != target || attach->texture != texture || attach->id != id ||
attach->sampler != sampler)
if (attach->target != target || attach->texture != texture || attach->id != id)
{
attach->target = target;
attach->texture = texture;
attach->id = id;
attach->initial = FALSE;
attach->sampler = sampler;
if (attach->changed == FALSE)
{
+2 -30
View File
@@ -29,37 +29,11 @@ typedef struct _GskGLAttachmentState GskGLAttachmentState;
typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
typedef struct _GskGLBindTexture GskGLBindTexture;
#define GSK_GL_N_FILTERS 3
static inline guint
filter_index (GLint filter)
{
switch (filter)
{
case GL_LINEAR:
return 0;
case GL_NEAREST:
return 1;
case GL_LINEAR_MIPMAP_LINEAR:
return 2;
default:
g_assert_not_reached ();
}
}
static inline guint
sampler_index (GLint min_filter,
GLint mag_filter)
{
return filter_index (min_filter) * GSK_GL_N_FILTERS + filter_index (mag_filter);
}
struct _GskGLBindTexture
{
guint changed : 1;
guint initial : 1;
GLenum target : 26;
guint sampler : 4;
GLenum target : 30;
GLenum texture;
guint id;
};
@@ -88,9 +62,7 @@ void gsk_gl_attachment_state_unref (GskGLAttachmentS
void gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
GLenum target,
GLenum texture,
guint id,
GLint min_filter,
GLint mag_filter);
guint id);
void gsk_gl_attachment_state_bind_framebuffer (GskGLAttachmentState *self,
guint id);
+21 -75
View File
@@ -247,16 +247,6 @@ will_ignore_batch (GskGLCommandQueue *self)
return TRUE;
}
static inline GLint
filter_from_index (guint index)
{
GLint filters[3] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
g_assert (index < GSK_GL_N_FILTERS);
return filters[index];
}
static inline guint
snapshot_attachments (const GskGLAttachmentState *state,
GskGLCommandBinds *array)
@@ -270,7 +260,6 @@ snapshot_attachments (const GskGLAttachmentState *state,
{
bind[count].id = state->textures[i].id;
bind[count].texture = state->textures[i].texture;
bind[count].sampler = state->textures[i].sampler;
count++;
}
}
@@ -411,9 +400,6 @@ gsk_gl_command_queue_dispose (GObject *object)
g_clear_pointer (&self->attachments, gsk_gl_attachment_state_unref);
g_clear_pointer (&self->uniforms, gsk_gl_uniform_state_unref);
if (self->has_samplers)
glDeleteSamplers (G_N_ELEMENTS (self->samplers), self->samplers);
gsk_gl_command_batches_clear (&self->batches);
gsk_gl_command_binds_clear (&self->batch_binds);
gsk_gl_command_uniforms_clear (&self->batch_uniforms);
@@ -448,7 +434,6 @@ gsk_gl_command_queue_new (GdkGLContext *context,
GskGLUniformState *uniforms)
{
GskGLCommandQueue *self;
guint i;
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
@@ -464,37 +449,7 @@ gsk_gl_command_queue_new (GdkGLContext *context,
/* Determine max texture size immediately and restore context */
gdk_gl_context_make_current (context);
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &self->max_texture_size);
if (g_getenv ("GSK_MAX_TEXTURE_SIZE"))
{
int max_texture_size = atoi (g_getenv ("GSK_MAX_TEXTURE_SIZE"));
if (max_texture_size == 0)
{
g_warning ("Failed to parse GSK_MAX_TEXTURE_SIZE");
}
else
{
max_texture_size = MAX (max_texture_size, 512);
GSK_DEBUG(OPENGL, "Limiting max texture size to %d", max_texture_size);
self->max_texture_size = MIN (self->max_texture_size, max_texture_size);
}
}
self->has_samplers = gdk_gl_context_check_version (context, 3, 3, 3, 0);
/* create the samplers */
if (self->has_samplers)
{
glGenSamplers (G_N_ELEMENTS (self->samplers), self->samplers);
for (i = 0; i < G_N_ELEMENTS (self->samplers); i++)
{
glSamplerParameteri (self->samplers[i], GL_TEXTURE_MIN_FILTER, filter_from_index(i / GSK_GL_N_FILTERS));
glSamplerParameteri (self->samplers[i], GL_TEXTURE_MAG_FILTER, filter_from_index(i % GSK_GL_N_FILTERS));
glSamplerParameteri (self->samplers[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri (self->samplers[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
return g_steal_pointer (&self);
}
@@ -1017,7 +972,6 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
guint vao_id;
guint vbo_id;
int textures[4];
int samplers[4];
int framebuffer = -1;
int next_batch_index;
int active = -1;
@@ -1030,8 +984,6 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
for (guint i = 0; i < G_N_ELEMENTS (textures); i++)
textures[i] = -1;
for (guint i = 0; i < G_N_ELEMENTS (samplers); i++)
samplers[i] = -1;
gsk_gl_command_queue_sort_batches (self);
@@ -1159,23 +1111,6 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBindTexture (GL_TEXTURE_2D, bind->id);
textures[bind->texture] = bind->id;
if (!self->has_samplers)
{
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_from_index(bind->sampler / GSK_GL_N_FILTERS));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_from_index(bind->sampler % GSK_GL_N_FILTERS));
}
}
if (samplers[bind->texture] != bind->sampler)
{
if (self->has_samplers)
glBindSampler (bind->texture, self->samplers[bind->sampler]);
else
{
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_from_index(bind->sampler / GSK_GL_N_FILTERS));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_from_index(bind->sampler % GSK_GL_N_FILTERS));
}
samplers[bind->texture] = bind->sampler;
}
bind++;
@@ -1311,6 +1246,8 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
int width,
int height,
int format,
int min_filter,
int mag_filter,
guint *out_fbo_id,
guint *out_texture_id)
{
@@ -1324,8 +1261,9 @@ gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
g_assert (out_texture_id != NULL);
texture_id = gsk_gl_command_queue_create_texture (self,
width, height,
format);
width, height,
format,
min_filter, mag_filter);
if (texture_id == -1)
{
@@ -1350,7 +1288,9 @@ int
gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
int width,
int height,
int format)
int format,
int min_filter,
int mag_filter)
{
GLuint texture_id = 0;
@@ -1366,9 +1306,9 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_id);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -1494,7 +1434,9 @@ gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
int
gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
GdkTexture *texture)
GdkTexture *texture,
int min_filter,
int mag_filter)
{
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
cairo_surface_t *surface = NULL;
@@ -1503,6 +1445,7 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
g_assert (!GDK_IS_GL_TEXTURE (texture));
g_assert (mag_filter == GL_LINEAR || mag_filter == GL_NEAREST);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
@@ -1511,10 +1454,10 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
g_warning ("Attempt to create texture of size %ux%u but max size is %d. "
"Clipping will occur.",
width, height, self->max_texture_size);
width = MIN (width, self->max_texture_size);
height = MIN (height, self->max_texture_size);
width = MAX (width, self->max_texture_size);
height = MAX (height, self->max_texture_size);
}
texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8);
texture_id = gsk_gl_command_queue_create_texture (self, width, height, GL_RGBA8, min_filter, mag_filter);
if (texture_id == -1)
return texture_id;
@@ -1526,6 +1469,9 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
gsk_gl_command_queue_do_upload_texture (self, texture);
if (min_filter == GL_LINEAR_MIPMAP_LINEAR)
glGenerateMipmap (GL_TEXTURE_2D);
/* Restore previous texture state if any */
if (self->attachments->textures[0].id > 0)
glBindTexture (self->attachments->textures[0].target,
+10 -16
View File
@@ -53,12 +53,10 @@ typedef struct _GskGLCommandBind
* texture will be placed into. We always use GL_TEXTURE_2D so we don't
* waste any bits here to indicate that.
*/
guint texture : 4;
guint sampler : 4;
guint texture : 5;
/* The identifier for the texture created with glGenTextures(). */
guint id: 24;
guint id : 27;
} GskGLCommandBind;
G_STATIC_ASSERT (sizeof (GskGLCommandBind) == 4);
@@ -227,13 +225,6 @@ struct _GskGLCommandQueue
*/
GskGLCommandUniforms batch_uniforms;
/* Array of samplers that we use for mag/min filter handling. It is indexed
* by the sampler_index() function.
* Note that when samplers are not supported (hello GLES), we fall back to
* setting the texture filter, but that needs to be done for every texture.
*/
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
/* 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.
@@ -266,9 +257,6 @@ struct _GskGLCommandQueue
/* Counter for uploads on the frame */
guint n_uploads;
/* If the GL context is new enough for sampler support */
guint has_samplers : 1;
/* If we're inside a begin/end_frame pair */
guint in_frame : 1;
@@ -293,16 +281,22 @@ void gsk_gl_command_queue_execute (GskGLCommandQueue
const cairo_region_t *scissor,
guint default_framebuffer);
int gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
GdkTexture *texture);
GdkTexture *texture,
int min_filter,
int mag_filter);
int gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
int width,
int height,
int format);
int format,
int min_filter,
int mag_filter);
guint gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self);
gboolean gsk_gl_command_queue_create_render_target (GskGLCommandQueue *self,
int width,
int height,
int format,
int min_filter,
int mag_filter,
guint *out_fbo_id,
guint *out_texture_id);
void gsk_gl_command_queue_delete_program (GskGLCommandQueue *self,
+71 -61
View File
@@ -59,7 +59,8 @@ texture_key_hash (gconstpointer v)
return GPOINTER_TO_SIZE (k->pointer) ^
((scale_x << 8) |
(scale_y << 4) |
(scale_y << 6) |
(k->filter << 1) |
k->pointer_is_child);
}
@@ -73,6 +74,7 @@ texture_key_equal (gconstpointer v1,
return k1->pointer == k2->pointer &&
k1->scale_x == k2->scale_x &&
k1->scale_y == k2->scale_y &&
k1->filter == k2->filter &&
k1->pointer_is_child == k2->pointer_is_child &&
(!k1->pointer_is_child || memcmp (&k1->parent_rect, &k2->parent_rect, sizeof k1->parent_rect) == 0);
}
@@ -617,7 +619,7 @@ gsk_gl_driver_after_frame (GskGLDriver *self)
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
gsk_gl_driver_autorelease_texture (self, render_target->texture_id);
g_free (render_target);
g_slice_free (GskGLRenderTarget, render_target);
self->render_targets->len--;
}
@@ -690,7 +692,8 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
* gsk_gl_driver_load_texture:
* @self: a `GdkTexture`
* @texture: a `GdkTexture`
* @ensure_mipmap: Mipmaps for this texture must exist for downscaling
* @min_filter: GL_NEAREST or GL_LINEAR
* @mag_filter: GL_NEAREST or GL_LINEAR
*
* Loads a `GdkTexture` by uploading the contents to the GPU when
* necessary. If @texture is a `GdkGLTexture`, it can be used without
@@ -711,7 +714,8 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
guint
gsk_gl_driver_load_texture (GskGLDriver *self,
GdkTexture *texture,
gboolean ensure_mipmap)
int min_filter,
int mag_filter)
{
GdkGLContext *context;
GdkMemoryTexture *downloaded_texture;
@@ -719,6 +723,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
guint texture_id;
int height;
int width;
int format;
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
g_return_val_if_fail (GDK_IS_TEXTURE (texture), 0);
@@ -726,23 +731,9 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
context = self->command_queue->context;
texture_id = 0;
downloaded_texture = NULL;
format = GL_RGBA8;
t = gdk_texture_get_render_data (texture, self);
if (t && t->texture_id)
{
if (ensure_mipmap & !t->has_mipmap)
{
glBindTexture (GL_TEXTURE_2D, t->texture_id);
glGenerateMipmap (GL_TEXTURE_2D);
t->has_mipmap = TRUE;
}
return t->texture_id;
}
if (GDK_IS_GL_TEXTURE (texture) && !ensure_mipmap)
if (GDK_IS_GL_TEXTURE (texture))
{
GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
@@ -752,32 +743,36 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
/* A GL texture from the same GL context is a simple task... */
return gdk_gl_texture_get_id (gl_texture);
}
else
{
downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
}
}
if (texture_id == 0)
else
{
if ((t = gdk_texture_get_render_data (texture, self)))
{
if (t->min_filter == min_filter && t->mag_filter == mag_filter && t->texture_id)
return t->texture_id;
}
downloaded_texture = gdk_memory_texture_from_texture (texture, gdk_texture_get_format (texture));
/* The download_texture() call may have switched the GL context. Make sure
* the right context is at work again.
*/
gdk_gl_context_make_current (context);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, GDK_TEXTURE (downloaded_texture));
}
/* The download_texture() call may have switched the GL context. Make sure
* the right context is at work again. */
gdk_gl_context_make_current (context);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
GDK_TEXTURE (downloaded_texture),
min_filter,
mag_filter);
t = gsk_gl_texture_new (texture_id,
width, height,
self->current_frame_id);
if (ensure_mipmap)
{
glBindTexture (GL_TEXTURE_2D, t->texture_id);
glGenerateMipmap (GL_TEXTURE_2D);
t->has_mipmap = TRUE;
}
width, height, format, min_filter, mag_filter,
self->current_frame_id);
g_hash_table_insert (self->textures, GUINT_TO_POINTER (texture_id), t);
@@ -789,7 +784,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
g_clear_object (&downloaded_texture);
return t->texture_id;
return texture_id;
}
/**
@@ -798,6 +793,8 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
* @width: the width of the texture
* @height: the height of the texture
* @format: format for the texture
* @min_filter: GL_NEAREST or GL_LINEAR
* @mag_filter: GL_NEAREST or GL_FILTER
*
* Creates a new texture immediately that can be used by the caller
* to upload data, map to a framebuffer, or other uses which may
@@ -815,7 +812,9 @@ GskGLTexture *
gsk_gl_driver_create_texture (GskGLDriver *self,
float width,
float height,
int format)
int format,
int min_filter,
int mag_filter)
{
GskGLTexture *texture;
guint texture_id;
@@ -823,11 +822,14 @@ gsk_gl_driver_create_texture (GskGLDriver *self,
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), NULL);
texture_id = gsk_gl_command_queue_create_texture (self->command_queue,
width, height,
format);
width, height,
format,
min_filter, mag_filter);
texture = gsk_gl_texture_new (texture_id,
width, height,
self->current_frame_id);
width, height,
format,
min_filter, mag_filter,
self->current_frame_id);
g_hash_table_insert (self->textures,
GUINT_TO_POINTER (texture->texture_id),
texture);
@@ -873,6 +875,8 @@ gsk_gl_driver_release_texture (GskGLDriver *self,
* @width: the width for the render target
* @height: the height for the render target
* @format: the format to use
* @min_filter: the min filter to use for the texture
* @mag_filter: the mag filter to use for the texture
* @out_render_target: (out): a location for the render target
*
* Creates a new render target which contains a framebuffer and a texture
@@ -893,6 +897,8 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
int width,
int height,
int format,
int min_filter,
int mag_filter,
GskGLRenderTarget **out_render_target)
{
guint framebuffer_id;
@@ -910,7 +916,9 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
GskGLRenderTarget *render_target = g_ptr_array_index (self->render_targets, i-1);
if (render_target->width == width &&
render_target->height == height)
render_target->height == height &&
render_target->min_filter == min_filter &&
render_target->mag_filter == mag_filter)
{
*out_render_target = g_ptr_array_steal_index_fast (self->render_targets, i-1);
return TRUE;
@@ -922,11 +930,14 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
if (gsk_gl_command_queue_create_render_target (self->command_queue,
width, height,
format,
min_filter, mag_filter,
&framebuffer_id, &texture_id))
{
GskGLRenderTarget *render_target;
render_target = g_new0 (GskGLRenderTarget, 1);
render_target = g_slice_new0 (GskGLRenderTarget);
render_target->min_filter = min_filter;
render_target->mag_filter = mag_filter;
render_target->format = format;
render_target->width = width;
render_target->height = height;
@@ -987,13 +998,16 @@ gsk_gl_driver_release_render_target (GskGLDriver *self,
texture = gsk_gl_texture_new (render_target->texture_id,
render_target->width,
render_target->height,
render_target->format,
render_target->min_filter,
render_target->mag_filter,
self->current_frame_id);
g_hash_table_insert (self->textures,
GUINT_TO_POINTER (texture_id),
g_steal_pointer (&texture));
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
g_free (render_target);
g_slice_free (GskGLRenderTarget, render_target);
}
@@ -1180,7 +1194,8 @@ gsk_gl_driver_create_command_queue (GskGLDriver *self,
void
gsk_gl_driver_add_texture_slices (GskGLDriver *self,
GdkTexture *texture,
gboolean ensure_mipmap,
int min_filter,
int mag_filter,
guint min_cols,
guint min_rows,
GskGLTextureSlice **out_slices,
@@ -1212,12 +1227,9 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
n_slices = cols * rows;
t = gdk_texture_get_render_data (texture, self);
if (t)
if ((t = gdk_texture_get_render_data (texture, self)))
{
if (t->n_slices == n_slices &&
(t->has_mipmap || !ensure_mipmap))
if (t->n_slices == n_slices)
{
*out_slices = t->slices;
*out_n_slices = t->n_slices;
@@ -1245,13 +1257,10 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
subtex = gdk_memory_texture_new_subtexture (memtex,
x, y,
slice_width, slice_height);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue, subtex);
texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
subtex,
min_filter, mag_filter);
g_object_unref (subtex);
if (ensure_mipmap)
{
glBindTexture (GL_TEXTURE_2D, texture_id);
glGenerateMipmap (GL_TEXTURE_2D);
}
slices[slice_index].rect.x = x;
slices[slice_index].rect.y = y;
@@ -1271,8 +1280,9 @@ gsk_gl_driver_add_texture_slices (GskGLDriver *self,
/* Allocate one Texture for the entire thing. */
t = gsk_gl_texture_new (0,
tex_width, tex_height,
GL_RGBA8,
GL_NEAREST, GL_NEAREST,
self->current_frame_id);
t->has_mipmap = ensure_mipmap;
/* Use gsk_gl_texture_free() as destroy notify here since we are
* not inserting this GskGLTexture into self->textures!
@@ -1331,7 +1341,7 @@ create_texture_from_texture_destroy (gpointer data)
gdk_gl_context_make_current (state->context);
glDeleteTextures (1, &state->texture_id);
g_clear_object (&state->context);
g_free (state);
g_slice_free (GskGLTextureState, state);
}
GdkTexture *
@@ -1352,7 +1362,7 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
if (!(texture = g_hash_table_lookup (self->textures, GUINT_TO_POINTER (texture_id))))
g_return_val_if_reached (NULL);
state = g_new0 (GskGLTextureState, 1);
state = g_slice_new0 (GskGLTextureState);
state->texture_id = texture_id;
state->context = g_object_ref (self->command_queue->context);
+22 -13
View File
@@ -61,6 +61,7 @@ typedef struct {
gconstpointer pointer;
float scale_x;
float scale_y;
int filter;
int pointer_is_child;
graphene_rect_t parent_rect; /* Valid when pointer_is_child */
} GskTextureKey;
@@ -85,6 +86,8 @@ struct _GskGLRenderTarget
{
guint framebuffer_id;
guint texture_id;
int min_filter;
int mag_filter;
int format;
int width;
int height;
@@ -141,6 +144,8 @@ gboolean gsk_gl_driver_create_render_target (GskGLDriver *s
int width,
int height,
int format,
int min_filter,
int mag_filter,
GskGLRenderTarget **render_target);
guint gsk_gl_driver_release_render_target (GskGLDriver *self,
GskGLRenderTarget *render_target,
@@ -156,11 +161,14 @@ void gsk_gl_driver_cache_texture (GskGLDriver *s
guint texture_id);
guint gsk_gl_driver_load_texture (GskGLDriver *self,
GdkTexture *texture,
gboolean ensure_mipmap);
int min_filter,
int mag_filter);
GskGLTexture * gsk_gl_driver_create_texture (GskGLDriver *self,
float width,
float height,
int format);
int format,
int min_filter,
int mag_filter);
void gsk_gl_driver_release_texture (GskGLDriver *self,
GskGLTexture *texture);
void gsk_gl_driver_release_texture_by_id (GskGLDriver *self,
@@ -169,7 +177,8 @@ GskGLTexture * gsk_gl_driver_mark_texture_permanent (GskGLDriver *s
guint texture_id);
void gsk_gl_driver_add_texture_slices (GskGLDriver *self,
GdkTexture *texture,
gboolean ensure_mipmap,
int min_filter,
int mag_filter,
guint min_cols,
guint min_rows,
GskGLTextureSlice **out_slices,
@@ -223,7 +232,8 @@ gsk_gl_driver_lookup_texture (GskGLDriver *self,
static inline void
gsk_gl_driver_slice_texture (GskGLDriver *self,
GdkTexture *texture,
gboolean ensure_mipmap,
int min_filter,
int mag_filter,
guint min_cols,
guint min_rows,
GskGLTextureSlice **out_slices,
@@ -231,18 +241,17 @@ gsk_gl_driver_slice_texture (GskGLDriver *self,
{
GskGLTexture *t;
t = gdk_texture_get_render_data (texture, self);
if (t && t->slices &&
(t->has_mipmap || !ensure_mipmap) &&
min_cols == 0 && min_rows == 0)
if ((t = gdk_texture_get_render_data (texture, self)))
{
*out_slices = t->slices;
*out_n_slices = t->n_slices;
return;
if (min_cols == 0 && min_rows == 0)
{
*out_slices = t->slices;
*out_n_slices = t->n_slices;
return;
}
}
gsk_gl_driver_add_texture_slices (self, texture, ensure_mipmap, min_cols, min_rows, out_slices, out_n_slices);
gsk_gl_driver_add_texture_slices (self, texture, min_filter, mag_filter, min_cols, min_rows, out_slices, out_n_slices);
}
G_END_DECLS
+2 -2
View File
@@ -74,13 +74,13 @@ gsk_gl_glyph_key_free (gpointer data)
GskGLGlyphKey *key = data;
g_clear_object (&key->font);
g_free (key);
g_slice_free (GskGLGlyphKey, key);
}
static void
gsk_gl_glyph_value_free (gpointer data)
{
g_free (data);
g_slice_free (GskGLGlyphValue, data);
}
static void
+1 -3
View File
@@ -88,9 +88,7 @@ gsk_gl_glyph_library_lookup_or_add (GskGLGlyphLibrary *self,
}
else
{
GskGLGlyphKey *k;
k = g_new (GskGLGlyphKey, 1);
memcpy (k, key, sizeof (GskGLGlyphKey));
GskGLGlyphKey *k = g_slice_copy (sizeof *key, key);
g_object_ref (k->font);
gsk_gl_glyph_library_add (self, k, out_value);
self->front[front_index].key = *key;
+1 -1
View File
@@ -52,7 +52,7 @@ gsk_gl_icon_data_free (gpointer data)
GskGLIconData *icon_data = data;
g_clear_object (&icon_data->source_texture);
g_free (icon_data);
g_slice_free (GskGLIconData, icon_data);
}
static void
+9 -31
View File
@@ -245,29 +245,6 @@ gsk_gl_program_set_uniform_color (GskGLProgram *self,
color);
}
static inline void
gsk_gl_program_set_uniform_texture_with_filter (GskGLProgram *self,
guint key,
guint stamp,
GLenum texture_target,
GLenum texture_slot,
guint texture_id,
GLint min_filter,
GLint mag_filter)
{
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
texture_target,
texture_slot,
texture_id,
min_filter,
mag_filter);
gsk_gl_uniform_state_set_texture (self->uniforms,
self->program_info,
key,
stamp,
texture_slot);
}
static inline void
gsk_gl_program_set_uniform_texture (GskGLProgram *self,
guint key,
@@ -276,14 +253,15 @@ gsk_gl_program_set_uniform_texture (GskGLProgram *self,
GLenum texture_slot,
guint texture_id)
{
gsk_gl_program_set_uniform_texture_with_filter (self,
key,
stamp,
texture_target,
texture_slot,
texture_id,
GL_LINEAR,
GL_LINEAR);
gsk_gl_attachment_state_bind_texture (self->driver->command_queue->attachments,
texture_target,
texture_slot,
texture_id);
gsk_gl_uniform_state_set_texture (self->uniforms,
self->program_info,
key,
stamp,
texture_slot);
}
static inline void
+1
View File
@@ -379,6 +379,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
if (gsk_gl_driver_create_render_target (self->driver,
width, height,
format,
GL_NEAREST, GL_NEAREST,
&render_target))
{
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
+139 -181
View File
@@ -29,7 +29,6 @@
#include <gsk/gskrendernodeprivate.h>
#include <gsk/gskglshaderprivate.h>
#include <gdk/gdktextureprivate.h>
#include <gdk/gdkmemorytextureprivate.h>
#include <gsk/gsktransformprivate.h>
#include <gsk/gskroundedrectprivate.h>
#include <math.h>
@@ -198,6 +197,7 @@ typedef struct _GskGLRenderOffscreen
guint force_offscreen : 1;
guint reset_clip : 1;
guint do_not_cache : 1;
guint linear_filter : 1;
/* Return location for whether we created a texture */
guint was_offscreen : 1;
@@ -260,7 +260,6 @@ node_supports_2d_transform (const GskRenderNode *node)
case GSK_OPACITY_NODE:
case GSK_COLOR_MATRIX_NODE:
case GSK_TEXTURE_NODE:
case GSK_TEXTURE_SCALE_NODE:
case GSK_CROSS_FADE_NODE:
case GSK_LINEAR_GRADIENT_NODE:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
@@ -315,7 +314,6 @@ node_supports_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:
@@ -874,21 +872,6 @@ gsk_gl_render_job_transform_bounds (GskGLRenderJob *job,
}
}
static inline void
gsk_gl_render_job_untransform_bounds (GskGLRenderJob *job,
const graphene_rect_t *rect,
graphene_rect_t *out_rect)
{
GskTransform *transform;
transform = gsk_transform_invert (gsk_transform_ref (job->current_modelview->transform));
gsk_transform_transform_bounds (transform, rect, out_rect);
out_rect->origin.x -= job->offset_x;
out_rect->origin.y -= job->offset_y;
}
static inline void
gsk_gl_render_job_transform_rounded_rect (GskGLRenderJob *job,
const GskRoundedRect *rect,
@@ -1220,6 +1203,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
key.pointer_is_child = FALSE;
key.scale_x = scale_x;
key.scale_y = scale_y;
key.filter = GL_NEAREST;
cached_id = gsk_gl_driver_lookup_texture (job->driver, &key);
@@ -1289,7 +1273,8 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
/* Create texture to upload */
texture = gdk_texture_new_for_surface (surface);
texture_id = gsk_gl_driver_load_texture (job->driver, texture, FALSE);
texture_id = gsk_gl_driver_load_texture (job->driver, texture,
GL_NEAREST, GL_NEAREST);
if (gdk_gl_context_has_debug (job->command_queue->context))
gdk_gl_context_label_object_printf (job->command_queue->context, GL_TEXTURE, texture_id,
@@ -1338,6 +1323,7 @@ blur_offscreen (GskGLRenderJob *job,
MAX (texture_to_blur_width, 1),
MAX (texture_to_blur_height, 1),
job->target_format,
GL_NEAREST, GL_NEAREST,
&pass1))
return 0;
@@ -1348,6 +1334,7 @@ blur_offscreen (GskGLRenderJob *job,
texture_to_blur_width,
texture_to_blur_height,
job->target_format,
GL_NEAREST, GL_NEAREST,
&pass2))
return gsk_gl_driver_release_render_target (job->driver, pass1, FALSE);
@@ -2100,14 +2087,13 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
{
GskGLRenderOffscreen offscreen = {0};
float sx = 1, sy = 1;
gboolean linear_filter = FALSE;
offscreen.bounds = &child->bounds;
offscreen.force_offscreen = FALSE;
offscreen.reset_clip = TRUE;
if (!result_is_axis_aligned (transform, &child->bounds))
linear_filter = TRUE;
offscreen.linear_filter = TRUE;
if (category == GSK_TRANSFORM_CATEGORY_2D)
{
@@ -2137,19 +2123,16 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob *job,
if (gsk_gl_render_job_visit_node_with_offscreen (job, child, &offscreen))
{
/* For non-trivial transforms, we draw everything on a texture and then
* draw the texture transformed.
*/
* draw the texture transformed. */
if (transform)
gsk_gl_render_job_push_modelview (job, transform);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
linear_filter ? GL_LINEAR : GL_NEAREST,
linear_filter ? GL_LINEAR : GL_NEAREST);
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
gsk_gl_render_job_draw_offscreen (job, &child->bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
@@ -2227,6 +2210,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
key.pointer_is_child = FALSE;
key.scale_x = scale_x;
key.scale_y = scale_y;
key.filter = GL_NEAREST;
blurred_texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
@@ -2270,6 +2254,7 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
if (!gsk_gl_driver_create_render_target (job->driver,
texture_width, texture_height,
get_target_format (job, node),
GL_NEAREST, GL_NEAREST,
&render_target))
g_assert_not_reached ();
@@ -2542,6 +2527,7 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
gsk_gl_driver_create_render_target (job->driver,
texture_width, texture_height,
get_target_format (job, node),
GL_NEAREST, GL_NEAREST,
&render_target);
if (gdk_gl_context_has_debug (context))
@@ -3202,6 +3188,7 @@ gsk_gl_render_job_visit_blur_node (GskGLRenderJob *job,
key.pointer_is_child = FALSE;
key.scale_x = job->scale_x;
key.scale_y = job->scale_y;
key.filter = GL_NEAREST;
offscreen.texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
cache_texture = offscreen.texture_id == 0;
@@ -3510,10 +3497,12 @@ gsk_gl_render_job_visit_gl_shader_node (GskGLRenderJob *job,
static void
gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
GdkTexture *texture,
gboolean ensure_mipmap,
int min_filter,
int mag_filter,
GskGLRenderOffscreen *offscreen)
{
if (!ensure_mipmap &&
if (min_filter == GL_LINEAR &&
mag_filter == GL_LINEAR &&
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
texture->width,
texture->height) &&
@@ -3527,7 +3516,7 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
}
else
{
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, min_filter, mag_filter);
init_full_texture_region (offscreen);
}
}
@@ -3538,28 +3527,23 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
const graphene_rect_t *bounds)
{
int max_texture_size = job->command_queue->max_texture_size;
gboolean use_mipmaps;
use_mipmaps = job->scale_x < 0.5 || job->scale_y < 0.5;
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
{
GskGLRenderOffscreen offscreen = {0};
gsk_gl_render_job_upload_texture (job, texture, use_mipmaps, &offscreen);
gsk_gl_render_job_upload_texture (job, texture, GL_LINEAR, GL_LINEAR, &offscreen);
g_assert (offscreen.texture_id);
g_assert (offscreen.was_offscreen == FALSE);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
use_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR);
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
gsk_gl_render_job_draw_offscreen (job, bounds, &offscreen);
gsk_gl_render_job_end_draw (job);
}
@@ -3574,7 +3558,7 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
GskGLTextureSlice *slices = NULL;
guint n_slices = 0;
gsk_gl_driver_slice_texture (job->driver, texture, use_mipmaps, 0, 0, &slices, &n_slices);
gsk_gl_driver_slice_texture (job->driver, texture, GL_NEAREST, GL_NEAREST, 0, 0, &slices, &n_slices);
g_assert (slices != NULL);
g_assert (n_slices > 0);
@@ -3593,13 +3577,11 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
if (i > 0)
gsk_gl_render_job_split_draw (job);
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
slice->texture_id,
use_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR);
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
slice->texture_id);
gsk_gl_render_job_draw_coords (job,
x1, y1, x2, y2,
@@ -3627,164 +3609,133 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
{
GdkTexture *texture = gsk_texture_scale_node_get_texture (node);
const graphene_rect_t *bounds = &node->bounds;
GskScalingFilter filter = gsk_texture_scale_node_get_filter (node);
GskScalingFilter scaling_filter = gsk_texture_scale_node_get_filter (node);
int min_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR };
int mag_filters[] = { GL_LINEAR, GL_NEAREST, GL_LINEAR };
int min_filter = min_filters[filter];
int mag_filter = mag_filters[filter];
int min_filter = min_filters[scaling_filter];
int mag_filter = mag_filters[scaling_filter];
int max_texture_size = job->command_queue->max_texture_size;
graphene_rect_t clip_rect;
GskGLRenderTarget *render_target;
graphene_rect_t viewport;
graphene_rect_t prev_viewport;
graphene_matrix_t prev_projection;
float prev_alpha;
guint prev_fbo;
float u0, u1, v0, v1;
GskTextureKey key;
guint texture_id;
if (filter == GSK_SCALING_FILTER_LINEAR)
if (scaling_filter == GSK_SCALING_FILTER_LINEAR)
{
gsk_gl_render_job_visit_texture (job, texture, bounds);
return;
}
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
return;
key.pointer = node;
key.pointer_is_child = TRUE;
key.parent_rect = clip_rect;
key.scale_x = 1.;
key.scale_y = 1.;
texture_id = gsk_gl_driver_lookup_texture (job->driver, &key);
if (texture_id != 0)
goto render_texture;
viewport = GRAPHENE_RECT_INIT (0, 0,
clip_rect.size.width,
clip_rect.size.height);
if (!gsk_gl_driver_create_render_target (job->driver,
(int) ceilf (clip_rect.size.width),
(int) ceilf (clip_rect.size.height),
get_target_format (job, node),
&render_target))
{
gsk_gl_render_job_visit_texture (job, texture, bounds);
return;
}
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
gsk_gl_render_job_set_projection_from_rect (job, &viewport, &prev_projection);
gsk_gl_render_job_set_modelview (job, NULL);
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &viewport);
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size)
{
texture_id = gsk_gl_driver_load_texture (job->driver, texture, filter == GSK_SCALING_FILTER_TRILINEAR);
GskGLRenderTarget *render_target;
GskGLRenderOffscreen offscreen = {0};
graphene_rect_t viewport;
graphene_rect_t prev_viewport;
graphene_matrix_t prev_projection;
float prev_alpha;
guint prev_fbo;
guint texture_id;
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;
viewport = GRAPHENE_RECT_INIT (0, 0,
bounds->size.width,
bounds->size.height);
if (!gsk_gl_driver_create_render_target (job->driver,
(int) ceilf (viewport.size.width),
(int) ceilf (viewport.size.height),
get_target_format (job, node),
GL_LINEAR, GL_LINEAR,
&render_target))
{
/* viewport is too big, slice the texture and try again */
goto slice;
}
gsk_gl_render_job_upload_texture (job, texture, min_filter, mag_filter, &offscreen);
g_assert (offscreen.texture_id);
g_assert (offscreen.was_offscreen == FALSE);
gsk_gl_render_job_set_viewport (job, &viewport, &prev_viewport);
gsk_gl_render_job_set_projection_from_rect (job, &viewport, &prev_projection);
gsk_gl_render_job_set_modelview (job, NULL);
prev_alpha = gsk_gl_render_job_set_alpha (job, 1.0f);
gsk_gl_render_job_push_clip (job, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
prev_fbo = gsk_gl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (job->command_queue, 0, &viewport);
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
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,
(guint16[]) { FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO });
gsk_gl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id);
gsk_gl_render_job_draw_offscreen (job, &viewport, &offscreen);
gsk_gl_render_job_end_draw (job);
gsk_gl_render_job_pop_clip (job);
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
gsk_gl_render_job_set_projection (job, &prev_projection);
gsk_gl_render_job_set_alpha (job, prev_alpha);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
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,
texture_id);
gsk_gl_render_job_draw_offscreen_rect (job, bounds);
gsk_gl_render_job_end_draw (job);
}
else
slice:
{
float scale_x = bounds->size.width / texture->width;
float scale_y = bounds->size.height / texture->height;
float min_x = bounds->origin.x;
float min_y = bounds->origin.y;
float max_x = min_x + bounds->size.width;
float max_y = min_y + bounds->size.height;
float scale_x = (max_x - min_x) / texture->width;
float scale_y = (max_y - min_y) / texture->height;
GskGLTextureSlice *slices = NULL;
guint n_slices = 0;
GdkGLContext *context = gsk_gl_driver_get_context (job->driver);
guint rows, cols;
gsk_gl_driver_slice_texture (job->driver, texture, filter == GSK_SCALING_FILTER_TRILINEAR, 0, 0, &slices, &n_slices);
/* Slice enough that neither the original texture nor the scaled texture
* exceed the texture size limit
*/
cols = (int)(MAX (bounds->size.width, texture->width) / (max_texture_size / 4)) + 1;
rows = (int)(MAX (bounds->size.height, texture->height) / (max_texture_size / 4)) + 1;
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_gl_driver_slice_texture (job->driver, texture, GL_NEAREST, GL_NEAREST, cols, rows, &slices, &n_slices);
for (guint i = 0; i < n_slices; i++)
g_assert (slices != NULL);
g_assert (n_slices > 0);
for (guint i = 0; i < n_slices; i ++)
{
const GskGLTextureSlice *slice = &slices[i];
graphene_rect_t slice_bounds;
float x1, x2, y1, y2;
GdkTexture *sub_texture;
GskRenderNode *sub_node;
slice_bounds.origin.x = bounds->origin.x - clip_rect.origin.x + slice->rect.x * scale_x;
slice_bounds.origin.y = bounds->origin.y - clip_rect.origin.y + slice->rect.y * scale_y;
slice_bounds.size.width = slice->rect.width * scale_x;
slice_bounds.size.height = slice->rect.height * scale_y;
x1 = min_x + (scale_x * slice->rect.x);
x2 = x1 + (slice->rect.width * scale_x);
y1 = min_y + (scale_y * slice->rect.y);
y2 = y1 + (slice->rect.height * scale_y);
if (!graphene_rect_intersection (&slice_bounds, &viewport, NULL))
continue;
sub_texture = gdk_gl_texture_new (context, slice->texture_id, slice->rect.width, slice->rect.height, NULL, NULL);
if (i > 0)
gsk_gl_render_job_split_draw (job);
sub_node = gsk_texture_scale_node_new (sub_texture, &GRAPHENE_RECT_INIT (x1, y1, x2 - x1, y2 - y1), scaling_filter);
gsk_gl_program_set_uniform_texture_with_filter (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
slice->texture_id,
min_filter,
mag_filter);
gsk_gl_render_job_draw_coords (job,
slice_bounds.origin.x,
slice_bounds.origin.y,
slice_bounds.origin.x + slice_bounds.size.width,
slice_bounds.origin.y + slice_bounds.size.height,
0, 0, 1, 1,
(guint16[]){ FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO } );
gsk_gl_render_job_visit_node (job, sub_node);
gsk_render_node_unref (sub_node);
g_object_unref (sub_texture);
}
gsk_gl_render_job_end_draw (job);
}
gsk_gl_render_job_pop_clip (job);
gsk_gl_render_job_pop_modelview (job);
gsk_gl_render_job_set_viewport (job, &prev_viewport, NULL);
gsk_gl_render_job_set_projection (job, &prev_projection);
gsk_gl_render_job_set_alpha (job, prev_alpha);
gsk_gl_command_queue_bind_framebuffer (job->command_queue, prev_fbo);
texture_id = gsk_gl_driver_release_render_target (job->driver, render_target, FALSE);
gsk_gl_driver_cache_texture (job->driver, &key, texture_id);
render_texture:
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,
texture_id);
gsk_gl_render_job_draw_coords (job,
job->offset_x + clip_rect.origin.x,
job->offset_y + clip_rect.origin.y,
job->offset_x + clip_rect.origin.x + clip_rect.size.width,
job->offset_y + clip_rect.origin.y + clip_rect.size.height,
0, clip_rect.size.width / ceilf (clip_rect.size.width),
clip_rect.size.height / ceilf (clip_rect.size.height), 0,
(guint16[]){ FP16_ZERO, FP16_ZERO, FP16_ZERO, FP16_ZERO } );
gsk_gl_render_job_end_draw (job);
}
static inline void
@@ -4047,6 +3998,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
{
GskTextureKey key;
guint cached_id;
int filter;
g_assert (job != NULL);
g_assert (node != NULL);
@@ -4067,15 +4019,19 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
offscreen->force_offscreen == FALSE)
{
GdkTexture *texture = gsk_texture_node_get_texture (node);
gsk_gl_render_job_upload_texture (job, texture, FALSE, offscreen);
gsk_gl_render_job_upload_texture (job, texture, GL_LINEAR, GL_LINEAR, offscreen);
g_assert (offscreen->was_offscreen == FALSE);
return TRUE;
}
filter = offscreen->linear_filter ? GL_LINEAR : GL_NEAREST;
key.pointer = node;
key.pointer_is_child = TRUE; /* Don't conflict with the child using the cache too */
key.parent_rect = *offscreen->bounds;
key.scale_x = job->scale_x;
key.scale_y = job->scale_y;
key.filter = filter;
float offset_x = job->offset_x;
float offset_y = job->offset_y;
@@ -4183,6 +4139,7 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
if (!gsk_gl_driver_create_render_target (job->driver,
texture_width, texture_height,
get_target_format (job, node),
filter, filter,
&render_target))
g_assert_not_reached ();
@@ -4270,6 +4227,7 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
MAX (1, job->viewport.size.width),
MAX (1, job->viewport.size.height),
job->target_format,
GL_NEAREST, GL_NEAREST,
&framebuffer_id, &texture_id))
return;
@@ -4412,7 +4370,7 @@ gsk_gl_render_job_new (GskGLDriver *driver,
if (framebuffer == 0 && default_framebuffer != 0)
framebuffer = default_framebuffer;
job = g_new0 (GskGLRenderJob, 1);
job = g_slice_new0 (GskGLRenderJob);
job->driver = g_object_ref (driver);
job->command_queue = job->driver->command_queue;
job->clip = g_array_sized_new (FALSE, FALSE, sizeof (GskGLRenderClip), 16);
@@ -4477,5 +4435,5 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
g_clear_pointer (&job->region, cairo_region_destroy);
g_clear_pointer (&job->modelview, g_array_unref);
g_clear_pointer (&job->clip, g_array_unref);
g_free (job);
g_slice_free (GskGLRenderJob, job);
}
+8 -2
View File
@@ -51,7 +51,7 @@ gsk_gl_texture_free (GskGLTexture *texture)
g_clear_pointer (&texture->slices, g_free);
g_clear_pointer (&texture->nine_slice, g_free);
g_free (texture);
g_slice_free (GskGLTexture, texture);
}
}
@@ -59,13 +59,19 @@ GskGLTexture *
gsk_gl_texture_new (guint texture_id,
int width,
int height,
int format,
int min_filter,
int mag_filter,
gint64 frame_id)
{
GskGLTexture *texture;
texture = g_new0 (GskGLTexture, 1);
texture = g_slice_new0 (GskGLTexture);
texture->texture_id = texture_id;
texture->link.data = texture;
texture->min_filter = min_filter;
texture->mag_filter = mag_filter;
texture->format = format;
texture->width = width;
texture->height = height;
texture->last_used_in_frame = frame_id;
+7 -5
View File
@@ -52,7 +52,7 @@ gsk_gl_texture_atlas_free (GskGLTextureAtlas *atlas)
}
g_clear_pointer (&atlas->nodes, g_free);
g_free (atlas);
g_slice_free (GskGLTextureAtlas, atlas);
}
static gboolean
@@ -320,7 +320,7 @@ gsk_gl_texture_library_pack_one (GskGLTextureLibrary *self,
height = MIN (height, self->driver->command_queue->max_texture_size);
}
texture = gsk_gl_driver_create_texture (self->driver, width, height, GL_RGBA8);
texture = gsk_gl_driver_create_texture (self->driver, width, height, GL_RGBA8, GL_LINEAR, GL_LINEAR);
texture->permanent = TRUE;
return texture;
@@ -388,7 +388,7 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
g_assert (out_packed_x != NULL);
g_assert (out_packed_y != NULL);
entry = g_malloc0 (valuelen);
entry = g_slice_alloc0 (valuelen);
entry->n_pixels = width * height;
entry->accessed = TRUE;
entry->used = TRUE;
@@ -542,7 +542,7 @@ gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self)
g_return_val_if_fail (self->atlas_width > 0, NULL);
g_return_val_if_fail (self->atlas_height > 0, NULL);
atlas = g_new0 (GskGLTextureAtlas, 1);
atlas = g_slice_new0 (GskGLTextureAtlas);
atlas->width = self->atlas_width;
atlas->height = self->atlas_height;
/* TODO: We might want to change the strategy about the amount of
@@ -552,7 +552,9 @@ gsk_gl_texture_library_acquire_atlas (GskGLTextureLibrary *self)
atlas->texture_id = gsk_gl_command_queue_create_texture (self->driver->command_queue,
atlas->width,
atlas->height,
GL_RGBA8);
GL_RGBA8,
GL_LINEAR,
GL_LINEAR);
gdk_gl_context_label_object_printf (gdk_gl_context_get_current (),
GL_TEXTURE, atlas->texture_id,
+6 -2
View File
@@ -65,16 +65,20 @@ struct _GskGLTexture
int width;
int height;
int min_filter;
int mag_filter;
int format;
/* Set when used by an atlas so we don't drop the texture */
guint permanent : 1;
/* we called glGenerateMipmap() for this texture */
guint has_mipmap : 1;
};
GskGLTexture * gsk_gl_texture_new (guint texture_id,
int width,
int height,
int format,
int min_filter,
int mag_filter,
gint64 frame_id);
const GskGLTextureNineSlice * gsk_gl_texture_get_nine_slice (GskGLTexture *texture,
const GskRoundedRect *outline,
+2 -2
View File
@@ -53,7 +53,7 @@ gsk_diff_settings_new (GCompareDataFunc compare_func,
{
GskDiffSettings *settings;
settings = g_new0 (GskDiffSettings, 1);
settings = g_slice_new0 (GskDiffSettings);
settings->compare_func = compare_func;
settings->keep_func = keep_func;
@@ -73,7 +73,7 @@ gsk_diff_settings_set_allow_abort (GskDiffSettings *settings,
void
gsk_diff_settings_free (GskDiffSettings *settings)
{
g_free (settings);
g_slice_free (GskDiffSettings, settings);
}
/*
+6 -4
View File
@@ -53,7 +53,8 @@ named_counter_free (gpointer data)
return;
g_free (counter->description);
g_free (counter);
g_slice_free (NamedCounter, counter);
}
static void
@@ -65,7 +66,8 @@ named_timer_free (gpointer data)
return;
g_free (timer->description);
g_free (timer);
g_slice_free (NamedTimer, timer);
}
static void
@@ -107,7 +109,7 @@ named_counter_new (GQuark id,
const char *description,
gboolean can_reset)
{
NamedCounter *res = g_new0 (NamedCounter, 1);
NamedCounter *res = g_slice_new0 (NamedCounter);
res->id = id;
res->description = g_strdup (description);
@@ -154,7 +156,7 @@ named_timer_new (GQuark id,
gboolean invert,
gboolean can_reset)
{
NamedTimer *res = g_new0 (NamedTimer, 1);
NamedTimer *res = g_slice_new0 (NamedTimer);
res->id = id;
res->description = g_strdup (description);
+28 -160
View File
@@ -21,10 +21,8 @@
#include "gskrendernodeprivate.h"
#include "gskcairoblurprivate.h"
#include "gskcairorenderer.h"
#include "gskdebugprivate.h"
#include "gskdiffprivate.h"
#include "gl/gskglrenderer.h"
#include "gskrendererprivate.h"
#include "gskroundedrectprivate.h"
#include "gsktransformprivate.h"
@@ -33,10 +31,6 @@
#include "gdk/gdkmemoryformatprivate.h"
#include "gdk/gdkprivate.h"
#include <cairo.h>
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
#endif
#include <hb-ot.h>
/* maximal number of rectangles we keep in a diff region before we throw
@@ -64,16 +58,6 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
cairo->height = ceilf (graphene->origin.y + graphene->size.height) - cairo->y;
}
static void
_graphene_rect_init_from_clip_extents (graphene_rect_t *rect,
cairo_t *cr)
{
double x1c, y1c, x2c, y2c;
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
graphene_rect_init (rect, x1c, y1c, x2c - x1c, y2c - y1c);
}
/* {{{ GSK_COLOR_NODE */
/**
@@ -1573,10 +1557,6 @@ gsk_texture_node_get_texture (const GskRenderNode *node)
* Creates a `GskRenderNode` that will render the given
* @texture into the area given by @bounds.
*
* Note that GSK applies linear filtering when textures are
* scaled and transformed. See [class@Gsk.TextureScaleNode]
* for a way to influence filtering.
*
* Returns: (transfer full) (type GskTextureNode): A new `GskRenderNode`
*/
GskRenderNode *
@@ -1645,21 +1625,15 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
};
cairo_t *cr2;
cairo_surface_t *surface2;
graphene_rect_t clip_rect;
/* Make sure we draw the minimum region by using the clip */
gsk_cairo_rectangle (cr, &node->bounds);
cairo_clip (cr);
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
if (clip_rect.size.width <= 0 || clip_rect.size.height <= 0)
return;
surface2 = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
(int) ceilf (clip_rect.size.width),
(int) ceilf (clip_rect.size.height));
cairo_surface_set_device_offset (surface2, -clip_rect.origin.x, -clip_rect.origin.y);
(int) ceilf (node->bounds.size.width),
(int) ceilf (node->bounds.size.height));
cr2 = cairo_create (surface2);
cairo_set_source_rgba (cr2, 0, 0, 0, 0);
cairo_paint (cr2);
surface = gdk_texture_download_surface (self->texture);
pattern = cairo_pattern_create_for_surface (surface);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
@@ -1758,11 +1732,7 @@ gsk_texture_scale_node_get_filter (const GskRenderNode *node)
* @filter: how to scale the texture
*
* Creates a node that scales the texture to the size given by the
* bounds using the filter and then places it at the bounds' position.
*
* Note that further scaling and other transformations which are
* applied to the node will apply linear filtering to the resulting
* texture, as usual.
* bounds and the filter and then places it at the bounds' position.
*
* This node is intended for tight control over scaling applied
* to a texture, such as in image editors and requires the
@@ -2102,15 +2072,15 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
GskInsetShadowNode *self = (GskInsetShadowNode *) node;
GskRoundedRect box, clip_box;
int clip_radius;
graphene_rect_t clip_rect;
double x1c, y1c, x2c, y2c;
double blur_radius;
/* We don't need to draw invisible shadows */
if (gdk_rgba_is_clear (&self->color))
return;
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
if (!gsk_rounded_rect_intersects_rect (&self->outline, &clip_rect))
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
if (!gsk_rounded_rect_intersects_rect (&self->outline, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))
return;
blur_radius = self->blur_radius / 2;
@@ -2398,7 +2368,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
GskOutsetShadowNode *self = (GskOutsetShadowNode *) node;
GskRoundedRect box, clip_box;
int clip_radius;
graphene_rect_t clip_rect;
double x1c, y1c, x2c, y2c;
float top, right, bottom, left;
double blur_radius;
@@ -2406,8 +2376,8 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
if (gdk_rgba_is_clear (&self->color))
return;
_graphene_rect_init_from_clip_extents (&clip_rect, cr);
if (!gsk_rounded_rect_intersects_rect (&self->outline, &clip_rect))
cairo_clip_extents (cr, &x1c, &y1c, &x2c, &y2c);
if (gsk_rounded_rect_contains_rect (&self->outline, &GRAPHENE_RECT_INIT (x1c, y1c, x2c - x1c, y2c - y1c)))
return;
blur_radius = self->blur_radius / 2;
@@ -6241,9 +6211,9 @@ gsk_render_node_init_types_once (void)
}
static void
gsk_render_node_serialize_bytes_finish (GObject *source,
GAsyncResult *result,
gpointer serializer)
gsk_render_node_content_serializer_finish (GObject *source,
GAsyncResult *result,
gpointer serializer)
{
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
@@ -6254,109 +6224,10 @@ gsk_render_node_serialize_bytes_finish (GObject *source,
gdk_content_serializer_return_success (serializer);
}
static void
gsk_render_node_serialize_bytes (GdkContentSerializer *serializer,
GBytes *bytes)
{
GInputStream *input;
input = g_memory_input_stream_new_from_bytes (bytes);
g_output_stream_splice_async (gdk_content_serializer_get_output_stream (serializer),
input,
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
gdk_content_serializer_get_priority (serializer),
gdk_content_serializer_get_cancellable (serializer),
gsk_render_node_serialize_bytes_finish,
serializer);
g_object_unref (input);
g_bytes_unref (bytes);
}
#ifdef CAIRO_HAS_SVG_SURFACE
static cairo_status_t
gsk_render_node_cairo_serializer_write (gpointer user_data,
const unsigned char *data,
unsigned int length)
{
g_byte_array_append (user_data, data, length);
return CAIRO_STATUS_SUCCESS;
}
static void
gsk_render_node_svg_serializer (GdkContentSerializer *serializer)
{
GskRenderNode *node;
cairo_surface_t *surface;
cairo_t *cr;
graphene_rect_t bounds;
GByteArray *array;
node = gsk_value_get_render_node (gdk_content_serializer_get_value (serializer));
gsk_render_node_get_bounds (node, &bounds);
array = g_byte_array_new ();
surface = cairo_svg_surface_create_for_stream (gsk_render_node_cairo_serializer_write,
array,
bounds.size.width,
bounds.size.height);
cairo_svg_surface_set_document_unit (surface, CAIRO_SVG_UNIT_PX);
cairo_surface_set_device_offset (surface, -bounds.origin.x, -bounds.origin.y);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_finish (surface);
if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS)
{
gsk_render_node_serialize_bytes (serializer, g_byte_array_free_to_bytes (array));
}
else
{
GError *error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED,
cairo_status_to_string (cairo_surface_status (surface)));
gdk_content_serializer_return_error (serializer, error);
g_byte_array_unref (array);
}
cairo_surface_destroy (surface);
}
#endif
static void
gsk_render_node_png_serializer (GdkContentSerializer *serializer)
{
GskRenderNode *node;
GdkTexture *texture;
GskRenderer *renderer;
GBytes *bytes;
node = gsk_value_get_render_node (gdk_content_serializer_get_value (serializer));
renderer = gsk_gl_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
g_object_unref (renderer);
renderer = gsk_cairo_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, NULL))
{
g_assert_not_reached ();
}
}
texture = gsk_renderer_render_texture (renderer, node, NULL);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
bytes = gdk_texture_save_to_png_bytes (texture);
g_object_unref (texture);
gsk_render_node_serialize_bytes (serializer, bytes);
}
static void
gsk_render_node_content_serializer (GdkContentSerializer *serializer)
{
GInputStream *input;
const GValue *value;
GskRenderNode *node;
GBytes *bytes;
@@ -6364,14 +6235,23 @@ gsk_render_node_content_serializer (GdkContentSerializer *serializer)
value = gdk_content_serializer_get_value (serializer);
node = gsk_value_get_render_node (value);
bytes = gsk_render_node_serialize (node);
input = g_memory_input_stream_new_from_bytes (bytes);
gsk_render_node_serialize_bytes (serializer, bytes);
g_output_stream_splice_async (gdk_content_serializer_get_output_stream (serializer),
input,
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
gdk_content_serializer_get_priority (serializer),
gdk_content_serializer_get_cancellable (serializer),
gsk_render_node_content_serializer_finish,
serializer);
g_object_unref (input);
g_bytes_unref (bytes);
}
static void
gsk_render_node_content_deserializer_finish (GObject *source,
GAsyncResult *result,
gpointer deserializer)
GAsyncResult *result,
gpointer deserializer)
{
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
@@ -6435,18 +6315,6 @@ gsk_render_node_init_content_serializers (void)
gsk_render_node_content_serializer,
NULL,
NULL);
#ifdef CAIRO_HAS_SVG_SURFACE
gdk_content_register_serializer (GSK_TYPE_RENDER_NODE,
"image/svg+xml",
gsk_render_node_svg_serializer,
NULL,
NULL);
#endif
gdk_content_register_serializer (GSK_TYPE_RENDER_NODE,
"image/png",
gsk_render_node_png_serializer,
NULL,
NULL);
gdk_content_register_deserializer ("application/x-gtk-render-node",
GSK_TYPE_RENDER_NODE,
+1 -1
View File
@@ -164,7 +164,7 @@ gskenum_h = gsk_enums[1]
gskresources = gnome.compile_resources('gskresources',
gsk_resources_xml,
dependencies: gsk_private_vulkan_compiled_shaders_deps,
source_dir: meson.current_source_dir(),
source_dir: '.',
c_name: '_gsk',
extra_args: [ '--manual-register', ],
)
+2 -2
View File
@@ -23,7 +23,7 @@ gsk_vulkan_buffer_new_internal (GdkVulkanContext *context,
VkMemoryRequirements requirements;
GskVulkanBuffer *self;
self = g_new0 (GskVulkanBuffer, 1);
self = g_slice_new0 (GskVulkanBuffer);
self->vulkan = g_object_ref (context);
self->size = size;
@@ -88,7 +88,7 @@ gsk_vulkan_buffer_free (GskVulkanBuffer *self)
g_object_unref (self->vulkan);
g_free (self);
g_slice_free (GskVulkanBuffer, self);
}
VkBuffer
+2 -2
View File
@@ -16,7 +16,7 @@ gsk_vulkan_command_pool_new (GdkVulkanContext *context)
{
GskVulkanCommandPool *self;
self = g_new0 (GskVulkanCommandPool, 1);
self = g_slice_new0 (GskVulkanCommandPool);
self->vulkan = g_object_ref (context);
@@ -56,7 +56,7 @@ gsk_vulkan_command_pool_free (GskVulkanCommandPool *self)
self->vk_command_pool,
NULL);
g_free (self);
g_slice_free (GskVulkanCommandPool, self);
}
void
+2 -2
View File
@@ -49,7 +49,7 @@ gsk_vulkan_uploader_new (GdkVulkanContext *context,
{
GskVulkanUploader *self;
self = g_new0 (GskVulkanUploader, 1);
self = g_slice_new0 (GskVulkanUploader);
self->vulkan = g_object_ref (context);
self->command_pool = command_pool;
@@ -75,7 +75,7 @@ gsk_vulkan_uploader_free (GskVulkanUploader *self)
g_object_unref (self->vulkan);
g_free (self);
g_slice_free (GskVulkanUploader, self);
}
static void
+2 -2
View File
@@ -22,7 +22,7 @@ gsk_vulkan_memory_new (GdkVulkanContext *context,
GskVulkanMemory *self;
uint32_t i;
self = g_new0 (GskVulkanMemory, 1);
self = g_slice_new0 (GskVulkanMemory);
self->vulkan = g_object_ref (context);
self->size = size;
@@ -62,7 +62,7 @@ gsk_vulkan_memory_free (GskVulkanMemory *self)
g_object_unref (self->vulkan);
g_free (self);
g_slice_free (GskVulkanMemory, self);
}
VkDeviceMemory
+5 -5
View File
@@ -113,7 +113,7 @@ gsk_vulkan_render_new (GskRenderer *renderer,
GskVulkanRender *self;
VkDevice device;
self = g_new0 (GskVulkanRender, 1);
self = g_slice_new0 (GskVulkanRender);
self->vulkan = context;
self->renderer = renderer;
@@ -281,7 +281,7 @@ gsk_vulkan_render_remove_framebuffer_from_image (gpointer data,
fb->framebuffer,
NULL);
g_free (fb);
g_slice_free (HashFramebufferEntry, fb);
}
VkFramebuffer
@@ -294,7 +294,7 @@ gsk_vulkan_render_get_framebuffer (GskVulkanRender *self,
if (fb)
return fb->framebuffer;
fb = g_new0 (HashFramebufferEntry, 1);
fb = g_slice_new0 (HashFramebufferEntry);
GSK_VK_CHECK (vkCreateFramebuffer, gdk_vulkan_context_get_device (self->vulkan),
&(VkFramebufferCreateInfo) {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
@@ -705,7 +705,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
vkDestroyFramebuffer (gdk_vulkan_context_get_device (self->vulkan),
fb->framebuffer,
NULL);
g_free (fb);
g_slice_free (HashFramebufferEntry, fb);
g_object_weak_unref (G_OBJECT (key), gsk_vulkan_render_remove_framebuffer_from_image, self);
g_hash_table_iter_remove (&iter);
}
@@ -749,7 +749,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
gsk_vulkan_command_pool_free (self->command_pool);
g_free (self);
g_slice_free (GskVulkanRender, self);
}
gboolean
+3 -3
View File
@@ -326,7 +326,7 @@ gsk_vulkan_renderer_clear_texture (gpointer p)
g_object_unref (data->image);
g_free (data);
g_slice_free (GskVulkanTextureData, data);
}
GskVulkanImage *
@@ -350,7 +350,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
cairo_image_surface_get_stride (surface));
cairo_surface_destroy (surface);
data = g_new0 (GskVulkanTextureData, 1);
data = g_slice_new0 (GskVulkanTextureData);
data->image = image;
data->texture = texture;
data->renderer = self;
@@ -362,7 +362,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
}
else
{
g_free (data);
g_slice_free (GskVulkanTextureData, data);
}
return image;
+2 -2
View File
@@ -140,7 +140,7 @@ gsk_vulkan_render_pass_new (GdkVulkanContext *context,
GskVulkanRenderPass *self;
VkImageLayout final_layout;
self = g_new0 (GskVulkanRenderPass, 1);
self = g_slice_new0 (GskVulkanRenderPass);
self->vulkan = g_object_ref (context);
self->render_ops = g_array_new (FALSE, FALSE, sizeof (GskVulkanOp));
@@ -231,7 +231,7 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
g_array_unref (self->wait_semaphores);
g_free (self);
g_slice_free (GskVulkanRenderPass, self);
}
#define FALLBACK(...) G_STMT_START { \
+2 -2
View File
@@ -37,7 +37,7 @@ gsk_vulkan_shader_new_from_bytes (GdkVulkanContext *context,
return NULL;
}
self = g_new0 (GskVulkanShader, 1);
self = g_slice_new0 (GskVulkanShader);
self->vulkan = g_object_ref (context);
self->type = type;
@@ -85,7 +85,7 @@ gsk_vulkan_shader_free (GskVulkanShader *self)
g_object_unref (self->vulkan);
g_free (self);
g_slice_free (GskVulkanShader, self);
}
GskVulkanShaderType
+1 -4
View File
@@ -158,12 +158,9 @@ component_handle_method (GDBusConnection *connection,
}
else
{
GtkATContext *context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (child));
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (context);
GtkAtSpiContext *ctx = GTK_AT_SPI_CONTEXT (gtk_accessible_get_at_context (GTK_ACCESSIBLE (child)));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", gtk_at_spi_context_to_ref (ctx)));
g_object_unref (context);
}
}
else if (g_strcmp0 (method_name, "GetExtents") == 0)
+33 -131
View File
@@ -203,7 +203,6 @@ collect_states (GtkAtSpiContext *self,
if (gtk_at_context_has_accessible_state (ctx, GTK_ACCESSIBLE_STATE_CHECKED))
{
set_atspi_state (&states, ATSPI_STATE_CHECKABLE);
value = gtk_at_context_get_accessible_state (ctx, GTK_ACCESSIBLE_STATE_CHECKED);
switch (gtk_tristate_accessible_value_get (value))
{
@@ -247,7 +246,7 @@ collect_states (GtkAtSpiContext *self,
case GTK_ACCESSIBLE_INVALID_TRUE:
case GTK_ACCESSIBLE_INVALID_GRAMMAR:
case GTK_ACCESSIBLE_INVALID_SPELLING:
set_atspi_state (&states, ATSPI_STATE_INVALID_ENTRY);
set_atspi_state (&states, ATSPI_STATE_INVALID);
break;
case GTK_ACCESSIBLE_INVALID_FALSE:
default:
@@ -283,44 +282,6 @@ collect_states (GtkAtSpiContext *self,
}
}
if (gtk_at_context_has_accessible_state (ctx, GTK_ACCESSIBLE_STATE_VISITED))
{
value = gtk_at_context_get_accessible_state (ctx, GTK_ACCESSIBLE_STATE_VISITED);
if (value->value_class->type == GTK_ACCESSIBLE_VALUE_TYPE_BOOLEAN)
{
if (gtk_boolean_accessible_value_get (value))
set_atspi_state (&states, ATSPI_STATE_VISITED);
}
}
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED))
{
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_REQUIRED);
if (gtk_boolean_accessible_value_get (value))
set_atspi_state (&states, ATSPI_STATE_REQUIRED);
}
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE))
{
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_MULTI_SELECTABLE);
if (gtk_boolean_accessible_value_get (value))
set_atspi_state (&states, ATSPI_STATE_MULTISELECTABLE);
}
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_HAS_POPUP))
{
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_HAS_POPUP);
if (gtk_boolean_accessible_value_get (value))
set_atspi_state (&states, ATSPI_STATE_HAS_POPUP);
}
if (gtk_at_context_has_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE))
{
value = gtk_at_context_get_accessible_property (ctx, GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE);
if (gtk_autocomplete_accessible_value_get (value) != GTK_ACCESSIBLE_AUTOCOMPLETE_NONE)
set_atspi_state (&states, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION);
}
g_variant_builder_add (builder, "u", (guint32) (states & 0xffffffff));
g_variant_builder_add (builder, "u", (guint32) (states >> 32));
}
@@ -338,12 +299,11 @@ collect_relations (GtkAtSpiContext *self,
{ GTK_ACCESSIBLE_RELATION_LABELLED_BY, ATSPI_RELATION_LABELLED_BY },
{ GTK_ACCESSIBLE_RELATION_CONTROLS, ATSPI_RELATION_CONTROLLER_FOR },
{ GTK_ACCESSIBLE_RELATION_DESCRIBED_BY, ATSPI_RELATION_DESCRIBED_BY },
{ GTK_ACCESSIBLE_RELATION_DETAILS, ATSPI_RELATION_DETAILS },
{ GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, ATSPI_RELATION_ERROR_MESSAGE},
{ GTK_ACCESSIBLE_RELATION_FLOW_TO, ATSPI_RELATION_FLOWS_TO},
};
GtkAccessibleValue *value;
GList *list, *l;
GtkATContext *target_ctx;
int i;
for (i = 0; i < G_N_ELEMENTS (map); i++)
@@ -358,16 +318,13 @@ collect_relations (GtkAtSpiContext *self,
for (l = list; l; l = l->next)
{
GtkATContext *target_ctx =
gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
target_ctx = gtk_accessible_get_at_context (GTK_ACCESSIBLE (l->data));
/* Realize the ATContext of the target, so we can ask for its ref */
gtk_at_context_realize (target_ctx);
g_variant_builder_add (&b, "@(so)",
gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (target_ctx)));
g_object_unref (target_ctx);
}
g_variant_builder_add (builder, "(ua(so))", map[i].s, &b);
@@ -379,17 +336,17 @@ static int
get_index_in (GtkAccessible *parent,
GtkAccessible *child)
{
GtkAccessible *candidate;
guint res;
if (parent == NULL)
return -1;
guint res = 0;
GtkAccessible *candidate;
res = 0;
for (candidate = gtk_accessible_get_first_accessible_child (parent);
candidate != NULL;
candidate = gtk_accessible_get_next_accessible_sibling (candidate))
{
g_object_unref (candidate);
if (candidate == child)
return res;
@@ -408,13 +365,7 @@ get_index_in_parent (GtkAccessible *accessible)
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
if (parent != NULL)
{
int res = get_index_in (parent, accessible);
g_object_unref (parent);
return res;
}
return get_index_in (parent, accessible);
return -1;
}
@@ -450,6 +401,7 @@ static GVariant *
get_parent_context_ref (GtkAccessible *accessible)
{
GVariant *res = NULL;
GtkAccessible *parent = gtk_accessible_get_accessible_parent (accessible);
if (parent == NULL)
@@ -458,19 +410,13 @@ get_parent_context_ref (GtkAccessible *accessible)
GtkAtSpiContext *self = GTK_AT_SPI_CONTEXT (context);
res = gtk_at_spi_root_to_ref (self->root);
g_object_unref (context);
}
else
{
GtkATContext *parent_context = gtk_accessible_get_at_context (parent);
gtk_at_context_realize (parent_context);
res = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (parent_context));
g_object_unref (parent_context);
g_object_unref (parent);
}
if (res == NULL)
@@ -551,32 +497,31 @@ handle_accessible_method (GDBusConnection *connection,
{
GtkATContext *context = NULL;
GtkAccessible *accessible;
GtkAccessible *child = NULL;
int idx, presentable_idx;
g_variant_get (parameters, "(i)", &idx);
accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
presentable_idx = 0;
GtkAccessible *child;
presentable_idx = 0;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
g_object_unref (child);
if (!gtk_accessible_should_present (child))
continue;
continue;
if (presentable_idx == idx)
break;
presentable_idx++;
presentable_idx += 1;
}
if (child != NULL)
context = gtk_accessible_get_at_context (child);
if (child)
{
context = gtk_accessible_get_at_context (child);
}
if (context == NULL)
{
@@ -591,23 +536,20 @@ handle_accessible_method (GDBusConnection *connection,
gtk_at_context_realize (context);
GVariant *ref = gtk_at_spi_context_to_ref (GTK_AT_SPI_CONTEXT (context));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
g_object_unref (context);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@(so))", ref));
}
else if (g_strcmp0 (method_name, "GetChildren") == 0)
{
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a(so)"));
GtkAccessible *accessible = gtk_at_context_get_accessible (GTK_AT_CONTEXT (self));
GtkAccessible *child = NULL;
GtkAccessible *child;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
g_object_unref (child);
{
if (!gtk_accessible_should_present (child))
continue;
@@ -620,8 +562,6 @@ handle_accessible_method (GDBusConnection *connection,
if (ref != NULL)
g_variant_builder_add (&builder, "@(so)", ref);
g_object_unref (context);
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a(so))", &builder));
@@ -801,13 +741,8 @@ emit_property_changed (GtkAtSpiContext *self,
const char *name,
GVariant *value)
{
GVariant *value_owned = g_variant_ref_sink (value);
if (self->connection == NULL)
{
g_variant_unref (value_owned);
return;
}
return;
g_dbus_connection_emit_signal (self->connection,
NULL,
@@ -815,9 +750,8 @@ emit_property_changed (GtkAtSpiContext *self,
"org.a11y.atspi.Event.Object",
"PropertyChange",
g_variant_new ("(siiva{sv})",
name, 0, 0, value_owned, NULL),
name, 0, 0, value, NULL),
NULL);
g_variant_unref (value_owned);
}
static void
@@ -916,6 +850,8 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_HIDDEN)
{
GtkAccessible *parent;
GtkATContext *context;
GtkAccessibleChildChange change;
value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_HIDDEN);
@@ -931,15 +867,10 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
}
else
{
GtkAccessible *parent =
gtk_accessible_get_accessible_parent (accessible);
GtkATContext *context =
gtk_accessible_get_at_context (parent);
parent = gtk_accessible_get_accessible_parent (accessible);
context = gtk_accessible_get_at_context (parent);
gtk_at_context_child_changed (context, change, accessible);
g_object_unref (context);
g_object_unref (parent);
}
}
@@ -1059,15 +990,6 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
emit_state_changed (self, "selectable", FALSE);
}
if (changed_states & GTK_ACCESSIBLE_STATE_CHANGE_VISITED)
{
value = gtk_accessible_attribute_set_get_value (states, GTK_ACCESSIBLE_STATE_VISITED);
if (value->value_class->type == GTK_ACCESSIBLE_VALUE_TYPE_BOOLEAN)
{
emit_state_changed (self, "visited",gtk_boolean_accessible_value_get (value));
}
}
if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_READ_ONLY)
{
gboolean readonly;
@@ -1115,18 +1037,10 @@ gtk_at_spi_context_state_change (GtkATContext *ctx,
}
if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_DESCRIPTION)
{
char *label = gtk_at_context_get_description (GTK_AT_CONTEXT (self));
GVariant *v = g_variant_new_take_string (label);
emit_property_changed (self, "accessible-description", v);
}
if (changed_properties & GTK_ACCESSIBLE_PROPERTY_CHANGE_VALUE_NOW)
{
value = gtk_accessible_attribute_set_get_value (properties, GTK_ACCESSIBLE_PROPERTY_VALUE_NOW);
emit_property_changed (self,
"accessible-value",
g_variant_new_double (gtk_number_accessible_value_get (value)));
char *label = gtk_at_context_get_description (GTK_AT_CONTEXT (self));
GVariant *v = g_variant_new_take_string (label);
emit_property_changed (self, "accessible-description", v);
}
}
@@ -1205,18 +1119,9 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
int idx = 0;
if (parent == NULL)
{
idx = -1;
}
idx = -1;
else if (parent == accessible)
{
idx = get_index_in (accessible, child);
g_object_unref (parent);
}
else
{
g_object_unref (parent);
}
idx = get_index_in (accessible, child);
if (change & GTK_ACCESSIBLE_CHILD_CHANGE_ADDED)
emit_children_changed (self,
@@ -1228,8 +1133,6 @@ gtk_at_spi_context_child_change (GtkATContext *ctx,
GTK_AT_SPI_CONTEXT (child_context),
idx,
GTK_ACCESSIBLE_CHILD_STATE_REMOVED);
g_object_unref (child_context);
}
/* }}} */
/* {{{ D-Bus Registration */
@@ -1798,16 +1701,15 @@ gtk_at_spi_context_get_child_count (GtkAtSpiContext *self)
int n_children = 0;
GtkAccessible *child = NULL;
for (child = gtk_accessible_get_first_accessible_child (accessible);
child != NULL;
child = gtk_accessible_get_next_accessible_sibling (child))
{
g_object_unref (child);
if (!gtk_accessible_should_present (child))
continue;
n_children += 1;
n_children++;
}
return n_children;

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