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 | |
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 |
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 | */ |
76 | GdkFrameTimings * |
77 | gdk_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 | */ |
94 | void |
95 | gdk_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 | */ |
116 | gint64 |
117 | gdk_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 | */ |
143 | gboolean |
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. |
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 | */ |
163 | gint64 |
164 | gdk_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 | */ |
183 | gint64 |
184 | gdk_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 | */ |
212 | gint64 |
213 | gdk_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 | */ |
234 | gint64 |
235 | gdk_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 | |