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

Commit 5d89c1d6 authored by David Sodman's avatar David Sodman
Browse files

SF: use shared_ptr to track hwcLayer

Add a wrapper class and use std::shared_ptr to track instances
of hwcLayer.  This is necessary because the calculation of
data for HWComposer is done in Layer and the processing of that
data is done in SurfaceFlinger, and we need to make sure that
the hwcLayer is not destroyed by Layer while or before being
used by SurfaceFlinger.

Merged-in: Icc7c002b84aaded1966d24aa8f849b47f51d2efb

Test: Compile/Boot
Change-Id: Icc7c002b84aaded1966d24aa8f849b47f51d2efb
parent e63a09dc
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -575,14 +575,14 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
    auto hwcId = displayDevice->getHwcDisplayId();
    auto& hwcInfo = getBE().mHwcLayers[hwcId];
    auto& hwcLayer = hwcInfo.layer;
    auto error = hwcLayer->setVisibleRegion(visible);
    auto error = (*hwcLayer)->setVisibleRegion(visible);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
        visible.dump(LOG_TAG);
    }

    error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
    error = (*hwcLayer)->setSurfaceDamage(surfaceDamageRegion);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
@@ -593,7 +593,7 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
    if (getBE().compositionInfo.hwc.sidebandStream.get()) {
        setCompositionType(hwcId, HWC2::Composition::Sideband);
        ALOGV("[%s] Requesting Sideband composition", mName.string());
        error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
        error = (*hwcLayer)->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
        if (error != HWC2::Error::None) {
            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
                  getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
@@ -612,14 +612,14 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
    }

    ALOGV("setPerFrameData: dataspace = %d", mDrawingState.dataSpace);
    error = hwcLayer->setDataspace(mDrawingState.dataSpace);
    error = (*hwcLayer)->setDataspace(mDrawingState.dataSpace);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
              to_string(error).c_str(), static_cast<int32_t>(error));
    }

    const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
    error = hwcLayer->setHdrMetadata(metadata);
    error = (*hwcLayer)->setHdrMetadata(metadata);
    if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
        ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
@@ -631,7 +631,7 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
                                                       &hwcBuffer);

    auto acquireFence = mConsumer->getCurrentFence();
    error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
    error = (*hwcLayer)->setBuffer(hwcSlot, hwcBuffer, acquireFence);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
              getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
+4 −4
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
    auto hwcId = displayDevice->getHwcDisplayId();
    auto& hwcInfo = getBE().mHwcLayers[hwcId];
    auto& hwcLayer = hwcInfo.layer;
    auto error = hwcLayer->setVisibleRegion(visible);
    auto error = (*hwcLayer)->setVisibleRegion(visible);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
              to_string(error).c_str(), static_cast<int32_t>(error));
@@ -77,14 +77,14 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {

    setCompositionType(hwcId, HWC2::Composition::SolidColor);

    error = hwcLayer->setDataspace(mDrawingState.dataSpace);
    error = (*hwcLayer)->setDataspace(mDrawingState.dataSpace);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mDrawingState.dataSpace,
              to_string(error).c_str(), static_cast<int32_t>(error));
    }

    half4 color = getColor();
    error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
    error = (*hwcLayer)->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
                                static_cast<uint8_t>(std::round(255.0f * color.g)),
                                static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
    if (error != HWC2::Error::None) {
@@ -93,7 +93,7 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
    }

    // Clear out the transform, because it doesn't make sense absent a source buffer
    error = hwcLayer->setTransform(HWC2::Transform::None);
    error = (*hwcLayer)->setTransform(HWC2::Transform::None);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
              static_cast<int32_t>(error));
+18 −18
Original line number Diff line number Diff line
@@ -221,15 +221,14 @@ sp<IBinder> Layer::getHandle() {
bool Layer::createHwcLayer(HWComposer* hwc, int32_t hwcId) {
    LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0,
                        "Already have a layer for hwcId %d", hwcId);
    HWC2::Layer* layer = hwc->createLayer(hwcId);

    std::shared_ptr<LayerContainer> layer(new LayerContainer(hwc, hwcId));
    if (!layer) {
        return false;
    }
    LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[hwcId];
    hwcInfo.hwc = hwc;
    hwcInfo.layer = layer;
    layer->setLayerDestroyedListener(
            [this, hwcId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(hwcId); });
    return true;
}

@@ -240,11 +239,12 @@ bool Layer::destroyHwcLayer(int32_t hwcId) {
    auto& hwcInfo = getBE().mHwcLayers[hwcId];
    LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer");
    LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer");
    hwcInfo.hwc->destroyLayer(hwcId, hwcInfo.layer);
    // The layer destroyed listener should have cleared the entry from
    // mHwcLayers. Verify that.
    LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(hwcId) != 0,
                        "Stale layer entry in getBE().mHwcLayers");
    hwcInfo.layer = nullptr;

    if (getBE().mHwcLayers.count(hwcId) == 1) {
        getBE().mHwcLayers.erase(hwcId);
    }

    return true;
}

