speedup gl port by detecting when the device hasn't changed
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 77eb134..b5a6b58 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -741,6 +741,7 @@
     uint32_t    fMCRecStorage[32];
 
     SkBounder*  fBounder;
+    SkDevice*   fLastDeviceToGainFocus;
 
     void prepareForDeviceDraw(SkDevice*);
     
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index c7289e8..fc323d3 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -562,10 +562,6 @@
     */
     void subdivide(SkScalar dist, bool bendLines, SkPath* dst = NULL) const;
 
-    /** Return an SVG-compatible string of the path.
-    */
-    void toString(SkString*) const;
-
     SkDEBUGCODE(void validate() const;)
 
 private:
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 4f44286..2513b51 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -813,6 +813,7 @@
     x <<= 1;
     y <<= 1;
     const SkPMColor* p = src.getAddr32(x, y);
+    const SkPMColor* baseP = p;
     SkPMColor c, ag, rb;
 
     c = *p; ag = (c >> 8) & 0xFF00FF; rb = c & 0xFF00FF;
@@ -821,8 +822,9 @@
     }
     c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
 
+    p = baseP;
     if (y < src.height() - 1) {
-        p = src.getAddr32(x, y + 1);
+        p += src.rowBytes() >> 2;
     }
     c = *p; ag += (c >> 8) & 0xFF00FF; rb += c & 0xFF00FF;
     if (x < src.width() - 1) {
@@ -849,19 +851,21 @@
     x <<= 1;
     y <<= 1;
     const uint16_t* p = src.getAddr16(x, y);
+    const uint16_t* baseP = p;
     SkPMColor       c;
 
     c = expand16(*p);
-    if (x < (int)src.width() - 1) {
+    if (x < src.width() - 1) {
         p += 1;
     }
     c += expand16(*p);
 
-    if (y < (int)src.height() - 1) {
-        p = src.getAddr16(x, y + 1);
+    p = baseP;
+    if (y < src.height() - 1) {
+        p += src.rowBytes() >> 1;
     }
     c += expand16(*p);
-    if (x < (int)src.width() - 1) {
+    if (x < src.width() - 1) {
         p += 1;
     }
     c += expand16(*p);
@@ -882,6 +886,7 @@
     x <<= 1;
     y <<= 1;
     const uint16_t* p = src.getAddr16(x, y);
+    const uint16_t* baseP = p;
     uint32_t        c;
 
     c = expand4444(*p);
@@ -890,8 +895,9 @@
     }
     c += expand4444(*p);
 
+    p = baseP;
     if (y < src.height() - 1) {
-        p = src.getAddr16(x, y + 1);
+        p += src.rowBytes() >> 1;
     }
     c += expand4444(*p);
     if (x < src.width() - 1) {
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 38135c6..852b25e 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -248,7 +248,7 @@
             }
 
             // fCurrLayer may be NULL now
-            
+
             fCanvas->prepareForDeviceDraw(fDevice);
             return true;
         }
@@ -390,6 +390,7 @@
 SkDevice* SkCanvas::init(SkDevice* device) {
     fBounder = NULL;
     fLocalBoundsCompareTypeDirty = true;
+    fLastDeviceToGainFocus = NULL;
 
     fMCRec = (MCRec*)fMCStack.push_back();
     new (fMCRec) MCRec(NULL, 0);
@@ -546,7 +547,10 @@
 
 void SkCanvas::prepareForDeviceDraw(SkDevice* device) {
     SkASSERT(device);
-    device->gainFocus(this);
+    if (fLastDeviceToGainFocus != device) {
+        device->gainFocus(this);
+        fLastDeviceToGainFocus = device;
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 2127bb4..082d2e8 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -1220,61 +1220,6 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-
-#include "SkString.h"
-#include "SkStream.h"
-
-static void write_scalar(SkWStream* stream, SkScalar value) {
-    char    buffer[SkStrAppendScalar_MaxSize];
-    char*   stop = SkStrAppendScalar(buffer, value);
-    stream->write(buffer, stop - buffer);
-}
-
-static void append_scalars(SkWStream* stream, char verb, const SkScalar data[],
-                           int count) {
-    stream->write(&verb, 1);
-    write_scalar(stream, data[0]);
-    for (int i = 1; i < count; i++) {
-        if (data[i] >= 0) {
-            // can skip the separater if data[i] is negative
-            stream->write(" ", 1);
-        }
-        write_scalar(stream, data[i]);
-    }
-}
-
-void SkPath::toString(SkString* str) const {
-    SkDynamicMemoryWStream  stream;
-
-    SkPath::Iter    iter(*this, false);
-    SkPoint         pts[4];
-    
-    for (;;) {
-        switch (iter.next(pts)) {
-            case SkPath::kMove_Verb:
-                append_scalars(&stream, 'M', &pts[0].fX, 2);
-                break;
-            case SkPath::kLine_Verb:
-                append_scalars(&stream, 'L', &pts[1].fX, 2);
-                break;
-            case SkPath::kQuad_Verb:
-                append_scalars(&stream, 'Q', &pts[1].fX, 4);
-                break;
-            case SkPath::kCubic_Verb:
-                append_scalars(&stream, 'C', &pts[1].fX, 6);
-                break;
-            case SkPath::kClose_Verb:
-                stream.write("Z", 1);
-                break;
-            case SkPath::kDone_Verb:
-                str->resize(stream.getOffset());
-                stream.copyTo(str->writable_str());
-                return;
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifdef SK_DEBUG