clutter/frame-clock: Pass ClutterFrame via the frame clock interface

Let the ClutterFrame live for the whole frame, and be carried as an
argument to the frame clock listener interface functions.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2795>
This commit is contained in:
Jonas Ådahl 2022-07-06 23:59:46 +02:00
parent 1c574068e0
commit 916b21674e
8 changed files with 49 additions and 41 deletions

View File

@ -20,6 +20,7 @@
#include "clutter/clutter-frame-clock.h"
#include "clutter/clutter-debug.h"
#include "clutter/clutter-frame-private.h"
#include "clutter/clutter-main.h"
#include "clutter/clutter-private.h"
#include "clutter/clutter-timeline-private.h"
@ -691,6 +692,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
int64_t time_us)
{
const ClutterFrameListenerIface *iface = frame_clock->listener.iface;
g_autoptr (ClutterFrame) frame = NULL;
int64_t frame_count;
ClutterFrameResult result;
int64_t ideal_dispatch_time_us, lateness_us;
@ -729,13 +731,12 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
frame_count = frame_clock->frame_count++;
frame = g_new0 (ClutterFrame, 1);
frame->frame_count = frame_count;
COGL_TRACE_BEGIN (ClutterFrameClockEvents, "Frame Clock (before frame)");
if (iface->before_frame)
{
iface->before_frame (frame_clock,
frame_count,
frame_clock->listener.user_data);
}
iface->before_frame (frame_clock, frame, frame_clock->listener.user_data);
COGL_TRACE_END (ClutterFrameClockEvents);
COGL_TRACE_BEGIN (ClutterFrameClockTimelines, "Frame Clock (timelines)");
@ -745,9 +746,7 @@ clutter_frame_clock_dispatch (ClutterFrameClock *frame_clock,
COGL_TRACE_END (ClutterFrameClockTimelines);
COGL_TRACE_BEGIN (ClutterFrameClockFrame, "Frame Clock (frame)");
result = iface->frame (frame_clock,
frame_count,
frame_clock->listener.user_data);
result = iface->frame (frame_clock, frame, frame_clock->listener.user_data);
COGL_TRACE_END (ClutterFrameClockFrame);
switch (frame_clock->state)

View File

@ -46,10 +46,10 @@ G_DECLARE_FINAL_TYPE (ClutterFrameClock, clutter_frame_clock,
typedef struct _ClutterFrameListenerIface
{
void (* before_frame) (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data);
ClutterFrameResult (* frame) (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data);
} ClutterFrameListenerIface;

View File

@ -22,12 +22,12 @@
struct _ClutterFrame
{
int64_t frame_count;
gboolean has_result;
ClutterFrameResult result;
};
#define CLUTTER_FRAME_INIT ((ClutterFrame) { 0 })
ClutterFrameResult clutter_frame_get_result (ClutterFrame *frame);
#endif /* CLUTTER_FRAME_PRIVATE_H */

View File

@ -17,6 +17,12 @@
#include "clutter/clutter-frame-private.h"
int64_t
clutter_frame_get_count (ClutterFrame *frame)
{
return frame->frame_count;
}
ClutterFrameResult
clutter_frame_get_result (ClutterFrame *frame)
{

View File

@ -26,6 +26,9 @@
typedef struct _ClutterFrame ClutterFrame;
CLUTTER_EXPORT
int64_t clutter_frame_get_count (ClutterFrame *frame);
CLUTTER_EXPORT
void clutter_frame_set_result (ClutterFrame *frame,
ClutterFrameResult result);
@ -33,4 +36,6 @@ void clutter_frame_set_result (ClutterFrame *frame,
CLUTTER_EXPORT
gboolean clutter_frame_has_result (ClutterFrame *frame);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFrame, g_free)
#endif /* CLUTTER_FRAME_H */

View File

@ -1131,7 +1131,7 @@ clutter_stage_view_has_shadowfb (ClutterStageView *view)
static void
handle_frame_clock_before_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
ClutterStageView *view = user_data;
@ -1207,7 +1207,7 @@ end_frame_timing_measurement (ClutterStageView *view)
static ClutterFrameResult
handle_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
ClutterStageView *view = user_data;
@ -1216,7 +1216,6 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
ClutterStage *stage = priv->stage;
ClutterStageWindow *stage_window = _clutter_stage_get_window (stage);
g_autoptr (GSList) devices = NULL;
ClutterFrame frame;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return CLUTTER_FRAME_RESULT_IDLE;
@ -1241,16 +1240,14 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
if (priv->needs_update_devices)
devices = clutter_stage_find_updated_devices (stage, view);
frame = CLUTTER_FRAME_INIT;
_clutter_stage_window_prepare_frame (stage_window, view, &frame);
_clutter_stage_window_prepare_frame (stage_window, view, frame);
clutter_stage_emit_prepare_frame (stage, view);
if (clutter_stage_view_has_redraw_clip (view))
{
clutter_stage_emit_before_paint (stage, view);
_clutter_stage_window_redraw_view (stage_window, view, &frame);
_clutter_stage_window_redraw_view (stage_window, view, frame);
clutter_frame_clock_record_flip_time (frame_clock,
g_get_monotonic_time ());
@ -1261,7 +1258,7 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
end_frame_timing_measurement (view);
}
_clutter_stage_window_finish_frame (stage_window, view, &frame);
_clutter_stage_window_finish_frame (stage_window, view, frame);
clutter_stage_update_devices (stage, devices);
priv->needs_update_devices = FALSE;
@ -1269,7 +1266,7 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
_clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_POST_PAINT);
clutter_stage_emit_after_update (stage, view);
return clutter_frame_get_result (&frame);
return clutter_frame_get_result (frame);
}
static const ClutterFrameListenerIface frame_clock_listener_iface = {

View File

@ -6,7 +6,7 @@ static const int64_t refresh_interval_us = G_USEC_PER_SEC / refresh_rate;
static ClutterFrameResult
timeline_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
ClutterFrameInfo frame_info;

View File

@ -1,4 +1,5 @@
#include "clutter/clutter.h"
#include "clutter/clutter-frame.h"
#include "tests/clutter-test-utils.h"
static const float refresh_rate = 60.0;
@ -91,13 +92,13 @@ fake_hw_clock_new (ClutterFrameClock *frame_clock,
static ClutterFrameResult
frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
FrameClockTest *test = user_data;
GMainLoop *main_loop = test->main_loop;
g_assert_cmpint (frame_count, ==, expected_frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, expected_frame_count);
expected_frame_count++;
@ -185,13 +186,13 @@ schedule_update_idle (gpointer user_data)
static ClutterFrameResult
immediate_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
GMainLoop *main_loop = user_data;
ClutterFrameInfo frame_info;
g_assert_cmpint (frame_count, ==, expected_frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, expected_frame_count);
expected_frame_count++;
@ -259,13 +260,13 @@ schedule_update_timeout (gpointer user_data)
static ClutterFrameResult
delayed_damage_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
FrameClockTest *test = user_data;
GMainLoop *main_loop = test->main_loop;
g_assert_cmpint (frame_count, ==, expected_frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, expected_frame_count);
expected_frame_count++;
@ -332,7 +333,7 @@ frame_clock_delayed_damage (void)
static ClutterFrameResult
no_damage_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
g_assert_not_reached ();
@ -385,13 +386,13 @@ typedef struct _UpdateNowFrameClockTest
static ClutterFrameResult
update_now_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
UpdateNowFrameClockTest *test = user_data;
GMainLoop *main_loop = test->base.main_loop;
g_assert_cmpint (frame_count, ==, expected_frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, expected_frame_count);
expected_frame_count++;
@ -481,23 +482,23 @@ frame_clock_schedule_update_now (void)
static void
before_frame_frame_clock_before_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
int64_t *expected_frame_count = user_data;
g_assert_cmpint (*expected_frame_count, ==, frame_count);
g_assert_cmpint (*expected_frame_count, ==, clutter_frame_get_count (frame));
}
static ClutterFrameResult
before_frame_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
int64_t *expected_frame_count = user_data;
ClutterFrameInfo frame_info;
g_assert_cmpint (*expected_frame_count, ==, frame_count);
g_assert_cmpint (*expected_frame_count, ==, clutter_frame_get_count (frame));
(*expected_frame_count)++;
@ -560,13 +561,13 @@ typedef struct _InhibitTest
static ClutterFrameResult
inhibit_frame_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
InhibitTest *test = user_data;
ClutterFrameInfo frame_info;
g_assert_cmpint (frame_count, ==, test->frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, test->frame_count);
test->frame_count++;
@ -637,13 +638,13 @@ typedef struct _RescheduleOnIdleFrameClockTest
static ClutterFrameResult
reschedule_on_idle_clock_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
RescheduleOnIdleFrameClockTest *test = user_data;
GMainLoop *main_loop = test->base.main_loop;
g_assert_cmpint (frame_count, ==, expected_frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, expected_frame_count);
expected_frame_count++;
@ -764,12 +765,12 @@ notify_ready_and_schedule_update_idle (gpointer user_data)
static ClutterFrameResult
frame_clock_ready_frame (ClutterFrameClock *frame_clock,
int64_t frame_count,
ClutterFrame *frame,
gpointer user_data)
{
GMainLoop *main_loop = user_data;
g_assert_cmpint (frame_count, ==, expected_frame_count);
g_assert_cmpint (clutter_frame_get_count (frame), ==, expected_frame_count);
expected_frame_count++;