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

Commit 60776fcb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "SF: Clean up HWC2::Layer ownership" into sc-dev am: e9f6e108

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/14471627

Change-Id: I2df4899eab7a809ba383b4a79bb753aa92bfb76d
parents fcb539ed e9f6e108
Loading
Loading
Loading
Loading
+1 −10
Original line number Diff line number Diff line
@@ -192,16 +192,7 @@ std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
    if (const auto halDisplayId = HalDisplayId::tryCast(mId);
        outputLayer && !mIsDisconnected && halDisplayId) {
        auto& hwc = getCompositionEngine().getHwComposer();
        // Note: For the moment we ensure it is safe to take a reference to the
        // HWComposer implementation by destroying all the OutputLayers (and
        // hence the HWC2::Layers they own) before setting a new HWComposer. See
        // for example SurfaceFlinger::updateVrFlinger().
        // TODO(b/121291683): Make this safer.
        auto hwcLayer =
                std::shared_ptr<HWC2::Layer>(hwc.createLayer(*halDisplayId),
                                             [&hwc, id = *halDisplayId](HWC2::Layer* layer) {
                                                 hwc.destroyLayer(id, layer);
                                             });
        auto hwcLayer = hwc.createLayer(*halDisplayId);
        ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
                 getName().c_str());
        outputLayer->setHwcLayer(std::move(hwcLayer));
+3 −4
Original line number Diff line number Diff line
@@ -533,16 +533,15 @@ using DisplayCreateOutputLayerTest = FullDisplayImplTestCommon;

TEST_F(DisplayCreateOutputLayerTest, setsHwcLayer) {
    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
    StrictMock<HWC2::mock::Layer> hwcLayer;
    auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();

    EXPECT_CALL(mHwComposer, createLayer(HalDisplayId(DEFAULT_DISPLAY_ID)))
            .WillOnce(Return(&hwcLayer));
            .WillOnce(Return(hwcLayer));

    auto outputLayer = mDisplay->createOutputLayer(layerFE);

    EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
    EXPECT_EQ(hwcLayer.get(), outputLayer->getHwcLayer());

    EXPECT_CALL(mHwComposer, destroyLayer(HalDisplayId(DEFAULT_DISPLAY_ID), &hwcLayer));
    outputLayer.reset();
}

