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

Commit e0451f75 authored by Alec Mouri's avatar Alec Mouri
Browse files

Respect buffer source crop in client composition.

Previously only the SurfaceControl crop was respected, which causes a
discrepancy with HWC, since HWC recevies a crop that is intersected with
the crop provided by BufferQueue.

Bug: 122171389
Change-Id: Ie83fd30369ddd93703027c9577292eeb6f3fe110
Test: adb screenrecord
Test: Repro steps in b/122171389 no longer repro.
Test: adb screencap
Test: 4k youtube playback, fullscreen + rotations
Test: virtual display simulation
parent 0a333b6d
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -624,16 +624,19 @@ void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityT
     * minimal value)? Or, we could make GL behave like HWC -- but this feel
     * like more of a hack.
     */
    const Rect bounds{computeBounds()}; // Rounds from FloatRect

    Rect win = bounds;
    const int bufferWidth = getBufferSize(s).getWidth();
    const int bufferHeight = getBufferSize(s).getHeight();

    const float left = float(win.left) / float(bufferWidth);
    const float top = float(win.top) / float(bufferHeight);
    const float right = float(win.right) / float(bufferWidth);
    const float bottom = float(win.bottom) / float(bufferHeight);
    // Convert to Rect so that bounds are clipped to integers.
    const Rect win{computeCrop(Rect::INVALID_RECT)};
    // computeCrop() returns the cropping rectangle in buffer space, so we
    // shouldn't use getBufferSize() since that may return a rectangle specified
    // in layer space. Otherwise we may compute incorrect texture coordinates.
    const float bufWidth = float(mActiveBuffer->getWidth());
    const float bufHeight = float(mActiveBuffer->getHeight());

    const float left = win.left / bufWidth;
    const float top = win.top / bufHeight;
    const float right = win.right / bufWidth;
    const float bottom = win.bottom / bufHeight;

    // TODO: we probably want to generate the texture coords with the mesh
    // here we assume that we only have 4 vertices
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ public:
    bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }

protected:
    FloatRect computeCrop(const sp<const DisplayDevice>& /*display*/) const override { return {}; }
    FloatRect computeCrop(const Rect& /*windowbounds*/) const override { return {}; }
};

} // namespace android
+14 −9
Original line number Diff line number Diff line
@@ -380,7 +380,7 @@ Rect Layer::getCroppedBufferSize(const State& s) const {
    return size;
}

Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const {
Rect Layer::computeInitialCrop(const Rect& windowBounds) const {
    // the crop is the area of the window that gets cropped, but not
    // scaled in any ways.
    const State& s(getDrawingState());
@@ -391,12 +391,17 @@ Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const {
    // pixels in the buffer.

    FloatRect activeCropFloat = computeBounds();
    ui::Transform t = getTransform();

    // If we have valid window boundaries then we need to crop to the window
    // boundaries in layer space.
    if (windowBounds.isValid()) {
        const ui::Transform t = getTransform();
        // Transform to screen space.
        activeCropFloat = t.transform(activeCropFloat);
    activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect());
        activeCropFloat = activeCropFloat.intersect(windowBounds.toFloatRect());
        // Back to layer space to work with the content crop.
        activeCropFloat = t.inverse().transform(activeCropFloat);
    }
    // This needs to be here as transform.transform(Rect) computes the
    // transformed rect and then takes the bounding box of the result before
    // returning. This means
@@ -426,7 +431,7 @@ void Layer::setupRoundedCornersCropCoordinates(Rect win,
    cropCoords[3] = vec2(win.right, win.top);
}

FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const {
FloatRect Layer::computeCrop(const Rect& windowBounds) const {
    // the content crop is the area of the content that gets scaled to the
    // layer's size. This is in buffer space.
    FloatRect crop = getContentCrop().toFloatRect();
@@ -434,7 +439,7 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const {
    // In addition there is a WM-specified crop we pull from our drawing state.
    const State& s(getDrawingState());

    Rect activeCrop = computeInitialCrop(display);
    Rect activeCrop = computeInitialCrop(windowBounds);
    Rect bufferSize = getBufferSize(s);

    // Transform the window crop to match the buffer coordinate system,
+12 −2
Original line number Diff line number Diff line
@@ -671,12 +671,22 @@ protected:

    uint32_t getEffectiveUsage(uint32_t usage) const;

    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const;
    // Computes the crop applied to this layer. windowBounds is the boundary of
    // layer-stack space, so the cropping rectangle will be clipped to those
    // bounds in that space. The crop rectangle is returned in buffer space. If
    // windowBounds is invalid, then it is ignored.
    virtual FloatRect computeCrop(const Rect& windowBounds) const;

    // See the above method, but pulls the window boundaries from the display.
    FloatRect computeCrop(const sp<const DisplayDevice>& display) const {
        return computeCrop(display->getViewport());
    }
    // Compute the initial crop as specified by parent layers and the
    // SurfaceControl for this layer. Does not include buffer crop from the
    // IGraphicBufferProducer client, as that should not affect child clipping.
    // Returns in screen space.
    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const;
    Rect computeInitialCrop(const Rect& windowBounds) const;

    /**
     * Setup rounded corners coordinates of this layer, taking into account the layer bounds and
     * crop coordinates, transforming them into layer space.