diff options
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 21 | ||||
| -rw-r--r-- | services/surfaceflinger/ColorLayer.h | 2 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 23 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 14 |
4 files changed, 39 insertions, 21 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4eafeac293..164a3a6a7e 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -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 diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h index d1b1697af8..aecde9fd75 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/ColorLayer.h @@ -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 diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 3f2d10a45b..ee49610dfc 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -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(); - // Transform to screen space. - activeCropFloat = t.transform(activeCropFloat); - activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect()); - // Back to layer space to work with the content crop. - activeCropFloat = t.inverse().transform(activeCropFloat); + + // 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(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, diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 2e75088a28..7bc7a82d3b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -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. |