+1 −2
Original line number Diff line number Diff line
@@ -48,8 +48,7 @@ public:
    MOCK_METHOD3(allocateVirtualDisplay,
                 std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
    MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
    MOCK_METHOD1(createLayer, HWC2::Layer*(HalDisplayId));
    MOCK_METHOD2(destroyLayer, void(HalDisplayId, HWC2::Layer*));
    MOCK_METHOD1(createLayer, std::shared_ptr<HWC2::Layer>(HalDisplayId));
    MOCK_METHOD4(getDeviceCompositionChanges,
                 status_t(HalDisplayId, bool, std::chrono::steady_clock::time_point,
                          std::optional<android::HWComposer::DeviceRequestedChanges>*));
+142 −52
Original line number Diff line number Diff line
@@ -78,7 +78,19 @@ Display::Display(android::Hwc2::Composer& composer,
}

Display::~Display() {
    mLayers.clear();
    // Note: The calls to onOwningDisplayDestroyed() are allowed (and expected)
    // to call Display::onLayerDestroyed(). As that call removes entries from
    // mLayers, we do not want to have a for loop directly over it here. Since
    // the end goal is an empty mLayers anyway, we just go ahead and swap an
    // initially empty local container with mLayers, and then enumerate
    // the contents of the local container.
    Layers destroyingLayers;
    std::swap(mLayers, destroyingLayers);
    for (const auto& [_, weakLayer] : destroyingLayers) {
        if (std::shared_ptr layer = weakLayer.lock()) {
            layer->onOwningDisplayDestroyed();
        }
    }

    Error error = Error::NONE;
    const char* msg;
@@ -110,29 +122,21 @@ Error Display::acceptChanges()
    return static_cast<Error>(intError);
}

Error Display::createLayer(HWC2::Layer** outLayer) {
    if (!outLayer) {
        return Error::BAD_PARAMETER;
    }
base::expected<std::shared_ptr<HWC2::Layer>, hal::Error> Display::createLayer() {
    HWLayerId layerId = 0;
    auto intError = mComposer.createLayer(mId, &layerId);
    auto error = static_cast<Error>(intError);
    if (error != Error::NONE) {
        return error;
        return base::unexpected(error);
    }

    auto layer = std::make_unique<impl::Layer>(mComposer, mCapabilities, mId, layerId);
    *outLayer = layer.get();
    mLayers.emplace(layerId, std::move(layer));
    return Error::NONE;
    auto layer = std::make_shared<impl::Layer>(mComposer, mCapabilities, *this, layerId);
    mLayers.emplace(layerId, layer);
    return layer;
}

Error Display::destroyLayer(HWC2::Layer* layer) {
    if (!layer) {
        return Error::BAD_PARAMETER;
    }
    mLayers.erase(layer->getId());
    return Error::NONE;
void Display::onLayerDestroyed(hal::HWLayerId layerId) {
    mLayers.erase(layerId);
}

bool Display::isVsyncPeriodSwitchSupported() const {
@@ -161,7 +165,7 @@ Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Compo
            auto type = types[element];
            ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
                    layer->getId(), to_string(type).c_str());
            outTypes->emplace(layer, type);
            outTypes->emplace(layer.get(), type);
        } else {
            ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
                    " on display %" PRIu64, layerIds[element], mId);
@@ -254,7 +258,7 @@ Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
        if (layer) {
            auto layerRequest =
                    static_cast<LayerRequest>(layerRequests[element]);
            outLayerRequests->emplace(layer, layerRequest);
            outLayerRequests->emplace(layer.get(), layerRequest);
        } else {
            ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
                    PRIu64, layerIds[element], mId);
@@ -340,7 +344,7 @@ Error Display::getReleaseFences(std::unordered_map<HWC2::Layer*, sp<Fence>>* out
        auto layer = getLayerById(layerIds[element]);
        if (layer) {
            sp<Fence> fence(new Fence(fenceFds[element]));
            releaseFences.emplace(layer, fence);
            releaseFences.emplace(layer.get(), fence);
        } else {
            ALOGE("getReleaseFences: invalid layer %" PRIu64
                    " found on display %" PRIu64, layerIds[element], mId);
@@ -550,12 +554,9 @@ void Display::setConnected(bool connected) {

// Other Display methods

HWC2::Layer* Display::getLayerById(HWLayerId id) const {
    if (mLayers.count(id) == 0) {
        return nullptr;
    }

    return mLayers.at(id).get();
std::shared_ptr<HWC2::Layer> Display::getLayerById(HWLayerId id) const {
    auto it = mLayers.find(id);
    return it != mLayers.end() ? it->second.lock() : nullptr;
}
} // namespace impl

@@ -566,47 +567,78 @@ Layer::~Layer() = default;
namespace impl {

Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
             HWDisplayId displayId, HWLayerId layerId)
             HWC2::Display& display, HWLayerId layerId)
      : mComposer(composer),
        mCapabilities(capabilities),
        mDisplayId(displayId),
        mDisplay(&display),
        mId(layerId),
        mColorMatrix(android::mat4()) {
    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId);
    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, display.getId());
}

Layer::~Layer()
{
    auto intError = mComposer.destroyLayer(mDisplayId, mId);
    onOwningDisplayDestroyed();
}

void Layer::onOwningDisplayDestroyed() {
    // Note: onOwningDisplayDestroyed() may be called to perform cleanup by
    // either the Layer dtor or by the Display dtor and must be safe to call
    // from either path. In particular, the call to Display::onLayerDestroyed()
    // is expected to be safe to do,

    if (CC_UNLIKELY(!mDisplay)) {
        return;
    }

    mDisplay->onLayerDestroyed(mId);

    // Note: If the HWC display was actually disconnected, these calls are will
    // return an error. We always make them as there may be other reasons for
    // the HWC2::Display to be destroyed.
    auto intError = mComposer.destroyLayer(mDisplay->getId(), mId);
    auto error = static_cast<Error>(intError);
    ALOGE_IF(error != Error::NONE,
             "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
             " failed: %s (%d)",
             mDisplayId, mId, to_string(error).c_str(), intError);
             mDisplay->getId(), mId, to_string(error).c_str(), intError);

    mDisplay = nullptr;
}

Error Layer::setCursorPosition(int32_t x, int32_t y)
{
    auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError = mComposer.setCursorPosition(mDisplay->getId(), mId, x, y);
    return static_cast<Error>(intError);
}

Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
        const sp<Fence>& acquireFence)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (buffer == nullptr && mBufferSlot == slot) {
        return Error::NONE;
    }
    mBufferSlot = slot;

    int32_t fenceFd = acquireFence->dup();
    auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer,
                                             fenceFd);
    auto intError = mComposer.setLayerBuffer(mDisplay->getId(), mId, slot, buffer, fenceFd);
    return static_cast<Error>(intError);
}

