diff --git a/clutter/clutter/clutter-frame-private.h b/clutter/clutter/clutter-frame-private.h
new file mode 100644
index 000000000..e0088564f
--- /dev/null
+++ b/clutter/clutter/clutter-frame-private.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 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 .
+ */
+
+#ifndef CLUTTER_FRAME_PRIVATE_H
+#define CLUTTER_FRAME_PRIVATE_H
+
+#include "clutter/clutter-frame.h"
+
+struct _ClutterFrame
+{
+ gboolean has_result;
+ ClutterFrameResult result;
+};
+
+#define CLUTTER_FRAME_INIT ((ClutterFrame) { 0 })
+
+ClutterFrameResult clutter_frame_get_result (ClutterFrame *frame);
+
+#endif /* CLUTTER_FRAME_PRIVATE_H */
diff --git a/clutter/clutter/clutter-frame.c b/clutter/clutter/clutter-frame.c
new file mode 100644
index 000000000..3c708da9d
--- /dev/null
+++ b/clutter/clutter/clutter-frame.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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 .
+ */
+
+#include "clutter/clutter-frame-private.h"
+
+ClutterFrameResult
+clutter_frame_get_result (ClutterFrame *frame)
+{
+ g_return_val_if_fail (frame->has_result, CLUTTER_FRAME_RESULT_IDLE);
+
+ return frame->result;
+}
+
+gboolean
+clutter_frame_has_result (ClutterFrame *frame)
+{
+ return frame->has_result;
+}
+
+void
+clutter_frame_set_result (ClutterFrame *frame,
+ ClutterFrameResult result)
+{
+ g_warn_if_fail (!frame->has_result);
+
+ frame->result = result;
+ frame->has_result = TRUE;
+}
diff --git a/clutter/clutter/clutter-frame.h b/clutter/clutter/clutter-frame.h
new file mode 100644
index 000000000..d3608e81c
--- /dev/null
+++ b/clutter/clutter/clutter-frame.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 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 .
+ */
+
+#ifndef CLUTTER_FRAME_H
+#define CLUTTER_FRAME_H
+
+#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "clutter/clutter-frame-clock.h"
+
+typedef struct _ClutterFrame ClutterFrame;
+
+CLUTTER_EXPORT
+void clutter_frame_set_result (ClutterFrame *frame,
+ ClutterFrameResult result);
+
+CLUTTER_EXPORT
+gboolean clutter_frame_has_result (ClutterFrame *frame);
+
+#endif /* CLUTTER_FRAME_H */
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 2b12b93ed..81662de06 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -25,6 +25,7 @@
#include "clutter/clutter-damage-history.h"
#include "clutter/clutter-frame-clock.h"
+#include "clutter/clutter-frame-private.h"
#include "clutter/clutter-private.h"
#include "clutter/clutter-mutter.h"
#include "clutter/clutter-stage-private.h"
@@ -1076,7 +1077,7 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
ClutterStage *stage = priv->stage;
ClutterStageWindow *stage_window = _clutter_stage_get_window (stage);
g_autoptr (GSList) devices = NULL;
- ClutterFrameResult result;
+ ClutterFrame frame;
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
return CLUTTER_FRAME_RESULT_IDLE;
@@ -1096,29 +1097,25 @@ handle_frame_clock_frame (ClutterFrameClock *frame_clock,
devices = clutter_stage_find_updated_devices (stage);
+ frame = CLUTTER_FRAME_INIT;
+
if (clutter_stage_view_has_redraw_clip (view))
{
clutter_stage_emit_before_paint (stage, view);
- _clutter_stage_window_redraw_view (stage_window, view);
+ _clutter_stage_window_redraw_view (stage_window, view, &frame);
clutter_stage_emit_after_paint (stage, view);
-
- result = CLUTTER_FRAME_RESULT_PENDING_PRESENTED;
- }
- else
- {
- result = CLUTTER_FRAME_RESULT_IDLE;
}
- _clutter_stage_window_finish_frame (stage_window, view);
+ _clutter_stage_window_finish_frame (stage_window, view, &frame);
clutter_stage_update_devices (stage, devices);
_clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_POST_PAINT);
clutter_stage_emit_after_update (stage, view);
- return result;
+ return clutter_frame_get_result (&frame);
}
static const ClutterFrameListenerIface frame_clock_listener_iface = {
diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
index 2d3192df0..5f7c48967 100644
--- a/clutter/clutter/clutter-stage-window.c
+++ b/clutter/clutter/clutter-stage-window.c
@@ -3,6 +3,7 @@
#include
#include "clutter-actor.h"
+#include "clutter-frame.h"
#include "clutter-stage-window.h"
#include "clutter-private.h"
@@ -104,11 +105,12 @@ _clutter_stage_window_get_geometry (ClutterStageWindow *window,
void
_clutter_stage_window_redraw_view (ClutterStageWindow *window,
- ClutterStageView *view)
+ ClutterStageView *view,
+ ClutterFrame *frame)
{
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
- CLUTTER_STAGE_WINDOW_GET_IFACE (window)->redraw_view (window, view);
+ CLUTTER_STAGE_WINDOW_GET_IFACE (window)->redraw_view (window, view, frame);
}
gboolean
@@ -135,12 +137,19 @@ _clutter_stage_window_get_views (ClutterStageWindow *window)
void
_clutter_stage_window_finish_frame (ClutterStageWindow *window,
- ClutterStageView *view)
+ ClutterStageView *view,
+ ClutterFrame *frame)
{
ClutterStageWindowInterface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
if (iface->finish_frame)
- iface->finish_frame (window, view);
+ {
+ iface->finish_frame (window, view, frame);
+ return;
+ }
+
+ if (!clutter_frame_has_result (frame))
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
}
int64_t
diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
index 0f2d5bc28..b1ebd2bad 100644
--- a/clutter/clutter/clutter-stage-window.h
+++ b/clutter/clutter/clutter-stage-window.h
@@ -45,14 +45,16 @@ struct _ClutterStageWindowInterface
cairo_rectangle_int_t *geometry);
void (* redraw_view) (ClutterStageWindow *stage_window,
- ClutterStageView *view);
+ ClutterStageView *view,
+ ClutterFrame *frame);
gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window);
GList *(* get_views) (ClutterStageWindow *stage_window);
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
void (* finish_frame) (ClutterStageWindow *stage_window,
- ClutterStageView *view);
+ ClutterStageView *view,
+ ClutterFrame *frame);
};
ClutterActor * _clutter_stage_window_get_wrapper (ClutterStageWindow *window);
@@ -80,14 +82,16 @@ void _clutter_stage_window_set_accept_focus (ClutterStageWin
gboolean accept_focus);
void _clutter_stage_window_redraw_view (ClutterStageWindow *window,
- ClutterStageView *view);
+ ClutterStageView *view,
+ ClutterFrame *frame);
gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window);
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
void _clutter_stage_window_finish_frame (ClutterStageWindow *window,
- ClutterStageView *view);
+ ClutterStageView *view,
+ ClutterFrame *frame);
int64_t _clutter_stage_window_get_frame_counter (ClutterStageWindow *window);
diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h
index 1453eaaad..569e36604 100644
--- a/clutter/clutter/clutter-types.h
+++ b/clutter/clutter/clutter-types.h
@@ -46,6 +46,7 @@ G_BEGIN_DECLS
typedef struct _ClutterActor ClutterActor;
typedef struct _ClutterStage ClutterStage;
+typedef struct _ClutterFrame ClutterFrame;
typedef struct _ClutterFrameInfo ClutterFrameInfo;
typedef struct _ClutterContainer ClutterContainer; /* dummy */
typedef struct _ClutterChildMeta ClutterChildMeta;
diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h
index d09f8afed..9b97cfc9e 100644
--- a/clutter/clutter/clutter.h
+++ b/clutter/clutter/clutter.h
@@ -64,6 +64,7 @@
#include "clutter-fixed-layout.h"
#include "clutter-flow-layout.h"
#include "clutter-frame-clock.h"
+#include "clutter-frame.h"
#include "clutter-gesture-action.h"
#include "clutter-grid-layout.h"
#include "clutter-image.h"
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index ffc13bad7..02b13781a 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -43,6 +43,7 @@
#include "clutter-event.h"
#include "clutter-enum-types.h"
#include "clutter-feature.h"
+#include "clutter-frame.h"
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
@@ -693,7 +694,8 @@ clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl,
static void
clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
- ClutterStageView *view)
+ ClutterStageView *view,
+ ClutterFrame *frame)
{
ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
g_autoptr (CoglScanout) scanout = NULL;
@@ -710,6 +712,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
clutter_stage_cogl_redraw_view_primary (stage_cogl, view);
+
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
}
static void
diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build
index 4b617bd98..9f20d7ba3 100644
--- a/clutter/clutter/meson.build
+++ b/clutter/clutter/meson.build
@@ -37,6 +37,7 @@ clutter_headers = [
'clutter-fixed-layout.h',
'clutter-flow-layout.h',
'clutter-frame-clock.h',
+ 'clutter-frame.h',
'clutter-gesture-action.h',
'clutter-grid-layout.h',
'clutter-image.h',
@@ -125,6 +126,7 @@ clutter_sources = [
'clutter-flatten-effect.c',
'clutter-flow-layout.c',
'clutter-frame-clock.c',
+ 'clutter-frame.c',
'clutter-gesture-action.c',
'clutter-graphene.c',
'clutter-grid-layout.c',
@@ -194,6 +196,7 @@ clutter_private_headers = [
'clutter-effect-private.h',
'clutter-event-private.h',
'clutter-flatten-effect.h',
+ 'clutter-frame-private.h',
'clutter-graphene.h',
'clutter-gesture-action-private.h',
'clutter-id-pool.h',
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
index 00c868c42..2a29f9312 100644
--- a/src/backends/native/meta-stage-native.c
+++ b/src/backends/native/meta-stage-native.c
@@ -107,12 +107,16 @@ meta_stage_native_get_views (ClutterStageWindow *stage_window)
static void
meta_stage_native_finish_frame (ClutterStageWindow *stage_window,
- ClutterStageView *stage_view)
+ ClutterStageView *stage_view,
+ ClutterFrame *frame)
{
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
meta_renderer_native_finish_frame (META_RENDERER_NATIVE (renderer));
+
+ if (!clutter_frame_has_result (frame))
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
}
static void
diff --git a/src/backends/x11/nested/meta-stage-x11-nested.c b/src/backends/x11/nested/meta-stage-x11-nested.c
index 6dfd7cb2f..4f3f5b796 100644
--- a/src/backends/x11/nested/meta-stage-x11-nested.c
+++ b/src/backends/x11/nested/meta-stage-x11-nested.c
@@ -159,7 +159,8 @@ draw_view (MetaStageX11Nested *stage_nested,
static void
meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window,
- ClutterStageView *stage_view)
+ ClutterStageView *stage_view,
+ ClutterFrame *frame)
{
MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window);
MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window);
@@ -196,6 +197,9 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window,
frame_info = cogl_frame_info_new (0);
cogl_onscreen_swap_buffers (stage_x11->onscreen, frame_info);
+
+ if (!clutter_frame_has_result (frame))
+ clutter_frame_set_result (frame, CLUTTER_FRAME_RESULT_IDLE);
}
static void