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

Commit f0c2851c authored by Vishnu Nair's avatar Vishnu Nair
Browse files

SF Bounds caching 3/3: Use cached transforms and bounds

Switch to using cached values for layer transforms and bounds.

Test: go/wm-smoke
Test: atest -a libinput_tests inputflinger_tests SurfaceFlinger_test libsurfaceflinger_unittest SurfaceParcelable_test libgui_test
Change-Id: I5ef52fe3dac81303606802915999d80fd0ba50e1
parent 4351ad58
Loading
Loading
Loading
Loading
+11 −88
Original line number Diff line number Diff line
@@ -295,9 +295,11 @@ static FloatRect reduce(const FloatRect& win, const Region& exclude) {
}

Rect Layer::getScreenBounds(bool reduceTransparentRegion) const {
    const State& s(getDrawingState());
    Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region();
    FloatRect bounds = getBounds(transparentRegion);
    if (!reduceTransparentRegion) {
        return Rect{mScreenBounds};
    }

    FloatRect bounds = getBounds();
    ui::Transform t = getTransform();
    // Transform to screen space.
    bounds = t.transform(bounds);
@@ -309,6 +311,11 @@ FloatRect Layer::getBounds() const {
    return getBounds(getActiveTransparentRegion(s));
}

FloatRect Layer::getBounds(const Region& activeTransparentRegion) const {
    // Subtract the transparent region and snap to the bounds.
    return reduce(mBounds, activeTransparentRegion);
}

ui::Transform Layer::getTransformWithScale() const {
    // If the layer is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
    // it isFixedSize) then there may be additional scaling not accounted
@@ -362,64 +369,7 @@ void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform)
    }
}

FloatRect Layer::getBounds(const Region& activeTransparentRegion) const {
    const State& s(getDrawingState());
    Rect bounds = getCroppedBufferSize(s);
    FloatRect floatBounds = bounds.toFloatRect();
    if (bounds.isValid()) {
        // Layer has bounds. Pass in our bounds as a special case. Then pass on to our parents so
        // that they can clip it.
        floatBounds = cropChildBounds(floatBounds);
    } else {
        // Layer does not have bounds, so we fill to our parent bounds. This is done by getting our
        // parent bounds and inverting the transform to get the maximum bounds we can have that
        // will fit within our parent bounds.
        const auto& p = mDrawingParent.promote();
        if (p != nullptr) {
            ui::Transform t = s.active_legacy.transform;
            // When calculating the parent bounds for purposes of clipping, we don't need to
            // constrain the parent to its transparent region. The transparent region is an
            // optimization based on the buffer contents of the layer, but does not affect the
            // space allocated to it by policy, and thus children should be allowed to extend into
            // the parent's transparent region.
            // One of the main uses is a parent window with a child sitting behind the parent
            // window, marked by a transparent region. When computing the parent bounds from the
            // parent's perspective we pass in the transparent region to reduce buffer allocation
            // size. When computing the parent bounds from the child's perspective, we pass in an
            // empty transparent region in order to extend into the the parent bounds.
            floatBounds = p->getBounds(Region());
            // Transform back to layer space.
            floatBounds = t.inverse().transform(floatBounds);
        }
    }

    // Subtract the transparent region and snap to the bounds.
    return reduce(floatBounds, activeTransparentRegion);
}

FloatRect Layer::cropChildBounds(const FloatRect& childBounds) const {
    const State& s(getDrawingState());
    Rect bounds = getCroppedBufferSize(s);
    FloatRect croppedBounds = childBounds;

    // If the layer has bounds, then crop the passed in child bounds and pass
    // it to our parents so they can crop it as well. If the layer has no bounds,
    // then pass on the child bounds.
    if (bounds.isValid()) {
        croppedBounds = croppedBounds.intersect(bounds.toFloatRect());
    }

    const auto& p = mDrawingParent.promote();
    if (p != nullptr) {
        // Transform to parent space and allow parent layer to crop the
        // child bounds as well.
        ui::Transform t = s.active_legacy.transform;
        croppedBounds = t.transform(croppedBounds);
        croppedBounds = p->cropChildBounds(croppedBounds);
        croppedBounds = t.inverse().transform(croppedBounds);
    }
    return croppedBounds;
}

Rect Layer::getCroppedBufferSize(const State& s) const {
    Rect size = getBufferSize(s);
@@ -2061,34 +2011,7 @@ void Layer::traverseChildrenInZOrder(LayerVector::StateSet stateSet,
}

ui::Transform Layer::getTransform() const {
    ui::Transform t;
    const auto& p = mDrawingParent.promote();
    if (p != nullptr) {
        t = p->getTransform();

        // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
        // it isFixedSize) then there may be additional scaling not accounted
        // for in the transform. We need to mirror this scaling in child surfaces
        // or we will break the contract where WM can treat child surfaces as
        // pixels in the parent surface.
        if (p->isFixedSize() && p->getBE().compositionInfo.mBuffer != nullptr) {
            int bufferWidth;
            int bufferHeight;
            if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) {
                bufferWidth = p->getBE().compositionInfo.mBuffer->getWidth();
                bufferHeight = p->getBE().compositionInfo.mBuffer->getHeight();
            } else {
                bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth();
                bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight();
            }
            float sx = p->getActiveWidth(p->getDrawingState()) / static_cast<float>(bufferWidth);
            float sy = p->getActiveHeight(p->getDrawingState()) / static_cast<float>(bufferHeight);
            ui::Transform extraParentScaling;
            extraParentScaling.set(sx, 0, 0, sy);
            t = t * extraParentScaling;
        }
    }
    return t * getActiveTransform(getDrawingState());
    return mEffectiveTransform;
}

half Layer::getAlpha() const {
+0 −7
Original line number Diff line number Diff line
@@ -894,13 +894,6 @@ private:
                                       const LayerVector::Visitor& visitor);
    LayerVector makeChildrenTraversalList(LayerVector::StateSet stateSet,
                                          const std::vector<Layer*>& layersInTree);
    /**
     * Retuns the child bounds in layer space cropped to its bounds as well all its parent bounds.
     * The cropped bounds must be transformed back from parent layer space to child layer space by
     * applying the inverse of the child's transformation.
     */
    FloatRect cropChildBounds(const FloatRect& childBounds) const;

    /**
     * Returns the cropped buffer size or the layer crop if the layer has no buffer. Return
     * INVALID_RECT if the layer has no buffer and no crop.
+0 −3
Original line number Diff line number Diff line
@@ -2992,9 +2992,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
        mDrawingState.traverseInZOrder([&](Layer* layer) {
            if (mLayersPendingRemoval.indexOf(layer) >= 0) {
                // this layer is not visible anymore
                // TODO: we could traverse the tree from front to back and
                //       compute the actual visible region
                // TODO: we could cache the transformed region
                Region visibleReg;
                visibleReg.set(layer->getScreenBounds());
                invalidateLayerStack(layer, visibleReg);