Error Layer::setSurfaceDamage(const Region& damage)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (damage.isRect() && mDamageRegion.isRect() &&
        (damage.getBounds() == mDamageRegion.getBounds())) {
        return Error::NONE;
@@ -617,8 +649,8 @@ Error Layer::setSurfaceDamage(const Region& damage)
    // rects for HWC
    Hwc2::Error intError = Hwc2::Error::NONE;
    if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
        intError = mComposer.setLayerSurfaceDamage(mDisplayId,
                mId, std::vector<Hwc2::IComposerClient::Rect>());
        intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId,
                                                   std::vector<Hwc2::IComposerClient::Rect>());
    } else {
        size_t rectCount = 0;
        auto rectArray = damage.getArray(&rectCount);
@@ -629,7 +661,7 @@ Error Layer::setSurfaceDamage(const Region& damage)
                    rectArray[rect].right, rectArray[rect].bottom});
        }

        intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects);
        intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId, hwcRects);
    }

    return static_cast<Error>(intError);
@@ -637,34 +669,54 @@ Error Layer::setSurfaceDamage(const Region& damage)

Error Layer::setBlendMode(BlendMode mode)
{
    auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, mode);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError = mComposer.setLayerBlendMode(mDisplay->getId(), mId, mode);
    return static_cast<Error>(intError);
}

Error Layer::setColor(Color color) {
    auto intError = mComposer.setLayerColor(mDisplayId, mId, color);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError = mComposer.setLayerColor(mDisplay->getId(), mId, color);
    return static_cast<Error>(intError);
}

Error Layer::setCompositionType(Composition type)
{
    auto intError = mComposer.setLayerCompositionType(mDisplayId, mId, type);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError = mComposer.setLayerCompositionType(mDisplay->getId(), mId, type);
    return static_cast<Error>(intError);
}

Error Layer::setDataspace(Dataspace dataspace)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (dataspace == mDataSpace) {
        return Error::NONE;
    }
    mDataSpace = dataspace;
    auto intError = mComposer.setLayerDataspace(mDisplayId, mId, mDataSpace);
    auto intError = mComposer.setLayerDataspace(mDisplay->getId(), mId, mDataSpace);
    return static_cast<Error>(intError);
}

Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
        const android::HdrMetadata& metadata)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (metadata == mHdrMetadata) {
        return Error::NONE;
    }
@@ -705,7 +757,7 @@ Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
    }

    Error error = static_cast<Error>(
            mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas));
            mComposer.setLayerPerFrameMetadata(mDisplay->getId(), mId, perFrameMetadatas));

    if (validTypes & HdrMetadata::HDR10PLUS) {
        if (CC_UNLIKELY(mHdrMetadata.hdr10plus.size() == 0)) {
@@ -715,8 +767,9 @@ Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
        std::vector<Hwc2::PerFrameMetadataBlob> perFrameMetadataBlobs;
        perFrameMetadataBlobs.push_back(
                {Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI, mHdrMetadata.hdr10plus});
        Error setMetadataBlobsError = static_cast<Error>(
                mComposer.setLayerPerFrameMetadataBlobs(mDisplayId, mId, perFrameMetadataBlobs));
        Error setMetadataBlobsError =
                static_cast<Error>(mComposer.setLayerPerFrameMetadataBlobs(mDisplay->getId(), mId,
                                                                           perFrameMetadataBlobs));
        if (error == Error::NONE) {
            return setMetadataBlobsError;
        }
@@ -726,46 +779,70 @@ Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,

Error Layer::setDisplayFrame(const Rect& frame)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
        frame.right, frame.bottom};
    auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect);
    auto intError = mComposer.setLayerDisplayFrame(mDisplay->getId(), mId, hwcRect);
    return static_cast<Error>(intError);
}

