add decoding bitmaps to bench tool
refresh misc. skia files
diff --git a/bench/Android.mk b/bench/Android.mk
index ba29622..f084eb9 100644
--- a/bench/Android.mk
+++ b/bench/Android.mk
@@ -4,6 +4,7 @@
 
 LOCAL_SRC_FILES := \
 	BitmapBench.cpp \
+    DecodeBench.cpp \
 	RectBench.cpp \
 	RepeatTileBench.cpp \
 	TextBench.cpp \
diff --git a/bench/BitmapBench.cpp b/bench/BitmapBench.cpp
index 22c0a01..89dfa74 100644
--- a/bench/BitmapBench.cpp
+++ b/bench/BitmapBench.cpp
@@ -96,7 +96,8 @@
     SkString    fName;
     enum { N = 300 };
 public:
-    BitmapBench(SkBitmap::Config c, int tx = -1, int ty = -1) : fTileX(tx), fTileY(ty) {
+    BitmapBench(void* param, SkBitmap::Config c, int tx = -1, int ty = -1)
+        : INHERITED(param), fTileX(tx), fTileY(ty) {
         const int w = 128;
         const int h = 128;
         SkBitmap bm;
@@ -153,10 +154,10 @@
     typedef SkBenchmark INHERITED;
 };
 
-static SkBenchmark* Fact0(void*) { return new BitmapBench(SkBitmap::kARGB_8888_Config); }
-static SkBenchmark* Fact1(void*) { return new BitmapBench(SkBitmap::kRGB_565_Config); }
-static SkBenchmark* Fact2(void*) { return new BitmapBench(SkBitmap::kARGB_4444_Config); }
-static SkBenchmark* Fact3(void*) { return new BitmapBench(SkBitmap::kIndex8_Config); }
+static SkBenchmark* Fact0(void* p) { return new BitmapBench(p, SkBitmap::kARGB_8888_Config); }
+static SkBenchmark* Fact1(void* p) { return new BitmapBench(p, SkBitmap::kRGB_565_Config); }
+static SkBenchmark* Fact2(void* p) { return new BitmapBench(p, SkBitmap::kARGB_4444_Config); }
+static SkBenchmark* Fact3(void* p) { return new BitmapBench(p, SkBitmap::kIndex8_Config); }
 
 static BenchRegistry gReg0(Fact0);
 static BenchRegistry gReg1(Fact1);
diff --git a/bench/DecodeBench.cpp b/bench/DecodeBench.cpp
new file mode 100644
index 0000000..6abd054
--- /dev/null
+++ b/bench/DecodeBench.cpp
@@ -0,0 +1,53 @@
+#include "SkBenchmark.h"
+#include "SkBitmap.h"
+#include "SkImageDecoder.h"
+#include "SkString.h"
+
+static const char* gConfigName[] = {
+    "ERROR", "a1", "a8", "index8", "565", "4444", "8888"
+};
+
+class DecodeBench : public SkBenchmark {
+    const char* fFilename;
+    SkBitmap::Config fPrefConfig;
+    SkString fName;
+    enum { N = 10 };
+public:
+    DecodeBench(void* param, SkBitmap::Config c) : SkBenchmark(param) {
+        fFilename = this->findDefine("decode-filename");
+        fPrefConfig = c;
+        
+        const char* fname = NULL;
+        if (fFilename) {
+            fname = strrchr(fFilename, '/');
+            if (fname) {
+                fname += 1; // skip the slash
+            }
+        }
+        fName.printf("decode_%s_%s", gConfigName[c], fname);
+    }
+
+protected:
+    virtual const char* onGetName() {
+        return fName.c_str();
+    }
+
+    virtual void onDraw(SkCanvas* canvas) {
+        for (int i = 0; i < N; i++) {
+            SkBitmap bm;
+            SkImageDecoder::DecodeFile(fFilename, &bm, fPrefConfig,
+                                       SkImageDecoder::kDecodePixels_Mode);
+        }
+    }
+
+private:
+    typedef SkBenchmark INHERITED;
+};
+
+static SkBenchmark* Fact0(void* p) { return new DecodeBench(p, SkBitmap::kARGB_8888_Config); }
+static SkBenchmark* Fact1(void* p) { return new DecodeBench(p, SkBitmap::kRGB_565_Config); }
+static SkBenchmark* Fact2(void* p) { return new DecodeBench(p, SkBitmap::kARGB_4444_Config); }
+
+static BenchRegistry gReg0(Fact0);
+static BenchRegistry gReg1(Fact1);
+static BenchRegistry gReg2(Fact2);
diff --git a/bench/RectBench.cpp b/bench/RectBench.cpp
index 69e0b00..6f34eb5 100644
--- a/bench/RectBench.cpp
+++ b/bench/RectBench.cpp
@@ -15,7 +15,7 @@
     SkRect  fRects[N];
     SkColor fColors[N];
 
-    RectBench(int shift) : fShift(shift) {
+    RectBench(void* param, int shift) : INHERITED(param), fShift(shift) {
         SkRandom rand;
         for (int i = 0; i < N; i++) {
             int x = rand.nextU() % W;
@@ -53,11 +53,13 @@
             this->drawThisRect(canvas, fRects[i], paint);
         }
     }
+private:
+    typedef SkBenchmark INHERITED;
 };
 
 class OvalBench : public RectBench {
 public:
-    OvalBench(int shift) : RectBench(shift) {}
+    OvalBench(void* param, int shift) : RectBench(param, shift) {}
 protected:
     virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
         c->drawOval(r, p);
@@ -67,7 +69,7 @@
 
 class RRectBench : public RectBench {
 public:
-    RRectBench(int shift) : RectBench(shift) {}
+    RRectBench(void* param, int shift) : RectBench(param, shift) {}
 protected:
     virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
         c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
@@ -80,8 +82,8 @@
     SkCanvas::PointMode fMode;
     const char* fName;
 
-    PointsBench(SkCanvas::PointMode mode, const char* name) : 
-        RectBench(2), fMode(mode) {
+    PointsBench(void* param, SkCanvas::PointMode mode, const char* name) : 
+        RectBench(param, 2), fMode(mode) {
         fName = name;
     }
 
@@ -105,20 +107,20 @@
     virtual const char* onGetName() { return fName; }
 };
 
-static SkBenchmark* RectFactory1(void*) { return SkNEW_ARGS(RectBench, (1)); }
-static SkBenchmark* RectFactory2(void*) { return SkNEW_ARGS(RectBench, (3)); }
-static SkBenchmark* OvalFactory1(void*) { return SkNEW_ARGS(OvalBench, (1)); }
-static SkBenchmark* OvalFactory2(void*) { return SkNEW_ARGS(OvalBench, (3)); }
-static SkBenchmark* RRectFactory1(void*) { return SkNEW_ARGS(RRectBench, (1)); }
-static SkBenchmark* RRectFactory2(void*) { return SkNEW_ARGS(RRectBench, (3)); }
-static SkBenchmark* PointsFactory(void*) {
-    return SkNEW_ARGS(PointsBench, (SkCanvas::kPoints_PointMode, "points"));
+static SkBenchmark* RectFactory1(void* p) { return SkNEW_ARGS(RectBench, (p, 1)); }
+static SkBenchmark* RectFactory2(void* p) { return SkNEW_ARGS(RectBench, (p, 3)); }
+static SkBenchmark* OvalFactory1(void* p) { return SkNEW_ARGS(OvalBench, (p, 1)); }
+static SkBenchmark* OvalFactory2(void* p) { return SkNEW_ARGS(OvalBench, (p, 3)); }
+static SkBenchmark* RRectFactory1(void* p) { return SkNEW_ARGS(RRectBench, (p, 1)); }
+static SkBenchmark* RRectFactory2(void* p) { return SkNEW_ARGS(RRectBench, (p, 3)); }
+static SkBenchmark* PointsFactory(void* p) {
+    return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points"));
 }
-static SkBenchmark* LinesFactory(void*) {
-    return SkNEW_ARGS(PointsBench, (SkCanvas::kLines_PointMode, "lines"));
+static SkBenchmark* LinesFactory(void* p) {
+    return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines"));
 }
-static SkBenchmark* PolygonFactory(void*) {
-    return SkNEW_ARGS(PointsBench, (SkCanvas::kPolygon_PointMode, "polygon"));
+static SkBenchmark* PolygonFactory(void* p) {
+    return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon"));
 }
 
 static BenchRegistry gRectReg1(RectFactory1);
diff --git a/bench/RepeatTileBench.cpp b/bench/RepeatTileBench.cpp
index 48c1f6f..97bbeb8 100644
--- a/bench/RepeatTileBench.cpp
+++ b/bench/RepeatTileBench.cpp
@@ -81,7 +81,7 @@
     SkString    fName;
     enum { N = 20 };
 public:
-    RepeatTileBench(SkBitmap::Config c) {
+    RepeatTileBench(void* param, SkBitmap::Config c) : INHERITED(param) {
         const int w = 50;
         const int h = 50;
         SkBitmap bm;
@@ -127,10 +127,10 @@
     typedef SkBenchmark INHERITED;
 };
 
-static SkBenchmark* Fact0(void*) { return new RepeatTileBench(SkBitmap::kARGB_8888_Config); }
-static SkBenchmark* Fact1(void*) { return new RepeatTileBench(SkBitmap::kRGB_565_Config); }
-static SkBenchmark* Fact2(void*) { return new RepeatTileBench(SkBitmap::kARGB_4444_Config); }
-static SkBenchmark* Fact3(void*) { return new RepeatTileBench(SkBitmap::kIndex8_Config); }
+static SkBenchmark* Fact0(void* p) { return new RepeatTileBench(p, SkBitmap::kARGB_8888_Config); }
+static SkBenchmark* Fact1(void* p) { return new RepeatTileBench(p, SkBitmap::kRGB_565_Config); }
+static SkBenchmark* Fact2(void* p) { return new RepeatTileBench(p, SkBitmap::kARGB_4444_Config); }
+static SkBenchmark* Fact3(void* p) { return new RepeatTileBench(p, SkBitmap::kIndex8_Config); }
 
 static BenchRegistry gReg0(Fact0);
 static BenchRegistry gReg1(Fact1);
diff --git a/bench/SkBenchmark.cpp b/bench/SkBenchmark.cpp
index 7bc87ee..8dd66f0 100644
--- a/bench/SkBenchmark.cpp
+++ b/bench/SkBenchmark.cpp
@@ -3,7 +3,8 @@
 
 template BenchRegistry* BenchRegistry::gHead;
 
-SkBenchmark::SkBenchmark() {
+SkBenchmark::SkBenchmark(void* defineDict) {
+    fDict = reinterpret_cast<const SkTDict<const char*>*>(defineDict);
     fForceAlpha = 0xFF;
     fForceAA = true;
 }
@@ -26,6 +27,16 @@
     paint->setFilterBitmap(fForceFilter);
 }
 
+const char* SkBenchmark::findDefine(const char* key) const {
+    if (fDict) {
+        const char* value;
+        if (fDict->find(key, &value)) {
+            return value;
+        }
+    }
+    return NULL;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 SkIPoint SkBenchmark::onGetSize() {
diff --git a/bench/SkBenchmark.h b/bench/SkBenchmark.h
index 2058251..5ecff3b 100644
--- a/bench/SkBenchmark.h
+++ b/bench/SkBenchmark.h
@@ -3,6 +3,7 @@
 
 #include "SkRefCnt.h"
 #include "SkPoint.h"
+#include "SkTDict.h"
 #include "SkTRegistry.h"
 
 class SkCanvas;
@@ -10,7 +11,7 @@
 
 class SkBenchmark : public SkRefCnt {
 public:
-    SkBenchmark();
+    SkBenchmark(void* defineDict);
 
     const char* getName();
     SkIPoint getSize();
@@ -27,7 +28,9 @@
     void setForceFilter(bool filter) {
         fForceFilter = filter;
     }
-    
+
+    const char* findDefine(const char* key) const;
+
 protected:
     void setupPaint(SkPaint* paint);
 
@@ -37,6 +40,7 @@
     virtual SkIPoint onGetSize();
 
 private:
+    const SkTDict<const char*>* fDict;
     int     fForceAlpha;
     bool    fForceAA;
     bool    fForceFilter;
diff --git a/bench/TextBench.cpp b/bench/TextBench.cpp
index a4ed9f2..93ef1c5 100644
--- a/bench/TextBench.cpp
+++ b/bench/TextBench.cpp
@@ -24,7 +24,8 @@
     SkString    fName;
     enum { N = 300 };
 public:
-    TextBench(const char text[], int ps, bool linearText, bool posText) {
+    TextBench(void* param, const char text[], int ps, bool linearText,
+              bool posText) : INHERITED(param) {
         fText.set(text);
 
         fPaint.setAntiAlias(true);
@@ -97,14 +98,14 @@
 #define SMALL   9
 #define BIG     48
 
-static SkBenchmark* Fact0(void*) { return new TextBench(STR, SMALL, false, false); }
-static SkBenchmark* Fact1(void*) { return new TextBench(STR, SMALL, false, true); }
-static SkBenchmark* Fact2(void*) { return new TextBench(STR, SMALL, true, false); }
-static SkBenchmark* Fact3(void*) { return new TextBench(STR, SMALL, true, true); }
-static SkBenchmark* Fact4(void*) { return new TextBench(STR, BIG, false, false); }
-static SkBenchmark* Fact5(void*) { return new TextBench(STR, BIG, false, true); }
-static SkBenchmark* Fact6(void*) { return new TextBench(STR, BIG, true, false); }
-static SkBenchmark* Fact7(void*) { return new TextBench(STR, BIG, true, true); }
+static SkBenchmark* Fact0(void* p) { return new TextBench(p, STR, SMALL, false, false); }
+static SkBenchmark* Fact1(void* p) { return new TextBench(p, STR, SMALL, false, true); }
+static SkBenchmark* Fact2(void* p) { return new TextBench(p, STR, SMALL, true, false); }
+static SkBenchmark* Fact3(void* p) { return new TextBench(p, STR, SMALL, true, true); }
+static SkBenchmark* Fact4(void* p) { return new TextBench(p, STR, BIG, false, false); }
+static SkBenchmark* Fact5(void* p) { return new TextBench(p, STR, BIG, false, true); }
+static SkBenchmark* Fact6(void* p) { return new TextBench(p, STR, BIG, true, false); }
+static SkBenchmark* Fact7(void* p) { return new TextBench(p, STR, BIG, true, true); }
 
 static BenchRegistry gReg0(Fact0);
 static BenchRegistry gReg1(Fact1);
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp
index 501e86a..8ccb373 100644
--- a/bench/benchmain.cpp
+++ b/bench/benchmain.cpp
@@ -49,21 +49,23 @@
 
 class Iter {
 public:
-    Iter() {
+    Iter(void* param) {
         fBench = BenchRegistry::Head();
+        fParam = param;
     }
     
     SkBenchmark* next() {
         if (fBench) {
             BenchRegistry::Factory f = fBench->factory();
             fBench = fBench->next();
-            return f(0);
+            return f(fParam);
         }
         return NULL;
     }
     
 private:
     const BenchRegistry* fBench;
+    void* fParam;
 };
 
 static void make_filename(const char name[], SkString* path) {
@@ -186,6 +188,7 @@
 int main (int argc, char * const argv[]) {
     SkAutoGraphics ag;
 
+    SkTDict<const char*> defineDict(1024);
     int repeatDraw = 1;
     int forceAlpha = 0xFF;
     bool forceAA = true;
@@ -273,6 +276,14 @@
                 log_error("missing arg for -config\n");
                 return -1;
             }
+        } else if (strncmp(*argv, "-D", 2) == 0) {
+            argv++;
+            if (strlen(*argv) > 2 && argv < stop) {
+                defineDict.set(argv[-1] + 2, *argv);
+            } else {
+                log_error("incomplete '-Dfoo bar' definition\n");
+                return -1;
+            }
         } else {
             SkString str;
             str.printf("unrecognized arg %s\n", *argv);
@@ -281,7 +292,7 @@
         }
     }
 
-    Iter iter;
+    Iter iter(&defineDict);
     SkBenchmark* bench;
     while ((bench = iter.next()) != NULL) {
         SkIPoint dim = bench->getSize();
diff --git a/include/core/SkTDStack.h b/include/core/SkTDStack.h
index 5bc10ee..321c138 100644
--- a/include/core/SkTDStack.h
+++ b/include/core/SkTDStack.h
@@ -40,6 +40,8 @@
     }
 
     int count() const { return fTotalCount; }
+    int depth() const { return fTotalCount; }
+    bool empty() const { return fTotalCount == 0; }
 
     T* push()
     {
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
index 229c3d8..2775543 100644
--- a/src/core/SkGeometry.cpp
+++ b/src/core/SkGeometry.cpp
@@ -505,6 +505,29 @@
     interp_cubic_coords(&src[0].fY, &dst[0].fY, t);
 }
 
+/*  http://code.google.com/p/skia/issues/detail?id=32
+ 
+    This test code would fail when we didn't check the return result of
+    valid_unit_divide in SkChopCubicAt(... tValues[], int roots). The reason is
+    that after the first chop, the parameters to valid_unit_divide are equal
+    (thanks to finite float precision and rounding in the subtracts). Thus
+    even though the 2nd tValue looks < 1.0, after we renormalize it, we end
+    up with 1.0, hence the need to check and just return the last cubic as
+    a degenerate clump of 4 points in the sampe place.
+
+    static void test_cubic() {
+        SkPoint src[4] = {
+            { 556.25000, 523.03003 },
+            { 556.23999, 522.96002 },
+            { 556.21997, 522.89001 },
+            { 556.21997, 522.82001 }
+        };
+        SkPoint dst[10];
+        SkScalar tval[] = { 0.33333334f, 0.99999994f };
+        SkChopCubicAt(src, dst, tval, 2);
+    }
+ */
+
 void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar tValues[], int roots)
 {
 #ifdef SK_DEBUG
@@ -533,12 +556,18 @@
                 if (i == roots - 1)
                     break;
 
-                SkDEBUGCODE(int valid =) valid_unit_divide(tValues[i+1] - tValues[i], SK_Scalar1 - tValues[i], &t);
-                SkASSERT(valid);
-
                 dst += 3;
+                // have src point to the remaining cubic (after the chop)
                 memcpy(tmp, dst, 4 * sizeof(SkPoint));
                 src = tmp;
+
+                // watch out in case the renormalized t isn't in range
+                if (!valid_unit_divide(tValues[i+1] - tValues[i],
+                                       SK_Scalar1 - tValues[i], &t)) {
+                    // if we can't, just create a degenerate cubic
+                    dst[4] = dst[5] = dst[6] = src[3];
+                    break;
+                }
             }
         }
     }
diff --git a/src/utils/mac/SkOSWindow_Mac.cpp b/src/utils/mac/SkOSWindow_Mac.cpp
index 40ed57c..98adbbe 100644
--- a/src/utils/mac/SkOSWindow_Mac.cpp
+++ b/src/utils/mac/SkOSWindow_Mac.cpp
@@ -327,17 +327,20 @@
 			GlobalToLocal(&pt);
 
 			switch (wKind) {
-			case kEventMouseDown:
-				(void)win->handleClick(pt.h, pt.v, Click::kDown_State);
-				break;
-			case kEventMouseDragged:
-				(void)win->handleClick(pt.h, pt.v, Click::kMoved_State);
-				break;
-			case kEventMouseUp:
-				(void)win->handleClick(pt.h, pt.v, Click::kUp_State);
-				break;
-			default:
-				break;
+                case kEventMouseDown:
+                    (void)win->handleClick(pt.h, pt.v, Click::kDown_State);
+                    result = noErr;
+                    break;
+                case kEventMouseDragged:
+                    (void)win->handleClick(pt.h, pt.v, Click::kMoved_State);
+                    result = noErr;
+                    break;
+                case kEventMouseUp:
+                    (void)win->handleClick(pt.h, pt.v, Click::kUp_State);
+                    result = noErr;
+                    break;
+                default:
+                    break;
 			}
             break;
 		}