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

Commit 98df80a1 authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge changes I5ef52fe3,I5d6ec6fd

* changes:
  SF Bounds caching 3/3: Use cached transforms and bounds
  SF Bounds caching 2/3: Compute and cache layer bounds during invalidate stage
parents 8381914f f0c2851c
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -206,7 +206,7 @@ bool BufferLayer::prepareClientLayer(const RenderArea& renderArea, const Region&
            memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
        }

        const Rect win{computeBounds()};
        const Rect win{getBounds()};
        const float bufferWidth = getBufferSize(s).getWidth();
        const float bufferHeight = getBufferSize(s).getHeight();

@@ -654,6 +654,38 @@ std::shared_ptr<compositionengine::Layer> BufferLayer::getCompositionLayer() con
    return mCompositionLayer;
}

FloatRect BufferLayer::computeSourceBounds(const FloatRect& parentBounds) const {
    const State& s(getDrawingState());

    // If we have a sideband stream, or we are scaling the buffer then return the layer size since
    // we cannot determine the buffer size.
    if ((s.sidebandStream != nullptr) ||
        (getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE)) {
        return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s));
    }

    if (mActiveBuffer == nullptr) {
        return parentBounds;
    }

    uint32_t bufWidth = mActiveBuffer->getWidth();
    uint32_t bufHeight = mActiveBuffer->getHeight();

    // Undo any transformations on the buffer and return the result.
    if (mCurrentTransform & ui::Transform::ROT_90) {
        std::swap(bufWidth, bufHeight);
    }

    if (getTransformToDisplayInverse()) {
        uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
        if (invTransform & ui::Transform::ROT_90) {
            std::swap(bufWidth, bufHeight);
        }
    }

    return FloatRect(0, 0, bufWidth, bufHeight);
}

} // namespace android

#if defined(__gl_h_)
+2 −0
Original line number Diff line number Diff line
@@ -191,6 +191,8 @@ private:
    Rect getBufferSize(const State& s) const override;

    std::shared_ptr<compositionengine::Layer> mCompositionLayer;

    FloatRect computeSourceBounds(const FloatRect& parentBounds) const override;
};

} // namespace android
+13 −1
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ Rect BufferStateLayer::getBufferSize(const State& s) const {
    // if the display frame is not defined, use the parent bounds as the buffer size.
    const auto& p = mDrawingParent.promote();
    if (p != nullptr) {
        Rect parentBounds = Rect(p->computeBounds(Region()));
        Rect parentBounds = Rect(p->getBounds(Region()));
        if (!parentBounds.isEmpty()) {
            return parentBounds;
        }
@@ -326,6 +326,18 @@ Rect BufferStateLayer::getBufferSize(const State& s) const {
    }
    return Rect::INVALID_RECT;
}

FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const {
    const State& s(getDrawingState());
    // for buffer state layers we use the display frame size as the buffer size.
    if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
        return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s));
    }

    // if the display frame is not defined, use the parent bounds as the buffer size.
    return parentBounds;
}

// -----------------------------------------------------------------------

// -----------------------------------------------------------------------
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public:
                                      uint64_t /*frameNumber*/) override {}

    Rect getBufferSize(const State& s) const override;
    FloatRect computeSourceBounds(const FloatRect& parentBounds) const override;
    // -----------------------------------------------------------------------

    // -----------------------------------------------------------------------
+69 −88
Original line number Diff line number Diff line
@@ -294,80 +294,83 @@ static FloatRect reduce(const FloatRect& win, const Region& exclude) {
    return Region(Rect{win}).subtract(exclude).getBounds().toFloatRect();
}

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

    FloatRect bounds = getBounds();
    ui::Transform t = getTransform();
    // Transform to screen space.
    bounds = t.transform(bounds);
    return Rect{bounds};
}

