mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
profile: Add a Sysprof-based profiler
This exposes the /org/gnome/Sysprof3/Profiler object inside Mutter to allow initiating a Sysprof capture. https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
This commit is contained in:
parent
04fb6f7659
commit
17c5436f6e
@ -64,6 +64,7 @@
|
|||||||
#include "clutter/clutter-mutter.h"
|
#include "clutter/clutter-mutter.h"
|
||||||
#include "meta/main.h"
|
#include "meta/main.h"
|
||||||
#include "meta/meta-backend.h"
|
#include "meta/meta-backend.h"
|
||||||
|
#include "backends/meta-profiler.h"
|
||||||
#include "meta/util.h"
|
#include "meta/util.h"
|
||||||
|
|
||||||
#ifdef HAVE_REMOTE_DESKTOP
|
#ifdef HAVE_REMOTE_DESKTOP
|
||||||
@ -126,6 +127,7 @@ struct _MetaBackendPrivate
|
|||||||
MetaScreenCast *screen_cast;
|
MetaScreenCast *screen_cast;
|
||||||
MetaRemoteDesktop *remote_desktop;
|
MetaRemoteDesktop *remote_desktop;
|
||||||
#endif
|
#endif
|
||||||
|
MetaProfiler *profiler;
|
||||||
|
|
||||||
ClutterBackend *clutter_backend;
|
ClutterBackend *clutter_backend;
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
@ -192,6 +194,7 @@ meta_backend_finalize (GObject *object)
|
|||||||
g_hash_table_destroy (priv->device_monitors);
|
g_hash_table_destroy (priv->device_monitors);
|
||||||
|
|
||||||
g_clear_object (&priv->settings);
|
g_clear_object (&priv->settings);
|
||||||
|
g_clear_object (&priv->profiler);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -841,6 +844,8 @@ meta_backend_initable_init (GInitable *initable,
|
|||||||
system_bus_gotten_cb,
|
system_bus_gotten_cb,
|
||||||
backend);
|
backend);
|
||||||
|
|
||||||
|
priv->profiler = meta_profiler_new ();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
193
src/backends/meta-profiler.c
Normal file
193
src/backends/meta-profiler.c
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Endless, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "src/backends/meta-profiler.h"
|
||||||
|
|
||||||
|
#include <glib-unix.h>
|
||||||
|
#include <gio/gunixfdlist.h>
|
||||||
|
|
||||||
|
#include "cogl/cogl-trace.h"
|
||||||
|
|
||||||
|
#define META_SYSPROF_PROFILER_DBUS_PATH "/org/gnome/Sysprof3/Profiler"
|
||||||
|
|
||||||
|
struct _MetaProfiler
|
||||||
|
{
|
||||||
|
MetaDBusSysprof3ProfilerSkeleton parent_instance;
|
||||||
|
|
||||||
|
GDBusConnection *connection;
|
||||||
|
GCancellable *cancellable;
|
||||||
|
|
||||||
|
gboolean running;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (MetaProfiler,
|
||||||
|
meta_profiler,
|
||||||
|
META_DBUS_TYPE_SYSPROF3_PROFILER_SKELETON,
|
||||||
|
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SYSPROF3_PROFILER,
|
||||||
|
meta_sysprof_capturer_init_iface))
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_start (MetaDBusSysprof3Profiler *dbus_profiler,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
GVariant *options,
|
||||||
|
GVariant *fd_variant)
|
||||||
|
{
|
||||||
|
MetaProfiler *profiler = META_PROFILER (dbus_profiler);
|
||||||
|
GMainContext *main_context = g_main_context_default ();
|
||||||
|
GDBusMessage *message;
|
||||||
|
GUnixFDList *fd_list;
|
||||||
|
int position;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
if (profiler->running)
|
||||||
|
{
|
||||||
|
g_dbus_method_invocation_return_error (invocation,
|
||||||
|
G_DBUS_ERROR,
|
||||||
|
G_DBUS_ERROR_FAILED,
|
||||||
|
"Profiler already running");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_get (fd_variant, "h", &position);
|
||||||
|
|
||||||
|
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, position, NULL);
|
||||||
|
|
||||||
|
if (fd != -1)
|
||||||
|
cogl_set_tracing_enabled_on_thread_with_fd (main_context, fd);
|
||||||
|
else
|
||||||
|
cogl_set_tracing_enabled_on_thread (main_context, "mutter-profile.syscap");
|
||||||
|
|
||||||
|
profiler->running = TRUE;
|
||||||
|
|
||||||
|
g_debug ("Profiler running");
|
||||||
|
|
||||||
|
meta_dbus_sysprof3_profiler_complete_start (dbus_profiler, invocation);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
handle_stop (MetaDBusSysprof3Profiler *dbus_profiler,
|
||||||
|
GDBusMethodInvocation *invocation)
|
||||||
|
{
|
||||||
|
MetaProfiler *profiler = META_PROFILER (dbus_profiler);
|
||||||
|
|
||||||
|
if (!profiler->running)
|
||||||
|
{
|
||||||
|
g_dbus_method_invocation_return_error (invocation,
|
||||||
|
G_DBUS_ERROR,
|
||||||
|
G_DBUS_ERROR_FAILED,
|
||||||
|
"Profiler not running");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cogl_set_tracing_disabled_on_thread (g_main_context_default ());
|
||||||
|
profiler->running = FALSE;
|
||||||
|
|
||||||
|
g_debug ("Stopping profiler");
|
||||||
|
|
||||||
|
meta_dbus_sysprof3_profiler_complete_stop (dbus_profiler, invocation);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface)
|
||||||
|
{
|
||||||
|
iface->handle_start = handle_start;
|
||||||
|
iface->handle_stop = handle_stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_bus_acquired_cb (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
g_autoptr (GDBusConnection) connection = NULL;
|
||||||
|
GDBusInterfaceSkeleton *interface_skeleton;
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
MetaProfiler *profiler;
|
||||||
|
|
||||||
|
connection = g_bus_get_finish (result, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
|
g_warning ("Failed to get session bus: %s\n", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler = META_PROFILER (user_data);
|
||||||
|
interface_skeleton = G_DBUS_INTERFACE_SKELETON (profiler);
|
||||||
|
|
||||||
|
if (!g_dbus_interface_skeleton_export (interface_skeleton,
|
||||||
|
connection,
|
||||||
|
META_SYSPROF_PROFILER_DBUS_PATH,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to export profiler object: %s\n", error->message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler->connection = g_steal_pointer (&connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_profiler_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MetaProfiler *self = (MetaProfiler *)object;
|
||||||
|
|
||||||
|
g_cancellable_cancel (self->cancellable);
|
||||||
|
|
||||||
|
g_clear_object (&self->cancellable);
|
||||||
|
g_clear_object (&self->connection);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (meta_profiler_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_profiler_class_init (MetaProfilerClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->finalize = meta_profiler_finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_profiler_init (MetaProfiler *self)
|
||||||
|
{
|
||||||
|
self->cancellable = g_cancellable_new ();
|
||||||
|
|
||||||
|
g_bus_get (G_BUS_TYPE_SESSION,
|
||||||
|
self->cancellable,
|
||||||
|
on_bus_acquired_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaProfiler *
|
||||||
|
meta_profiler_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (META_TYPE_PROFILER, NULL);
|
||||||
|
}
|
41
src/backends/meta-profiler.h
Normal file
41
src/backends/meta-profiler.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Endless, Inc
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_PROFILER_H
|
||||||
|
#define META_PROFILER_H
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "meta-dbus-sysprof3-profiler.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define META_TYPE_PROFILER (meta_profiler_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (MetaProfiler,
|
||||||
|
meta_profiler,
|
||||||
|
META,
|
||||||
|
PROFILER,
|
||||||
|
MetaDBusSysprof3ProfilerSkeleton)
|
||||||
|
|
||||||
|
MetaProfiler * meta_profiler_new (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* META_PROFILER_H */
|
@ -625,6 +625,23 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
|
|||||||
)
|
)
|
||||||
mutter_built_sources += dbus_idle_monitor_built_sources
|
mutter_built_sources += dbus_idle_monitor_built_sources
|
||||||
|
|
||||||
|
if have_profiler
|
||||||
|
mutter_sources += [
|
||||||
|
'backends/meta-profiler.c',
|
||||||
|
'backends/meta-profiler.h',
|
||||||
|
]
|
||||||
|
|
||||||
|
dbus_interfaces_dir = join_paths(datadir, 'dbus-1', 'interfaces')
|
||||||
|
sysprof3_dbus_file = join_paths(dbus_interfaces_dir, 'org.gnome.Sysprof3.Profiler.xml')
|
||||||
|
|
||||||
|
dbus_sysprof3_profiler_built_sources = gnome.gdbus_codegen('meta-dbus-sysprof3-profiler',
|
||||||
|
sysprof3_dbus_file,
|
||||||
|
interface_prefix: 'org.gnome.',
|
||||||
|
namespace: 'MetaDBus',
|
||||||
|
)
|
||||||
|
mutter_built_sources += dbus_sysprof3_profiler_built_sources
|
||||||
|
endif
|
||||||
|
|
||||||
if have_native_backend
|
if have_native_backend
|
||||||
cvt = find_program('cvt')
|
cvt = find_program('cvt')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user