SF: Add dumpsys flags to dump displays
Dump display configuration (--displays) and composition state (--comp-
displays) separately.
Use consistent formatting. Remove noise, e.g. repetitive display modes,
physical display state that is expectedly missing for virtual displays.
Bug: 182939859
Test: dumpsys SurfaceFlinger --displays
Test: dumpsys SurfaceFlinger --comp-displays
Change-Id: I787eedb82d76c74363e653a648ae88699096cc47
diff --git a/libs/ui/DeviceProductInfo.cpp b/libs/ui/DeviceProductInfo.cpp
index 4d6ce43..04d9d3c 100644
--- a/libs/ui/DeviceProductInfo.cpp
+++ b/libs/ui/DeviceProductInfo.cpp
@@ -57,7 +57,7 @@
}
void DeviceProductInfo::dump(std::string& result) const {
- StringAppendF(&result, "{name=%s, ", name.c_str());
+ StringAppendF(&result, "{name=\"%s\", ", name.c_str());
StringAppendF(&result, "manufacturerPnpId=%s, ", manufacturerPnpId.data());
StringAppendF(&result, "productId=%s, ", productId.c_str());
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h
index a63145a..49013e0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/ProjectionSpace.h
@@ -120,16 +120,16 @@
} // namespace compositionengine
-inline std::string to_string(const android::compositionengine::ProjectionSpace& space) {
- return android::base::
- StringPrintf("ProjectionSpace(bounds = %s, content = %s, orientation = %s)",
- to_string(space.getBoundsAsRect()).c_str(),
- to_string(space.getContent()).c_str(), toCString(space.getOrientation()));
+inline std::string to_string(const compositionengine::ProjectionSpace& space) {
+ return base::StringPrintf("ProjectionSpace{bounds=%s, content=%s, orientation=%s}",
+ to_string(space.getBoundsAsRect()).c_str(),
+ to_string(space.getContent()).c_str(),
+ toCString(space.getOrientation()));
}
// Defining PrintTo helps with Google Tests.
-inline void PrintTo(const android::compositionengine::ProjectionSpace& space, ::std::ostream* os) {
+inline void PrintTo(const compositionengine::ProjectionSpace& space, std::ostream* os) {
*os << to_string(space);
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
index 5fa0d67..61be983 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputCompositionState.h
@@ -155,6 +155,8 @@
SUCCESS = 1,
// Composition strategy prediction failed for this frame.
FAIL = 2,
+
+ ftl_last = FAIL
};
CompositionStrategyPredictionState strategyPrediction =
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index f545886..b79b46b 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -131,15 +131,11 @@
}
void Display::dump(std::string& out) const {
- using android::base::StringAppendF;
+ const char* const type = isVirtual() ? "virtual" : "physical";
+ base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(mId).c_str(), type,
+ getName().c_str());
- StringAppendF(&out, " Composition Display State: [\"%s\"]", getName().c_str());
-
- out.append("\n ");
- dumpVal(out, "isVirtual", isVirtual());
- dumpVal(out, "DisplayId", to_string(mId));
- out.append("\n");
-
+ out.append("\n Composition Display State:\n");
Output::dumpBase(out);
}
diff --git a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
index 01c368d..290c710 100644
--- a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
@@ -89,7 +89,6 @@
void dumpVal(std::string& out, const char* name, const ui::Transform& transform) {
transform.dump(out, name);
- out.append(" ");
}
void dumpVal(std::string& out, const char* name, const mat4& tr) {
@@ -99,7 +98,7 @@
"[%0.3f,%0.3f,%0.3f,%0.3f]"
"[%0.3f,%0.3f,%0.3f,%0.3f]"
"[%0.3f,%0.3f,%0.3f,%0.3f]"
- "[%0.3f,%0.3f,%0.3f,%0.3f]]",
+ "[%0.3f,%0.3f,%0.3f,%0.3f]] ",
name,
tr[0][0], tr[1][0], tr[2][0], tr[3][0],
tr[0][1], tr[1][1], tr[2][1], tr[3][1],
@@ -109,9 +108,9 @@
}
void dumpVal(std::string& out, const char* name, const StretchEffect& effect) {
- StringAppendF(&out, "%s={ width =%f, height = %f, vec=(%f, %f), max=(%f, %f) } ", name,
- effect.width, effect.height,
- effect.vectorX, effect.vectorY, effect.maxAmountX, effect.maxAmountY);
+ StringAppendF(&out, "%s={width=%f, height=%f, vec=(%f, %f), max=(%f, %f)} ", name, effect.width,
+ effect.height, effect.vectorX, effect.vectorY, effect.maxAmountX,
+ effect.maxAmountY);
}
} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index e99b70f..c92c569 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -294,17 +294,15 @@
}
void Output::dump(std::string& out) const {
- using android::base::StringAppendF;
-
- StringAppendF(&out, " Composition Output State: [\"%s\"]", mName.c_str());
-
- out.append("\n ");
+ base::StringAppendF(&out, "Output \"%s\"", mName.c_str());
+ out.append("\n Composition Output State:\n");
dumpBase(out);
}
void Output::dumpBase(std::string& out) const {
dumpState(out);
+ out += '\n';
if (mDisplayColorProfile) {
mDisplayColorProfile->dump(out);
@@ -312,13 +310,15 @@
out.append(" No display color profile!\n");
}
+ out += '\n';
+
if (mRenderSurface) {
mRenderSurface->dump(out);
} else {
out.append(" No render surface!\n");
}
- android::base::StringAppendF(&out, "\n %zu Layers\n", getOutputLayerCount());
+ base::StringAppendF(&out, "\n %zu Layers\n", getOutputLayerCount());
for (const auto* outputLayer : getOutputLayersOrderedByZ()) {
if (!outputLayer) {
continue;
@@ -329,7 +329,7 @@
void Output::dumpPlannerInfo(const Vector<String16>& args, std::string& out) const {
if (!mPlanner) {
- base::StringAppendF(&out, "Planner is disabled\n");
+ out.append("Planner is disabled\n");
return;
}
base::StringAppendF(&out, "Planner info for display [%s]\n", mName.c_str());
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
index 7188281..3b85e3b 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputCompositionState.cpp
@@ -14,40 +14,30 @@
* limitations under the License.
*/
+#include <ftl/enum.h>
+
#include <compositionengine/impl/DumpHelpers.h>
#include <compositionengine/impl/OutputCompositionState.h>
namespace android::compositionengine::impl {
-using CompositionStrategyPredictionState =
- OutputCompositionState::CompositionStrategyPredictionState;
-
-std::string toString(CompositionStrategyPredictionState state) {
- switch (state) {
- case CompositionStrategyPredictionState::DISABLED:
- return "Disabled";
- case CompositionStrategyPredictionState::SUCCESS:
- return "Success";
- case CompositionStrategyPredictionState::FAIL:
- return "Fail";
- }
-}
void OutputCompositionState::dump(std::string& out) const {
out.append(" ");
dumpVal(out, "isEnabled", isEnabled);
dumpVal(out, "isSecure", isSecure);
-
- dumpVal(out, "usesClientComposition", usesClientComposition);
dumpVal(out, "usesDeviceComposition", usesDeviceComposition);
+
+ out.append("\n ");
+ dumpVal(out, "usesClientComposition", usesClientComposition);
dumpVal(out, "flipClientTarget", flipClientTarget);
dumpVal(out, "reusedClientComposition", reusedClientComposition);
- dumpVal(out, "layerFilter", layerFilter);
out.append("\n ");
-
+ dumpVal(out, "layerFilter", layerFilter);
+ out.append("\n ");
dumpVal(out, "transform", transform);
- out.append("\n ");
+ out.append(" "); // ui::Transform::dump appends EOL.
dumpVal(out, "layerStackSpace", to_string(layerStackSpace));
out.append("\n ");
dumpVal(out, "framebufferSpace", to_string(framebufferSpace));
@@ -59,19 +49,24 @@
dumpVal(out, "needsFiltering", needsFiltering);
out.append("\n ");
-
dumpVal(out, "colorMode", toString(colorMode), colorMode);
dumpVal(out, "renderIntent", toString(renderIntent), renderIntent);
dumpVal(out, "dataspace", toString(dataspace), dataspace);
+ dumpVal(out, "targetDataspace", toString(targetDataspace), targetDataspace);
+
+ out.append("\n ");
dumpVal(out, "colorTransformMatrix", colorTransformMatrix);
- dumpVal(out, "target dataspace", toString(targetDataspace), targetDataspace);
+
+ out.append("\n ");
dumpVal(out, "displayBrightnessNits", displayBrightnessNits);
dumpVal(out, "sdrWhitePointNits", sdrWhitePointNits);
dumpVal(out, "clientTargetBrightness", clientTargetBrightness);
dumpVal(out, "displayBrightness", displayBrightness);
- dumpVal(out, "compositionStrategyPredictionState", toString(strategyPrediction));
- out.append("\n");
+ out.append("\n ");
+ dumpVal(out, "compositionStrategyPredictionState", ftl::enum_string(strategyPrediction));
+
+ out += '\n';
}
} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 65e7a7f..52529d6 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -24,7 +24,6 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <android-base/stringprintf.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/Display.h>
#include <compositionengine/DisplayColorProfile.h>
@@ -49,8 +48,6 @@
namespace hal = hardware::graphics::composer::hal;
-using android::base::StringAppendF;
-
ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
@@ -342,38 +339,40 @@
}
std::string DisplayDevice::getDebugName() const {
- const char* type = "virtual";
+ using namespace std::string_literals;
+
+ std::string name = "Display "s + to_string(getId()) + " ("s;
+
if (mConnectionType) {
- type = isInternal() ? "internal" : "external";
+ name += isInternal() ? "internal"s : "external"s;
+ } else {
+ name += "virtual"s;
}
- return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
- isPrimary() ? ", primary" : "", mDisplayName.c_str());
+ if (isPrimary()) {
+ name += ", primary"s;
+ }
+
+ return name + ", \""s + mDisplayName + "\")"s;
}
void DisplayDevice::dump(std::string& result) const {
- StringAppendF(&result, "+ %s\n", getDebugName().c_str());
- StringAppendF(&result, " powerMode=%s (%d)\n", to_string(mPowerMode).c_str(),
- static_cast<int32_t>(mPowerMode));
- const auto activeMode = getActiveMode();
- StringAppendF(&result, " activeMode=%s\n",
- activeMode ? to_string(*activeMode).c_str() : "none");
+ using namespace std::string_literals;
- result.append(" supportedModes=\n");
- for (const auto& [id, mode] : mSupportedModes) {
- result.append(" ");
- result.append(to_string(*mode));
- result.push_back('\n');
+ result += getDebugName();
+
+ if (!isVirtual()) {
+ result += "\n deviceProductInfo="s;
+ if (mDeviceProductInfo) {
+ mDeviceProductInfo->dump(result);
+ } else {
+ result += "{}"s;
+ }
}
- StringAppendF(&result, " deviceProductInfo=");
- if (mDeviceProductInfo) {
- mDeviceProductInfo->dump(result);
- } else {
- result.append("{}");
- }
- result.append("\n");
- getCompositionDisplay()->dump(result);
+ result += "\n powerMode="s;
+ result += to_string(mPowerMode);
+ result += '\n';
if (mRefreshRateConfigs) {
mRefreshRateConfigs->dump(result);
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 8d685cf..eb14933 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -44,18 +44,10 @@
#include "HWComposer.h"
#include "../SurfaceFlinger.h"
-// ----------------------------------------------------------------------------
namespace android {
-// ----------------------------------------------------------------------------
using ui::Dataspace;
-/*
- * This implements the (main) framebuffer management. This class is used
- * mostly by SurfaceFlinger, but also by command line GL application.
- *
- */
-
FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer,
const ui::Size& size, const ui::Size& maxSize)
@@ -205,14 +197,14 @@
void FramebufferSurface::dumpAsString(String8& result) const {
Mutex::Autolock lock(mMutex);
- result.appendFormat(" FramebufferSurface: dataspace: %s(%d)\n",
+ result.append(" FramebufferSurface\n");
+ result.appendFormat(" mDataSpace=%s (%d)\n",
dataspaceDetails(static_cast<android_dataspace>(mDataSpace)).c_str(),
mDataSpace);
- ConsumerBase::dumpLocked(result, " ");
+ ConsumerBase::dumpLocked(result, " ");
}
-void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const
-{
+void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const {
ConsumerBase::dumpLocked(result, prefix);
}
@@ -220,9 +212,7 @@
return mCurrentFence;
}
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 3226f22..ca83496 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -133,9 +133,9 @@
} // namespace
std::string RefreshRateConfigs::Policy::toString() const {
- return base::StringPrintf("default mode ID: %d, allowGroupSwitching = %d"
- ", primary range: %s, app request range: %s",
- defaultMode.value(), allowGroupSwitching,
+ return base::StringPrintf("{defaultModeId=%d, allowGroupSwitching=%s"
+ ", primaryRange=%s, appRequestRange=%s}",
+ defaultMode.value(), allowGroupSwitching ? "true" : "false",
to_string(primaryRange).c_str(), to_string(appRequestRange).c_str());
}
@@ -922,41 +922,46 @@
}
void RefreshRateConfigs::dump(std::string& result) const {
+ using namespace std::string_literals;
+
std::lock_guard lock(mLock);
- base::StringAppendF(&result, "DesiredDisplayModeSpecs (DisplayManager): %s\n\n",
- mDisplayManagerPolicy.toString().c_str());
- scheduler::RefreshRateConfigs::Policy currentPolicy = *getCurrentPolicyLocked();
- if (mOverridePolicy && currentPolicy != mDisplayManagerPolicy) {
- base::StringAppendF(&result, "DesiredDisplayModeSpecs (Override): %s\n\n",
- currentPolicy.toString().c_str());
- }
- base::StringAppendF(&result, "Active mode: %s\n", to_string(*mActiveModeIt->second).c_str());
+ const auto activeModeId = mActiveModeIt->first;
+ result += " activeModeId="s;
+ result += std::to_string(activeModeId.value());
- result.append("Display modes:\n");
+ result += "\n displayModes=\n"s;
for (const auto& [id, mode] : mDisplayModes) {
- result.push_back('\t');
- result.append(to_string(*mode));
- result.push_back('\n');
+ result += " "s;
+ result += to_string(*mode);
+ result += '\n';
}
- base::StringAppendF(&result, "Supports Frame Rate Override By Content: %s\n",
- mSupportsFrameRateOverrideByContent ? "yes" : "no");
+ base::StringAppendF(&result, " displayManagerPolicy=%s\n",
+ mDisplayManagerPolicy.toString().c_str());
- result.append("Idle timer: ");
- if (const auto controller = mConfig.kernelIdleTimerController) {
- base::StringAppendF(&result, "(kernel via %s) ", ftl::enum_string(*controller).c_str());
- } else {
- result.append("(platform) ");
+ if (const Policy& currentPolicy = *getCurrentPolicyLocked();
+ mOverridePolicy && currentPolicy != mDisplayManagerPolicy) {
+ base::StringAppendF(&result, " overridePolicy=%s\n", currentPolicy.toString().c_str());
}
+ base::StringAppendF(&result, " supportsFrameRateOverrideByContent=%s\n",
+ mSupportsFrameRateOverrideByContent ? "true" : "false");
+
+ result += " idleTimer="s;
if (mIdleTimer) {
- result.append(mIdleTimer->dump());
+ result += mIdleTimer->dump();
} else {
- result.append("off");
+ result += "off"s;
}
- result.append("\n\n");
+ if (const auto controller = mConfig.kernelIdleTimerController) {
+ base::StringAppendF(&result, " (kernel via %s)", ftl::enum_string(*controller).c_str());
+ } else {
+ result += " (platform)"s;
+ }
+
+ result += '\n';
}
std::chrono::milliseconds RefreshRateConfigs::getIdleTimerTimeout() {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f33ea5b..2616203 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4941,7 +4941,9 @@
pid, uid);
} else {
static const std::unordered_map<std::string, Dumper> dumpers = {
+ {"--comp-displays"s, dumper(&SurfaceFlinger::dumpCompositionDisplays)},
{"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
+ {"--displays"s, dumper(&SurfaceFlinger::dumpDisplays)},
{"--dispsync"s, dumper([this](std::string& s) { mScheduler->dumpVsync(s); })},
{"--edid"s, argsDumper(&SurfaceFlinger::dumpRawDisplayIdentificationData)},
{"--frame-events"s, dumper(&SurfaceFlinger::dumpFrameEventsLocked)},
@@ -5118,6 +5120,20 @@
[&] (Layer* layer) { layer->dumpFrameEvents(result); });
}
+void SurfaceFlinger::dumpCompositionDisplays(std::string& result) const {
+ for (const auto& [token, display] : mDisplays) {
+ display->getCompositionDisplay()->dump(result);
+ result += '\n';
+ }
+}
+
+void SurfaceFlinger::dumpDisplays(std::string& result) const {
+ for (const auto& [token, display] : mDisplays) {
+ display->dump(result);
+ result += '\n';
+ }
+}
+
void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
const auto displayId = PhysicalDisplayId::tryCast(display->getId());
@@ -5326,21 +5342,12 @@
});
}
- /*
- * Dump Display state
- */
-
colorizer.bold(result);
StringAppendF(&result, "Displays (%zu entries)\n", mDisplays.size());
colorizer.reset(result);
- for (const auto& [token, display] : mDisplays) {
- display->dump(result);
- }
- result.append("\n");
-
- /*
- * Dump CompositionEngine state
- */
+ dumpDisplays(result);
+ dumpCompositionDisplays(result);
+ result.push_back('\n');
mCompositionEngine->dump(result);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6aa54ff..74e0407 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1094,9 +1094,13 @@
void dumpStaticScreenStats(std::string& result) const;
// Not const because each Layer needs to query Fences and cache timestamps.
void dumpFrameEventsLocked(std::string& result);
+
+ void dumpCompositionDisplays(std::string& result) const REQUIRES(mStateLock);
+ void dumpDisplays(std::string& result) const REQUIRES(mStateLock);
void dumpDisplayIdentificationData(std::string& result) const REQUIRES(mStateLock);
void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
void dumpWideColorInfo(std::string& result) const REQUIRES(mStateLock);
+
LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
void dumpOffscreenLayersProto(LayersProto& layersProto,
uint32_t traceFlags = LayerTracing::TRACE_ALL) const;