Error Layer::setPlaneAlpha(float alpha)
{
    auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError = mComposer.setLayerPlaneAlpha(mDisplay->getId(), mId, alpha);
    return static_cast<Error>(intError);
}

Error Layer::setSidebandStream(const native_handle_t* stream)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (mCapabilities.count(Capability::SIDEBAND_STREAM) == 0) {
        ALOGE("Attempted to call setSidebandStream without checking that the "
                "device supports sideband streams");
        return Error::UNSUPPORTED;
    }
    auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream);
    auto intError = mComposer.setLayerSidebandStream(mDisplay->getId(), mId, stream);
    return static_cast<Error>(intError);
}

Error Layer::setSourceCrop(const FloatRect& crop)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    Hwc2::IComposerClient::FRect hwcRect{
        crop.left, crop.top, crop.right, crop.bottom};
    auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect);
    auto intError = mComposer.setLayerSourceCrop(mDisplay->getId(), mId, hwcRect);
    return static_cast<Error>(intError);
}

Error Layer::setTransform(Transform transform)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intTransform = static_cast<Hwc2::Transform>(transform);
    auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform);
    auto intError = mComposer.setLayerTransform(mDisplay->getId(), mId, intTransform);
    return static_cast<Error>(intError);
}

Error Layer::setVisibleRegion(const Region& region)
{
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (region.isRect() && mVisibleRegion.isRect() &&
        (region.getBounds() == mVisibleRegion.getBounds())) {
        return Error::NONE;
@@ -781,22 +858,30 @@ Error Layer::setVisibleRegion(const Region& region)
                rectArray[rect].right, rectArray[rect].bottom});
    }

    auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects);
    auto intError = mComposer.setLayerVisibleRegion(mDisplay->getId(), mId, hwcRects);
    return static_cast<Error>(intError);
}

Error Layer::setZOrder(uint32_t z)
{
    auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError = mComposer.setLayerZOrder(mDisplay->getId(), mId, z);
    return static_cast<Error>(intError);
}