FloatRect Layer::computeBounds() const {
FloatRect Layer::getBounds() const {
    const State& s(getDrawingState());
    return computeBounds(getActiveTransparentRegion(s));
    return getBounds(getActiveTransparentRegion(s));
}

FloatRect Layer::computeBounds(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->computeBounds(Region());
            // Transform back to layer space.
            floatBounds = t.inverse().transform(floatBounds);
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
    // for in the transform. We need to mirror this scaling to child surfaces
    // or we will break the contract where WM can treat child surfaces as
    // pixels in the parent surface.
    if (!isFixedSize() || !getBE().compositionInfo.mBuffer) {
        return mEffectiveTransform;
    }

    // Subtract the transparent region and snap to the bounds.
    return reduce(floatBounds, activeTransparentRegion);
    int bufferWidth;
    int bufferHeight;
    if ((mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) {
        bufferWidth = getBE().compositionInfo.mBuffer->getWidth();
        bufferHeight = getBE().compositionInfo.mBuffer->getHeight();
    } else {
        bufferHeight = getBE().compositionInfo.mBuffer->getWidth();
        bufferWidth = getBE().compositionInfo.mBuffer->getHeight();
    }
    float sx = getActiveWidth(getDrawingState()) / static_cast<float>(bufferWidth);
    float sy = getActiveHeight(getDrawingState()) / static_cast<float>(bufferHeight);
    ui::Transform extraParentScaling;
    extraParentScaling.set(sx, 0, 0, sy);
    return mEffectiveTransform * extraParentScaling;
}

FloatRect Layer::cropChildBounds(const FloatRect& childBounds) const {
void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform) {
    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());
    // Calculate effective layer transform
    mEffectiveTransform = parentTransform * getActiveTransform(s);

    // Transform parent bounds to layer space
    parentBounds = getActiveTransform(s).inverse().transform(parentBounds);

    // Calculate display frame
    mSourceBounds = computeSourceBounds(parentBounds);

    // Calculate bounds by croping diplay frame with layer crop and parent bounds
    FloatRect bounds = mSourceBounds;
    const Rect layerCrop = getCrop(s);
    if (!layerCrop.isEmpty()) {
        bounds = mSourceBounds.intersect(layerCrop.toFloatRect());
    }
    bounds = bounds.intersect(parentBounds);

    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);
    mBounds = bounds;
    mScreenBounds = mEffectiveTransform.transform(mBounds);
    for (const sp<Layer>& child : mDrawingChildren) {
        child->computeBounds(mBounds, getTransformWithScale());
    }
    return croppedBounds;
}



Rect Layer::getCroppedBufferSize(const State& s) const {
    Rect size = getBufferSize(s);
    Rect crop = getCrop(s);
@@ -389,7 +392,7 @@ Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const {
    // if there are no window scaling involved, this operation will map to full
    // pixels in the buffer.

    FloatRect activeCropFloat = computeBounds();
    FloatRect activeCropFloat = getBounds();
    ui::Transform t = getTransform();
    // Transform to screen space.
    activeCropFloat = t.transform(activeCropFloat);
@@ -550,9 +553,9 @@ void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
                Rect(activeCrop.right, activeCrop.top, bufferSize.getWidth(), activeCrop.bottom));
    }

    // computeBounds returns a FloatRect to provide more accuracy during the
    // getBounds returns a FloatRect to provide more accuracy during the
    // transformation. We then round upon constructing 'frame'.
    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
    Rect frame{t.transform(getBounds(activeTransparentRegion))};
    if (!frame.intersect(display->getViewport(), &frame)) {
        frame.clear();
    }
@@ -721,7 +724,7 @@ bool Layer::prepareClientLayer(const RenderArea& renderArea, bool useIdentityTra
bool Layer::prepareClientLayer(const RenderArea& /*renderArea*/, const Region& /*clip*/,
                               bool useIdentityTransform, Region& /*clearRegion*/,
                               renderengine::LayerSettings& layer) {
    FloatRect bounds = computeBounds();
    FloatRect bounds = getBounds();
    half alpha = getAlpha();
    layer.geometry.boundaries = bounds;
    if (useIdentityTransform) {
@@ -841,7 +844,7 @@ void Layer::computeGeometry(const RenderArea& renderArea,
                            renderengine::Mesh& mesh,
                            bool useIdentityTransform) const {
    const ui::Transform renderAreaTransform(renderArea.getTransform());
    FloatRect win = computeBounds();
    FloatRect win = getBounds();

    vec2 lt = vec2(win.left, win.top);
    vec2 lb = vec2(win.left, win.bottom);
@@ -1680,6 +1683,7 @@ bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) {
void Layer::setChildrenDrawingParent(const sp<Layer>& newParent) {
    for (const sp<Layer>& child : mDrawingChildren) {
        child->mDrawingParent = newParent;
        child->computeBounds(newParent->mBounds, newParent->getTransformWithScale());
    }
}

@@ -2007,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 {
@@ -2066,7 +2043,7 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const {
        }
    }
    const float radius = getDrawingState().cornerRadius;
    return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
    return radius > 0 ? RoundedCornerState(getBounds(), radius) : RoundedCornerState();
}

void Layer::commitChildList() {
@@ -2181,6 +2158,10 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet)
    for (const auto& entry : state.metadata.mMap) {
        (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
    }
    LayerProtoHelper::writeToProto(mEffectiveTransform, layerInfo->mutable_effective_transform());
    LayerProtoHelper::writeToProto(mSourceBounds, layerInfo->mutable_source_bounds());
    LayerProtoHelper::writeToProto(mScreenBounds, layerInfo->mutable_screen_bounds());
    LayerProtoHelper::writeToProto(mBounds, layerInfo->mutable_bounds());
}

void Layer::writeToProto(LayerProto* layerInfo, DisplayId displayId) {
Loading