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

Commit a484edb5 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Automerger Merge Worker
Browse files

Merge "Maintain Z order for all layers in offscreen hierarchy" into rvc-dev am: 7e5f235d

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

Change-Id: I400aeb5522a59397ea8a5d3b23bdf07bb0abead2
parents 4e5109c2 7e5f235d
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -229,13 +229,23 @@ void Layer::removeFromCurrentState() {
    mFlinger->markLayerPendingRemovalLocked(this);
}

sp<Layer> Layer::getRootLayer() {
    sp<Layer> parent = getParent();
    if (parent == nullptr) {
        return this;
    }
    return parent->getRootLayer();
}

void Layer::onRemovedFromCurrentState() {
    auto layersInTree = getLayersInTree(LayerVector::StateSet::Current);
    // Use the root layer since we want to maintain the hierarchy for the entire subtree.
    auto layersInTree = getRootLayer()->getLayersInTree(LayerVector::StateSet::Current);
    std::sort(layersInTree.begin(), layersInTree.end());
    for (const auto& layer : layersInTree) {

    traverse(LayerVector::StateSet::Current, [&](Layer* layer) {
        layer->removeFromCurrentState();
        layer->removeRelativeZ(layersInTree);
    }
    });
}

void Layer::addToCurrentState() {
+4 −0
Original line number Diff line number Diff line
@@ -1098,6 +1098,10 @@ private:
    // Find the root of the cloned hierarchy, this means the first non cloned parent.
    // This will return null if first non cloned parent is not found.
    sp<Layer> getClonedRoot();

    // Finds the top most layer in the hierarchy. This will find the root Layer where the parent is
    // null.
    sp<Layer> getRootLayer();
};

} // namespace android
+65 −0
Original line number Diff line number Diff line
@@ -207,6 +207,71 @@ TEST_F(RelativeZTest, LayerAndRelativeRemoved) {
        sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
    }
}

// Preserve the relative z order when a layer is reparented to a layer that's already offscreen
TEST_F(RelativeZTest, LayerWithRelativeReparentedToOffscreen) {
    std::unique_ptr<ScreenCapture> sc;

    Color testLayerColor = {255, 100, 0, 255};

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

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

    {
        // The childLevel1a should be in front of childLevel2b.
        ScreenCapture::captureScreen(&sc);
        sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), testLayerColor);
    }

    // Background layer (RED)
    // Foregroud layer (GREEN)
    //   child level 1a (testLayerColor) (relative to child level 2b)
    Transaction{}.reparent(childLevel1b, nullptr).apply();

    // // Background layer (RED)
    // // Foregroud layer (GREEN)
    Transaction{}.reparent(childLevel1a, childLevel2a->getHandle()).apply();

    {
        // The childLevel1a and childLevel1b are no longer on screen
        ScreenCapture::captureScreen(&sc);
        sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), Color::GREEN);
    }

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

    {
        // Nothing should change at this point since relative z info was preserved.
        ScreenCapture::captureScreen(&sc);
        sc->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), testLayerColor);
    }
}
} // namespace android

// TODO(b/129481165): remove the #pragma below and fix conversion issues