2012-11-14 17:49:06 +00:00
|
|
|
|
/* 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"
|
|
|
|
|
|
2016-04-26 10:08:11 +00:00
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2013-02-12 21:14:24 +00:00
|
|
|
|
#include "gdkframeclockprivate.h"
|
2012-11-14 17:49:06 +00:00
|
|
|
|
|
2017-12-26 19:39:24 +00:00
|
|
|
|
/**
|
|
|
|
|
* GdkFrameTimings:
|
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* A `GdkFrameTimings` object holds timing information for a single frame
|
|
|
|
|
* of the application’s displays.
|
|
|
|
|
*
|
|
|
|
|
* To retrieve `GdkFrameTimings` objects, use [method@Gdk.FrameClock.get_timings]
|
|
|
|
|
* or [method@Gdk.FrameClock.get_current_timings]. The information in
|
|
|
|
|
* `GdkFrameTimings` is useful for precise synchronization of video with
|
|
|
|
|
* the event or audio streams, and for measuring quality metrics for the
|
|
|
|
|
* application’s display, such as latency and jitter.
|
2017-12-26 19:39:24 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2012-11-14 17:49:06 +00:00
|
|
|
|
G_DEFINE_BOXED_TYPE (GdkFrameTimings, gdk_frame_timings,
|
|
|
|
|
gdk_frame_timings_ref,
|
|
|
|
|
gdk_frame_timings_unref)
|
|
|
|
|
|
|
|
|
|
GdkFrameTimings *
|
2013-02-12 21:14:24 +00:00
|
|
|
|
_gdk_frame_timings_new (gint64 frame_counter)
|
2012-11-14 17:49:06 +00:00
|
|
|
|
{
|
|
|
|
|
GdkFrameTimings *timings;
|
|
|
|
|
|
|
|
|
|
timings = g_slice_new0 (GdkFrameTimings);
|
|
|
|
|
timings->ref_count = 1;
|
|
|
|
|
timings->frame_counter = frame_counter;
|
|
|
|
|
|
|
|
|
|
return timings;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-26 10:08:11 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_ref:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: a `GdkFrameTimings`
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Increases the reference count of @timings.
|
|
|
|
|
*
|
|
|
|
|
* Returns: @timings
|
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
GdkFrameTimings *
|
|
|
|
|
gdk_frame_timings_ref (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (timings != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
timings->ref_count++;
|
|
|
|
|
|
|
|
|
|
return timings;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_unref:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: a `GdkFrameTimings`
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* Decreases the reference count of @timings.
|
|
|
|
|
*
|
|
|
|
|
* If @timings is no longer referenced, it will be freed.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_get_frame_counter:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: a `GdkFrameTimings`
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* Gets the frame counter value of the `GdkFrameClock` when
|
2013-02-12 23:26:17 +00:00
|
|
|
|
* this frame was drawn.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the frame counter value for this frame
|
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
gint64
|
|
|
|
|
gdk_frame_timings_get_frame_counter (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
return timings->frame_counter;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
2013-02-25 09:57:34 +00:00
|
|
|
|
* gdk_frame_timings_get_complete:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: a `GdkFrameTimings`
|
|
|
|
|
*
|
|
|
|
|
* Returns whether @timings are complete.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* The timing information in a `GdkFrameTimings` is filled in
|
2013-02-12 23:26:17 +00:00
|
|
|
|
* incrementally as the frame as drawn and passed off to the
|
|
|
|
|
* window system for processing and display to the user. The
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* accessor functions for `GdkFrameTimings` can return 0 to
|
2013-02-12 23:26:17 +00:00
|
|
|
|
* indicate an unavailable value for two reasons: either because
|
|
|
|
|
* the information is not yet available, or because it isn't
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* available at all.
|
|
|
|
|
*
|
|
|
|
|
* Once this function returns %TRUE for a frame, you can be
|
|
|
|
|
* certain that no further values will become available and be
|
|
|
|
|
* stored in the `GdkFrameTimings`.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if all information that will be available
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* for the frame has been filled in.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
gboolean
|
|
|
|
|
gdk_frame_timings_get_complete (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (timings != NULL, FALSE);
|
|
|
|
|
|
|
|
|
|
return timings->complete;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_get_frame_time:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: A `GdkFrameTimings`
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* Returns the frame time for the frame.
|
|
|
|
|
*
|
|
|
|
|
* This is the time value that is typically used to time
|
|
|
|
|
* animations for the frame. See [method@Gdk.FrameClock.get_frame_time].
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Returns: the frame time for the frame, in the timescale
|
|
|
|
|
* of g_get_monotonic_time()
|
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
gint64
|
|
|
|
|
gdk_frame_timings_get_frame_time (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (timings != NULL, 0);
|
|
|
|
|
|
|
|
|
|
return timings->frame_time;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_get_presentation_time:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: a `GdkFrameTimings`
|
|
|
|
|
*
|
|
|
|
|
* Reurns the presentation time.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* This is the time at which the frame became visible to the user.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Returns: the time the frame was displayed to the user, in the
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* timescale of g_get_monotonic_time(), or 0 if no presentation
|
|
|
|
|
* time is available. See [method@Gdk.FrameTimings.get_complete]
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
gint64
|
|
|
|
|
gdk_frame_timings_get_presentation_time (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (timings != NULL, 0);
|
|
|
|
|
|
|
|
|
|
return timings->presentation_time;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_get_predicted_presentation_time:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @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 [method@Gdk.FrameTimings.get_presentation_time], which is only
|
|
|
|
|
* available after the frame has been presented.
|
|
|
|
|
*
|
|
|
|
|
* In general, if you are simply animating, you should use
|
|
|
|
|
* [method@Gdk.FrameClock.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.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Returns: The predicted time at which the frame will be presented,
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* in the timescale of g_get_monotonic_time(), or 0 if no predicted
|
|
|
|
|
* presentation time is available.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*/
|
2012-11-15 19:11:41 +00:00
|
|
|
|
gint64
|
|
|
|
|
gdk_frame_timings_get_predicted_presentation_time (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (timings != NULL, 0);
|
|
|
|
|
|
|
|
|
|
return timings->predicted_presentation_time;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-12 23:26:17 +00:00
|
|
|
|
/**
|
|
|
|
|
* gdk_frame_timings_get_refresh_interval:
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* @timings: a `GdkFrameTimings`
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Gets the natural interval between presentation times for
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* the display that this frame was displayed on.
|
|
|
|
|
*
|
|
|
|
|
* Frame presentation usually happens during the “vertical
|
|
|
|
|
* blanking interval”.
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*
|
|
|
|
|
* Returns: the refresh interval of the display, in microseconds,
|
2021-02-21 05:13:57 +00:00
|
|
|
|
* or 0 if the refresh interval is not available.
|
|
|
|
|
* See [method@Gdk.FrameTimings.get_complete].
|
2013-02-12 23:26:17 +00:00
|
|
|
|
*/
|
2012-11-14 17:49:06 +00:00
|
|
|
|
gint64
|
|
|
|
|
gdk_frame_timings_get_refresh_interval (GdkFrameTimings *timings)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (timings != NULL, 0);
|
|
|
|
|
|
|
|
|
|
return timings->refresh_interval;
|
|
|
|
|
}
|