gdkframetimings.c 6.71 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* GDK - The GIMP Drawing Kit
 * Copyright (C) 2012 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */

#include "config.h"

20 21
#include <string.h>

22
#include "gdkframeclockprivate.h"
23

24
/**
25
 * SECTION:gdkframetimings
26 27 28 29
 * @Short_description: Object holding timing information for a single frame
 * @Title: Frame timings
 *
 * A #GdkFrameTimings object holds timing information for a single frame
30
 * of the application’s displays. To retrieve #GdkFrameTimings objects,
31 32 33
 * use gdk_frame_clock_get_timings() or gdk_frame_clock_get_current_timings().
 * The information in #GdkFrameTimings is useful for precise synchronization
 * 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
 */

37 38 39 40 41
G_DEFINE_BOXED_TYPE (GdkFrameTimings, gdk_frame_timings,
                     gdk_frame_timings_ref,
                     gdk_frame_timings_unref)

GdkFrameTimings *
42
_gdk_frame_timings_new (gint64 frame_counter)
43 44 45 46 47 48 49 50 51 52
{
  GdkFrameTimings *timings;

  timings = g_slice_new0 (GdkFrameTimings);
  timings->ref_count = 1;
  timings->frame_counter = frame_counter;

  return timings;
}

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
gboolean
_gdk_frame_timings_steal (GdkFrameTimings *timings,
                          gint64           frame_counter)
{
  if (timings->ref_count == 1)
    {
      memset (timings, 0, sizeof *timings);
      timings->ref_count = 1;
      timings->frame_counter = frame_counter;
      return TRUE;
    }

  return FALSE;
}

68 69 70 71 72 73 74 75 76
/**
 * gdk_frame_timings_ref:
 * @timings: a #GdkFrameTimings
 *
 * Increases the reference count of @timings.
 *
 * Returns: @timings
 * Since: 3.8
 */
77 78 79 80 81 82 83 84 85 86
GdkFrameTimings *
gdk_frame_timings_ref (GdkFrameTimings *timings)
{
  g_return_val_if_fail (timings != NULL, NULL);

  timings->ref_count++;

  return timings;
}

87 88 89 90 91 92 93 94 95
/**
 * gdk_frame_timings_unref:
 * @timings: a #GdkFrameTimings
 *
 * Decreases the reference count of @timings. If @timings
 * is no longer referenced, it will be freed.
 *
 * Since: 3.8
 */
96 97 98 99 100 101 102 103 104 105 106 107 108
void
gdk_frame_timings_unref (GdkFrameTimings *timings)
{
  g_return_if_fail (timings != NULL);
  g_return_if_fail (timings->ref_count > 0);

  timings->ref_count--;
  if (timings->ref_count == 0)
    {
      g_slice_free (GdkFrameTimings, timings);
    }
}

109 110 111 112 113 114 115 116 117 118
/**
 * gdk_frame_timings_get_frame_counter:
 * @timings: a #GdkFrameTimings
 *
 * Gets the frame counter value of the #GdkFrameClock when this
 * this frame was drawn.
 *
 * Returns: the frame counter value for this frame
 * Since: 3.8
 */
119 120 121 122 123 124
gint64
gdk_frame_timings_get_frame_counter (GdkFrameTimings *timings)
{
  return timings->frame_counter;
}

125
/**
126
 * gdk_frame_timings_get_complete:
127 128 129 130 131 132 133 134
 * @timings: a #GdkFrameTimings
 *
 * The timing information in a #GdkFrameTimings is filled in
 * incrementally as the frame as drawn and passed off to the
 * window system for processing and display to the user. The
 * accessor functions for #GdkFrameTimings can return 0 to
 * indicate an unavailable value for two reasons: either because
 * the information is not yet available, or because it isn't
135
 * available at all. Once gdk_frame_timings_get_complete() returns
136 137 138 139 140 141 142
 * %TRUE for a frame, you can be certain that no further values
 * will become available and be stored in the #GdkFrameTimings.
 *
 * Returns: %TRUE if all information that will be available
 *  for the frame has been filled in.
 * Since: 3.8
 */
143 144 145 146 147 148 149 150
gboolean
gdk_frame_timings_get_complete (GdkFrameTimings *timings)
{
  g_return_val_if_fail (timings != NULL, FALSE);

  return timings->complete;
}

151 152 153 154 155 156 157 158 159 160 161
/**
 * gdk_frame_timings_get_frame_time:
 * @timings: A #GdkFrameTimings
 *
 * Returns the frame time for the frame. This is the time value
 * that is typically used to time animations for the frame. See
 * gdk_frame_clock_get_frame_time().
 *
 * Returns: the frame time for the frame, in the timescale
 *  of g_get_monotonic_time()
 */
162 163 164 165 166 167 168 169
gint64
gdk_frame_timings_get_frame_time (GdkFrameTimings *timings)
{
  g_return_val_if_fail (timings != NULL, 0);

  return timings->frame_time;
}

170 171 172 173 174 175 176 177 178 179 180 181
/**
 * gdk_frame_timings_get_presentation_time:
 * @timings: a #GdkFrameTimings
 *
 * Reurns the presentation time. This is the time at which the frame
 * became visible to the user.
 *
 * Returns: the time the frame was displayed to the user, in the
 *  timescale of g_get_monotonic_time(), or 0 if no presentation
 *  time is available. See gdk_frame_timings_get_complete()
 * Since: 3.8
 */
182 183 184 185 186 187 188 189
gint64
gdk_frame_timings_get_presentation_time (GdkFrameTimings *timings)
{
  g_return_val_if_fail (timings != NULL, 0);

  return timings->presentation_time;
}

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
/**
 * gdk_frame_timings_get_predicted_presentation_time:
 * @timings: a #GdkFrameTimings
 *
 * Gets the predicted time at which this frame will be displayed. Although
 * no predicted time may be available, if one is available, it will
 * be available while the frame is being generated, in contrast to
 * gdk_frame_timings_get_presentation_time(), which is only available
 * after the frame has been presented. In general, if you are simply
 * animating, you should use gdk_frame_clock_get_frame_time() rather
 * than this function, but this function is useful for applications
 * that want exact control over latency. For example, a movie player
 * may want this information for Audio/Video synchronization.
 *
 * Returns: The predicted time at which the frame will be presented,
 *  in the timescale of g_get_monotonic_time(), or 0 if no predicted
 *  presentation time is available.
 * Since: 3.8
 */
209 210 211 212 213 214 215 216
gint64
gdk_frame_timings_get_predicted_presentation_time (GdkFrameTimings *timings)
{
  g_return_val_if_fail (timings != NULL, 0);

  return timings->predicted_presentation_time;
}

217 218 219 220 221 222
/**
 * gdk_frame_timings_get_refresh_interval:
 * @timings: a #GdkFrameTimings
 *
 * Gets the natural interval between presentation times for
 * the display that this frame was displayed on. Frame presentation
223
 * usually happens during the “vertical blanking interval”.
224 225 226 227 228 229
 *
 * Returns: the refresh interval of the display, in microseconds,
 *  or 0 if the refresh interval is not available.
 *  See gdk_frame_timings_get_complete().
 * Since: 3.8
 */
230 231 232 233 234 235 236
gint64
gdk_frame_timings_get_refresh_interval (GdkFrameTimings *timings)
{
  g_return_val_if_fail (timings != NULL, 0);

  return timings->refresh_interval;
}