Cleanup debug options

Bug: 18138852
Bug: 18065434
Change-Id: Ibb07b73b147c2a8b287fe8aee3f6624582f21b00
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 1e46517..0711aed 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -255,6 +255,9 @@
             mProfilingEnabled = wantProfiling;
             changed = true;
         }
+        if (changed) {
+            invalidateRoot();
+        }
         return changed;
     }
 
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index a998594..fab4a1a 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -525,7 +525,7 @@
     deferInfo.mergeable &= !recordingComplexClip();
     deferInfo.opaqueOverBounds &= !recordingComplexClip() && mSaveStack.isEmpty();
 
-    if (CC_LIKELY(mAvoidOverdraw) && mBatches.size() &&
+    if (mBatches.size() &&
             state->mClipSideFlags != kClipSide_ConservativeFull &&
             deferInfo.opaqueOverBounds && state->mBounds.contains(mBounds)) {
         // avoid overdraw by resetting drawing state + discarding drawing ops
@@ -677,13 +677,12 @@
     DrawModifiers restoreDrawModifiers = renderer.getDrawModifiers();
     renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
 
-    if (CC_LIKELY(mAvoidOverdraw)) {
-        for (unsigned int i = 1; i < mBatches.size(); i++) {
-            if (mBatches[i] && mBatches[i]->coversBounds(mBounds)) {
-                discardDrawingBatches(i - 1);
-            }
+    for (unsigned int i = 1; i < mBatches.size(); i++) {
+        if (mBatches[i] && mBatches[i]->coversBounds(mBounds)) {
+            discardDrawingBatches(i - 1);
         }
     }
+
     // NOTE: depth of the save stack at this point, before playback, should be reflected in
     // FLUSH_SAVE_STACK_DEPTH, so that save/restores match up correctly
     status |= replayBatchList(mBatches, renderer, dirty);
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 8a015b2..885b411 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -81,8 +81,8 @@
 class DeferredDisplayList {
     friend class DeferStateStruct; // used to give access to allocator
 public:
-    DeferredDisplayList(const Rect& bounds, bool avoidOverdraw = true) :
-            mBounds(bounds), mAvoidOverdraw(avoidOverdraw) {
+    DeferredDisplayList(const Rect& bounds) :
+            mBounds(bounds) {
         clear();
     }
     ~DeferredDisplayList() { clear(); }
@@ -150,7 +150,6 @@
 
     // layer space bounds of rendering
     Rect mBounds;
-    const bool mAvoidOverdraw;
 
     /**
      * At defer time, stores the *defer time* savecount of save/saveLayer ops that were deferred, so
diff --git a/libs/hwui/DrawProfiler.cpp b/libs/hwui/DrawProfiler.cpp
index 2409554..e590642 100644
--- a/libs/hwui/DrawProfiler.cpp
+++ b/libs/hwui/DrawProfiler.cpp
@@ -22,7 +22,8 @@
 
 #define DEFAULT_MAX_FRAMES 128
 
-#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == kNone)) return
+#define RETURN_IF_PROFILING_DISABLED() if (CC_LIKELY(mType == kNone)) return
+#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == kNone && !mShowDirtyRegions)) return
 
 #define NANOS_TO_MILLIS_FLOAT(nanos) ((nanos) * 0.000001f)
 
@@ -64,7 +65,9 @@
         , mPreviousTime(0)
         , mVerticalUnit(0)
         , mHorizontalUnit(0)
-        , mThresholdStroke(0) {
+        , mThresholdStroke(0)
+        , mShowDirtyRegions(false)
+        , mFlashToggle(false) {
     setDensity(1);
 }
 
@@ -82,27 +85,27 @@
 }
 
 void DrawProfiler::startFrame(nsecs_t recordDurationNanos) {
-    RETURN_IF_DISABLED();
+    RETURN_IF_PROFILING_DISABLED();
     mData[mCurrentFrame].record = NANOS_TO_MILLIS_FLOAT(recordDurationNanos);
     mPreviousTime = systemTime(CLOCK_MONOTONIC);
 }
 
 void DrawProfiler::markPlaybackStart() {
-    RETURN_IF_DISABLED();
+    RETURN_IF_PROFILING_DISABLED();
     nsecs_t now = systemTime(CLOCK_MONOTONIC);
     mData[mCurrentFrame].prepare = NANOS_TO_MILLIS_FLOAT(now - mPreviousTime);
     mPreviousTime = now;
 }
 
 void DrawProfiler::markPlaybackEnd() {
-    RETURN_IF_DISABLED();
+    RETURN_IF_PROFILING_DISABLED();
     nsecs_t now = systemTime(CLOCK_MONOTONIC);
     mData[mCurrentFrame].playback = NANOS_TO_MILLIS_FLOAT(now - mPreviousTime);
     mPreviousTime = now;
 }
 
 void DrawProfiler::finishFrame() {
-    RETURN_IF_DISABLED();
+    RETURN_IF_PROFILING_DISABLED();
     nsecs_t now = systemTime(CLOCK_MONOTONIC);
     mData[mCurrentFrame].swapBuffers = NANOS_TO_MILLIS_FLOAT(now - mPreviousTime);
     mPreviousTime = now;
@@ -114,19 +117,30 @@
     // Not worth worrying about minimizing the dirty region for debugging, so just
     // dirty the entire viewport.
     if (dirty) {
+        mDirtyRegion = *dirty;
         dirty->setEmpty();
     }
 }
 
 void DrawProfiler::draw(OpenGLRenderer* canvas) {
-    if (CC_LIKELY(mType != kBars)) {
-        return;
+    RETURN_IF_DISABLED();
+
+    if (mShowDirtyRegions) {
+        mFlashToggle = !mFlashToggle;
+        if (mFlashToggle) {
+            SkPaint paint;
+            paint.setColor(0x7fff0000);
+            canvas->drawRect(mDirtyRegion.fLeft, mDirtyRegion.fTop,
+                    mDirtyRegion.fRight, mDirtyRegion.fBottom, &paint);
+        }
     }
 
-    prepareShapes(canvas->getViewportHeight());
-    drawGraph(canvas);
-    drawCurrentFrame(canvas);
-    drawThreshold(canvas);
+    if (mType == kBars) {
+        prepareShapes(canvas->getViewportHeight());
+        drawGraph(canvas);
+        drawCurrentFrame(canvas);
+        drawThreshold(canvas);
+    }
 }
 
 void DrawProfiler::createData() {
@@ -217,6 +231,7 @@
 }
 
 bool DrawProfiler::loadSystemProperties() {
+    bool changed = false;
     ProfileType newType = loadRequestedProfileType();
     if (newType != mType) {
         mType = newType;
@@ -225,13 +240,18 @@
         } else {
             createData();
         }
-        return true;
+        changed = true;
     }
-    return false;
+    bool showDirty = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
+    if (showDirty != mShowDirtyRegions) {
+        mShowDirtyRegions = showDirty;
+        changed = true;
+    }
+    return changed;
 }
 
 void DrawProfiler::dumpData(int fd) {
-    RETURN_IF_DISABLED();
+    RETURN_IF_PROFILING_DISABLED();
 
     // This method logs the last N frames (where N is <= mDataSize) since the
     // last call to dumpData(). In other words if there's a dumpData(), draw frame,
diff --git a/libs/hwui/DrawProfiler.h b/libs/hwui/DrawProfiler.h
index 7c06e5d..de64088 100644
--- a/libs/hwui/DrawProfiler.h
+++ b/libs/hwui/DrawProfiler.h
@@ -88,6 +88,10 @@
      * information.
      */
     float** mRects;
+
+    bool mShowDirtyRegions;
+    SkRect mDirtyRegion;
+    bool mFlashToggle;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7a094fd..19fc9a3 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -151,7 +151,6 @@
         , mScissorOptimizationDisabled(false)
         , mSuppressTiling(false)
         , mFirstFrameAfterResize(true)
-        , mCountOverdraw(false)
         , mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN})
         , mLightRadius(FLT_MIN)
         , mAmbientShadowAlpha(0)
@@ -266,7 +265,7 @@
 }
 
 status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
-    if (!opaque || mCountOverdraw) {
+    if (!opaque) {
         mCaches.enableScissor();
         mCaches.setScissor(left, getViewportHeight() - bottom, right - left, bottom - top);
         glClear(GL_COLOR_BUFFER_BIT);
@@ -347,10 +346,6 @@
 #endif
     }
 
-    if (mCountOverdraw) {
-        countOverdraw();
-    }
-
     mFrameStarted = false;
 }
 
@@ -464,21 +459,6 @@
     }
 }
 
-void OpenGLRenderer::countOverdraw() {
-    size_t count = getWidth() * getHeight();
-    uint32_t* buffer = new uint32_t[count];
-    glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
-
-    size_t total = 0;
-    for (size_t i = 0; i < count; i++) {
-        total += buffer[i] & 0xff;
-    }
-
-    mOverdraw = total / float(count);
-
-    delete[] buffer;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Layers
 ///////////////////////////////////////////////////////////////////////////////
@@ -1647,8 +1627,6 @@
     mDescription.hasDebugHighlight = !mCaches.debugOverdraw &&
             mCaches.debugStencilClip == Caches::kStencilShowHighlight &&
             mCaches.stencil.isTestEnabled();
-
-    mDescription.emulateStencil = mCountOverdraw;
 }
 
 void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
@@ -1980,8 +1958,7 @@
             return status | replayStruct.mDrawGlStatus;
         }
 