// Composer HAL 2.3
Error Layer::setColorTransform(const android::mat4& matrix) {
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    if (matrix == mColorMatrix) {
        return Error::NONE;
    }
    auto intError = mComposer.setLayerColorTransform(mDisplayId, mId, matrix.asArray());
    auto intError = mComposer.setLayerColorTransform(mDisplay->getId(), mId, matrix.asArray());
    Error error = static_cast<Error>(intError);
    if (error != Error::NONE) {
        return error;
@@ -808,7 +893,12 @@ Error Layer::setColorTransform(const android::mat4& matrix) {
// Composer HAL 2.4
Error Layer::setLayerGenericMetadata(const std::string& name, bool mandatory,
                                     const std::vector<uint8_t>& value) {
    auto intError = mComposer.setLayerGenericMetadata(mDisplayId, mId, name, mandatory, value);
    if (CC_UNLIKELY(!mDisplay)) {
        return Error::BAD_DISPLAY;
    }

    auto intError =
            mComposer.setLayerGenericMetadata(mDisplay->getId(), mId, name, mandatory, value);
    return static_cast<Error>(intError);
}

+20 −13
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#pragma once

#include <android-base/expected.h>
#include <gui/HdrMetadata.h>
#include <math/mat4.h>
#include <ui/HdrCapabilities.h>
@@ -84,10 +85,11 @@ public:
    virtual void setConnected(bool connected) = 0; // For use by Device only
    virtual const std::unordered_set<hal::DisplayCapability>& getCapabilities() const = 0;
    virtual bool isVsyncPeriodSwitchSupported() const = 0;
    virtual void onLayerDestroyed(hal::HWLayerId layerId) = 0;

    [[clang::warn_unused_result]] virtual hal::Error acceptChanges() = 0;
    [[clang::warn_unused_result]] virtual hal::Error createLayer(Layer** outLayer) = 0;
    [[clang::warn_unused_result]] virtual hal::Error destroyLayer(Layer* layer) = 0;
    [[clang::warn_unused_result]] virtual base::expected<std::shared_ptr<HWC2::Layer>, hal::Error>
    createLayer() = 0;
    [[clang::warn_unused_result]] virtual hal::Error getChangedCompositionTypes(
            std::unordered_map<Layer*, hal::Composition>* outTypes) = 0;
    [[clang::warn_unused_result]] virtual hal::Error getColorModes(
@@ -152,6 +154,8 @@ public:

namespace impl {

class Layer;

class Display : public HWC2::Display {
public:
    Display(android::Hwc2::Composer&, const std::unordered_set<hal::Capability>&, hal::HWDisplayId,
@@ -160,10 +164,9 @@ public:

    // Required by HWC2
    hal::Error acceptChanges() override;
    hal::Error createLayer(Layer** outLayer) override;
    hal::Error destroyLayer(Layer*) override;
    base::expected<std::shared_ptr<HWC2::Layer>, hal::Error> createLayer() override;
    hal::Error getChangedCompositionTypes(
            std::unordered_map<Layer*, hal::Composition>* outTypes) override;
            std::unordered_map<HWC2::Layer*, hal::Composition>* outTypes) override;
    hal::Error getColorModes(std::vector<hal::ColorMode>* outModes) const override;
    // Returns a bitmask which contains HdrMetadata::Type::*.
    int32_t getSupportedPerFrameMetadata() const override;
@@ -174,7 +177,7 @@ public:
    hal::Error getName(std::string* outName) const override;
    hal::Error getRequests(
            hal::DisplayRequest* outDisplayRequests,
            std::unordered_map<Layer*, hal::LayerRequest>* outLayerRequests) override;
            std::unordered_map<HWC2::Layer*, hal::LayerRequest>* outLayerRequests) override;
    hal::Error getConnectionType(ui::DisplayConnectionType*) const override;
    hal::Error supportsDoze(bool* outSupport) const override;
    hal::Error getHdrCapabilities(android::HdrCapabilities* outCapabilities) const override;
@@ -185,8 +188,8 @@ public:
                                                uint64_t maxFrames) const override;
    hal::Error getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
                                         android::DisplayedFrameStats* outStats) const override;
    hal::Error getReleaseFences(
            std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const override;
    hal::Error getReleaseFences(std::unordered_map<HWC2::Layer*, android::sp<android::Fence>>*
                                        outFences) const override;
    hal::Error present(android::sp<android::Fence>* outPresentFence) override;
    hal::Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target,
                               const android::sp<android::Fence>& acquireFence,
@@ -218,13 +221,14 @@ public:
    const std::unordered_set<hal::DisplayCapability>& getCapabilities() const override {
        return mDisplayCapabilities;
    };
    virtual bool isVsyncPeriodSwitchSupported() const override;
    bool isVsyncPeriodSwitchSupported() const override;
    void onLayerDestroyed(hal::HWLayerId layerId) override;

private:

    // This may fail (and return a null pointer) if no layer with this ID exists
    // on this display
    Layer* getLayerById(hal::HWLayerId) const;
    std::shared_ptr<HWC2::Layer> getLayerById(hal::HWLayerId id) const;

    friend android::TestableSurfaceFlinger;

@@ -240,7 +244,8 @@ private:
    hal::DisplayType mType;
    bool mIsConnected = false;

    std::unordered_map<hal::HWLayerId, std::unique_ptr<Layer>> mLayers;
    using Layers = std::unordered_map<hal::HWLayerId, std::weak_ptr<HWC2::impl::Layer>>;
    Layers mLayers;

    std::once_flag mDisplayCapabilityQueryFlag;
    std::unordered_set<hal::DisplayCapability> mDisplayCapabilities;
@@ -295,10 +300,12 @@ namespace impl {
class Layer : public HWC2::Layer {
public:
    Layer(android::Hwc2::Composer& composer,
          const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId displayId,
          const std::unordered_set<hal::Capability>& capabilities, HWC2::Display& display,
          hal::HWLayerId layerId);
    ~Layer() override;

    void onOwningDisplayDestroyed();

    hal::HWLayerId getId() const override { return mId; }

    hal::Error setCursorPosition(int32_t x, int32_t y) override;
@@ -334,7 +341,7 @@ private:
    android::Hwc2::Composer& mComposer;
    const std::unordered_set<hal::Capability>& mCapabilities;

    hal::HWDisplayId mDisplayId;
    HWC2::Display* mDisplay;
    hal::HWLayerId mId;

    // Cached HWC2 data, to ensure the same commands aren't sent to the HWC
Loading