tests/kms/render: Disable triple buffering for now
This requires reverting the previous changes intended for adapting to triple buffering. Fixes these tests randomly failing, also in CI pipelines of MRs not directly related to any of this. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4290>
This commit is contained in:
parent
a67a118a7e
commit
eeaff29264
@ -39,29 +39,22 @@
|
||||
#include "tests/meta-wayland-test-driver.h"
|
||||
#include "tests/meta-wayland-test-utils.h"
|
||||
|
||||
#define N_FRAMES_PER_TEST 30
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int number_of_frames_left;
|
||||
GMainLoop *loop;
|
||||
|
||||
struct {
|
||||
int n_frames_started;
|
||||
int n_presentations;
|
||||
int n_direct_scanouts;
|
||||
GList *fb_ids;
|
||||
gboolean wait_for_scanout;
|
||||
gboolean expect_double_buffering;
|
||||
int n_paints;
|
||||
uint32_t fb_id;
|
||||
} scanout;
|
||||
|
||||
gboolean wait_for_scanout;
|
||||
|
||||
struct {
|
||||
int last_frame_started;
|
||||
int last_frame_presented;
|
||||
int frame_sabotaged;
|
||||
int first_scanout;
|
||||
int fallbacks_painted;
|
||||
gboolean first_scanout_presented;
|
||||
gboolean scanout_sabotaged;
|
||||
gboolean fallback_painted;
|
||||
guint repaint_guard_id;
|
||||
ClutterStageView *scanout_failed_view;
|
||||
} scanout_fallback;
|
||||
} KmsRenderingTest;
|
||||
@ -108,7 +101,7 @@ meta_test_kms_render_basic (void)
|
||||
gulong handler_id;
|
||||
|
||||
test = (KmsRenderingTest) {
|
||||
.number_of_frames_left = N_FRAMES_PER_TEST,
|
||||
.number_of_frames_left = 10,
|
||||
.loop = g_main_loop_new (NULL, FALSE),
|
||||
};
|
||||
handler_id = g_signal_connect (stage, "after-update",
|
||||
@ -123,6 +116,16 @@ meta_test_kms_render_basic (void)
|
||||
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
|
||||
on_scanout_before_paint (ClutterStage *stage,
|
||||
ClutterStageView *stage_view,
|
||||
@ -132,9 +135,6 @@ on_scanout_before_paint (ClutterStage *stage,
|
||||
CoglScanout *scanout;
|
||||
CoglScanoutBuffer *scanout_buffer;
|
||||
MetaDrmBuffer *buffer;
|
||||
uint32_t fb_id;
|
||||
|
||||
test->scanout.n_frames_started++;
|
||||
|
||||
scanout = clutter_stage_view_peek_scanout (stage_view);
|
||||
if (!scanout)
|
||||
@ -143,13 +143,18 @@ on_scanout_before_paint (ClutterStage *stage,
|
||||
scanout_buffer = cogl_scanout_get_buffer (scanout);
|
||||
g_assert_true (META_IS_DRM_BUFFER (scanout_buffer));
|
||||
buffer = META_DRM_BUFFER (scanout_buffer);
|
||||
fb_id = meta_drm_buffer_get_fb_id (buffer);
|
||||
g_assert_cmpuint (fb_id, >, 0);
|
||||
test->scanout.fb_ids = g_list_append (test->scanout.fb_ids,
|
||||
GUINT_TO_POINTER (fb_id));
|
||||
test->scanout.fb_id = meta_drm_buffer_get_fb_id (buffer);
|
||||
g_assert_cmpuint (test->scanout.fb_id, >, 0);
|
||||
}
|
||||
|
||||
/* Triple buffering, but no higher */
|
||||
g_assert_cmpuint (g_list_length (test->scanout.fb_ids), <=, 2);
|
||||
static void
|
||||
on_scanout_paint_view (ClutterStage *stage,
|
||||
ClutterStageView *stage_view,
|
||||
MtkRegion *region,
|
||||
ClutterFrame *frame,
|
||||
KmsRenderingTest *test)
|
||||
{
|
||||
test->scanout.n_paints++;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -168,17 +173,13 @@ on_scanout_presented (ClutterStage *stage,
|
||||
MetaDeviceFile *device_file;
|
||||
GError *error = NULL;
|
||||
drmModeCrtc *drm_crtc;
|
||||
uint32_t first_fb_id_expected;
|
||||
|
||||
/* Ignore frames from previous sub-tests */
|
||||
if (test->scanout.n_frames_started <= 0)
|
||||
if (test->wait_for_scanout && test->scanout.n_paints > 0)
|
||||
return;
|
||||
|
||||
if (test->scanout.wait_for_scanout && test->scanout.fb_ids == NULL)
|
||||
if (test->wait_for_scanout && test->scanout.fb_id == 0)
|
||||
return;
|
||||
|
||||
test->scanout.n_presentations++;
|
||||
|
||||
device_pool = meta_backend_native_get_device_pool (backend_native);
|
||||
|
||||
fb = clutter_stage_view_get_onscreen (stage_view);
|
||||
@ -196,37 +197,15 @@ on_scanout_presented (ClutterStage *stage,
|
||||
drm_crtc = drmModeGetCrtc (meta_device_file_get_fd (device_file),
|
||||
meta_kms_crtc_get_id (kms_crtc));
|
||||
g_assert_nonnull (drm_crtc);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
if (test->scanout.fb_id == 0)
|
||||
g_assert_cmpuint (drm_crtc->buffer_id, !=, test->scanout.fb_id);
|
||||
else
|
||||
{
|
||||
first_fb_id_expected = 0;
|
||||
g_assert_cmpuint (drm_crtc->buffer_id, !=, first_fb_id_expected);
|
||||
}
|
||||
|
||||
g_assert_cmpuint (drm_crtc->buffer_id, ==, test->scanout.fb_id);
|
||||
drmModeFreeCrtc (drm_crtc);
|
||||
|
||||
meta_device_file_release (device_file);
|
||||
|
||||
test->number_of_frames_left--;
|
||||
if (test->number_of_frames_left <= 0)
|
||||
g_main_loop_quit (test->loop);
|
||||
else
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
typedef enum
|
||||
@ -247,7 +226,9 @@ meta_test_kms_render_client_scanout (void)
|
||||
KmsRenderingTest test;
|
||||
MetaWaylandTestClient *wayland_test_client;
|
||||
g_autoptr (MetaWaylandTestDriver) test_driver = NULL;
|
||||
gulong before_update_handler_id;
|
||||
gulong before_paint_handler_id;
|
||||
gulong paint_view_handler_id;
|
||||
gulong presented_handler_id;
|
||||
MetaWindow *window;
|
||||
MtkRectangle view_rect;
|
||||
@ -263,11 +244,9 @@ meta_test_kms_render_client_scanout (void)
|
||||
g_assert_nonnull (wayland_test_client);
|
||||
|
||||
test = (KmsRenderingTest) {
|
||||
.number_of_frames_left = N_FRAMES_PER_TEST,
|
||||
.loop = g_main_loop_new (NULL, FALSE),
|
||||
.scanout = {0},
|
||||
.wait_for_scanout = TRUE,
|
||||
};
|
||||
test.scanout.wait_for_scanout = TRUE;
|
||||
|
||||
g_assert_cmpuint (g_list_length (clutter_stage_peek_stage_views (stage)),
|
||||
==,
|
||||
@ -275,6 +254,12 @@ meta_test_kms_render_client_scanout (void)
|
||||
clutter_stage_view_get_layout (clutter_stage_peek_stage_views (stage)->data,
|
||||
&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 =
|
||||
g_signal_connect (stage, "before-paint",
|
||||
G_CALLBACK (on_scanout_before_paint), &test);
|
||||
@ -285,8 +270,7 @@ meta_test_kms_render_client_scanout (void)
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
g_main_loop_run (test.loop);
|
||||
|
||||
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_assert_cmpuint (test.scanout.fb_id, >, 0);
|
||||
|
||||
g_debug ("Unmake fullscreen");
|
||||
window = meta_find_window_from_title (test_context, "dma-buf-scanout-test");
|
||||
@ -307,18 +291,11 @@ meta_test_kms_render_client_scanout (void)
|
||||
g_assert_cmpint (buffer_rect.x, ==, 10);
|
||||
g_assert_cmpint (buffer_rect.y, ==, 10);
|
||||
|
||||
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;
|
||||
|
||||
test.wait_for_scanout = FALSE;
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
g_main_loop_run (test.loop);
|
||||
|
||||
g_assert_cmpint (test.scanout.n_presentations, ==, N_FRAMES_PER_TEST);
|
||||
g_assert_cmpint (test.scanout.n_direct_scanouts, ==, 1);
|
||||
g_assert_cmpuint (test.scanout.fb_id, ==, 0);
|
||||
|
||||
g_debug ("Moving back to 0, 0");
|
||||
meta_window_move_frame (window, TRUE, 0, 0);
|
||||
@ -329,20 +306,15 @@ meta_test_kms_render_client_scanout (void)
|
||||
g_assert_cmpint (buffer_rect.x, ==, 0);
|
||||
g_assert_cmpint (buffer_rect.y, ==, 0);
|
||||
|
||||
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;
|
||||
|
||||
test.wait_for_scanout = TRUE;
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
g_main_loop_run (test.loop);
|
||||
|
||||
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_assert_cmpuint (test.scanout.fb_id, >, 0);
|
||||
|
||||
g_signal_handler_disconnect (stage, before_update_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);
|
||||
|
||||
meta_wayland_test_driver_emit_sync_event (test_driver, 0);
|
||||
@ -350,6 +322,30 @@ meta_test_kms_render_client_scanout (void)
|
||||
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
|
||||
on_scanout_fallback_before_paint (ClutterStage *stage,
|
||||
ClutterStageView *stage_view,
|
||||
@ -360,43 +356,15 @@ on_scanout_fallback_before_paint (ClutterStage *stage,
|
||||
MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
MetaFrameNative *frame_native = meta_frame_native_from_frame (frame);
|
||||
CoglScanout *scanout;
|
||||
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;
|
||||
MetaKmsUpdate *kms_update;
|
||||
|
||||
scanout = clutter_stage_view_peek_scanout (stage_view);
|
||||
if (!scanout)
|
||||
return;
|
||||
|
||||
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;
|
||||
g_assert_false (test->scanout_fallback.scanout_sabotaged);
|
||||
|
||||
if (is_atomic_mode_setting (kms_device))
|
||||
{
|
||||
@ -407,6 +375,17 @@ on_scanout_fallback_before_paint (ClutterStage *stage,
|
||||
drm_mock_queue_error (DRM_MOCK_CALL_PAGE_FLIP, 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
|
||||
@ -416,14 +395,13 @@ on_scanout_fallback_paint_view (ClutterStage *stage,
|
||||
ClutterFrame *frame,
|
||||
KmsRenderingTest *test)
|
||||
{
|
||||
/* 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
|
||||
* check if the a notification of the failed commit has been emitted yet.
|
||||
* Just make sure there has been at least one repaint after the sabotage AND
|
||||
* that at the end of the test g_test_assert_expected_messages passes.
|
||||
*/
|
||||
if (test->scanout_fallback.frame_sabotaged)
|
||||
test->scanout_fallback.fallbacks_painted++;
|
||||
if (test->scanout_fallback.scanout_sabotaged)
|
||||
{
|
||||
g_assert_cmpuint (test->scanout_fallback.repaint_guard_id, !=, 0);
|
||||
g_clear_handle_id (&test->scanout_fallback.repaint_guard_id,
|
||||
g_source_remove);
|
||||
test->scanout_fallback.fallback_painted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -432,21 +410,11 @@ on_scanout_fallback_presented (ClutterStage *stage,
|
||||
ClutterFrameInfo *frame_info,
|
||||
KmsRenderingTest *test)
|
||||
{
|
||||
int this_frame;
|
||||
if (!test->scanout_fallback.scanout_sabotaged)
|
||||
return;
|
||||
|
||||
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_assert_true (test->scanout_fallback.fallback_painted);
|
||||
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
|
||||
@ -475,7 +443,6 @@ meta_test_kms_render_client_scanout_fallback (void)
|
||||
g_assert_nonnull (wayland_test_client);
|
||||
|
||||
test = (KmsRenderingTest) {
|
||||
.number_of_frames_left = N_FRAMES_PER_TEST,
|
||||
.loop = g_main_loop_new (NULL, FALSE),
|
||||
};
|
||||
|
||||
@ -497,16 +464,6 @@ meta_test_kms_render_client_scanout_fallback (void)
|
||||
g_main_loop_run (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_signal_handler_disconnect (stage, before_paint_handler_id);
|
||||
@ -565,6 +522,9 @@ main (int argc,
|
||||
g_autoptr (MetaContext) context = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
/* See https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441#note_2350786 */
|
||||
g_setenv ("CLUTTER_PAINT", "disable-triple-buffering", TRUE);
|
||||
|
||||
context = meta_create_test_context (META_CONTEXT_TEST_TYPE_VKMS,
|
||||
META_CONTEXT_TEST_FLAG_NO_X11);
|
||||
g_assert_true (meta_context_configure (context, &argc, &argv, NULL));
|
||||
|
Loading…
x
Reference in New Issue
Block a user