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

Commit 443e47a7 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixes for parentless layers"

parents 833dd79f 61626f2e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ BufferLayer::~BufferLayer() {
        ALOGE("Found stale hardware composer layers when destroying "
              "surface flinger layer %s",
              mName.string());
        destroyAllHwcLayers();
        destroyAllHwcLayersPlusChildren();
    }

    mTimeStats.onDestroy(getSequence());
+19 −3
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ Layer::~Layer() {

    mFrameTracker.logAndResetStats(mName);

    destroyAllHwcLayers();
    destroyAllHwcLayersPlusChildren();

    mFlinger->onLayerDestroyed();
}
@@ -175,6 +175,14 @@ void Layer::onRemovedFromCurrentState() {
    }
}

void Layer::addToCurrentState() {
    mRemovedFromCurrentState = false;

    for (const auto& child : mCurrentChildren) {
        child->addToCurrentState();
    }
}

// ---------------------------------------------------------------------------
// set-up
// ---------------------------------------------------------------------------
@@ -226,17 +234,21 @@ bool Layer::destroyHwcLayer(DisplayId displayId) {
    return true;
}

void Layer::destroyAllHwcLayers() {
void Layer::destroyHwcLayersForAllDisplays() {
    size_t numLayers = getBE().mHwcLayers.size();
    for (size_t i = 0; i < numLayers; ++i) {
        LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.empty(), "destroyAllHwcLayers failed");
        destroyHwcLayer(getBE().mHwcLayers.begin()->first);
    }
}

void Layer::destroyAllHwcLayersPlusChildren() {
    destroyHwcLayersForAllDisplays();
    LOG_ALWAYS_FATAL_IF(!getBE().mHwcLayers.empty(),
                        "All hardware composer layers should have been destroyed");

    for (const sp<Layer>& child : mDrawingChildren) {
        child->destroyAllHwcLayers();
        child->destroyAllHwcLayersPlusChildren();
    }
}

@@ -1580,6 +1592,10 @@ bool Layer::reparent(const sp<IBinder>& newParentHandle) {
    }
    newParent->addChild(this);

    if (!newParent->isRemovedFromCurrentState()) {
        addToCurrentState();
    }

    sp<Client> client(mClientRef.promote());
    sp<Client> newParentClient(newParent->mClientRef.promote());

+7 −1
Original line number Diff line number Diff line
@@ -491,6 +491,11 @@ public:
     */
    void onRemovedFromCurrentState();

    /*
     * Called when the layer is added back to the current state list.
     */
    void addToCurrentState();

    // Updates the transform hint in our SurfaceFlingerConsumer to match
    // the current orientation of the display device.
    void updateTransformHint(const sp<const DisplayDevice>& display) const;
@@ -512,7 +517,8 @@ public:

    bool createHwcLayer(HWComposer* hwc, DisplayId displayId);
    bool destroyHwcLayer(DisplayId displayId);
    void destroyAllHwcLayers();
    void destroyHwcLayersForAllDisplays();
    void destroyAllHwcLayersPlusChildren();

    bool hasHwcLayer(DisplayId displayId) const { return getBE().mHwcLayers.count(displayId) > 0; }

+14 −5
Original line number Diff line number Diff line
@@ -2754,6 +2754,17 @@ void SurfaceFlinger::updateCursorAsync()
    }
}

void SurfaceFlinger::latchAndReleaseBuffer(const sp<Layer>& layer) {
    if (layer->hasReadyFrame()) {
        const nsecs_t expectedPresentTime = mPrimaryDispSync->expectedPresentTime();
        if (layer->shouldPresentNow(expectedPresentTime)) {
            bool ignored = false;
            layer->latchBuffer(ignored, systemTime(), Fence::NO_FENCE);
        }
    }
    layer->releasePendingBuffer(systemTime());
}

void SurfaceFlinger::commitTransaction()
{
    if (!mLayersPendingRemoval.isEmpty()) {
@@ -2767,11 +2778,9 @@ void SurfaceFlinger::commitTransaction()
            // showing at its last configured state until we eventually
            // abandon the buffer queue.
            if (l->isRemovedFromCurrentState()) {
                l->destroyAllHwcLayers();
                // destroyAllHwcLayers traverses to children, but releasePendingBuffer
                // doesn't in other scenarios. So we have to traverse explicitly here.
                l->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* child) {
                    child->releasePendingBuffer(systemTime());
                    child->destroyHwcLayersForAllDisplays();
                    latchAndReleaseBuffer(child);
                });
            }
        }
@@ -3224,7 +3233,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
        } else {
            if (parent->isRemovedFromCurrentState()) {
                ALOGE("addClientLayer called with a removed parent");
                return NAME_NOT_FOUND;
                lbc->onRemovedFromCurrentState();
            }
            parent->addChild(lbc);
        }
+1 −0
Original line number Diff line number Diff line
@@ -552,6 +552,7 @@ private:
    // Can only be called from the main thread or with mStateLock held
    uint32_t setTransactionFlags(uint32_t flags);
    uint32_t setTransactionFlags(uint32_t flags, Scheduler::TransactionStart transactionStart);
    void latchAndReleaseBuffer(const sp<Layer>& layer);
    void commitTransaction();
    bool containsAnyInvalidClientState(const Vector<ComposerState>& states);
    uint32_t setClientStateLocked(const ComposerState& composerState);