From 0583f19628ec72f7fac38c64ca2f3b93bae3436d Mon Sep 17 00:00:00 2001 From: Andrew Wolfers Date: Mon, 8 Sep 2025 20:33:26 +0000 Subject: [PATCH] drm_hwcomposer: Change cursor composition testing This CL strengthens the cursor plane usage check with a test commit. A test commit is a cheap and definitive means of determining whether the cursor plane can be used. Under the previous scheme, if a validation test commit would fail, it was unclear whether the failure was due to the cursor plane or due to other factors, and sometimes the cursor would be demoted when it was not at fault. The new flow relies on the result of the cursor test commit, and applies updated fallback behavior to preserve the cursor as much as possible. Change-Id: If3b86a4cbfb5220532a58b14797d6840c3a93af6 --- backend/Backend.cpp | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/backend/Backend.cpp b/backend/Backend.cpp index 6536e8c..7abb65a 100644 --- a/backend/Backend.cpp +++ b/backend/Backend.cpp @@ -59,14 +59,22 @@ auto Backend::ValidateDisplay(HwcDisplay* display) -> ValidatedComposition { } } - size_t client_start = 0; - size_t client_size = 0; + bool use_cursor_plane = false; const auto* cursor_layer = GetCursorLayer(layers); auto cursor_plane = display->GetPipe().GetUsablePlanes().second; - bool use_cursor_plane = cursor_layer != nullptr && cursor_plane != nullptr && - !IsClientLayer(display, cursor_layer) && - cursor_plane->Get()->IsValidForLayer( - &cursor_layer->GetLayerData()); + if (cursor_layer != nullptr && cursor_plane != nullptr && + !IsClientLayer(display, cursor_layer) && + cursor_plane->Get()->IsValidForLayer(&cursor_layer->GetLayerData())) { + // Create and test a composition using only cursor plane and all other + // layers client-composited to infer whether the cursor plane can be used. + ValidatedComposition cursor_composition{ + .composition_types = GetCompositionTypes(layers, 0, layers.size() - 1, + /*use_cursor_plane=*/true)}; + use_cursor_plane = display->TestComposition(cursor_composition); + } + + size_t client_start = 0; + size_t client_size = 0; ValidatedComposition validated_composition; // Populates and tests |validated_composition|, returning whether it @@ -92,18 +100,26 @@ auto Backend::ValidateDisplay(HwcDisplay* display) -> ValidatedComposition { use_cursor_plane); bool success = validate_and_test(); - // First fallback: convert cursor layer to device composition and reattempt. - if (!success && use_cursor_plane) { - ++display->total_stats().failed_kms_cursor_validate; - use_cursor_plane = false; - std::tie(client_start, client_size) = GetClientLayers(display, layers, - use_cursor_plane); - success = validate_and_test(); + // Cursor fallback: convert all non-cursor layers to client composition and + // reattempt. (Cursor layer is preserved as _either_ cursor _or_ device + // composited.) + if (!success && cursor_layer != nullptr) { + if (layers.back()->GetSfType() != CompositionType::kCursor) { + ALOGE("Cursor layer was not found at highest z-order"); + // Continue to next fallback. + } else { + client_start = 0; + client_size = layers.size() - 1; + success = validate_and_test(); + } } // Final fallback: convert all layers to client composition. if (!success) { ++display->total_stats().failed_kms_validate; + if (use_cursor_plane) { + ++display->total_stats().failed_kms_cursor_validate; + } use_cursor_plane = false; validated_composition = GetFlattenedComposition(layers); }