Skip to content

Commit ad9d514

Browse files
committed
Demarcate cached sets in composition summary
Previously, the composition summary indicated that HWC was compositing more layers than it actually was. Example when youtube video open and playing in a free form window Before: bbrrrRrbbb After: [b:brr]r[R:rbbb] So there are 2 cached sets and 1 uncached set. One cached set and one uncached layer is composited by HWC, the other cached set is composed by the GPU. Bug: 391428079 Flag: EXEMPT log only update Test: Capture perfetto trace and confirm layers are skipped and overridden as expected Change-Id: I4ffda43f5248ef8bb690cdaca0eeca7ffac3d997
1 parent 01e3f8a commit ad9d514

9 files changed

Lines changed: 101 additions & 37 deletions

File tree

services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <optional>
2020
#include <ostream>
2121
#include <unordered_set>
22+
#include "aidl/android/hardware/graphics/composer3/Composition.h"
2223
#include "ui/LayerStack.h"
2324

2425
// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -36,10 +37,6 @@
3637
#include <utils/RefBase.h>
3738
#include <utils/Timers.h>
3839

39-
namespace aidl::android::hardware::graphics::composer3 {
40-
enum class Composition;
41-
}
42-
4340
namespace android {
4441

4542
class Fence;
@@ -182,10 +179,27 @@ class LayerFE : public virtual RefBase {
182179
// Whether the layer should be rendered with rounded corners.
183180
virtual bool hasRoundedCorners() const = 0;
184181
virtual void setWasClientComposed(const sp<Fence>&) {}
185-
virtual void setHwcCompositionType(
186-
aidl::android::hardware::graphics::composer3::Composition) = 0;
187-
virtual aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
188-
const = 0;
182+
183+
// These fields are all copied from the last written HWC state.
184+
// This state is only used for debugging purposes.
185+
struct HwcLayerDebugState {
186+
aidl::android::hardware::graphics::composer3::Composition lastCompositionType =
187+
aidl::android::hardware::graphics::composer3::Composition::INVALID;
188+
// Corresponds to passing an alpha of 0 to HWC2::Layer::setPlaneAlpha.
189+
bool wasSkipped = false;
190+
191+
// Indicates whether the compositionengine::OutputLayer had properties overwritten.
192+
// Not directly passed to HWC.
193+
bool wasOverridden = false;
194+
195+
// Corresponds to the GraphicBuffer ID of the buffer passed to HWC2::Layer::setBuffer.
196+
// This buffer corresponds to a CachedSet that the LayerFE was flattened to.
197+
uint64_t overrideBufferId = 0;
198+
};
199+
200+
// Used for debugging purposes, e.g. perfetto tracing, dumpsys.
201+
virtual void setLastHwcState(const LayerFE::HwcLayerDebugState &hwcState) = 0;
202+
virtual const HwcLayerDebugState &getLastHwcState() const = 0;
189203

190204
virtual const gui::LayerMetadata* getMetadata() const = 0;
191205
virtual const gui::LayerMetadata* getRelativeMetadata() const = 0;

services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ class LayerFE : public compositionengine::LayerFE {
5959
MOCK_CONST_METHOD0(getMetadata, gui::LayerMetadata*());
6060
MOCK_CONST_METHOD0(getRelativeMetadata, gui::LayerMetadata*());
6161
MOCK_METHOD0(onPictureProfileCommitted, void());
62-
MOCK_METHOD(void, setHwcCompositionType,
63-
(aidl::android::hardware::graphics::composer3::Composition), (override));
64-
MOCK_METHOD(aidl::android::hardware::graphics::composer3::Composition, getHwcCompositionType,
62+
MOCK_METHOD(void, setLastHwcState,
63+
(const HwcLayerDebugState&), (override));
64+
MOCK_METHOD(const HwcLayerDebugState&, getLastHwcState,
6565
(), (const, override));
6666
};
6767

services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,15 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t
502502

503503
editState().hwc->stateOverridden = isOverridden;
504504
editState().hwc->layerSkipped = skipLayer;
505+
506+
507+
// Save the final HWC state for debugging purposes, e.g. perfetto tracing, dumpsys.
508+
getLayerFE().setLastHwcState({.lastCompositionType = editState().hwc->hwcCompositionType,
509+
.wasSkipped = skipLayer,
510+
.wasOverridden = isOverridden,
511+
.overrideBufferId = editState().overrideInfo.buffer
512+
? editState().overrideInfo.buffer.get()->getId()
513+
: 0});
505514
}
506515

507516
void OutputLayer::writeOutputDependentGeometryStateToHWC(HWC2::Layer* hwcLayer,
@@ -867,7 +876,6 @@ void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer,
867876
if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType ||
868877
(outputDependentState.hwc->layerSkipped && !skipLayer)) {
869878
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
870-
getLayerFE().setHwcCompositionType(requestedCompositionType);
871879

872880
if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
873881
error != hal::Error::NONE) {
@@ -965,7 +973,13 @@ void OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType)
965973
}
966974

967975
hwcState.hwcCompositionType = compositionType;
968-
getLayerFE().setHwcCompositionType(compositionType);
976+
977+
getLayerFE().setLastHwcState({.lastCompositionType = hwcState.hwcCompositionType,
978+
.wasSkipped = hwcState.layerSkipped,
979+
.wasOverridden = hwcState.stateOverridden,
980+
.overrideBufferId = state.overrideInfo.buffer
981+
? state.overrideInfo.buffer.get()->getId()
982+
: 0});
969983
}
970984

