summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author John Reck <jreck@google.com> 2024-10-14 16:16:30 -0400
committer John Reck <jreck@google.com> 2024-10-14 16:18:37 -0400
commit3d5cfdd440795cec8d9b426a07a0e23d7536669f (patch)
treeea863c3663e20b310cbe0b2cc15777aa6f5f7a69
parentb6924395f6e50db24129c3c820c38e8e96dd7216 (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.java4
-rw-r--r--libs/hwui/DamageAccumulator.cpp84
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) {