merge with changes for GPU backend



git-svn-id: http://skia.googlecode.com/svn/trunk@637 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleAll.cpp b/samplecode/SampleAll.cpp
index 7e83dec..bc24cd3 100644
--- a/samplecode/SampleAll.cpp
+++ b/samplecode/SampleAll.cpp
@@ -37,7 +37,7 @@
     unsigned g = SkGetPackedG32(c);
     unsigned b = SkGetPackedB32(c);
     
-    unsigned x = r * 5 + g * 7 + b * 4 >> 4;
+    unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
     
     return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
 }
@@ -346,7 +346,7 @@
 static void test_math()
 {
     float x;
-    const float PI = 3.141593;
+    const float PI = 3.141593f;
     
     for (x = 0; x < 1; x += 0.05f)
         printf("atan(%g) = %g\n", x, atanf(x) * 180/PI);
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 2bd1fe0..b9e7b48 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -1,6 +1,7 @@
+#include <OpenGL/gl.h>
+
 #include "SkCanvas.h"
 #include "SkDevice.h"
-#include "SkGLCanvas.h"
 #include "SkGraphics.h"
 #include "SkImageEncoder.h"
 #include "SkPaint.h"
@@ -11,19 +12,33 @@
 
 #include "SampleCode.h"
 
+#ifdef SUPPORT_GPU
+    #include "SkGpuCanvas.h"
+    #include "GrContext.h"
+
+    #ifdef SK_SUPPORT_GL
+        #include "GrGLConfig.h"
+    #elif defined(SK_SUPPORT_D3D9)
+        #include <d3d9.h>
+    #endif
+#else
+    typedef SkCanvas SkGpuCanvas;
+    class GrContext;
+#endif
+
+//#define DEFAULT_TO_GPU
+
 extern SkView* create_overview(int, const SkViewFactory[]);
 
 #define SK_SUPPORT_GL
-
-#ifdef SK_SUPPORT_GL
-#include <AGL/agl.h>
-#include <OpenGL/gl.h>
-#endif
+//#define SK_SUPPORT_D3D9
 
 #define ANIMATING_EVENTTYPE "nextSample"
 #define ANIMATING_DELAY     750
 
-#define USE_OFFSCREEN
+#if !defined(SK_BUILD_FOR_WIN32)
+//#define USE_OFFSCREEN
+#endif
 
 SkViewRegister* SkViewRegister::gHead;
 SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
@@ -37,69 +52,65 @@
     gHead = this;
 }
 
-#ifdef SK_SUPPORT_GL
-static AGLContext   gAGLContext;
-
-static void init_gl(WindowRef wref) {
-    GLint major, minor;
-    
-    aglGetVersion(&major, &minor);
-    SkDebugf("---- agl version %d %d\n", major, minor);
-    
-    const GLint pixelAttrs[] = {
-        AGL_RGBA,
-        AGL_DEPTH_SIZE, 32,
-        AGL_OFFSCREEN,
-        AGL_NONE
-    };
-    
-    AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
-    SkDebugf("----- agl format %p\n", format);
-    gAGLContext = aglCreateContext(format, NULL);
-    SkDebugf("----- agl context %p\n", gAGLContext);
-    aglDestroyPixelFormat(format);
-
-    aglEnable(gAGLContext, GL_BLEND);
-    aglEnable(gAGLContext, GL_LINE_SMOOTH);
-    aglEnable(gAGLContext, GL_POINT_SMOOTH);
-    aglEnable(gAGLContext, GL_POLYGON_SMOOTH);
-    
-    aglSetCurrentContext(gAGLContext);
-}
-
-static void setup_offscreen_gl(const SkBitmap& offscreen, WindowRef wref) {
-    GLboolean success = true;
-
-#ifdef USE_OFFSCREEN
-    success = aglSetOffScreen(gAGLContext,
-                                        offscreen.width(),
-                                        offscreen.height(),
-                                        offscreen.rowBytes(),
-                                        offscreen.getPixels());
-#else
-    success = aglSetWindowRef(gAGLContext, wref);
+#if defined(SK_SUPPORT_GL) && defined(SK_SUPPORT_D3D9)
+    #error "choose either GL or D3D9"
 #endif
 
-    GLenum err = aglGetError();
-    if (err) {
-        SkDebugf("---- setoffscreen %d %d %s [%d %d]\n", success, err,
-                 aglErrorString(err), offscreen.width(), offscreen.height());
+#if defined(SK_SUPPORT_GL)
+    #define SK_USE_SHADERS
+#endif
+
+static GrContext* get_global_grctx(SkOSWindow* oswin) {
+#ifdef SUPPORT_GPU
+    // should be pthread-local at least
+    static GrContext* ctx;
+    if (NULL == ctx) {
+#if defined(SK_SUPPORT_GL)
+    #if defined(SK_USE_SHADERS)
+        ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+    #else
+        ctx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
+    #endif
+#elif defined(SK_SUPPORT_D3D9)
+        if (oswin->d3d9Device()) {
+            ctx = GrContext::Create(GrGpu::kDirect3D9_Engine, 
+                                    (IDirect3DDevice9*) oswin->d3d9Device());
+        }
+#endif
     }
-    
-    glEnable(GL_BLEND);
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-    glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
-    glEnable(GL_TEXTURE_2D);
-
-    glClearColor(0, 0, 0, 0);
-    glClear(GL_COLOR_BUFFER_BIT);
-}
+    return ctx;
+#else
+    return NULL;
 #endif
+}
 
 //////////////////////////////////////////////////////////////////////////////
 
+static const char gCharEvtName[] = "SampleCode_Char_Event";
+static const char gKeyEvtName[] = "SampleCode_Key_Event";
 static const char gTitleEvtName[] = "SampleCode_Title_Event";
 static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
+static const char gFastTextEvtName[] = "SampleCode_FastText_Event";
+
+bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
+    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
+        if (outUni) {
+            *outUni = evt.getFast32();
+        }
+        return true;
+    }
+    return false;
+}
+
+bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
+    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
+        if (outKey) {
+            *outKey = (SkKey)evt.getFast32();
+        }
+        return true;
+    }
+    return false;
+}
 
 bool SampleCode::TitleQ(const SkEvent& evt) {
     return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
@@ -122,20 +133,40 @@
     evt->setScalars(gPrefSizeEvtName, 2, size);
 }
 