-        bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs!
-        DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw);
+        DeferredDisplayList deferredList(*currentClipRect());
         DeferStateStruct deferStruct(deferredList, *this, replayFlags);
         renderNode->defer(deferStruct, 0);
 
@@ -3453,19 +3430,6 @@
     }
     mSkipOutlineClip = true;
 
-    if (mCountOverdraw) {
-        if (!mCaches.blend) glEnable(GL_BLEND);
-        if (mCaches.lastSrcMode != GL_ONE || mCaches.lastDstMode != GL_ONE) {
-            glBlendFunc(GL_ONE, GL_ONE);
-        }
-
-        mCaches.blend = true;
-        mCaches.lastSrcMode = GL_ONE;
-        mCaches.lastDstMode = GL_ONE;
-
-        return;
-    }
-
     blend = blend || mode != SkXfermode::kSrcOver_Mode;
 
     if (blend) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 47ef1a9..c2c0b0e 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -136,14 +136,6 @@
     virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
     virtual void finish();
 
-    void setCountOverdrawEnabled(bool enabled) {
-        mCountOverdraw = enabled;
-    }
-
-    float getOverdraw() {
-        return mCountOverdraw ? mOverdraw : 0.0f;
-    }
-
     virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
 
     void pushLayerUpdate(Layer* layer);
