forked from AuroraMiddleware/gtk
Merge branch 'new-sysprof' into 'master'
Port profiling to sysprof-collector api See merge request GNOME/gtk!2457
This commit is contained in:
commit
125ed52ccb
@ -74,7 +74,7 @@ fedora-x86_64:
|
||||
script:
|
||||
- meson subprojects update
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
-Dprofiler=true
|
||||
-Dsysprof=enabled
|
||||
_build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
|
@ -103,7 +103,7 @@
|
||||
#mesondefine HAVE_SYS_PARAM_H
|
||||
|
||||
/* Have the sysprof-capture library */
|
||||
#mesondefine HAVE_SYSPROF_CAPTURE
|
||||
#mesondefine HAVE_SYSPROF
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#mesondefine HAVE_SYS_STAT_H
|
||||
|
@ -335,17 +335,13 @@ GSettings schema.
|
||||
## Profiling {#profiling}
|
||||
|
||||
GTK supports profiling with sysprof. It exports timing information
|
||||
about frameclock phases and various characteristics of GskRenders
|
||||
about frameclock phases and various characteristics of GskRenderers
|
||||
in a format that can be displayed by sysprof or GNOME Builder.
|
||||
|
||||
A simple way to capture data is to set the `GTK_TRACE` environment
|
||||
variable. When it is set, GTK will write profiling data to a file
|
||||
called `gtk.PID.syscap`.
|
||||
A simple way to capture data is to run your application under the
|
||||
`sysprof-cli` wrapper, which will write profiling data to a file
|
||||
called `capture.syscap`.
|
||||
|
||||
When launching the application from sysprof, it will set the
|
||||
`SYSPROF_TRACE_FD` environment variable to point GTK at a file
|
||||
descriptor to write profiling data to.
|
||||
|
||||
When GtkApplication registers with D-Bus, it exports the
|
||||
`org.gnome.Sysprof2.Profiler` D-Bus interface that lets sysprof
|
||||
request profiling data at runtime.
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
#include "gdkversionmacros.h"
|
||||
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
|
||||
@ -304,11 +303,6 @@ gdk_pre_parse (void)
|
||||
g_warning ("GDK_DEBUG set but ignored because GTK isn't built with G_ENABLE_DEBUG");
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
if (g_getenv ("GTK_TRACE_FD"))
|
||||
gdk_profiler_start (atoi (g_getenv ("GTK_TRACE_FD")));
|
||||
else if (g_getenv ("GTK_TRACE"))
|
||||
gdk_profiler_start (-1);
|
||||
|
||||
#ifndef G_HAS_CONSTRUCTORS
|
||||
stash_desktop_startup_notification_id ();
|
||||
#endif
|
||||
|
@ -175,17 +175,13 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
||||
g_object_class_install_properties (gobject_class, LAST_PROP, pspecs);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static guint pixels_counter;
|
||||
#endif
|
||||
|
||||
static void
|
||||
gdk_draw_context_init (GdkDrawContext *self)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (pixels_counter == 0)
|
||||
pixels_counter = gdk_profiler_define_int_counter ("frame pixels", "Pixels drawn per frame");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,7 +321,7 @@ gdk_draw_context_begin_frame (GdkDrawContext *context,
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, priv->frame_region);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
#ifdef HAVE_SYSPROF
|
||||
static gint64
|
||||
region_get_pixels (cairo_region_t *region)
|
||||
{
|
||||
@ -383,12 +379,7 @@ gdk_draw_context_end_frame (GdkDrawContext *context)
|
||||
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, priv->frame_region);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_set_int_counter (pixels_counter,
|
||||
g_get_monotonic_time (),
|
||||
region_get_pixels (priv->frame_region));
|
||||
#endif
|
||||
gdk_profiler_set_int_counter (pixels_counter, region_get_pixels (priv->frame_region));
|
||||
|
||||
g_clear_pointer (&priv->frame_region, cairo_region_destroy);
|
||||
g_clear_object (&priv->surface->paint_context);
|
||||
|
@ -673,34 +673,37 @@ _gdk_frame_clock_emit_before_paint (GdkFrameClock *frame_clock)
|
||||
void
|
||||
_gdk_frame_clock_emit_update (GdkFrameClock *frame_clock)
|
||||
{
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
g_signal_emit (frame_clock, signals[UPDATE], 0);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "frameclock update", NULL);
|
||||
gdk_profiler_end_mark (before, "frameclock update", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_layout (GdkFrameClock *frame_clock)
|
||||
{
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
g_signal_emit (frame_clock, signals[LAYOUT], 0);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "frameclock layout", NULL);
|
||||
gdk_profiler_end_mark (before, "frameclock layout", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_frame_clock_emit_paint (GdkFrameClock *frame_clock)
|
||||
{
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
g_signal_emit (frame_clock, signals[PAINT], 0);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "frameclock paint", NULL);
|
||||
gdk_profiler_end_mark (before, "frameclock paint", NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -715,6 +718,7 @@ _gdk_frame_clock_emit_resume_events (GdkFrameClock *frame_clock)
|
||||
g_signal_emit (frame_clock, signals[RESUME_EVENTS], 0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYSPROF
|
||||
static gint64
|
||||
guess_refresh_interval (GdkFrameClock *frame_clock)
|
||||
{
|
||||
@ -780,24 +784,25 @@ frame_clock_get_fps (GdkFrameClock *frame_clock)
|
||||
interval = guess_refresh_interval (frame_clock);
|
||||
if (interval == 0)
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ((double) end_counter - start_counter) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_gdk_frame_clock_add_timings_to_profiler (GdkFrameClock *clock,
|
||||
GdkFrameTimings *timings)
|
||||
{
|
||||
if (timings->drawn_time != 0)
|
||||
gdk_profiler_add_mark (timings->drawn_time, 0, "drawn window", NULL);
|
||||
{
|
||||
gdk_profiler_add_mark (1000 * timings->drawn_time, 0, "drawn window", NULL);
|
||||
}
|
||||
|
||||
if (timings->presentation_time != 0)
|
||||
gdk_profiler_add_mark (timings->presentation_time, 0, "presented window", NULL);
|
||||
|
||||
if (timings->presentation_time != 0 || timings->drawn_time != 0)
|
||||
{
|
||||
gint64 time = timings->presentation_time != 0 ? timings->presentation_time : timings->drawn_time;
|
||||
gdk_profiler_set_counter (fps_counter, time, frame_clock_get_fps (clock));
|
||||
gdk_profiler_add_mark (1000 * timings->presentation_time, 0, "presented window", NULL);
|
||||
}
|
||||
|
||||
gdk_profiler_set_counter (fps_counter, frame_clock_get_fps (clock));
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ struct _GdkFrameClockIdlePrivate
|
||||
for details. */
|
||||
|
||||
gint64 sleep_serial;
|
||||
gint64 freeze_time;
|
||||
gint64 freeze_time; /* in microseconds */
|
||||
|
||||
guint flush_idle_id;
|
||||
guint paint_idle_id;
|
||||
@ -400,7 +400,9 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
GdkFrameClockIdlePrivate *priv = clock_idle->priv;
|
||||
gboolean skip_to_resume_events;
|
||||
GdkFrameTimings *timings = NULL;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
priv->paint_idle_id = 0;
|
||||
priv->in_paint_idle = TRUE;
|
||||
@ -659,8 +661,7 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (priv->freeze_count == 0)
|
||||
priv->sleep_serial = get_sleep_serial ();
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "frameclock cycle", NULL);
|
||||
gdk_profiler_end_mark (before, "frameclock cycle", NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -766,8 +767,7 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock)
|
||||
{
|
||||
if (priv->freeze_time != 0)
|
||||
{
|
||||
gdk_profiler_end_mark (priv->freeze_time,
|
||||
"frameclock frozen", NULL);
|
||||
gdk_profiler_end_mark (priv->freeze_time * 1000, "frameclock frozen", NULL);
|
||||
priv->freeze_time = 0;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
@ -28,301 +30,133 @@
|
||||
#endif
|
||||
|
||||
#include "gdkversionmacros.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdkframeclockprivate.h"
|
||||
|
||||
#ifdef HAVE_SYSPROF_CAPTURE
|
||||
|
||||
#include <sysprof-capture.h>
|
||||
|
||||
static SysprofCaptureWriter *writer = NULL;
|
||||
static gboolean running = FALSE;
|
||||
|
||||
static void
|
||||
profiler_stop (int s)
|
||||
{
|
||||
if (writer)
|
||||
sysprof_capture_writer_unref (writer);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_start (int fd)
|
||||
{
|
||||
if (writer)
|
||||
return;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = g_strdup_printf ("gtk.%d.syscap", getpid ());
|
||||
g_print ("Writing profiling data to %s\n", filename);
|
||||
writer = sysprof_capture_writer_new (filename, 16*1024);
|
||||
g_free (filename);
|
||||
}
|
||||
else if (fd > 2)
|
||||
writer = sysprof_capture_writer_new_from_fd (fd, 16*1024);
|
||||
|
||||
if (writer)
|
||||
running = TRUE;
|
||||
|
||||
atexit (G_CALLBACK (profiler_stop));
|
||||
signal (SIGTERM, profiler_stop);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_stop (void)
|
||||
{
|
||||
running = FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_profiler_is_running (void)
|
||||
{
|
||||
return running;
|
||||
#ifdef HAVE_SYSPROF
|
||||
return sysprof_collector_is_active ();
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_add_mark (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *message)
|
||||
(gdk_profiler_add_mark) (gint64 begin_time,
|
||||
gint64 duration,
|
||||
const char *name,
|
||||
const char *message)
|
||||
{
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
sysprof_capture_writer_add_mark (writer,
|
||||
start * 1000L,
|
||||
-1, getpid (),
|
||||
duration * 1000L,
|
||||
"gtk", name, message);
|
||||
}
|
||||
|
||||
static void add_markvf (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *format,
|
||||
va_list args) G_GNUC_PRINTF(4, 0);
|
||||
|
||||
static void
|
||||
add_markvf (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *format,
|
||||
va_list args)
|
||||
{
|
||||
char *message;
|
||||
message = g_strdup_vprintf (format, args);
|
||||
sysprof_capture_writer_add_mark (writer,
|
||||
start * 1000L,
|
||||
-1, getpid (),
|
||||
duration * 1000L,
|
||||
"gtk", name, message);
|
||||
g_free (message);
|
||||
#ifdef HAVE_SYSPROF
|
||||
sysprof_collector_mark (begin_time, duration, "gtk", name, message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_add_markf (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...)
|
||||
(gdk_profiler_end_mark) (gint64 begin_time,
|
||||
const char *name,
|
||||
const char *message)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
sysprof_collector_mark (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, "gtk", name, message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
(gdk_profiler_add_markf) (gint64 begin_time,
|
||||
gint64 duration,
|
||||
const gchar *name,
|
||||
const gchar *message_format,
|
||||
...)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
va_list args;
|
||||
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
va_start (args, format);
|
||||
add_markvf (start, duration, name, format, args);
|
||||
va_start (args, message_format);
|
||||
sysprof_collector_mark_vprintf (begin_time, duration, "gtk", name, message_format, args);
|
||||
va_end (args);
|
||||
#endif /* HAVE_SYSPROF */
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_end_mark (gint64 start,
|
||||
const char *name,
|
||||
const char *message)
|
||||
{
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
sysprof_capture_writer_add_mark (writer,
|
||||
start * 1000L,
|
||||
-1, getpid (),
|
||||
(g_get_monotonic_time () - start) * 1000L,
|
||||
"gtk", name, message);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_end_markf (gint64 start,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...)
|
||||
(gdk_profiler_end_markf) (gint64 begin_time,
|
||||
const gchar *name,
|
||||
const gchar *message_format,
|
||||
...)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
va_list args;
|
||||
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
va_start (args, format);
|
||||
add_markvf (start, g_get_monotonic_time () - start, name, format, args);
|
||||
va_start (args, message_format);
|
||||
sysprof_collector_mark_vprintf (begin_time, GDK_PROFILER_CURRENT_TIME - begin_time, "gtk", name, message_format, args);
|
||||
va_end (args);
|
||||
#endif /* HAVE_SYSPROF */
|
||||
}
|
||||
|
||||
|
||||
static guint
|
||||
define_counter (const char *name,
|
||||
const char *description,
|
||||
int type)
|
||||
guint
|
||||
(gdk_profiler_define_counter) (const char *name,
|
||||
const char *description)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
SysprofCaptureCounter counter;
|
||||
|
||||
if (!writer)
|
||||
return 0;
|
||||
|
||||
counter.id = (guint) sysprof_capture_writer_request_counter (writer, 1);
|
||||
counter.type = type;
|
||||
counter.value.vdbl = 0;
|
||||
counter.id = sysprof_collector_request_counters (1);
|
||||
counter.type = SYSPROF_CAPTURE_COUNTER_DOUBLE;
|
||||
counter.value.vdbl = 0.0;
|
||||
g_strlcpy (counter.category, "gtk", sizeof counter.category);
|
||||
g_strlcpy (counter.name, name, sizeof counter.name);
|
||||
g_strlcpy (counter.description, description, sizeof counter.name);
|
||||
|
||||
sysprof_capture_writer_define_counters (writer,
|
||||
SYSPROF_CAPTURE_CURRENT_TIME,
|
||||
-1,
|
||||
getpid (),
|
||||
&counter,
|
||||
1);
|
||||
sysprof_collector_define_counters (&counter, 1);
|
||||
|
||||
return counter.id;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_profiler_define_counter (const char *name,
|
||||
const char *description)
|
||||
(gdk_profiler_define_int_counter) (const char *name,
|
||||
const char *description)
|
||||
{
|
||||
return define_counter (name, description, SYSPROF_CAPTURE_COUNTER_DOUBLE);
|
||||
}
|
||||
#ifdef HAVE_SYSPROF
|
||||
SysprofCaptureCounter counter;
|
||||
|
||||
guint
|
||||
gdk_profiler_define_int_counter (const char *name,
|
||||
const char *description)
|
||||
{
|
||||
return define_counter (name, description, SYSPROF_CAPTURE_COUNTER_INT64);
|
||||
counter.id = sysprof_collector_request_counters (1);
|
||||
counter.type = SYSPROF_CAPTURE_COUNTER_INT64;
|
||||
counter.value.v64 = 0;
|
||||
g_strlcpy (counter.category, "gtk", sizeof counter.category);
|
||||
g_strlcpy (counter.name, name, sizeof counter.name);
|
||||
g_strlcpy (counter.description, description, sizeof counter.name);
|
||||
|
||||
sysprof_collector_define_counters (&counter, 1);
|
||||
|
||||
return counter.id;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_set_counter (guint id,
|
||||
gint64 time,
|
||||
double val)
|
||||
(gdk_profiler_set_counter) (guint id,
|
||||
double val)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
SysprofCaptureCounterValue value;
|
||||
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
value.vdbl = val;
|
||||
sysprof_capture_writer_set_counters (writer,
|
||||
time * 1000L,
|
||||
-1, getpid (),
|
||||
&id, &value, 1);
|
||||
sysprof_collector_set_counters (&id, &value, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_set_int_counter (guint id,
|
||||
gint64 time,
|
||||
gint64 val)
|
||||
(gdk_profiler_set_int_counter) (guint id,
|
||||
gint64 val)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
SysprofCaptureCounterValue value;
|
||||
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
value.v64 = val;
|
||||
sysprof_capture_writer_set_counters (writer,
|
||||
time * 1000L,
|
||||
-1, getpid (),
|
||||
&id, &value, 1);
|
||||
sysprof_collector_set_counters (&id, &value, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
gdk_profiler_start (int fd)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_stop (void)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_profiler_is_running (void)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_add_mark (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *message)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_add_markf (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_end_mark (gint64 start,
|
||||
const char *name,
|
||||
const char *message)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_end_markf (gint64 start,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_profiler_define_counter (const char *name,
|
||||
const char *description)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_set_counter (guint id,
|
||||
gint64 time,
|
||||
double value)
|
||||
{
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_profiler_define_int_counter (const char *name,
|
||||
const char *description)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_profiler_set_int_counter (guint id,
|
||||
gint64 time,
|
||||
gint64 value)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* G_OS_WIN32 */
|
||||
|
@ -21,52 +21,76 @@
|
||||
#include "gdk/gdkframeclock.h"
|
||||
#include "gdk/gdkdisplay.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* Ensure we included config.h as needed for the below HAVE_SYSPROF_CAPTURE check */
|
||||
#ifndef GETTEXT_PACKAGE
|
||||
#error "config.h was not included before gdkprofilerprivate.h."
|
||||
#endif
|
||||
|
||||
/* We make this a macro you use as if (GDK_PROFILER_IS_RUNNING) because that
|
||||
* way we can ensure all the code is compiled out when not supported, and
|
||||
* we can add a G_UNLIKELY() for better codegen if it is.
|
||||
*/
|
||||
#ifdef HAVE_SYSPROF_CAPTURE
|
||||
#define GDK_PROFILER_IS_RUNNING G_UNLIKELY (gdk_profiler_is_running ())
|
||||
#else
|
||||
#define GDK_PROFILER_IS_RUNNING FALSE
|
||||
#ifdef HAVE_SYSPROF
|
||||
#include <sysprof-capture.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef HAVE_SYSPROF
|
||||
#define GDK_PROFILER_IS_RUNNING (gdk_profiler_is_running ())
|
||||
#define GDK_PROFILER_CURRENT_TIME SYSPROF_CAPTURE_CURRENT_TIME
|
||||
#else
|
||||
#define GDK_PROFILER_IS_RUNNING 0
|
||||
#define GDK_PROFILER_CURRENT_TIME 0
|
||||
#endif
|
||||
|
||||
void gdk_profiler_start (int fd);
|
||||
void gdk_profiler_stop (void);
|
||||
gboolean gdk_profiler_is_running (void);
|
||||
void gdk_profiler_add_mark (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *message);
|
||||
void gdk_profiler_add_markf (gint64 start,
|
||||
guint64 duration,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (4, 5);
|
||||
void gdk_profiler_end_mark (gint64 start,
|
||||
const char *name,
|
||||
const char *message);
|
||||
void gdk_profiler_end_markf (gint64 start,
|
||||
const char *name,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF (3, 4);
|
||||
guint gdk_profiler_define_counter (const char *name,
|
||||
const char *description);
|
||||
void gdk_profiler_set_counter (guint id,
|
||||
gint64 time,
|
||||
double value);
|
||||
guint gdk_profiler_define_int_counter (const char *name,
|
||||
const char *description);
|
||||
void gdk_profiler_set_int_counter (guint id,
|
||||
gint64 time,
|
||||
gint64 value);
|
||||
|
||||
/* Note: Times and durations are in nanoseconds;
|
||||
* g_get_monotonic_time(), and GdkFrameClock times
|
||||
* are in microseconds, so multiply by 1000.
|
||||
*/
|
||||
void gdk_profiler_add_mark (gint64 begin_time,
|
||||
gint64 duration,
|
||||
const gchar *name,
|
||||
const gchar *message);
|
||||
void gdk_profiler_add_markf (gint64 begin_time,
|
||||
gint64 duration,
|
||||
const gchar *name,
|
||||
const gchar *message_format,
|
||||
...) G_GNUC_PRINTF (4, 5);
|
||||
void gdk_profiler_end_mark (gint64 begin_time,
|
||||
const gchar *name,
|
||||
const gchar *message);
|
||||
void gdk_profiler_end_markf (gint64 begin_time,
|
||||
const gchar *name,
|
||||
const gchar *message_format,
|
||||
...) G_GNUC_PRINTF (3, 4);
|
||||
|
||||
guint gdk_profiler_define_counter (const char *name,
|
||||
const char *description);
|
||||
guint gdk_profiler_define_int_counter (const char *name,
|
||||
const char *description);
|
||||
void gdk_profiler_set_counter (guint id,
|
||||
double value);
|
||||
void gdk_profiler_set_int_counter (guint id,
|
||||
gint64 value);
|
||||
|
||||
#ifndef HAVE_SYSPROF
|
||||
#define gdk_profiler_add_mark(b, d, n, m)
|
||||
#define gdk_profiler_end_mark(b, n, m)
|
||||
/* Optimise the whole call out */
|
||||
#if defined(G_HAVE_ISO_VARARGS)
|
||||
#define gdk_profiler_add_markf(b, d, n, m, ...)
|
||||
#define gdk_profiler_end_markf(b, n, m, ...)
|
||||
#elif defined(G_HAVE_GNUC_VARARGS)
|
||||
#define gdk_profiler_add_markf(b, d, n, m...)
|
||||
#define gdk_profiler_end_markf(b, n, m...)
|
||||
#else
|
||||
/* no varargs macro support; the call will have to be optimised out by the compiler */
|
||||
#endif
|
||||
|
||||
#define gdk_profiler_define_counter(n, d) 0
|
||||
#define gdk_profiler_define_int_counter(n, d) 0
|
||||
#define gdk_profiler_set_counter(i, v)
|
||||
#define gdk_profiler_set_int_counter(i, v)
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -2679,11 +2679,12 @@ check_autohide (GdkEvent *event)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
static inline void
|
||||
add_event_mark (GdkEvent *event,
|
||||
gint64 time,
|
||||
guint64 duration)
|
||||
gint64 end_time)
|
||||
{
|
||||
#ifdef HAVE_SYSPROF
|
||||
char *message = NULL;
|
||||
const char *kind;
|
||||
GEnumClass *class;
|
||||
@ -2772,15 +2773,16 @@ add_event_mark (GdkEvent *event,
|
||||
break;
|
||||
}
|
||||
|
||||
gdk_profiler_add_mark (time, duration, "event", message ? message : kind);
|
||||
gdk_profiler_add_mark (time, end_time - time, "event", message ? message : kind);
|
||||
|
||||
g_free (message);
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_surface_handle_event (GdkEvent *event)
|
||||
{
|
||||
gint64 begin_time = g_get_monotonic_time ();
|
||||
gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
if (check_autohide (event))
|
||||
@ -2801,7 +2803,7 @@ gdk_surface_handle_event (GdkEvent *event)
|
||||
}
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
add_event_mark (event, begin_time, g_get_monotonic_time () - begin_time);
|
||||
add_event_mark (event, begin_time, GDK_PROFILER_CURRENT_TIME);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
@ -194,8 +194,8 @@ gdk_deps = [
|
||||
]
|
||||
|
||||
if profiler_enabled
|
||||
if profiler_dep.found()
|
||||
gdk_deps += [profiler_dep]
|
||||
if libsysprof_capture_dep.found()
|
||||
gdk_deps += [libsysprof_capture_dep]
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -1109,7 +1109,9 @@ _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland)
|
||||
guint size;
|
||||
const char *name;
|
||||
GValue v = G_VALUE_INIT;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
g_assert (display_wayland);
|
||||
g_assert (display_wayland->shm);
|
||||
@ -1130,8 +1132,7 @@ _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland)
|
||||
gdk_wayland_display_set_cursor_theme (GDK_DISPLAY (display_wayland), name, size);
|
||||
g_value_unset (&v);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "wayland", "load cursor theme");
|
||||
gdk_profiler_end_mark (before, "wayland", "load cursor theme");
|
||||
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time (), 0, "wayland", "swap buffers");
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "swap buffers");
|
||||
if (display_wayland->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
|
@ -504,7 +504,7 @@ frame_callback (void *data,
|
||||
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time (), 0, "wayland", "frame event");
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "frame event");
|
||||
GDK_DISPLAY_NOTE (GDK_DISPLAY (display_wayland), EVENTS, g_message ("frame %p", surface));
|
||||
|
||||
wl_callback_destroy (callback);
|
||||
@ -640,7 +640,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
* before we need to stage any changes, then we can take it back and
|
||||
* use it again.
|
||||
*/
|
||||
gdk_profiler_add_mark (g_get_monotonic_time (), 0, "wayland", "surface commit");
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
|
||||
impl->pending_commit = FALSE;
|
||||
@ -1801,7 +1801,7 @@ gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
|
||||
maybe_set_gtk_surface_dbus_properties (surface);
|
||||
maybe_set_gtk_surface_modal (surface);
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time (), 0, "wayland", "surface commit");
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
}
|
||||
|
||||
@ -2558,7 +2558,7 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
gdk_profiler_add_mark (g_get_monotonic_time (), 0, "wayland", "surface commit");
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
|
||||
if (GDK_IS_POPUP (surface))
|
||||
|
@ -842,8 +842,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
_gdk_x11_surface_grab_check_unmap (surface, xevent->xany.serial);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_add_markf (g_get_monotonic_time (), 0, "unmapped window", "0x%lx", GDK_SURFACE_XID (surface));
|
||||
gdk_profiler_add_markf (GDK_PROFILER_CURRENT_TIME, 0, "unmapped window", "0x%lx", GDK_SURFACE_XID (surface));
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -3069,8 +3069,9 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
GError **error)
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
/* If we didn't get a GdkGLContext before realization, try creating
|
||||
* one now, for our exclusive use.
|
||||
*/
|
||||
@ -3101,8 +3102,7 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
self->icon_cache = get_icon_cache_for_display (gdk_surface_get_display (surface), self->atlases);
|
||||
gsk_gl_shadow_cache_init (&self->shadow_cache);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "gl renderer realize", NULL);
|
||||
gdk_profiler_end_mark (before, "gl renderer realize", NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -3685,7 +3685,8 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
graphene_matrix_t projection;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 gpu_time, cpu_time, start_time;
|
||||
gint64 gpu_time, cpu_time;
|
||||
gint64 start_time G_GNUC_UNUSED;
|
||||
#endif
|
||||
GPtrArray *removed;
|
||||
|
||||
@ -3804,9 +3805,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
|
||||
gsk_profiler_push_samples (profiler);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_add_mark (start_time, cpu_time, "GL render", "");
|
||||
|
||||
gdk_profiler_add_mark (start_time * 1000, cpu_time * 1000, "GL render", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,8 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 cpu_time, start_time;
|
||||
gint64 cpu_time;
|
||||
gint64 start_time G_GNUC_UNUSED;
|
||||
#endif
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -213,12 +214,10 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
gdk_profiler_add_mark (start_time, cpu_time, "render", "");
|
||||
gdk_profiler_add_mark (start_time * 1000, cpu_time * 1000, "render", "");
|
||||
gdk_profiler_set_int_counter (texture_pixels_counter,
|
||||
start_time + cpu_time,
|
||||
gsk_profiler_counter_get (profiler, self->profile_counters.texture_pixels));
|
||||
gdk_profiler_set_int_counter (fallback_pixels_counter,
|
||||
start_time + cpu_time,
|
||||
gsk_profiler_counter_get (profiler, self->profile_counters.fallback_pixels));
|
||||
}
|
||||
#endif
|
||||
|
@ -157,7 +157,6 @@ typedef struct
|
||||
GtkActionMuxer *muxer;
|
||||
GtkBuilder *menus_builder;
|
||||
char *help_overlay_path;
|
||||
guint profiler_id;
|
||||
} GtkApplicationPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
|
||||
@ -253,25 +252,25 @@ gtk_application_startup (GApplication *g_application)
|
||||
{
|
||||
GtkApplication *application = GTK_APPLICATION (g_application);
|
||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before2;
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
gint64 before2 G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
G_APPLICATION_CLASS (gtk_application_parent_class)->startup (g_application);
|
||||
|
||||
gtk_action_muxer_insert (priv->muxer, "app", G_ACTION_GROUP (application));
|
||||
|
||||
before2 = g_get_monotonic_time ();
|
||||
before2 = GDK_PROFILER_CURRENT_TIME;
|
||||
gtk_init ();
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before2, "gtk init", NULL);
|
||||
gdk_profiler_end_mark (before2, "gtk init", NULL);
|
||||
|
||||
priv->impl = gtk_application_impl_new (application, gdk_display_get_default ());
|
||||
gtk_application_impl_startup (priv->impl, priv->register_session);
|
||||
|
||||
gtk_application_load_resources (application);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "gtk application startup", NULL);
|
||||
gdk_profiler_end_mark (before, "gtk application startup", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -502,135 +501,6 @@ gtk_application_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_application_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
|
||||
static const char org_gnome_Sysprof3_Profiler_xml[] =
|
||||
"<node>"
|
||||
"<interface name='org.gnome.Sysprof3.Profiler'>"
|
||||
"<property name='Capabilities' type='a{sv}' access='read'/>"
|
||||
"<method name='Start'>"
|
||||
"<arg type='a{sv}' name='options' direction='in'/>"
|
||||
"<arg type='h' name='fd' direction='in'/>"
|
||||
"</method>"
|
||||
"<method name='Stop'>"
|
||||
"</method>"
|
||||
"</interface>"
|
||||
"</node>";
|
||||
|
||||
static GDBusInterfaceInfo *org_gnome_Sysprof3_Profiler;
|
||||
|
||||
static void
|
||||
sysprof_profiler_method_call (GDBusConnection *connection,
|
||||
const char *sender,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
const char *method_name,
|
||||
GVariant *parameters,
|
||||
GDBusMethodInvocation *invocation,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (strcmp (method_name, "Start") == 0)
|
||||
{
|
||||
GDBusMessage *message;
|
||||
GUnixFDList *fd_list;
|
||||
GVariant *options;
|
||||
int fd = -1;
|
||||
int idx;
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Profiler already running");
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_get (parameters, "(@a{sv}h)", &options, &idx);
|
||||
|
||||
message = g_dbus_method_invocation_get_message (invocation);
|
||||
fd_list = g_dbus_message_get_unix_fd_list (message);
|
||||
if (fd_list)
|
||||
fd = g_unix_fd_list_get (fd_list, idx, NULL);
|
||||
|
||||
gdk_profiler_start (fd);
|
||||
|
||||
g_variant_unref (options);
|
||||
}
|
||||
else if (strcmp (method_name, "Stop") == 0)
|
||||
{
|
||||
if (!GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Profiler not running");
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_profiler_stop ();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_UNKNOWN_METHOD,
|
||||
"Unknown method");
|
||||
return;
|
||||
}
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_application_dbus_register (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const char *object_path,
|
||||
GError **error)
|
||||
{
|
||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (GTK_APPLICATION (application));
|
||||
GDBusInterfaceVTable vtable = {
|
||||
sysprof_profiler_method_call,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
if (org_gnome_Sysprof3_Profiler == NULL)
|
||||
{
|
||||
GDBusNodeInfo *info;
|
||||
|
||||
info = g_dbus_node_info_new_for_xml (org_gnome_Sysprof3_Profiler_xml, error);
|
||||
if (info == NULL)
|
||||
return FALSE;
|
||||
|
||||
org_gnome_Sysprof3_Profiler = g_dbus_node_info_lookup_interface (info, "org.gnome.Sysprof3.Profiler");
|
||||
g_dbus_interface_info_ref (org_gnome_Sysprof3_Profiler);
|
||||
g_dbus_node_info_unref (info);
|
||||
}
|
||||
|
||||
priv->profiler_id = g_dbus_connection_register_object (connection,
|
||||
"/org/gtk/Profiler",
|
||||
org_gnome_Sysprof3_Profiler,
|
||||
&vtable,
|
||||
NULL,
|
||||
NULL,
|
||||
error);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_dbus_unregister (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
const char *object_path)
|
||||
{
|
||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (GTK_APPLICATION (application));
|
||||
|
||||
g_dbus_connection_unregister_object (connection, priv->profiler_id);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static gboolean
|
||||
gtk_application_dbus_register (GApplication *application,
|
||||
GDBusConnection *connection,
|
||||
@ -647,8 +517,6 @@ gtk_application_dbus_unregister (GApplication *application,
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
gtk_application_class_init (GtkApplicationClass *class)
|
||||
{
|
||||
|
@ -2168,7 +2168,7 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
const char * domain;
|
||||
ParserData data;
|
||||
GSList *l;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
/* Store the original domain so that interface domain attribute can be
|
||||
* applied for the builder and the original domain can be restored after
|
||||
@ -2246,8 +2246,10 @@ _gtk_builder_parser_parse_buffer (GtkBuilder *builder,
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
guint64 after = g_get_monotonic_time ();
|
||||
if (after - before > 500)
|
||||
gdk_profiler_add_mark (before, after - before, "builder load", filename);
|
||||
guint64 after = GDK_PROFILER_CURRENT_TIME;
|
||||
if (after - before > 500000) /* half a millisecond */
|
||||
{
|
||||
gdk_profiler_add_mark (before, after - before, "builder load", filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1364,7 +1364,9 @@ gtk_css_node_validate (GtkCssNode *cssnode)
|
||||
{
|
||||
GtkCountingBloomFilter filter = GTK_COUNTING_BLOOM_FILTER_INIT;
|
||||
gint64 timestamp;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
g_assert (cssnode->parent == NULL);
|
||||
|
||||
@ -1374,10 +1376,9 @@ gtk_css_node_validate (GtkCssNode *cssnode)
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
gint64 after = g_get_monotonic_time ();
|
||||
gdk_profiler_add_mark (before, (after - before), "css validation", "");
|
||||
gdk_profiler_set_int_counter (invalidated_nodes_counter, after, invalidated_nodes);
|
||||
gdk_profiler_set_int_counter (created_styles_counter, after, created_styles);
|
||||
gdk_profiler_end_mark (before, "css validation", "");
|
||||
gdk_profiler_set_int_counter (invalidated_nodes_counter, invalidated_nodes);
|
||||
gdk_profiler_set_int_counter (created_styles_counter, created_styles);
|
||||
invalidated_nodes = 0;
|
||||
created_styles = 0;
|
||||
}
|
||||
|
@ -978,7 +978,9 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (css_provider);
|
||||
GtkCssSelectorTreeBuilder *builder;
|
||||
guint i;
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
g_array_sort (priv->rulesets, gtk_css_provider_compare_rule);
|
||||
|
||||
@ -1010,8 +1012,7 @@ gtk_css_provider_postprocess (GtkCssProvider *css_provider)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "create selector tree", NULL);
|
||||
gdk_profiler_end_mark (before, "create selector tree", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1020,7 +1021,9 @@ gtk_css_provider_load_internal (GtkCssProvider *self,
|
||||
GFile *file,
|
||||
GBytes *bytes)
|
||||
{
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (bytes == NULL)
|
||||
{
|
||||
|
@ -571,9 +571,9 @@ populate_emoji_chooser (gpointer data)
|
||||
{
|
||||
GtkEmojiChooser *chooser = data;
|
||||
GVariant *item;
|
||||
guint64 start, now;
|
||||
gint64 start, now;
|
||||
|
||||
start = g_get_monotonic_time ();
|
||||
start = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (!chooser->data)
|
||||
{
|
||||
@ -614,11 +614,10 @@ populate_emoji_chooser (gpointer data)
|
||||
add_emoji (chooser->box, FALSE, item, 0, chooser);
|
||||
g_variant_unref (item);
|
||||
|
||||
now = g_get_monotonic_time ();
|
||||
if (now > start + 8000)
|
||||
now = GDK_PROFILER_CURRENT_TIME;
|
||||
if (now > start + 2000000) /* 2 ms */
|
||||
{
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_add_mark (start, (now - start), "emojichooser", "populate");
|
||||
gdk_profiler_add_mark (start, (now - start), "emojichooser", "populate");
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
}
|
||||
@ -628,8 +627,7 @@ populate_emoji_chooser (gpointer data)
|
||||
chooser->box = NULL;
|
||||
chooser->populate_idle = 0;
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (start, "emojichooser", "populate (finish)");
|
||||
gdk_profiler_end_mark (start, "emojichooser", "populate (finish)");
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
@ -2070,16 +2070,16 @@ ensure_valid_themes (GtkIconTheme *self,
|
||||
|
||||
if (!self->themes_valid)
|
||||
{
|
||||
gint64 before;
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
if (non_blocking)
|
||||
return FALSE;
|
||||
|
||||
before = g_get_monotonic_time ();
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
load_themes (self);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "icon theme load", self->current_theme);
|
||||
gdk_profiler_end_mark (before, "icon theme load", self->current_theme);
|
||||
|
||||
if (was_valid)
|
||||
queue_theme_changed (self);
|
||||
@ -3720,7 +3720,7 @@ icon_ensure_texture__locked (GtkIconPaintable *icon,
|
||||
if (icon->texture)
|
||||
return;
|
||||
|
||||
before = g_get_monotonic_time ();
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
/* This is the natural pixel size for the requested icon size + scale in this directory.
|
||||
* We precalculate this so we can use it as a rasterization size for svgs.
|
||||
@ -3825,11 +3825,13 @@ icon_ensure_texture__locked (GtkIconPaintable *icon,
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
guint64 end = g_get_monotonic_time ();
|
||||
gint64 end = GDK_PROFILER_CURRENT_TIME;
|
||||
/* Don't report quick (< 0.5 msec) parses */
|
||||
if (end - before > 500 || !in_thread)
|
||||
gdk_profiler_add_markf (before, (end - before), in_thread ? "icon load (thread)" : "icon load" ,
|
||||
"%s size %d@%d", icon->filename, icon->desired_size, icon->desired_scale);
|
||||
if (end - before > 500000 || !in_thread)
|
||||
{
|
||||
gdk_profiler_add_markf (before, (end - before), in_thread ? "icon load (thread)" : "icon load" ,
|
||||
"%s size %d@%d", icon->filename, icon->desired_size, icon->desired_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,15 +247,16 @@ init_compose_table_thread_cb (GTask *task,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
guint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (g_task_return_error_if_cancelled (task))
|
||||
return;
|
||||
|
||||
gtk_im_context_simple_init_compose_table ();
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "im compose table load (thread)", NULL);
|
||||
gdk_profiler_end_mark (before, "im compose table load (thread)", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -10951,8 +10951,11 @@ gtk_widget_render (GtkWidget *widget,
|
||||
GskRenderer *renderer;
|
||||
GskRenderNode *root;
|
||||
double x, y;
|
||||
gint64 before_snapshot = g_get_monotonic_time ();
|
||||
gint64 before_render = 0;
|
||||
gint64 before_snapshot G_GNUC_UNUSED;
|
||||
gint64 before_render G_GNUC_UNUSED;
|
||||
|
||||
before_snapshot = GDK_PROFILER_CURRENT_TIME;
|
||||
before_render = 0;
|
||||
|
||||
if (!GTK_IS_NATIVE (widget))
|
||||
return;
|
||||
@ -10969,7 +10972,7 @@ gtk_widget_render (GtkWidget *widget,
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
{
|
||||
before_render = g_get_monotonic_time ();
|
||||
before_render = GDK_PROFILER_CURRENT_TIME;
|
||||
gdk_profiler_add_mark (before_snapshot, (before_render - before_snapshot), "widget snapshot", "");
|
||||
}
|
||||
|
||||
@ -10985,8 +10988,7 @@ gtk_widget_render (GtkWidget *widget,
|
||||
|
||||
gsk_render_node_unref (root);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before_render, "widget render", "");
|
||||
gdk_profiler_end_mark (before_render, "widget render", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1873,15 +1873,16 @@ static void
|
||||
gtk_window_native_check_resize (GtkNative *native)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (native);
|
||||
gint64 before = g_get_monotonic_time ();
|
||||
gint64 before G_GNUC_UNUSED;
|
||||
|
||||
before = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
if (!_gtk_widget_get_alloc_needed (widget))
|
||||
gtk_widget_ensure_allocate (widget);
|
||||
else if (gtk_widget_get_visible (widget))
|
||||
gtk_window_move_resize (GTK_WINDOW (native));
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
gdk_profiler_end_mark (before, "size allocation", "");
|
||||
gdk_profiler_end_mark (before, "size allocation", "");
|
||||
}
|
||||
|
||||
static void
|
||||
|
25
meson.build
25
meson.build
@ -701,27 +701,40 @@ if cloudproviders_enabled
|
||||
endif
|
||||
endif
|
||||
|
||||
profiler_enabled = get_option('profiler')
|
||||
profiler_enabled = get_option('sysprof').enabled()
|
||||
if profiler_enabled
|
||||
# libsysprof-capture support
|
||||
profiler_dep = dependency('sysprof-capture-4',
|
||||
libsysprof_capture_dep = dependency('sysprof-capture-4',
|
||||
required: true,
|
||||
default_options: [
|
||||
'enable_examples=false',
|
||||
'enable_gtk=false',
|
||||
'enable_tests=false',
|
||||
'enable_tools=false',
|
||||
'libsysprof=false',
|
||||
'libsysprof=true',
|
||||
'with_sysprofd=none',
|
||||
'help=false',
|
||||
],
|
||||
fallback: ['sysprof', 'libsysprof_capture_dep'],
|
||||
)
|
||||
if profiler_dep.found()
|
||||
cdata.set('HAVE_SYSPROF_CAPTURE', profiler_dep.found())
|
||||
if libsysprof_capture_dep.found()
|
||||
cdata.set('HAVE_SYSPROF', 1)
|
||||
else
|
||||
error('Profiler support not found, but was explicitly requested.')
|
||||
endif
|
||||
libsysprof_dep = dependency('sysprof-4',
|
||||
required: false,
|
||||
default_options: [
|
||||
'enable_examples=false',
|
||||
'enable_gtk=false',
|
||||
'enable_tests=false',
|
||||
'enable_tools=false',
|
||||
'libsysprof=true',
|
||||
'with_sysprofd=none',
|
||||
'help=false',
|
||||
],
|
||||
fallback: ['sysprof', 'libsysprof_dep'],
|
||||
)
|
||||
endif
|
||||
|
||||
graphene_dep_type = graphene_dep.type_name()
|
||||
@ -878,7 +891,7 @@ summary('Print backends', print_backends)
|
||||
summary('Media backends', media_backends)
|
||||
summary('Vulkan support', have_vulkan)
|
||||
summary('Cloud support', get_option('cloudproviders'))
|
||||
summary('Profiler', get_option('profiler'))
|
||||
summary('Sysprof support', get_option('sysprof').enabled())
|
||||
summary('Colord support', get_option('colord'))
|
||||
|
||||
# Build
|
||||
|
@ -23,8 +23,12 @@ option('xinerama', type: 'combo', choices : ['yes', 'no', 'auto'], value : 'auto
|
||||
description : 'Enable support for the Xinerama extension')
|
||||
option('cloudproviders', type: 'boolean', value: false,
|
||||
description : 'Enable the cloudproviders support')
|
||||
option('profiler', type: 'boolean', value: false,
|
||||
description : 'Enable profiler support')
|
||||
|
||||
option('sysprof',
|
||||
type: 'feature',
|
||||
value: 'disabled',
|
||||
description : 'include tracing support for sysprof')
|
||||
|
||||
option('tracker3', type: 'boolean', value: false,
|
||||
description : 'Enable Tracker3 filechooser search')
|
||||
|
||||
|
@ -136,9 +136,9 @@ foreach t: gtk_tests
|
||||
dependencies: [libgtk_dep, libm])
|
||||
endforeach
|
||||
|
||||
if get_option('profiler')
|
||||
if profiler_enabled
|
||||
executable('testperf', 'testperf.c',
|
||||
dependencies: [profiler_dep, platform_gio_dep, libm])
|
||||
dependencies: [libsysprof_dep, platform_gio_dep, libm])
|
||||
endif
|
||||
|
||||
librsvg = dependency('librsvg-2.0', version: '>= 2.46.0', required: false)
|
||||
|
@ -1,5 +1,7 @@
|
||||
if get_option ('profiler')
|
||||
test_performance = executable('test-performance', 'test-performance.c',
|
||||
c_args: common_cflags,
|
||||
dependencies: [profiler_dep, platform_gio_dep, libm])
|
||||
if profiler_enabled
|
||||
if libsysprof_dep.found()
|
||||
test_performance = executable('test-performance', 'test-performance.c',
|
||||
c_args: common_cflags,
|
||||
dependencies: [libsysprof_dep, platform_gio_dep, libm])
|
||||
endif
|
||||
endif
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sysprof-capture.h>
|
||||
#include <sysprof.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
typedef struct {
|
||||
@ -46,6 +47,8 @@ static char *opt_detail;
|
||||
static char *opt_name;
|
||||
static char *opt_output;
|
||||
static gboolean opt_start_time;
|
||||
static GMainLoop *main_loop;
|
||||
static GError *failure;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "mark", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &opt_mark, "Name of the mark", "NAME" },
|
||||
@ -57,6 +60,29 @@ static GOptionEntry options[] = {
|
||||
{ NULL, }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
start_in_main (gpointer data)
|
||||
{
|
||||
SysprofProfiler *profiler = data;
|
||||
sysprof_profiler_start (profiler);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_failure_cb (SysprofProfiler *profiler,
|
||||
const GError *error)
|
||||
{
|
||||
g_propagate_error (&failure, g_error_copy (error));
|
||||
g_main_loop_quit (main_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
on_stopped_cb (SysprofProfiler *profiler)
|
||||
{
|
||||
g_clear_error (&failure);
|
||||
g_main_loop_quit (main_loop);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -64,12 +90,13 @@ main (int argc, char *argv[])
|
||||
GError *error = NULL;
|
||||
Data data;
|
||||
SysprofCaptureFrameType type;
|
||||
char fd_str[20];
|
||||
gint64 *values;
|
||||
gint64 min, max, total;
|
||||
int count;
|
||||
char *output_dir = NULL;
|
||||
int i;
|
||||
char **spawn_env;
|
||||
char *workdir;
|
||||
int i, j;
|
||||
|
||||
context = g_option_context_new ("COMMANDLINE");
|
||||
g_option_context_add_main_entries (context, options, NULL);
|
||||
@ -85,6 +112,12 @@ main (int argc, char *argv[])
|
||||
if (opt_rep < 1)
|
||||
g_error ("COUNT must be a positive number");
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
workdir = g_get_current_dir ();
|
||||
|
||||
spawn_env = g_get_environ ();
|
||||
spawn_env = g_environ_setenv (spawn_env, "GTK_DEBUG_AUTO_QUIT", "1", TRUE);
|
||||
|
||||
if (opt_output)
|
||||
{
|
||||
GError *err = NULL;
|
||||
@ -117,41 +150,54 @@ main (int argc, char *argv[])
|
||||
|
||||
for (i = 0; i < opt_rep; i++)
|
||||
{
|
||||
GSubprocessLauncher *launcher;
|
||||
GSubprocess *subprocess;
|
||||
SysprofProfiler *profiler;
|
||||
int fd;
|
||||
char *name;
|
||||
SysprofCaptureWriter *writer;
|
||||
SysprofCaptureReader *reader;
|
||||
SysprofCaptureCursor *cursor;
|
||||
SysprofCaptureCondition *condition;
|
||||
char **child_argv;
|
||||
|
||||
fd = g_file_open_tmp ("gtk.XXXXXX.syscap", &name, &error);
|
||||
if (error)
|
||||
g_error ("Create syscap file: %s", error->message);
|
||||
|
||||
launcher = g_subprocess_launcher_new (0);
|
||||
g_subprocess_launcher_take_fd (launcher, fd, fd);
|
||||
g_snprintf (fd_str, sizeof (fd_str), "%d", fd);
|
||||
g_subprocess_launcher_setenv (launcher, "GTK_TRACE_FD", fd_str, TRUE);
|
||||
g_subprocess_launcher_setenv (launcher, "GTK_DEBUG_AUTO_QUIT", "1", TRUE);
|
||||
child_argv = g_new (char *, argc);
|
||||
for (j = 0; j + 1 < argc; j++)
|
||||
child_argv[j] = argv[j + 1];
|
||||
child_argv[argc - 1] = NULL;
|
||||
|
||||
subprocess = g_subprocess_launcher_spawnv (launcher, (const char *const *)argv + 1, &error);
|
||||
if (error)
|
||||
g_error ("Launch child: %s", error->message);
|
||||
writer = sysprof_capture_writer_new_from_fd (fd, 0);
|
||||
if (!writer)
|
||||
g_error ("Failed to create capture writer: %s", g_strerror (errno));
|
||||
|
||||
if (!g_subprocess_wait (subprocess, NULL, &error))
|
||||
g_error ("Run child: %s", error->message);
|
||||
profiler = sysprof_local_profiler_new ();
|
||||
sysprof_profiler_set_whole_system (profiler, FALSE);
|
||||
sysprof_profiler_set_spawn (profiler, TRUE);
|
||||
sysprof_profiler_set_spawn_argv (profiler, (const char * const *)child_argv);
|
||||
sysprof_profiler_set_spawn_cwd (profiler, workdir);
|
||||
sysprof_profiler_set_spawn_env (profiler, (const char * const *)spawn_env);
|
||||
sysprof_profiler_set_writer (profiler, writer);
|
||||
|
||||
if (!g_subprocess_get_successful (subprocess))
|
||||
g_error ("Child process failed");
|
||||
sysprof_capture_writer_unref (writer);
|
||||
g_free (child_argv);
|
||||
|
||||
g_object_unref (subprocess);
|
||||
g_object_unref (launcher);
|
||||
g_signal_connect_swapped (profiler, "failed", G_CALLBACK (on_failure_cb), NULL);
|
||||
g_signal_connect_swapped (profiler, "stopped", G_CALLBACK (on_stopped_cb), NULL);
|
||||
|
||||
reader = sysprof_capture_reader_new (name);
|
||||
g_idle_add (start_in_main, profiler);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
if (failure)
|
||||
g_error ("Run child: %s", failure->message);
|
||||
|
||||
reader = sysprof_capture_writer_create_reader (writer);
|
||||
if (!reader)
|
||||
g_error ("Opening syscap file: %s", g_strerror (errno));
|
||||
|
||||
sysprof_capture_writer_unref (writer);
|
||||
|
||||
data.mark = opt_mark ? opt_mark : "css validation";
|
||||
data.detail = opt_detail ? opt_detail : NULL;
|
||||
data.do_start = opt_start_time;
|
||||
@ -196,6 +242,8 @@ main (int argc, char *argv[])
|
||||
g_usleep (300000);
|
||||
}
|
||||
|
||||
g_free (workdir);
|
||||
|
||||
min = G_MAXINT64;
|
||||
max = 0;
|
||||
count = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user