+bool SampleCode::FastTextQ(const SkEvent& evt) {
+    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 static SkMSec gAnimTime;
+static SkMSec gAnimTimePrev;
+
 SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
+SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
+SkScalar SampleCode::GetAnimSecondsDelta() {
+    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
+}
 
 SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
-    SkScalar seconds = SkFloatToScalar(gAnimTime / 1000.0f);
-    SkScalar value = SkScalarMul(speed, seconds);
+    // since gAnimTime can be up to 32 bits, we can't convert it to a float
+    // or we'll lose the low bits. Hence we use doubles for the intermediate
+    // calculations
+    double seconds = (double)gAnimTime / 1000.0;
+    double value = SkScalarToDouble(speed) * seconds;
     if (period) {
-        value = SkScalarMod(value, period);
+        value = ::fmod(value, SkScalarToDouble(period));
     }
-    return value;
+    return SkDoubleToScalar(value);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
+static SkView* curr_view(SkWindow* wind) {
+    SkView::F2BIter iter(wind);
+    return iter.next();
+}
+
 class SampleWindow : public SkOSWindow {
     SkTDArray<SkViewFactory> fSamples;
 public:
@@ -156,6 +187,7 @@
     virtual void afterChild(SkView* child, SkCanvas* canvas);
     
 	virtual bool onEvent(const SkEvent& evt);
+    virtual bool onQuery(SkEvent* evt);
 
 #if 0
 	virtual bool handleChar(SkUnichar uni);
@@ -171,13 +203,13 @@
     int fCurrIndex;
     
     SkPicture* fPicture;
-    SkGLCanvas* fGLCanvas;
+    SkGpuCanvas* fGpuCanvas;
     SkPath fClipPath;
     
     enum CanvasType {
         kRaster_CanvasType,
         kPicture_CanvasType,
-        kOpenGL_CanvasType
+        kGPU_CanvasType
     };
     CanvasType fCanvasType;
 
@@ -187,6 +219,7 @@
     bool fAnimating;
     bool fRotate;
     bool fScale;
+    bool fRequestGrabImage;
     
     int fScrollTestX, fScrollTestY;
     
@@ -210,33 +243,35 @@
 SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
     static const CanvasType gCT[] = {
         kPicture_CanvasType,
-        kOpenGL_CanvasType,
+        kGPU_CanvasType,
         kRaster_CanvasType
     };
     return gCT[ct];
 }
 
 SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
-#ifdef SK_SUPPORT_GL
-    init_gl((WindowRef)hwnd);
-#endif
-
     fPicture = NULL;
-    fGLCanvas = NULL;
+    fGpuCanvas = NULL;
 
+#ifdef DEFAULT_TO_GPU
+    fCanvasType = kGPU_CanvasType;
+#else
     fCanvasType = kRaster_CanvasType;
+#endif
     fUseClip = false;
     fNClip = false;
     fRepeatDrawing = false;
     fAnimating = false;
     fRotate = false;
     fScale = false;
+    fRequestGrabImage = false;
 
     fScrollTestX = fScrollTestY = 0;
 
 //	this->setConfig(SkBitmap::kRGB_565_Config);
 	this->setConfig(SkBitmap::kARGB_8888_Config);
 	this->setVisibleP(true);
+    this->setClipToBounds(false);
 
     {
         const SkViewRegister* reg = SkViewRegister::Head();
@@ -251,7 +286,7 @@
 
 SampleWindow::~SampleWindow() {
     delete fPicture;
-    delete fGLCanvas;
+    delete fGpuCanvas;
 }
 
 static SkBitmap capture_bitmap(SkCanvas* canvas) {
@@ -284,6 +319,7 @@
 
 void SampleWindow::draw(SkCanvas* canvas) {
     // update the animation time
+    gAnimTimePrev = gAnimTime;
     gAnimTime = SkTime::GetMSecs();
 
     if (fNClip) {
@@ -346,11 +382,17 @@
 }
 
 SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
+    SkIPoint viewport;
+    bool alreadyGPU = canvas->getViewport(&viewport);
+    
+    if (kGPU_CanvasType != fCanvasType) {
 #ifdef SK_SUPPORT_GL
-#ifndef USE_OFFSCREEN
-    aglSetWindowRef(gAGLContext, NULL);
-#endif
-#endif
+        detachGL();
+#elif defined(SK_SUPPORT_D3D9)
+        detachD3D9();
+#endif   
+    }
+    
     switch (fCanvasType) {
         case kRaster_CanvasType:
             canvas = this->INHERITED::beforeChildren(canvas);
@@ -359,20 +401,35 @@
             fPicture = new SkPicture;
             canvas = fPicture->beginRecording(9999, 9999);
             break;
-#ifdef SK_SUPPORT_GL
-        case kOpenGL_CanvasType: {
-            //SkGLCanvas::DeleteAllTextures();  // just for testing
-            SkDevice* device = canvas->getDevice();
-            const SkBitmap& bitmap = device->accessBitmap(true);
-            // first clear the raster bitmap, so we don't see any leftover bits
-            bitmap.eraseColor(0);
-            // now setup our glcanvas
-            setup_offscreen_gl(bitmap, (WindowRef)this->getHWND());
-            fGLCanvas = new SkGLCanvas;
-            fGLCanvas->setViewport(bitmap.width(), bitmap.height());
-            canvas = fGLCanvas;
+#ifdef SUPPORT_GPU
+        case kGPU_CanvasType:
+            if (!alreadyGPU) {
+                SkDevice* device = canvas->getDevice();
+                const SkBitmap& bitmap = device->accessBitmap(true);            
+#ifdef SK_SUPPORT_GL                
+    #ifdef USE_OFFSCREEN
+                // first clear the raster bitmap, so we don't see any leftover bits
+                bitmap.eraseColor(0);
+                // now setup our glcanvas
+                attachGL(&bitmap);
+    #else
+                attachGL(NULL);
+    #endif
+                glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+#elif defined(SK_SUPPORT_D3D9)
+                // now setup our canvas
+                attachD3D9();           
+#endif
+                SkBitmap viewport;
+                viewport.setConfig(SkBitmap::kARGB_8888_Config, bitmap.width(), bitmap.height());
+                fGpuCanvas = new SkGpuCanvas(get_global_grctx(this));
+                fGpuCanvas->setBitmapDevice(viewport);
+                canvas = fGpuCanvas;
+                
+            } else {
+                canvas = this->INHERITED::beforeChildren(canvas);
+            }
             break;
-        }
 #endif
     }
 
@@ -395,6 +452,22 @@
 }
 
 void SampleWindow::afterChildren(SkCanvas* orig) {
+    if (fRequestGrabImage) {
+        fRequestGrabImage = false;
+        
+        SkCanvas* canvas = fGpuCanvas ? fGpuCanvas : orig;
+        SkDevice* device = canvas->getDevice();
+        SkBitmap bitmap;
+        SkIRect bounds = { 0, 0, this->width(), this->height() };
+        if (device->readPixels(bounds, &bitmap)) {
+            static int gSampleGrabCounter;
+            SkString name;
+            name.printf("sample_grab_%d", gSampleGrabCounter++);
+            SkImageEncoder::EncodeFile(name.c_str(), bitmap,
+                                       SkImageEncoder::kPNG_Type, 100);
+        }
+    }
+
     switch (fCanvasType) {
         case kRaster_CanvasType:
             break;
@@ -419,19 +492,27 @@
             fPicture = NULL;
             break;
 #ifdef SK_SUPPORT_GL
-        case kOpenGL_CanvasType:
-            glFlush();
-            delete fGLCanvas;
-            fGLCanvas = NULL;
+        case kGPU_CanvasType:
+            delete fGpuCanvas;
+            fGpuCanvas = NULL;
+            presentGL();
 #ifdef USE_OFFSCREEN
             reverseRedAndBlue(orig->getDevice()->accessBitmap(true));
 #endif
             break;
+#elif defined(SK_SUPPORT_D3D9)
+        case kGPU_CanvasType: {
+            delete fGpuCanvas;
+            fGpuCanvas = NULL;
+            presentD3D9();
+            break;
+        }
 #endif
+
     }
     
 //    if ((fScrollTestX | fScrollTestY) != 0)
-    {
+    if (false) {
         const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
         int dx = fScrollTestX * 7;
         int dy = fScrollTestY * 7;
@@ -501,6 +582,27 @@
     return this->INHERITED::onEvent(evt);
 }
 
+bool SampleWindow::onQuery(SkEvent* query) {
+    if (query->isType("get-slide-count")) {
+        query->setFast32(fSamples.count());
+        return true;
+    }
+    if (query->isType("get-slide-title")) {
+        SkView* view = fSamples[query->getFast32()]();
+        SkEvent evt(gTitleEvtName);
+        if (view->doQuery(&evt)) {
+            query->setString("title", evt.findString(gTitleEvtName));
+        }
+        SkSafeUnref(view);
+        return true;
+    }
+    if (query->isType("use-fast-text")) {
+        SkEvent evt(gFastTextEvtName);
+        return curr_view(this)->doQuery(&evt);
+    }
+    return this->INHERITED::onQuery(query);
+}
+
 static void cleanup_for_filename(SkString* name) {
     char* str = name->writable_str();
     for (size_t i = 0; i < name->size(); i++) {
@@ -514,6 +616,17 @@
 }
 
 bool SampleWindow::onHandleChar(SkUnichar uni) {
+    {
+        SkView* view = curr_view(this);
+        if (view) {
+            SkEvent evt(gCharEvtName);
+            evt.setFast32(uni);
+            if (view->doQuery(&evt)) {
+                return true;
+            }
+        }
+    }
+    
     int dx = 0xFF;
     int dy = 0xFF;
 
@@ -573,6 +686,13 @@
             this->inval(NULL);
             this->updateTitle();
             return true;
+        case 'd':
+            SkGraphics::SetFontCacheUsed(0);
+            return true;
+        case 'g':
+            fRequestGrabImage = true;
+            this->inval(NULL);
+            break;
         default:
             break;
     }
@@ -583,6 +703,17 @@
 #include "SkDumpCanvas.h"
 
 bool SampleWindow::onHandleKey(SkKey key) {
+    {
+        SkView* view = curr_view(this);
+        if (view) {
+            SkEvent evt(gKeyEvtName);
+            evt.setFast32(key);
+            if (view->doQuery(&evt)) {
+                return true;
+            }
+        }
+    }
+
     switch (key) {
         case kRight_SkKey:
             if (this->nextSample()) {
@@ -604,7 +735,7 @@
             this->updateTitle();
             return true;
         case kOK_SkKey:
-            if (true) {
+            if (false) {
                 SkDebugfDumper dumper;
                 SkDumpCanvas dc(&dumper);
                 this->draw(&dc);
@@ -635,6 +766,7 @@
         view = create_overview(fSamples.count(), fSamples.begin());
     }
     view->setVisibleP(true);
+    view->setClipToBounds(false);
     this->attachChildToFront(view)->unref();
     view->setSize(this->width(), this->height());
 
@@ -728,7 +860,108 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+template <typename T> void SkTBSort(T array[], int count) {
+    for (int i = 1; i < count - 1; i++) {
+        bool didSwap = false;
+        for (int j = count - 1; j > i; --j) {
+            if (array[j] < array[j-1]) {
+                T tmp(array[j-1]);
+                array[j-1] = array[j];
+                array[j] = tmp;
+                didSwap = true;
+            }
+        }
+        if (!didSwap) {
+            break;
+        }
+    }
+    
+    for (int k = 0; k < count - 1; k++) {
+        SkASSERT(!(array[k+1] < array[k]));
+    }
+}
+
+#include "SkRandom.h"
+
+static void rand_rect(SkIRect* rect, SkRandom& rand) {
+    int bits = 8;
+    int shift = 32 - bits;
+    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
+              rand.nextU() >> shift, rand.nextU() >> shift);
+    rect->sort();
+}
+
+static void dumpRect(const SkIRect& r) {
+    SkDebugf(" { %d, %d, %d, %d },\n",
+             r.fLeft, r.fTop,
+             r.fRight, r.fBottom);
+}
+
+static void test_rects(const SkIRect rect[], int count) {
+    SkRegion rgn0, rgn1;
+
+    for (int i = 0; i < count; i++) {
+        rgn0.op(rect[i], SkRegion::kUnion_Op);
+     //   dumpRect(rect[i]);
+    }
+    rgn1.setRects(rect, count);
+
+    if (rgn0 != rgn1) {
+        SkDebugf("\n");
+        for (int i = 0; i < count; i++) {
+            dumpRect(rect[i]);
+        }
+        SkDebugf("\n");
+    }
+}
+
+static void test() {
+    size_t i;
+
+    const SkIRect r0[] = {
+        { 0, 0, 1, 1 },
+        { 2, 2, 3, 3 },
+    };
+    const SkIRect r1[] = {
+        { 0, 0, 1, 3 },
+        { 1, 1, 2, 2 },
+        { 2, 0, 3, 3 },
+    };
+    const SkIRect r2[] = {
+        { 0, 0, 1, 2 },
+        { 2, 1, 3, 3 },
+        { 4, 0, 5, 1 },
+        { 6, 0, 7, 4 },
+    };
+
+    static const struct {
+        const SkIRect* fRects;
+        int            fCount;
+    } gRecs[] = {
+        { r0, SK_ARRAY_COUNT(r0) },
+        { r1, SK_ARRAY_COUNT(r1) },
+        { r2, SK_ARRAY_COUNT(r2) },
+    };
+
+    for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
+        test_rects(gRecs[i].fRects, gRecs[i].fCount);
+    }
+    
+    SkRandom rand;
+    for (i = 0; i < 10000; i++) {
+        SkRegion rgn0, rgn1;
+
+        const int N = 8;
+        SkIRect rect[N];
+        for (int j = 0; j < N; j++) {
+            rand_rect(&rect[j], rand);
+        }
+        test_rects(rect, N);
+    }
+}
+
 SkOSWindow* create_sk_window(void* hwnd) {
+//    test();
 	return new SampleWindow(hwnd);
 }
 
diff --git a/samplecode/SampleBitmapRect.cpp b/samplecode/SampleBitmapRect.cpp
index 0d981d6..0c1cd7a 100644
--- a/samplecode/SampleBitmapRect.cpp
+++ b/samplecode/SampleBitmapRect.cpp
@@ -75,12 +75,12 @@
         for (size_t i = 0; i < SK_ARRAY_COUNT(src); i++) {
             SkRect srcR;
             srcR.set(src[i]);
-            
+
             canvas->drawBitmap(fBitmap, 0, 0, &paint);
             canvas->drawBitmapRect(fBitmap, &src[i], dstR, &paint);
 
-            canvas->drawRect(srcR, paint);
             canvas->drawRect(dstR, paint);
+            canvas->drawRect(srcR, paint);
             
             canvas->translate(160, 0);
         }
diff --git a/samplecode/SampleCamera.cpp b/samplecode/SampleCamera.cpp
index 4d50b5a..c71cc43 100644
--- a/samplecode/SampleCamera.cpp
+++ b/samplecode/SampleCamera.cpp
@@ -9,22 +9,46 @@
 #include "SkShader.h"
 #include "SkUtils.h"
 #include "SkRandom.h"
+#include "SkImageDecoder.h"
 
 class CameraView : public SkView {
+    SkTDArray<SkShader*> fShaders;
+    int     fShaderIndex;
+    bool    fFrontFace;
 public:
-	CameraView()
-    {
+	CameraView() {
         fRX = fRY = fRZ = 0;
+        fShaderIndex = 0;
+        fFrontFace = false;
+
+        for (int i = 0;; i++) {
+            SkString str;
+            str.printf("/skimages/elephant%d.jpeg", i);
+            SkBitmap bm;
+            if (SkImageDecoder::DecodeFile(str.c_str(), &bm)) {
+                SkShader* s = SkShader::CreateBitmapShader(bm,
+                                                           SkShader::kClamp_TileMode,
+                                                           SkShader::kClamp_TileMode);
+                
+                SkRect src = { 0, 0, bm.width(), bm.height() };
+                SkRect dst = { -150, -150, 150, 150 };
+                SkMatrix matrix;
+                matrix.setRectToRect(src, dst, SkMatrix::kFill_ScaleToFit);
+                s->setLocalMatrix(matrix);
+                *fShaders.append() = s;
+            } else {
+                break;
+            }
+        }
     }
     
-    virtual ~CameraView()
-    {
+    virtual ~CameraView() {
+        fShaders.unrefAll();
     }
 
 protected:
     // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt)
-    {
+    virtual bool onQuery(SkEvent* evt) {
         if (SampleCode::TitleQ(*evt))
         {
             SampleCode::TitleR(evt, "Camera");
@@ -32,69 +56,54 @@
         }
         return this->INHERITED::onQuery(evt);
     }
-    
-    void drawBG(SkCanvas* canvas)
-    {
+
+    void drawBG(SkCanvas* canvas) {
         canvas->drawColor(0xFFDDDDDD);
     }
     
-    virtual void onDraw(SkCanvas* canvas)
-    {
+    virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
 
         canvas->translate(this->width()/2, this->height()/2);
 
         Sk3DView    view;
-        view.rotateX(SkIntToScalar(fRX));
-        view.rotateY(SkIntToScalar(fRY));
+        view.rotateX(fRX);
+        view.rotateY(fRY);
         view.applyToCanvas(canvas);
         
         SkPaint paint;
         SkScalar rad = SkIntToScalar(50);
         SkScalar dim = rad*2;
-
-        if (view.dotWithNormal(0, 0, SK_Scalar1) < 0) {
-            paint.setColor(SK_ColorRED);
+        if (fShaders.count() > 0) {
+            bool frontFace = view.dotWithNormal(0, 0, SK_Scalar1) < 0;
+            if (frontFace != fFrontFace) {
+                fFrontFace = frontFace;
+                fShaderIndex = (fShaderIndex + 1) % fShaders.count();
+            }
+        
+            paint.setAntiAlias(true);
+            paint.setShader(fShaders[fShaderIndex]);
+#if 0
+            canvas->drawCircle(0, 0, rad, paint);
+            canvas->drawCircle(-dim, -dim, rad, paint);
+            canvas->drawCircle(-dim,  dim, rad, paint);
+            canvas->drawCircle( dim, -dim, rad, paint);
+            canvas->drawCircle( dim,  dim, rad, paint);
+#else
+            SkRect r = { -150, -150, 150, 150 };
+            canvas->drawRoundRect(r, 30, 30, paint);
+#endif
         }
         
-        paint.setAntiAlias(true);
-
-#if 0
-        SkEmbossMaskFilter::Light light;
-        light.fDirection[0] = SK_Scalar1;
-        light.fDirection[1] = SK_Scalar1;
-        light.fDirection[2] = SK_Scalar1;
-        light.fAmbient = 180;
-        light.fSpecular = 16 * 2;
-        paint.setMaskFilter(new SkEmbossMaskFilter(light, SkIntToScalar(4)));
-#endif
-
-        canvas->drawCircle(0, 0, rad, paint);
-        canvas->drawCircle(-dim, -dim, rad, paint);
-        canvas->drawCircle(-dim,  dim, rad, paint);
-        canvas->drawCircle( dim, -dim, rad, paint);
-        canvas->drawCircle( dim,  dim, rad, paint);
-        
-        fRY += 1;
-        if (fRY >= 360)
+        fRY += SampleCode::GetAnimSecondsDelta() * 90;
+        if (fRY >= SkIntToScalar(360)) {
             fRY = 0;
+        }
         this->inval(NULL);
     }
 
-    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) 
-    {
-        SkScalar angle = SkScalarDiv(this->height()/2 - y, this->height());
-        fRX = SkScalarRound(angle * 180);
-        return this->INHERITED::onFindClickHandler(x, y);
-    }
-    
-    virtual bool onClick(Click* click) 
-    {
-        return this->INHERITED::onClick(click);
-    }
-    
 private:
-    int fRX, fRY, fRZ;
+    SkScalar fRX, fRY, fRZ;
     typedef SkView INHERITED;
 };
 
diff --git a/samplecode/SampleCircle.cpp b/samplecode/SampleCircle.cpp
index b250f29..8f0436b 100644
--- a/samplecode/SampleCircle.cpp
+++ b/samplecode/SampleCircle.cpp
@@ -19,9 +19,9 @@
 
 class CircleView : public SkView {
 public:
-    static const SkScalar ANIM_DX = SK_Scalar1 / 67;
-    static const SkScalar ANIM_DY = SK_Scalar1 / 29;
-    static const SkScalar ANIM_RAD = SK_Scalar1 / 19;
+    static const SkScalar ANIM_DX;
+    static const SkScalar ANIM_DY;
+    static const SkScalar ANIM_RAD;
     SkScalar fDX, fDY, fRAD;
 
     CircleView() {
@@ -97,7 +97,7 @@
 
     virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
-        
+
         SkPaint paint;
         paint.setAntiAlias(true);
         paint.setStyle(SkPaint::kStroke_Style);
@@ -127,16 +127,16 @@
             canvas->translate(dx, 0);
             canvas->translate(SK_ScalarHalf, SK_ScalarHalf);
             drawSix(canvas, dx, dy);
-        }
         
-        fDX += ANIM_DX;
-        fDY += ANIM_DY;
-        fRAD += ANIM_RAD;
-        fN += 1;
-        if (fN > 40) {
-            fN = 3;
+            fDX += ANIM_DX;
+            fDY += ANIM_DY;
+            fRAD += ANIM_RAD;
+            fN += 1;
+            if (fN > 40) {
+                fN = 3;
+            }
+            this->inval(NULL);
         }
-        this->inval(NULL);
     }
     
 private:
@@ -144,9 +144,9 @@
     typedef SkView INHERITED;
 };
 
-const SkScalar CircleView::ANIM_DX;
-const SkScalar CircleView::ANIM_DY;
-const SkScalar CircleView::ANIM_RAD;
+const SkScalar CircleView::ANIM_DX(SK_Scalar1 / 67);
+const SkScalar CircleView::ANIM_DY(SK_Scalar1 / 29);
+const SkScalar CircleView::ANIM_RAD(SK_Scalar1 / 19);
 
 //////////////////////////////////////////////////////////////////////////////
 
diff --git a/samplecode/SampleCode.h b/samplecode/SampleCode.h
index c901af3..058985a 100644
--- a/samplecode/SampleCode.h
+++ b/samplecode/SampleCode.h
@@ -2,16 +2,24 @@
 #define SampleCode_DEFINED
 
 #include "SkEvent.h"
+#include "SkKey.h"
 
 class SampleCode {
 public:
+    static bool KeyQ(const SkEvent&, SkKey* outKey);
+    static bool CharQ(const SkEvent&, SkUnichar* outUni);
+
     static bool TitleQ(const SkEvent&);
     static void TitleR(SkEvent*, const char title[]);
     
     static bool PrefSizeQ(const SkEvent&);
     static void PrefSizeR(SkEvent*, SkScalar width, SkScalar height);
-    
+
+    static bool FastTextQ(const SkEvent&);
+
     static SkMSec GetAnimTime();
+    static SkMSec GetAnimTimeDelta();
+    static SkScalar GetAnimSecondsDelta();
     static SkScalar GetAnimScalar(SkScalar speedPerSec, SkScalar period = 0);
 };
 
diff --git a/samplecode/SampleDrawLooper.cpp b/samplecode/SampleDrawLooper.cpp
index 1a7a870..7ea7b75 100644
--- a/samplecode/SampleDrawLooper.cpp
+++ b/samplecode/SampleDrawLooper.cpp
@@ -6,8 +6,6 @@
 #include "SkLayerDrawLooper.h"
 #include "SkBlurMaskFilter.h"
 
-#include <pthread.h>
-
 #define WIDTH   200
 #define HEIGHT  200
 
diff --git a/samplecode/SampleGM.cpp b/samplecode/SampleGM.cpp
index 095dfe6..d85cad1 100644
--- a/samplecode/SampleGM.cpp
+++ b/samplecode/SampleGM.cpp
@@ -6,13 +6,6 @@
 
 using namespace skiagm;
 
-GM::GM() {}
-GM::~GM() {}
-
-void GM::draw(SkCanvas* canvas) {
-	this->onDraw(canvas);
-}
-
 // need to explicitly declare this, or we get some weird infinite loop llist
 template GMRegistry* GMRegistry::gHead;
 
@@ -82,3 +75,15 @@
 static SkView* MyFactory() { return new GMView; }
 static SkViewRegister reg(MyFactory);
 
+///////////////////////////////////////////////////////////////////////////////
+
+using namespace skiagm;
+
+GM::GM() {}
+GM::~GM() {}
+
+void GM::draw(SkCanvas* canvas) {
+	this->onDraw(canvas);
+}
+
+
diff --git a/samplecode/SampleGradients.cpp b/samplecode/SampleGradients.cpp
index f3705bc..8c65fe0 100644
--- a/samplecode/SampleGradients.cpp
+++ b/samplecode/SampleGradients.cpp
@@ -130,7 +130,6 @@
         SkShader::TileMode tm = SkShader::kClamp_TileMode;
         SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
         SkPaint paint;
-        paint.setAntiAlias(true);
         paint.setDither(true);
 
         canvas->save();
@@ -138,10 +137,10 @@
         for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) {
             canvas->save();
             for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) {
-                SkShader* shader = gGradMakers[j](pts, gGradData[i], tm, NULL);
-                paint.setShader(shader);
+                SkShader* shader;
+                shader = gGradMakers[j](pts, gGradData[i], tm, NULL);
+                paint.setShader(shader)->unref();
                 canvas->drawRect(r, paint);
-                shader->unref();
                 canvas->translate(0, SkIntToScalar(120));
             }
             canvas->restore();
@@ -151,6 +150,7 @@
         
         canvas->translate(0, SkIntToScalar(370));
      //   test_alphagradients(canvas);
+        this->inval(NULL);
     }
     
 private:
diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp
index ae8bd33..f1e8dd8 100644
--- a/samplecode/SampleLayers.cpp
+++ b/samplecode/SampleLayers.cpp
@@ -161,7 +161,7 @@
             SkPaint p;
             canvas->saveLayer(&r, &p);
             canvas->drawColor(0xFFFF0000);
-            p.setAlpha(1);  // or 0
+            p.setAlpha(0);  // or 0
             p.setXfermodeMode(SkXfermode::kSrc_Mode);
             canvas->drawOval(r, p);
             canvas->restore();
diff --git a/samplecode/SampleLines.cpp b/samplecode/SampleLines.cpp
index a0238b0..4d05a9a 100644
--- a/samplecode/SampleLines.cpp
+++ b/samplecode/SampleLines.cpp
@@ -82,11 +82,11 @@
         r.set(x, y, x + SkIntToScalar(100), y + SkIntToScalar(100));
         
         SkPaint paint;
-        paint.setAntiAlias(true);
+     //   paint.setAntiAlias(true);
         paint.setStyle(SkPaint::kStroke_Style);
         paint.setStrokeWidth(SkScalarHalf(SkIntToScalar(3)));
         paint.setColor(0xFFFF8800);
-        paint.setColor(0xFFFFFFFF);
+     //   paint.setColor(0xFFFFFFFF);
         canvas->drawRect(r, paint);
     }
     
diff --git a/samplecode/SampleMipMap.cpp b/samplecode/SampleMipMap.cpp
index 07227e5..6e0efe0 100644
--- a/samplecode/SampleMipMap.cpp
+++ b/samplecode/SampleMipMap.cpp
@@ -31,7 +31,7 @@
 class MipMapView : public SkView {
     SkBitmap fBitmap;
     enum {
-        N = 90
+        N = 64
     };
 public:
     MipMapView() {
@@ -44,7 +44,7 @@
     // overrides from SkEventSink
     virtual bool onQuery(SkEvent* evt) {
         if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "MapMaps");
+            SampleCode::TitleR(evt, "MipMaps");
             return true;
         }
         return this->INHERITED::onQuery(evt);
diff --git a/samplecode/SamplePatch.cpp b/samplecode/SamplePatch.cpp
index 3f898bc..fb70dba 100644
--- a/samplecode/SamplePatch.cpp
+++ b/samplecode/SamplePatch.cpp
@@ -35,7 +35,7 @@
     SkBitmap    bm;
     
 //    SkImageDecoder::DecodeFile("/skimages/progressivejpg.jpg", &bm);
-    SkImageDecoder::DecodeFile("/skimages/beach.jpg", &bm);
+    SkImageDecoder::DecodeFile("/skimages/logo.png", &bm);
     size->set(bm.width(), bm.height());
     return SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode,
                                         SkShader::kClamp_TileMode);
@@ -279,77 +279,6 @@
         SkPaint paint;
         paint.setDither(true);
         paint.setFilterBitmap(true);
-
-        if (false) {
-            SkPath p;
-            p.moveTo(0, 0);
-            p.lineTo(SkIntToScalar(30000), SkIntToScalar(30000));
-            paint.setStyle(SkPaint::kStroke_Style);
-            paint.setStrokeWidth(SkIntToScalar(4));
-            paint.setAntiAlias(true);
-            canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
-            canvas->drawPath(p, paint);
-            return;
-        }
-        
-        if (false) {
-            for (int dy = -1; dy <= 2; dy++) {
-                canvas->save();
-                if (dy == 2) {
-                    canvas->translate(0, SK_Scalar1/2);
-                } else {
-                    canvas->translate(0, SkIntToScalar(dy)/100);
-                }
-            
-                SkBitmap bm;
-                bm.setConfig(SkBitmap::kARGB_8888_Config, 20, 20);
-                bm.allocPixels();
-                SkCanvas c(bm);
-                SkRect r = { 0, 0, 20*SK_Scalar1, SK_Scalar1 };
-                for (int y = 0; y < 20; y++) {
-                    SkPaint p;
-                    p.setARGB(0xFF, y*5&0xFF, y*13&0xFF, y*29&0xFF);
-                    c.drawRect(r, p);
-                    r.offset(0, SK_Scalar1);
-                }
-                SkIRect src;
-                SkRect  dst;
-                
-                static const int srcPts[] = {
-                 //   2, 0, 15, 2,
-                    2, 2, 15, 16,
-                    17, 2, 2, 16,
-                    19, 2, 1, 16,
-                //    2, 18, 15, 2
-                };
-                static const double dstPts[] = {
-                //    7, 262 15, 24.5,
-                    7, 286.5, 15, 16,
-                    22, 286.5, 5, 16,
-                    27, 286.5, 1, 16,
-                 //   7, 302.5, 15, 24.5
-                };
-                
-                SkPaint p;
-//                p.setFilterBitmap(true);
-                const int* s = srcPts;
-                const double* d = dstPts;
-                for (int i = 0; i < 3; i++) {
-                    src.set(s[0], s[1], s[0]+s[2], s[1]+s[3]);
-                    dst.set(SkDoubleToScalar(d[0]),
-                            SkDoubleToScalar(d[1]),
-                            SkDoubleToScalar(d[0]+d[2]),
-                            SkDoubleToScalar(d[1]+d[3]));
-                    canvas->drawBitmapRect(bm, &src, dst, &p);
-                    canvas->translate(SkDoubleToScalar(1), 0);
-                    s += 4;
-                    d += 4;
-                }
-                canvas->restore();
-                canvas->translate(SkIntToScalar(32), 0);
-            }
-            return;
-        }
         
         canvas->translate(SkIntToScalar(20), 0);
 
@@ -370,8 +299,7 @@
         paint.setShader(NULL);
         paint.setAntiAlias(true);
         paint.setStrokeWidth(SkIntToScalar(5));
-        canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(fPts),
-                           fPts, paint);
+        canvas->drawPoints(SkCanvas::kPoints_PointMode, SK_ARRAY_COUNT(fPts), fPts, paint);
         
         canvas->translate(0, SkIntToScalar(300));
         
diff --git a/samplecode/SamplePath.cpp b/samplecode/SamplePath.cpp
index 1eb4222..2c8e8c2 100644
--- a/samplecode/SamplePath.cpp
+++ b/samplecode/SamplePath.cpp
@@ -1,3 +1,4 @@
+
 #include "SampleCode.h"
 #include "SkView.h"
 #include "SkCanvas.h"
@@ -44,7 +45,12 @@
     SkParsePath::FromSVGString(str, &path);
     
     {
+#ifdef SK_BUILD_FOR_WIN
+        // windows doesn't have strtof
+        float x = (float)strtod("9.94099e+07", NULL);
+#else
         float x = strtof("9.94099e+07", NULL);
+#endif
         int ix = (int)x;
         int fx = (int)(x * 65536);
         int ffx = SkScalarToFixed(x);
diff --git a/samplecode/SamplePathEffects.cpp b/samplecode/SamplePathEffects.cpp
index 42f50a3..1ba775f 100644
--- a/samplecode/SamplePathEffects.cpp
+++ b/samplecode/SamplePathEffects.cpp
@@ -13,15 +13,6 @@
 #include "SkColorPriv.h"
 #include "SkPixelXorXfermode.h"
 
-static void test_grow(SkPath* path)
-{
-    for (int i = 0; i < 100000; i++)
-    {
-        path->lineTo(i, i);
-        path->lineTo(i, i*2);
-    }
-}
-
 #define CORNER_RADIUS   12
 static SkScalar gPhase;
 
@@ -29,8 +20,7 @@
     4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4
 };
 
-static SkPathEffect* make_pe(int flags)
-{
+static SkPathEffect* make_pe(int flags) {
     if (flags == 1)
         return new SkCornerPathEffect(SkIntToScalar(CORNER_RADIUS));
 
@@ -54,8 +44,7 @@
     return pe;
 }
 
-static SkPathEffect* make_warp_pe()
-{
+static SkPathEffect* make_warp_pe() {
     SkPath  path;
     path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
     for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
@@ -79,8 +68,7 @@
 
 class testrast : public SkLayerRasterizer {
 public:
-    testrast()
-    {
+    testrast() {
         SkPaint paint;
         paint.setAntiAlias(true);
 
@@ -106,8 +94,7 @@
     SkPath  fPath;
     SkPoint fClickPt;
 public:
-	PathEffectView()
-    {
+	PathEffectView() {
         SkRandom    rand;
         int         steps = 20;
         SkScalar    dist = SkIntToScalar(400);
@@ -115,8 +102,7 @@
         SkScalar    y = SkIntToScalar(50);
         
         fPath.moveTo(x, y);
-        for (int i = 0; i < steps; i++)
-        {
+        for (int i = 0; i < steps; i++) {
             x += dist/steps;
             SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
             if (i == steps/2) {
@@ -139,39 +125,22 @@
 	
 protected:
     // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt)
-    {
-            if (SampleCode::TitleQ(*evt))
-            {
-                SampleCode::TitleR(evt, "PathEffects");
-                return true;
-            }
-            return this->INHERITED::onQuery(evt);
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SampleCode::TitleR(evt, "PathEffects");
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
     }
     
-    void drawBG(SkCanvas* canvas)
-    {
+    void drawBG(SkCanvas* canvas) {
         canvas->drawColor(0xFFDDDDDD);
-
-#if 0
-        SkPath path;
-        test_grow(&path);
-        SkPaint p;
-        
-        p.setAntiAlias(true);
-        p.setStyle(SkPaint::kStroke_Style);
-        p.setStrokeWidth(SK_Scalar1);
-        canvas->drawPath(path, p);
-        path.close();
-#endif
     }
     
-    virtual void onDraw(SkCanvas* canvas)
-    {
+    virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
         
-        if (true)
-        {
+        if (false) {
             canvas->drawColor(SK_ColorWHITE);
             
             SkPixelXorXfermode  mode(SK_ColorWHITE);
@@ -188,11 +157,12 @@
          //   return;
         }
         
-        gPhase -= SK_Scalar1;
+        gPhase -= SampleCode::GetAnimSecondsDelta() * 40;
         this->inval(NULL);
         
         SkPaint paint;
         
+#if 0
         paint.setAntiAlias(true);
         paint.setStyle(SkPaint::kStroke_Style);
         paint.setStrokeWidth(SkIntToScalar(5));
@@ -202,6 +172,7 @@
         paint.setColor(SK_ColorWHITE);
         paint.setPathEffect(make_pe(1))->unref();
         canvas->drawPath(fPath, paint);
+#endif
         
         canvas->translate(0, SkIntToScalar(50));
         
@@ -221,40 +192,6 @@
         paint.setPathEffect(make_warp_pe())->unref();
         paint.setRasterizer(new testrast)->unref();
         canvas->drawPath(fPath, paint);
-        
-        {
-            SkRect  oval;
-            
-            oval.set(SkIntToScalar(50), SkIntToScalar(100),
-                     SkIntToScalar(150), SkIntToScalar(150));
-            canvas->drawRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8), paint);
-        }
-        
-        {
-            SkRect  bounds;
-            SkPaint paint;
-            
-            paint.setAntiAlias(true);
-            paint.setAlpha(0x80);
-            paint.setColorFilter(
-                SkColorFilter::CreateModeFilter(
-                    SkColorSetARGB(0x44, 0, 0xFF, 0), SkXfermode::kSrcATop_Mode))->unref();
-            
-            bounds.set(SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(150), SkIntToScalar(70));
-            canvas->saveLayer(&bounds, &paint,
-                              (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
-            
-            paint.setColorFilter(NULL);
-            paint.setColor(SK_ColorRED);
-            canvas->drawOval(bounds, paint);
-
-            paint.setColor(SK_ColorBLUE);
-            paint.setAlpha(0x80);
-            bounds.inset(SkIntToScalar(10), SkIntToScalar(10));
-            canvas->drawOval(bounds, paint);
-            
-            canvas->restore();
-        }
     }
     
 private:
diff --git a/samplecode/SamplePoints.cpp b/samplecode/SamplePoints.cpp
index 57e45c9..db2e6b7 100644
--- a/samplecode/SamplePoints.cpp
+++ b/samplecode/SamplePoints.cpp
@@ -85,7 +85,7 @@
         p3.setColor(SK_ColorWHITE);
         
      //   fAA = !fAA;
-        fAA = true;
+        fAA = false;
         p0.setAntiAlias(fAA);
         p1.setAntiAlias(fAA);
         p2.setAntiAlias(fAA);
diff --git a/samplecode/SampleRegion.cpp b/samplecode/SampleRegion.cpp
index 6259000..8777050 100644
--- a/samplecode/SampleRegion.cpp
+++ b/samplecode/SampleRegion.cpp
@@ -8,6 +8,11 @@
 #include "SkUtils.h"
 #include "SkImageDecoder.h"
 
+#ifdef SK_BUILD_FOR_WIN
+// windows doesn't have roundf
+inline float roundf(float x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); }
+#endif
+
 #ifdef SK_DEBUG
 static void make_rgn(SkRegion* rgn, int left, int top, int right, int bottom,
                      size_t count, int32_t runs[]) {
@@ -232,13 +237,7 @@
         canvas->drawPaint(paint);
     }
 
-    virtual void onDraw(SkCanvas* canvas)
-    {
-        if (true) {
-            SkRect r = { 0, 0, 1 << 30, 1 << 30 };
-            bool open = canvas->clipRect(r);
-            SkDebugf("---- giant clip is %d\n", open);
-        }
+    virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
         
         if (false) {
diff --git a/samplecode/SampleShapes.cpp b/samplecode/SampleShapes.cpp
index b92614b..30ff3fd 100644
--- a/samplecode/SampleShapes.cpp
+++ b/samplecode/SampleShapes.cpp
@@ -5,6 +5,8 @@
 #include "SkStream.h"
 #include "SkView.h"
 
+#define DO_AA   false
+
 #include "SkRectShape.h"
 #include "SkGroupShape.h"
 
@@ -21,6 +23,7 @@
     if (red) {
         s->paint().setColor(SK_ColorRED);
     }
+    s->paint().setAntiAlias(DO_AA);
     return s;
 }
 
@@ -28,6 +31,7 @@
     SkRectShape* s = new SkRectShape;
     s->setOval(make_rect(10, 10, 90, 90));
     s->paint().setColor(SK_ColorBLUE);
+    s->paint().setAntiAlias(DO_AA);
     return s;
 }
 
@@ -36,6 +40,7 @@
     s->setRRect(make_rect(10, 10, 90, 90),
                 SkIntToScalar(20), SkIntToScalar(20));
     s->paint().setColor(SK_ColorGREEN);
+    s->paint().setAntiAlias(DO_AA);
     return s;
 }
 
@@ -83,7 +88,7 @@
     }
     
     void drawpicture(SkCanvas* canvas, SkPicture& pict) {
-#if 1
+#if 0
         SkDynamicMemoryWStream ostream;
         pict.serialize(&ostream);
 
@@ -99,13 +104,21 @@
     virtual void onDraw(SkCanvas* canvas) {
         this->drawBG(canvas);
         
-        SkScalar angle = SampleCode::GetAnimScalar(SkIntToScalar(360)/2,
+        SkScalar angle = SampleCode::GetAnimScalar(SkIntToScalar(180),
                                                    SkIntToScalar(360));
 
         SkMatrix saveM = *fMatrixRefs[3];
         SkScalar c = SkIntToScalar(50);
         fMatrixRefs[3]->preRotate(angle, c, c);
         
+        const SkScalar dx = 350;
+        const SkScalar dy = 500;
+        const int N = 1;
+        for (int v = -N; v <= N; v++) {
+            for (int h = -N; h <= N; h++) {
+                SkAutoCanvasRestore acr(canvas, true);
+                canvas->translate(h * dx, v * dy);
+        
         SkMatrix matrix;
      
         SkGroupShape* gs = new SkGroupShape;
@@ -121,18 +134,21 @@
 #if 0
         canvas->drawShape(gs);
 #else
-        SkPicture pict;
-        SkCanvas* cv = pict.beginRecording(1000, 1000);
+        SkPicture* pict = new SkPicture;
+        SkCanvas* cv = pict->beginRecording(1000, 1000);
         cv->scale(SK_ScalarHalf, SK_ScalarHalf);
         cv->drawShape(gs);
         cv->translate(SkIntToScalar(680), SkIntToScalar(480));
         cv->scale(-SK_Scalar1, SK_Scalar1);
         cv->drawShape(gs);
-        pict.endRecording();
+        pict->endRecording();
         
-        drawpicture(canvas, pict);
+        drawpicture(canvas, *pict);
+        pict->unref();
 #endif
 
+        }}
+
         *fMatrixRefs[3] = saveM;
         this->inval(NULL);
 }
diff --git a/samplecode/SampleSlides.cpp b/samplecode/SampleSlides.cpp
index 2029967..f57cb5a 100644
--- a/samplecode/SampleSlides.cpp
+++ b/samplecode/SampleSlides.cpp
@@ -330,7 +330,8 @@
                                           SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode, NULL);
 }
 
-struct Rec {
+class Rec {
+public:
     SkCanvas::VertexMode    fMode;
     int                     fCount;
     SkPoint*                fVerts;
@@ -426,13 +427,14 @@
     
     SkShader* fShader0 = make_shader0(&size);
     SkShader* fShader1 = make_shader1(size);
-    
+
+    SkAutoUnref aur0(fShader0);
+    SkAutoUnref aur1(fShader1);
+
     make_strip(&fRecs[0], size.fX, size.fY);
     make_fan(&fRecs[1], size.fX, size.fY);
     make_tris(&fRecs[2]);
 
-
-
     SkPaint paint;
     paint.setDither(true);
     paint.setFilterBitmap(true);
diff --git a/samplecode/SampleTestGL.cpp b/samplecode/SampleTestGL.cpp
index c5938ba..a0dfea3 100644
--- a/samplecode/SampleTestGL.cpp
+++ b/samplecode/SampleTestGL.cpp
@@ -50,7 +50,7 @@
     "    float u = uv.x;"
     "    float v = uv.y;"
     "    if (u*u > v) {"
-"    gl_FragColor = vec4(1.0, 0, 0, 1.0);"
+"    gl_FragColor = vec4(0.0, 0, 0, 0.0);"
     "    } else {"
     "    gl_FragColor = vec4(0, 1.0, 0, 1.0);"
     "}"
diff --git a/samplecode/SampleText.cpp b/samplecode/SampleText.cpp
index 14b3d80..abd88be 100644
--- a/samplecode/SampleText.cpp
+++ b/samplecode/SampleText.cpp
@@ -225,7 +225,7 @@
 #ifdef SK_DEBUG
     #define REPEAT_COUNT    1
 #else
-    #define REPEAT_COUNT    5000
+    #define REPEAT_COUNT    5
 #endif
 
 static int count_char_points(const SkPaint& paint, char c)
diff --git a/samplecode/SampleTextOnPath.cpp b/samplecode/SampleTextOnPath.cpp
index aec8fd6..6657d5e 100644
--- a/samplecode/SampleTextOnPath.cpp
+++ b/samplecode/SampleTextOnPath.cpp
@@ -16,7 +16,7 @@
 #include "SkTypeface.h"
 #include "SkAvoidXfermode.h"
 
-#define REPEAT_COUNT    1
+#define REPEAT_COUNT    0
 
 static const char gText[] = "Hamburgefons";
 
@@ -48,13 +48,13 @@
     for (int i = 0; i < 100; i++) {
         rand_text(text, rand, 256);
         paint.getTextWidths(text, count, widths, NULL);
-        SkScalar tw0 = sum_widths(widths, count);
+        SkDEBUGCODE(SkScalar tw0 = sum_widths(widths, count);)
         paint.getTextWidths(text, count, widths, rects);
-        SkScalar tw1 = sum_widths(widths, count);
+        SkDEBUGCODE(SkScalar tw1 = sum_widths(widths, count);)
         SkASSERT(tw0 == tw1);
 
-        SkScalar w0 = paint.measureText(text, count, NULL);
-        SkScalar w1 = paint.measureText(text, count, &bounds);
+        SkDEBUGCODE(SkScalar w0 = paint.measureText(text, count, NULL);)
+        SkDEBUGCODE(SkScalar w1 = paint.measureText(text, count, &bounds);)
         SkASSERT(w0 == w1);
         SkASSERT(w0 == tw0);
         
@@ -175,12 +175,12 @@
     paint.setAntiAlias(true);
     
     paint.setStyle(SkPaint::kStroke_Style);
-    canvas->drawPath(path, paint);
+ //   canvas->drawPath(path, paint);
     paint.setStyle(SkPaint::kFill_Style);
     paint.setTextSize(SkIntToScalar(48));
     paint.setTextAlign(SkPaint::kRight_Align);
     
-    const char* text = "Android";
+    const char* text = "Reflection";
     size_t      len = strlen(text);
     SkScalar    pathLen = getpathlen(path);
 
@@ -211,7 +211,8 @@
         r.set(SkIntToScalar(100), SkIntToScalar(100),
               SkIntToScalar(300), SkIntToScalar(300));
         fPath.addOval(r);
-        
+        fPath.offset(SkIntToScalar(200), 0);
+
         fHOffset = SkIntToScalar(50);
     }
 
@@ -278,12 +279,10 @@
         
         paint.setColor(SK_ColorGREEN);
         paint.setStyle(SkPaint::kStroke_Style);
-        canvas->drawPath(fPath, paint);
+//        canvas->drawPath(fPath, paint);
         
-        canvas->translate(SkIntToScalar(200), 0);
+        canvas->translate(0, SkIntToScalar(100));
         test_textpathmatrix(canvas);
-
-        test_bitmap_blur(canvas);
         
         if (REPEAT_COUNT > 1)
             this->inval(NULL);
diff --git a/samplecode/SampleTiling.cpp b/samplecode/SampleTiling.cpp
index 759c17c..87aeae4 100644
--- a/samplecode/SampleTiling.cpp
+++ b/samplecode/SampleTiling.cpp
@@ -8,6 +8,7 @@
 #include "SkUtils.h"
 #include "SkColorPriv.h"
 #include "SkColorFilter.h"
+#include "SkPicture.h"
 #include "SkTypeface.h"
 
 // effects
@@ -55,6 +56,7 @@
 static const int gHeight = 32;
 
 class TilingView : public SkView {
+    SkPicture           fTextPicture;
     SkBlurDrawLooper    fLooper;
 public:
 	TilingView()
@@ -97,19 +99,26 @@
         SkScalar y = SkIntToScalar(24);
         SkScalar x = SkIntToScalar(10);
 
-        for (int kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
-            for (int ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
-                SkPaint p;
-                SkString str;
-                p.setAntiAlias(true);
-                p.setDither(true);
-                p.setLooper(&fLooper);
-                str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
+        SkCanvas* textCanvas = NULL;
+        if (fTextPicture.width() == 0) {
+            textCanvas = fTextPicture.beginRecording(1000, 1000);
+        }
 
-                p.setTextAlign(SkPaint::kCenter_Align);
-                canvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);
-                
-                x += r.width() * 4 / 3;
+        if (textCanvas) {
+            for (int kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
+                for (int ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
+                    SkPaint p;
+                    SkString str;
+                    p.setAntiAlias(true);
+                    p.setDither(true);
+                    p.setLooper(&fLooper);
+                    str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
+
+                    p.setTextAlign(SkPaint::kCenter_Align);
+                    textCanvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);
+                    
+                    x += r.width() * 4 / 3;
+                }
             }
         }
         
@@ -132,22 +141,20 @@
                         x += r.width() * 4 / 3;
                     }
                 }
-                {
+                if (textCanvas) {
                     SkPaint p;
                     SkString str;
                     p.setAntiAlias(true);
                     p.setLooper(&fLooper);
                     str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
-                    canvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
+                    textCanvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
                 }
 
                 y += r.height() * 4 / 3;
             }
         }
-        
-    #ifdef SK_RELEASE
-        this->inval(NULL);
-    #endif
+
+        canvas->drawPicture(fTextPicture);
     }
     
     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
diff --git a/samplecode/SampleTinyBitmap.cpp b/samplecode/SampleTinyBitmap.cpp
index 1563c7a..ffbff25 100644
--- a/samplecode/SampleTinyBitmap.cpp
+++ b/samplecode/SampleTinyBitmap.cpp
@@ -48,6 +48,10 @@
     }
     
     void drawBG(SkCanvas* canvas) {
+        SkIPoint size;
+        if (canvas->getViewport(&size)) {
+            SkDebugf("");
+        }
         canvas->drawColor(0xFFDDDDDD);
     }
     
diff --git a/samplecode/SampleVertices.cpp b/samplecode/SampleVertices.cpp
index 96c9849..96fa0da 100644
--- a/samplecode/SampleVertices.cpp
+++ b/samplecode/SampleVertices.cpp
@@ -22,7 +22,7 @@
 static SkShader* make_shader0(SkIPoint* size) {
     SkBitmap    bm;
     
-    SkImageDecoder::DecodeFile("/skimages/logo.gif", &bm);
+    SkImageDecoder::DecodeFile("/skimages/logo.png", &bm);
     size->set(bm.width(), bm.height());
     return SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode,
                                         SkShader::kClamp_TileMode);
diff --git a/samplecode/SampleXfermodes.cpp b/samplecode/SampleXfermodes.cpp
index 7fecec6..a85bee2 100644
--- a/samplecode/SampleXfermodes.cpp
+++ b/samplecode/SampleXfermodes.cpp
@@ -23,6 +23,7 @@
 #include "SkColorPriv.h"
 #include "SkImageDecoder.h"
 
+#if 0
 static int newscale(U8CPU a, U8CPU b, int shift) {
     unsigned prod = a * b + (1 << (shift - 1));
     return (prod + (prod >> shift)) >> shift;
@@ -73,6 +74,7 @@
     p.setARGB(0xFF, rgb, rgb, rgb);
     canvas->drawRect(rect, p);
 }
+#endif
 
 static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {    
     src->setConfig(SkBitmap::kARGB_8888_Config, w, h);
@@ -103,27 +105,26 @@
 static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
 
 class XfermodesView : public SkView {
-    SkBitmap    fBitmap;
     SkBitmap    fBG;
     SkBitmap    fSrcB, fDstB;
 
-    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha) {
+    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha,
+                   SkScalar x, SkScalar y) {
         SkPaint p;
-        
-        canvas->drawBitmap(fSrcB, 0, 0, &p);        
+
+        canvas->drawBitmap(fSrcB, x, y, &p);        
         p.setAlpha(alpha);
         p.setXfermode(mode);
-        canvas->drawBitmap(fDstB, 0, 0, &p);
+        canvas->drawBitmap(fDstB, x, y, &p);
     }
     
 public:
+    const static int W = 64;
+    const static int H = 64;
 	XfermodesView() {
         const int W = 64;
         const int H = 64;
         
-        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, W, H);
-        fBitmap.allocPixels();
-        
         fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
         fBG.setPixels(gBG);
         fBG.setIsOpaque(true);
@@ -143,42 +144,13 @@
 
     void drawBG(SkCanvas* canvas) {
         canvas->drawColor(SK_ColorWHITE);
-        return;
-        SkShader* s = SkShader::CreateBitmapShader(fBG,
-                                                   SkShader::kRepeat_TileMode,
-                                                   SkShader::kRepeat_TileMode);
-        SkPaint p;
-        SkMatrix m;
-        
-        p.setShader(s)->unref();
-        m.setScale(SkIntToScalar(8), SkIntToScalar(8));
-        s->setLocalMatrix(m);
-        canvas->drawPaint(p);
     }
     
     virtual void onDraw(SkCanvas* canvas) {
+        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
+
         this->drawBG(canvas);
         
-        if (false) {
-            test_srcover565(canvas);
-        }
-        
-        if (false) {
-            SkPaint paint;
-            paint.setFlags(0x43);
-            paint.setTextSize(SkIntToScalar(128));
-            SkMatrix matrix;
-            matrix.reset();
-            matrix.set(0, 0x0019d049);
-            matrix.set(2, 0x712cf400);
-            matrix.set(4, 0x0019c96f);
-            matrix.set(5, 0xF8d76598);
-            canvas->concat(matrix);
-            canvas->drawText("HamburgefonsHamburgefonsHamburgefonsHamburgefons",
-                             48, 0, 0, paint);
-            return;
-        }
-
         const struct {
             SkXfermode::Mode  fMode;
             const char*         fLabel;
@@ -209,12 +181,9 @@
             { SkXfermode::kDifference_Mode,   "Difference"    },
             { SkXfermode::kExclusion_Mode,    "Exclusion"     },
         };
-        
-        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
-        
-        SkCanvas c(fBitmap);
-        const SkScalar w = SkIntToScalar(fBitmap.width());
-        const SkScalar h = SkIntToScalar(fBitmap.height());
+
+        const SkScalar w = SkIntToScalar(W);
+        const SkScalar h = SkIntToScalar(H);
         SkShader* s = SkShader::CreateBitmapShader(fBG,
                                                    SkShader::kRepeat_TileMode,
                                                    SkShader::kRepeat_TileMode);
@@ -233,27 +202,29 @@
             SkScalar x = x0, y = 0;
             for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
                 SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
-
-                fBitmap.eraseColor(0);
-                draw_mode(&c, mode, twice ? 0x88 : 0xFF);
-                SkSafeUnref(mode);
-                
-                SkPaint p;
+                SkAutoUnref aur(mode);
                 SkRect r;
                 r.set(x, y, x+w, y+h);
-                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
-                p.setStyle(SkPaint::kStroke_Style);
-                canvas->drawRect(r, p);
+
+                SkPaint p;
                 p.setStyle(SkPaint::kFill_Style);
                 p.setShader(s);
-                r.inset(SK_ScalarHalf, SK_ScalarHalf);
+                canvas->drawRect(r, p);
+                
+                canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
+         //       canvas->save();
+                draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
+                canvas->restore();
+
+                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
+                p.setStyle(SkPaint::kStroke_Style);
+                p.setShader(NULL);
                 canvas->drawRect(r, p);
 
-                canvas->drawBitmap(fBitmap, x, y, NULL);
-
+#if 1
                 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
                                  x + w/2, y - labelP.getTextSize()/2, labelP);
-
+#endif
                 x += w + SkIntToScalar(10);
                 if ((i % W) == W - 1) {
                     x = x0;