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
G_DEFINE_BOXED_TYPE(GdkFrameTimings,gdk_frame_timings,gdk_frame_timings_ref,gdk_frame_timings_unref)37 G_DEFINE_BOXED_TYPE (GdkFrameTimings, gdk_frame_timings,
38 gdk_frame_timings_ref,
39 gdk_frame_timings_unref)
40
41 GdkFrameTimings *
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
53 gboolean
_gdk_frame_timings_steal(GdkFrameTimings * timings,gint64 frame_counter)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 */
77 GdkFrameTimings *
gdk_frame_timings_ref(GdkFrameTimings * timings)78 gdk_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 */
96 void
gdk_frame_timings_unref(GdkFrameTimings * timings)97 gdk_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 */
119 gint64
gdk_frame_timings_get_frame_counter(GdkFrameTimings * timings)120 gdk_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 */
143 gboolean
gdk_frame_timings_get_complete(GdkFrameTimings * timings)144 gdk_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 */
162 gint64
gdk_frame_timings_get_frame_time(GdkFrameTimings * timings)163 gdk_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 */
182 gint64
gdk_frame_timings_get_presentation_time(GdkFrameTimings * timings)183 gdk_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 */
209 gint64
gdk_frame_timings_get_predicted_presentation_time(GdkFrameTimings * timings)210 gdk_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 */
230 gint64
gdk_frame_timings_get_refresh_interval(GdkFrameTimings * timings)231 gdk_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