am 79107083: Merge "Add option to enable scrim SRC optimization" into lmp-dev

* commit '79107083ca50b99c9e7b678d7739b9ab4798db0f':
  Add option to enable scrim SRC optimization
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 13170ad..08bda1f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -81,6 +81,13 @@
     <!-- Show camera affordance on Keyguard -->
     <bool name="config_keyguardShowCameraAffordance">true</bool>
 
+    <!-- Whether we should use SRC drawing mode when drawing the scrim behind. If this flag is set,
+         we change the canvas opacity so libhwui doesn't call glClear on our surface, and then we
+         draw the scrim with SRC to overwrite the whole buffer, which saves us a layer of overdraw.
+         However, SRC performs poorly on some devices, where it is more efficient to
+         glClear + SRC_OVER, in which case this flag should be disabled. -->
+    <bool name="config_status_bar_scrim_behind_use_src">true</bool>
+
     <!-- The length of the vibration when the notification pops open. -->
     <integer name="one_finger_pop_duration_ms">10</integer>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index e7c0109..682676b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -70,7 +70,7 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (mDrawAsSrc || !mIsEmpty) {
+        if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
             PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
             int color = mScrimColor;
             color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 71fef65..0651708 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -430,6 +430,7 @@
     private boolean mVisible;
     private boolean mWaitingForKeyguardExit;
     private boolean mDozing;
+    private boolean mScrimSrcModeEnabled;
 
     private Interpolator mLinearOutSlowIn;
     private Interpolator mLinearInterpolator = new LinearInterpolator();
@@ -569,6 +570,8 @@
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
         updateDisplaySize();
+        mScrimSrcModeEnabled = mContext.getResources().getBoolean(
+                R.bool.config_status_bar_scrim_behind_use_src);
         super.start(); // calls createAndAddWindows()
 
         mMediaSessionManager
@@ -737,7 +740,7 @@
 
         ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
         ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
-        mScrimController = new ScrimController(scrimBehind, scrimInFront);
+        mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled);
         mScrimController.setBackDropView(mBackdrop);
         mStatusBarView.setScrimController(mScrimController);
 
@@ -1870,7 +1873,9 @@
                 if (mBackdropBack.getDrawable() != null) {
                     Drawable drawable = mBackdropBack.getDrawable();
                     mBackdropFront.setImageDrawable(drawable);
-                    mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
+                    if (mScrimSrcModeEnabled) {
+                        mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode);
+                    }
                     mBackdropFront.setAlpha(1f);
                     mBackdropFront.setVisibility(View.VISIBLE);
                 } else {
@@ -1885,7 +1890,9 @@
                 } else {
                     mBackdropBack.setImageBitmap(artworkBitmap);
                 }
-                mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
+                if (mScrimSrcModeEnabled) {
+                    mBackdropBack.getDrawable().mutate().setXfermode(mSrcXferMode);
+                }
 
                 if (mBackdropFront.getVisibility() == View.VISIBLE) {
                     if (DEBUG_MEDIA) {
@@ -2134,6 +2141,10 @@
         return mMediaNotificationKey;
     }
 
+    public boolean isScrimSrcModeEnabled() {
+        return mScrimSrcModeEnabled;
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 5353f25..6793f69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -74,8 +74,9 @@
     private final Interpolator mInterpolator = new DecelerateInterpolator();
     private final Interpolator mLinearOutSlowInInterpolator;
     private BackDropView mBackDropView;
+    private boolean mScrimSrcEnabled;
 
-    public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront) {
+    public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, boolean scrimSrcEnabled) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
         final Context context = scrimBehind.getContext();
@@ -83,6 +84,7 @@
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 android.R.interpolator.linear_out_slow_in);
         mDozeParameters = new DozeParameters(context);
+        mScrimSrcEnabled = scrimSrcEnabled;
     }
 
     public void setKeyguardShowing(boolean showing) {
@@ -384,7 +386,7 @@
     }
 
     private void updateScrimBehindDrawingMode() {
-        boolean asSrc = mBackDropView.getVisibility() != View.VISIBLE;
+        boolean asSrc = mBackDropView.getVisibility() != View.VISIBLE && mScrimSrcEnabled;
         mScrimBehind.setDrawAsSrc(asSrc);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 4c86990..242f1b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -55,7 +55,6 @@
     public StatusBarWindowView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setMotionEventSplittingEnabled(false);
-        setWillNotDraw(false);
         mTransparentSrcPaint.setColor(0);
         mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
     }
@@ -105,11 +104,16 @@
         // We need to ensure that our window doesn't suffer from overdraw which would normally
         // occur if our window is translucent. Since we are drawing the whole window anyway with
         // the scrim, we don't need the window to be cleared in the beginning.
-        IBinder windowToken = getWindowToken();
-        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
-        lp.token = windowToken;
-        setLayoutParams(lp);
-        WindowManagerGlobal.getInstance().changeCanvasOpacity(windowToken, true);
+        if (mService.isScrimSrcModeEnabled()) {
+            IBinder windowToken = getWindowToken();
+            WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
+            lp.token = windowToken;
+            setLayoutParams(lp);
+            WindowManagerGlobal.getInstance().changeCanvasOpacity(windowToken, true);
+            setWillNotDraw(false);
+        } else {
+            setWillNotDraw(!DEBUG);
+        }
     }
 
     @Override
@@ -199,23 +203,25 @@
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        // We need to ensure that our window is always drawn fully even when we have paddings,
-        // since we simulate it to be opaque.
-        int paddedBottom = getHeight() - getPaddingBottom();
-        int paddedRight = getWidth() - getPaddingRight();
-        if (getPaddingTop() != 0) {
-            canvas.drawRect(0, 0, getWidth(), getPaddingTop(), mTransparentSrcPaint);
-        }
-        if (getPaddingBottom() != 0) {
-            canvas.drawRect(0, paddedBottom, getWidth(), getHeight(), mTransparentSrcPaint);
-        }
-        if (getPaddingLeft() != 0) {
-            canvas.drawRect(0, getPaddingTop(), getPaddingLeft(), paddedBottom,
-                    mTransparentSrcPaint);
-        }
-        if (getPaddingRight() != 0) {
-            canvas.drawRect(paddedRight, getPaddingTop(), getWidth(), paddedBottom,
-                    mTransparentSrcPaint);
+        if (mService.isScrimSrcModeEnabled()) {
+            // We need to ensure that our window is always drawn fully even when we have paddings,
+            // since we simulate it to be opaque.
+            int paddedBottom = getHeight() - getPaddingBottom();
+            int paddedRight = getWidth() - getPaddingRight();
+            if (getPaddingTop() != 0) {
+                canvas.drawRect(0, 0, getWidth(), getPaddingTop(), mTransparentSrcPaint);
+            }
+            if (getPaddingBottom() != 0) {
+                canvas.drawRect(0, paddedBottom, getWidth(), getHeight(), mTransparentSrcPaint);
+            }
+            if (getPaddingLeft() != 0) {
+                canvas.drawRect(0, getPaddingTop(), getPaddingLeft(), paddedBottom,
+                        mTransparentSrcPaint);
+            }
+            if (getPaddingRight() != 0) {
+                canvas.drawRect(paddedRight, getPaddingTop(), getWidth(), paddedBottom,
+                        mTransparentSrcPaint);
+            }
         }
         if (DEBUG) {
             Paint pt = new Paint();