1/* GDK - The GIMP Drawing Kit
2 * Copyright (C) 2012 Red Hat, Inc.
3 *
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.
8 *
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.
13 *
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/>.
16 */
17
18#include "config.h"
19
20#include <string.h>
21
22#include "gdkframeclockprivate.h"
23
24/**
25 * SECTION:gdkframetimings
26 * @Short_description: Object holding timing information for a single frame
27 * @Title: Frame timings
28 *
29 * A #GdkFrameTimings object holds timing information for a single frame
30 * of the application’s displays. To retrieve #GdkFrameTimings objects,
31 * use gdk_frame_clock_get_timings() or gdk_frame_clock_get_current_timings().
32 * The information in #GdkFrameTimings is useful for precise synchronization
33 * of video with the event or audio streams, and for measuring
34 * quality metrics for the application’s display, such as latency and jitter.
35 */
36
37G_DEFINE_BOXED_TYPE (GdkFrameTimings, gdk_frame_timings,
38 gdk_frame_timings_ref,
39 gdk_frame_timings_unref)
40
41GdkFrameTimings *
42_gdk_frame_timings_new (gint64 frame_counter)
43{
44 GdkFrameTimings *timings;
45
46 timings = g_slice_new0 (GdkFrameTimings);
47 timings->ref_count = 1;
48 timings->frame_counter = frame_counter;
49
50 return timings;
51}
52
53gboolean
54_gdk_frame_timings_steal (GdkFrameTimings *timings,
55 gint64 frame_counter)
56{
57 if (timings->ref_count == 1)
58 {
59 memset (timings, 0, sizeof *timings);
60 timings->ref_count = 1;
61 timings->frame_counter = frame_counter;
62 return TRUE;
63 }
64
65 return FALSE;
66}
67
68/**
69 * gdk_frame_timings_ref:
70 * @timings: a #GdkFrameTimings
71 *
72 * Increases the reference count of @timings.
73 *
74 * Returns: @timings
75 * Since: 3.8
76 */
77GdkFrameTimings *
78gdk_frame_timings_ref (GdkFrameTimings *timings)
79{
80 g_return_val_if_fail (timings != NULL, NULL);
81
82 timings->ref_count++;
83
84 return timings;
85}
86
87/**
88 * gdk_frame_timings_unref:
89 * @timings: a #GdkFrameTimings
90 *
91 * Decreases the reference count of @timings. If @timings
92 * is no longer referenced, it will be freed.
93 *
94 * Since: 3.8
95 */
96void
97gdk_frame_timings_unref (GdkFrameTimings *timings)
98{
99 g_return_if_fail (timings != NULL);
100 g_return_if_fail (timings->ref_count > 0);
101
102 timings->ref_count--;
103 if (timings->ref_count == 0)
104 {
105 g_slice_free (GdkFrameTimings, timings);
106 }
107}
108
109/**
110 * gdk_frame_timings_get_frame_counter:
111 * @timings: a #GdkFrameTimings
112 *
113 * Gets the frame counter value of the #GdkFrameClock when this
114 * this frame was drawn.
115 *
116 * Returns: the frame counter value for this frame
117 * Since: 3.8
118 */
119gint64
120gdk_frame_timings_get_frame_counter (GdkFrameTimings *timings)
121{
122 return timings->frame_counter;
123}
124
125/**
126 * gdk_frame_timings_get_complete:
127 * @timings: a #GdkFrameTimings
128 *
129 * The timing information in a #GdkFrameTimings is filled in
130 * incrementally as the frame as drawn and passed off to the
131 * window system for processing and display to the user. The
132 * accessor functions for #GdkFrameTimings can return 0 to
133 * indicate an unavailable value for two reasons: either because
134 * the information is not yet available, or because it isn't
135 * available at all. Once gdk_frame_timings_get_complete() returns
136 * %TRUE for a frame, you can be certain that no further values
137 * will become available and be stored in the #GdkFrameTimings.
138 *
139 * Returns: %TRUE if all information that will be available
140 * for the frame has been filled in.
141 * Since: 3.8
142 */
143gboolean
144gdk_frame_timings_get_complete (GdkFrameTimings *timings)
145{
146 g_return_val_if_fail (timings != NULL, FALSE);
147
148 return timings->complete;
149}
150
151/**
152 * gdk_frame_timings_get_frame_time:
153 * @timings: A #GdkFrameTimings
154 *
155 * Returns the frame time for the frame. This is the time value
156 * that is typically used to time animations for the frame. See
157 * gdk_frame_clock_get_frame_time().
158 *
159 * Returns: the frame time for the frame, in the timescale
160 * of g_get_monotonic_time()
161 */
162gint64
163gdk_frame_timings_get_frame_time (GdkFrameTimings *timings)
164{
165 g_return_val_if_fail (timings != NULL, 0);
166
167 return timings->frame_time;
168}
169
170/**
171 * gdk_frame_timings_get_presentation_time:
172 * @timings: a #GdkFrameTimings
173 *
174 * Reurns the presentation time. This is the time at which the frame
175 * became visible to the user.
176 *
177 * Returns: the time the frame was displayed to the user, in the
178 * timescale of g_get_monotonic_time(), or 0 if no presentation
179 * time is available. See gdk_frame_timings_get_complete()
180 * Since: 3.8
181 */
182gint64
183gdk_frame_timings_get_presentation_time (GdkFrameTimings *timings)
184{
185 g_return_val_if_fail (timings != NULL, 0);
186
187 return timings->presentation_time;
188}
189
190/**
191 * gdk_frame_timings_get_predicted_presentation_time:
192 * @timings: a #GdkFrameTimings
193 *
194 * Gets the predicted time at which this frame will be displayed. Although
195 * no predicted time may be available, if one is available, it will
196 * be available while the frame is being generated, in contrast to
197 * gdk_frame_timings_get_presentation_time(), which is only available
198 * after the frame has been presented. In general, if you are simply
199 * animating, you should use gdk_frame_clock_get_frame_time() rather
200 * than this function, but this function is useful for applications
201 * that want exact control over latency. For example, a movie player
202 * may want this information for Audio/Video synchronization.
203 *
204 * Returns: The predicted time at which the frame will be presented,
205 * in the timescale of g_get_monotonic_time(), or 0 if no predicted
206 * presentation time is available.
207 * Since: 3.8
208 */
209gint64
210gdk_frame_timings_get_predicted_presentation_time (GdkFrameTimings *timings)
211{
212 g_return_val_if_fail (timings != NULL, 0);
213
214 return timings->predicted_presentation_time;
215}
216
217/**
218 * gdk_frame_timings_get_refresh_interval:
219 * @timings: a #GdkFrameTimings
220 *
221 * Gets the natural interval between presentation times for
222 * the display that this frame was displayed on. Frame presentation
223 * usually happens during the “vertical blanking interval”.
224 *
225 * Returns: the refresh interval of the display, in microseconds,
226 * or 0 if the refresh interval is not available.
227 * See gdk_frame_timings_get_complete().
228 * Since: 3.8
229 */
230gint64
231gdk_frame_timings_get_refresh_interval (GdkFrameTimings *timings)
232{
233 g_return_val_if_fail (timings != NULL, 0);
234
235 return timings->refresh_interval;
236}
237