clutter: Enable triple buffering and adapt the KMS render tests
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
This commit is contained in:

committed by
Marge Bot

parent
394bf5ab24
commit
463fc8b92c
@ -977,8 +977,7 @@ clutter_frame_clock_uninhibit (ClutterFrameClock *frame_clock)
|
|||||||
static gboolean
|
static gboolean
|
||||||
want_triple_buffering (ClutterFrameClock *frame_clock)
|
want_triple_buffering (ClutterFrameClock *frame_clock)
|
||||||
{
|
{
|
||||||
/* disabled until test cases are updated */
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -39,22 +39,29 @@
|
|||||||
#include "tests/meta-wayland-test-driver.h"
|
#include "tests/meta-wayland-test-driver.h"
|
||||||
#include "tests/meta-wayland-test-utils.h"
|
#include "tests/meta-wayland-test-utils.h"
|
||||||
|
|
||||||
|
#define N_FRAMES_PER_TEST 30
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int number_of_frames_left;
|
int number_of_frames_left;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int n_paints;
|
int n_frames_started;
|
||||||
uint32_t fb_id;
|
int n_presentations;
|
||||||
|
int n_direct_scanouts;
|
||||||
|
GList *fb_ids;
|
||||||
|
gboolean wait_for_scanout;
|
||||||
|
gboolean expect_double_buffering;
|
||||||
} scanout;
|
} scanout;
|
||||||
|
|
||||||
gboolean wait_for_scanout;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
gboolean scanout_sabotaged;
|
int last_frame_started;
|
||||||
gboolean fallback_painted;
|
int last_frame_presented;
|
||||||
guint repaint_guard_id;
|
int frame_sabotaged;
|
||||||
|
int first_scanout;
|
||||||
|
int fallbacks_painted;
|
||||||
|
gboolean first_scanout_presented;
|
||||||
ClutterStageView *scanout_failed_view;
|
ClutterStageView *scanout_failed_view;
|
||||||
} scanout_fallback;
|
} scanout_fallback;
|
||||||
} KmsRenderingTest;
|
} KmsRenderingTest;
|
||||||
@ -101,7 +108,7 @@ meta_test_kms_render_basic (void)
|
|||||||
gulong handler_id;
|
gulong handler_id;
|
||||||
|
|
||||||
test = (KmsRenderingTest) {
|
test = (KmsRenderingTest) {
|
||||||
.number_of_frames_left = 10,
|
.number_of_frames_left = N_FRAMES_PER_TEST,
|
||||||
.loop = g_main_loop_new (NULL, FALSE),
|
.loop = g_main_loop_new (NULL, FALSE),
|
||||||
};
|
};
|
||||||
handler_id = g_signal_connect (stage, "after-update",
|
handler_id = g_signal_connect (stage, "after-update",
|
||||||
@ -116,16 +123,6 @@ meta_test_kms_render_basic (void)
|
|||||||
g_signal_handler_disconnect (stage, handler_id);
|
g_signal_handler_disconnect (stage, handler_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
on_scanout_before_update (ClutterStage *stage,
|
|
||||||
ClutterStageView *stage_view,
|
|
||||||
ClutterFrame *frame,
|
|
||||||
KmsRenderingTest *test)
|
|
||||||
{
|
|
||||||
test->scanout.n_paints = 0;
|
|
||||||
test->scanout.fb_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_scanout_before_paint (ClutterStage *stage,
|
on_scanout_before_paint (ClutterStage *stage,
|
||||||
ClutterStageView *stage_view,
|
ClutterStageView *stage_view,
|
||||||
@ -135,6 +132,9 @@ on_scanout_before_paint (ClutterStage *stage,
|
|||||||
CoglScanout *scanout;
|
CoglScanout *scanout;
|
||||||
CoglScanoutBuffer *scanout_buffer;
|
CoglScanoutBuffer *scanout_buffer;
|
||||||
MetaDrmBuffer *buffer;
|
MetaDrmBuffer *buffer;
|
||||||
|
uint32_t fb_id;
|
||||||
|
|
||||||
|
test->scanout.n_frames_started++;
|
||||||
|
|
||||||
scanout = clutter_stage_view_peek_scanout (stage_view);
|
scanout = clutter_stage_view_peek_scanout (stage_view);
|
||||||
if (!scanout)
|
if (!scanout)
|
||||||
@ -143,18 +143,13 @@ on_scanout_before_paint (ClutterStage *stage,
|
|||||||
scanout_buffer = cogl_scanout_get_buffer (scanout);
|
scanout_buffer = cogl_scanout_get_buffer (scanout);
|
||||||
g_assert_true (META_IS_DRM_BUFFER (scanout_buffer));
|
g_assert_true (META_IS_DRM_BUFFER (scanout_buffer));
|
||||||
buffer = META_DRM_BUFFER (scanout_buffer);
|
buffer = META_DRM_BUFFER (scanout_buffer);
|
||||||
test->scanout.fb_id = meta_drm_buffer_get_fb_id (buffer);
|
fb_id = meta_drm_buffer_get_fb_id (buffer);
|
||||||
g_assert_cmpuint (test->scanout.fb_id, >, 0);
|
g_assert_cmpuint (fb_id, >, 0);
|
||||||
}
|
test->scanout.fb_ids = g_list_append (test->scanout.fb_ids,
|
||||||
|
GUINT_TO_POINTER (fb_id));
|
||||||
|
|
||||||
static void
|
/* Triple buffering, but no higher */
|
||||||
on_scanout_paint_view (ClutterStage *stage,
|
g_assert_cmpuint (g_list_length (test->scanout.fb_ids), <=, 2);
|
||||||
ClutterStageView *stage_view,
|
|
||||||
MtkRegion *region,
|
|
||||||
ClutterFrame *frame,
|
|
||||||
KmsRenderingTest *test)
|
|
||||||
{
|
|
||||||
test->scanout.n_paints++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -173,13 +168,17 @@ on_scanout_presented (ClutterStage *stage,
|
|||||||
MetaDeviceFile *device_file;
|
MetaDeviceFile *device_file;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
drmModeCrtc *drm_crtc;
|
drmModeCrtc *drm_crtc;
|
||||||
|
uint32_t first_fb_id_expected;
|
||||||
|
|
||||||
if (test->wait_for_scanout && test->scanout.n_paints > 0)
|
/* Ignore frames from previous sub-tests */
|
||||||
|
if (test->scanout.n_frames_started <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (test->wait_for_scanout && test->scanout.fb_id == 0)
|
if (test->scanout.wait_for_scanout && test->scanout.fb_ids == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
test->scanout.n_presentations++;
|
||||||
|
|
||||||
device_pool = meta_backend_native_get_device_pool (backend_native);
|
device_pool = meta_backend_native_get_device_pool (backend_native);
|
||||||
|
|
||||||
fb = clutter_stage_view_get_onscreen (stage_view);
|
fb = clutter_stage_view_get_onscreen (stage_view);
|
||||||
@ -197,15 +196,37 @@ on_scanout_presented (ClutterStage *stage,
|
|||||||
drm_crtc = drmModeGetCrtc (meta_device_file_get_fd (device_file),
|
drm_crtc = drmModeGetCrtc (meta_device_file_get_fd (device_file),
|
||||||
meta_kms_crtc_get_id (kms_crtc));
|
meta_kms_crtc_get_id (kms_crtc));
|
||||||
g_assert_nonnull (drm_crtc);
|
g_assert_nonnull (drm_crtc);
|
||||||
if (test->scanout.fb_id == 0)
|
|
||||||
g_assert_cmpuint (drm_crtc->buffer_id, !=, test->scanout.fb_id);
|
/* Triple buffering remains in effect even when transitioning to
|
||||||
|
* direct scanout. So we expect the first presentation after
|
||||||
|
* wait_for_scanout will still be composited and won't match the head of
|
||||||
|
* fb_ids yet...
|
||||||
|
*/
|
||||||
|
if (test->scanout.fb_ids &&
|
||||||
|
(test->scanout.expect_double_buffering ||
|
||||||
|
test->scanout.n_presentations > 1))
|
||||||
|
{
|
||||||
|
test->scanout.n_direct_scanouts++;
|
||||||
|
first_fb_id_expected = GPOINTER_TO_UINT (test->scanout.fb_ids->data);
|
||||||
|
test->scanout.fb_ids = g_list_delete_link (test->scanout.fb_ids,
|
||||||
|
test->scanout.fb_ids);
|
||||||
|
g_assert_cmpuint (drm_crtc->buffer_id, ==, first_fb_id_expected);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g_assert_cmpuint (drm_crtc->buffer_id, ==, test->scanout.fb_id);
|
{
|
||||||
|
first_fb_id_expected = 0;
|
||||||
|
g_assert_cmpuint (drm_crtc->buffer_id, !=, first_fb_id_expected);
|
||||||
|
}
|
||||||
|
|
||||||
drmModeFreeCrtc (drm_crtc);
|
drmModeFreeCrtc (drm_crtc);
|
||||||
|
|
||||||
meta_device_file_release (device_file);
|
meta_device_file_release (device_file);
|
||||||
|
|
||||||
|
test->number_of_frames_left--;
|
||||||
|
if (test->number_of_frames_left <= 0)
|
||||||
g_main_loop_quit (test->loop);
|
g_main_loop_quit (test->loop);
|
||||||
|
else
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -226,9 +247,7 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
KmsRenderingTest test;
|
KmsRenderingTest test;
|
||||||
MetaWaylandTestClient *wayland_test_client;
|
MetaWaylandTestClient *wayland_test_client;
|
||||||
g_autoptr (MetaWaylandTestDriver) test_driver = NULL;
|
g_autoptr (MetaWaylandTestDriver) test_driver = NULL;
|
||||||
gulong before_update_handler_id;
|
|
||||||
gulong before_paint_handler_id;
|
gulong before_paint_handler_id;
|
||||||
gulong paint_view_handler_id;
|
|
||||||
gulong presented_handler_id;
|
gulong presented_handler_id;
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MtkRectangle view_rect;
|
MtkRectangle view_rect;
|
||||||
@ -244,9 +263,11 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
g_assert_nonnull (wayland_test_client);
|
g_assert_nonnull (wayland_test_client);
|
||||||
|
|
||||||
test = (KmsRenderingTest) {
|
test = (KmsRenderingTest) {
|
||||||
|
.number_of_frames_left = N_FRAMES_PER_TEST,
|
||||||
.loop = g_main_loop_new (NULL, FALSE),
|
.loop = g_main_loop_new (NULL, FALSE),
|
||||||
.wait_for_scanout = TRUE,
|
.scanout = {0},
|
||||||
};
|
};
|
||||||
|
test.scanout.wait_for_scanout = TRUE;
|
||||||
|
|
||||||
g_assert_cmpuint (g_list_length (clutter_stage_peek_stage_views (stage)),
|
g_assert_cmpuint (g_list_length (clutter_stage_peek_stage_views (stage)),
|
||||||
==,
|
==,
|
||||||
@ -254,12 +275,6 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
clutter_stage_view_get_layout (clutter_stage_peek_stage_views (stage)->data,
|
clutter_stage_view_get_layout (clutter_stage_peek_stage_views (stage)->data,
|
||||||
&view_rect);
|
&view_rect);
|
||||||
|
|
||||||
paint_view_handler_id =
|
|
||||||
g_signal_connect (stage, "paint-view",
|
|
||||||
G_CALLBACK (on_scanout_paint_view), &test);
|
|
||||||
before_update_handler_id =
|
|
||||||
g_signal_connect (stage, "before-update",
|
|
||||||
G_CALLBACK (on_scanout_before_update), &test);
|
|
||||||
before_paint_handler_id =
|
before_paint_handler_id =
|
||||||
g_signal_connect (stage, "before-paint",
|
g_signal_connect (stage, "before-paint",
|
||||||
G_CALLBACK (on_scanout_before_paint), &test);
|
G_CALLBACK (on_scanout_before_paint), &test);
|
||||||
@ -270,7 +285,8 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
g_main_loop_run (test.loop);
|
g_main_loop_run (test.loop);
|
||||||
|
|
||||||
g_assert_cmpuint (test.scanout.fb_id, >, 0);
|
g_assert_cmpint (test.scanout.n_presentations, ==, N_FRAMES_PER_TEST);
|
||||||
|
g_assert_cmpint (test.scanout.n_direct_scanouts, ==, N_FRAMES_PER_TEST - 1);
|
||||||
|
|
||||||
g_debug ("Unmake fullscreen");
|
g_debug ("Unmake fullscreen");
|
||||||
window = meta_find_window_from_title (test_context, "dma-buf-scanout-test");
|
window = meta_find_window_from_title (test_context, "dma-buf-scanout-test");
|
||||||
@ -291,11 +307,18 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
g_assert_cmpint (buffer_rect.x, ==, 10);
|
g_assert_cmpint (buffer_rect.x, ==, 10);
|
||||||
g_assert_cmpint (buffer_rect.y, ==, 10);
|
g_assert_cmpint (buffer_rect.y, ==, 10);
|
||||||
|
|
||||||
test.wait_for_scanout = FALSE;
|
test.number_of_frames_left = N_FRAMES_PER_TEST;
|
||||||
|
test.scanout.wait_for_scanout = FALSE;
|
||||||
|
test.scanout.expect_double_buffering = TRUE; /* because wait_for_sync_point */
|
||||||
|
test.scanout.n_frames_started = 0;
|
||||||
|
test.scanout.n_presentations = 0;
|
||||||
|
test.scanout.n_direct_scanouts = 0;
|
||||||
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
g_main_loop_run (test.loop);
|
g_main_loop_run (test.loop);
|
||||||
|
|
||||||
g_assert_cmpuint (test.scanout.fb_id, ==, 0);
|
g_assert_cmpint (test.scanout.n_presentations, ==, N_FRAMES_PER_TEST);
|
||||||
|
g_assert_cmpint (test.scanout.n_direct_scanouts, ==, 1);
|
||||||
|
|
||||||
g_debug ("Moving back to 0, 0");
|
g_debug ("Moving back to 0, 0");
|
||||||
meta_window_move_frame (window, TRUE, 0, 0);
|
meta_window_move_frame (window, TRUE, 0, 0);
|
||||||
@ -306,15 +329,20 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
g_assert_cmpint (buffer_rect.x, ==, 0);
|
g_assert_cmpint (buffer_rect.x, ==, 0);
|
||||||
g_assert_cmpint (buffer_rect.y, ==, 0);
|
g_assert_cmpint (buffer_rect.y, ==, 0);
|
||||||
|
|
||||||
test.wait_for_scanout = TRUE;
|
test.number_of_frames_left = N_FRAMES_PER_TEST;
|
||||||
|
test.scanout.wait_for_scanout = TRUE;
|
||||||
|
test.scanout.expect_double_buffering = FALSE;
|
||||||
|
test.scanout.n_frames_started = 0;
|
||||||
|
test.scanout.n_presentations = 0;
|
||||||
|
test.scanout.n_direct_scanouts = 0;
|
||||||
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
g_main_loop_run (test.loop);
|
g_main_loop_run (test.loop);
|
||||||
|
|
||||||
g_assert_cmpuint (test.scanout.fb_id, >, 0);
|
g_assert_cmpint (test.scanout.n_presentations, ==, N_FRAMES_PER_TEST);
|
||||||
|
g_assert_cmpint (test.scanout.n_direct_scanouts, ==, N_FRAMES_PER_TEST - 1);
|
||||||
|
|
||||||
g_signal_handler_disconnect (stage, before_update_handler_id);
|
|
||||||
g_signal_handler_disconnect (stage, before_paint_handler_id);
|
g_signal_handler_disconnect (stage, before_paint_handler_id);
|
||||||
g_signal_handler_disconnect (stage, paint_view_handler_id);
|
|
||||||
g_signal_handler_disconnect (stage, presented_handler_id);
|
g_signal_handler_disconnect (stage, presented_handler_id);
|
||||||
|
|
||||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||||
@ -322,30 +350,6 @@ meta_test_kms_render_client_scanout (void)
|
|||||||
g_main_loop_unref (test.loop);
|
g_main_loop_unref (test.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
needs_repainted_guard (gpointer user_data)
|
|
||||||
{
|
|
||||||
g_assert_not_reached ();
|
|
||||||
return G_SOURCE_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
scanout_fallback_result_feedback (const MetaKmsFeedback *kms_feedback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
KmsRenderingTest *test = user_data;
|
|
||||||
|
|
||||||
g_assert_cmpuint (test->scanout_fallback.repaint_guard_id, ==, 0);
|
|
||||||
g_assert_nonnull (test->scanout_fallback.scanout_failed_view);
|
|
||||||
|
|
||||||
test->scanout_fallback.repaint_guard_id =
|
|
||||||
g_idle_add_full (G_PRIORITY_LOW, needs_repainted_guard, test, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const MetaKmsResultListenerVtable scanout_fallback_result_listener_vtable = {
|
|
||||||
.feedback = scanout_fallback_result_feedback,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_scanout_fallback_before_paint (ClutterStage *stage,
|
on_scanout_fallback_before_paint (ClutterStage *stage,
|
||||||
ClutterStageView *stage_view,
|
ClutterStageView *stage_view,
|
||||||
@ -356,15 +360,43 @@ on_scanout_fallback_before_paint (ClutterStage *stage,
|
|||||||
MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
|
MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
|
||||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||||
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
|
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||||
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
|
|
||||||
CoglScanout *scanout;
|
CoglScanout *scanout;
|
||||||
MetaKmsUpdate *kms_update;
|
int this_frame;
|
||||||
|
|
||||||
|
/* We don't know exactly how many frames the test will take due to:
|
||||||
|
* 1. Client scanouts taking a while to get started.
|
||||||
|
* 2. Triple buffering being asynchronous so one can't infer which DRM
|
||||||
|
* calls have completed from just the painting state.
|
||||||
|
* 3. Atomic commits now live in a separate thread!
|
||||||
|
*
|
||||||
|
* So ensure there's always a reason to start the next frame and
|
||||||
|
* the test never hangs;
|
||||||
|
*/
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
|
|
||||||
|
this_frame = ++test->scanout_fallback.last_frame_started;
|
||||||
|
|
||||||
scanout = clutter_stage_view_peek_scanout (stage_view);
|
scanout = clutter_stage_view_peek_scanout (stage_view);
|
||||||
if (!scanout)
|
if (!scanout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_assert_false (test->scanout_fallback.scanout_sabotaged);
|
if (!test->scanout_fallback.first_scanout)
|
||||||
|
{
|
||||||
|
test->scanout_fallback.first_scanout = this_frame;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep the test simple: Only one frame is ever sabotaged and it is
|
||||||
|
* definitely a direct scanout. But we can't rely on the value of 'scanout'
|
||||||
|
* alone because that may be non-NULL even when the next commit is going
|
||||||
|
* to be composited (triple buffering). So wait until first_scanout_presented
|
||||||
|
* before doing the sabotage.
|
||||||
|
*/
|
||||||
|
if (test->scanout_fallback.frame_sabotaged ||
|
||||||
|
!test->scanout_fallback.first_scanout_presented)
|
||||||
|
return;
|
||||||
|
|
||||||
|
test->scanout_fallback.frame_sabotaged = this_frame;
|
||||||
|
|
||||||
if (is_atomic_mode_setting (kms_device))
|
if (is_atomic_mode_setting (kms_device))
|
||||||
{
|
{
|
||||||
@ -375,17 +407,6 @@ on_scanout_fallback_before_paint (ClutterStage *stage,
|
|||||||
drm_mock_queue_error (DRM_MOCK_CALL_PAGE_FLIP, EINVAL);
|
drm_mock_queue_error (DRM_MOCK_CALL_PAGE_FLIP, EINVAL);
|
||||||
drm_mock_queue_error (DRM_MOCK_CALL_SET_CRTC, EINVAL);
|
drm_mock_queue_error (DRM_MOCK_CALL_SET_CRTC, EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
test->scanout_fallback.scanout_sabotaged = TRUE;
|
|
||||||
|
|
||||||
kms_update = meta_frame_native_ensure_kms_update (frame_native, kms_device);
|
|
||||||
meta_kms_update_add_result_listener (kms_update,
|
|
||||||
&scanout_fallback_result_listener_vtable,
|
|
||||||
NULL,
|
|
||||||
test,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
test->scanout_fallback.scanout_failed_view = stage_view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -395,13 +416,14 @@ on_scanout_fallback_paint_view (ClutterStage *stage,
|
|||||||
ClutterFrame *frame,
|
ClutterFrame *frame,
|
||||||
KmsRenderingTest *test)
|
KmsRenderingTest *test)
|
||||||
{
|
{
|
||||||
if (test->scanout_fallback.scanout_sabotaged)
|
/* With triple buffering, usable fallback paints may occur even before the
|
||||||
{
|
* failing commit they are needed to replace. So it would be too racy to
|
||||||
g_assert_cmpuint (test->scanout_fallback.repaint_guard_id, !=, 0);
|
* check if the a notification of the failed commit has been emitted yet.
|
||||||
g_clear_handle_id (&test->scanout_fallback.repaint_guard_id,
|
* Just make sure there has been at least one repaint after the sabotage AND
|
||||||
g_source_remove);
|
* that at the end of the test g_test_assert_expected_messages passes.
|
||||||
test->scanout_fallback.fallback_painted = TRUE;
|
*/
|
||||||
}
|
if (test->scanout_fallback.frame_sabotaged)
|
||||||
|
test->scanout_fallback.fallbacks_painted++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -410,11 +432,21 @@ on_scanout_fallback_presented (ClutterStage *stage,
|
|||||||
ClutterFrameInfo *frame_info,
|
ClutterFrameInfo *frame_info,
|
||||||
KmsRenderingTest *test)
|
KmsRenderingTest *test)
|
||||||
{
|
{
|
||||||
if (!test->scanout_fallback.scanout_sabotaged)
|
int this_frame;
|
||||||
return;
|
|
||||||
|
|
||||||
g_assert_true (test->scanout_fallback.fallback_painted);
|
if (test->scanout_fallback.last_frame_started <= 0)
|
||||||
|
return; /* Leftovers from previous tests. Ignore. */
|
||||||
|
|
||||||
|
this_frame = ++test->scanout_fallback.last_frame_presented;
|
||||||
|
if (this_frame >= test->scanout_fallback.first_scanout)
|
||||||
|
test->scanout_fallback.first_scanout_presented = TRUE;
|
||||||
|
|
||||||
|
if (test->scanout_fallback.fallbacks_painted > 0)
|
||||||
g_main_loop_quit (test->loop);
|
g_main_loop_quit (test->loop);
|
||||||
|
|
||||||
|
test->number_of_frames_left--;
|
||||||
|
g_assert_cmpint (test->number_of_frames_left, >, 0);
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -443,6 +475,7 @@ meta_test_kms_render_client_scanout_fallback (void)
|
|||||||
g_assert_nonnull (wayland_test_client);
|
g_assert_nonnull (wayland_test_client);
|
||||||
|
|
||||||
test = (KmsRenderingTest) {
|
test = (KmsRenderingTest) {
|
||||||
|
.number_of_frames_left = N_FRAMES_PER_TEST,
|
||||||
.loop = g_main_loop_new (NULL, FALSE),
|
.loop = g_main_loop_new (NULL, FALSE),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -464,6 +497,16 @@ meta_test_kms_render_client_scanout_fallback (void)
|
|||||||
g_main_loop_run (test.loop);
|
g_main_loop_run (test.loop);
|
||||||
g_main_loop_unref (test.loop);
|
g_main_loop_unref (test.loop);
|
||||||
|
|
||||||
|
g_test_message ("Test ending with:\n"
|
||||||
|
"\tfallbacks_painted: %d\n"
|
||||||
|
"\tlast_frame_started: %d\n"
|
||||||
|
"\tlast_frame_presented: %d\n"
|
||||||
|
"\tframe_sabotaged: %d",
|
||||||
|
test.scanout_fallback.fallbacks_painted,
|
||||||
|
test.scanout_fallback.last_frame_started,
|
||||||
|
test.scanout_fallback.last_frame_presented,
|
||||||
|
test.scanout_fallback.frame_sabotaged);
|
||||||
|
|
||||||
g_test_assert_expected_messages ();
|
g_test_assert_expected_messages ();
|
||||||
|
|
||||||
g_signal_handler_disconnect (stage, before_paint_handler_id);
|
g_signal_handler_disconnect (stage, before_paint_handler_id);
|
||||||
|
Reference in New Issue
Block a user