Compare commits
15 Commits
dmabug-tex
...
wip/baeder
Author | SHA1 | Date | |
---|---|---|---|
|
b800c078ac | ||
|
4997a46277 | ||
|
c28ea4e544 | ||
|
c414fa8a14 | ||
|
46551ca367 | ||
|
bff5324aba | ||
|
deabf2cf37 | ||
|
b185de19b6 | ||
|
b93172f968 | ||
|
0694c2a65e | ||
|
3279901e64 | ||
|
d4616f784d | ||
|
3b78ef4170 | ||
|
0f85831921 | ||
|
bca184ff5c |
156
benchmarks/benchmark.h
Normal file
156
benchmarks/benchmark.h
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
|
||||||
|
#ifndef __GTK_BENCHMARK_H__
|
||||||
|
#define __GTK_BENCHMARK_H__
|
||||||
|
|
||||||
|
#include <valgrind/callgrind.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#define SAMPLE_SIZE 5
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _Benchmark Benchmark;
|
||||||
|
typedef void (*BenchmarkFunc)(Benchmark *b, gsize size, gpointer user_data);
|
||||||
|
|
||||||
|
struct _Benchmark
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
gint64 start_time;
|
||||||
|
gint64 end_time;
|
||||||
|
gsize size;
|
||||||
|
BenchmarkFunc func;
|
||||||
|
guint profile : 1;
|
||||||
|
gpointer data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmark_destroy (Benchmark *b)
|
||||||
|
{
|
||||||
|
g_free (b->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmark_start (Benchmark *b)
|
||||||
|
{
|
||||||
|
b->start_time = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
if (b->profile)
|
||||||
|
CALLGRIND_START_INSTRUMENTATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmark_stop (Benchmark *b)
|
||||||
|
{
|
||||||
|
if (b->profile)
|
||||||
|
CALLGRIND_STOP_INSTRUMENTATION;
|
||||||
|
|
||||||
|
b->end_time = g_get_monotonic_time ();
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GArray *benchmarks;
|
||||||
|
char *profile_benchmark_name;
|
||||||
|
} BenchmarkSuite;
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmark_suite_init (BenchmarkSuite *bs,
|
||||||
|
const char *profile_benchmark_name)
|
||||||
|
{
|
||||||
|
bs->benchmarks = g_array_new (FALSE, TRUE, sizeof (Benchmark));
|
||||||
|
g_array_set_clear_func (bs->benchmarks, (GDestroyNotify)benchmark_destroy);
|
||||||
|
bs->profile_benchmark_name = (char *)profile_benchmark_name; // XXX strdup
|
||||||
|
|
||||||
|
g_assert (SAMPLE_SIZE % 2 == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
benchmark_suite_add (BenchmarkSuite *bs,
|
||||||
|
const char *benchmark_name,
|
||||||
|
gsize size,
|
||||||
|
BenchmarkFunc benchmark_func,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
Benchmark *b;
|
||||||
|
|
||||||
|
g_array_set_size (bs->benchmarks, bs->benchmarks->len + 1);
|
||||||
|
b = &g_array_index (bs->benchmarks, Benchmark, bs->benchmarks->len - 1);
|
||||||
|
|
||||||
|
b->name = (char *)benchmark_name; /* XXX strdup? */
|
||||||
|
b->size = size;
|
||||||
|
b->func = benchmark_func;
|
||||||
|
b->data = user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
benchmark_suite_run (BenchmarkSuite *bs)
|
||||||
|
{
|
||||||
|
const guint n_benchmarks = bs->benchmarks->len;
|
||||||
|
const gboolean profile = bs->profile_benchmark_name != NULL;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
if (profile)
|
||||||
|
{
|
||||||
|
/* For profiling, we only run the selected benchmark. */
|
||||||
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < n_benchmarks; i ++)
|
||||||
|
{
|
||||||
|
Benchmark *b = &g_array_index (bs->benchmarks, Benchmark, i);
|
||||||
|
|
||||||
|
if (strcmp (bs->profile_benchmark_name, b->name) == 0)
|
||||||
|
{
|
||||||
|
b->profile = TRUE;
|
||||||
|
b->func (b, b->size, b->data);
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
g_error ("No benchmark '%s' found", bs->profile_benchmark_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < n_benchmarks; i ++)
|
||||||
|
{
|
||||||
|
gint64 samples[SAMPLE_SIZE];
|
||||||
|
Benchmark *b = &g_array_index (bs->benchmarks, Benchmark, i);
|
||||||
|
int s, x, y;
|
||||||
|
|
||||||
|
for (s = 0; s < SAMPLE_SIZE; s ++)
|
||||||
|
{
|
||||||
|
b->start_time = 0;
|
||||||
|
b->end_time = 0;
|
||||||
|
|
||||||
|
b->func (b, b->size, b->data);
|
||||||
|
|
||||||
|
if (b->start_time == 0)
|
||||||
|
g_error ("Benchmark '%s' did not call benchmark_start()", b->name);
|
||||||
|
|
||||||
|
if (b->end_time == 0)
|
||||||
|
g_error ("Benchmark '%s' did not call benchmark_stop()", b->name);
|
||||||
|
|
||||||
|
samples[s] = b->end_time - b->start_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bubble sort \o/ */
|
||||||
|
for (x = 0; x < SAMPLE_SIZE; x ++)
|
||||||
|
for (y = 0; y < SAMPLE_SIZE; y ++)
|
||||||
|
if (samples[x] < samples[y])
|
||||||
|
{
|
||||||
|
int k = samples[x];
|
||||||
|
samples[x] = samples[y];
|
||||||
|
samples[y] = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Median of SAMPLE_SIZE */
|
||||||
|
printf ("%s (%" G_GSIZE_FORMAT ") | %.2fms\n", b->name, b->size,
|
||||||
|
samples[SAMPLE_SIZE / 2 + 1] / 1000.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
237
benchmarks/containers.c
Normal file
237
benchmarks/containers.c
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "benchmark.h"
|
||||||
|
|
||||||
|
/* Command line options */
|
||||||
|
const char *profile_benchmark_name = NULL;
|
||||||
|
|
||||||
|
static GOptionEntry options[] = {
|
||||||
|
{ "profile", 'p', 0, G_OPTION_ARG_STRING, &profile_benchmark_name, "Benchmark name to profile using callgrind", NULL },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GType type;
|
||||||
|
} ContainerData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PROFILING:
|
||||||
|
*
|
||||||
|
* valgrind --tool=callgrind --instr-atstart=no benchmarks/name --profile="benchmark name"
|
||||||
|
*
|
||||||
|
* ENJOY.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
container_create_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ContainerData *data = user_data;
|
||||||
|
guint i;
|
||||||
|
GtkWidget **widgets = g_malloc (sizeof (GtkWidget*) * size);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
widgets[i] = g_object_new (data->type, NULL);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
container_destroy_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ContainerData *data = user_data;
|
||||||
|
guint i;
|
||||||
|
GtkWidget **widgets = g_malloc (sizeof (GtkWidget*) * size);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
widgets[i] = g_object_new (data->type, NULL);
|
||||||
|
g_object_ref_sink (widgets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
g_object_unref (widgets[i]);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
container_add_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ContainerData *data = user_data;
|
||||||
|
guint i;
|
||||||
|
GtkWidget *container;
|
||||||
|
GtkWidget **buttons = g_malloc (sizeof (GtkWidget*) * size);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
buttons[i] = gtk_button_new ();
|
||||||
|
|
||||||
|
container = g_object_new (data->type, NULL);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gtk_container_add ((GtkContainer *)container, buttons[i]);
|
||||||
|
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
container_remove_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ContainerData *data = user_data;
|
||||||
|
guint i;
|
||||||
|
GtkWidget *container;
|
||||||
|
GtkWidget **buttons = g_malloc (sizeof (GtkWidget*) * size);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
buttons[i] = gtk_button_new ();
|
||||||
|
/* We add an extra ref here so the later remove() does NOT dispose the buttons. */
|
||||||
|
g_object_ref_sink (buttons[i]);
|
||||||
|
g_object_ref (buttons[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
container = g_object_new (data->type, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gtk_container_add ((GtkContainer *)container, buttons[i]);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gtk_container_remove ((GtkContainer *)container, buttons[i]);
|
||||||
|
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
container_measure_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ContainerData *data = user_data;
|
||||||
|
guint i;
|
||||||
|
GtkWidget *container;
|
||||||
|
GtkWidget **buttons = g_malloc (sizeof (GtkWidget*) * size);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
buttons[i] = gtk_button_new ();
|
||||||
|
|
||||||
|
container = g_object_new (data->type, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gtk_container_add ((GtkContainer *)container, buttons[i]);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
|
||||||
|
gtk_widget_measure (container, GTK_ORIENTATION_HORIZONTAL, -1,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
container_allocate_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ContainerData *data = user_data;
|
||||||
|
guint i;
|
||||||
|
GtkWidget *container;
|
||||||
|
GtkWidget **buttons = g_malloc (sizeof (GtkWidget*) * size);
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
buttons[i] = gtk_button_new ();
|
||||||
|
|
||||||
|
container = g_object_new (data->type, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gtk_container_add ((GtkContainer *)container, buttons[i]);
|
||||||
|
|
||||||
|
|
||||||
|
gtk_widget_measure (container, GTK_ORIENTATION_HORIZONTAL, -1,
|
||||||
|
&width, NULL, NULL, NULL);
|
||||||
|
gtk_widget_measure (container, GTK_ORIENTATION_VERTICAL, width,
|
||||||
|
&height, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
gtk_widget_size_allocate (container,
|
||||||
|
&(GtkAllocation){0, 0, width, height},
|
||||||
|
-1);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
BenchmarkSuite suite;
|
||||||
|
GOptionContext *option_context;
|
||||||
|
GError *error = NULL;
|
||||||
|
const GType types[] = {
|
||||||
|
GTK_TYPE_BOX,
|
||||||
|
GTK_TYPE_GRID,
|
||||||
|
GTK_TYPE_STACK,
|
||||||
|
/* GTK_TYPE_NOTEBOOK, XXX too slow! :( */
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
int N = 10000;
|
||||||
|
|
||||||
|
option_context = g_option_context_new ("");
|
||||||
|
g_option_context_add_main_entries (option_context, options, NULL);
|
||||||
|
if (!g_option_context_parse (option_context, &argc, &argv, &error))
|
||||||
|
{
|
||||||
|
g_printerr ("Option parsing failed: %s\n", error->message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_suite_init (&suite, profile_benchmark_name);
|
||||||
|
gtk_init ();
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (types); i ++)
|
||||||
|
{
|
||||||
|
ContainerData *data = g_malloc (sizeof (ContainerData));
|
||||||
|
data->type = types[i];
|
||||||
|
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s create", g_type_name (types[i])),
|
||||||
|
N, container_create_benchmark, data);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s destroy", g_type_name (types[i])),
|
||||||
|
N, container_destroy_benchmark, data);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s add", g_type_name (types[i])),
|
||||||
|
N, container_add_benchmark, data);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s remove", g_type_name (types[i])),
|
||||||
|
N, container_remove_benchmark, data);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s measure", g_type_name (types[i])),
|
||||||
|
N, container_measure_benchmark, data);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s allocate", g_type_name (types[i])),
|
||||||
|
N, container_allocate_benchmark, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return benchmark_suite_run (&suite);
|
||||||
|
}
|
77
benchmarks/css.c
Normal file
77
benchmarks/css.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "benchmark.h"
|
||||||
|
|
||||||
|
/* Command line options */
|
||||||
|
const char *profile_benchmark_name = NULL;
|
||||||
|
static GOptionEntry options[] = {
|
||||||
|
{ "profile", 'p', 0, G_OPTION_ARG_STRING, &profile_benchmark_name, "Benchmark name to profile using callgrind", NULL },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
css_compute_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget **widgets = g_malloc (sizeof (GtkWidget *) * size);
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *scroller;
|
||||||
|
GtkWidget *window;
|
||||||
|
GdkFrameClock *frame_clock;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
widgets[i] = gtk_label_new ("foo");
|
||||||
|
/*widgets[i] = gtk_button_new ();*/
|
||||||
|
gtk_container_add (GTK_CONTAINER (box), widgets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
scroller = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (scroller), box);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), scroller);
|
||||||
|
|
||||||
|
gtk_widget_realize (window);
|
||||||
|
frame_clock = gtk_widget_get_frame_clock (window);
|
||||||
|
g_assert (frame_clock != NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (window);
|
||||||
|
g_signal_connect (frame_clock, "layout", G_CALLBACK (gtk_main_quit), NULL);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
gtk_main ();
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
gtk_widget_hide (window);
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
|
g_free (widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
BenchmarkSuite suite;
|
||||||
|
GOptionContext *option_context;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
option_context = g_option_context_new ("");
|
||||||
|
g_option_context_add_main_entries (option_context, options, NULL);
|
||||||
|
if (!g_option_context_parse (option_context, &argc, &argv, &error))
|
||||||
|
{
|
||||||
|
g_printerr ("Option parsing failed: %s\n", error->message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_suite_init (&suite, profile_benchmark_name);
|
||||||
|
gtk_init ();
|
||||||
|
|
||||||
|
benchmark_suite_add (&suite, "css compute", 10000, css_compute_benchmark, NULL);
|
||||||
|
|
||||||
|
return benchmark_suite_run (&suite);
|
||||||
|
}
|
21
benchmarks/meson.build
Normal file
21
benchmarks/meson.build
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
# benchmark name, optional extra sources
|
||||||
|
gtk_benchmarks = [
|
||||||
|
['containers'],
|
||||||
|
['css'],
|
||||||
|
['widget'],
|
||||||
|
['renderers'],
|
||||||
|
]
|
||||||
|
|
||||||
|
foreach b : gtk_benchmarks
|
||||||
|
b_name = b.get(0)
|
||||||
|
b_sources = ['@0@.c'.format(b_name), b.get(1, [])]
|
||||||
|
b_exec = executable (
|
||||||
|
b_name,
|
||||||
|
b_sources,
|
||||||
|
include_directories: [confinc, gdkinc],
|
||||||
|
dependencies: [libgtk_dep, libm]
|
||||||
|
)
|
||||||
|
benchmark(b_name, b_exec)
|
||||||
|
|
||||||
|
endforeach
|
275
benchmarks/renderers.c
Normal file
275
benchmarks/renderers.c
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "benchmark.h"
|
||||||
|
|
||||||
|
/* Command line options */
|
||||||
|
const char *profile_benchmark_name = NULL;
|
||||||
|
static GOptionEntry options[] = {
|
||||||
|
{ "profile", 'p', 0, G_OPTION_ARG_STRING, &profile_benchmark_name, "Benchmark name to profile using callgrind", NULL },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
borders_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GskRenderer *renderer = user_data;
|
||||||
|
GskRenderNode *root_node;
|
||||||
|
GskRenderNode **child_nodes;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
child_nodes = g_malloc (sizeof (GskRenderNode *) * size);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
GskRoundedRect outline;
|
||||||
|
|
||||||
|
gsk_rounded_rect_init (&outline,
|
||||||
|
&GRAPHENE_RECT_INIT (0, 0, 1920, 1080),
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4});
|
||||||
|
|
||||||
|
child_nodes[i] = gsk_border_node_new (&outline,
|
||||||
|
(float[4]){2, 2, 2 ,2}, /* Widths */
|
||||||
|
(GdkRGBA[4]) { /* Colors */
|
||||||
|
{1, 0, 0, 1},
|
||||||
|
{1, 0, 0, 1},
|
||||||
|
{1, 0, 0, 1},
|
||||||
|
{1, 0, 0, 1},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
root_node = gsk_container_node_new (child_nodes, size);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gsk_render_node_unref (child_nodes[i]);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
gsk_renderer_render_texture (renderer, root_node, NULL);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (child_nodes);
|
||||||
|
gsk_render_node_unref (root_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
outset_shadows_unblurred_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GskRenderer *renderer = user_data;
|
||||||
|
GskRenderNode *root_node;
|
||||||
|
GskRenderNode **child_nodes;
|
||||||
|
GdkTexture *texture;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
child_nodes = g_malloc (sizeof (GskRenderNode *) * size);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
GskRoundedRect outline;
|
||||||
|
|
||||||
|
gsk_rounded_rect_init (&outline,
|
||||||
|
&GRAPHENE_RECT_INIT (0, 0, 1920, 1080),
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4});
|
||||||
|
|
||||||
|
child_nodes[i] = gsk_outset_shadow_node_new (&outline,
|
||||||
|
&(GdkRGBA){0, 0, 0, 1},
|
||||||
|
0, 0, /* Offset */
|
||||||
|
10, /* Spread */
|
||||||
|
0); /* Blur */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
root_node = gsk_container_node_new (child_nodes, size);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gsk_render_node_unref (child_nodes[i]);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
texture = gsk_renderer_render_texture (renderer, root_node, NULL);
|
||||||
|
g_object_unref (texture);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (child_nodes);
|
||||||
|
gsk_render_node_unref (root_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
outset_shadows_blurred_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GskRenderer *renderer = user_data;
|
||||||
|
GskRenderNode *root_node;
|
||||||
|
GskRenderNode **child_nodes;
|
||||||
|
GdkTexture *texture;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
child_nodes = g_malloc (sizeof (GskRenderNode *) * size);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
GskRoundedRect outline;
|
||||||
|
|
||||||
|
gsk_rounded_rect_init (&outline,
|
||||||
|
&GRAPHENE_RECT_INIT (0, 0, 1920, 1080),
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4},
|
||||||
|
&(graphene_size_t){4, 4});
|
||||||
|
|
||||||
|
child_nodes[i] = gsk_outset_shadow_node_new (&outline,
|
||||||
|
&(GdkRGBA){0, 0, 0, 1},
|
||||||
|
0, 0, /* Offset */
|
||||||
|
10, /* Spread */
|
||||||
|
10); /* Blur */
|
||||||
|
}
|
||||||
|
|
||||||
|
root_node = gsk_container_node_new (child_nodes, size);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gsk_render_node_unref (child_nodes[i]);
|
||||||
|
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
texture = gsk_renderer_render_texture (renderer, root_node, NULL);
|
||||||
|
g_object_unref (texture);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (child_nodes);
|
||||||
|
gsk_render_node_unref (root_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
linear_gradient_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GskRenderer *renderer = user_data;
|
||||||
|
GskRenderNode *root_node;
|
||||||
|
GskRenderNode **child_nodes;
|
||||||
|
GdkTexture *texture;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
child_nodes = g_malloc (sizeof (GskRenderNode *) * size);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
if (i % 2 == 0)
|
||||||
|
child_nodes[i] = gsk_linear_gradient_node_new (&GRAPHENE_RECT_INIT (0, 0, 1920, 1080),
|
||||||
|
&(graphene_point_t){0, 0},
|
||||||
|
&(graphene_point_t){0, 20},
|
||||||
|
(GskColorStop[3]) {
|
||||||
|
{0.0, (GdkRGBA){1, 0, 0, 1}},
|
||||||
|
{0.5, (GdkRGBA){0, 1, 0, 1}},
|
||||||
|
{1.0, (GdkRGBA){0, 0, 1, 1}},
|
||||||
|
}, 3);
|
||||||
|
else
|
||||||
|
child_nodes[i] = gsk_linear_gradient_node_new (&GRAPHENE_RECT_INIT (0, 0, 1920, 1080),
|
||||||
|
&(graphene_point_t){0, 0},
|
||||||
|
&(graphene_point_t){20, 20},
|
||||||
|
(GskColorStop[3]) {
|
||||||
|
{0.0, (GdkRGBA){1, 0, 0, 1}},
|
||||||
|
{0.5, (GdkRGBA){0, 1, 1, 1}},
|
||||||
|
{1.0, (GdkRGBA){1, 0, 1, 1}},
|
||||||
|
}, 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
root_node = gsk_container_node_new (child_nodes, size);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
gsk_render_node_unref (child_nodes[i]);
|
||||||
|
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
texture = gsk_renderer_render_texture (renderer, root_node, NULL);
|
||||||
|
g_object_unref (texture);
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (child_nodes);
|
||||||
|
gsk_render_node_unref (root_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
BenchmarkSuite suite;
|
||||||
|
GOptionContext *option_context;
|
||||||
|
GError *error = NULL;
|
||||||
|
static const struct {
|
||||||
|
const char *type_name;
|
||||||
|
const char *renderer_name;
|
||||||
|
} renderers[] = {
|
||||||
|
{"GskCairoRenderer", "cairo"},
|
||||||
|
{"GskGLRenderer", "opengl"},
|
||||||
|
#ifdef GDK_RENDERING_VULKAN
|
||||||
|
{"GskVulkanRenderer", "vulkan"},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
option_context = g_option_context_new ("");
|
||||||
|
g_option_context_add_main_entries (option_context, options, NULL);
|
||||||
|
if (!g_option_context_parse (option_context, &argc, &argv, &error))
|
||||||
|
{
|
||||||
|
g_printerr ("Option parsing failed: %s\n", error->message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_suite_init (&suite, profile_benchmark_name);
|
||||||
|
gtk_init ();
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (renderers); i ++)
|
||||||
|
{
|
||||||
|
GskRenderer *renderer;
|
||||||
|
GdkSurface *surface;
|
||||||
|
gsize s = 0;
|
||||||
|
|
||||||
|
g_setenv ("GSK_RENDERER", renderers[i].renderer_name, TRUE);
|
||||||
|
|
||||||
|
surface = gdk_surface_new_toplevel (gdk_display_get_default (), 10, 10);
|
||||||
|
renderer = gsk_renderer_new_for_surface (surface);
|
||||||
|
|
||||||
|
if (strcmp (g_type_name (G_OBJECT_TYPE (renderer)), renderers[i].type_name) != 0)
|
||||||
|
{
|
||||||
|
g_message ("%s != %s, skipping...",
|
||||||
|
g_type_name (G_OBJECT_TYPE (renderer)),
|
||||||
|
renderers[i].type_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (s = 2; s < 256; s *= 2)
|
||||||
|
{
|
||||||
|
/* All the benchmarks for this renderer type */
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s borders", renderers[i].renderer_name),
|
||||||
|
s,
|
||||||
|
borders_benchmark,
|
||||||
|
renderer);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s outset shadows unblurred", renderers[i].renderer_name),
|
||||||
|
s,
|
||||||
|
outset_shadows_unblurred_benchmark,
|
||||||
|
renderer);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s outset shadows blurred", renderers[i].renderer_name),
|
||||||
|
s,
|
||||||
|
outset_shadows_blurred_benchmark,
|
||||||
|
renderer);
|
||||||
|
benchmark_suite_add (&suite,
|
||||||
|
g_strdup_printf ("%s linear gradient", renderers[i].renderer_name),
|
||||||
|
s,
|
||||||
|
linear_gradient_benchmark,
|
||||||
|
renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX We can't do this here of course since the renderers have to live until
|
||||||
|
* benchmark_suite_run is done. */
|
||||||
|
/*g_object_unref (renderer);*/
|
||||||
|
/*g_object_unref (surface);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return benchmark_suite_run (&suite);
|
||||||
|
}
|
260
benchmarks/widget.c
Normal file
260
benchmarks/widget.c
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "benchmark.h"
|
||||||
|
|
||||||
|
/* Command line options */
|
||||||
|
const char *profile_benchmark_name = NULL;
|
||||||
|
static GOptionEntry options[] = {
|
||||||
|
{ "profile", 'p', 0, G_OPTION_ARG_STRING, &profile_benchmark_name, "Benchmark name to profile using callgrind", NULL },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_parent_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget *w;
|
||||||
|
GtkWidget **widgets;
|
||||||
|
|
||||||
|
widgets = g_malloc (sizeof (GtkWidget *) * size);
|
||||||
|
w = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
widgets[i] = gtk_button_new ();
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
gtk_widget_set_parent (widgets[i], w);
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
|
||||||
|
g_free (widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
reorder_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget *w;
|
||||||
|
GtkWidget **widgets;
|
||||||
|
|
||||||
|
widgets = g_malloc (sizeof (GtkWidget *) * size);
|
||||||
|
w = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
widgets[i] = gtk_button_new ();
|
||||||
|
gtk_widget_set_parent (widgets[i], w);
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
/* Move this child to the very end */
|
||||||
|
gtk_widget_insert_before (widgets[i], w, NULL);
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_size_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget *w;
|
||||||
|
int width, height;
|
||||||
|
int button_width;
|
||||||
|
int button_height;
|
||||||
|
|
||||||
|
w = gtk_button_new ();
|
||||||
|
|
||||||
|
gtk_widget_measure (w, GTK_ORIENTATION_HORIZONTAL, -1, &width, NULL, NULL, NULL);
|
||||||
|
gtk_widget_measure (w, GTK_ORIENTATION_VERTICAL, width, &height, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
button_width = 200 + width;
|
||||||
|
button_height = 300 + height;
|
||||||
|
|
||||||
|
gtk_widget_size_allocate (w,
|
||||||
|
&(GtkAllocation){0, 0, button_width, button_height}, -1);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
width = gtk_widget_get_width (w);
|
||||||
|
height = gtk_widget_get_height (w);
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_assert_cmpint (width, <=, button_width);
|
||||||
|
g_assert_cmpint (height, <=, button_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
compute_bounds_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget *w;
|
||||||
|
int width, height;
|
||||||
|
int button_width;
|
||||||
|
int button_height;
|
||||||
|
|
||||||
|
w = gtk_button_new ();
|
||||||
|
|
||||||
|
gtk_widget_measure (w, GTK_ORIENTATION_HORIZONTAL, -1, &width, NULL, NULL, NULL);
|
||||||
|
gtk_widget_measure (w, GTK_ORIENTATION_VERTICAL, width, &height, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
button_width = 200 + width;
|
||||||
|
button_height = 300 + height;
|
||||||
|
|
||||||
|
gtk_widget_size_allocate (w,
|
||||||
|
&(GtkAllocation){0, 0, button_width, button_height}, -1);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
graphene_rect_t r;
|
||||||
|
|
||||||
|
gtk_widget_compute_bounds (w, w, &r);
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
translate_coords_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget *root;
|
||||||
|
GtkWidget *widget_a;
|
||||||
|
GtkWidget *widget_b;
|
||||||
|
GtkWidget *iter;
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
/* Create an unbalanced widget tree with depth @size on one side and
|
||||||
|
* depth 1 on the other. */
|
||||||
|
|
||||||
|
root = gtk_button_new ();
|
||||||
|
widget_a = gtk_button_new ();
|
||||||
|
widget_b = gtk_button_new ();
|
||||||
|
|
||||||
|
iter = root;
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
GtkWidget *w = gtk_button_new ();
|
||||||
|
|
||||||
|
gtk_widget_set_parent (w, iter);
|
||||||
|
iter = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_set_parent (widget_a, root);
|
||||||
|
gtk_widget_set_parent (widget_b, iter);
|
||||||
|
|
||||||
|
/* This will create all the CSS styles, which is the actual slow part... */
|
||||||
|
gtk_widget_translate_coordinates (widget_a, widget_b, x, y, &x, &y);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
|
||||||
|
gtk_widget_translate_coordinates (widget_a, widget_b, x, y, &x, &y);
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
measure_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget *root;
|
||||||
|
int min;
|
||||||
|
|
||||||
|
/* Create an unbalanced widget tree with depth @size on one side and
|
||||||
|
* depth 1 on the other. */
|
||||||
|
|
||||||
|
root = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
GtkWidget *w = gtk_button_new ();
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (root), w);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_measure (root, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
gtk_widget_measure (root, GTK_ORIENTATION_HORIZONTAL, min + i, &min, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
templates_benchmark (Benchmark *b,
|
||||||
|
gsize size,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
GtkWidget **widgets = g_malloc (sizeof (GtkWidget *) * size);
|
||||||
|
|
||||||
|
/* Just load some widget using composite templates a bunch of times. */
|
||||||
|
|
||||||
|
benchmark_start (b);
|
||||||
|
for (i = 0; i < size; i ++)
|
||||||
|
{
|
||||||
|
widgets[i] = gtk_info_bar_new ();
|
||||||
|
}
|
||||||
|
benchmark_stop (b);
|
||||||
|
|
||||||
|
g_free (widgets);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
BenchmarkSuite suite;
|
||||||
|
GOptionContext *option_context;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
option_context = g_option_context_new ("");
|
||||||
|
g_option_context_add_main_entries (option_context, options, NULL);
|
||||||
|
if (!g_option_context_parse (option_context, &argc, &argv, &error))
|
||||||
|
{
|
||||||
|
g_printerr ("Option parsing failed: %s\n", error->message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
benchmark_suite_init (&suite, profile_benchmark_name);
|
||||||
|
gtk_init ();
|
||||||
|
|
||||||
|
benchmark_suite_add (&suite, "set_parent", 10000, set_parent_benchmark, NULL);
|
||||||
|
benchmark_suite_add (&suite, "reorder", 10000, reorder_benchmark, NULL);
|
||||||
|
benchmark_suite_add (&suite, "get_size", 10000, get_size_benchmark, NULL);
|
||||||
|
benchmark_suite_add (&suite, "compute_bounds", 10000, compute_bounds_benchmark, NULL);
|
||||||
|
benchmark_suite_add (&suite, "translate_coords", 1000, translate_coords_benchmark, NULL);
|
||||||
|
benchmark_suite_add (&suite, "measure", 10000, measure_benchmark, NULL);
|
||||||
|
benchmark_suite_add (&suite, "templates", 10000, templates_benchmark, NULL);
|
||||||
|
|
||||||
|
return benchmark_suite_run (&suite);
|
||||||
|
}
|
@@ -4334,6 +4334,7 @@ gtk_widget_get_can_focus
|
|||||||
gtk_widget_set_can_focus
|
gtk_widget_set_can_focus
|
||||||
gtk_widget_get_focus_on_click
|
gtk_widget_get_focus_on_click
|
||||||
gtk_widget_set_focus_on_click
|
gtk_widget_set_focus_on_click
|
||||||
|
gtk_widget_set_focus_child
|
||||||
gtk_widget_get_has_surface
|
gtk_widget_get_has_surface
|
||||||
gtk_widget_set_has_surface
|
gtk_widget_set_has_surface
|
||||||
gtk_widget_get_sensitive
|
gtk_widget_get_sensitive
|
||||||
|
@@ -115,8 +115,6 @@ typedef enum
|
|||||||
GDK_EVENT_FLUSHED = 1 << 2
|
GDK_EVENT_FLUSHED = 1 << 2
|
||||||
} GdkEventFlags;
|
} GdkEventFlags;
|
||||||
|
|
||||||
typedef struct _GdkSurfacePaint GdkSurfacePaint;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
GDK_INPUT_OUTPUT,
|
GDK_INPUT_OUTPUT,
|
||||||
|
@@ -201,15 +201,13 @@ color_matrix_modifies_alpha (GskRenderNode *node)
|
|||||||
const graphene_matrix_t *matrix = gsk_color_matrix_node_peek_color_matrix (node);
|
const graphene_matrix_t *matrix = gsk_color_matrix_node_peek_color_matrix (node);
|
||||||
const graphene_vec4_t *offset = gsk_color_matrix_node_peek_color_offset (node);
|
const graphene_vec4_t *offset = gsk_color_matrix_node_peek_color_offset (node);
|
||||||
graphene_vec4_t row3;
|
graphene_vec4_t row3;
|
||||||
graphene_vec4_t id_row3;
|
|
||||||
|
|
||||||
if (graphene_vec4_get_w (offset) != 0.0f)
|
if (graphene_vec4_get_w (offset) != 0.0f)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
graphene_vec4_init (&id_row3, 0, 0, 0, 1);
|
|
||||||
graphene_matrix_get_row (matrix, 3, &row3);
|
graphene_matrix_get_row (matrix, 3, &row3);
|
||||||
|
|
||||||
return !graphene_vec4_equal (&id_row3, &row3);
|
return !graphene_vec4_equal (graphene_vec4_w_axis (), &row3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@@ -597,15 +597,9 @@ get_renderer_for_display (GdkSurface *surface)
|
|||||||
static GType
|
static GType
|
||||||
get_renderer_for_env_var (GdkSurface *surface)
|
get_renderer_for_env_var (GdkSurface *surface)
|
||||||
{
|
{
|
||||||
static GType env_var_type = G_TYPE_NONE;
|
const char *renderer_name = g_getenv ("GSK_RENDERER");
|
||||||
|
|
||||||
if (env_var_type == G_TYPE_NONE)
|
return get_renderer_for_name (renderer_name);
|
||||||
{
|
|
||||||
const char *renderer_name = g_getenv ("GSK_RENDERER");
|
|
||||||
env_var_type = get_renderer_for_name (renderer_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return env_var_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GType
|
static GType
|
||||||
|
@@ -284,7 +284,7 @@ gtk_grid_set_property (GObject *object,
|
|||||||
static GtkGridChild *
|
static GtkGridChild *
|
||||||
get_grid_child (GtkWidget *widget)
|
get_grid_child (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
return (GtkGridChild *) g_object_get_qdata (G_OBJECT (widget), child_data_quark);
|
return (GtkGridChild *) g_object_get_qdata ((GObject *)widget, child_data_quark);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -420,8 +420,6 @@ find_attach_position (GtkGrid *grid,
|
|||||||
gint op_span,
|
gint op_span,
|
||||||
gboolean max)
|
gboolean max)
|
||||||
{
|
{
|
||||||
GtkGridChildAttach *attach;
|
|
||||||
GtkGridChildAttach *opposite;
|
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
gint pos;
|
gint pos;
|
||||||
gboolean hit;
|
gboolean hit;
|
||||||
@@ -433,14 +431,13 @@ find_attach_position (GtkGrid *grid,
|
|||||||
|
|
||||||
hit = FALSE;
|
hit = FALSE;
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (grid));
|
for (child = _gtk_widget_get_first_child (GTK_WIDGET (grid));
|
||||||
child != NULL;
|
child != NULL;
|
||||||
child = gtk_widget_get_next_sibling (child))
|
child = _gtk_widget_get_next_sibling (child))
|
||||||
{
|
{
|
||||||
GtkGridChild *grid_child = get_grid_child (child);
|
const GtkGridChild *grid_child = get_grid_child (child);
|
||||||
|
const GtkGridChildAttach *attach = &grid_child->attach[orientation];
|
||||||
attach = &grid_child->attach[orientation];
|
const GtkGridChildAttach *opposite = &grid_child->attach[1 - orientation];
|
||||||
opposite = &grid_child->attach[1 - orientation];
|
|
||||||
|
|
||||||
/* check if the ranges overlap */
|
/* check if the ranges overlap */
|
||||||
if (opposite->pos <= op_pos + op_span && op_pos <= opposite->pos + opposite->span)
|
if (opposite->pos <= op_pos + op_span && op_pos <= opposite->pos + opposite->span)
|
||||||
|
@@ -13330,6 +13330,19 @@ gtk_widget_snapshot_child (GtkWidget *widget,
|
|||||||
gtk_snapshot_offset (snapshot, -x, -y);
|
gtk_snapshot_offset (snapshot, -x, -y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_widget_set_focus_child:
|
||||||
|
* @widget: a #GtkWidget
|
||||||
|
* @child: (nullable): a direct child widget of @widget or %NULL
|
||||||
|
* to unset the focus child of @widget
|
||||||
|
*
|
||||||
|
* Set @child as the current focus child of @widget. The previous
|
||||||
|
* focus child will be unset.
|
||||||
|
*
|
||||||
|
* This function is only suitable for widget implementations.
|
||||||
|
* If you want a certain widget to get the input focus, call
|
||||||
|
* gtk_widget_grab_focus() on it.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
gtk_widget_set_focus_child (GtkWidget *widget,
|
gtk_widget_set_focus_child (GtkWidget *widget,
|
||||||
GtkWidget *child)
|
GtkWidget *child)
|
||||||
@@ -13364,10 +13377,17 @@ gtk_widget_set_focus_child (GtkWidget *widget,
|
|||||||
|
|
||||||
if (GTK_IS_CONTAINER (widget))
|
if (GTK_IS_CONTAINER (widget))
|
||||||
gtk_container_set_focus_child (GTK_CONTAINER (widget), child);
|
gtk_container_set_focus_child (GTK_CONTAINER (widget), child);
|
||||||
|
|
||||||
/* TODO: ??? */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_widget_get_focus_child:
|
||||||
|
* @widget: a #GtkWidget
|
||||||
|
*
|
||||||
|
* Returns the current focus child of @widget.
|
||||||
|
*
|
||||||
|
* Returns: (nullable): The current focus child of @widget,
|
||||||
|
* or %NULL in case the focus child is unset.
|
||||||
|
*/
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
gtk_widget_get_focus_child (GtkWidget *widget)
|
gtk_widget_get_focus_child (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
|
@@ -645,6 +645,7 @@ subdir('gdk')
|
|||||||
subdir('gsk')
|
subdir('gsk')
|
||||||
subdir('gtk')
|
subdir('gtk')
|
||||||
subdir('modules')
|
subdir('modules')
|
||||||
|
subdir('benchmarks')
|
||||||
if get_option('demos')
|
if get_option('demos')
|
||||||
subdir('demos')
|
subdir('demos')
|
||||||
endif
|
endif
|
||||||
|
Reference in New Issue
Block a user