From 87a07ea39df12f5e480182cd786fd8b8174520a1 Mon Sep 17 00:00:00 2001 From: chaviw Date: Thu, 29 Apr 2021 09:04:41 -0500 Subject: [PATCH] Restore old behavior in pulic API setGeometry When setFrame was removed, it required some changes to setGeometry. However, this created some behavior changes between R and S. Modified setGeometry to restore old behavior. 1. Destination can't have negative left and top. If negative values are set, it will revert to (0,0,w,h) 2. If invalid source is set, an invalid rect for crop will be sent to SF which would normally mean crop is ignored. Test: ASurfaceControlTest Bug: 185533162 Change-Id: I5c86da7327f97e82c63ae1f1c985829b8a4dbaef --- native/android/surface_control.cpp | 43 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 7540a143c2f37..a8c2ea544d38c 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -438,27 +438,44 @@ void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction, const ARect& destination, int32_t transform) { CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); + CHECK_VALID_RECT(source); CHECK_VALID_RECT(destination); - Rect sourceRect = static_cast(source); - // Adjust the source so its top and left are not negative - sourceRect.left = std::max(sourceRect.left, 0); - sourceRect.top = std::max(sourceRect.top, 0); - LOG_ALWAYS_FATAL_IF(sourceRect.isEmpty(), "invalid arg passed as source argument"); - sp surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); + Rect sourceRect = static_cast(source); + Rect destRect = static_cast(destination); + // Adjust the source so its top and left are not negative + sourceRect.left = std::max(sourceRect.left, 0); + sourceRect.top = std::max(sourceRect.top, 0); + + if (!sourceRect.isValid()) { + sourceRect.makeInvalid(); + } transaction->setBufferCrop(surfaceControl, sourceRect); - float dsdx = (destination.right - destination.left) / - static_cast(sourceRect.right - sourceRect.left); - float dsdy = (destination.bottom - destination.top) / - static_cast(sourceRect.bottom - sourceRect.top); + int destW = destRect.width(); + int destH = destRect.height(); + if (destRect.left < 0) { + destRect.left = 0; + destRect.right = destW; + } + if (destRect.top < 0) { + destRect.top = 0; + destRect.bottom = destH; + } + + if (!sourceRect.isEmpty()) { + float sx = destW / static_cast(sourceRect.width()); + float sy = destH / static_cast(sourceRect.height()); + transaction->setPosition(surfaceControl, destRect.left - (sourceRect.left * sx), + destRect.top - (sourceRect.top * sy)); + transaction->setMatrix(surfaceControl, sx, 0, 0, sy); + } else { + transaction->setPosition(surfaceControl, destRect.left, destRect.top); + } - transaction->setPosition(surfaceControl, destination.left - (sourceRect.left * dsdx), - destination.top - (sourceRect.top * dsdy)); - transaction->setMatrix(surfaceControl, dsdx, 0, 0, dsdy); transaction->setTransform(surfaceControl, transform); bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;