This adds cull rect visualization to the debugger's "mega" visualization mode.

R=fmalita@google.com, fmalita@chromium.org

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/177423013

git-svn-id: http://skia.googlecode.com/svn/trunk@13649 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index db2b7dc..066d7a6 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -197,8 +197,9 @@
 
 // set up the saveLayer commands so that the active ones
 // return true in their 'active' method
-void SkDebugCanvas::markActiveSaveLayers(int index) {
-    SkTDArray<SkDrawCommand*> activeLayers;
+void SkDebugCanvas::markActiveCommands(int index) {
+    fActiveLayers.rewind();
+    fActiveCulls.rewind();
 
     for (int i = 0; i < fCommandVector.count(); ++i) {
         fCommandVector[i]->setActive(false);
@@ -206,15 +207,23 @@
 
     for (int i = 0; i < index; ++i) {
         SkDrawCommand::Action result = fCommandVector[i]->action();
-        if (SkDrawCommand::kPush_Action == result) {
-            activeLayers.push(fCommandVector[i]);
-        } else if (SkDrawCommand::kPop_Action == result) {
-            activeLayers.pop();
+        if (SkDrawCommand::kPushLayer_Action == result) {
+            fActiveLayers.push(fCommandVector[i]);
+        } else if (SkDrawCommand::kPopLayer_Action == result) {
+            fActiveLayers.pop();
+        } else if (SkDrawCommand::kPushCull_Action == result) {
+            fActiveCulls.push(fCommandVector[i]);
+        } else if (SkDrawCommand::kPopCull_Action == result) {
+            fActiveCulls.pop();
         }
     }
 
-    for (int i = 0; i < activeLayers.count(); ++i) {
-        activeLayers[i]->setActive(true);
+    for (int i = 0; i < fActiveLayers.count(); ++i) {
+        fActiveLayers[i]->setActive(true);
+    }
+
+    for (int i = 0; i < fActiveCulls.count(); ++i) {
+        fActiveCulls[i]->setActive(true);
     }
 }
 
@@ -268,7 +277,7 @@
     }
 
     if (fMegaVizMode) {
-        this->markActiveSaveLayers(index);
+        this->markActiveCommands(index);
     }
 
     for (; i <= index; i++) {
@@ -288,14 +297,16 @@
 
         if (fCommandVector[i]->isVisible()) {
             if (fMegaVizMode && fCommandVector[i]->active()) {
-                // All active saveLayers get replaced with saves so all draws go to the
-                // visible canvas
-                canvas->save();
-                ++fOutstandingSaveCount;
+                // "active" commands execute their visualization behaviors:
+                //     All active saveLayers get replaced with saves so all draws go to the
+                //     visible canvas.
+                //     All active culls draw their cull box
+                fCommandVector[i]->vizExecute(canvas);
             } else {
                 fCommandVector[i]->execute(canvas);
-                fCommandVector[i]->trackSaveState(&fOutstandingSaveCount);
             }
+
+            fCommandVector[i]->trackSaveState(&fOutstandingSaveCount);
         }
     }
 
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index cb4acc8..8c1f72f 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -254,7 +254,7 @@
     virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
     virtual void onClipRegion(const SkRegion& region, SkRegion::Op) SK_OVERRIDE;
 
-    void markActiveSaveLayers(int index);
+    void markActiveCommands(int index);
 
 private:
     SkTDArray<SkDrawCommand*> fCommandVector;
@@ -281,6 +281,18 @@
     */
     int fOutstandingSaveCount;
 
+    /** 
+        The active saveLayer commands at a given point in the renderering.
+        Only used when "mega" visualization is enabled.
+    */
+    SkTDArray<SkDrawCommand*> fActiveLayers;
+
+    /** 
+        The active cull commands at a given point in the rendering.
+        Only used when "mega" visualization is enabled.
+    */
+    SkTDArray<SkDrawCommand*> fActiveCulls;
+
     /**
         Adds the command to the classes vector of commands.
         @param command  The draw command for execution
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 16b8556..7e6b22b 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -885,6 +885,10 @@
                       fFlags);
 }
 
+void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) {
+    canvas->save();
+}
+
 void SkSaveLayerCommand::trackSaveState(int* state) {
     (*state)++;
 }
@@ -946,10 +950,18 @@
 }
 
 void SkPushCullCommand::execute(SkCanvas* canvas) {
-    //FIXME: add visualization overlay.
     canvas->pushCull(fCullRect);
 }
 
+void SkPushCullCommand::vizExecute(SkCanvas* canvas) {
+    canvas->pushCull(fCullRect);
+
+    SkPaint p;
+    p.setColor(SK_ColorCYAN);
+    p.setStyle(SkPaint::kStroke_Style);
+    canvas->drawRect(fCullRect, p);
+}
+
 SkPopCullCommand::SkPopCullCommand() {
     fDrawType = POP_CULL;
 }
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index 60df688..a4f50c9 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -36,21 +36,29 @@
     }
 
     SkTDArray<SkString*>* Info() {return &fInfo; };
-    virtual void execute(SkCanvas* canvas)=0;
+    virtual void execute(SkCanvas* canvas) = 0;
+    virtual void vizExecute(SkCanvas* canvas) { };
     /** Does nothing by default, but used by save() and restore()-type
         subclasses to track unresolved save() calls. */
     virtual void trackSaveState(int* state) { };
 
-    // The next "active" system is only used by save, saveLayer and restore.
-    // It is used to determine which saveLayers are currently active (at a 
+    // The next "active" system is only used by save, saveLayer, restore,
+    // pushCull and popCull. It is used in two ways:
+    // To determine which saveLayers are currently active (at a 
     // given point in the rendering).
-    //      save just return a kPush action but don't track active state
-    //      restore just return a kPop action
-    //      saveLayers return kPush but also track the active state
+    //      save just return a kPushLayer action but don't track active state
+    //      restore just return a kPopLayer action
+    //      saveLayers return kPushLayer but also track the active state
+    // To determine which culls are currently active (at a given point)
+    // in the rendering).
+    //      pushCull returns a kPushCull action
+    //      popCull  returns a kPopCull action
     enum Action {
         kNone_Action,
-        kPop_Action,
-        kPush_Action
+        kPopLayer_Action,
+        kPushLayer_Action,
+        kPopCull_Action,
+        kPushCull_Action
     };
     virtual Action action() const { return kNone_Action; }
     virtual void setActive(bool active) {}
@@ -75,7 +83,7 @@
     SkRestoreCommand();
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual void trackSaveState(int* state) SK_OVERRIDE;
-    virtual Action action() const SK_OVERRIDE { return kPop_Action; }
+    virtual Action action() const SK_OVERRIDE { return kPopLayer_Action; }
 
 private:
     typedef SkDrawCommand INHERITED;
@@ -513,7 +521,7 @@
     SkSaveCommand(SkCanvas::SaveFlags flags);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
     virtual void trackSaveState(int* state) SK_OVERRIDE;
-    virtual Action action() const SK_OVERRIDE { return kPush_Action; }
+    virtual Action action() const SK_OVERRIDE { return kPushLayer_Action; }
 private:
     SkCanvas::SaveFlags fFlags;
 
@@ -525,8 +533,9 @@
     SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint,
                        SkCanvas::SaveFlags flags);
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
+    virtual void vizExecute(SkCanvas* canvas) SK_OVERRIDE;
     virtual void trackSaveState(int* state) SK_OVERRIDE;
-    virtual Action action() const SK_OVERRIDE{ return kPush_Action; }
+    virtual Action action() const SK_OVERRIDE{ return kPushLayer_Action; }
     virtual void setActive(bool active) SK_OVERRIDE { fActive = active; }
     virtual bool active() const SK_OVERRIDE { return fActive; }
 
@@ -598,9 +607,13 @@
 public:
     SkPushCullCommand(const SkRect&);
     virtual void execute(SkCanvas*) SK_OVERRIDE;
-
+    virtual void vizExecute(SkCanvas* canvas) SK_OVERRIDE;
+    virtual Action action() const { return kPushCull_Action; }
+    virtual void setActive(bool active) { fActive = active; }
+    virtual bool active() const { return fActive; }
 private:
     SkRect fCullRect;
+    bool   fActive;
 
     typedef SkDrawCommand INHERITED;
 };
@@ -609,7 +622,7 @@
 public:
     SkPopCullCommand();
     virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
-
+    virtual Action action() const { return kPopCull_Action; }
 private:
     typedef SkDrawCommand INHERITED;
 };