sysprof: add animation helpers

Reluctantly adding animation helpers so we can do some automated scrolling.
This commit is contained in:
Christian Hergert
2023-08-28 14:12:43 -07:00
parent a60bc04de2
commit dc15089133
5 changed files with 1475 additions and 3 deletions

View File

@ -1,13 +1,14 @@
sysprof_sources = [
'main.c',
'sysprof-animation.c',
'sysprof-application.c',
'sysprof-axis.c',
'sysprof-callgraph-view.c',
'sysprof-category-icon.c',
'sysprof-chart-layer.c',
'sysprof-chart-layer-factory.c',
'sysprof-chart-layer-item.c',
'sysprof-chart-layer-item-widget.c',
'sysprof-chart-layer-item.c',
'sysprof-chart-layer.c',
'sysprof-chart.c',
'sysprof-color-iter.c',
'sysprof-column-layer.c',
@ -21,6 +22,7 @@ sysprof_sources = [
'sysprof-entry-popover.c',
'sysprof-files-section.c',
'sysprof-flame-graph.c',
'sysprof-frame-source.c',
'sysprof-frame-utility.c',
'sysprof-graphics-section.c',
'sysprof-greeter.c',
@ -38,10 +40,10 @@ sysprof_sources = [
'sysprof-normalized-series-item.c',
'sysprof-normalized-series.c',
'sysprof-pair.c',
'sysprof-power-profiles.c',
'sysprof-process-dialog.c',
'sysprof-processes-section.c',
'sysprof-progress-cell.c',
'sysprof-power-profiles.c',
'sysprof-recording-pad.c',
'sysprof-recording-template.c',
'sysprof-sampled-model.c',

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
/* sysprof-animation.h
*
* Copyright (C) 2010-2020 Christian Hergert <christian@hergert.me>
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gdk/gdk.h>
G_BEGIN_DECLS
#define SYSPROF_TYPE_ANIMATION (sysprof_animation_get_type())
#define SYSPROF_TYPE_ANIMATION_MODE (sysprof_animation_mode_get_type())
G_DECLARE_FINAL_TYPE (SysprofAnimation, sysprof_animation, SYSPROF, ANIMATION, GInitiallyUnowned)
typedef enum _SysprofAnimationMode
{
SYSPROF_ANIMATION_LINEAR,
SYSPROF_ANIMATION_EASE_IN_QUAD,
SYSPROF_ANIMATION_EASE_OUT_QUAD,
SYSPROF_ANIMATION_EASE_IN_OUT_QUAD,
SYSPROF_ANIMATION_EASE_IN_CUBIC,
SYSPROF_ANIMATION_EASE_OUT_CUBIC,
SYSPROF_ANIMATION_EASE_IN_OUT_CUBIC,
SYSPROF_ANIMATION_LAST
} SysprofAnimationMode;
GType sysprof_animation_mode_get_type (void) G_GNUC_CONST;
void sysprof_animation_start (SysprofAnimation *animation);
void sysprof_animation_stop (SysprofAnimation *animation);
void sysprof_animation_add_property (SysprofAnimation *animation,
GParamSpec *pspec,
const GValue *value);
SysprofAnimation *sysprof_object_animatev (gpointer object,
SysprofAnimationMode mode,
guint duration_msec,
GdkFrameClock *frame_clock,
const gchar *first_property,
va_list args);
SysprofAnimation *sysprof_object_animate (gpointer object,
SysprofAnimationMode mode,
guint duration_msec,
GdkFrameClock *frame_clock,
const gchar *first_property,
...) G_GNUC_NULL_TERMINATED;
SysprofAnimation *sysprof_object_animate_full (gpointer object,
SysprofAnimationMode mode,
guint duration_msec,
GdkFrameClock *frame_clock,
GDestroyNotify notify,
gpointer notify_data,
const gchar *first_property,
...) G_GNUC_NULL_TERMINATED;
guint sysprof_animation_calculate_duration (GdkMonitor *monitor,
gdouble from_value,
gdouble to_value);
G_END_DECLS

View File

@ -0,0 +1,174 @@
/* sysprof-frame-source.c
*
* Copyright 2010-2016 Christian Hergert <christian@hergert.me>
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define G_LOG_DOMAIN "sysprof-frame-source"
#include "config.h"
#include "sysprof-frame-source.h"
/**
* SECTION:sysprof-frame-source
* @title: SysprofFrameSource
* @short_description: a frame source for objects without frame clocks
*
* If you are working with something that is not a #GtkWidget, getting
* access to a frame-clock is sometimes not possible. This can be used
* as a suitable fallback that approximates a frame-rate.
*
* If you have access to a #GdkFrameClock, in most cases you'll want that
* instead of using this.
*/
typedef struct
{
GSource parent;
guint fps;
guint frame_count;
gint64 start_time;
} SysprofFrameSource;
static gboolean
sysprof_frame_source_prepare (GSource *source,
gint *timeout_)
{
SysprofFrameSource *fsource = (SysprofFrameSource *)(gpointer)source;
gint64 current_time;
guint elapsed_time;
guint new_frame_num;
guint frame_time;
current_time = g_source_get_time(source) / 1000;
elapsed_time = current_time - fsource->start_time;
new_frame_num = elapsed_time * fsource->fps / 1000;
/* If time has gone backwards or the time since the last frame is
* greater than the two frames worth then reset the time and do a
* frame now */
if (new_frame_num < fsource->frame_count ||
new_frame_num - fsource->frame_count > 2) {
/* Get the frame time rounded up to the nearest ms */
frame_time = (1000 + fsource->fps - 1) / fsource->fps;
/* Reset the start time */
fsource->start_time = current_time;
/* Move the start time as if one whole frame has elapsed */
fsource->start_time -= frame_time;
fsource->frame_count = 0;
*timeout_ = 0;
return TRUE;
} else if (new_frame_num > fsource->frame_count) {
*timeout_ = 0;
return TRUE;
} else {
*timeout_ = (fsource->frame_count + 1) * 1000 / fsource->fps - elapsed_time;
return FALSE;
}
}
static gboolean
sysprof_frame_source_check (GSource *source)
{
gint timeout_;
return sysprof_frame_source_prepare(source, &timeout_);
}
static gboolean
sysprof_frame_source_dispatch (GSource *source,
GSourceFunc source_func,
gpointer user_data)
{
SysprofFrameSource *fsource = (SysprofFrameSource *)(gpointer)source;
gboolean ret;
if ((ret = source_func(user_data)))
fsource->frame_count++;
return ret;
}
static GSourceFuncs source_funcs = {
sysprof_frame_source_prepare,
sysprof_frame_source_check,
sysprof_frame_source_dispatch,
};
/**
* sysprof_frame_source_add:
* @frames_per_sec: (in): Target frames per second.
* @callback: (in) (scope notified): A #GSourceFunc to execute.
* @user_data: (in): User data for @callback.
*
* Creates a new frame source that will execute when the timeout interval
* for the source has elapsed. The timing will try to synchronize based
* on the end time of the animation.
*
* Returns: A source id that can be removed with g_source_remove().
*/
guint
sysprof_frame_source_add (guint frames_per_sec,
GSourceFunc callback,
gpointer user_data)
{
SysprofFrameSource *fsource;
GSource *source;
guint ret;
g_return_val_if_fail (frames_per_sec > 0, 0);
source = g_source_new (&source_funcs, sizeof (SysprofFrameSource));
fsource = (SysprofFrameSource *)(gpointer)source;
fsource->fps = frames_per_sec;
fsource->frame_count = 0;
fsource->start_time = g_get_monotonic_time () / 1000L;
g_source_set_callback (source, callback, user_data, NULL);
g_source_set_name (source, "SysprofFrameSource");
ret = g_source_attach (source, NULL);
g_source_unref (source);
return ret;
}
guint
sysprof_frame_source_add_full (gint priority,
guint frames_per_sec,
GSourceFunc callback,
gpointer user_data,
GDestroyNotify notify)
{
SysprofFrameSource *fsource;
GSource *source;
guint ret;
g_return_val_if_fail (frames_per_sec > 0, 0);
source = g_source_new (&source_funcs, sizeof (SysprofFrameSource));
fsource = (SysprofFrameSource *)(gpointer)source;
fsource->fps = frames_per_sec;
fsource->frame_count = 0;
fsource->start_time = g_get_monotonic_time () / 1000L;
g_source_set_callback (source, callback, user_data, notify);
g_source_set_name (source, "SysprofFrameSource");
ret = g_source_attach (source, NULL);
g_source_unref (source);
return ret;
}

View File

@ -0,0 +1,35 @@
/* sysprof-frame-source.h
*
* Copyright 2010-2020 Christian Hergert <christian@hergert.me>
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <glib.h>
G_BEGIN_DECLS
guint sysprof_frame_source_add (guint frames_per_sec,
GSourceFunc callback,
gpointer user_data);
guint sysprof_frame_source_add_full (gint priority,
guint frames_per_sec,
GSourceFunc callback,
gpointer user_data,
GDestroyNotify notify);
G_END_DECLS