@@ -503,7 +503,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z
        blendMode =
                mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
    }
    auto error = hwcLayer->setBlendMode(blendMode);
    auto error = (*hwcLayer)->setBlendMode(blendMode);
    ALOGE_IF(error != HWC2::Error::None,
             "[%s] Failed to set blend mode %s:"
             " %s (%d)",
@@ -551,7 +551,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z
    }
    const Transform& tr(displayDevice->getTransform());
    Rect transformedFrame = tr.transform(frame);
    error = hwcLayer->setDisplayFrame(transformedFrame);
    error = (*hwcLayer)->setDisplayFrame(transformedFrame);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(),
              transformedFrame.left, transformedFrame.top, transformedFrame.right,
@@ -561,7 +561,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z
    }

    FloatRect sourceCrop = computeCrop(displayDevice);
    error = hwcLayer->setSourceCrop(sourceCrop);
    error = (*hwcLayer)->setSourceCrop(sourceCrop);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
              "%s (%d)",
@@ -572,13 +572,13 @@ void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z
    }

    float alpha = static_cast<float>(getAlpha());
    error = hwcLayer->setPlaneAlpha(alpha);
    error = (*hwcLayer)->setPlaneAlpha(alpha);
    ALOGE_IF(error != HWC2::Error::None,
             "[%s] Failed to set plane alpha %.3f: "
             "%s (%d)",
             mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));

    error = hwcLayer->setZOrder(z);
    error = (*hwcLayer)->setZOrder(z);
    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
             to_string(error).c_str(), static_cast<int32_t>(error));

@@ -591,7 +591,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z
        appId = parentState.appId;
    }

    error = hwcLayer->setInfo(type, appId);
    error = (*hwcLayer)->setInfo(type, appId);
    ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
             static_cast<int32_t>(error));

@@ -640,7 +640,7 @@ void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z
    } else {
        auto transform = static_cast<HWC2::Transform>(orientation);
        hwcInfo.transform = transform;
        auto error = hwcLayer->setTransform(transform);
        auto error = (*hwcLayer)->setTransform(transform);
        ALOGE_IF(error != HWC2::Error::None,
                 "[%s] Failed to set transform %s: "
                 "%s (%d)",
@@ -693,7 +693,7 @@ void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
    auto& displayTransform(displayDevice->getTransform());
    auto position = displayTransform.transform(frame);

    auto error = getBE().mHwcLayers[hwcId].layer->setCursorPosition(position.left,
    auto error = (*getBE().mHwcLayers[hwcId].layer)->setCursorPosition(position.left,
                                                                              position.top);
    ALOGE_IF(error != HWC2::Error::None,
             "[%s] Failed to set cursor position "
@@ -737,13 +737,13 @@ void Layer::setCompositionType(int32_t hwcId, HWC2::Composition type, bool callI
    }
    auto& hwcInfo = getBE().mHwcLayers[hwcId];
    auto& hwcLayer = hwcInfo.layer;
    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", hwcLayer->getId(), to_string(type).c_str(),
    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", (*hwcLayer)->getId(), to_string(type).c_str(),
          static_cast<int>(callIntoHwc));
    if (hwcInfo.compositionType != type) {
        ALOGV("    actually setting");
        hwcInfo.compositionType = type;
        if (callIntoHwc) {
            auto error = hwcLayer->setCompositionType(type);
            auto error = (*hwcLayer)->setCompositionType(type);
            ALOGE_IF(error != HWC2::Error::None,
                     "[%s] Failed to set "
                     "composition type %s: %s (%d)",
+9 −1
Original line number Diff line number Diff line
@@ -435,7 +435,15 @@ public:
        if (getBE().mHwcLayers.count(hwcId) == 0) {
            return nullptr;
        }
        return getBE().mHwcLayers[hwcId].layer;
        return *(getBE().mHwcLayers[hwcId].layer.get());
    }

    bool setHwcLayer(int32_t hwcId) {
        if (getBE().mHwcLayers.count(hwcId) == 0) {
            return false;
        }
        getBE().compositionInfo.hwc.hwcLayer = getBE().mHwcLayers[hwcId].layer;
        return true;
    }

    // -----------------------------------------------------------------------
+27 −2
Original line number Diff line number Diff line
@@ -29,12 +29,37 @@

namespace android {

class LayerContainer
{
    public:
        LayerContainer(HWComposer* hwc, int32_t hwcId) : mHwc(hwc), mHwcId(hwcId) {
            mLayer = hwc->createLayer(hwcId);
        }

        ~LayerContainer() {
            mHwc->destroyLayer(mHwcId, mLayer);
        }

        HWC2::Layer* operator->() {
            return mLayer;
        }

        operator HWC2::Layer*const () const {
            return mLayer;
        }

    private:
        HWComposer* mHwc;
        int32_t mHwcId;
        HWC2::Layer* mLayer;
};

struct CompositionInfo {
    HWC2::Composition compositionType;
    sp<GraphicBuffer> mBuffer = nullptr;
    int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
    struct {
        HWC2::Layer* hwcLayer;
        std::shared_ptr<LayerContainer> hwcLayer;
        int32_t hwid = -1;
        sp<Fence> fence;
        HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid;
@@ -74,7 +99,7 @@ public:
                transform(HWC2::Transform::None) {}

        HWComposer* hwc;
        HWC2::Layer* layer;
        std::shared_ptr<LayerContainer> layer;
        bool forceClientComposition;
        HWC2::Composition compositionType;
        bool clearClientTarget;