@@ -1015,11 +1007,6 @@
     bool mSuppressTiling;
     bool mFirstFrameAfterResize;
 
-    // If true, this renderer will setup drawing to emulate
-    // an increment stencil buffer in the color buffer
-    bool mCountOverdraw;
-    float mOverdraw;
-
     bool mSkipOutlineClip;
 
     // Lighting + shadows
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 56773f4..d05b331 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -84,8 +84,7 @@
 #define PROGRAM_HAS_COLORS 42
 
 #define PROGRAM_HAS_DEBUG_HIGHLIGHT 43
-#define PROGRAM_EMULATE_STENCIL 44
-#define PROGRAM_HAS_ROUND_RECT_CLIP 45
+#define PROGRAM_HAS_ROUND_RECT_CLIP 44
 
 ///////////////////////////////////////////////////////////////////////////////
 // Types
@@ -161,7 +160,6 @@
     float gamma;
 
     bool hasDebugHighlight;
-    bool emulateStencil;
     bool hasRoundRectClip;
 
     /**
@@ -204,7 +202,6 @@
         gamma = 2.2f;
 
         hasDebugHighlight = false;
-        emulateStencil = false;
         hasRoundRectClip = false;
     }
 
@@ -272,7 +269,6 @@
         if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
         if (hasColors) key |= programid(0x1) << PROGRAM_HAS_COLORS;
         if (hasDebugHighlight) key |= programid(0x1) << PROGRAM_HAS_DEBUG_HIGHLIGHT;
-        if (emulateStencil) key |= programid(0x1) << PROGRAM_EMULATE_STENCIL;
         if (hasRoundRectClip) key |= programid(0x1) << PROGRAM_HAS_ROUND_RECT_CLIP;
         return key;
     }
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 06353c0..62835e0 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -347,12 +347,6 @@
 
 const char* gFS_Main_DebugHighlight =
         "    gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n";
-const char* gFS_Main_EmulateStencil =
-        "    gl_FragColor.rgba = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 1.0);\n"
-        "    return;\n"
-        "    /*\n";
-const char* gFS_Footer_EmulateStencil =
-        "    */\n";
 const char* gFS_Footer =
         "}\n\n";
 
@@ -617,7 +611,6 @@
             && !description.hasColors
             && description.colorOp == ProgramDescription::kColorNone
             && !description.hasDebugHighlight
-            && !description.emulateStencil
             && !description.hasRoundRectClip) {
         bool fast = false;
 
@@ -698,9 +691,6 @@
 
     // Begin the shader
     shader.append(gFS_Main); {
-        if (description.emulateStencil) {
-            shader.append(gFS_Main_EmulateStencil);
-        }
         // Stores the result in fragColor directly
         if (description.hasTexture || description.hasExternalTexture) {
             if (description.hasAlpha8Texture) {
@@ -779,9 +769,6 @@
             shader.append(gFS_Main_DebugHighlight);
         }
     }
-    if (description.emulateStencil) {
-        shader.append(gFS_Footer_EmulateStencil);
-    }
     // End the shader
     shader.append(gFS_Footer);
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 7eb9a32..befed16 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -133,6 +133,15 @@
 #define PROPERTY_DEBUG_STENCIL_CLIP "debug.hwui.show_non_rect_clip"
 
 /**
+ * Turn on to draw dirty regions every other frame.
+ *
+ * Possible values:
+ * "true", to enable dirty regions debugging
+ * "false", to disable dirty regions debugging
+ */
+#define PROPERTY_DEBUG_SHOW_DIRTY_REGIONS "debug.hwui.show_dirty_regions"
+
+/**
  * Disables draw operation deferral if set to "true", forcing draw
  * commands to be issued to OpenGL in order, and processed in sequence
  * with state-manipulation canvas commands.