1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2012 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
20 #include "gdkframehistory.h"
21 #include "gdkinternals.h"
23 #define FRAME_HISTORY_MAX_LENGTH 16
25 struct _GdkFrameHistory
27 GObject parent_instance;
32 GdkFrameTimings *timings[FRAME_HISTORY_MAX_LENGTH];
35 struct _GdkFrameHistoryClass
37 GObjectClass parent_class;
40 G_DEFINE_TYPE (GdkFrameHistory, gdk_frame_history, G_TYPE_OBJECT)
43 gdk_frame_history_finalize (GObject *object)
45 GdkFrameHistory *history = GDK_FRAME_HISTORY (object);
48 for (i = 0; i < FRAME_HISTORY_MAX_LENGTH; i++)
49 if (history->timings[i] != 0)
50 gdk_frame_timings_unref (history->timings[i]);
52 G_OBJECT_CLASS (gdk_frame_history_parent_class)->finalize (object);
56 gdk_frame_history_class_init (GdkFrameHistoryClass *klass)
58 GObjectClass *object_class = G_OBJECT_CLASS (klass);
60 object_class->finalize = gdk_frame_history_finalize;
64 gdk_frame_history_init (GdkFrameHistory *history)
66 history->frame_counter = -1;
67 history->current = FRAME_HISTORY_MAX_LENGTH - 1;
71 gdk_frame_history_new (void)
73 return g_object_new (GDK_TYPE_FRAME_HISTORY, NULL);
77 gdk_frame_history_get_frame_counter (GdkFrameHistory *history)
79 g_return_val_if_fail (GDK_IS_FRAME_HISTORY (history), 0);
81 return history->frame_counter;
85 gdk_frame_history_get_start (GdkFrameHistory *history)
87 g_return_val_if_fail (GDK_IS_FRAME_HISTORY (history), 0);
89 return history->frame_counter + 1 - history->n_timings;
93 gdk_frame_history_begin_frame (GdkFrameHistory *history)
95 g_return_if_fail (GDK_IS_FRAME_HISTORY (history));
97 history->frame_counter++;
98 history->current = (history->current + 1) % FRAME_HISTORY_MAX_LENGTH;
100 if (history->n_timings < FRAME_HISTORY_MAX_LENGTH)
101 history->n_timings++;
104 gdk_frame_timings_unref(history->timings[history->current]);
107 history->timings[history->current] = gdk_frame_timings_new (history->frame_counter);
111 gdk_frame_history_get_timings (GdkFrameHistory *history,
112 gint64 frame_counter)
116 g_return_val_if_fail (GDK_IS_FRAME_HISTORY (history), NULL);
118 if (frame_counter > history->frame_counter)
121 if (frame_counter <= history->frame_counter - history->n_timings)
124 pos = (history->current - (history->frame_counter - frame_counter) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
126 return history->timings[pos];
130 gdk_frame_history_get_last_complete (GdkFrameHistory *history)
134 g_return_val_if_fail (GDK_IS_FRAME_HISTORY (history), NULL);
136 for (i = 0; i < history->n_timings; i++)
138 gint pos = ((history->current - i) + FRAME_HISTORY_MAX_LENGTH) % FRAME_HISTORY_MAX_LENGTH;
139 if (gdk_frame_timings_get_complete (history->timings[pos]))
140 return history->timings[pos];
146 #ifdef G_ENABLE_DEBUG
148 _gdk_frame_history_debug_print (GdkFrameHistory *history,
149 GdkFrameTimings *timings)
151 gint64 frame_counter = gdk_frame_timings_get_frame_counter (timings);
152 gint64 layout_start_time = _gdk_frame_timings_get_layout_start_time (timings);
153 gint64 paint_start_time = _gdk_frame_timings_get_paint_start_time (timings);
154 gint64 frame_end_time = _gdk_frame_timings_get_frame_end_time (timings);
155 gint64 frame_time = gdk_frame_timings_get_frame_time (timings);
156 gint64 presentation_time = gdk_frame_timings_get_presentation_time (timings);
157 gint64 predicted_presentation_time = gdk_frame_timings_get_predicted_presentation_time (timings);
158 gint64 refresh_interval = gdk_frame_timings_get_refresh_interval (timings);
159 gint64 previous_frame_time = 0;
160 gboolean slept_before = gdk_frame_timings_get_slept_before (timings);
161 GdkFrameTimings *previous_timings = gdk_frame_history_get_timings (history,
164 if (previous_timings != NULL)
165 previous_frame_time = gdk_frame_timings_get_frame_time (previous_timings);
167 g_print ("%5" G_GINT64_FORMAT ":", frame_counter);
168 if (previous_frame_time != 0)
170 g_print (" interval=%-4.1f", (frame_time - previous_frame_time) / 1000.);
171 g_print (slept_before ? " (sleep)" : " ");
173 if (layout_start_time != 0)
174 g_print (" layout_start=%-4.1f", (layout_start_time - frame_time) / 1000.);
175 if (paint_start_time != 0)
176 g_print (" paint_start=%-4.1f", (paint_start_time - frame_time) / 1000.);
177 if (frame_end_time != 0)
178 g_print (" frame_end=%-4.1f", (frame_end_time - frame_time) / 1000.);
179 if (presentation_time != 0)
180 g_print (" present=%-4.1f", (presentation_time - frame_time) / 1000.);
181 if (predicted_presentation_time != 0)
182 g_print (" predicted=%-4.1f", (predicted_presentation_time - frame_time) / 1000.);
183 if (refresh_interval != 0)
184 g_print (" refresh_interval=%-4.1f", refresh_interval / 1000.);
187 #endif /* G_ENABLE_DEBUG */