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 * GdkFrameTimings:
26 *
27 * A `GdkFrameTimings` object holds timing information for a single frame
28 * of the application’s displays.
29 *
30 * To retrieve `GdkFrameTimings` objects, use [method@Gdk.FrameClock.get_timings]
31 * or [method@Gdk.FrameClock.get_current_timings]. The information in
32 * `GdkFrameTimings` is useful for precise synchronization of video with
33 * the event or audio streams, and for measuring quality metrics for the
34 * 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 (s: timings, c: 0, n: 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 */
76GdkFrameTimings *
77gdk_frame_timings_ref (GdkFrameTimings *timings)
78{
79 g_return_val_if_fail (timings != NULL, NULL);
80
81 timings->ref_count++;
82
83 return timings;
84}
85
86/**
87 * gdk_frame_timings_unref:
88 * @timings: a `GdkFrameTimings`
89 *
90 * Decreases the reference count of @timings.
91 *
92 * If @timings is no longer referenced, it will be freed.
93 */
94void
95gdk_frame_timings_unref (GdkFrameTimings *timings)
96{
97 g_return_if_fail (timings != NULL);
98 g_return_if_fail (timings->ref_count > 0);
99
100 timings->ref_count--;
101 if (timings->ref_count == 0)
102 {
103 g_slice_free (GdkFrameTimings, timings);
104 }
105}
106
107/**
108 * gdk_frame_timings_get_frame_counter:
109 * @timings: a `GdkFrameTimings`
110 *
111 * Gets the frame counter value of the `GdkFrameClock` when
112 * this frame was drawn.
113 *
114 * Returns: the frame counter value for this frame
115 */
116gint64
117gdk_frame_timings_get_frame_counter (GdkFrameTimings *timings)
118{
119 return timings->frame_counter;
120}
121
122/**
123 * gdk_frame_timings_get_complete:
124 * @timings: a `GdkFrameTimings`
125 *
126 * Returns whether @timings are complete.
127 *
128 * The timing information in a `GdkFrameTimings` is filled in
129 * incrementally as the frame as drawn and passed off to the
130 * window system for processing and display to the user. The
131 * accessor functions for `GdkFrameTimings` can return 0 to
132 * indicate an unavailable value for two reasons: either because
133 * the information is not yet available, or because it isn't
134 * available at all.
135 *
136 * Once this function returns %TRUE for a frame, you can be
137 * certain that no further values will become available and be
138 * stored in the `GdkFrameTimings`.
139 *
140 * Returns: %TRUE if all information that will be available
141 * for the frame has been filled in.
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.
156 *
157 * This is the time value that is typically used to time
158 * animations for the frame. See [method@Gdk.FrameClock.get_frame_time].
159 *
160 * Returns: the frame time for the frame, in the timescale
161 * of g_get_monotonic_time()
162 */
163gint64
164gdk_frame_timings_get_frame_time (GdkFrameTimings *timings)
165{
166 g_return_val_if_fail (timings != NULL, 0);
167
168 return timings->frame_time;
169}
170
171/**
172 * gdk_frame_timings_get_presentation_time:
173 * @timings: a `GdkFrameTimings`
174 *
175 * Reurns the presentation time.
176 *
177 * This is the time at which the frame became visible to the user.
178 *
179 * Returns: the time the frame was displayed to the user, in the
180 * timescale of g_get_monotonic_time(), or 0 if no presentation
181 * time is available. See [method@Gdk.FrameTimings.get_complete]
182 */
183gint64
184gdk_frame_timings_get_presentation_time (GdkFrameTimings *timings)
185{
186 g_return_val_if_fail (timings != NULL, 0);
187
188 return timings->presentation_time;
189}
190
191/**
192 * gdk_frame_timings_get_predicted_presentation_time:
193 * @timings: a `GdkFrameTimings`
194 *
195 * Gets the predicted time at which this frame will be displayed.
196 *
197 * Although no predicted time may be available, if one is available,
198 * it will be available while the frame is being generated, in contrast
199 * to [method@Gdk.FrameTimings.get_presentation_time], which is only
200 * available after the frame has been presented.
201 *
202 * In general, if you are simply animating, you should use
203 * [method@Gdk.FrameClock.get_frame_time] rather than this function,
204 * but this function is useful for applications that want exact control
205 * over latency. For example, a movie player may want this information
206 * for Audio/Video synchronization.
207 *
208 * Returns: The predicted time at which the frame will be presented,
209 * in the timescale of g_get_monotonic_time(), or 0 if no predicted
210 * presentation time is available.
211 */
212gint64
213gdk_frame_timings_get_predicted_presentation_time (GdkFrameTimings *timings)
214{
215 g_return_val_if_fail (timings != NULL, 0);
216
217 return timings->predicted_presentation_time;
218}
219
220/**
221 * gdk_frame_timings_get_refresh_interval:
222 * @timings: a `GdkFrameTimings`
223 *
224 * Gets the natural interval between presentation times for
225 * the display that this frame was displayed on.
226 *
227 * Frame presentation usually happens during the “vertical
228 * blanking interval”.
229 *
230 * Returns: the refresh interval of the display, in microseconds,
231 * or 0 if the refresh interval is not available.
232 * See [method@Gdk.FrameTimings.get_complete].
233 */
234gint64
235gdk_frame_timings_get_refresh_interval (GdkFrameTimings *timings)
236{
237 g_return_val_if_fail (timings != NULL, 0);
238
239 return timings->refresh_interval;
240}
241

source code of gtk/gdk/gdkframetimings.c