971985
void OutputLayer::prepareForDeviceLayerRequests() {

services/surfaceflinger/FrontEnd/LayerSnapshot.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,13 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate
537537
}
538538
}
539539

540-
char LayerSnapshot::classifyCompositionForDebug(Composition compositionType) const {
540+
char LayerSnapshot::classifyCompositionForDebug(
541+
const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const {
541542
if (!isVisible) {
542543
return '.';
543544
}
544545

545-
switch (compositionType) {
546+
switch (hwcState.lastCompositionType) {
546547
case Composition::INVALID:
547548
return 'i';
548549
case Composition::SOLID_COLOR:
@@ -561,21 +562,21 @@ char LayerSnapshot::classifyCompositionForDebug(Composition compositionType) con
561562
}
562563

563564
char code = '.'; // Default to invisible
564-
if (hasBufferOrSidebandStream()) {
565-
code = 'b';
566-
} else if (fillsColor()) {
567-
code = 'c'; // Solid color
568-
} else if (hasBlur()) {
565+
if (hasBlur()) {
569566
code = 'l'; // Blur
570567
} else if (hasProtectedContent) {
571568
code = 'p'; // Protected content
572-
} else if (drawShadows()) {
573-
code = 's'; // Shadow
574569
} else if (roundedCorner.hasRoundedCorners()) {
575570
code = 'r'; // Rounded corners
571+
} else if (drawShadows()) {
572+
code = 's'; // Shadow
573+
} else if (fillsColor()) {
574+
code = 'c'; // Solid color
575+
} else if (hasBufferOrSidebandStream()) {
576+
code = 'b';
576577
}
577578

578-
if (compositionType == Composition::CLIENT) {
579+
if (hwcState.lastCompositionType == Composition::CLIENT) {
579580
return static_cast<char>(std::toupper(code));
580581
} else {
581582
return code;

services/surfaceflinger/FrontEnd/LayerSnapshot.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "RequestedLayerState.h"
2525
#include "Scheduler/LayerInfo.h"
2626
#include "android-base/stringprintf.h"
27+
#include "compositionengine/LayerFE.h"
2728

2829
namespace android::surfaceflinger::frontend {
2930

@@ -163,7 +164,7 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
163164
// Returns a char summarizing the composition request
164165
// This function tries to maintain parity with planner::Plan chars.
165166
char classifyCompositionForDebug(
166-
aidl::android::hardware::graphics::composer3::Composition compositionType) const;
167+
const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const;
167168
};
168169

169170
} // namespace android::surfaceflinger::frontend

services/surfaceflinger/LayerFE.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,13 +428,12 @@ LayerFE::ReleaseFencePromiseStatus LayerFE::getReleaseFencePromiseStatus() {
428428
return mReleaseFencePromiseStatus;
429429
}
430430

431-
void LayerFE::setHwcCompositionType(
432-
aidl::android::hardware::graphics::composer3::Composition type) {
433-
mLastHwcCompositionType = type;
431+
void LayerFE::setLastHwcState(const LayerFE::HwcLayerDebugState &state) {
432+
mLastHwcState = state;
434433
}
435434

436-
aidl::android::hardware::graphics::composer3::Composition LayerFE::getHwcCompositionType() const {
437-
return mLastHwcCompositionType;
438-
}
435+
const LayerFE::HwcLayerDebugState& LayerFE::getLastHwcState() const {
436+
return mLastHwcState;
437+
};
439438

440439
} // namespace android

services/surfaceflinger/LayerFE.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ class LayerFE : public virtual RefBase, public virtual compositionengine::LayerF
5959
void setReleaseFence(const FenceResult& releaseFence) override;
6060
LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() override;
6161
void onPictureProfileCommitted() override;
62-
void setHwcCompositionType(aidl::android::hardware::graphics::composer3::Composition) override;
63-
aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
64-
const override;
62+
63+
// Used for debugging purposes, e.g. perfetto tracing, dumpsys.
64+
void setLastHwcState(const HwcLayerDebugState &state) override;
65+
const HwcLayerDebugState &getLastHwcState() const override;
6566

6667
std::unique_ptr<surfaceflinger::frontend::LayerSnapshot> mSnapshot;
6768

@@ -93,8 +94,7 @@ class LayerFE : public virtual RefBase, public virtual compositionengine::LayerF
9394
std::string mName;
9495
std::promise<FenceResult> mReleaseFence;
9596
ReleaseFencePromiseStatus mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::UNINITIALIZED;
96-
aidl::android::hardware::graphics::composer3::Composition mLastHwcCompositionType =
97-
aidl::android::hardware::graphics::composer3::Composition::INVALID;
97+
HwcLayerDebugState mLastHwcState;
9898
};
9999

100100
} // namespace android

services/surfaceflinger/SurfaceFlinger.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2980,6 +2980,8 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
29802980
int index = 0;
29812981
ftl::StaticVector<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary;
29822982
auto lastLayerStack = ui::INVALID_LAYER_STACK;
2983+
2984+
uint64_t prevOverrideBufferId = 0;
29832985
for (auto& [layer, layerFE] : layers) {
29842986
CompositionResult compositionResult{layerFE->stealCompositionResult()};
29852987
if (lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) {
@@ -2989,8 +2991,37 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
29892991
}
29902992
lastLayerStack = layerFE->mSnapshot->outputFilter.layerStack;
29912993
}
2994+
2995+
// If there are N layers in a cached set they should all share the same buffer id.
2996+
// The first layer in the cached set will be not skipped and layers 1..N-1 will be skipped.
2997+
// We expect all layers in the cached set to be marked as composited by HWC.
2998+
// Here is a made up example of how it is visualized
2999+
//
3000+
// [b:rrc][s:cc]
3001+
//
3002+
// This should be interpreted to mean that there are 2 cached sets.
3003+
// So there are only 2 non skipped layers -- b and s.
3004+
// The layers rrc and cc are flattened into layers b and s respectively.
3005+
const LayerFE::HwcLayerDebugState &hwcState = layerFE->getLastHwcState();
3006+
if (hwcState.overrideBufferId != prevOverrideBufferId) {
3007+
// End the existing run.
3008+
if (prevOverrideBufferId) {
3009+
compositionSummary.push_back(']');
3010+
}
3011+
// Start a new run.
3012+
if (hwcState.overrideBufferId) {
3013+
compositionSummary.push_back('[');
3014+
}
3015+
}
3016+
29923017
compositionSummary.push_back(
2993-
layerFE->mSnapshot->classifyCompositionForDebug(layerFE->getHwcCompositionType()));
3018+
layerFE->mSnapshot->classifyCompositionForDebug(hwcState));
3019+
3020+
if (hwcState.overrideBufferId && !hwcState.wasSkipped) {
3021+
compositionSummary.push_back(':');
3022+
}
3023+
prevOverrideBufferId = hwcState.overrideBufferId;
3024+
29943025
if (layerFE->mSnapshot->hasEffect()) {
29953026
compositedWorkload |= adpf::Workload::EFFECTS;
29963027
}
@@ -3002,6 +3033,10 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
30023033
mActivePictureTracker.onLayerComposed(*layer, *layerFE, compositionResult);
30033034
}
30043035
}
3036+
// End the last run.
3037+
if (prevOverrideBufferId) {
3038+
compositionSummary.push_back(']');
3039+
}
30053040

30063041
// Concisely describe the layers composited this frame using single chars. GPU composited layers
30073042
// are uppercase, DPU composited are lowercase. Special chars denote effects (blur, shadow,

services/surfaceflinger/common/include/common/WorkloadTracer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace android::WorkloadTracer {
2323

2424
static constexpr int32_t COMPOSITION_TRACE_COOKIE = 1;
2525
static constexpr int32_t POST_COMPOSITION_TRACE_COOKIE = 2;
26-
static constexpr size_t COMPOSITION_SUMMARY_SIZE = 20;
26+
static constexpr size_t COMPOSITION_SUMMARY_SIZE = 64;
2727
static constexpr const char* TRACK_NAME = "CriticalWorkload";
2828

2929
} // namespace android::WorkloadTracer

0 commit comments

Comments
 (0)