Improve SurfaceView postion snapping

bug:27098060

Snap SurfaceView positions to safely align to pixel boundaries.

Also expands MovingSurfaceViewActivity to support a scaling option, and
show problems more clearly.

Change-Id: Ic8e9c1e2f80c2c653bf4428e373f14528ddbce81
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index d3e18ed..a6db0f4 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -562,6 +562,16 @@
             bounds.top -= info.windowInsetTop;
             bounds.bottom -= info.windowInsetTop;
 
+            if (CC_LIKELY(transform.isPureTranslate())) {
+                // snap/round the computed bounds, so they match the rounding behavior
+                // of the clear done in SurfaceView#draw().
+                bounds.snapToPixelBoundaries();
+            } else {
+                // Conservatively round out so the punched hole (in the ZOrderOnTop = true case)
+                // doesn't extend beyond the other window
+                bounds.roundOut();
+            }
+
             auto functor = std::bind(
                 std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePosition), this,
                 (jlong) info.canvasContext.getFrameNumber(),
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java
index cd15ef1..fa25b45 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MovingSurfaceViewActivity.java
@@ -20,33 +20,36 @@
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.SurfaceHolder;
 import android.view.SurfaceHolder.Callback;
 import android.view.SurfaceView;
-import android.view.View;
 import android.view.animation.LinearInterpolator;
 import android.widget.FrameLayout;
 
 public class MovingSurfaceViewActivity extends Activity implements Callback {
-    static final String TAG = "MovingSurfaceView";
     SurfaceView mSurfaceView;
     ObjectAnimator mAnimator;
 
     class MySurfaceView extends SurfaceView {
-        boolean mSlowToggled;
+        boolean mSlow;
+        boolean mScaled;
+        int mToggle = 0;
 
         public MySurfaceView(Context context) {
             super(context);
-            setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mSlowToggled = !mSlowToggled;
-                    Log.d(TAG, "SLOW MODE: " + mSlowToggled);
-                    invalidate();
-                }
+            setOnClickListener(v -> {
+                mToggle = (mToggle + 1) % 4;
+                mSlow = (mToggle & 0x2) != 0;
+                mScaled = (mToggle & 0x1) != 0;
+
+                mSurfaceView.setScaleX(mScaled ? 1.6f : 1f);
+                mSurfaceView.setScaleY(mScaled ? 0.8f : 1f);
+
+                setTitle("Slow=" + mSlow + ", scaled=" + mScaled);
+                invalidate();
             });
             setWillNotDraw(false);
         }
@@ -54,7 +57,7 @@
         @Override
         public void draw(Canvas canvas) {
             super.draw(canvas);
-            if (mSlowToggled) {
+            if (mSlow) {
                 try {
                     Thread.sleep(16);
                 } catch (InterruptedException e) {}
@@ -63,7 +66,7 @@
 
         public void setMyTranslationY(float ty) {
             setTranslationY(ty);
-            if (mSlowToggled) {
+            if (mSlow) {
                 invalidate();
             }
         }
@@ -86,7 +89,7 @@
         int size = (int) (200 * density);
 
         content.addView(mSurfaceView, new FrameLayout.LayoutParams(
-                size, size, Gravity.CENTER));
+                size, size, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
         mAnimator = ObjectAnimator.ofFloat(mSurfaceView, "myTranslationY",
                 0, size);
         mAnimator.setRepeatMode(ObjectAnimator.REVERSE);
@@ -103,7 +106,7 @@
     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
         Canvas canvas = holder.lockCanvas();
-        canvas.drawARGB(0xFF, 0x00, 0xFF, 0x00);
+        canvas.drawColor(Color.WHITE);
         holder.unlockCanvasAndPost(canvas);
     }