fix dumpcanvas to recurse on pictures and shapes
add cached bitmap for gradients to avoid thrashing textures in gl



git-svn-id: http://skia.googlecode.com/svn/trunk@201 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp
index 6d7c795..047c482 100644
--- a/src/effects/SkGradientShader.cpp
+++ b/src/effects/SkGradientShader.cpp
@@ -129,6 +129,9 @@
     const uint16_t*     getCache16();
     const SkPMColor*    getCache32();
 
+    // called when we kill our cached colors (to be rebuilt later on demand)
+    virtual void onCacheReset() {}
+
 private:
     enum {
         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
@@ -388,6 +391,8 @@
         fCache16 = NULL;                // inval the cache
         fCache32 = NULL;                // inval the cache
         fCacheAlpha = paintAlpha;       // record the new alpha
+        // inform our subclasses
+        this->onCacheReset();
     }
     return true;
 }
@@ -606,11 +611,24 @@
                     SkShader::TileMode mode, SkUnitMapper* mapper)
         : Gradient_Shader(colors, pos, colorCount, mode, mapper)
     {
+        fCachedBitmap = NULL;
         pts_to_unit_matrix(pts, &fPtsToUnit);
     }
+    virtual ~Linear_Gradient() {
+        if (fCachedBitmap) {
+            SkDELETE(fCachedBitmap);
+        }
+    }
+
     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count);
     virtual bool asABitmap(SkBitmap*, SkMatrix*, TileMode*);
+    virtual void onCacheReset() {
+        if (fCachedBitmap) {
+            SkDELETE(fCachedBitmap);
+            fCachedBitmap = NULL;
+        }
+    }
 
     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 
         return SkNEW_ARGS(Linear_Gradient, (buffer));
@@ -621,6 +639,8 @@
     virtual Factory getFactory() { return CreateProc; }
 
 private:
+    SkBitmap* fCachedBitmap;    // allocated on demand
+
     typedef Gradient_Shader INHERITED;
 };
 
@@ -731,10 +751,16 @@
 
 bool Linear_Gradient::asABitmap(SkBitmap* bitmap, SkMatrix* matrix,
                                 TileMode xy[]) {
+    // we cache our "bitmap", so it's generationID will be const on subsequent
+    // calls to asABitmap
+    if (NULL == fCachedBitmap) {
+        fCachedBitmap = SkNEW(SkBitmap);
+        fCachedBitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
+        fCachedBitmap->setPixels((void*)this->getCache32(), NULL);
+    }
+
     if (bitmap) {
-        bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1);
-        bitmap->allocPixels();  // share with shader???
-        memcpy(bitmap->getPixels(), this->getCache32(), kCache32Count * 4);
+        *bitmap = *fCachedBitmap;
     }
     if (matrix) {
         matrix->setScale(SkIntToScalar(kCache32Count), SK_Scalar1);
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 7a05f09..2151133 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -1,4 +1,5 @@
 #include "SkDumpCanvas.h"
+#include "SkPicture.h"  
 #include "SkPixelRef.h"
 #include "SkString.h"
 #include <stdarg.h>
@@ -138,7 +139,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkDumpCanvas::SkDumpCanvas(Dumper* dumper) {
+SkDumpCanvas::SkDumpCanvas(Dumper* dumper) : fNestLevel(0) {
     dumper->safeRef();
     fDumper = dumper;
 
@@ -352,10 +353,20 @@
 
 void SkDumpCanvas::drawShape(SkShape* shape) {
     this->dump(kDrawShape_Verb, NULL, "drawShape(%p)", shape);
+    fNestLevel += 1;
+    this->INHERITED::drawShape(shape);
+    fNestLevel -= 1;
+    this->dump(kDrawShape_Verb, NULL, "endShape(%p)", shape);
 }
 
 void SkDumpCanvas::drawPicture(SkPicture& picture) {
-    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p)", &picture);
+    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %d:%d", &picture,
+               picture.width(), picture.height());
+    fNestLevel += 1;
+    this->INHERITED::drawPicture(picture);
+    fNestLevel -= 1;
+    this->dump(kDrawPicture_Verb, NULL, "endPicture(%p) %d:%d", &picture,
+               picture.width(), picture.height());
 }
 
 void SkDumpCanvas::drawVertices(VertexMode vmode, int vertexCount,
@@ -397,7 +408,7 @@
 void SkFormatDumper::dump(SkDumpCanvas* canvas, SkDumpCanvas::Verb verb,
                           const char str[], const SkPaint* p) {
     SkString msg, tab;
-    const int level = canvas->getSaveCount() - 1;
+    const int level = canvas->getNestLevel() + canvas->getSaveCount() - 1;
     SkASSERT(level >= 0);
     for (int i = 0; i < level; i++) {
         tab.append("\t");