Merge changes from topic "sfdo" into main
* changes:
[sfdo] Add the forceClientComposition command to sfdo.
[sfdo] Fix minor formatting issues.
diff --git a/cmds/sfdo/sfdo.cpp b/cmds/sfdo/sfdo.cpp
index 55326ea..de0e171 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,18 +29,28 @@
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() {
- std::cout << "usage: sfdo [help, FrameRateIndicator show, DebugFlash enabled, ...]\n\n";
+ std::cout << "usage: sfdo [help, frameRateIndicator show, debugFlash enabled, ...]\n\n";
for (const auto& sf : g_functions) {
const std::string fn = sf.first;
std::string fdetails = "TODO";
@@ -50,7 +60,26 @@
}
}
-int FrameRateIndicator([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
+// 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) {
show = strcmp(argv[2], "show") == 0;
@@ -60,13 +89,13 @@
if (show || hide) {
ComposerServiceAIDL::getComposerService()->enableRefreshRateOverlay(show);
} else {
- std::cerr << "Incorrect usage of FrameRateIndicator. Missing [hide | show].\n";
+ std::cerr << "Incorrect usage of frameRateIndicator. Missing [hide | show].\n";
return -1;
}
return 0;
}
-int DebugFlash([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
+int debugFlash(int argc, char** argv) {
int delay = 0;
if (argc == 3) {
delay = atoi(argv[2]) == 0;
@@ -86,14 +115,40 @@
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";
- g_functions["FrameRateIndicator"] = FrameRateIndicator;
- g_functions["DebugFlash"] = DebugFlash;
+ g_functions["frameRateIndicator"] = frameRateIndicator;
+ 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 a7cf5dd..4a2e0b9 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -514,6 +514,13 @@
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 3142103..b0253cc 100644
--- a/libs/gui/fuzzer/libgui_fuzzer_utils.h
+++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h
@@ -154,6 +154,7 @@
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 0e26544..ec01189 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -934,6 +934,10 @@
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 829eea6..5cc2985 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -6769,8 +6769,7 @@
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;
@@ -9059,6 +9058,11 @@
setTransactionFlags(eTransactionNeeded | eDisplayTransactionNeeded | eTraversalNeeded);
}
+void SurfaceFlinger::sfdo_forceClientComposition(bool enabled) {
+ mDebugDisableHWC = enabled;
+ scheduleRepaint();
+}
+
// gui::ISurfaceComposer
binder::Status SurfaceComposerAIDL::bootFinished() {
@@ -9777,6 +9781,11 @@
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 fa48549..6e1b4f4 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1462,6 +1462,7 @@
void sfdo_setDebugFlash(int delay);
void sfdo_scheduleComposite();
void sfdo_scheduleCommit();
+ void sfdo_forceClientComposition(bool enabled);
};
class SurfaceComposerAIDL : public gui::BnSurfaceComposer {
@@ -1572,6 +1573,7 @@
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;