summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h30
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h6
-rw-r--r--services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp18
-rw-r--r--services/surfaceflinger/FrontEnd/LayerSnapshot.cpp21
-rw-r--r--services/surfaceflinger/FrontEnd/LayerSnapshot.h3
-rw-r--r--services/surfaceflinger/LayerFE.cpp11
-rw-r--r--services/surfaceflinger/LayerFE.h10
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp37
-rw-r--r--services/surfaceflinger/common/include/common/WorkloadTracer.h2
9 files changed, 101 insertions, 37 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index e876693498..780758e2a3 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -19,6 +19,7 @@
#include <optional>
#include <ostream>
#include <unordered_set>
+#include "aidl/android/hardware/graphics/composer3/Composition.h"
#include "ui/LayerStack.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -36,10 +37,6 @@
#include <utils/RefBase.h>
#include <utils/Timers.h>
-namespace aidl::android::hardware::graphics::composer3 {
-enum class Composition;
-}
-
namespace android {
class Fence;
@@ -182,10 +179,27 @@ public:
// Whether the layer should be rendered with rounded corners.
virtual bool hasRoundedCorners() const = 0;
virtual void setWasClientComposed(const sp<Fence>&) {}
- virtual void setHwcCompositionType(
- aidl::android::hardware::graphics::composer3::Composition) = 0;
- virtual aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
- const = 0;
+
+ // These fields are all copied from the last written HWC state.
+ // This state is only used for debugging purposes.
+ struct HwcLayerDebugState {
+ aidl::android::hardware::graphics::composer3::Composition lastCompositionType =
+ aidl::android::hardware::graphics::composer3::Composition::INVALID;
+ // Corresponds to passing an alpha of 0 to HWC2::Layer::setPlaneAlpha.
+ bool wasSkipped = false;
+
+ // Indicates whether the compositionengine::OutputLayer had properties overwritten.
+ // Not directly passed to HWC.
+ bool wasOverridden = false;
+
+ // Corresponds to the GraphicBuffer ID of the buffer passed to HWC2::Layer::setBuffer.
+ // This buffer corresponds to a CachedSet that the LayerFE was flattened to.
+ uint64_t overrideBufferId = 0;
+ };
+
+ // Used for debugging purposes, e.g. perfetto tracing, dumpsys.
+ virtual void setLastHwcState(const LayerFE::HwcLayerDebugState &hwcState) = 0;
+ virtual const HwcLayerDebugState &getLastHwcState() const = 0;
virtual const gui::LayerMetadata* getMetadata() const = 0;
virtual const gui::LayerMetadata* getRelativeMetadata() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 7744b8bb99..d2a5a2066c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -59,9 +59,9 @@ public:
MOCK_CONST_METHOD0(getMetadata, gui::LayerMetadata*());
MOCK_CONST_METHOD0(getRelativeMetadata, gui::LayerMetadata*());
MOCK_METHOD0(onPictureProfileCommitted, void());
- MOCK_METHOD(void, setHwcCompositionType,
- (aidl::android::hardware::graphics::composer3::Composition), (override));
- MOCK_METHOD(aidl::android::hardware::graphics::composer3::Composition, getHwcCompositionType,
+ MOCK_METHOD(void, setLastHwcState,
+ (const HwcLayerDebugState&), (override));
+ MOCK_METHOD(const HwcLayerDebugState&, getLastHwcState,
(), (const, override));
};
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 9b66f01789..9d67122f2e 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -502,6 +502,15 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t
editState().hwc->stateOverridden = isOverridden;
editState().hwc->layerSkipped = skipLayer;
+
+
+ // Save the final HWC state for debugging purposes, e.g. perfetto tracing, dumpsys.
+ getLayerFE().setLastHwcState({.lastCompositionType = editState().hwc->hwcCompositionType,
+ .wasSkipped = skipLayer,
+ .wasOverridden = isOverridden,
+ .overrideBufferId = editState().overrideInfo.buffer
+ ? editState().overrideInfo.buffer.get()->getId()
+ : 0});
}
void OutputLayer::writeOutputDependentGeometryStateToHWC(HWC2::Layer* hwcLayer,
@@ -867,7 +876,6 @@ void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer,
if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType ||
(outputDependentState.hwc->layerSkipped && !skipLayer)) {
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
- getLayerFE().setHwcCompositionType(requestedCompositionType);
if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
error != hal::Error::NONE) {
@@ -965,7 +973,13 @@ void OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType)
}
hwcState.hwcCompositionType = compositionType;
- getLayerFE().setHwcCompositionType(compositionType);
+
+ getLayerFE().setLastHwcState({.lastCompositionType = hwcState.hwcCompositionType,
+ .wasSkipped = hwcState.layerSkipped,
+ .wasOverridden = hwcState.stateOverridden,
+ .overrideBufferId = state.overrideInfo.buffer
+ ? state.overrideInfo.buffer.get()->getId()
+ : 0});
}
void OutputLayer::prepareForDeviceLayerRequests() {
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index 523ef7bfbe..bbf42a81aa 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -537,12 +537,13 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate
}
}
-char LayerSnapshot::classifyCompositionForDebug(Composition compositionType) const {
+char LayerSnapshot::classifyCompositionForDebug(
+ const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const {
if (!isVisible) {
return '.';
}
- switch (compositionType) {
+ switch (hwcState.lastCompositionType) {
case Composition::INVALID:
return 'i';
case Composition::SOLID_COLOR:
@@ -561,21 +562,21 @@ char LayerSnapshot::classifyCompositionForDebug(Composition compositionType) con
}
char code = '.'; // Default to invisible
- if (hasBufferOrSidebandStream()) {
- code = 'b';
- } else if (fillsColor()) {
- code = 'c'; // Solid color
- } else if (hasBlur()) {
+ if (hasBlur()) {
code = 'l'; // Blur
} else if (hasProtectedContent) {
code = 'p'; // Protected content
- } else if (drawShadows()) {
- code = 's'; // Shadow
} else if (roundedCorner.hasRoundedCorners()) {
code = 'r'; // Rounded corners
+ } else if (drawShadows()) {
+ code = 's'; // Shadow
+ } else if (fillsColor()) {
+ code = 'c'; // Solid color
+ } else if (hasBufferOrSidebandStream()) {
+ code = 'b';
}
- if (compositionType == Composition::CLIENT) {
+ if (hwcState.lastCompositionType == Composition::CLIENT) {
return static_cast<char>(std::toupper(code));
} else {
return code;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 04b9f3b448..69120bdcff 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -24,6 +24,7 @@
#include "RequestedLayerState.h"
#include "Scheduler/LayerInfo.h"
#include "android-base/stringprintf.h"
+#include "compositionengine/LayerFE.h"
namespace android::surfaceflinger::frontend {
@@ -163,7 +164,7 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
// Returns a char summarizing the composition request
// This function tries to maintain parity with planner::Plan chars.
char classifyCompositionForDebug(
- aidl::android::hardware::graphics::composer3::Composition compositionType) const;
+ const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const;
};
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index 725a782177..b6192685ae 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -428,13 +428,12 @@ LayerFE::ReleaseFencePromiseStatus LayerFE::getReleaseFencePromiseStatus() {
return mReleaseFencePromiseStatus;
}
-void LayerFE::setHwcCompositionType(
- aidl::android::hardware::graphics::composer3::Composition type) {
- mLastHwcCompositionType = type;
+void LayerFE::setLastHwcState(const LayerFE::HwcLayerDebugState &state) {
+ mLastHwcState = state;
}
-aidl::android::hardware::graphics::composer3::Composition LayerFE::getHwcCompositionType() const {
- return mLastHwcCompositionType;
-}
+const LayerFE::HwcLayerDebugState& LayerFE::getLastHwcState() const {
+ return mLastHwcState;
+};
} // namespace android
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
index 64ec27862d..a537456beb 100644
--- a/services/surfaceflinger/LayerFE.h
+++ b/services/surfaceflinger/LayerFE.h
@@ -59,9 +59,10 @@ public:
void setReleaseFence(const FenceResult& releaseFence) override;
LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() override;
void onPictureProfileCommitted() override;
- void setHwcCompositionType(aidl::android::hardware::graphics::composer3::Composition) override;
- aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
- const override;
+
+ // Used for debugging purposes, e.g. perfetto tracing, dumpsys.
+ void setLastHwcState(const HwcLayerDebugState &state) override;
+ const HwcLayerDebugState &getLastHwcState() const override;
std::unique_ptr<surfaceflinger::frontend::LayerSnapshot> mSnapshot;
@@ -93,8 +94,7 @@ private:
std::string mName;
std::promise<FenceResult> mReleaseFence;
ReleaseFencePromiseStatus mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::UNINITIALIZED;
- aidl::android::hardware::graphics::composer3::Composition mLastHwcCompositionType =
- aidl::android::hardware::graphics::composer3::Composition::INVALID;
+ HwcLayerDebugState mLastHwcState;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index eecdd72727..f24e441a54 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2980,6 +2980,8 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
int index = 0;
ftl::StaticVector<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary;
auto lastLayerStack = ui::INVALID_LAYER_STACK;
+
+ uint64_t prevOverrideBufferId = 0;
for (auto& [layer, layerFE] : layers) {
CompositionResult compositionResult{layerFE->stealCompositionResult()};
if (lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) {
@@ -2989,8 +2991,37 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
}
lastLayerStack = layerFE->mSnapshot->outputFilter.layerStack;
}
+
+ // If there are N layers in a cached set they should all share the same buffer id.
+ // The first layer in the cached set will be not skipped and layers 1..N-1 will be skipped.
+ // We expect all layers in the cached set to be marked as composited by HWC.
+ // Here is a made up example of how it is visualized
+ //
+ // [b:rrc][s:cc]
+ //
+ // This should be interpreted to mean that there are 2 cached sets.
+ // So there are only 2 non skipped layers -- b and s.
+ // The layers rrc and cc are flattened into layers b and s respectively.
+ const LayerFE::HwcLayerDebugState &hwcState = layerFE->getLastHwcState();
+ if (hwcState.overrideBufferId != prevOverrideBufferId) {
+ // End the existing run.
+ if (prevOverrideBufferId) {
+ compositionSummary.push_back(']');
+ }
+ // Start a new run.
+ if (hwcState.overrideBufferId) {
+ compositionSummary.push_back('[');
+ }
+ }
+
compositionSummary.push_back(
- layerFE->mSnapshot->classifyCompositionForDebug(layerFE->getHwcCompositionType()));
+ layerFE->mSnapshot->classifyCompositionForDebug(hwcState));
+
+ if (hwcState.overrideBufferId && !hwcState.wasSkipped) {
+ compositionSummary.push_back(':');
+ }
+ prevOverrideBufferId = hwcState.overrideBufferId;
+
if (layerFE->mSnapshot->hasEffect()) {
compositedWorkload |= adpf::Workload::EFFECTS;
}
@@ -3002,6 +3033,10 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
mActivePictureTracker.onLayerComposed(*layer, *layerFE, compositionResult);
}
}
+ // End the last run.
+ if (prevOverrideBufferId) {
+ compositionSummary.push_back(']');
+ }
// Concisely describe the layers composited this frame using single chars. GPU composited layers
// are uppercase, DPU composited are lowercase. Special chars denote effects (blur, shadow,
diff --git a/services/surfaceflinger/common/include/common/WorkloadTracer.h b/services/surfaceflinger/common/include/common/WorkloadTracer.h
index 39b6fa1bf4..c4074f72ff 100644
--- a/services/surfaceflinger/common/include/common/WorkloadTracer.h
+++ b/services/surfaceflinger/common/include/common/WorkloadTracer.h
@@ -23,7 +23,7 @@ namespace android::WorkloadTracer {
static constexpr int32_t COMPOSITION_TRACE_COOKIE = 1;
static constexpr int32_t POST_COMPOSITION_TRACE_COOKIE = 2;
-static constexpr size_t COMPOSITION_SUMMARY_SIZE = 20;
+static constexpr size_t COMPOSITION_SUMMARY_SIZE = 64;
static constexpr const char* TRACK_NAME = "CriticalWorkload";
} // namespace android::WorkloadTracer \ No newline at end of file