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

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

Merge "SF: Add support for boundless layers 1/2"

parents 4cdb2e05 6035634d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -665,6 +665,36 @@ uint64_t BufferLayer::getHeadFrameNumber() const {
    }
}

Rect BufferLayer::getBufferSize(const State& s) const {
    // 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 Rect(getActiveWidth(s), getActiveHeight(s));
    }

    if (mActiveBuffer == nullptr) {
        return Rect::INVALID_RECT;
    }

    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 Rect(bufWidth, bufHeight);
}

} // namespace android

#if defined(__gl_h_)
+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,8 @@ private:
    mutable renderengine::Texture mTexture;

    bool mRefreshPending{false};

    Rect getBufferSize(const State& s) const override;
};

} // namespace android
+4 −2
Original line number Diff line number Diff line
@@ -35,7 +35,9 @@ const std::array<float, 16> BufferStateLayer::IDENTITY_MATRIX{
};
// clang-format on

BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) : BufferLayer(args) {
    mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
}
BufferStateLayer::~BufferStateLayer() = default;

// -----------------------------------------------------------------------
@@ -447,7 +449,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse
        }
    }

    if (mOverrideScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
    if (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
        (s.active.w != bufferWidth || s.active.h != bufferHeight)) {
        ALOGE("[%s] rejecting buffer: "
              "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
+63 −50
Original line number Diff line number Diff line
@@ -275,39 +275,12 @@ 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());
    Rect win(getActiveWidth(s), getActiveHeight(s));

    Rect crop = getCrop(s);
    if (!crop.isEmpty()) {
        win.intersect(crop, &win);
    }

Rect Layer::computeScreenBounds() const {
    FloatRect bounds = computeBounds();
    ui::Transform t = getTransform();
    win = t.transform(win);

    const sp<Layer>& p = mDrawingParent.promote();
    // Now we need to calculate the parent bounds, so we can clip ourselves to those.
    // 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. In fact one of the main uses, is to reduce
    // buffer allocation size in cases where a child window sits behind a main window
    // (by marking the hole in the parent window as a transparent region)
    if (p != nullptr) {
        Rect bounds = p->computeScreenBounds(false);
        bounds.intersect(win, &win);
    }

    if (reduceTransparentRegion) {
        auto const screenTransparentRegion = t.transform(getActiveTransparentRegion(s));
        win = reduce(win, screenTransparentRegion);
    }

    return win;
    // Transform to screen space.
    bounds = t.transform(bounds);
    return Rect{bounds};
}

FloatRect Layer::computeBounds() const {
@@ -317,32 +290,72 @@ FloatRect Layer::computeBounds() const {

FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
    const State& s(getDrawingState());
    Rect win(getActiveWidth(s), getActiveHeight(s));

    Rect crop = getCrop(s);
    if (!crop.isEmpty()) {
        win.intersect(crop, &win);
    }

    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();
    FloatRect floatWin = win.toFloatRect();
    FloatRect parentBounds = floatWin;
        if (p != nullptr) {
        // We pass an empty Region here for reasons mirroring that of the case described in
        // the computeScreenBounds reduceTransparentRegion=false case.
        parentBounds = p->computeBounds(Region());
            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);
        }
    }

    ui::Transform t = s.active_legacy.transform;
    // 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) {
        floatWin = t.transform(floatWin);
        floatWin = floatWin.intersect(parentBounds);
        floatWin = t.inverse().transform(floatWin);
        // 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;
}

    // subtract the transparent region and snap to the bounds
    return reduce(floatWin, activeTransparentRegion);
Rect Layer::getCroppedBufferSize(const State& s) const {
    Rect size = getBufferSize(s);
    Rect crop = getCrop(s);
    if (!crop.isEmpty() && size.isValid()) {
        size.intersect(crop, &size);
    } else if (!crop.isEmpty()) {
        size = crop;
    }
    return size;
}

Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const {
+22 −1
Original line number Diff line number Diff line
@@ -579,7 +579,7 @@ public:
    ssize_t removeChild(const sp<Layer>& layer);
    sp<Layer> getParent() const { return mCurrentParent.promote(); }
    bool hasParent() const { return getParent() != nullptr; }
    Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
    Rect computeScreenBounds() const;
    bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
    bool setChildRelativeLayer(const sp<Layer>& childLayer,
            const sp<IBinder>& relativeToHandle, int32_t relativeZ);
@@ -791,6 +791,27 @@ 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.
     * A layer with an invalid buffer size and no crop is considered to be boundless. The layer
     * bounds are constrained by its parent bounds.
     */
    Rect getCroppedBufferSize(const Layer::State& s) const;

    /**
     * Returns active buffer size in the correct orientation. Buffer size is determined by undoing
     * any buffer transformations. If the layer has no buffer then return INVALID_RECT.
     */
    virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; }
};

// ---------------------------------------------------------------------------
Loading