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

Commit 56746155 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5633711 from 383ad339 to qt-c2f2-release

Change-Id: I763e5000b2c7c0788cc4f1f9887d1ca310efbf27
parents 612a9ea1 383ad339
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -545,6 +545,12 @@ void BufferLayer::notifyAvailableFrames() {
        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled &&
            presentTimeIsCurrent) {
            point->setFrameAvailable();
            sp<Layer> requestedSyncLayer = point->getRequestedSyncLayer();
            if (requestedSyncLayer) {
                // Need to update the transaction flag to ensure the layer's pending transaction
                // gets applied.
                requestedSyncLayer->setTransactionFlags(eTransactionNeeded);
            }
        }
    }
}
+42 −17
Original line number Diff line number Diff line
@@ -144,28 +144,47 @@ Layer::~Layer() {
 */
void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {}

void Layer::onRemovedFromCurrentState() {
    mRemovedFromCurrentState = true;
void Layer::removeRemoteSyncPoints() {
    for (auto& point : mRemoteSyncPoints) {
        point->setTransactionApplied();
    }
    mRemoteSyncPoints.clear();

    {
        Mutex::Autolock pendingStateLock(mPendingStateMutex);
        for (State pendingState : mPendingStates) {
            pendingState.barrierLayer_legacy = nullptr;
        }
    }
}

void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) {
    if (mCurrentState.zOrderRelativeOf == nullptr) {
        return;
    }

    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
    if (mCurrentState.zOrderRelativeOf != nullptr) {
    sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
        if (strongRelative != nullptr) {
    if (strongRelative == nullptr) {
        setZOrderRelativeOf(nullptr);
        return;
    }

    if (!std::binary_search(layersInTree.begin(), layersInTree.end(), strongRelative.get())) {
        strongRelative->removeZOrderRelative(this);
        mFlinger->setTransactionFlags(eTraversalNeeded);
        }
        setZOrderRelativeOf(nullptr);
    }
}

void Layer::removeFromCurrentState() {
    mRemovedFromCurrentState = true;

    // Since we are no longer reachable from CurrentState SurfaceFlinger
    // will no longer invoke doTransaction for us, and so we will
    // never finish applying transactions. We signal the sync point
    // now so that another layer will not become indefinitely
    // blocked.
    for (auto& point: mRemoteSyncPoints) {
        point->setTransactionApplied();
    }
    mRemoteSyncPoints.clear();
    removeRemoteSyncPoints();

    {
    Mutex::Autolock syncLock(mLocalSyncPointMutex);
@@ -175,11 +194,16 @@ void Layer::onRemovedFromCurrentState() {
    mLocalSyncPoints.clear();
    }

    for (const auto& child : mCurrentChildren) {
        child->onRemovedFromCurrentState();
    mFlinger->markLayerPendingRemovalLocked(this);
}

    mFlinger->markLayerPendingRemovalLocked(this);
void Layer::onRemovedFromCurrentState() {
    auto layersInTree = getLayersInTree(LayerVector::StateSet::Current);
    std::sort(layersInTree.begin(), layersInTree.end());
    for (const auto& layer : layersInTree) {
        layer->removeFromCurrentState();
        layer->removeRelativeZ(layersInTree);
    }
}

void Layer::addToCurrentState() {
@@ -667,7 +691,7 @@ void Layer::pushPendingState() {
            // to be applied as per normal (no synchronization).
            mCurrentState.barrierLayer_legacy = nullptr;
        } else {
            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy, this);
            if (barrierLayer->addSyncPoint(syncPoint)) {
                mRemoteSyncPoints.push_back(std::move(syncPoint));
            } else {
@@ -1510,6 +1534,7 @@ bool Layer::detachChildren() {
        if (client != nullptr && parentClient != client) {
            child->mLayerDetached = true;
            child->detachChildren();
            child->removeRemoteSyncPoints();
        }
    }

+21 −2
Original line number Diff line number Diff line
@@ -570,6 +570,17 @@ public:

    virtual bool isBufferLatched() const { return false; }

    /*
     * Remove relative z for the layer if its relative parent is not part of the
     * provided layer tree.
     */
    void removeRelativeZ(const std::vector<Layer*>& layersInTree);

    /*
     * Remove from current state and mark for removal.
     */
    void removeFromCurrentState();

    /*
     * called with the state lock from a binder thread when the layer is
     * removed from the current list to the pending removal list
@@ -733,8 +744,11 @@ protected:

    class SyncPoint {
    public:
        explicit SyncPoint(uint64_t frameNumber)
              : mFrameNumber(frameNumber), mFrameIsAvailable(false), mTransactionIsApplied(false) {}
        explicit SyncPoint(uint64_t frameNumber, wp<Layer> requestedSyncLayer)
              : mFrameNumber(frameNumber),
                mFrameIsAvailable(false),
                mTransactionIsApplied(false),
                mRequestedSyncLayer(requestedSyncLayer) {}

        uint64_t getFrameNumber() const { return mFrameNumber; }

@@ -746,10 +760,13 @@ protected:

        void setTransactionApplied() { mTransactionIsApplied = true; }

        sp<Layer> getRequestedSyncLayer() { return mRequestedSyncLayer.promote(); }

    private:
        const uint64_t mFrameNumber;
        std::atomic<bool> mFrameIsAvailable;
        std::atomic<bool> mTransactionIsApplied;
        wp<Layer> mRequestedSyncLayer;
    };

    // SyncPoints which will be signaled when the correct frame is at the head
@@ -928,6 +945,8 @@ private:
    void setZOrderRelativeOf(const wp<Layer>& relativeOf);

    bool mGetHandleCalled = false;

    void removeRemoteSyncPoints();
};

} // namespace android
+1 −1
Original line number Diff line number Diff line
{
        "presubmit": {
            "filter": "CredentialsTest.*:SurfaceFlingerStress.*:SurfaceInterceptorTest.*:LayerTransactionTest.*:LayerTypeTransactionTest.*:LayerUpdateTest.*:GeometryLatchingTest.*:CropLatchingTest.*:ChildLayerTest.*:ScreenCaptureTest.*:ScreenCaptureChildOnlyTest.*:DereferenceSurfaceControlTest.*:BoundlessLayerTest.*:MultiDisplayLayerBoundsTest.*:InvalidHandleTest.*:VirtualDisplayTest.*"
            "filter": "CredentialsTest.*:SurfaceFlingerStress.*:SurfaceInterceptorTest.*:LayerTransactionTest.*:LayerTypeTransactionTest.*:LayerUpdateTest.*:GeometryLatchingTest.*:CropLatchingTest.*:ChildLayerTest.*:ScreenCaptureTest.*:ScreenCaptureChildOnlyTest.*:DereferenceSurfaceControlTest.*:BoundlessLayerTest.*:MultiDisplayLayerBoundsTest.*:InvalidHandleTest.*:VirtualDisplayTest.*:RelativeZTest.*"
        }
}
+176 −0
Original line number Diff line number Diff line
@@ -385,6 +385,18 @@ protected:
        return createLayer(mClient, name, width, height, flags, parent);
    }

    sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
                                        SurfaceControl* parent = nullptr) {
        auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */,
                                        PIXEL_FORMAT_RGBA_8888,
                                        ISurfaceComposerClient::eFXSurfaceColor, parent);
        asTransaction([&](Transaction& t) {
            t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f});
            t.setAlpha(colorLayer, color.a / 255.0f);
        });
        return colorLayer;
    }

    ANativeWindow_Buffer getBufferQueueLayerBuffer(const sp<SurfaceControl>& layer) {
        // wait for previous transactions (such as setSize) to complete
        Transaction().apply(true);
@@ -4725,6 +4737,48 @@ TEST_F(ChildLayerTest, DetachChildrenThenAttach) {
        mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
    }
}
TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) {
    sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
    sp<SurfaceControl> childNewClient =
            newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
                                             PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());

    ASSERT_TRUE(childNewClient != nullptr);
    ASSERT_TRUE(childNewClient->isValid());

    fillSurfaceRGBA8(childNewClient, 200, 200, 200);

    Transaction()
            .hide(mChild)
            .show(childNewClient)
            .setPosition(childNewClient, 10, 10)
            .setPosition(mFGSurfaceControl, 64, 64)
            .apply();

    {
        mCapture = screenshot();
        Rect rect = Rect(74, 74, 84, 84);
        mCapture->expectBorder(rect, Color{195, 63, 63, 255});
        mCapture->expectColor(rect, Color{200, 200, 200, 255});
    }

    Transaction()
            .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(),
                                          mFGSurfaceControl->getSurface()->getNextFrameNumber())
            .apply();
    Transaction().detachChildren(mFGSurfaceControl).apply();
    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32));

    // BufferLayer can still dequeue buffers even though there's a detached layer with a
    // deferred transaction.
    {
        SCOPED_TRACE("new buffer");
        mCapture = screenshot();
        Rect rect = Rect(74, 74, 84, 84);
        mCapture->expectBorder(rect, Color::RED);
        mCapture->expectColor(rect, Color{200, 200, 200, 255});
    }
}

TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
    asTransaction([&](Transaction& t) {
@@ -5833,4 +5887,126 @@ TEST_F(DisplayActiveConfigTest, changeAllowedConfig) {
                allowedConfigs.end());
}

class RelativeZTest : public LayerTransactionTest {
protected:
    virtual void SetUp() {
        LayerTransactionTest::SetUp();
        ASSERT_EQ(NO_ERROR, mClient->initCheck());

        const auto display = SurfaceComposerClient::getInternalDisplayToken();
        ASSERT_FALSE(display == nullptr);

        // Back layer
        mBackgroundLayer = createColorLayer("Background layer", Color::RED);

        // Front layer
        mForegroundLayer = createColorLayer("Foreground layer", Color::GREEN);

        asTransaction([&](Transaction& t) {
            t.setDisplayLayerStack(display, 0);
            t.setLayer(mBackgroundLayer, INT32_MAX - 2).show(mBackgroundLayer);
            t.setLayer(mForegroundLayer, INT32_MAX - 1).show(mForegroundLayer);
        });
    }

    virtual void TearDown() {
        LayerTransactionTest::TearDown();
        mBackgroundLayer = 0;
        mForegroundLayer = 0;
    }

    sp<SurfaceControl> mBackgroundLayer;
    sp<SurfaceControl> mForegroundLayer;
};

// When a layer is reparented offscreen, remove relative z order if the relative parent
// is still onscreen so that the layer is not drawn.
TEST_F(RelativeZTest, LayerRemoved) {
    std::unique_ptr<ScreenCapture> sc;

    // Background layer (RED)
    //   Child layer (WHITE) (relative to foregroud layer)
    // Foregroud layer (GREEN)
    sp<SurfaceControl> childLayer =
            createColorLayer("Child layer", Color::BLUE, mBackgroundLayer.get());

    Transaction{}
            .setRelativeLayer(childLayer, mForegroundLayer->getHandle(), 1)
            .show(childLayer)
            .apply();

    {
        // The childLayer should be in front of the FG control.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
    }

    // Background layer (RED)
    // Foregroud layer (GREEN)
    Transaction{}.reparent(childLayer, nullptr).apply();

    // Background layer (RED)
    //   Child layer (WHITE)
    // Foregroud layer (GREEN)
    Transaction{}.reparent(childLayer, mBackgroundLayer->getHandle()).apply();

    {
        // The relative z info for child layer should be reset, leaving FG control on top.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
    }
}

// When a layer is reparented offscreen, preseve relative z order if the relative parent
// is also offscreen. Regression test b/132613412
TEST_F(RelativeZTest, LayerRemovedOffscreenRelativeParent) {
    std::unique_ptr<ScreenCapture> sc;

    // Background layer (RED)
    // Foregroud layer (GREEN)
    //   child level 1 (WHITE)
    //     child level 2a (BLUE)
    //       child level 3 (GREEN) (relative to child level 2b)
    //     child level 2b (BLACK)
    sp<SurfaceControl> childLevel1 =
            createColorLayer("child level 1", Color::WHITE, mForegroundLayer.get());
    sp<SurfaceControl> childLevel2a =
            createColorLayer("child level 2a", Color::BLUE, childLevel1.get());
    sp<SurfaceControl> childLevel2b =
            createColorLayer("child level 2b", Color::BLACK, childLevel1.get());
    sp<SurfaceControl> childLevel3 =
            createColorLayer("child level 3", Color::GREEN, childLevel2a.get());

    Transaction{}
            .setRelativeLayer(childLevel3, childLevel2b->getHandle(), 1)
            .show(childLevel2a)
            .show(childLevel2b)
            .show(childLevel3)
            .apply();

    {
        // The childLevel3 should be in front of childLevel2b.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
    }

    // Background layer (RED)
    // Foregroud layer (GREEN)
    Transaction{}.reparent(childLevel1, nullptr).apply();

    // Background layer (RED)
    // Foregroud layer (GREEN)
    //   child level 1 (WHITE)
    //     child level 2 back (BLUE)
    //       child level 3 (GREEN) (relative to child level 2b)
    //     child level 2 front (BLACK)
    Transaction{}.reparent(childLevel1, mForegroundLayer->getHandle()).apply();

    {
        // Nothing should change at this point since relative z info was preserved.
        ScreenCapture::captureScreen(&sc);
        sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
    }
}

} // namespace android