diff options
-rw-r--r-- | cmds/sfdo/sfdo.cpp | 71 | ||||
-rw-r--r-- | libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 7 | ||||
-rw-r--r-- | libs/gui/fuzzer/libgui_fuzzer_utils.h | 1 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 13 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
6 files changed, 88 insertions, 10 deletions
diff --git a/cmds/sfdo/sfdo.cpp b/cmds/sfdo/sfdo.cpp index f00f7b5513..de0e1718ab 100644 --- a/cmds/sfdo/sfdo.cpp +++ b/cmds/sfdo/sfdo.cpp @@ -16,7 +16,7 @@ #include <inttypes.h> #include <stdint.h> #include <any> -#include <unordered_map> +#include <map> #include <cutils/properties.h> #include <sys/resource.h> @@ -29,14 +29,24 @@ using namespace android; -std::unordered_map<std::string, std::any> g_functions; +std::map<std::string, std::any> g_functions; -const std::unordered_map<std::string, std::string> g_function_details = { - {"debugFlash", "[optional(delay)] Perform a debug flash."}, - {"frameRateIndicator", "[hide | show] displays the framerate in the top left corner."}, - {"scheduleComposite", "Force composite ahead of next VSYNC."}, - {"scheduleCommit", "Force commit ahead of next VSYNC."}, - {"scheduleComposite", "PENDING - if you have a good understanding let me know!"}, +enum class ParseToggleResult { + kError, + kFalse, + kTrue, +}; + +const std::map<std::string, std::string> g_function_details = { + {"debugFlash", "[optional(delay)] Perform a debug flash."}, + {"frameRateIndicator", "[hide | show] displays the framerate in the top left corner."}, + {"scheduleComposite", "Force composite ahead of next VSYNC."}, + {"scheduleCommit", "Force commit ahead of next VSYNC."}, + {"scheduleComposite", "PENDING - if you have a good understanding let me know!"}, + {"forceClientComposition", + "[enabled | disabled] When enabled, it disables " + "Hardware Overlays, and routes all window composition to the GPU. This can " + "help check if there is a bug in HW Composer."}, }; static void ShowUsage() { @@ -50,6 +60,25 @@ static void ShowUsage() { } } +// Returns 1 for positive keywords and 0 for negative keywords. +// If the string does not match any it will return -1. +ParseToggleResult parseToggle(const char* str) { + const std::unordered_set<std::string> positive{"1", "true", "y", "yes", + "on", "enabled", "show"}; + const std::unordered_set<std::string> negative{"0", "false", "n", "no", + "off", "disabled", "hide"}; + + const std::string word(str); + if (positive.count(word)) { + return ParseToggleResult::kTrue; + } + if (negative.count(word)) { + return ParseToggleResult::kFalse; + } + + return ParseToggleResult::kError; +} + int frameRateIndicator(int argc, char** argv) { bool hide = false, show = false; if (argc == 3) { @@ -86,6 +115,31 @@ int scheduleCommit([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { return 0; } +int forceClientComposition(int argc, char** argv) { + bool enabled = true; + // A valid command looks like this: + // adb shell sfdo forceClientComposition enabled + if (argc >= 3) { + const ParseToggleResult toggle = parseToggle(argv[2]); + if (toggle == ParseToggleResult::kError) { + std::cerr << "Incorrect usage of forceClientComposition. " + "Missing [enabled | disabled].\n"; + return -1; + } + if (argc > 3) { + std::cerr << "Too many arguments after [enabled | disabled]. " + "Ignoring extra arguments.\n"; + } + enabled = (toggle == ParseToggleResult::kTrue); + } else { + std::cerr << "Incorrect usage of forceClientComposition. Missing [enabled | disabled].\n"; + return -1; + } + + ComposerServiceAIDL::getComposerService()->forceClientComposition(enabled); + return 0; +} + int main(int argc, char** argv) { std::cout << "Execute SurfaceFlinger internal commands.\n"; std::cout << "sfdo requires to be run with root permissions..\n"; @@ -94,6 +148,7 @@ int main(int argc, char** argv) { g_functions["debugFlash"] = debugFlash; g_functions["scheduleComposite"] = scheduleComposite; g_functions["scheduleCommit"] = scheduleCommit; + g_functions["forceClientComposition"] = forceClientComposition; if (argc > 1 && g_functions.find(argv[1]) != g_functions.end()) { std::cout << "Running: " << argv[1] << "\n"; diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index a7cf5ddeb4..4a2e0b9738 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -514,6 +514,13 @@ interface ISurfaceComposer { void scheduleCommit(); /** + * Force all window composition to the GPU (i.e. disable Hardware Overlays). + * This can help check if there is a bug in HW Composer. + * Requires root or android.permission.HARDWARE_TEST + */ + void forceClientComposition(boolean enabled); + + /** * Gets priority of the RenderEngine in SurfaceFlinger. */ int getGpuContextPriority(); diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h index 3142103d17..b0253cc26e 100644 --- a/libs/gui/fuzzer/libgui_fuzzer_utils.h +++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h @@ -154,6 +154,7 @@ public: MOCK_METHOD(binder::Status, setDebugFlash, (int), (override)); MOCK_METHOD(binder::Status, scheduleComposite, (), (override)); MOCK_METHOD(binder::Status, scheduleCommit, (), (override)); + MOCK_METHOD(binder::Status, forceClientComposition, (bool), (override)); MOCK_METHOD(binder::Status, updateSmallAreaDetection, (const std::vector<int32_t>&, const std::vector<float>&), (override)); MOCK_METHOD(binder::Status, setSmallAreaDetectionThreshold, (int32_t, float), (override)); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index e7b1232eac..cf009b7b9a 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -999,6 +999,10 @@ public: binder::Status scheduleCommit() override { return binder::Status::ok(); } + binder::Status forceClientComposition(bool /*enabled*/) override { + return binder::Status::ok(); + } + binder::Status updateSmallAreaDetection(const std::vector<int32_t>& /*appIds*/, const std::vector<float>& /*thresholds*/) { return binder::Status::ok(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 62eb17d2e7..46514c5a34 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6736,8 +6736,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r case 1007: // Unused. return NAME_NOT_FOUND; case 1008: // Toggle forced GPU composition. - mDebugDisableHWC = data.readInt32() != 0; - scheduleRepaint(); + sfdo_forceClientComposition(data.readInt32() != 0); return NO_ERROR; case 1009: // Toggle use of transform hint. mDebugDisableTransformHint = data.readInt32() != 0; @@ -9025,6 +9024,11 @@ void SurfaceFlinger::sfdo_scheduleCommit() { setTransactionFlags(eTransactionNeeded | eDisplayTransactionNeeded | eTraversalNeeded); } +void SurfaceFlinger::sfdo_forceClientComposition(bool enabled) { + mDebugDisableHWC = enabled; + scheduleRepaint(); +} + // gui::ISurfaceComposer binder::Status SurfaceComposerAIDL::bootFinished() { @@ -9743,6 +9747,11 @@ binder::Status SurfaceComposerAIDL::scheduleCommit() { return binder::Status::ok(); } +binder::Status SurfaceComposerAIDL::forceClientComposition(bool enabled) { + mFlinger->sfdo_forceClientComposition(enabled); + return binder::Status::ok(); +} + binder::Status SurfaceComposerAIDL::updateSmallAreaDetection(const std::vector<int32_t>& appIds, const std::vector<float>& thresholds) { status_t status; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 520bd221b3..66cb8266dd 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1457,6 +1457,7 @@ private: void sfdo_setDebugFlash(int delay); void sfdo_scheduleComposite(); void sfdo_scheduleCommit(); + void sfdo_forceClientComposition(bool enabled); }; class SurfaceComposerAIDL : public gui::BnSurfaceComposer { @@ -1567,6 +1568,7 @@ public: binder::Status setDebugFlash(int delay) override; binder::Status scheduleComposite() override; binder::Status scheduleCommit() override; + binder::Status forceClientComposition(bool enabled) override; binder::Status updateSmallAreaDetection(const std::vector<int32_t>& appIds, const std::vector<float>& thresholds) override; binder::Status setSmallAreaDetectionThreshold(int32_t appId, float threshold) override; |