Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad9d5147 authored by Cairn Overturf's avatar Cairn Overturf
Browse files

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
parent 01e3f8a3
Loading
Loading
Loading
Loading
+22 −8
Original line number Diff line number Diff line
@@ -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;
+3 −3
Original line number Diff line number Diff line
@@ -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));
};

+16 −2
Original line number Diff line number Diff line
@@ -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() {
+11 −10
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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
Loading