diff options
author | 2024-10-14 16:16:30 -0400 | |
---|---|---|
committer | 2024-10-14 16:18:37 -0400 | |
commit | 3d5cfdd440795cec8d9b426a07a0e23d7536669f (patch) | |
tree | ea863c3663e20b310cbe0b2cc15777aa6f5f7a69 | |
parent | b6924395f6e50db24129c3c820c38e8e96dd7216 (diff) |
Fix SurfaceView window crop computation
1) Transform matrix is now computed in the right direction,
matches long-time computeCurrentTransform
2) The scaling on the SV side was incorrect, removed it
Bug: 298621623
Test: repro cases in b/313721727 & b/318611127
Flag: clip_surfaceviews
Change-Id: Ieef1aa2ec8564fe6150f27da4c1f35d84f9a71dc
-rw-r--r-- | core/java/android/view/SurfaceView.java | 4 | ||||
-rw-r--r-- | libs/hwui/DamageAccumulator.cpp | 84 |
2 files changed, 50 insertions, 38 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index f7745d14188e..50f95521bd8e 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -1702,9 +1702,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mRTLastReportedPosition.top /*positionTop*/, postScaleX, postScaleY); - mRTLastSetCrop.set((int) (clipLeft / postScaleX), (int) (clipTop / postScaleY), - (int) Math.ceil(clipRight / postScaleX), - (int) Math.ceil(clipBottom / postScaleY)); + mRTLastSetCrop.set(clipLeft, clipTop, clipRight, clipBottom); if (DEBUG_POSITION) { Log.d(TAG, String.format("Setting layer crop = [%d, %d, %d, %d] " + "from scale %f, %f", mRTLastSetCrop.left, diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp index 28d85bd860df..a3737131702d 100644 --- a/libs/hwui/DamageAccumulator.cpp +++ b/libs/hwui/DamageAccumulator.cpp @@ -242,45 +242,59 @@ void DamageAccumulator::applyRenderNodeTransform(DirtyStack* frame) { } } -SkRect DamageAccumulator::computeClipAndTransform(const SkRect& bounds, Matrix4* outMatrix) const { - const DirtyStack* frame = mHead; - Matrix4 transform; - SkRect pretransformResult = bounds; - while (true) { - SkRect currentBounds = pretransformResult; - pretransformResult.setEmpty(); - switch (frame->type) { - case TransformRenderNode: { - const RenderProperties& props = frame->renderNode->properties(); - // Perform clipping - if (props.getClipDamageToBounds() && !currentBounds.isEmpty()) { - if (!currentBounds.intersect( - SkRect::MakeIWH(props.getWidth(), props.getHeight()))) { - currentBounds.setEmpty(); - } +static void computeClipAndTransformImpl(const DirtyStack* currentFrame, SkRect* crop, + Matrix4* outMatrix) { + SkRect currentCrop = *crop; + switch (currentFrame->type) { + case TransformRenderNode: { + const RenderProperties& props = currentFrame->renderNode->properties(); + // Perform clipping + if (props.getClipDamageToBounds() && !currentCrop.isEmpty()) { + if (!currentCrop.intersect(SkRect::MakeIWH(props.getWidth(), props.getHeight()))) { + currentCrop.setEmpty(); } + } - // apply all transforms - mapRect(props, currentBounds, &pretransformResult); - frame->renderNode->applyViewPropertyTransforms(transform); - } break; - case TransformMatrix4: - mapRect(frame->matrix4, currentBounds, &pretransformResult); - transform.multiply(*frame->matrix4); - break; - default: - pretransformResult = currentBounds; - break; - } - if (frame->prev == frame) break; - frame = frame->prev; + // apply all transforms + crop->setEmpty(); + mapRect(props, currentCrop, crop); + } break; + case TransformMatrix4: + crop->setEmpty(); + mapRect(currentFrame->matrix4, currentCrop, crop); + break; + default: + break; + } + + if (currentFrame->prev != currentFrame) { + computeClipAndTransformImpl(currentFrame->prev, crop, outMatrix); + } + switch (currentFrame->type) { + case TransformRenderNode: + currentFrame->renderNode->applyViewPropertyTransforms(*outMatrix); + break; + case TransformMatrix4: + outMatrix->multiply(*currentFrame->matrix4); + break; + case TransformNone: + // nothing to be done + break; + default: + LOG_ALWAYS_FATAL("Tried to compute transform with an invalid type: %d", + currentFrame->type); } - SkRect result; +} + +SkRect DamageAccumulator::computeClipAndTransform(const SkRect& bounds, Matrix4* outMatrix) const { + SkRect cropInGlobal = bounds; + outMatrix->loadIdentity(); + computeClipAndTransformImpl(mHead, &cropInGlobal, outMatrix); + SkRect cropInLocal; Matrix4 globalToLocal; - globalToLocal.loadInverse(transform); - mapRect(&globalToLocal, pretransformResult, &result); - *outMatrix = transform; - return result; + globalToLocal.loadInverse(*outMatrix); + mapRect(&globalToLocal, cropInGlobal, &cropInLocal); + return cropInLocal; } void DamageAccumulator::dirty(float left, float top, float right, float bottom) { |