diff --git a/gpu/src/FlingState.cpp b/gpu/src/FlingState.cpp
new file mode 100644
index 0000000..cb634cc
--- /dev/null
+++ b/gpu/src/FlingState.cpp
@@ -0,0 +1,134 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "FlingState.h"
+#include "SkMatrix.h"
+#include "SkTime.h"
+
+#define DISCRETIZE_TRANSLATE_TO_AVOID_FLICKER   true
+
+static const float MAX_FLING_SPEED = 1500;
+
+static float pin_max_fling(float speed) {
+    if (speed > MAX_FLING_SPEED) {
+        speed = MAX_FLING_SPEED;
+    }
+    return speed;
+}
+
+static double getseconds() {
+    return SkTime::GetMSecs() * 0.001;
+}
+
+// returns +1 or -1, depending on the sign of x
+// returns +1 if x is zero
+static SkScalar SkScalarSign(SkScalar x) {
+    SkScalar sign = SK_Scalar1;
+    if (x < 0) {
+        sign = -sign;
+    }
+    return sign;
+}
+
+static void unit_axis_align(SkVector* unit) {
+    const SkScalar TOLERANCE = SkDoubleToScalar(0.15);
+    if (SkScalarAbs(unit->fX) < TOLERANCE) {
+        unit->fX = 0;
+        unit->fY = SkScalarSign(unit->fY);
+    } else if (SkScalarAbs(unit->fY) < TOLERANCE) {
+        unit->fX = SkScalarSign(unit->fX);
+        unit->fY = 0;
+    }
+}
+
+void FlingState::reset(float sx, float sy) {
+    fActive = true;
+    fDirection.set(sx, sy);
+    fSpeed0 = SkPoint::Normalize(&fDirection);
+    fSpeed0 = pin_max_fling(fSpeed0);
+    fTime0 = getseconds();
+
+    unit_axis_align(&fDirection);
+//    printf("---- speed %g dir %g %g\n", fSpeed0, fDirection.fX, fDirection.fY);
+}
+
+bool FlingState::evaluateMatrix(SkMatrix* matrix) {
+    if (!fActive) {
+        return false;
+    }
+
+    const float t =  getseconds() - fTime0;
+    const float MIN_SPEED = 2;
+    const float K0 = 5.0;
+    const float K1 = 0.02;
+    const float speed = fSpeed0 * (sk_float_exp(- K0 * t) - K1);
+    if (speed <= MIN_SPEED) {
+        fActive = false;
+        return false;
+    }
+    float dist = (fSpeed0 - speed) / K0;
+
+//    printf("---- time %g speed %g dist %g\n", t, speed, dist);
+    float tx = fDirection.fX * dist;
+    float ty = fDirection.fY * dist;
+    if (DISCRETIZE_TRANSLATE_TO_AVOID_FLICKER) {
+        tx = sk_float_round2int(tx);
+        ty = sk_float_round2int(ty);
+    }
+    matrix->setTranslate(tx, ty);
+//    printf("---- evaluate (%g %g)\n", tx, ty);
+
+    return true;
+}
+
+////////////////////////////////////////
+
+GrAnimateFloat::GrAnimateFloat() : fTime0(0) {}
+
+void GrAnimateFloat::start(float v0, float v1, float duration) {
+    fValue0 = v0;
+    fValue1 = v1;
+    fDuration = duration;
+    if (duration > 0) {
+        fTime0 = SkTime::GetMSecs();
+        if (!fTime0) {
+            fTime0 = 1;  // time0 is our sentinel
+        }
+    } else {
+        fTime0 = 0;
+    }
+}
+
+float GrAnimateFloat::evaluate() {
+    if (!fTime0) {
+        return fValue1;
+    }
+    
+    double elapsed = (SkTime::GetMSecs() - fTime0) * 0.001;
+    if (elapsed >= fDuration) {
+        fTime0 = 0;
+        return fValue1;
+    }
+    
+    double t = elapsed / fDuration;
+    if (true) {
+        t = (3 - 2 * t) * t * t;
+    }
+    return fValue0 + t * (fValue1 - fValue0);
+}
+
+
diff --git a/gpu/src/GrAllocPool.cpp b/gpu/src/GrAllocPool.cpp
new file mode 100644
index 0000000..f133f97
--- /dev/null
+++ b/gpu/src/GrAllocPool.cpp
@@ -0,0 +1,127 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAllocPool.h"
+
+#define GrAllocPool_MIN_BLOCK_SIZE      ((size_t)128)
+
+struct GrAllocPool::Block {
+    Block*  fNext;
+    char*   fPtr;
+    size_t  fBytesFree;
+    size_t  fBytesTotal;
+
+    static Block* Create(size_t size, Block* next) {
+        GrAssert(size >= GrAllocPool_MIN_BLOCK_SIZE);
+
+        Block* block = (Block*)GrMalloc(sizeof(Block) + size);
+        block->fNext = next;
+        block->fPtr = (char*)block + sizeof(Block);
+        block->fBytesFree = size;
+        block->fBytesTotal = size;
+        return block;
+    }
+
+    bool canAlloc(size_t bytes) const {
+        return bytes <= fBytesFree;
+    }
+
+    void* alloc(size_t bytes) {
+        GrAssert(bytes <= fBytesFree);
+        fBytesFree -= bytes;
+        void* ptr = fPtr;
+        fPtr += bytes;
+        return ptr;
+    }
+    
+    size_t release(size_t bytes) {
+        GrAssert(bytes > 0);
+        size_t free = GrMin(bytes, fBytesTotal - fBytesFree);
+        fBytesFree += free;
+        fPtr -= free;
+        return bytes - free;
+    }
+    
+    bool empty() const { return fBytesTotal == fBytesFree; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrAllocPool::GrAllocPool(size_t blockSize) {
+    fBlock = NULL;
+    fMinBlockSize = GrMax(blockSize, GrAllocPool_MIN_BLOCK_SIZE);
+    GR_DEBUGCODE(fBlocksAllocated = 0;)
+}
+
+GrAllocPool::~GrAllocPool() {
+    this->reset();
+}
+
+void GrAllocPool::reset() {
+    this->validate();
+
+    Block* block = fBlock;
+    while (block) {
+        Block* next = block->fNext;
+        GrFree(block);
+        block = next;
+    }
+    fBlock = NULL;
+    GR_DEBUGCODE(fBlocksAllocated = 0;)
+}
+
+void* GrAllocPool::alloc(size_t size) {
+    this->validate();
+    
+    if (!fBlock || !fBlock->canAlloc(size)) {
+        size_t blockSize = GrMax(fMinBlockSize, size);
+        fBlock = Block::Create(blockSize, fBlock);
+        GR_DEBUGCODE(fBlocksAllocated += 1;)
+    }
+    return fBlock->alloc(size);
+}
+
+void GrAllocPool::release(size_t bytes) {
+    this->validate();
+    
+    while (bytes && NULL != fBlock) {
+        bytes = fBlock->release(bytes);
+        if (fBlock->empty()) {
+            Block* next = fBlock->fNext;
+            GrFree(fBlock);
+            fBlock = next;
+            GR_DEBUGCODE(fBlocksAllocated -= 1;)
+        }
+    }
+}
+
+
+#if GR_DEBUG
+
+void GrAllocPool::validate() const {
+    Block* block = fBlock;
+    int count = 0;
+    while (block) {
+        count += 1;
+        block = block->fNext;
+    }
+    GrAssert(fBlocksAllocated == count);
+}
+
+#endif
+
+
diff --git a/gpu/src/GrAtlas.cpp b/gpu/src/GrAtlas.cpp
new file mode 100644
index 0000000..b55a029
--- /dev/null
+++ b/gpu/src/GrAtlas.cpp
@@ -0,0 +1,187 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAtlas.h"
+#include "GrGpu.h"
+#include "GrMemory.h"
+#include "GrRectanizer.h"
+#include "GrPlotMgr.h"
+
+#if 0
+#define GR_PLOT_WIDTH   8
+#define GR_PLOT_HEIGHT  4
+#define GR_ATLAS_WIDTH  256
+#define GR_ATLAS_HEIGHT 256
+
+#define GR_ATLAS_TEXTURE_WIDTH  (GR_PLOT_WIDTH * GR_ATLAS_WIDTH)
+#define GR_ATLAS_TEXTURE_HEIGHT (GR_PLOT_HEIGHT * GR_ATLAS_HEIGHT)
+
+#else
+
+#define GR_ATLAS_TEXTURE_WIDTH  1024
+#define GR_ATLAS_TEXTURE_HEIGHT 2048
+
+#define GR_ATLAS_WIDTH  341
+#define GR_ATLAS_HEIGHT 341
+
+#define GR_PLOT_WIDTH   (GR_ATLAS_TEXTURE_WIDTH / GR_ATLAS_WIDTH)
+#define GR_PLOT_HEIGHT  (GR_ATLAS_TEXTURE_HEIGHT / GR_ATLAS_HEIGHT)
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define BORDER      1
+
+#if GR_DEBUG
+    static int gCounter;
+#endif
+
+GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY) {
+    fAtlasMgr = mgr;    // just a pointer, not an owner
+    fNext = NULL;
+    fTexture = mgr->getTexture(); // we're not an owner, just a pointer
+    fPlot.set(plotX, plotY);
+
+    fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
+                                   GR_ATLAS_HEIGHT - BORDER);
+
+#if GR_DEBUG
+    GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
+    gCounter += 1;
+#endif
+}
+
+GrAtlas::~GrAtlas() {
+    fAtlasMgr->freePlot(fPlot.fX, fPlot.fY);
+
+    delete fRects;
+
+#if GR_DEBUG
+    --gCounter;
+    GrPrintf("~GrAtlas %p [%d %d] %d\n", this, fPlot.fX, fPlot.fY, gCounter);
+#endif
+}
+
+static void adjustForPlot(GrIPoint16* loc, const GrIPoint16& plot) {
+    loc->fX += plot.fX * GR_ATLAS_WIDTH;
+    loc->fY += plot.fY * GR_ATLAS_HEIGHT;
+}
+
+bool GrAtlas::addSubImage(int width, int height, const void* image,
+                          GrIPoint16* loc) {
+    if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
+        return false;
+    }
+
+    GrAutoSMalloc<1024> storage;
+    int srcW = width + 2*BORDER;
+    int srcH = height + 2*BORDER;
+    if (BORDER) {
+        uint8_t* ptr = (uint8_t*)storage.realloc(srcW * srcH);
+        Gr_bzero(ptr, srcW);                // zero top row
+        ptr += srcW;
+        for (int y = 0; y < height; y++) {
+            *ptr++ = 0;                     // zero left edge
+            memcpy(ptr, image, width); ptr += width;
+            *ptr++ = 0;                     // zero right edge
+            image = (const void*)((const char*)image + width);
+        }
+        Gr_bzero(ptr, srcW);                // zero bottom row
+        image = storage.get();
+    }
+    adjustForPlot(loc, fPlot);
+    fTexture->uploadTextureData(loc->fX, loc->fY, srcW, srcH, image);
+
+    // now tell the caller to skip the top/left BORDER
+    loc->fX += BORDER;
+    loc->fY += BORDER;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrAtlasMgr::GrAtlasMgr(GrGpu* gpu) {
+    fGpu = gpu;
+    gpu->ref();
+    fTexture = NULL;
+    fPlotMgr = new GrPlotMgr(GR_PLOT_WIDTH, GR_PLOT_HEIGHT);
+}
+
+GrAtlasMgr::~GrAtlasMgr() {
+    GrSafeUnref(fTexture);
+    delete fPlotMgr;
+    fGpu->unref();
+}
+
+GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
+                                int width, int height, const void* image,
+                                GrIPoint16* loc) {
+    if (atlas && atlas->addSubImage(width, height, image, loc)) {
+        return atlas;
+    }
+
+    // If the above fails, then either we have no starting atlas, or the current
+    // one is full. Either way we need to allocate a new atlas
+
+    GrIPoint16 plot;
+    if (!fPlotMgr->newPlot(&plot)) {
+        return NULL;
+    }
+
+    if (NULL == fTexture) {
+        GrGpu::TextureDesc desc = {
+            GrGpu::kDynamicUpdate_TextureFlag, 
+            GrGpu::kNone_AALevel,
+            GR_ATLAS_TEXTURE_WIDTH, 
+            GR_ATLAS_TEXTURE_HEIGHT,
+            GrTexture::kAlpha_8_PixelConfig
+        };
+        fTexture = fGpu->createTexture(desc, NULL, 0);
+        if (NULL == fTexture) {
+            return NULL;
+        }
+    }
+
+    GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY);
+    if (!newAtlas->addSubImage(width, height, image, loc)) {
+        delete newAtlas;
+        return NULL;
+    }
+
+    newAtlas->fNext = atlas;
+    return newAtlas;
+}
+
+void GrAtlasMgr::freePlot(int x, int y) {
+    GrAssert(fPlotMgr->isBusy(x, y));
+    fPlotMgr->freePlot(x, y);
+}
+
+void GrAtlasMgr::abandonAll() {
+#if 0
+    GrAtlas** curr = fList.begin();
+    GrAtlas** stop = fList.end();
+    for (; curr < stop; curr++) {
+        (*curr)->texture()->abandon();
+        delete *curr;
+    }
+    fList.reset();
+#endif
+}
+
+
diff --git a/gpu/src/GrClip.cpp b/gpu/src/GrClip.cpp
new file mode 100644
index 0000000..b7a839b
--- /dev/null
+++ b/gpu/src/GrClip.cpp
@@ -0,0 +1,136 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrClip.h"
+
+GrClip::GrClip() {
+    fBounds.setEmpty();
+    this->validate();
+}
+
+GrClip::GrClip(const GrClip& src) {
+    *this = src;
+}
+
+GrClip::GrClip(GrClipIterator* iter) {
+    fBounds.setEmpty();
+    this->setFromIterator(iter);
+}
+
+GrClip::~GrClip() {}
+
+GrClip& GrClip::operator=(const GrClip& src) {
+    fList = src.fList;
+    fBounds = src.fBounds;
+    this->validate();
+    return *this;
+}
+
+void GrClip::setEmpty() {
+    fList.reset();
+    fBounds.setEmpty();
+    this->validate();
+}
+
+void GrClip::setRect(const GrIRect& r) {
+    fList.reset();
+
+    // we need a canonical "empty" rect, so that our operator== will behave
+    // correctly with two empty clips.
+    if (r.isEmpty()) {
+        fBounds.setEmpty();
+    } else {
+        fBounds = r;
+    }
+    this->validate();
+}
+
+void GrClip::addRect(const GrIRect& r) {
+    if (!r.isEmpty()) {
+        this->validate();
+        if (this->isEmpty()) {
+            GrAssert(fList.count() == 0);
+            fBounds = r;
+        } else {
+            if (this->isRect()) {
+                *fList.append() = fBounds;
+            }
+            *fList.append() = r;
+            fBounds.unionWith(r);
+        }
+        this->validate();
+    }
+}
+
+void GrClip::setFromIterator(GrClipIterator* iter) {
+    this->setEmpty();
+    if (iter) {
+        for (iter->rewind(); !iter->isDone(); iter->next()) {
+            GrIRect r;
+            iter->getRect(&r);
+            this->addRect(r);
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrClipIter::reset(const GrClip& clip) { fClip = &clip; fIndex = 0; }
+
+bool GrClipIter::isDone() { 
+    return (NULL == fClip) || (fIndex >= fClip->countRects()); 
+}
+
+void GrClipIter::rewind() { fIndex = 0; }
+void GrClipIter::getRect(GrIRect* r) { *r = fClip->getRects()[fIndex]; }
+void GrClipIter::next() { fIndex += 1; }
+void GrClipIter::computeBounds(GrIRect* r) { 
+    if (NULL == fClip) {
+        r->setEmpty();
+    } else {
+        *r = fClip->getBounds();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+
+void GrClip::validate() const {
+    if (fBounds.isEmpty()) {
+        GrAssert(0 == fBounds.fLeft);
+        GrAssert(0 == fBounds.fTop);
+        GrAssert(0 == fBounds.fRight);
+        GrAssert(0 == fBounds.fBottom);
+        GrAssert(0 == fList.count());
+    } else {
+        int count = fList.count();
+        if (count > 0) {
+            GrAssert(count > 1);
+            GrAssert(!fList[0].isEmpty());
+            GrIRect bounds = fList[0];
+            for (int i = 1; i < count; i++) {
+                GrAssert(!fList[i].isEmpty());
+                bounds.unionWith(fList[i]);
+            }
+            GrAssert(fBounds == bounds);
+        }
+    }
+}
+
+#endif
+
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
new file mode 100644
index 0000000..6e94ef7
--- /dev/null
+++ b/gpu/src/GrContext.cpp
@@ -0,0 +1,1040 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrContext.h"
+#include "GrTextureCache.h"
+#include "GrTextStrike.h"
+#include "GrMemory.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+#include "GrIndexBuffer.h"
+
+#define DEFER_TEXT_RENDERING 1
+
+static const size_t MAX_TEXTURE_CACHE_COUNT = 128;
+static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
+
+#if DEFER_TEXT_RENDERING
+    static const uint32_t POOL_VB_SIZE = 2048 *
+            GrDrawTarget::VertexSize(GrDrawTarget::kTextFormat_VertexLayoutBit);
+    static const uint32_t NUM_POOL_VBS = 8;
+#else
+    static const uint32_t POOL_VB_SIZE = 0;
+    static const uint32_t NUM_POOL_VBS = 0;
+
+#endif
+
+GrContext* GrContext::Create(GrGpu::Engine engine,
+                             GrGpu::Platform3DContext context3D) {
+    GrContext* ctx = NULL;
+    GrGpu* fGpu = GrGpu::Create(engine, context3D);
+    if (NULL != fGpu) {
+        ctx = new GrContext(fGpu);
+        fGpu->unref();
+    }
+    return ctx;
+}
+
+GrContext::~GrContext() {
+    fGpu->unref();
+    delete fTextureCache;
+    delete fFontCache;
+}
+
+void GrContext::abandonAllTextures() {
+    fTextureCache->deleteAll(GrTextureCache::kAbandonTexture_DeleteMode);
+    fFontCache->abandonAll();
+}
+
+GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key,
+                                              const GrSamplerState& sampler) {
+    finalizeTextureKey(key, sampler);
+    return fTextureCache->findAndLock(*key);
+}
+
+static void stretchImage(void* dst,
+                         int dstW,
+                         int dstH,
+                         void* src,
+                         int srcW,
+                         int srcH,
+                         int bpp) {
+    GrFixed dx = (srcW << 16) / dstW;
+    GrFixed dy = (srcH << 16) / dstH;
+
+    GrFixed y = dy >> 1;
+
+    int dstXLimit = dstW*bpp;
+    for (int j = 0; j < dstH; ++j) {
+        GrFixed x = dx >> 1;
+        void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp;
+        void* dstRow = (uint8_t*)dst + j*dstW*bpp;
+        for (int i = 0; i < dstXLimit; i += bpp) {
+            memcpy((uint8_t*) dstRow + i,
+                   (uint8_t*) srcRow + (x>>16)*bpp,
+                   bpp);
+            x += dx;
+        }
+        y += dy;
+    }
+}
+
+GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
+                                                const GrSamplerState& sampler,
+                                                const GrGpu::TextureDesc& desc,
+                                                void* srcData, size_t rowBytes) {
+    GrAssert(key->width() == desc.fWidth);
+    GrAssert(key->height() == desc.fHeight);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+    GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight);
+#endif
+
+    GrTextureEntry* entry = NULL;
+    bool special = finalizeTextureKey(key, sampler);
+    if (special) {
+        GrTextureEntry* clampEntry;
+        GrTextureKey clampKey(*key);
+        clampEntry = findAndLockTexture(&clampKey, GrSamplerState::ClampNoFilter());
+
+        if (NULL == clampEntry) {
+            clampEntry = createAndLockTexture(&clampKey,
+                                              GrSamplerState::ClampNoFilter(),
+                                              desc, srcData, rowBytes);
+            GrAssert(NULL != clampEntry);
+            if (NULL == clampEntry) {
+                return NULL;
+            }
+        }
+        GrTexture* clampTexture = clampEntry->texture();
+        GrGpu::TextureDesc rtDesc = desc;
+        rtDesc.fFlags |= GrGpu::kRenderTarget_TextureFlag |
+                         GrGpu::kNoPathRendering_TextureFlag;
+        rtDesc.fWidth  = GrNextPow2(GrMax<int>(desc.fWidth,
+                                               fGpu->minRenderTargetWidth()));
+        rtDesc.fHeight = GrNextPow2(GrMax<int>(desc.fHeight,
+                                               fGpu->minRenderTargetHeight()));
+
+        GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
+
+        if (NULL != texture) {
+            GrGpu::AutoStateRestore asr(fGpu);
+            fGpu->setRenderTarget(texture->asRenderTarget());
+            fGpu->setTexture(clampEntry->texture());
+            fGpu->setStencilPass(GrGpu::kNone_StencilPass);
+            fGpu->setTextureMatrix(GrMatrix::I());
+            fGpu->setViewMatrix(GrMatrix::I());
+            fGpu->setAlpha(0xff);
+            fGpu->setBlendFunc(GrGpu::kOne_BlendCoeff, GrGpu::kZero_BlendCoeff);
+            fGpu->disableState(GrGpu::kDither_StateBit |
+                               GrGpu::kClip_StateBit   |
+                               GrGpu::kAntialias_StateBit);
+            GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
+                                          GrSamplerState::kClamp_WrapMode,
+                                          sampler.isFilter());
+            fGpu->setSamplerState(stretchSampler);
+
+            static const GrVertexLayout layout =
+                                GrDrawTarget::kSeparateTexCoord_VertexLayoutBit;
+            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
+
+            if (arg.succeeded()) {
+                GrPoint* verts = (GrPoint*) arg.vertices();
+                verts[0].setIRectFan(0, 0,
+                                     texture->contentWidth(),
+                                     texture->contentHeight(),
+                                     2*sizeof(GrPoint));
+                GrScalar tw = GrFixedToScalar(GR_Fixed1 *
+                                              clampTexture->contentWidth() /
+                                              clampTexture->allocWidth());
+                GrScalar th = GrFixedToScalar(GR_Fixed1 *
+                                              clampTexture->contentHeight() /
+                                              clampTexture->allocHeight());
+                verts[1].setRectFan(0, 0, tw, th, 2*sizeof(GrPoint));
+                fGpu->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType,
+                                     0, 4);
+                entry = fTextureCache->createAndLock(*key, texture);
+            }
+            texture->removeRenderTarget();
+        } else {
+            // TODO: Our CPU stretch doesn't filter. But we create separate
+            // stretched textures when the sampler state is either filtered or
+            // not. Either implement filtered stretch blit on CPU or just create
+            // one when FBO case fails.
+
+            rtDesc.fFlags = 0;
+            // no longer need to clamp at min RT size.
+            rtDesc.fWidth  = GrNextPow2(desc.fWidth);
+            rtDesc.fHeight = GrNextPow2(desc.fHeight);
+            int bpp = GrTexture::BytesPerPixel(desc.fFormat);
+            GrAutoSMalloc<128*128*4> stretchedPixels(bpp *
+                                                     rtDesc.fWidth *
+                                                     rtDesc.fHeight);
+            stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight,
+                         srcData, desc.fWidth, desc.fHeight, bpp);
+
+            size_t stretchedRowBytes = rtDesc.fWidth * bpp;
+
+            GrTexture* texture = fGpu->createTexture(rtDesc,
+                                                     stretchedPixels.get(),
+                                                     stretchedRowBytes);
+            GrAssert(NULL != texture);
+            entry = fTextureCache->createAndLock(*key, texture);
+        }
+        fTextureCache->unlock(clampEntry);
+
+    } else {
+        GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes);
+        if (NULL != texture) {
+            entry = fTextureCache->createAndLock(*key, texture);
+        } else {
+            entry = NULL;
+        }
+    }
+    return entry;
+}
+
+void GrContext::unlockTexture(GrTextureEntry* entry) {
+    fTextureCache->unlock(entry);
+}
+
+void GrContext::detachCachedTexture(GrTextureEntry* entry) {
+    fTextureCache->detach(entry);
+}
+
+void GrContext::reattachAndUnlockCachedTexture(GrTextureEntry* entry) {
+    fTextureCache->reattachAndUnlock(entry);
+}
+
+GrTexture* GrContext::createUncachedTexture(const GrGpu::TextureDesc& desc,
+                                            void* srcData,
+                                            size_t rowBytes) {
+    return fGpu->createTexture(desc, srcData, rowBytes);
+}
+
+GrRenderTarget* GrContext::createPlatformRenderTarget(intptr_t platformRenderTarget,
+                                                      int width, int height) {
+    return fGpu->createPlatformRenderTarget(platformRenderTarget,
+                                            width, height);
+}
+
+bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
+                                          int width, int height) {
+    if (!fGpu->supports8BitPalette()) {
+        return false;
+    }
+
+    bool needsRepeat = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
+                       sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
+    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+    switch (fGpu->npotTextureSupport()) {
+        case GrGpu::kNone_NPOTTextureType:
+            return isPow2;
+        case GrGpu::kNoRepeat_NPOTTextureType:
+            return isPow2 || !needsRepeat;
+        case GrGpu::kNonRendertarget_NPOTTextureType:
+        case GrGpu::kFull_NPOTTextureType:
+            return true;
+    }
+    // should never get here
+    GrAssert(!"Bad enum from fGpu->npotTextureSupport");
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::eraseColor(GrColor color) {
+    fGpu->eraseColor(color);
+}
+
+void GrContext::drawFull(bool useTexture) {
+    // set rect to be big enough to fill the space, but not super-huge, so we
+    // don't overflow fixed-point implementations
+    GrRect r(fGpu->getClip().getBounds());
+    GrMatrix inverse;
+    if (fGpu->getViewInverse(&inverse)) {
+        inverse.mapRect(&r);
+    } else {
+        GrPrintf("---- fGpu->getViewInverse failed\n");
+    }
+
+    this->fillRect(r, useTexture);
+}
+
+/*  create a triangle strip that strokes the specified triangle. There are 8
+ unique vertices, but we repreat the last 2 to close up. Alternatively we
+ could use an indices array, and then only send 8 verts, but not sure that
+ would be faster.
+ */
+static void setStrokeRectStrip(GrPoint verts[10], const GrRect& rect,
+                               GrScalar width) {
+    const GrScalar rad = GrScalarHalf(width);
+
+    verts[0].set(rect.fLeft + rad, rect.fTop + rad);
+    verts[1].set(rect.fLeft - rad, rect.fTop - rad);
+    verts[2].set(rect.fRight - rad, rect.fTop + rad);
+    verts[3].set(rect.fRight + rad, rect.fTop - rad);
+    verts[4].set(rect.fRight - rad, rect.fBottom - rad);
+    verts[5].set(rect.fRight + rad, rect.fBottom + rad);
+    verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
+    verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
+    verts[8] = verts[0];
+    verts[9] = verts[1];
+}
+
+void GrContext::drawRect(const GrRect& rect, bool useTexture, GrScalar width) {
+    GrVertexLayout layout = useTexture ?
+                            GrDrawTarget::kPositionAsTexCoord_VertexLayoutBit :
+                            0;
+
+    static const int worstCaseVertCount = 10;
+    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, worstCaseVertCount, 0);
+    if (!geo.succeeded()) {
+        return;
+    }
+
+    this->flushText();
+
+    int vertCount;
+    GrGpu::PrimitiveType primType;
+    GrPoint* vertex = geo.positions();
+
+    if (width >= 0) {
+        if (width > 0) {
+            vertCount = 10;
+            primType = GrGpu::kTriangleStrip_PrimitiveType;
+            setStrokeRectStrip(vertex, rect, width);
+        } else {
+            // hairline
+            vertCount = 5;
+            primType = GrGpu::kLineStrip_PrimitiveType;
+            vertex[0].set(rect.fLeft, rect.fTop);
+            vertex[1].set(rect.fRight, rect.fTop);
+            vertex[2].set(rect.fRight, rect.fBottom);
+            vertex[3].set(rect.fLeft, rect.fBottom);
+            vertex[4].set(rect.fLeft, rect.fTop);
+        }
+    } else {
+        vertCount = 4;
+        primType = GrGpu::kTriangleFan_PrimitiveType;
+        vertex->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
+    }
+
+    fGpu->drawNonIndexed(primType, 0, vertCount);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define NEW_EVAL        1   // Use adaptive path tesselation
+#define STENCIL_OFF     0   // Always disable stencil (even when needed)
+#define CPU_TRANSFORM   0   // Transform path verts on CPU
+
+#if NEW_EVAL
+
+#define EVAL_TOL GR_Scalar1
+
+static uint32_t quadratic_point_count(const GrPoint points[], GrScalar tol) {
+    GrScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]);
+    // TODO: fixed points sqrt
+    if (d < tol) {
+        return 1;
+    } else {
+        // Each time we subdivide, d should be cut in 4. So we need to
+        // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x)
+        // points.
+        // 2^(log4(x)) = sqrt(x);
+        d = ceilf(sqrtf(d/tol));
+        return GrNextPow2((uint32_t)d);
+    }
+}
+
+static uint32_t generate_quadratic_points(const GrPoint& p0,
+                                          const GrPoint& p1,
+                                          const GrPoint& p2,
+                                          GrScalar tolSqd,
+                                          GrPoint** points,
+                                          uint32_t pointsLeft) {
+    if (pointsLeft < 2 ||
+        (p1.distanceToLineSegmentBetweenSqd(p0, p2)) < tolSqd) {
+        (*points)[0] = p2;
+        *points += 1;
+        return 1;
+    }
+
+    GrPoint q[] = {
+        GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)),
+        GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)),
+    };
+    GrPoint r(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY));
+
+    pointsLeft >>= 1;
+    uint32_t a = generate_quadratic_points(p0, q[0], r, tolSqd, points, pointsLeft);
+    uint32_t b = generate_quadratic_points(r, q[1], p2, tolSqd, points, pointsLeft);
+    return a + b;
+}
+
+static uint32_t cubic_point_count(const GrPoint points[], GrScalar tol) {
+    GrScalar d = GrMax(points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]),
+                       points[2].distanceToLineSegmentBetweenSqd(points[0], points[3]));
+    d = sqrtf(d);
+    if (d < tol) {
+        return 1;
+    } else {
+        d = ceilf(sqrtf(d/tol));
+        return GrNextPow2((uint32_t)d);
+    }
+}
+
+static uint32_t generate_cubic_points(const GrPoint& p0,
+                                      const GrPoint& p1,
+                                      const GrPoint& p2,
+                                      const GrPoint& p3,
+                                      GrScalar tolSqd,
+                                      GrPoint** points,
+                                      uint32_t pointsLeft) {
+    if (pointsLeft < 2 ||
+        (p1.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd &&
+         p2.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd)) {
+            (*points)[0] = p3;
+            *points += 1;
+            return 1;
+        }
+    GrPoint q[] = {
+        GrPoint(GrScalarAve(p0.fX, p1.fX), GrScalarAve(p0.fY, p1.fY)),
+        GrPoint(GrScalarAve(p1.fX, p2.fX), GrScalarAve(p1.fY, p2.fY)),
+        GrPoint(GrScalarAve(p2.fX, p3.fX), GrScalarAve(p2.fY, p3.fY))
+    };
+    GrPoint r[] = {
+        GrPoint(GrScalarAve(q[0].fX, q[1].fX), GrScalarAve(q[0].fY, q[1].fY)),
+        GrPoint(GrScalarAve(q[1].fX, q[2].fX), GrScalarAve(q[1].fY, q[2].fY))
+    };
+    GrPoint s(GrScalarAve(r[0].fX, r[1].fX), GrScalarAve(r[0].fY, r[1].fY));
+    pointsLeft >>= 1;
+    uint32_t a = generate_cubic_points(p0, q[0], r[0], s, tolSqd, points, pointsLeft);
+    uint32_t b = generate_cubic_points(s, r[1], q[2], p3, tolSqd, points, pointsLeft);
+    return a + b;
+}
+
+#else // !NEW_EVAL
+
+static GrScalar gr_eval_quad(const GrScalar coord[], GrScalar t) {
+    GrScalar A = coord[0] - 2 * coord[2] + coord[4];
+    GrScalar B = 2 * (coord[2] - coord[0]);
+    GrScalar C = coord[0];
+
+    return GrMul(GrMul(A, t) + B, t) + C;
+}
+
+static void gr_eval_quad_at(const GrPoint src[3], GrScalar t, GrPoint* pt) {
+    GrAssert(src);
+    GrAssert(pt);
+    GrAssert(t >= 0 && t <= GR_Scalar1);
+    pt->set(gr_eval_quad(&src[0].fX, t), gr_eval_quad(&src[0].fY, t));
+}
+
+static GrScalar gr_eval_cubic(const GrScalar coord[], GrScalar t) {
+    GrScalar A = coord[6] - coord[0] + 3 * (coord[2] - coord[4]);
+    GrScalar B = 3 * (coord[0] - 2 * coord[2] + coord[4]);
+    GrScalar C = 3 * (coord[2] - coord[0]);
+    GrScalar D = coord[0];
+
+    return GrMul(GrMul(GrMul(A, t) + B, t) + C, t) + D;
+}
+
+static void gr_eval_cubic_at(const GrPoint src[4], GrScalar t, GrPoint* pt) {
+    GrAssert(src);
+    GrAssert(pt);
+    GrAssert(t >= 0 && t <= GR_Scalar1);
+
+    pt->set(gr_eval_cubic(&src[0].fX, t), gr_eval_cubic(&src[0].fY, t));
+}
+
+#endif // !NEW_EVAL
+
+static int worst_case_point_count(GrPathIter* path,
+                                  int* subpaths,
+                                  const GrMatrix& matrix,
+                                  GrScalar tol) {
+    int pointCount = 0;
+    *subpaths = 1;
+
+    bool first = true;
+
+    GrPathIter::Command cmd;
+
+    GrPoint pts[4];
+    while ((cmd = path->next(pts)) != GrPathIter::kEnd_Command) {
+
+        switch (cmd) {
+            case GrPathIter::kLine_Command:
+                pointCount += 1;
+                break;
+            case GrPathIter::kQuadratic_Command:
+#if NEW_EVAL
+                matrix.mapPoints(pts, pts, 3);
+                pointCount += quadratic_point_count(pts, tol);
+#else
+                pointCount += 9;
+#endif
+                break;
+            case GrPathIter::kCubic_Command:
+#if NEW_EVAL
+                matrix.mapPoints(pts, pts, 4);
+                pointCount += cubic_point_count(pts, tol);
+#else
+                pointCount += 17;
+#endif
+                break;
+            case GrPathIter::kMove_Command:
+                pointCount += 1;
+                if (!first) {
+                    ++(*subpaths);
+                }
+                break;
+            default:
+                break;
+        }
+        first = false;
+    }
+    return pointCount;
+}
+
+static inline bool single_pass_path(const GrPathIter& path,
+                                    GrContext::PathFills fill,
+                                    bool useTex,
+                                    const GrGpu& gpu) {
+#if STENCIL_OFF
+    return true;
+#else
+    if (GrContext::kEvenOdd_PathFill == fill) {
+        GrPathIter::ConvexHint hint = path.hint();
+        return hint == GrPathIter::kConvex_ConvexHint ||
+               hint == GrPathIter::kNonOverlappingConvexPieces_ConvexHint;
+    } else if (GrContext::kWinding_PathFill == fill) {
+        GrPathIter::ConvexHint hint = path.hint();
+        return hint == GrPathIter::kConvex_ConvexHint ||
+               hint == GrPathIter::kNonOverlappingConvexPieces_ConvexHint ||
+               (hint == GrPathIter::kSameWindingConvexPieces_ConvexHint &&
+                gpu.canDisableBlend() && !gpu.isDitherState());
+
+    }
+    return false;
+#endif
+}
+
+void GrContext::drawPath(GrPathIter* path, PathFills fill,
+                         bool useTexture, const GrPoint* translate) {
+
+    flushText();
+
+    GrGpu::AutoStateRestore asr(fGpu);
+
+#if NEW_EVAL
+    GrMatrix viewM;
+    fGpu->getViewMatrix(&viewM);
+    // In order to tesselate the path we get a bound on how much the matrix can
+    // stretch when mapping to screen coordinates.
+    GrScalar stretch = viewM.getMaxStretch();
+    bool useStretch = stretch > 0;
+    GrScalar tol = EVAL_TOL;
+    if (!useStretch) {
+        // TODO: deal with perspective in some better way.
+        tol /= 10;
+    } else {
+        // TODO: fixed point divide
+        GrScalar sinv = 1 / stretch;
+        tol = GrMul(tol, sinv);
+        viewM = GrMatrix::I();
+    }
+    GrScalar tolSqd = GrMul(tol, tol);
+#else
+    // pass to worst_case... but won't be used.
+    static const GrScalar tol = -1;
+#endif
+
+    int subpathCnt;
+    int maxPts = worst_case_point_count(path,
+                                        &subpathCnt,
+#if CPU_TRANSFORM
+                                        cpuMatrix,
+#else
+                                        GrMatrix::I(),
+#endif
+                                        tol);
+    GrVertexLayout layout = 0;
+    if (useTexture) {
+        layout = GrDrawTarget::kPositionAsTexCoord_VertexLayoutBit;
+    }
+    // add 4 to hold the bounding rect
+    GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, maxPts + 4, 0);
+
+    GrPoint* base = (GrPoint*) arg.vertices();
+    GrPoint* vert = base;
+    GrPoint* subpathBase = base;
+
+    GrAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt);
+
+    path->rewind();
+
+    // TODO: use primitve restart if available rather than multiple draws
+    GrGpu::PrimitiveType  type;
+    int                   passCount = 0;
+    GrGpu::StencilPass    passes[3];
+    bool                  reverse = false;
+
+    if (kHairLine_PathFill == fill) {
+        type = GrGpu::kLineStrip_PrimitiveType;
+        passCount = 1;
+        passes[0] = GrGpu::kNone_StencilPass;
+    } else {
+        type = GrGpu::kTriangleFan_PrimitiveType;
+        if (single_pass_path(*path, fill, useTexture, *fGpu)) {
+            passCount = 1;
+            passes[0] = GrGpu::kNone_StencilPass;
+        } else {
+            switch (fill) {
+                case kInverseEvenOdd_PathFill:
+                    reverse = true;
+                    // fallthrough
+                case kEvenOdd_PathFill:
+                    passCount = 2;
+                    passes[0] = GrGpu::kEvenOddStencil_StencilPass;
+                    passes[1] = GrGpu::kEvenOddColor_StencilPass;
+                    break;
+
+                case kInverseWinding_PathFill:
+                    reverse = true;
+                    // fallthrough
+                case kWinding_PathFill:
+                    passes[0] = GrGpu::kWindingStencil1_StencilPass;
+                    if (fGpu->supportsSingleStencilPassWinding()) {
+                        passes[1] = GrGpu::kWindingColor_StencilPass;
+                        passCount = 2;
+                    } else {
+                        passes[1] = GrGpu::kWindingStencil2_StencilPass;
+                        passes[2] = GrGpu::kWindingColor_StencilPass;
+                        passCount = 3;
+                    }
+                    break;
+                default:
+                    GrAssert(!"Unknown path fill!");
+                    return;
+            }
+        }
+    }
+    fGpu->setReverseFill(reverse);
+#if CPU_TRANSFORM
+    GrMatrix cpuMatrix;
+    fGpu->getViewMatrix(&cpuMatrix);
+    fGpu->setViewMatrix(GrMatrix::I());
+#endif
+
+    GrPoint pts[4];
+
+    bool first = true;
+    int subpath = 0;
+
+    for (;;) {
+        GrPathIter::Command cmd = path->next(pts);
+#if CPU_TRANSFORM
+        int numPts = GrPathIter::NumCommandPoints(cmd);
+        cpuMatrix.mapPoints(pts, pts, numPts);
+#endif
+        switch (cmd) {
+            case GrPathIter::kMove_Command:
+                if (!first) {
+                    subpathVertCount[subpath] = vert-subpathBase;
+                    subpathBase = vert;
+                    ++subpath;
+                }
+                *vert = pts[0];
+                vert++;
+                break;
+            case GrPathIter::kLine_Command:
+                *vert = pts[1];
+                vert++;
+                break;
+            case GrPathIter::kQuadratic_Command: {
+#if NEW_EVAL
+
+                generate_quadratic_points(pts[0], pts[1], pts[2],
+                                          tolSqd, &vert,
+                                          quadratic_point_count(pts, tol));
+#else
+                const int n = 8;
+                const GrScalar dt = GR_Scalar1 / n;
+                GrScalar t = dt;
+                for (int i = 1; i < n; i++) {
+                    gr_eval_quad_at(pts, t, (GrPoint*)vert);
+                    t += dt;
+                    vert++;
+                }
+                vert->set(pts[2].fX, pts[2].fY);
+                vert++;
+#endif
+                break;
+            }
+            case GrPathIter::kCubic_Command: {
+#if NEW_EVAL
+                generate_cubic_points(pts[0], pts[1], pts[2], pts[3],
+                                      tolSqd, &vert,
+                                      cubic_point_count(pts, tol));
+#else
+                const int n = 16;
+                const GrScalar dt = GR_Scalar1 / n;
+                GrScalar t = dt;
+                for (int i = 1; i < n; i++) {
+                    gr_eval_cubic_at(pts, t, (GrPoint*)vert);
+                    t += dt;
+                    vert++;
+                }
+                vert->set(pts[3].fX, pts[3].fY);
+                vert++;
+#endif
+                break;
+            }
+            case GrPathIter::kClose_Command:
+                break;
+            case GrPathIter::kEnd_Command:
+                subpathVertCount[subpath] = vert-subpathBase;
+                ++subpath; // this could be only in debug
+                goto FINISHED;
+        }
+        first = false;
+    }
+FINISHED:
+    GrAssert(subpath == subpathCnt);
+    GrAssert((vert - base) <= maxPts);
+
+    if (translate) {
+        int count = vert - base;
+        for (int i = 0; i < count; i++) {
+            base[i].offset(translate->fX, translate->fY);
+        }
+    }
+
+    // arbitrary path complexity cutoff
+    bool useBounds = fill != kHairLine_PathFill &&
+                    (reverse || (vert - base) > 8);
+    GrPoint* boundsVerts = base + maxPts;
+    if (useBounds) {
+        GrRect bounds;
+        if (reverse) {
+            GrAssert(NULL != fGpu->currentRenderTarget());
+            // draw over the whole world.
+            bounds.setLTRB(0, 0,
+                           GrIntToScalar(fGpu->currentRenderTarget()->width()),
+                           GrIntToScalar(fGpu->currentRenderTarget()->height()));
+        } else {
+            bounds.setBounds((GrPoint*)base, vert - base);
+        }
+        boundsVerts[0].setRectFan(bounds.fLeft, bounds.fTop, bounds.fRight,
+                                  bounds.fBottom);
+    }
+
+    for (int p = 0; p < passCount; ++p) {
+        fGpu->setStencilPass(passes[p]);
+        if (useBounds && (GrGpu::kEvenOddColor_StencilPass == passes[p] ||
+                          GrGpu::kWindingColor_StencilPass == passes[p])) {
+            fGpu->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType,
+                                 maxPts, 4);
+        } else {
+            int baseVertex = 0;
+            for (int sp = 0; sp < subpathCnt; ++sp) {
+                fGpu->drawNonIndexed(type,
+                                     baseVertex,
+                                     subpathVertCount[sp]);
+                baseVertex += subpathVertCount[sp];
+            }
+        }
+    }
+}
+
+void GrContext::flush(bool flushRenderTarget) {
+    flushText();
+    if (flushRenderTarget) {
+        fGpu->forceRenderTargetFlush();
+    }
+}
+
+void GrContext::flushText() {
+    fTextDrawBuffer.playback(fGpu);
+    fTextDrawBuffer.reset();
+}
+
+bool GrContext::readPixels(int left, int top, int width, int height,
+                           GrTexture::PixelConfig config, void* buffer) {
+    this->flush(true);
+    return fGpu->readPixels(left, top, width, height, config, buffer);
+}
+
+void GrContext::writePixels(int left, int top, int width, int height,
+                            GrTexture::PixelConfig config, const void* buffer,
+                            size_t stride) {
+    const GrGpu::TextureDesc desc = {
+        0, GrGpu::kNone_AALevel, width, height, config
+    };
+    GrTexture* texture = fGpu->createTexture(desc, buffer, stride);
+    if (NULL == texture) {
+        return;
+    }
+
+    this->flush(true);
+
+    GrAutoUnref                     aur(texture);
+    GrDrawTarget::AutoStateRestore  asr(fGpu);
+
+    GrMatrix matrix;
+    matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
+    fGpu->setViewMatrix(matrix);
+    matrix.setScale(GR_Scalar1 / texture->allocWidth(),
+                    GR_Scalar1 / texture->allocHeight());
+    fGpu->setTextureMatrix(matrix);
+
+    fGpu->disableState(GrDrawTarget::kClip_StateBit);
+    fGpu->setAlpha(0xFF);
+    fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff,
+                       GrDrawTarget::kZero_BlendCoeff);
+    fGpu->setTexture(texture);
+    fGpu->setSamplerState(GrSamplerState::ClampNoFilter());
+
+    this->fillRect(GrRect(0, 0, GrIntToScalar(width), GrIntToScalar(height)),
+                   true);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+/* -------------------------------------------------------
+ * Mimicking the GrGpu interface for now
+ * TODO: define appropriate higher-level API for context
+ */
+
+void GrContext::resetContext() {
+    fGpu->resetContext();
+}
+
+GrVertexBuffer* GrContext::createVertexBuffer(uint32_t size, bool dynamic) {
+    return fGpu->createVertexBuffer(size, dynamic);
+}
+
+GrIndexBuffer* GrContext::createIndexBuffer(uint32_t size, bool dynamic) {
+    return fGpu->createIndexBuffer(size, dynamic);
+}
+
+void GrContext::setTexture(GrTexture* texture) {
+    fGpu->setTexture(texture);
+}
+
+void GrContext::setRenderTarget(GrRenderTarget* target) {
+    flushText();
+    fGpu->setRenderTarget(target);
+}
+
+GrRenderTarget* GrContext::currentRenderTarget() const {
+    return fGpu->currentRenderTarget();
+}
+
+void GrContext::setDefaultRenderTargetSize(uint32_t width, uint32_t height) {
+    fGpu->setDefaultRenderTargetSize(width, height);
+}
+
+void GrContext::setSamplerState(const GrSamplerState& samplerState) {
+    fGpu->setSamplerState(samplerState);
+}
+
+void GrContext::setTextureMatrix(const GrMatrix& m) {
+    fGpu->setTextureMatrix(m);
+}
+
+void GrContext::getViewMatrix(GrMatrix* m) const {
+    fGpu->getViewMatrix(m);
+}
+
+void GrContext::setViewMatrix(const GrMatrix& m) {
+    fGpu->setViewMatrix(m);
+}
+
+bool GrContext::reserveAndLockGeometry(GrVertexLayout    vertexLayout,
+                                       uint32_t          vertexCount,
+                                       uint32_t          indexCount,
+                                       void**            vertices,
+                                       void**            indices) {
+    return fGpu->reserveAndLockGeometry(vertexLayout,
+                                        vertexCount,
+                                        indexCount,
+                                        vertices,
+                                        indices);
+}
+
+void GrContext::drawIndexed(GrGpu::PrimitiveType type,
+                            uint32_t startVertex,
+                            uint32_t startIndex,
+                            uint32_t vertexCount,
+                            uint32_t indexCount) {
+    flushText();
+    fGpu->drawIndexed(type,
+                      startVertex,
+                      startIndex,
+                      vertexCount,
+                      indexCount);
+}
+
+void GrContext::drawNonIndexed(GrGpu::PrimitiveType type,
+                               uint32_t startVertex,
+                               uint32_t vertexCount) {
+    flushText();
+    fGpu->drawNonIndexed(type,
+                         startVertex,
+                         vertexCount);
+}
+
+void GrContext::setVertexSourceToArray(const void* array,
+                                       GrVertexLayout vertexLayout) {
+    fGpu->setVertexSourceToArray(array, vertexLayout);
+}
+
+void GrContext::setIndexSourceToArray(const void* array) {
+    fGpu->setIndexSourceToArray(array);
+}
+
+void GrContext::setVertexSourceToBuffer(GrVertexBuffer* buffer,
+                                       GrVertexLayout vertexLayout) {
+    fGpu->setVertexSourceToBuffer(buffer, vertexLayout);
+}
+
+void GrContext::setIndexSourceToBuffer(GrIndexBuffer* buffer) {
+    fGpu->setIndexSourceToBuffer(buffer);
+}
+
+void GrContext::releaseReservedGeometry() {
+    fGpu->releaseReservedGeometry();
+}
+
+void GrContext::setClip(const GrClip& clip) {
+    fGpu->setClip(clip);
+    fGpu->enableState(GrDrawTarget::kClip_StateBit);
+}
+
+void GrContext::setAlpha(uint8_t alpha) {
+    fGpu->setAlpha(alpha);
+}
+
+void GrContext::setColor(GrColor color) {
+    fGpu->setColor(color);
+}
+
+static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
+    intptr_t mask = 1 << shift;
+    if (pred) {
+        bits |= mask;
+    } else {
+        bits &= ~mask;
+    }
+    return bits;
+}
+
+void GrContext::setAntiAlias(bool aa) {
+    if (aa) {
+        fGpu->enableState(GrGpu::kAntialias_StateBit);
+    } else {
+        fGpu->disableState(GrGpu::kAntialias_StateBit);
+    }
+}
+
+void GrContext::setDither(bool dither) {
+    // hack for now, since iPad dither is hella-slow
+    dither = false;
+
+    if (dither) {
+        fGpu->enableState(GrGpu::kDither_StateBit);
+    } else {
+        fGpu->disableState(GrGpu::kDither_StateBit);
+    }
+}
+
+void GrContext::setPointSize(float size) {
+    fGpu->setPointSize(size);
+}
+
+void GrContext::setBlendFunc(GrGpu::BlendCoeff srcCoef,
+                             GrGpu::BlendCoeff dstCoef) {
+    fGpu->setBlendFunc(srcCoef, dstCoef);
+}
+
+void GrContext::resetStats() {
+    fGpu->resetStats();
+}
+
+const GrGpu::Stats& GrContext::getStats() const {
+    return fGpu->getStats();
+}
+
+void GrContext::printStats() const {
+    fGpu->printStats();
+}
+
+GrContext::GrContext(GrGpu* gpu) :
+        fVBAllocPool(gpu,
+                     gpu->supportsBufferLocking() ? POOL_VB_SIZE : 0,
+                     gpu->supportsBufferLocking() ? NUM_POOL_VBS : 0),
+        fTextDrawBuffer(gpu->supportsBufferLocking() ? &fVBAllocPool : NULL) {
+    fGpu = gpu;
+    fGpu->ref();
+    fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,
+                                       MAX_TEXTURE_CACHE_BYTES);
+    fFontCache = new GrFontCache(fGpu);
+}
+
+bool GrContext::finalizeTextureKey(GrTextureKey* key,
+                                   const GrSamplerState& sampler) const {
+    uint32_t bits = 0;
+    uint16_t width = key->width();
+    uint16_t height = key->height();
+    if (fGpu->npotTextureSupport() < GrGpu::kNonRendertarget_NPOTTextureType) {
+        if ((sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
+             sampler.getWrapY() != GrSamplerState::kClamp_WrapMode) &&
+            (!GrIsPow2(width) || !GrIsPow2(height))) {
+            bits |= 1;
+            bits |= sampler.isFilter() ? 2 : 0;
+        }
+    }
+    key->finalize(bits);
+    return 0 != bits;
+}
+
+GrDrawTarget* GrContext::getTextTarget() {
+#if DEFER_TEXT_RENDERING
+    fTextDrawBuffer.initializeDrawStateAndClip(*fGpu);
+    return &fTextDrawBuffer;
+#else
+    return fGpu;
+#endif
+}
+
+const GrIndexBuffer* GrContext::quadIndexBuffer() const {
+    return fGpu->quadIndexBuffer();
+}
+
+int GrContext::maxQuadsInIndexBuffer() const {
+    return fGpu->maxQuadsInIndexBuffer();
+}
+
+
+
+
diff --git a/gpu/src/GrDrawMesh.cpp b/gpu/src/GrDrawMesh.cpp
new file mode 100644
index 0000000..bd79005
--- /dev/null
+++ b/gpu/src/GrDrawMesh.cpp
@@ -0,0 +1,140 @@
+#include "GrMesh.h"
+#include "SkCanvas.h"
+
+GrMesh::GrMesh() : fPts(NULL), fCount(0), fIndices(NULL), fIndexCount(0) {}
+
+GrMesh::~GrMesh() {
+    delete[] fPts;
+    delete[] fIndices;
+}
+
+GrMesh& GrMesh::operator=(const GrMesh& src) {
+    delete[] fPts;
+    delete[] fIndices;
+
+    fBounds = src.fBounds;
+    fRows = src.fRows;
+    fCols = src.fCols;
+
+    fCount = src.fCount;
+    fPts = new SkPoint[fCount * 2];
+    fTex = fPts + fCount;
+    memcpy(fPts, src.fPts, fCount * 2 * sizeof(SkPoint));
+    
+    delete[] fIndices;
+    fIndexCount = src.fIndexCount;
+    fIndices = new uint16_t[fIndexCount];
+    memcpy(fIndices, src.fIndices, fIndexCount * sizeof(uint16_t));
+
+    return *this;
+}
+
+void GrMesh::init(const SkRect& bounds, int rows, int cols,
+                const SkRect& texture) {
+    SkASSERT(rows > 0 && cols > 0);
+
+    fBounds = bounds;
+    fRows = rows;
+    fCols = cols;
+
+    delete[] fPts;
+    fCount = (rows + 1) * (cols + 1);
+    fPts = new SkPoint[fCount * 2];
+    fTex = fPts + fCount;
+
+    delete[] fIndices;
+    fIndexCount = rows * cols * 6;
+    fIndices = new uint16_t[fIndexCount];
+    
+    SkPoint* pts = fPts;
+    const SkScalar dx = bounds.width() / rows;
+    const SkScalar dy = bounds.height() / cols;
+    SkPoint* tex = fTex;
+    const SkScalar dtx = texture.width() / rows;
+    const SkScalar dty = texture.height() / cols;
+    uint16_t* idx = fIndices;
+    int index = 0;
+    for (int y = 0; y <= cols; y++) {
+        for (int x = 0; x <= rows; x++) {
+            pts->set(bounds.fLeft + x*dx, bounds.fTop + y*dy);
+            pts += 1;
+            tex->set(texture.fLeft + x*dtx, texture.fTop + y*dty);
+            tex += 1;
+            
+            if (y < cols && x < rows) {
+                *idx++ = index;
+                *idx++ = index + rows + 1;
+                *idx++ = index + 1;
+
+                *idx++ = index + 1;
+                *idx++ = index + rows + 1;
+                *idx++ = index + rows + 2;
+                
+                index += 1;
+            }
+        }
+        index += 1;
+    }
+}
+
+void GrMesh::draw(SkCanvas* canvas, const SkPaint& paint) {
+    canvas->drawVertices(SkCanvas::kTriangles_VertexMode, fCount,
+                         fPts, fTex, NULL, NULL, fIndices, fIndexCount,
+                         paint);
+}
+
+/////////////////////////////////////////////
+
+#include "SkBoundaryPatch.h"
+#include "SkMeshUtils.h"
+
+static SkPoint SkPointInterp(const SkPoint& a, const SkPoint& b, SkScalar t) {
+    return SkPoint::Make(SkScalarInterp(a.fX, b.fX, t),
+                         SkScalarInterp(a.fY, b.fY, t));
+}
+
+static void set_cubic(SkPoint pts[4], SkScalar x0, SkScalar y0,
+                      SkScalar x3, SkScalar y3, SkScalar scale = 1) {
+    SkPoint tmp, tmp2;
+    
+    pts[0].set(x0, y0);
+    pts[3].set(x3, y3);
+    
+    tmp = SkPointInterp(pts[0], pts[3], SK_Scalar1/3);
+    tmp2 = pts[0] - tmp;
+    tmp2.rotateCW();
+    tmp2.scale(scale);
+    pts[1] = tmp + tmp2;
+    
+    tmp = SkPointInterp(pts[0], pts[3], 2*SK_Scalar1/3);
+    tmp2 = pts[3] - tmp;
+    tmp2.rotateCW();
+    tmp2.scale(scale);
+    pts[2] = tmp + tmp2;
+}
+
+void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale) {
+    const float w = bm.width();
+    const float h = bm.height();
+    SkCubicBoundary cubic;    
+    set_cubic(cubic.fPts + 0, 0, 0, w, 0, scale);
+    set_cubic(cubic.fPts + 3, w, 0, w, h, scale);
+    set_cubic(cubic.fPts + 6, w, h, 0, h, -scale);
+    set_cubic(cubic.fPts + 9, 0, h, 0, 0, scale);
+    
+    SkBoundaryPatch patch;
+    patch.setBoundary(&cubic);
+    
+    const int Rows = 16;
+    const int Cols = 16;
+    SkPoint pts[Rows * Cols];
+    patch.evalPatch(pts, Rows, Cols);
+    
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setFilterBitmap(true);
+
+    SkMeshUtils::Draw(canvas, bm, Rows, Cols, pts, NULL, paint);
+}
+
+
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
new file mode 100644
index 0000000..82f94a3
--- /dev/null
+++ b/gpu/src/GrDrawTarget.cpp
@@ -0,0 +1,296 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrDrawTarget.h"
+#include "GrGpuVertex.h"
+
+#define VERTEX_LAYOUT_ASSERTS \
+    GrAssert(!(vertexLayout & kTextFormat_VertexLayoutBit) ||           \
+             vertexLayout == kTextFormat_VertexLayoutBit);              \
+    GrAssert(!(vertexLayout & kSeparateTexCoord_VertexLayoutBit) ||     \
+             !(vertexLayout & kPositionAsTexCoord_VertexLayoutBit));
+
+size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
+    VERTEX_LAYOUT_ASSERTS
+    if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
+        return 2 * sizeof(GrGpuTextVertex);
+    } else {
+        size_t size = sizeof(GrPoint);
+        if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
+            size += sizeof(GrPoint);
+        }
+        if (vertexLayout & kColor_VertexLayoutBit) {
+            size += sizeof(GrColor);
+        }
+        return size;
+    }
+}
+
+int GrDrawTarget::VertexTexCoordOffset(GrVertexLayout vertexLayout) {
+    VERTEX_LAYOUT_ASSERTS
+    if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
+        return sizeof(GrGpuTextVertex);
+    } else if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
+        return sizeof(GrPoint);
+    } else if (vertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+        return 0;
+    }
+    return -1;
+}
+
+int  GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
+    VERTEX_LAYOUT_ASSERTS
+    if (vertexLayout & kColor_VertexLayoutBit) {
+        if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
+            return 2 * sizeof(GrPoint);
+        } else {
+            return sizeof(GrPoint);
+        }
+    }
+    return -1;
+}
+
+int GrDrawTarget::VertexSizeAndOffsets(GrVertexLayout vertexLayout,
+                                       int* texCoordOffset,
+                                       int* colorOffset) {
+    VERTEX_LAYOUT_ASSERTS
+
+    GrAssert(NULL != texCoordOffset);
+    GrAssert(NULL != colorOffset);
+
+    if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
+        *texCoordOffset = sizeof(GrGpuTextVertex);
+        *colorOffset = 0;
+        return 2 * sizeof(GrGpuTextVertex);
+    } else {
+        size_t size = sizeof(GrPoint);
+        if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
+            *texCoordOffset = sizeof(GrPoint);
+            size += sizeof(GrPoint);
+        } else if (vertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+            *texCoordOffset = 0;
+        } else {
+            *texCoordOffset = -1;
+        }
+        if (vertexLayout & kColor_VertexLayoutBit) {
+            *colorOffset = size;
+            size += sizeof(GrColor);
+        } else {
+            *colorOffset = -1;
+        }
+        return size;
+    }
+}
+
+bool GrDrawTarget::VertexHasTexCoords(GrVertexLayout vertexLayout) {
+    return !!(vertexLayout & (kSeparateTexCoord_VertexLayoutBit   |
+                              kPositionAsTexCoord_VertexLayoutBit |
+                              kTextFormat_VertexLayoutBit));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::GrDrawTarget() {
+    fReservedGeometry.fLocked = false;
+#if GR_DEBUG
+    fReservedGeometry.fVertexCount  = ~0;
+    fReservedGeometry.fIndexCount   = ~0;
+#endif
+    fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
+    fGeometrySrc.fIndexSrc  = kReserved_GeometrySrcType;
+}
+
+void GrDrawTarget::setClip(const GrClip& clip) {
+    clipWillChange(clip);
+    fClip = clip;
+}
+
+const GrClip& GrDrawTarget::getClip() const {
+    return fClip;
+}
+
+void GrDrawTarget::setTexture(GrTexture* tex) {
+    fCurrDrawState.fTexture = tex;
+}
+
+GrTexture* GrDrawTarget::currentTexture() const {
+    return fCurrDrawState.fTexture;
+}
+
+void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
+    fCurrDrawState.fRenderTarget = target;
+}
+
+GrRenderTarget* GrDrawTarget::currentRenderTarget() const {
+    return fCurrDrawState.fRenderTarget;
+}
+
+void GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) {
+    GrMatrix mv;
+    mv.setConcat(fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode], matrix);
+    this->loadMatrix(mv, kModelView_MatrixMode);
+}
+
+void GrDrawTarget::getViewMatrix(GrMatrix* matrix) const {
+    *matrix = fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
+}
+
+bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
+    // Can we cache this somewhere?
+
+    GrMatrix inverse;
+    if (fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode].invert(&inverse)) {
+        if (matrix) {
+            *matrix = inverse;
+        }
+        return true;
+    }
+    return false;
+}
+
+void GrDrawTarget::setSamplerState(const GrSamplerState& state) {
+    fCurrDrawState.fSamplerState = state;
+}
+
+void GrDrawTarget::setStencilPass(StencilPass pass) {
+    fCurrDrawState.fStencilPass = pass;
+}
+
+void GrDrawTarget::setReverseFill(bool reverse) {
+    fCurrDrawState.fReverseFill = reverse;
+}
+
+void GrDrawTarget::enableState(uint32_t bits) {
+    fCurrDrawState.fFlagBits |= bits;
+}
+
+void GrDrawTarget::disableState(uint32_t bits) {
+    fCurrDrawState.fFlagBits &= ~(bits);
+}
+
+void GrDrawTarget::loadMatrix(const GrMatrix& matrix, MatrixMode m) {
+    fCurrDrawState.fMatrixModeCache[m] = matrix;
+}
+
+void GrDrawTarget::setPointSize(float size) {
+    fCurrDrawState.fPointSize = size;
+}
+
+void GrDrawTarget::setBlendFunc(BlendCoeff srcCoef,
+                                BlendCoeff dstCoef) {
+    fCurrDrawState.fSrcBlend = srcCoef;
+    fCurrDrawState.fDstBlend = dstCoef;
+}
+
+void GrDrawTarget::setColor(GrColor c) {
+    fCurrDrawState.fColor = c;
+}
+
+void GrDrawTarget::setAlpha(uint8_t a) {
+    this->setColor((a << 24) | (a << 16) | (a << 8) | a);
+}
+
+void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
+    state->fState = fCurrDrawState;
+}
+
+void GrDrawTarget::restoreDrawState(const SavedDrawState& state) {
+    fCurrDrawState = state.fState;
+}
+
+void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
+    fCurrDrawState = srcTarget.fCurrDrawState;
+}
+
+
+bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout    vertexLayout,
+                                          uint32_t          vertexCount,
+                                          uint32_t          indexCount,
+                                          void**            vertices,
+                                          void**            indices) {
+    GrAssert(!fReservedGeometry.fLocked);
+    fReservedGeometry.fVertexCount  = vertexCount;
+    fReservedGeometry.fIndexCount   = indexCount;
+
+    fReservedGeometry.fLocked = acquireGeometryHelper(vertexLayout,
+                                                      vertices,
+                                                      indices);
+    if (fReservedGeometry.fLocked) {
+        if (vertexCount) {
+            fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
+            fGeometrySrc.fVertexLayout = vertexLayout;
+        }
+        if (indexCount) {
+            fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
+        }
+    }
+    return fReservedGeometry.fLocked;
+}
+
+bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
+                                 int32_t* vertexCount,
+                                 int32_t* indexCount) const {
+    GrAssert(!fReservedGeometry.fLocked);
+    if (NULL != vertexCount) {
+        *vertexCount = -1;
+    }
+    if (NULL != indexCount) {
+        *indexCount = -1;
+    }
+    return false;
+}
+
+void GrDrawTarget::releaseReservedGeometry() {
+    GrAssert(fReservedGeometry.fLocked);
+    releaseGeometryHelper();
+    fReservedGeometry.fLocked = false;
+}
+
+void GrDrawTarget::setVertexSourceToArray(const void* array,
+                                          GrVertexLayout vertexLayout) {
+    fGeometrySrc.fVertexSrc    = kArray_GeometrySrcType;
+    fGeometrySrc.fVertexArray  = array;
+    fGeometrySrc.fVertexLayout = vertexLayout;
+}
+
+void GrDrawTarget::setIndexSourceToArray(const void* array) {
+    fGeometrySrc.fIndexSrc   = kArray_GeometrySrcType;
+    fGeometrySrc.fIndexArray = array;
+}
+
+void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer,
+                                           GrVertexLayout vertexLayout) {
+    fGeometrySrc.fVertexSrc    = kBuffer_GeometrySrcType;
+    fGeometrySrc.fVertexBuffer = buffer;
+    fGeometrySrc.fVertexLayout = vertexLayout;
+}
+
+void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
+    fGeometrySrc.fIndexSrc     = kBuffer_GeometrySrcType;
+    fGeometrySrc.fIndexBuffer  = buffer;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target) {
+    fDrawTarget = target;
+    fDrawTarget->saveCurrentDrawState(&fDrawState);
+}
+
+GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
+    fDrawTarget->restoreDrawState(fDrawState);
+}
diff --git a/gpu/src/GrGLIndexBuffer.cpp b/gpu/src/GrGLIndexBuffer.cpp
new file mode 100644
index 0000000..82cffaa
--- /dev/null
+++ b/gpu/src/GrGLIndexBuffer.cpp
@@ -0,0 +1,106 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLIndexBuffer.h"
+#include "GrGpuGL.h"
+
+GrGLIndexBuffer::GrGLIndexBuffer(GLuint id, GrGpuGL* gl, uint32_t sizeInBytes,
+                                   bool dynamic) : 
+                                INHERITED(sizeInBytes, dynamic),
+                                fGL(gl),
+                                fBufferID(id),
+                                fLockPtr(NULL) {
+}
+
+GLuint GrGLIndexBuffer::bufferID() const {
+    return fBufferID;
+}
+
+GrGLIndexBuffer::~GrGLIndexBuffer() {
+    // make sure we've not been abandoned
+    if (fBufferID) {
+        fGL->notifyIndexBufferDelete(this);
+        GR_GL(DeleteBuffers(1, &fBufferID));
+    }
+}
+
+void GrGLIndexBuffer::abandon() {
+    fBufferID = 0; 
+    fGL = NULL;
+    fLockPtr = NULL;
+}
+
+void* GrGLIndexBuffer::lock() {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (fGL->supportsBufferLocking()) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
+        fGL->notifyIndexBufferBind(this);
+        // call bufferData with null ptr to allow driver to perform renaming
+        // If this call is removed revisit updateData to be sure it doesn't
+        // leave buffer undersized (as it currently does).
+        GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, size(), NULL, 
+                         dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        fLockPtr = GR_GLEXT(fGL->extensions(),
+                            MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GR_WRITE_ONLY));
+
+        return fLockPtr;
+    }
+    return NULL;
+}
+
+void GrGLIndexBuffer::unlock() {
+    GrAssert(fBufferID);
+    GrAssert(isLocked());
+
+    if (fGL->supportsBufferLocking()) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
+        fGL->notifyIndexBufferBind(this);
+        GR_GLEXT(fGL->extensions(),
+                 UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
+        fLockPtr = NULL;
+    }
+}
+
+bool GrGLIndexBuffer::isLocked() const {
+    GrAssert(fBufferID);
+#if GR_DEBUG
+    if (fGL->supportsBufferLocking()) {
+        GLint mapped;
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
+        fGL->notifyIndexBufferBind(this);
+        GR_GL(GetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, 
+                                   GR_BUFFER_MAPPED, &mapped));
+        GrAssert(!!mapped == !!fLockPtr);
+    }
+#endif
+    return NULL != fLockPtr;
+}
+
+bool GrGLIndexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes > size()) {
+        return false;
+    }
+    GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, fBufferID));
+    fGL->notifyIndexBufferBind(this);
+    GR_GL(BufferData(GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src, 
+                     dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+    return true;
+}
+
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
new file mode 100644
index 0000000..b75cad5
--- /dev/null
+++ b/gpu/src/GrGLTexture.cpp
@@ -0,0 +1,174 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLTexture.h"
+#include "GrGpuGL.h"
+
+GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids, 
+                                   const GrIRect& viewport,
+                                   GrGLTexture* texture,
+                                   GrGpuGL* gl) : INHERITED(texture) {
+    fGL                     = gl;
+    fRTFBOID                = ids.fRTFBOID;
+    fTexFBOID               = ids.fTexFBOID;
+    fStencilRenderbufferID  = ids.fStencilRenderbufferID;
+    fMSColorRenderbufferID  = ids.fMSColorRenderbufferID;
+    fNeedsResolve           = false;
+    fViewport               = viewport;
+    fOwnIDs                 = ids.fOwnIDs;
+    // viewport should be GL's viewport with top >= bottom
+    GrAssert(viewport.height() <= 0);
+}
+
+GrGLRenderTarget::~GrGLRenderTarget() {
+    fGL->notifyRenderTargetDelete(this);
+    if (fOwnIDs) {
+        if (fTexFBOID) {
+            GR_GLEXT(fGL->extensions(), DeleteFramebuffers(1, &fTexFBOID));
+        }
+        if (fRTFBOID && fRTFBOID != fTexFBOID) {
+            GR_GLEXT(fGL->extensions(), DeleteFramebuffers(1, &fRTFBOID));
+        }
+        if (fStencilRenderbufferID) {
+            GR_GLEXT(fGL->extensions(), DeleteRenderbuffers(1, &fStencilRenderbufferID));
+        }
+        if (fMSColorRenderbufferID) {
+            GR_GLEXT(fGL->extensions(), DeleteRenderbuffers(1, &fMSColorRenderbufferID));
+        }
+    }
+}
+
+void GrGLRenderTarget::abandon() {
+    fRTFBOID                = 0;
+    fTexFBOID               = 0;
+    fStencilRenderbufferID  = 0;
+    fMSColorRenderbufferID  = 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+const GLenum GrGLTexture::gWrapMode2GLWrap[] = {
+    GL_CLAMP_TO_EDGE,
+    GL_REPEAT,
+#ifdef GL_MIRRORED_REPEAT
+    GL_MIRRORED_REPEAT
+#else
+    GL_REPEAT       // GL_MIRRORED_REPEAT not supported :(
+#endif
+};
+
+
+GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
+                         const GLRenderTargetIDs& rtIDs,
+                         GrGpuGL* gl) :
+        INHERITED(textureDesc.fContentWidth, 
+                  textureDesc.fContentHeight, 
+                  textureDesc.fAllocWidth, 
+                  textureDesc.fAllocHeight,
+                  textureDesc.fFormat),
+        fTextureID(textureDesc.fTextureID),
+        fUploadFormat(textureDesc.fUploadFormat),
+        fUploadByteCount(textureDesc.fUploadByteCount),
+        fUploadType(textureDesc.fUploadType),
+        fOrientation(textureDesc.fOrientation),
+        fRenderTarget(NULL),
+        fGpuGL(gl) {
+
+    GrAssert(0 != textureDesc.fTextureID);
+
+    if (rtIDs.fTexFBOID) {
+        GrIRect vp;
+        vp.fLeft   = 0;
+        vp.fRight  = (int32_t) textureDesc.fContentWidth;
+        // viewport for GL is top > bottom 
+        vp.fTop    = (int32_t) textureDesc.fAllocHeight;
+        vp.fBottom = (int32_t) textureDesc.fAllocHeight - 
+                     (int32_t)textureDesc.fContentHeight;
+        fRenderTarget = new GrGLRenderTarget(rtIDs, vp, this, gl);
+    }
+
+    fSamplerState.setClampNoFilter();
+    
+    GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID));
+    gl->notifyTextureBind(this);
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+}
+
+GrGLTexture::~GrGLTexture() {
+    // make sure we haven't been abandoned
+    if (fTextureID) {
+        fGpuGL->notifyTextureDelete(this);
+        GR_GL(DeleteTextures(1, &fTextureID));
+    }
+    delete fRenderTarget;
+}
+
+void GrGLTexture::abandon() {
+    fTextureID = 0;
+    if (NULL != fRenderTarget) {
+    	fRenderTarget->abandon();
+    }
+}
+
+bool GrGLTexture::isRenderTarget() const {
+    return NULL != fRenderTarget;
+}
+
+GrRenderTarget* GrGLTexture::asRenderTarget() {
+    return (GrRenderTarget*)fRenderTarget;
+}
+
+void GrGLTexture::removeRenderTarget() {
+    GrAssert(NULL != fRenderTarget);
+    if (NULL != fRenderTarget) {
+        // must do this notify before the delete
+        fGpuGL->notifyTextureRemoveRenderTarget(this);
+        delete fRenderTarget;
+        fRenderTarget = NULL;        
+    }
+}
+
+void GrGLTexture::uploadTextureData(uint32_t x,
+                                    uint32_t y,
+                                    uint32_t width,
+                                    uint32_t height,
+                                    const void* srcData) {
+    // glCompressedTexSubImage2D doesn't support any formats
+    // (at least without extensions)
+    GrAssert(fUploadFormat != GR_PALETTE8_RGBA8);
+
+    // If we need to update textures that are created upside down
+    // then we have to modify this code to flip the srcData
+    GrAssert(kTopDown_Orientation == fOrientation);
+    GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID));
+    fGpuGL->notifyTextureBind(this);
+    GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, fUploadByteCount));
+    GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, 
+                        fUploadFormat, fUploadType, srcData));
+
+}
+
+intptr_t GrGLTexture::getTextureHandle() {
+    return fTextureID;
+}
+
+
+
diff --git a/gpu/src/GrGLVertexBuffer.cpp b/gpu/src/GrGLVertexBuffer.cpp
new file mode 100644
index 0000000..b4ddc24
--- /dev/null
+++ b/gpu/src/GrGLVertexBuffer.cpp
@@ -0,0 +1,103 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLVertexBuffer.h"
+#include "GrGpuGL.h"
+
+GrGLVertexBuffer::GrGLVertexBuffer(GLuint id, GrGpuGL* gl, uint32_t sizeInBytes,
+                                   bool dynamic) : 
+                                   INHERITED(sizeInBytes, dynamic),
+                                   fGL(gl),
+                                   fBufferID(id),
+                                   fLockPtr(NULL) {
+}
+
+GrGLVertexBuffer::~GrGLVertexBuffer() {
+    // make sure we've not been abandoned
+    if (fBufferID) {
+        fGL->notifyVertexBufferDelete(this);
+        GR_GL(DeleteBuffers(1, &fBufferID));
+    }
+}
+
+GLuint GrGLVertexBuffer::bufferID() const {
+    return fBufferID;
+}
+
+void GrGLVertexBuffer::abandon() { 
+    fBufferID = 0;
+    fGL = NULL;
+    fLockPtr = NULL;
+}
+
+void* GrGLVertexBuffer::lock() {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (fGL->supportsBufferLocking()) {
+        GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+        fGL->notifyVertexBufferBind(this);
+        // call bufferData with null ptr to allow driver to perform renaming
+        // If this call is removed revisit updateData to be sure it doesn't
+        // leave buffer undersized (as it currently does).
+        GR_GL(BufferData(GL_ARRAY_BUFFER, size(), NULL, 
+                         dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        fLockPtr = GR_GLEXT(fGL->extensions(),
+                            MapBuffer(GL_ARRAY_BUFFER, GR_WRITE_ONLY)); 
+        return fLockPtr;
+    }
+    return NULL;
+}
+
+void GrGLVertexBuffer::unlock() {
+    GrAssert(fBufferID);
+    GrAssert(isLocked());
+    if (fGL->supportsBufferLocking()) {
+        GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+        fGL->notifyVertexBufferBind(this);
+        GR_GLEXT(fGL->extensions(),
+                 UnmapBuffer(GL_ARRAY_BUFFER));
+        fLockPtr = NULL;
+    }
+}
+
+bool GrGLVertexBuffer::isLocked() const {
+    GrAssert(fBufferID);
+#if GR_DEBUG
+    if (fGL->supportsBufferLocking()) {
+        GLint mapped;
+        GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+        fGL->notifyVertexBufferBind(this);
+        GR_GL(GetBufferParameteriv(GL_ARRAY_BUFFER, GR_BUFFER_MAPPED, &mapped));
+        GrAssert(!!mapped == !!fLockPtr);
+    }
+#endif
+    return NULL != fLockPtr;
+}
+
+bool GrGLVertexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+    GrAssert(fBufferID);
+    GrAssert(!isLocked());
+    if (srcSizeInBytes > size()) {
+        return false;
+    }
+    GR_GL(BindBuffer(GL_ARRAY_BUFFER, fBufferID));
+    fGL->notifyVertexBufferBind(this);
+    GR_GL(BufferData(GL_ARRAY_BUFFER, srcSizeInBytes, src, 
+                     dynamic() ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+    return true;
+}
+
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
new file mode 100644
index 0000000..c6340bd
--- /dev/null
+++ b/gpu/src/GrGpu.cpp
@@ -0,0 +1,343 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGpu.h"
+#include "GrMemory.h"
+#include "GrTextStrike.h"
+#include "GrTextureCache.h"
+#include "GrClipIterator.h"
+#include "GrIndexBuffer.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+size_t GrTexture::BytesPerPixel(PixelConfig config) {
+    switch (config) {
+        case kAlpha_8_PixelConfig:
+        case kIndex_8_PixelConfig:
+            return 1;
+        case kRGB_565_PixelConfig:
+        case kRGBA_4444_PixelConfig:
+            return 2;
+        case kRGBA_8888_PixelConfig:
+        case kRGBX_8888_PixelConfig:
+            return 4;
+        default:
+            return 0;
+    }
+}
+
+bool GrTexture::PixelConfigIsOpaque(PixelConfig config) {
+    switch (config) {
+        case GrTexture::kRGB_565_PixelConfig:
+        case GrTexture::kRGBX_8888_PixelConfig:
+            return true;
+        default:
+            return false;
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+extern void gr_run_unittests();
+
+GrGpu::GrGpu() : f8bitPaletteSupport(false),
+                 fNPOTTextureSupport(kNone_NPOTTextureType),
+                 fQuadIndexBuffer(NULL) {
+#if GR_DEBUG
+//    gr_run_unittests();
+#endif
+    resetStats();
+}
+
+GrGpu::~GrGpu() {
+    if (NULL != fQuadIndexBuffer) {
+        fQuadIndexBuffer->unref();
+    }
+}
+
+void GrGpu::resetContext() {
+}
+
+void GrGpu::unimpl(const char msg[]) {
+//    GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool GrGpu::canDisableBlend() const {
+    if ((kOne_BlendCoeff == fCurrDrawState.fSrcBlend) &&
+        (kZero_BlendCoeff == fCurrDrawState.fDstBlend)) {
+            return true;
+    }
+
+    // If we have vertex color without alpha then we can't force blend off
+    if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
+         0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
+        return false;
+    }
+
+    // If the src coef will always be 1...
+    bool fullSrc = kSA_BlendCoeff == fCurrDrawState.fSrcBlend ||
+                   kOne_BlendCoeff == fCurrDrawState.fSrcBlend;
+
+    // ...and the dst coef is always 0...
+    bool noDst = kISA_BlendCoeff == fCurrDrawState.fDstBlend ||
+                 kZero_BlendCoeff == fCurrDrawState.fDstBlend;
+
+    // ...and there isn't a texture with an alpha channel...
+    bool noTexAlpha = !VertexHasTexCoords(fGeometrySrc.fVertexLayout)  ||
+        fCurrDrawState.fTexture->config() == GrTexture::kRGB_565_PixelConfig ||
+        fCurrDrawState.fTexture->config() == GrTexture::kRGBX_8888_PixelConfig;
+
+    // ...then we disable blend.
+    return fullSrc && noDst && noTexAlpha;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const int MAX_QUADS = 512; // max possible: (1 << 14) - 1;
+
+GR_STATIC_ASSERT(4 * MAX_QUADS <= UINT16_MAX);
+
+static inline void fillIndices(uint16_t* indices, int quadCount) {
+    for (int i = 0; i < quadCount; ++i) {
+        indices[6 * i + 0] = 4 * i + 0;
+        indices[6 * i + 1] = 4 * i + 1;
+        indices[6 * i + 2] = 4 * i + 2;
+        indices[6 * i + 3] = 4 * i + 0;
+        indices[6 * i + 4] = 4 * i + 2;
+        indices[6 * i + 5] = 4 * i + 3;
+    }
+}
+
+const GrIndexBuffer* GrGpu::quadIndexBuffer() const {
+    if (NULL == fQuadIndexBuffer) {
+        static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS;
+        GrGpu* me = const_cast<GrGpu*>(this);
+        fQuadIndexBuffer = me->createIndexBuffer(SIZE, false);
+        if (NULL != fQuadIndexBuffer) {
+            uint16_t* indices = (uint16_t*)fQuadIndexBuffer->lock();
+            if (NULL != indices) {
+                fillIndices(indices, MAX_QUADS);
+                fQuadIndexBuffer->unlock();
+            } else {
+                indices = (uint16_t*)GrMalloc(SIZE);
+                fillIndices(indices, MAX_QUADS);
+                if (!fQuadIndexBuffer->updateData(indices, SIZE)) {
+                    fQuadIndexBuffer->unref();
+                    fQuadIndexBuffer = NULL;
+                    GrAssert(!"Can't get indices into buffer!");
+                }
+                GrFree(indices);
+            }
+        }
+    }
+
+    return fQuadIndexBuffer;
+}
+
+int GrGpu::maxQuadsInIndexBuffer() const {
+    return (NULL == this->quadIndexBuffer()) ? 0 : MAX_QUADS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrGpu::clipWillChange(const GrClip& clip) {
+    if (clip != fClip) {
+        fClipState.fClipIsDirty = true;
+    }
+}
+
+bool GrGpu::setupClipAndFlushState(PrimitiveType type) {
+    const GrIRect* r = NULL;
+
+    if (fCurrDrawState.fFlagBits & kClip_StateBit) {
+        fClipState.fClipInStencil = fClip.countRects() > 1;
+
+        if (fClipState.fClipInStencil &&
+            (fClipState.fClipIsDirty ||
+             fClipState.fStencilClipTarget != fCurrDrawState.fRenderTarget)) {
+
+            AutoStateRestore asr(this);
+            AutoGeometrySrcRestore agsr(this);
+            this->disableState(kClip_StateBit);
+            eraseStencilClip();
+
+            int rectTotal = fClip.countRects();
+            static const int PtsPerRect = 4;
+            // this may be called while geometry is already reserved by the
+            // client. So we use our own vertex array where we avoid malloc
+            // if we have 4 or fewer rects.
+            GrAutoSTMalloc<PtsPerRect * 4, GrPoint> vertices(PtsPerRect *
+                                                             rectTotal);
+            this->setVertexSourceToArray(vertices.get(), 0);
+            int currRect = 0;
+            while (currRect < rectTotal) {
+                int rectCount = GrMin(this->maxQuadsInIndexBuffer(),
+                                      rectTotal - currRect);
+
+                GrPoint* verts = (GrPoint*)vertices +
+                                 (currRect * PtsPerRect);
+
+                for (int i = 0; i < rectCount; i++) {
+                    GrRect r(fClip.getRects()[i + currRect]);
+                    verts = r.setRectFan(verts);
+                }
+                this->setIndexSourceToBuffer(quadIndexBuffer());
+
+                this->setViewMatrix(GrMatrix::I());
+                this->setStencilPass((GrDrawTarget::StencilPass)kSetClip_StencilPass);
+                this->drawIndexed(GrGpu::kTriangles_PrimitiveType,
+                                  currRect * PtsPerRect, 0,
+                                  rectCount * PtsPerRect, rectCount * 6);
+
+                currRect += rectCount;
+            }
+            fClipState.fStencilClipTarget = fCurrDrawState.fRenderTarget;
+        }
+        fClipState.fClipIsDirty = false;
+        if (!fClipState.fClipInStencil) {
+            r = &fClip.getBounds();
+        }
+    }
+    // Must flush the scissor after graphics state
+    if (!flushGraphicsState(type)) {
+        return false;
+    }
+    flushScissor(r);
+    return true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrGpu::drawIndexed(PrimitiveType type,
+                        uint32_t startVertex,
+                        uint32_t startIndex,
+                        uint32_t vertexCount,
+                        uint32_t indexCount) {
+    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
+             fReservedGeometry.fLocked);
+    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
+             fReservedGeometry.fLocked);
+
+    if (!setupClipAndFlushState(type)) {
+        return;
+    }
+
+#if GR_COLLECT_STATS
+    fStats.fVertexCnt += vertexCount;
+    fStats.fIndexCnt  += indexCount;
+    fStats.fDrawCnt   += 1;
+#endif
+
+    setupGeometry(startVertex, startIndex, vertexCount, indexCount);
+
+    drawIndexedHelper(type, startVertex, startIndex,
+                      vertexCount, indexCount);
+}
+
+void GrGpu::drawNonIndexed(PrimitiveType type,
+                           uint32_t startVertex,
+                           uint32_t vertexCount) {
+    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
+             fReservedGeometry.fLocked);
+
+    if (!setupClipAndFlushState(type)) {
+        return;
+    }
+#if GR_COLLECT_STATS
+    fStats.fVertexCnt += vertexCount;
+    fStats.fDrawCnt   += 1;
+#endif
+
+    setupGeometry(startVertex, 0, vertexCount, 0);
+
+    drawNonIndexedHelper(type, startVertex, vertexCount);
+}
+
+bool GrGpu::acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                  void**         vertices,
+                                  void**         indices) {
+    GrAssert((fReservedGeometry.fVertexCount == 0) ||
+             (NULL != vertices));
+    if (NULL != vertices) {
+        *vertices = fVertices.realloc(VertexSize(vertexLayout) *
+                                      fReservedGeometry.fVertexCount);
+        if (!*vertices && fReservedGeometry.fVertexCount) {
+            return false;
+        }
+    }
+    GrAssert((fReservedGeometry.fIndexCount == 0) ||
+             (NULL != indices));
+    if (NULL != indices) {
+        *indices =  fIndices.realloc(sizeof(uint16_t) *
+                                     fReservedGeometry.fIndexCount);
+        if (!*indices && fReservedGeometry.fIndexCount) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void GrGpu::releaseGeometryHelper() {
+    return;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+const GrGpu::Stats& GrGpu::getStats() const {
+    return fStats;
+}
+
+void GrGpu::resetStats() {
+    memset(&fStats, 0, sizeof(fStats));
+}
+
+void GrGpu::printStats() const {
+    if (GR_COLLECT_STATS) {
+     GrPrintf(
+     "-v-------------------------GPU STATS----------------------------v-\n"
+     "Stats collection is: %s\n"
+     "Draws: %04d, Verts: %04d, Indices: %04d\n"
+     "ProgChanges: %04d, TexChanges: %04d, RTChanges: %04d\n"
+     "TexCreates: %04d, RTCreates:%04d\n"
+     "-^--------------------------------------------------------------^-\n",
+     (GR_COLLECT_STATS ? "ON" : "OFF"),
+    fStats.fDrawCnt, fStats.fVertexCnt, fStats.fIndexCnt,
+    fStats.fProgChngCnt, fStats.fTextureChngCnt, fStats.fRenderTargetChngCnt,
+    fStats.fTextureCreateCnt, fStats.fRenderTargetCreateCnt);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrTexture::~GrTexture() {
+    // use this to set a break-point if needed
+//    Gr_clz(3);
+}
+
+const GrSamplerState GrSamplerState::gClampNoFilter(
+    GrSamplerState::kClamp_WrapMode,
+    GrSamplerState::kClamp_WrapMode,
+    GrSamplerState::kNormal_SampleMode,
+    false);
+
+
+
+
diff --git a/gpu/src/GrGpuD3D9.cpp b/gpu/src/GrGpuD3D9.cpp
new file mode 100644
index 0000000..868097d
--- /dev/null
+++ b/gpu/src/GrGpuD3D9.cpp
@@ -0,0 +1,1484 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGpuD3D9.h"
+#include "GrGpuVertex.h"
+
+void d3dCheckErr(HRESULT hr) {
+    GrAssert(SUCCEEDED(hr));
+}
+
+#if GR_DEBUG
+    #define GR_D3D9(OBJ, X) d3dCheckErr(OBJ-> X);
+#else
+    #define GR_D3D9(OBJ, X) OBJ-> X;
+#endif
+
+#if GR_SCALAR_IS_FIXED
+    //mobile d3d allows 3 component fixed point verts
+    #error "fixed is unsupported in D3D9"
+#elif GR_SCALAR_IS_FLOAT
+    #define FVF_POS_TYPE D3DFVF_XYZ
+    #define FVF_TEX_TYPE (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(1))
+#else
+    #error "unknown GPU type"
+#endif
+
+#define FVF_COL_TYPE D3DFVF_DIFFUSE
+
+#if GR_TEXT_SCALAR_IS_FIXED
+    //mobile d3d allows 3 component fixed point verts
+    #error "fixed is unsupported in D3D9"
+#elif GR_TEXT_SCALAR_IS_FLOAT
+    #define FVF_POS_TYPE_TEXT D3DFVF_XYZ
+    #define FVF_TEX_TYPE_TEXT (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(1))
+#elif GR_TEXT_SCALAR_IS_USHORT
+    #error "positions must be float in fixed-pipe D3D9"
+#else
+    #error "unknown GPU text type"
+#endif
+
+static const int STAGE_NUM_VERTS = 512;
+static const int STAGE_VERTEX_SIZE = sizeof(GrPoint)*STAGE_NUM_VERTS;
+static const int STAGE_INDEX_SIZE  = 2*STAGE_NUM_VERTS*2*3; 
+                                  // 2 bytes per index * 
+                                  // 2 triangles per vert (euler char) * 3
+                                  // 3 indices/triangle
+
+static const D3DTRANSFORMSTATETYPE gMatrixMode2D3D9Matrix[] = {
+    D3DTS_WORLD,     // kModelView_MatrixMode
+    D3DTS_TEXTURE0,  // kTexture_MatrixMode
+};
+
+static const D3DPRIMITIVETYPE gPrimType2D3D9PrimType[] = {
+    D3DPT_TRIANGLELIST,
+    D3DPT_TRIANGLESTRIP,
+    D3DPT_TRIANGLEFAN,
+    D3DPT_POINTLIST,
+    D3DPT_LINELIST,
+    D3DPT_LINESTRIP,
+};
+
+const GrGpuD3D9::VertDecls GrGpuD3D9::gVertFlags2VertDeclIdx[] = {
+    kPosOnly_VertDecl,              // no flags
+    kTex_VertDecl,                  // kTexCoord_VertFlag
+    kColors_VertDecl,               // kColors_VertFlag
+    kTexAndColors_VertDecl,         // kColors_VertFlag & kColors_VertFlag
+    kInvalid_VertDecl,              // kPositionAsTexCoord_VertFlag
+    kPosAsTex_VertDecl,             // kPositionAsTexCoord_VertFlag & kTexCoord_VertFlag
+    kInvalid_VertDecl,              // kPositionAsTexCoord_VertFlag & kColors_VertFlag
+    kPosAsTexAndColors_VertDecl     // kPositionAsTexCoord_VertFlag & kTexCoord_VertFlag & kColors_VertFlag
+};
+
+const DWORD GrGpuD3D9::gDeclToFVFs[] = {
+    FVF_POS_TYPE, // kPosOnly_VertDecl
+    FVF_POS_TYPE | FVF_TEX_TYPE, // kTex_VertDecl
+    FVF_POS_TYPE | FVF_COL_TYPE, // kColors_VertDecl
+    FVF_POS_TYPE | FVF_TEX_TYPE | FVF_COL_TYPE, // kTexAndColors_VertDecl
+    FVF_POS_TYPE, // kPosAsTex_VertDecl
+    FVF_POS_TYPE | FVF_COL_TYPE, // kPosAsTexAndColors_VertDecl
+};
+
+const DWORD GrGpuD3D9::gTextFVF = FVF_POS_TYPE_TEXT | FVF_TEX_TYPE_TEXT;
+
+#if   (SK_A32_SHIFT == 24) && (SK_R32_SHIFT == 16) && \
+      (SK_G32_SHIFT == 8) && (SK_B32_SHIFT == 0)
+    #define GR_D3D9_32BPP_COLOR_FORMAT D3DFMT_A8R8G8B8
+#elif (SK_A32_SHIFT == 24) && (SK_B32_SHIFT == 16) && \
+      (SK_G32_SHIFT == 8) && (SK_R32_SHIFT == 0)
+    #define GR_D3D9_32BPP_COLOR_FORMAT D3DFMT_A8B8G8R8
+#else
+    #error "Skia's 32bit color format is not understood by D3D9."
+#endif
+
+static const DWORD gXfermodeCoeff2Blend[] = {
+    D3DBLEND_ZERO,
+    D3DBLEND_ONE,
+    D3DBLEND_SRCCOLOR,
+    D3DBLEND_INVSRCCOLOR,
+    D3DBLEND_DESTCOLOR,
+    D3DBLEND_INVDESTCOLOR,
+    D3DBLEND_SRCALPHA,
+    D3DBLEND_INVSRCALPHA,
+    D3DBLEND_DESTALPHA,
+    D3DBLEND_INVDESTALPHA,
+};
+
+static const DWORD gTileMode2D3D9Wrap[] = {
+    D3DTADDRESS_CLAMP,
+    D3DTADDRESS_WRAP,
+    D3DTADDRESS_MIRROR
+};
+
+static bool can_be_texture(GrTexture::PixelConfig config, D3DFORMAT* format) {
+    switch (config) {
+        case GrTexture::kRGBA_8888_PixelConfig:
+            *format = GR_D3D9_32BPP_COLOR_FORMAT;
+            break;
+        case GrTexture::kRGB_565_PixelConfig:
+            *format = D3DFMT_R5G6B5;
+            break;
+        case GrTexture::kRGBA_4444_PixelConfig:
+            *format = D3DFMT_A4R4G4B4;
+            break;
+        case GrTexture::kIndex_8_PixelConfig:
+            // we promote index to argb32
+            *format = GR_D3D9_32BPP_COLOR_FORMAT;
+            break;
+        case GrTexture::kAlpha_8_PixelConfig:
+            *format = D3DFMT_A8;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+
+static int format_bytes(D3DFORMAT format) {
+    switch (format) {
+        case GR_D3D9_32BPP_COLOR_FORMAT:
+            return 4;
+        case D3DFMT_R5G6B5:
+            return 2;
+        case D3DFMT_A4R4G4B4:
+            return 2;
+        case D3DFMT_A8:
+            return 1;
+        default:
+            GrAssert(!"Unexpected D3D format!");
+            return 0;
+    }
+}
+
+uint32_t vertex_to_primitive_count(GrGpu::PrimitiveTypes type, 
+                                   uint32_t vertexCount) {
+    switch (type) {
+        case GrGpu::kTriangles_PrimitiveType:
+            return vertexCount / 3;
+        case GrGpu::kTriangleStrip_PrimitiveType: // fallthru
+        case GrGpu::kTriangleFan_PrimitiveType:
+            return vertexCount > 2 ? vertexCount - 2 : 0;
+        case GrGpu::kPoints_PrimitiveType:
+            return vertexCount;
+        case GrGpu::kLines_PrimitiveType:
+            return vertexCount / 2;
+        case GrGpu::kLineStrip_PrimitiveType:
+            return vertexCount > 1 ? vertexCount - 1 : 0;
+        default:
+            GrAssert(!"Unknown primitive type!");
+            return 0;
+    }
+}
+
+void gr_matrix_to_d3d_matrix(D3DMATRIX* d3dmat, GrMatrix& grmat) {
+    d3dmat->_11 = grmat[GrMatrix::kScaleX];
+    d3dmat->_21 = grmat[GrMatrix::kSkewX];
+    d3dmat->_31 = 0;
+    d3dmat->_41 = grmat[GrMatrix::kTransX];
+
+    d3dmat->_12 = grmat[GrMatrix::kSkewY];
+    d3dmat->_22 = grmat[GrMatrix::kScaleY];
+    d3dmat->_32 = 0;
+    d3dmat->_42 = grmat[GrMatrix::kTransY];
+    
+    d3dmat->_13 = 0;
+    d3dmat->_23 = 0;
+    d3dmat->_33 = 1;
+    d3dmat->_43 = 0;
+
+    d3dmat->_14 = grmat[GrMatrix::kPersp0];
+    d3dmat->_24 = grmat[GrMatrix::kPersp1];
+    d3dmat->_34 = 0;
+    d3dmat->_44 = grmat[GrMatrix::kPersp2];
+}
+
+bool color_and_stencil_compatible(const D3DSURFACE_DESC& rtDesc, 
+                                  const D3DSURFACE_DESC& dsDesc) {
+    return (rtDesc.Width  <= dsDesc.Width)  &&
+           (rtDesc.Height <= dsDesc.Height) &&
+           (rtDesc.MultiSampleType == dsDesc.MultiSampleType) &&
+           (rtDesc.MultiSampleQuality == dsDesc.MultiSampleQuality);
+}
+
+int format_stencil_bits(D3DFORMAT format) {
+    switch (format) {
+    case D3DFMT_D24S8:
+    case D3DFMT_D24FS8:
+    case D3DFMT_S8_LOCKABLE:
+        return 8;
+    }
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrGpuD3D9::GrGpuD3D9(IDirect3DDevice9* device) : GrGpu(), fDevice(device) {
+    GrPrintf("----------------------- create GrGpuD3D9 %p --------------\n", this);
+
+    fDeviceEx = NULL;
+    fDevice->QueryInterface(__uuidof(::IDirect3DDevice9Ex), (void**)&fDeviceEx);
+
+    fLastBlendOff = false;
+    GR_D3D9(fDevice, SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE));
+
+    GR_D3D9(fDevice, SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_LIGHTING, FALSE));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_COLORVERTEX, TRUE));
+
+    fLastVertexState.fFlagBits = 0;
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_SELECTARG2));
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2));
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE));
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE));
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CONSTANT));
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CONSTANT));
+
+    fLastVertFVF = -1;
+
+    fLastColorArg1 = D3DTA_TEXTURE;
+
+    fLastDrawState.fSamplerState.fFilter = false;
+    GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT));
+    GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT));
+    GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE));
+
+    fNextDrawState.fSamplerState.fWrapX = (GrGpu::WrapModes)-1; // illegal
+    fNextDrawState.fSamplerState.fWrapY = (GrGpu::WrapModes)-1; // illegal
+
+    GR_D3D9(fDevice, SetPixelShader(NULL));
+    GR_D3D9(fDevice, SetVertexShader(NULL));
+
+    fLastDrawState.fFlagBits = 0;    
+    GR_D3D9(fDevice, SetRenderState(D3DRS_DITHERENABLE, FALSE));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE));
+
+    // illegal values
+    fLastDrawState.fSrcBlend = (BlendCoeff)-1;
+    fLastDrawState.fDstBlend = (BlendCoeff)-1;
+    fLastDrawState.fColor = GrColor_ILLEGAL;
+    fLastDrawState.fPointSize = fLastDrawState.fLineWidth = -1;
+    fLastDrawState.fTexture = NULL;
+    
+    GR_D3D9(fDevice,GetRenderTarget(0,&fDefaultRenderTarget.fColor));
+    fLastDrawState.fRenderTarget = (GrRenderTarget*) &fDefaultRenderTarget;
+    GrAssert(NULL != fDefaultRenderTarget.fColor);
+
+    // We need a stencil buffer to do path rendering.
+    D3DSURFACE_DESC rtDesc;
+    GR_D3D9(fDefaultRenderTarget.fColor, GetDesc(&rtDesc));
+    fDefaultRenderTarget.fStencil = NULL;
+    GR_D3D9(fDevice, GetDepthStencilSurface(&fDefaultRenderTarget.fStencil));
+    // make sure any existing depth stencil is compatible with the rendertarget
+    // and has at least 8 bits of stencil
+    if (NULL != fDefaultRenderTarget.fStencil) {
+        D3DSURFACE_DESC dsDesc;
+        GR_D3D9(fDefaultRenderTarget.fStencil, GetDesc(&dsDesc));
+        if (!color_and_stencil_compatible(rtDesc, dsDesc) ||
+            format_stencil_bits(dsDesc.Format) < 8) {
+            fDefaultRenderTarget.fStencil = NULL;
+        } else {
+            // add a ref so that we can safely Release in destructor
+            fDefaultRenderTarget.fStencil->AddRef();
+        }
+    }    
+    if (NULL == fDefaultRenderTarget.fStencil) {
+        fDefaultRenderTarget.fStencil = createStencil(rtDesc.Width, 
+                                                      rtDesc.Height,
+                                                      rtDesc.MultiSampleType,
+                                                      rtDesc.MultiSampleQuality);
+        GrAssert(NULL != fDefaultRenderTarget.fStencil);
+        GR_D3D9(fDevice, SetDepthStencilSurface(fDefaultRenderTarget.fStencil));
+    }
+
+    fLastDrawState.fScissorRect.setEmpty();
+    RECT rect;
+    rect.left = rect.right = rect.top = rect.bottom = 0;
+    GR_D3D9(fDevice,SetScissorRect(&rect));
+    
+    D3DMATRIX identity;
+    memset(&identity, 0, sizeof(identity));
+    identity._11 = identity._22 = identity._33 = identity._44 = 1.f;
+    for (int i = 0; i < kMatrixModeCount; i++) {
+        fLastDrawState.fMatrixModeCache[i].setIdentity();
+        GR_D3D9(fDevice, SetTransform(gMatrixMode2D3D9Matrix[i], &identity));
+    }
+    GR_D3D9(fDevice, 
+        SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2));
+    GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0));
+    fLastTexGen = false;
+
+    fLastDrawState.fViewportW = -1;
+    fLastDrawState.fViewportH = -1;
+
+    GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, FALSE));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILMASK, 0xffffffff));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff));
+    GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0xf));
+    fLastDrawState.fDrawMode = kOther_DrawMode;
+    fLastDrawState.fPathPass = (PathPass)-1;
+    fLastDrawState.fReverseFill = false;
+     
+    fNextDrawState = fLastDrawState;
+    fNextVertexState = fLastVertexState;
+
+    fLastIndexBuffer = NULL;
+
+    fStageVBuffer = (GrD3D9VertexBuffer*) 
+                        this->createVertexBuffer(STAGE_VERTEX_SIZE, true);
+    GrAssert(NULL != fStageVBuffer);
+
+    fStageIBuffer = (GrD3D9IndexBuffer*) 
+                        this->createIndexBuffer(STAGE_INDEX_SIZE, true);
+    GrAssert(NULL != fStageIBuffer);
+
+    TextureDesc dummyDesc = {
+        0, 
+        kNone_AALevel, 
+        1, 
+        1, 
+        false,
+        GrTexture::kAlpha_8_PixelConfig
+    };
+    fDummyTexture = (GrD3D9Texture*) this->createTexture(dummyDesc, NULL);
+    GrAssert(NULL != fDummyTexture);
+
+    fNPOTTextureSupport = kFull_NPOTTextureType;
+    D3DCAPS9 caps;
+    GR_D3D9(fDevice, GetDeviceCaps(&caps));
+    fSingleStencilPassForWinding = 
+        0 != (caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED);
+    GrAssert(D3DSTENCILOP_INVERT & caps.StencilCaps);
+    GrAssert(D3DSTENCILOP_INCR & caps.StencilCaps);
+    GrAssert(D3DSTENCILOP_DECR & caps.StencilCaps);
+    GrAssert(D3DSTENCILOP_ZERO & caps.StencilCaps);
+
+    // start off with all zeros, keep this after fNextDrawState assignment
+    eraseStencil();
+    fDefaultRenderTarget.fClearStencil = false;
+}
+
+GrGpuD3D9::~GrGpuD3D9() {
+    fStageVBuffer->unref();
+    fStageIBuffer->unref();
+    fDummyTexture->unref();
+    // Currently we are assuming that the default render target
+    // existed before our constructor was called. We don't ever create
+    // it and we never add a ref to it, so don't release.
+    // We do create a stencil buffer if needed, though.
+    fDefaultRenderTarget.fStencil->Release();
+}
+
+IDirect3DSurface9* GrGpuD3D9::createStencil(uint32_t width, 
+                                            uint32_t height,
+                                            D3DMULTISAMPLE_TYPE msType,
+                                            DWORD msQual) {
+    IDirect3DSurface9* dsSurface = NULL;
+    // Direct3D9 Ex adds a stencil only format.
+    if (NULL != fDeviceEx) {
+        GR_D3D9(fDeviceEx, CreateDepthStencilSurfaceEx(width, height,
+                                                       D3DFMT_S8_LOCKABLE, 
+                                                       msType, msQual, FALSE, 
+                                                       &dsSurface, NULL, 
+                                                       D3DUSAGE_DEPTHSTENCIL));
+        fDeviceEx->Release();
+    }
+    if (NULL == dsSurface) {
+        fDevice->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, msType, 
+                                           msQual, FALSE, &dsSurface, NULL);
+    }
+    return dsSurface;
+}
+
+GrTexture* GrGpuD3D9::createTexture(const TextureDesc& desc,
+                                    const void* srcData) {
+    D3DFORMAT d3dformat;
+    bool renderTarget = (desc.fFlags & kRenderTarget_TextureFlag);
+    if (desc.fAALevel != kNone_AALevel  && renderTarget) {
+        GrPrintf("Requested AA RT/Tex but not yet implemented in D3D.");
+    }
+    if (can_be_texture(desc.fFormat, &d3dformat)) {
+        DWORD usage = desc.fDynamic ? D3DUSAGE_DYNAMIC : 0;
+        usage |= renderTarget ? D3DUSAGE_RENDERTARGET : 0;
+        IDirect3DTexture9* d3dTex = NULL;
+    
+        GR_D3D9(fDevice, CreateTexture(desc.fWidth, desc.fHeight, 1, usage, 
+                                       d3dformat, D3DPOOL_DEFAULT, &d3dTex, 
+                                       NULL));
+
+        // In D3D9 the depth-stencil can be larger but not smaller than the RT
+        IDirect3DSurface9* depthStencil = NULL;
+        D3DSURFACE_DESC dsDesc;
+        fDefaultRenderTarget.fStencil->GetDesc(&dsDesc);        
+        // check if existing depth stencil is compatible
+        if ((renderTarget) && 
+                ((desc.fWidth > dsDesc.Width) || 
+                 (desc.fHeight > dsDesc.Height) ||
+                 (dsDesc.MultiSampleType != D3DMULTISAMPLE_NONE))) {
+            depthStencil = createStencil(desc.fWidth, desc.fHeight, 
+                                         D3DMULTISAMPLE_NONE, 0);
+            GrAssert(NULL != depthStencil);
+        }
+        if (d3dTex) {
+            GrD3D9Texture* texture = new GrD3D9Texture(desc.fWidth, 
+                                                       desc.fHeight, 
+                                                       desc.fFormat,
+                                                       d3dTex, 
+                                                       depthStencil,
+                                                       true,
+                                                       this);
+            if (NULL != srcData) {
+                texture->uploadTextureData(0, 0, desc.fWidth, 
+                                           desc.fHeight, srcData);
+            }
+            return texture;
+        }
+    }
+    return NULL;
+}
+
+GrVertexBuffer* GrGpuD3D9::createVertexBuffer(uint32_t size, bool dynamic) {
+    DWORD usage = (dynamic & kRenderTarget_TextureFlag) ? D3DUSAGE_DYNAMIC : 0;
+    usage |= D3DUSAGE_WRITEONLY;
+    IDirect3DVertexBuffer9* vbuffer = NULL;
+    GR_D3D9(fDevice, CreateVertexBuffer(size, usage, 0, 
+                                        D3DPOOL_DEFAULT, &vbuffer, NULL));
+    if (vbuffer) {
+        return new GrD3D9VertexBuffer(size, dynamic, vbuffer, this);
+    }
+    return NULL;
+}
+
+GrIndexBuffer* GrGpuD3D9::createIndexBuffer(uint32_t size, bool dynamic) {
+    DWORD usage = (dynamic & kRenderTarget_TextureFlag) ? D3DUSAGE_DYNAMIC : 0;
+    usage |= D3DUSAGE_WRITEONLY;
+    IDirect3DIndexBuffer9* ibuffer = NULL;
+    GR_D3D9(fDevice, CreateIndexBuffer(size, usage, D3DFMT_INDEX16, 
+                                       D3DPOOL_DEFAULT, &ibuffer, NULL));
+    if (ibuffer) {
+        return new GrD3D9IndexBuffer(size, dynamic, ibuffer, this);
+    }
+    return NULL;
+}
+
+bool GrGpuD3D9::flushGraphicsState(PrimitiveTypes type) {
+    GrAssert(fNextDrawState.fViewportW != -1);
+
+    if (fNextDrawState.fDrawMode == kRadialTexture_DrawMode ||
+        fNextDrawState.fDrawMode == kSweepTexture_DrawMode ||
+        fNextDrawState.fDrawMode == kTwoPointRadialTexture_DrawMode) {
+        unimpl("Fixed pipe doesn't support radial/sweep gradient");
+        return false;
+    }
+
+    uint32_t stateDiff = fNextDrawState.fFlagBits ^ fLastDrawState.fFlagBits;
+
+    if (fLastDrawState.fRenderTarget != fNextDrawState.fRenderTarget) {
+        setRenderTargetImm();
+        GrD3D9RenderTarget& rt = *(GrD3D9RenderTarget*)fNextDrawState.fRenderTarget;
+        if (rt.fClearStencil) {
+            eraseStencil();
+            rt.fClearStencil = false;
+        }
+        // may need to change how AA is handled.
+        stateDiff |= (1 << kAntialias_StateFlag);
+    }
+
+    if (stateDiff)
+    {
+        if (stateDiff & (1<<kDither_StateFlag)) {
+            GR_D3D9(fDevice,SetRenderState(D3DRS_DITHERENABLE, 
+                    (fNextDrawState.fFlagBits & (1<<kDither_StateFlag)) ? 
+                        TRUE : 
+                        FALSE));
+        }
+        if (stateDiff & (1<<kAntialias_StateFlag)) {
+            DWORD aa = fNextDrawState.fFlagBits & (1<<kAntialias_StateFlag) ? 
+                                TRUE : FALSE;
+            GrD3D9RenderTarget& rt = *(GrD3D9RenderTarget*)fNextDrawState.fRenderTarget;
+            D3DSURFACE_DESC desc;
+            rt.fColor->GetDesc(&desc);
+            if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, aa));
+            } else {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, aa));
+            }
+        }
+        fLastDrawState.fFlagBits = fNextDrawState.fFlagBits;
+    }
+    bool blendOff = canDisableBlend();
+    if (fLastBlendOff != blendOff) {
+        GR_D3D9(fDevice, SetRenderState(D3DRS_ALPHABLENDENABLE, 
+                         blendOff ? FALSE : TRUE));
+        fLastBlendOff = blendOff;
+    }
+    if (!blendOff) {
+        if (fLastDrawState.fSrcBlend != fNextDrawState.fSrcBlend) {
+            GR_D3D9(fDevice, SetRenderState(D3DRS_SRCBLEND, 
+                                 gXfermodeCoeff2Blend[fNextDrawState.fSrcBlend]));
+            fLastDrawState.fSrcBlend = fNextDrawState.fSrcBlend;
+        }
+        if (fLastDrawState.fDstBlend != fNextDrawState.fDstBlend) {
+            GR_D3D9(fDevice, SetRenderState(D3DRS_DESTBLEND, 
+                                gXfermodeCoeff2Blend[fNextDrawState.fDstBlend]));
+            fLastDrawState.fDstBlend = fNextDrawState.fDstBlend;
+        }
+    }
+
+    // bind texture and set sampler state
+    if (fNextVertexState.fFlagBits & (1 << kTexCoord_VertFlag)) {
+        GrD3D9Texture* nextTexture = (GrD3D9Texture*)fNextDrawState.fTexture;
+        if (NULL != nextTexture) {
+            if (fLastDrawState.fTexture != nextTexture) {
+                GR_D3D9(fDevice, SetTexture(0, nextTexture->texture()));
+                DWORD nextColorArg1 = nextTexture->format() == D3DFMT_A8 ?
+                                    (D3DTA_TEXTURE | D3DTA_ALPHAREPLICATE) :
+                                    D3DTA_TEXTURE;                        
+                if (fLastColorArg1 != nextColorArg1) {                    
+                    GR_D3D9(fDevice, SetTextureStageState(0, 
+                                                          D3DTSS_COLORARG1, 
+                                                          nextColorArg1));
+                    fLastColorArg1 = nextColorArg1;
+                }
+                fLastDrawState.fTexture = nextTexture;
+            }
+
+            if (fLastDrawState.fSamplerState.fFilter != 
+                    fNextDrawState.fSamplerState.fFilter) {
+                DWORD filter = fNextDrawState.fSamplerState.fFilter ?
+                                                       D3DTEXF_LINEAR :
+                                                       D3DTEXF_POINT;
+                GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_MAGFILTER, filter));
+                GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_MINFILTER, filter));
+                fLastDrawState.fSamplerState.fFilter = 
+                    fNextDrawState.fSamplerState.fFilter;
+            }
+            if (fLastDrawState.fSamplerState.fWrapX != 
+                    fNextDrawState.fSamplerState.fWrapX) {
+                GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_ADDRESSU, 
+                    gTileMode2D3D9Wrap[fNextDrawState.fSamplerState.fWrapX]));
+                fLastDrawState.fSamplerState.fWrapX = 
+                    fNextDrawState.fSamplerState.fWrapX;
+            }
+            if (fLastDrawState.fSamplerState.fWrapY != 
+                    fNextDrawState.fSamplerState.fWrapY) {
+                GR_D3D9(fDevice, SetSamplerState(0, D3DSAMP_ADDRESSV, 
+                    gTileMode2D3D9Wrap[fNextDrawState.fSamplerState.fWrapY]));
+                fLastDrawState.fSamplerState.fWrapY = 
+                    fNextDrawState.fSamplerState.fWrapY;
+            }
+        } else {
+            GrAssert(!"Rendering with texture vert flag set but no bound texture");
+            if (NULL != fLastDrawState.fTexture) {            
+                GR_D3D9(fDevice,SetTexture(0, NULL));
+    //            GrPrintf("---- bindtexture 0\n");
+                fLastDrawState.fTexture = NULL;
+            }
+        }
+    }
+
+    // check for circular rendering
+    GrAssert(!(fNextVertexState.fFlagBits & (1 << kTexCoord_VertFlag)) ||
+             NULL == fNextDrawState.fRenderTarget || 
+             NULL == fNextDrawState.fTexture ||
+             fNextDrawState.fTexture->asRenderTarget() != fNextDrawState.fRenderTarget);
+
+    if ((type == GrGpu::kLineStrip_PrimitiveType ||
+         type == GrGpu::kLines_PrimitiveType) &&
+        fLastDrawState.fLineWidth != fNextDrawState.fLineWidth) {
+        // D3D9 doesn't support wide lines!
+        //GrAssert(fNextDrawState.fLineWidth == 1);
+    }
+
+    bool stencilChange = 
+                fLastDrawState.fPathPass != fNextDrawState.fPathPass ||
+                (kNone_PathPass != fNextDrawState.fPathPass &&
+                 fLastDrawState.fReverseFill != fNextDrawState.fReverseFill);
+                        
+    if (stencilChange) {
+        switch (fNextDrawState.fPathPass) {
+        case kNone_PathPass:
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, FALSE));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0xf));
+            if (!fSingleStencilPassForWinding) {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
+            }
+            break;
+        case kEvenOddStencil_PathPass:
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, TRUE));
+            if (fSingleStencilPassForWinding) {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE));
+            } else {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
+            }
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_INVERT));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INVERT));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INVERT));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0x0));
+            break;
+        case kEvenOddColor_PathPass:
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, TRUE));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILREF, 0xffffffff));
+            if (fSingleStencilPassForWinding) {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE));
+            } else {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
+            }
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFUNC, 
+                fNextDrawState.fReverseFill ? D3DCMP_NOTEQUAL : D3DCMP_EQUAL));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_ZERO));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_ZERO));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_ZERO));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0xf));
+            break;
+        case kWindingStencil1_PathPass:
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, TRUE));
+            if (fSingleStencilPassForWinding) {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE));
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS));
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_DECR));
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_DECR));
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR));
+            } else {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_CW));
+            }
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS));            
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_INCR));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0x0));
+            break;
+        case kWindingStencil2_PathPass:
+            GrAssert(!fSingleStencilPassForWinding);
+            GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, TRUE));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS));            
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_DECR));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0x0));
+            break;
+        case kWindingColor_PathPass:
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILENABLE, TRUE));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILREF, 0x00000000));
+            if (fSingleStencilPassForWinding) {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE));
+            } else {
+                GR_D3D9(fDevice, SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE));
+            }
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFUNC, 
+                    fNextDrawState.fReverseFill ? D3DCMP_EQUAL : D3DCMP_NOTEQUAL));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_ZERO));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_ZERO));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_ZERO));
+            GR_D3D9(fDevice, SetRenderState(D3DRS_COLORWRITEENABLE, 0xf));
+            break;
+        default:
+            GrAssert(!"Unexpected path pass.");
+            break;
+        }
+        fLastDrawState.fPathPass = fNextDrawState.fPathPass;
+        fLastDrawState.fReverseFill = fNextDrawState.fReverseFill;
+    }
+    fLastDrawState.fDrawMode    = fNextDrawState.fDrawMode;
+    
+    //////////////////////////////////////////////////////////////////////////
+    // Fixed pipe stuff
+
+    DWORD vertFVF = (fNextDrawState.fDrawMode == kTextGlyphs_DrawMode) ? 
+                gTextFVF :
+                gDeclToFVFs[gVertFlags2VertDeclIdx[fNextVertexState.fFlagBits]];
+    GrAssert(-1 != vertFVF);
+    if (fLastVertFVF != vertFVF) {
+        GR_D3D9(fDevice, SetFVF(vertFVF));
+        fLastVertFVF = vertFVF;
+    }
+
+    // this has to stay after the set render target because
+    // setrendertarget resets the viewport
+    if (fLastDrawState.fViewportW != fNextDrawState.fViewportW ||
+        fLastDrawState.fViewportH != fNextDrawState.fViewportH) {
+        D3DVIEWPORT9 vp;
+        vp.X = vp.Y = 0;
+        vp.MinZ = 0; vp.MaxZ = 1;
+        vp.Width  = fNextDrawState.fViewportW;
+        vp.Height = fNextDrawState.fViewportH;
+        GR_D3D9(fDevice, SetViewport(&vp));
+        
+        D3DMATRIX mat;
+        sk_bzero(&mat, sizeof(mat));
+    
+        float invW = 1.f / fNextDrawState.fViewportW;
+        float invH = 1.f / fNextDrawState.fViewportH;
+
+        mat._11 = 2.f * invW;
+        mat._22 = -2.f * invH;
+        //mat._33 = -1.f;
+        mat._33 = 1.f;
+        mat._44 = 1;
+    
+        // included here is 1/2 pixel adjustment because
+        // d3d9 puts pixel *centers* at integer offset in viewport space.
+        mat._41 = -1.f - invW;
+        mat._42 = 1.f + invH;
+
+        GR_D3D9(fDevice, SetTransform(D3DTS_PROJECTION, &mat));
+
+        fLastDrawState.fViewportW = fNextDrawState.fViewportW;
+        fLastDrawState.fViewportH = fNextDrawState.fViewportH;
+    }
+
+    uint32_t vertDiff = fNextVertexState.fFlagBits ^ fLastVertexState.fFlagBits;
+
+    if (vertDiff) {
+        if (vertDiff & (1 << kTexCoord_VertFlag)) {            
+            if (fNextVertexState.fFlagBits & (1 << kTexCoord_VertFlag)) {
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLOROP, 
+                                                      D3DTOP_MODULATE));
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAOP, 
+                                                      D3DTOP_MODULATE));
+            } else {
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLOROP, 
+                                                      D3DTOP_SELECTARG2));
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAOP, 
+                                                      D3DTOP_SELECTARG2));
+            }
+        }
+        if (vertDiff & (1 << kColors_VertFlag)) {
+            if (fNextVertexState.fFlagBits & (1 << kColors_VertFlag)) {
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLORARG2,
+                                                      D3DTA_CURRENT));
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAARG2, 
+                                                      D3DTA_CURRENT));
+            } else {
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_COLORARG2, 
+                                                      D3DTA_CONSTANT));
+                GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_ALPHAARG2, 
+                                                      D3DTA_CONSTANT));                
+            }
+        }
+        fLastVertexState.fFlagBits = fNextVertexState.fFlagBits;
+    }
+ 
+    if (fLastDrawState.fTexture != fDummyTexture &&
+        !(fNextVertexState.fFlagBits & ((1 << kColors_VertFlag) || 
+                                     (1 << kColors_VertFlag)))) {
+        GR_D3D9(fDevice, SetTexture(0, fDummyTexture->texture()));
+        fLastDrawState.fTexture = fDummyTexture;
+    }
+
+    if (fLastDrawState.fPointSize != fNextDrawState.fPointSize) {
+        GR_D3D9(fDevice,SetRenderState(D3DRS_POINTSIZE, 
+                                       *(DWORD*)&fNextDrawState.fPointSize));
+        fLastDrawState.fPointSize = fNextDrawState.fPointSize;
+    }
+    
+    if (!(fNextVertexState.fFlagBits & (1 << kColors_VertFlag)) &&
+        fLastDrawState.fColor != fNextDrawState.fColor) {
+        GR_D3D9(fDevice, SetTextureStageState(0, D3DTSS_CONSTANT, 
+                                              fNextDrawState.fColor));
+        fLastDrawState.fColor = fNextDrawState.fColor;
+    }
+    bool mvChanged = fLastDrawState.fMatrixModeCache[kModelView_MatrixMode] != 
+                     fNextDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    if (mvChanged) {
+        D3DMATRIX mat;
+        gr_matrix_to_d3d_matrix(&mat, 
+            fNextDrawState.fMatrixModeCache[kModelView_MatrixMode]);
+        GR_D3D9(fDevice, SetTransform(
+            gMatrixMode2D3D9Matrix[kModelView_MatrixMode], &mat));
+        fLastDrawState.fMatrixModeCache[kModelView_MatrixMode] = 
+            fNextDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    }
+
+    // Since fixed-pipe FVF doesn't allow using positions
+    // as tex coords like vertex decls do in for shaders, we
+    // use tex gen
+    // D3D9 tex coord gen uses the camera space vertex pos as the 
+    // texture coordinates. We want to use the worldspace pos so
+    // we invert the view matrix as part of the texture matrix.
+    if ((fNextVertexState.fFlagBits & (1 << kTexCoord_VertFlag))) {
+        bool texGen = 0 != (fNextVertexState.fFlagBits & 
+                      (1 << kPositionAsTexCoord_VertFlag));
+
+        bool texGenChange = fLastTexGen != texGen;
+
+        if (fLastDrawState.fMatrixModeCache[kTexture_MatrixMode] != 
+            fNextDrawState.fMatrixModeCache[kTexture_MatrixMode] || 
+            texGenChange ||
+            (texGen && mvChanged)) {
+            GrMatrix* m;
+            GrMatrix temp;
+            D3DMATRIX d3dMat;
+            if (texGen) {
+                fNextDrawState.fMatrixModeCache[kModelView_MatrixMode].
+                    invert(&temp);
+                temp.postConcat(fNextDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+                m =  &temp;
+            } else {
+                m = &fNextDrawState.fMatrixModeCache[kTexture_MatrixMode];
+            }
+
+            gr_matrix_to_d3d_matrix(&d3dMat, *m);
+            GR_D3D9(fDevice, SetTransform(
+                gMatrixMode2D3D9Matrix[kTexture_MatrixMode], &d3dMat));
+            fLastDrawState.fMatrixModeCache[kTexture_MatrixMode] = 
+                fNextDrawState.fMatrixModeCache[kTexture_MatrixMode];
+            if (texGenChange) {
+                GR_D3D9(fDevice, SetTextureStageState(0, 
+                            D3DTSS_TEXCOORDINDEX,
+                            texGen ? D3DTSS_TCI_CAMERASPACEPOSITION : 0));
+            }
+            fLastTexGen = texGen;
+        }
+    }
+    return true;
+}
+
+void GrGpuD3D9::flushScissor() {
+    if (fLastDrawState.fScissorRect != fNextDrawState.fScissorRect) {
+        RECT rect;
+        rect.left = fNextDrawState.fScissorRect.fLeft;
+        rect.right = fNextDrawState.fScissorRect.fRight;
+        rect.top = fNextDrawState.fScissorRect.fTop;
+        rect.bottom = fNextDrawState.fScissorRect.fBottom;
+    
+        GR_D3D9(fDevice, SetScissorRect(&rect));
+        fLastDrawState.fScissorRect != fNextDrawState.fScissorRect;
+    }
+
+}
+
+void GrGpuD3D9::eraseColor(GrColor color) {
+    
+    DWORD clr = D3DCLEAR_TARGET;
+
+    if (fLastDrawState.fRenderTarget != fNextDrawState.fRenderTarget) {
+        setRenderTargetImm();
+        // In D3D9 setting the render target resets the viewport
+        fLastDrawState.fViewportH = -1;
+        GrD3D9RenderTarget& rt = *(GrD3D9RenderTarget*)fNextDrawState.fRenderTarget;
+        if ((NULL != rt.fStencil) && rt.fClearStencil) {
+            clr |= D3DCLEAR_STENCIL;
+        }
+    }
+
+    D3DCOLOR d3dColor = D3DCOLOR_ARGB(GrColorUnpackA(color),
+                                      GrColorUnpackR(color),
+                                      GrColorUnpackG(color),
+                                      GrColorUnpackB(color));
+     
+    // we enable the scissor in the preamble and flush 
+    // assumes it is always enabled
+    GR_D3D9(fDevice, SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE));
+    GR_D3D9(fDevice, Clear(0, NULL, clr, d3dColor, 0.f, 0x0));    
+    GR_D3D9(fDevice, SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE));
+}
+
+void GrGpuD3D9::eraseStencil() {
+    if (fLastDrawState.fRenderTarget != fNextDrawState.fRenderTarget) {
+        setRenderTargetImm();
+        // In D3D9 setting the render target resets the viewport
+        fLastDrawState.fViewportH = -1;
+    }
+
+    // we enable the scissor in the preamble and flush 
+    // assumes it is always enabled
+    GR_D3D9(fDevice, SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE));
+    GR_D3D9(fDevice,Clear(0, NULL, D3DCLEAR_STENCIL, 0x0, 0.f, 0x0));    
+    GR_D3D9(fDevice, SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE));
+}
+
+GrD3D9VertexBuffer* GrGpuD3D9::setupVBufferStage(int vsize,
+                                                 int* baseVertex,
+                                                 int vertexCount,
+                                                 DrawModes mode) {
+    GrD3D9VertexBuffer*vbuf;
+    if (vsize*(vertexCount) > STAGE_VERTEX_SIZE) {
+        GrPrintf("Staging vertex buffer is too small!");
+        vbuf = (GrD3D9VertexBuffer*) createVertexBuffer(vsize*vertexCount, true);
+        if (NULL == vbuf) {
+            GrAssert(!"Temporary vertex buffer failed!");
+            return NULL;
+        }
+    } else {
+        vbuf = fStageVBuffer;
+        // add a reference so that caller can unref without deleting
+        vbuf->ref();
+    }
+    void* vptr = vbuf->lock();
+    if (NULL == vptr) {
+        GrAssert(!"Locking staging/temp vbuffer failed!");
+        vbuf->unref();
+        return NULL;
+    }
+    vptr = (char*) vptr;
+    
+    if (mode == kTextGlyphs_DrawMode) {
+        GrAssert((fNextVertexState.fFlagBits & (1 << kTexCoord_VertFlag)) &&
+                    !(fNextVertexState.fFlagBits & (1 << kColors_VertFlag)) &&
+                    !(fNextVertexState.fFlagBits & 
+                                      (1 << kPositionAsTexCoord_VertFlag)));
+        GrAssert(sizeof(GrGpuTextVertex) == 2*sizeof(float));
+        for (int i = 0; i < vertexCount; ++i) {
+            GrGpuTextVertex* posxy = (GrGpuTextVertex*)((char*)vptr + i*vsize);
+            float* posz  = (float*)posxy + 2;
+            GrGpuTextVertex* tex = (GrGpuTextVertex*)(posz+1);
+            *posxy = *((GrGpuTextVertex*)fNextVertexState.fArrays.positions + i + *baseVertex);
+            *posz = .5;
+            *tex = *((GrGpuTextVertex*)fNextVertexState.fArrays.texCoords + i + *baseVertex);
+        }
+    } else {
+        switch (fNextVertexState.fFlagBits) {
+            GrAssert(sizeof(GrPoint) == 2*sizeof(float));
+            case 0: // position only
+            case (1 << kTexCoord_VertFlag) | 
+                 (1 << kPositionAsTexCoord_VertFlag): 
+                for (int i = 0; i < vertexCount; ++i) {
+                    GrPoint* posxy = (GrPoint*)((char*)vptr + i*vsize);
+                    float* posz = (float*)(posxy + 1);
+                    *posxy = *((GrPoint*)fNextVertexState.fArrays.positions + i + *baseVertex);
+                    *posz = .5;
+                }
+                break;
+            case (1 << kTexCoord_VertFlag):
+                for (int i = 0; i < vertexCount; ++i) {
+                    GrPoint* posxy = (GrPoint*)((char*)vptr + i*vsize);
+                    float* posz = (float*)(posxy + 1);
+                    GrPoint* tex = (GrPoint*)(posz + 1);
+                    *posxy = *((GrPoint*)fNextVertexState.fArrays.positions + i + *baseVertex);
+                    *posz = .5;
+                    *tex = *((GrPoint*)fNextVertexState.fArrays.texCoords + i + *baseVertex);
+                }
+                break;
+            case (1 << kColors_VertFlag):
+            case (1 << kTexCoord_VertFlag) |
+                 (1 << kPositionAsTexCoord_VertFlag) |
+                 (1 << kColors_VertFlag):
+                for (int i = 0; i < vertexCount; ++i) {
+                    GrPoint* posxy = (GrPoint*)((char*)vptr + i*vsize);
+                    float* posz = (float*)(posxy + 1);
+                    uint32_t* col = (uint32_t*)(posz + 1);
+                    *posxy = *((GrPoint*)fNextVertexState.fArrays.positions + i + *baseVertex);
+                    *posz = .5;
+                    *col =  *((uint32_t*)fNextVertexState.fArrays.colors + i + *baseVertex);
+                }
+                break;
+            case (1 << kTexCoord_VertFlag) | (1 << kColors_VertFlag):
+                for (int i = 0; i < vertexCount; ++i) {
+                    GrPoint* posxy = (GrPoint*)((char*)vptr + i*vsize);
+                    float* posz = (float*)posxy + 2;
+                    uint32_t* col = (uint32_t*)(posz + 1);
+                    GrPoint* tex = (GrPoint*)(col + 1);
+                    *posxy = *((GrPoint*)fNextVertexState.fArrays.positions + i + *baseVertex);
+                    *posz = .5;
+                    *col =  *((uint32_t*)fNextVertexState.fArrays.colors + i + *baseVertex);
+                    *tex = *((GrPoint*)fNextVertexState.fArrays.texCoords + i + *baseVertex);
+                }
+                break;
+            default:
+                GrAssert(!"Unexpected vertex flags!");
+        }
+    }
+    *baseVertex = 0;
+    vbuf->unlock();
+    return vbuf;
+}
+
+void GrGpuD3D9::setRenderTargetImm() {
+    GrD3D9RenderTarget& rt = *(GrD3D9RenderTarget*)fNextDrawState.fRenderTarget;
+    GrAssert(NULL != rt.fColor);
+    GR_D3D9(fDevice, SetRenderTarget(0, 
+            (IDirect3DSurface9*) rt.fColor));
+    if (NULL != rt.fStencil) {
+        GR_D3D9(fDevice, SetDepthStencilSurface(rt.fStencil));
+    } else {
+        GrAssert(NULL != fDefaultRenderTarget.fStencil);
+        GR_DEBUGCODE(D3DSURFACE_DESC rtDesc;)
+        GR_DEBUGCODE(D3DSURFACE_DESC dsDesc;)
+        GR_DEBUGCODE(GR_D3D9(rt.fColor,       GetDesc(&rtDesc));)
+        GR_DEBUGCODE(GR_D3D9(fDefaultRenderTarget.fStencil, \
+                        GetDesc(&dsDesc));)
+        GR_DEBUGCODE(GrAssert(color_and_stencil_compatible(rtDesc, 
+                                                            dsDesc));)
+        GR_D3D9(fDevice, 
+            SetDepthStencilSurface(fDefaultRenderTarget.fStencil));        
+    }
+    fLastDrawState.fRenderTarget = fNextDrawState.fRenderTarget;
+}
+
+GrD3D9IndexBuffer* GrGpuD3D9::setupIBufferStage(int* startIndex, int indexCount,
+                                                const uint16_t* indices) {
+    GrD3D9IndexBuffer* ibuf;
+    if (indexCount*2 > STAGE_INDEX_SIZE) {
+        GrPrintf("Staging index buffer is too small!");
+        ibuf = (GrD3D9IndexBuffer*) createIndexBuffer(indexCount*2, true);
+        if (NULL == ibuf) {
+            GrAssert(!"Temporary index buffer is too small!");
+            return NULL;
+        }
+    } else {
+        ibuf = fStageIBuffer;
+        // add a reference so that caller can unref without deleting
+        ibuf->ref();
+    }
+    void* iptr = ibuf->lock();
+    if (NULL == iptr) {
+        GrAssert(!"Locking staging/temp ibuffer failed!");
+        ibuf->unref();
+        return NULL;
+    }
+    memcpy(iptr, indices + *startIndex, 2*indexCount);
+    *startIndex = 0;
+    ibuf->unlock();
+    return ibuf;
+}
+
+int GrGpuD3D9::vertexSize(int vertFlagBits, GrGpu::DrawModes mode) {
+    if (mode == kTextGlyphs_DrawMode) {
+        return 5*sizeof(float);
+    } else {
+        switch (vertFlagBits) {
+            case 0: // position only
+            case (1 << kTexCoord_VertFlag) | 
+                 (1 << kPositionAsTexCoord_VertFlag):
+                return 3*sizeof(float);
+            case (1 << kTexCoord_VertFlag):
+                return 5*sizeof(float);
+            case (1 << kColors_VertFlag):
+            case (1 << kTexCoord_VertFlag) | 
+                 (1 << kPositionAsTexCoord_VertFlag) | 
+                 (1 << kColors_VertFlag):
+                return 3*sizeof(float) + 4;
+            case (1 << kTexCoord_VertFlag) | (1 << kColors_VertFlag):
+                return 5*sizeof(float) + 4;
+            default:
+                GrAssert(!"Unexpected vertex flags!");
+                return 0;
+        }
+    }
+}
+
+void GrGpuD3D9::drawIndexArrayApi(PrimitiveTypes type,
+                                  int baseVertex,
+                                  int vertexCount,
+                                  int indexCount,
+                                  const uint16_t* indexArray,
+                                  bool redrawHint) {
+    int vsize = vertexSize(fNextVertexState.fFlagBits, fNextDrawState.fDrawMode);
+
+    GrD3D9VertexBuffer* vbuf;
+    if (fNextVertexState.fUsingBuffer) {
+        vbuf = (GrD3D9VertexBuffer*) fNextVertexState.fBuffer;
+    } else {
+        vbuf = setupVBufferStage(vsize, &baseVertex, vertexCount,
+                                 fNextDrawState.fDrawMode);
+        if (NULL == vbuf) {
+            return;
+        }
+    }
+    int startIndex = 0;
+    GrD3D9IndexBuffer* ibuf = 
+                    setupIBufferStage(&startIndex, indexCount, indexArray);    
+    if (NULL == ibuf) {
+        vbuf->unref();
+    }
+
+    GR_D3D9(fDevice,SetStreamSource(0, vbuf->buffer(), 0, vsize));
+    GR_D3D9(fDevice,SetIndices(ibuf->buffer()));
+    GR_D3D9(fDevice,DrawIndexedPrimitive(gPrimType2D3D9PrimType[type], 
+                                            baseVertex, 0, vertexCount, startIndex,
+                                            vertex_to_primitive_count(type,
+                                                            indexCount)));
+    vbuf->unref();
+    ibuf->unref();
+}
+
+void GrGpuD3D9::drawIndexBufferApi(PrimitiveTypes type,
+                                   int baseVertex,
+                                   int startIndex,
+                                   int vertexCount,
+                                   int indexCount,                                   
+                                   GrIndexBuffer* indexBuffer,
+                                   bool redrawHint) {
+    int vsize = vertexSize(fNextVertexState.fFlagBits, fNextDrawState.fDrawMode);
+    GrD3D9VertexBuffer* vbuf;
+    bool unrefVBuf = false;
+    if (fNextVertexState.fUsingBuffer) {
+        vbuf = (GrD3D9VertexBuffer*) fNextVertexState.fBuffer;
+    } else {
+        vbuf = setupVBufferStage(vsize, &baseVertex, vertexCount, 
+                                 fNextDrawState.fDrawMode);
+        if (NULL == vbuf) {
+            return;
+        }
+    }
+    GR_D3D9(fDevice,SetStreamSource(0, vbuf->buffer(), 0, vsize));
+    GR_D3D9(fDevice,SetIndices(((GrD3D9IndexBuffer*)indexBuffer)->buffer()));
+    GR_D3D9(fDevice,DrawIndexedPrimitive(gPrimType2D3D9PrimType[type], 
+                                         baseVertex, 0, vertexCount, startIndex,
+                                         vertex_to_primitive_count(type, 
+                                                                  indexCount)));
+    vbuf->unref();
+}
+
+void GrGpuD3D9::drawNonIndexedApi(PrimitiveTypes type,
+                                  int baseVertex,
+                                  int vertexCount,
+                                  bool redrawHint) {
+    
+    int vsize = vertexSize(fNextVertexState.fFlagBits, fNextDrawState.fDrawMode);
+    GrD3D9VertexBuffer* vbuf;
+
+    if (fNextVertexState.fUsingBuffer) {
+        vbuf = (GrD3D9VertexBuffer*) fNextVertexState.fBuffer;
+    } else {
+        vbuf = setupVBufferStage(vsize, &baseVertex, vertexCount, 
+                                 fNextDrawState.fDrawMode);
+    }
+    GR_D3D9(fDevice,SetStreamSource(0, vbuf->buffer(), 0, vsize));
+    GR_D3D9(fDevice,DrawPrimitive(gPrimType2D3D9PrimType[type], baseVertex, 
+                                 vertex_to_primitive_count(type, vertexCount)));
+    vbuf->unref();
+}
+
+void GrGpuD3D9::notifyVertexBufferBind(GrD3D9VertexBuffer* buffer) {
+}
+
+void GrGpuD3D9::notifyVertexBufferDelete(GrD3D9VertexBuffer* buffer) {
+    if (fNextVertexState.fUsingBuffer && fNextVertexState.fBuffer == buffer) {
+        fNextVertexState.fBuffer = NULL;
+    }
+}
+
+void GrGpuD3D9::notifyIndexBufferBind(GrD3D9IndexBuffer* buffer) {
+}
+
+void GrGpuD3D9::notifyIndexBufferDelete(GrD3D9IndexBuffer* buffer) {
+    if (fLastIndexBuffer == buffer) {
+        fLastIndexBuffer = NULL;
+    }
+}
+
+void GrGpuD3D9::notifyTextureDelete(GrD3D9Texture* texture) {
+    if (fNextDrawState.fTexture == texture ||
+        fLastDrawState.fTexture == texture) {
+        fNextDrawState.fTexture = NULL;
+        fLastDrawState.fTexture = NULL;
+        GR_D3D9(fDevice, SetTexture(0, NULL));
+    }
+    if (fNextDrawState.fRenderTarget == texture->asRenderTarget() || 
+        fLastDrawState.fRenderTarget == texture->asRenderTarget()) {        
+        fNextDrawState.fRenderTarget = (GrRenderTarget*) &fDefaultRenderTarget;
+        setRenderTargetImm();
+    }
+}
+
+void GrGpuD3D9::notifyTextureRemoveRenderTarget(GrD3D9Texture* texture) {
+    if (fNextDrawState.fRenderTarget == texture->asRenderTarget() || 
+        fLastDrawState.fRenderTarget == texture->asRenderTarget()) {        
+        fNextDrawState.fRenderTarget = (GrRenderTarget*) &fDefaultRenderTarget;
+        setRenderTargetImm();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrD3D9Texture::GrD3D9Texture(uint32_t width, 
+                             uint32_t height,
+                             GrTexture::PixelConfig config,
+                             IDirect3DTexture9* texture,
+                             IDirect3DSurface9* stencil,
+                             bool clearStencil,
+                             GrGpuD3D9* gpuD3D9) : 
+        INHERITED(width, height, width, height, config),
+        fTexture(texture),
+        fStencil(stencil),
+        fGpuD3D9(gpuD3D9) {    
+    GrAssert(NULL != fTexture);
+    fTexture->GetLevelDesc(0, &fDesc);
+    
+    if (fDesc.Usage & D3DUSAGE_RENDERTARGET) {
+        BOOL result = fTexture->GetSurfaceLevel(0, &fRenderTarget.fColor);
+        GrAssert(S_OK == result && NULL != fRenderTarget.fColor);
+        fRenderTarget.fStencil = stencil;
+        fRenderTarget.fClearStencil = clearStencil;
+    } else {
+        GrAssert(NULL == stencil);
+        fRenderTarget.fColor = NULL;
+        fRenderTarget.fStencil = NULL;
+        fRenderTarget.fClearStencil = false;
+    }
+}
+
+GrD3D9Texture::~GrD3D9Texture() {
+    fGpuD3D9->notifyTextureDelete(this);
+    if (NULL != fRenderTarget.fColor) {
+        fRenderTarget.fColor->Release();
+    }
+    if (NULL != fRenderTarget.fStencil) {
+        fRenderTarget.fStencil->Release();
+    }
+    if (NULL != fTexture) {
+        fTexture->Release();
+    }
+}
+    
+void GrD3D9Texture::abandon() {
+    GrAssert(NULL != fTexture);
+    // release on device already deleted the objects?
+    fTexture = NULL;
+    fRenderTarget.fColor = NULL;
+    fRenderTarget.fStencil = NULL;
+}
+
+bool GrD3D9Texture::isRenderTarget() {
+    GrAssert(NULL != fTexture);
+    return (fDesc.Usage & D3DUSAGE_RENDERTARGET);
+}
+
+void GrD3D9Texture::removeRenderTarget() {
+    fGpuD3D9->notifyTextureRemoveRenderTarget(this);
+    if (NULL != fRenderTarget.fColor) {
+        fRenderTarget.fColor->Release();
+        fRenderTarget.fColor = NULL;
+    }
+    if (NULL != fRenderTarget.fStencil) {
+        fRenderTarget.fStencil->Release();
+        fRenderTarget.fStencil = NULL;
+    }
+    fRenderTarget.fClearStencil = false;
+}
+
+void GrD3D9Texture::uploadTextureData(uint32_t x,
+                                      uint32_t y,
+                                      uint32_t width,
+                                      uint32_t height,
+                                      const void* srcData) {
+    GrAssert(NULL != fTexture);
+    HRESULT hr;
+#if 0 // is it ever beneficial to lock the texture directly?
+    if (fDesc.Usage & D3DUSAGE_DYNAMIC) {
+        D3DLOCKED_RECT lock;
+        RECT rect;
+        rect.left = x;
+        rect.right = x + width;
+        rect.top = y;
+        rect.bottom = y + height;
+        hr = fTexture->LockRect(0, &lock, &rect, 0);
+        if (FAILED(hr)) {
+            GrAssert(!"Failed to lock texture!");
+            return;
+        }
+        int bpp = format_bytes(fDesc.Format);
+        if (lock.Pitch == width * bpp) {
+            memcpy(lock.pBits, srcData, width*height*bpp);
+        } else {
+            for (uint32_t y = 0; y < height; ++y) {
+                memcpy((char*)lock.pBits + y * lock.Pitch,
+                       (char*)srcData + y*width*bpp, width*bpp);
+            }
+        }
+        hr = fTexture->UnlockRect(0);
+        GrAssert(SUCCEEDED(hr));
+    } else 
+#endif
+    {
+        // should the temp textures be cached 
+        // somewhere so we aren't recreating them?
+        IDirect3DDevice9* device;
+        hr = fTexture->GetDevice(&device);
+        if (FAILED(hr) || NULL == device) {
+            GrAssert("getting device from texture failed!");
+            return;
+        }
+        IDirect3DTexture9* tempTexture;
+        GR_D3D9(device, CreateTexture(width, height, 1, 0, fDesc.Format, 
+                                   D3DPOOL_SYSTEMMEM, &tempTexture, NULL));
+        GrAssert(NULL != tempTexture);
+        IDirect3DSurface9* tempSurface;
+        GR_D3D9(tempTexture, GetSurfaceLevel(0, &tempSurface));
+        GrAssert(NULL != tempTexture);
+
+        D3DLOCKED_RECT lock;
+        GR_D3D9(tempSurface, LockRect(&lock, NULL, 0));
+        GrAssert(NULL != lock.pBits);
+
+        // For 4444 D3D uses ARGB for while Skia uses RGBA
+        if (D3DFMT_A4R4G4B4 == fDesc.Format) {
+            WORD* src = (WORD*)srcData;
+            for (uint32_t y = 0; y < height; ++y) {
+                for (uint32_t x = 0; x < width; ++x, ++src) {
+                    WORD* dst = (WORD*)((char*)lock.pBits + y * lock.Pitch)+x;
+                    *dst = ((0xfff0 & *src) >> 4) | ((0x000f & *src) << 12);                    
+                }
+            }
+        } else {
+            int bpp = format_bytes(fDesc.Format);        
+            if (lock.Pitch == width * bpp) {
+                memcpy(lock.pBits, srcData, width*height*bpp);
+            } else {
+                for (uint32_t y = 0; y < height; ++y) {
+                    memcpy((char*)lock.pBits + y * lock.Pitch,
+                           (char*)srcData + y*width*bpp, width*bpp);
+                }
+            }
+        }
+        GR_D3D9(tempSurface, UnlockRect());
+
+        IDirect3DSurface9* level0;
+        GR_D3D9(fTexture, GetSurfaceLevel(0, &level0));
+
+        POINT xy = {x, y};
+        GR_D3D9(device, UpdateSurface(tempSurface, NULL, level0, &xy));
+
+        tempSurface->Release();
+        tempTexture->Release();
+        level0->Release();
+        device->Release();
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrD3D9VertexBuffer::GrD3D9VertexBuffer(uint32_t size, 
+                                       bool dynamic,
+                                       IDirect3DVertexBuffer9* vbuffer,
+                                       GrGpuD3D9* gpuD3D9) :
+            INHERITED(size, dynamic),
+            fBuffer(vbuffer),
+            fLocked(false),
+            fGpuD3D9(gpuD3D9) {
+    HRESULT hr = fBuffer->GetDesc(&fDesc);
+    GrAssert(SUCCEEDED(hr));
+}
+
+GrD3D9VertexBuffer::~GrD3D9VertexBuffer() {
+    fGpuD3D9->notifyVertexBufferDelete(this);
+    if (NULL != fBuffer) {
+        fBuffer->Release();
+    }
+}
+
+void GrD3D9VertexBuffer::abandon() {
+    GrAssert(NULL != fBuffer);
+    fBuffer = NULL;
+}
+
+void* GrD3D9VertexBuffer::lock() {
+    GrAssert(NULL != fBuffer);
+    HRESULT hr;
+    void* data = NULL;
+    hr = fBuffer->Lock(0, fDesc.Size, &data, D3DLOCK_DISCARD);
+    fLocked = SUCCEEDED(hr);
+    GrAssert(fLocked && NULL != data);
+    return data;
+}
+
+void GrD3D9VertexBuffer::unlock() {
+    GrAssert(fLocked);
+    HRESULT hr = fBuffer->Unlock();
+    GrAssert(SUCCEEDED(hr));
+}
+
+bool GrD3D9VertexBuffer::isLocked() {
+    return fLocked;
+}
+
+bool GrD3D9VertexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+    GrAssert(srcSizeInBytes <= fDesc.Size);
+    HRESULT hr;
+    void* data;
+    hr = fBuffer->Lock(0, fDesc.Size, &data, D3DLOCK_DISCARD);
+    GrAssert(SUCCEEDED(hr));
+    if (SUCCEEDED(hr)) {
+        fLocked = true;
+        GrAssert(NULL != data);
+        memcpy(data, src, srcSizeInBytes);
+        hr = fBuffer->Unlock();
+        fLocked = SUCCEEDED(hr);
+        GrAssert(!fLocked);
+        return !fLocked;
+    }
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrD3D9IndexBuffer::GrD3D9IndexBuffer(uint32_t size, 
+                                     bool dynamic,
+                                     IDirect3DIndexBuffer9* ibuffer,
+                                     GrGpuD3D9* gpuD3D9) :
+            INHERITED(size, dynamic),
+            fBuffer(ibuffer),
+            fLocked(false),
+            fGpuD3D9(gpuD3D9) {
+    HRESULT hr = fBuffer->GetDesc(&fDesc);
+    GrAssert(SUCCEEDED(hr));
+}
+
+GrD3D9IndexBuffer::~GrD3D9IndexBuffer() {
+    fGpuD3D9->notifyIndexBufferDelete(this);
+    if (NULL != fBuffer) {
+        fBuffer->Release();
+    }
+}
+
+void GrD3D9IndexBuffer::abandon() {
+    GrAssert(NULL != fBuffer);
+    fBuffer = NULL;
+}
+
+void* GrD3D9IndexBuffer::lock() {
+    GrAssert(NULL != fBuffer);
+    HRESULT hr;
+    void* data = NULL;
+    hr = fBuffer->Lock(0, fDesc.Size, &data, D3DLOCK_DISCARD);
+    fLocked = SUCCEEDED(hr);
+    GrAssert(fLocked && NULL != data);
+    return data;
+}
+
+void GrD3D9IndexBuffer::unlock() {
+    GrAssert(fLocked);
+    HRESULT hr = fBuffer->Unlock();
+    GrAssert(SUCCEEDED(hr));
+}
+
+bool GrD3D9IndexBuffer::isLocked() {
+    return fLocked;
+}
+
+bool GrD3D9IndexBuffer::updateData(const void* src, uint32_t srcSizeInBytes) {
+    GrAssert(srcSizeInBytes <= fDesc.Size);
+    HRESULT hr;
+    void* data;
+    hr = fBuffer->Lock(0, fDesc.Size, &data, D3DLOCK_DISCARD);
+    GrAssert(SUCCEEDED(hr));
+    if (SUCCEEDED(hr)) {
+        fLocked = true;
+        GrAssert(NULL != data);
+        memcpy(data, src, srcSizeInBytes);
+        hr = fBuffer->Unlock();
+        fLocked = SUCCEEDED(hr);
+        GrAssert(!fLocked);
+        return !fLocked;
+    }
+    return false;
+}
diff --git a/gpu/src/GrGpuFactory.cpp b/gpu/src/GrGpuFactory.cpp
new file mode 100644
index 0000000..b3627c9
--- /dev/null
+++ b/gpu/src/GrGpuFactory.cpp
@@ -0,0 +1,78 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTypes.h"
+
+// must be before GrGLConfig.h
+#if GR_WIN32_BUILD
+//    #include "GrGpuD3D9.h"
+#endif
+
+#include "GrGLConfig.h"
+
+#define GR_USE_GLSHADERS2 0
+
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+    #include "GrGpuGLFixed.h"
+#endif
+
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+    #if GR_USE_GLSHADERS2
+        #include "GrGpuGLShaders2.h"
+    #else
+        #include "GrGpuGLShaders.h"
+    #endif
+#endif
+
+#include "GrGpu.h"
+
+GrGpu* GrGpu::Create(Engine engine, Platform3DContext context3D) {
+    GrGpu* gpu = NULL;
+
+    switch (engine) {
+        case kOpenGL_Shaders_Engine:
+            GrAssert(NULL == context3D);
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+    #if GR_USE_GLSHADERS2
+            gpu = new GrGpuGLShaders2;
+    #else
+            gpu = new GrGpuGLShaders;
+    #endif
+#endif
+            break;
+        case kOpenGL_Fixed_Engine:
+            GrAssert(NULL == context3D);
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+            gpu = new GrGpuGLFixed;
+#endif
+            break;
+        case kDirect3D9_Engine:
+            GrAssert(NULL != context3D);
+#if GR_WIN32_BUILD
+//            gpu = new GrGpuD3D9((IDirect3DDevice9*)context3D);
+#endif
+            break;
+        default:
+            GrAssert(!"unknown engine");
+            break;
+    }
+
+    return gpu;
+}
+
+
+
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
new file mode 100644
index 0000000..8a1169e
--- /dev/null
+++ b/gpu/src/GrGpuGL.cpp
@@ -0,0 +1,1824 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+#include "GrGpuGL.h"
+#include "GrMemory.h"
+#include <stdio.h>
+
+static const GLuint GR_MAX_GLUINT = ~0;
+static const GLint  GR_INVAL_GLINT = ~0;
+
+#define SKIP_CACHE_CHECK    true
+
+static const GLenum gXfermodeCoeff2Blend[] = {
+    GL_ZERO,
+    GL_ONE,
+    GL_SRC_COLOR,
+    GL_ONE_MINUS_SRC_COLOR,
+    GL_DST_COLOR,
+    GL_ONE_MINUS_DST_COLOR,
+    GL_SRC_ALPHA,
+    GL_ONE_MINUS_SRC_ALPHA,
+    GL_DST_ALPHA,
+    GL_ONE_MINUS_DST_ALPHA,
+};
+
+bool has_gl_extension(const char* ext) {
+    const char* glstr = (const char*) glGetString(GL_EXTENSIONS);
+
+    int extLength = strlen(ext);
+
+    while (true) {
+        int n = strcspn(glstr, " ");
+        if (n == extLength && 0 == strncmp(ext, glstr, n)) {
+            return true;
+        }
+        if (0 == glstr[n]) {
+            return false;
+        }
+        glstr += n+1;
+    }
+}
+
+void gl_version(int* major, int* minor) {
+    const char* v = (const char*) glGetString(GL_VERSION);
+    if (NULL == v) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#if GR_GL_DESKTOP
+    int n = sscanf(v, "%d.%d", major, minor);
+    if (n != 2) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#else
+    char profile[2];
+    int n = sscanf(v, "OpenGL ES-%c%c %d.%d", profile, profile+1, major, minor);
+    bool ok = 4 == n;
+    if (!ok) {
+        int n = sscanf(v, "OpenGL ES %d.%d", major, minor);
+        ok = 2 == n;
+    }
+    if (!ok) {
+        GrAssert(0);
+        *major = 0;
+        *minor = 0;
+        return;
+    }
+#endif
+}
+///////////////////////////////////////////////////////////////////////////////
+
+bool fbo_test(GrGLExts exts, int w, int h) {
+    GLuint testFBO;
+    GR_GLEXT(exts, GenFramebuffers(1, &testFBO));
+    GR_GLEXT(exts, BindFramebuffer(GR_FRAMEBUFFER, testFBO));
+    GLuint testRTTex;
+    GR_GL(GenTextures(1, &testRTTex));
+    GR_GL(BindTexture(GL_TEXTURE_2D, testRTTex));
+
+    GR_GL(TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h,
+                     0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
+    GR_GL(BindTexture(GL_TEXTURE_2D, 0));
+    GR_GLEXT(exts, FramebufferTexture2D(GR_FRAMEBUFFER, GR_COLOR_ATTACHMENT0,
+                                        GL_TEXTURE_2D, testRTTex, 0));
+    GLenum status = GR_GLEXT(exts, CheckFramebufferStatus(GR_FRAMEBUFFER));
+    GR_GLEXT(exts, DeleteFramebuffers(1, &testFBO));
+    GR_GL(DeleteTextures(1, &testRTTex));
+    return status == GR_FRAMEBUFFER_COMPLETE;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrGpuGL::GrGpuGL() {
+    GrPrintf("------------------------- create GrGpuGL %p --------------\n",
+             this);
+    GrPrintf("------ VENDOR %s\n", glGetString(GL_VENDOR));
+    GrPrintf("------ RENDERER %s\n", glGetString(GL_RENDERER));
+    GrPrintf("------ VERSION %s\n", glGetString(GL_VERSION));
+    GrPrintf("------ EXTENSIONS\n %s \n", glGetString(GL_EXTENSIONS));
+
+    GrGLClearErr();
+
+    GrGLInitExtensions(&fExts);
+
+    resetContextHelper();
+
+    GrGLRenderTarget::GLRenderTargetIDs defaultRTIDs;
+    GR_GL(GetIntegerv(GR_FRAMEBUFFER_BINDING, (GLint*)&defaultRTIDs.fRTFBOID));
+    defaultRTIDs.fTexFBOID = defaultRTIDs.fRTFBOID;
+    defaultRTIDs.fMSColorRenderbufferID = 0;
+    defaultRTIDs.fStencilRenderbufferID = 0;
+    GLint vp[4];
+    GR_GL(GetIntegerv(GL_VIEWPORT, vp));
+    fHWBounds.fViewportRect.setLTRB(vp[0],
+                                    vp[1] + vp[3],
+                                    vp[0] + vp[2],
+                                    vp[1]);
+    defaultRTIDs.fOwnIDs = false;
+
+    fDefaultRenderTarget = new GrGLRenderTarget(defaultRTIDs,
+                                                fHWBounds.fViewportRect,
+                                                NULL,
+                                                this);
+    fHWDrawState.fRenderTarget = fDefaultRenderTarget;
+    fRenderTargetChanged = true;
+
+    fCurrDrawState = fHWDrawState;
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Check for supported features.
+
+    int major, minor;
+    gl_version(&major, &minor);
+
+    GLint numFormats;
+    GR_GL(GetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats));
+    GrAutoSTMalloc<10, GLint> formats(numFormats);
+    GR_GL(GetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats));
+    for (int i = 0; i < numFormats; ++i) {
+        if (formats[i] == GR_PALETTE8_RGBA8) {
+            f8bitPaletteSupport = true;
+            break;
+        }
+    }
+    GrPrintf("Palette8 support: %s\n", (f8bitPaletteSupport ? "YES" : "NO"));
+
+    GR_STATIC_ASSERT(0 == kNone_AALevel);
+    GR_STATIC_ASSERT(1 == kLow_AALevel);
+    GR_STATIC_ASSERT(2 == kMed_AALevel);
+    GR_STATIC_ASSERT(3 == kHigh_AALevel);
+
+    memset(fAASamples, 0, sizeof(fAASamples));
+    fMSFBOType = kNone_MSFBO;
+    if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {
+        fMSFBOType = kIMG_MSFBO;
+        GrPrintf("MSAA Support: IMG ES EXT.\n");
+    }
+    else if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
+        fMSFBOType = kApple_MSFBO;
+        GrPrintf("MSAA Support: APPLE ES EXT.\n");
+    }
+#if GR_GL_DESKTOP
+    else if ((major >= 3) ||
+             has_gl_extension("GL_ARB_framebuffer_object") ||
+             (has_gl_extension("GL_EXT_framebuffer_multisample") &&
+              has_gl_extension("GL_EXT_framebuffer_blit"))) {
+        fMSFBOType = kDesktop_MSFBO;
+        GrPrintf("MSAA Support: DESKTOP\n");
+    }
+#endif
+    else {
+        GrPrintf("MSAA Support: NONE\n");
+    }
+
+    if (kNone_MSFBO != fMSFBOType) {
+        GLint maxSamples;
+        GLenum maxSampleGetter = (kIMG_MSFBO == fMSFBOType) ?
+                                                            GR_MAX_SAMPLES_IMG :
+                                                            GR_MAX_SAMPLES;
+        GR_GL(GetIntegerv(maxSampleGetter, &maxSamples));
+        if (maxSamples > 1 ) {
+            fAASamples[kNone_AALevel] = 0;
+            fAASamples[kLow_AALevel] = GrMax(2,
+                                             GrFixedFloorToInt((GR_FixedHalf) *
+                                                             maxSamples));
+            fAASamples[kMed_AALevel] = GrMax(2,
+                                             GrFixedFloorToInt(((GR_Fixed1*3)/4) *
+                                                             maxSamples));
+            fAASamples[kHigh_AALevel] = maxSamples;
+        }
+        GrPrintf("\tMax Samples: %d\n", maxSamples);
+    }
+
+#if GR_GL_DESKTOP
+    fHasStencilWrap = (major >= 2 || (major == 1 && minor >= 4)) ||
+                      has_gl_extension("GL_EXT_stencil_wrap");
+#else
+    fHasStencilWrap = (major >= 2) || has_gl_extension("GL_OES_stencil_wrap");
+#endif
+    GrPrintf("Stencil Wrap: %s\n", (fHasStencilWrap ? "YES" : "NO"));
+
+#if GR_GL_DESKTOP
+    // we could also look for GL_ATI_separate_stencil extension or
+    // GL_EXT_stencil_two_side but they use different function signatures
+    // than GL2.0+ (and than each other).
+    fSingleStencilPassForWinding = (major >= 2);
+#else
+    // ES 2 has two sided stencil but 1.1 doesn't. There doesn't seem to be
+    // an ES1 extension.
+    fSingleStencilPassForWinding = (major >= 2);
+#endif
+    GrPrintf("Single Stencil Pass For Winding: %s\n", (fSingleStencilPassForWinding ? "YES" : "NO"));
+
+
+#if GR_GL_DESKTOP
+    fRGBA8Renderbuffer = true;
+#else
+    fRGBA8Renderbuffer = has_gl_extension("GL_OES_rgb8_rgba8");
+#endif
+    GrPrintf("RGBA Renderbuffer: %s\n", (fRGBA8Renderbuffer ? "YES" : "NO"));
+
+
+#if GR_GL_DESKTOP
+    fBufferLockSupport = true; // we require VBO support and the desktop VBO
+                               // extension includes glMapBuffer.
+#else
+    fBufferLockSupport = has_gl_extension("GL_OES_mapbuffer");
+#endif
+    GrPrintf("Map Buffer: %s\n", (fBufferLockSupport ? "YES" : "NO"));
+
+#if GR_GL_DESKTOP
+    fNPOTTextureSupport =
+        (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) ?
+            kFull_NPOTTextureType :
+            kNone_NPOTTextureType;
+#else
+    if (has_gl_extension("GL_OES_texture_npot")) {
+        fNPOTTextureSupport = kFull_NPOTTextureType;
+    } else if (major >= 2 ||
+               has_gl_extension("GL_APPLE_texture_2D_limited_npot")) {
+        fNPOTTextureSupport = kNoRepeat_NPOTTextureType;
+    } else {
+        fNPOTTextureSupport = kNone_NPOTTextureType;
+    }
+#endif
+    ////////////////////////////////////////////////////////////////////////////
+    // Experiments to determine limitations that can't be queried. TODO: Make
+    // these a preprocess that generate some compile time constants.
+
+    /* Experimentation has found that some GLs that support NPOT textures
+       do not support FBOs with a NPOT texture. They report "unsupported" FBO
+       status. I don't know how to explicitly query for this. Do an
+       experiment. Note they may support NPOT with a renderbuffer but not a
+       texture. Presumably, the implementation bloats the renderbuffer
+       internally to the next POT.
+     */
+    if (fNPOTTextureSupport == kFull_NPOTTextureType) {
+        bool npotFBOSuccess = fbo_test(fExts, 200, 200);
+        if (!npotFBOSuccess) {
+            fNPOTTextureSupport = kNonRendertarget_NPOTTextureType;
+            GrPrintf("NPOT Renderbuffer Test: FAILED\n");
+        } else {
+            GrPrintf("NPOT Renderbuffer Test: PASSED\n");
+        }
+    }
+    switch (fNPOTTextureSupport) {
+    case kNone_NPOTTextureType:
+        GrPrintf("NPOT Support: NONE\n");
+        break;
+    case kNoRepeat_NPOTTextureType:
+        GrPrintf("NPOT Support: NO REPEAT\n");
+        break;
+    case kNonRendertarget_NPOTTextureType:
+        GrPrintf("NPOT Support: NO FBOTEX\n");
+        break;
+    case kFull_NPOTTextureType:
+        GrPrintf("NPOT Support: FULL\n");
+        break;
+    }
+
+    // sanity check to make sure we can at least create an FBO from a POT texture
+    if (fNPOTTextureSupport < kFull_NPOTTextureType) {
+        bool npotFBOSuccess = fbo_test(fExts, 128, 128);
+        if (!npotFBOSuccess) {
+            GrPrintf("FBO Sanity Test: FAILED\n");
+        } else {
+            GrPrintf("FBO Sanity Test: PASSED\n");
+        }
+    }
+
+    /* The iPhone 4 has a restriction that for an FBO with texture color
+       attachment with height <= 8 then the width must be <= height. Here
+       we look for such a limitation.
+     */
+    fMinRenderTargetHeight = GR_INVAL_GLINT;
+    GLint maxRenderSize;
+    glGetIntegerv(GR_MAX_RENDERBUFFER_SIZE, &maxRenderSize);
+
+    GrPrintf("Small height FBO texture experiments\n");
+    for (GLuint i = 1; i <= 256;
+         (kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
+        GLuint w = maxRenderSize;
+        GLuint h = i;
+        if (fbo_test(fExts, w, h)) {
+            GrPrintf("\t[%d, %d]: PASSED\n", w, h);
+            fMinRenderTargetHeight = i;
+            break;
+        } else {
+            GrPrintf("\t[%d, %d]: FAILED\n", w, h);
+        }
+    }
+    GrAssert(GR_INVAL_GLINT != fMinRenderTargetHeight);
+
+    GrPrintf("Small width FBO texture experiments\n");
+    fMinRenderTargetWidth = GR_MAX_GLUINT;
+    for (GLuint i = 1; i <= 256;
+         (kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
+        GLuint w = i;
+        GLuint h = maxRenderSize;
+        if (fbo_test(fExts, w, h)) {
+            GrPrintf("\t[%d, %d]: PASSED\n", w, h);
+            fMinRenderTargetWidth = i;
+            break;
+        } else {
+            GrPrintf("\t[%d, %d]: FAILED\n", w, h);
+        }
+    }
+    GrAssert(GR_INVAL_GLINT != fMinRenderTargetWidth);
+
+#if GR_IOS_BUILD
+    /*
+        The iPad seems to fail, at least sometimes, if the height is < 16,
+        so we pin the values here for now. A better fix might be to
+        conditionalize this based on known that its an iPad (or some other
+        check).
+     */
+    fMinRenderTargetWidth = GrMax<GLuint>(fMinRenderTargetWidth, 16);
+    fMinRenderTargetHeight = GrMax<GLuint>(fMinRenderTargetHeight, 16);
+#endif
+    // bind back to original FBO
+    GR_GLEXT(fExts, BindFramebuffer(GR_FRAMEBUFFER, defaultRTIDs.fRTFBOID));
+#if GR_COLLECT_STATS
+    ++fStats.fRenderTargetChngCnt;
+#endif
+    eraseStencil(0, ~0);
+}
+
+GrGpuGL::~GrGpuGL() {
+    fDefaultRenderTarget->abandon();
+    fDefaultRenderTarget->unref();
+}
+
+void GrGpuGL::resetContextHelper() {
+// We detect cases when blending is effectively off
+    fHWBlendDisabled = false;
+    GR_GL(Enable(GL_BLEND));
+
+    // this is always disabled
+    GR_GL(Disable(GL_CULL_FACE));
+
+    GR_GL(Disable(GL_DITHER));
+#if GR_GL_DESKTOP
+    GR_GL(Disable(GL_LINE_SMOOTH));
+    GR_GL(Disable(GL_POINT_SMOOTH));
+	GR_GL(Disable(GL_MULTISAMPLE));
+#endif
+
+    // we only ever use lines in hairline mode
+    GR_GL(LineWidth(1));
+
+    GR_GL(ActiveTexture(GL_TEXTURE0));
+
+    fHWDrawState.fFlagBits = 0;
+
+    // illegal values
+    fHWDrawState.fSrcBlend = (BlendCoeff)-1;
+    fHWDrawState.fDstBlend = (BlendCoeff)-1;
+    fHWDrawState.fColor = GrColor_ILLEGAL;
+    fHWDrawState.fPointSize = -1;
+    fHWDrawState.fTexture = NULL;
+
+    GR_GL(Scissor(0,0,0,0));
+    fHWBounds.fScissorRect.setLTRB(0,0,0,0);
+    fHWBounds.fScissorEnabled = false;
+    GR_GL(Disable(GL_SCISSOR_TEST));
+
+    fHWDrawState.fSamplerState.setRadial2Params(-GR_ScalarMax,
+                                                -GR_ScalarMax,
+                                                true);
+
+    for (int i = 0; i < kMatrixModeCount; i++) {
+        fHWDrawState.fMatrixModeCache[i].setScale(GR_ScalarMax, GR_ScalarMax); // illegal
+    }
+
+    // disabling the stencil test also disables
+    // stencil buffer writes
+    GR_GL(Disable(GL_STENCIL_TEST));
+    GR_GL(StencilMask(0xffffffff));
+    GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+    fHWDrawState.fReverseFill = false;
+    fHWDrawState.fStencilPass = kNone_StencilPass;
+    fHWStencilClip = false;
+
+    fHWGeometryState.fIndexBuffer = NULL;
+    fHWGeometryState.fVertexBuffer = NULL;
+    GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
+    GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+
+    fHWDrawState.fRenderTarget = NULL;
+}
+
+void GrGpuGL::resetContext() {
+    INHERITED::resetContext();
+    resetContextHelper();
+}
+
+
+// defines stencil formats from more to less preferred
+#if GR_GL_ES
+    GLenum GR_GL_STENCIL_FORMAT_ARRAY[] = {
+        GR_STENCIL_INDEX8,
+    };
+#else
+    GLenum GR_GL_STENCIL_FORMAT_ARRAY[] = {
+        GR_STENCIL_INDEX8,
+        GR_STENCIL_INDEX16,
+        GR_UNSIGNED_INT_24_8,
+        GR_DEPTH_STENCIL,
+    };
+#endif
+
+// good to set a break-point here to know when createTexture fails
+static GrTexture* return_null_texture() {
+//    GrAssert(!"null texture");
+    return NULL;
+}
+
+#if GR_DEBUG
+static size_t as_size_t(int x) {
+    return x;
+}
+#endif
+
+GrRenderTarget* GrGpuGL::createPlatformRenderTarget(
+                                                intptr_t platformRenderTarget,
+                                                int width, int height) {
+    GrGLRenderTarget::GLRenderTargetIDs rtIDs;
+    rtIDs.fStencilRenderbufferID = 0;
+    rtIDs.fMSColorRenderbufferID = 0;
+    rtIDs.fTexFBOID              = 0;
+    rtIDs.fOwnIDs                = false;
+
+    GrIRect viewport;
+
+    // viewport is in GL coords (top >= bottom)
+    viewport.setLTRB(0, height, width, 0);
+
+    rtIDs.fRTFBOID  = (GLuint)platformRenderTarget;
+    rtIDs.fTexFBOID = (GLuint)platformRenderTarget;
+
+    GrGLRenderTarget* rt = new GrGLRenderTarget(rtIDs, viewport, NULL, this);
+
+    return rt;
+}
+
+GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
+                                  const void* srcData, size_t rowBytes) {
+
+#if GR_COLLECT_STATS
+    ++fStats.fTextureCreateCnt;
+#endif
+    GrGLTexture::GLTextureDesc glDesc;
+    GLenum internalFormat;
+
+    glDesc.fContentWidth  = desc.fWidth;
+    glDesc.fContentHeight = desc.fHeight;
+    glDesc.fAllocWidth    = desc.fWidth;
+    glDesc.fAllocHeight   = desc.fHeight;
+    glDesc.fFormat        = desc.fFormat;
+
+    bool renderTarget = 0 != (desc.fFlags & kRenderTarget_TextureFlag);
+    if (!canBeTexture(desc.fFormat,
+                      &internalFormat,
+                      &glDesc.fUploadFormat,
+                      &glDesc.fUploadType)) {
+        return return_null_texture();
+    }
+
+    GrAssert(as_size_t(desc.fAALevel) < GR_ARRAY_COUNT(fAASamples));
+    GLint samples = fAASamples[desc.fAALevel];
+    if (kNone_MSFBO == fMSFBOType && desc.fAALevel != kNone_AALevel) {
+        GrPrintf("AA RT requested but not supported on this platform.");
+    }
+
+    GR_GL(GenTextures(1, &glDesc.fTextureID));
+    if (!glDesc.fTextureID) {
+        return return_null_texture();
+    }
+
+    glDesc.fUploadByteCount = GrTexture::BytesPerPixel(desc.fFormat);
+
+    /*
+     *  check if our srcData has extra bytes past each row. If so, we need
+     *  to trim those off here, since GL doesn't let us pass the rowBytes as
+     *  a parameter to glTexImage2D
+     */
+#if GR_GL_DESKTOP
+    if (srcData) {
+        GR_GL(PixelStorei(GL_UNPACK_ROW_LENGTH,
+                          rowBytes / glDesc.fUploadByteCount));
+    }
+#else
+    GrAutoSMalloc<128 * 128> trimStorage;
+    size_t trimRowBytes = desc.fWidth * glDesc.fUploadByteCount;
+    if (srcData && (trimRowBytes < rowBytes)) {
+        size_t trimSize = desc.fHeight * trimRowBytes;
+        trimStorage.realloc(trimSize);
+        // now copy the data into our new storage, skipping the trailing bytes
+        const char* src = (const char*)srcData;
+        char* dst = (char*)trimStorage.get();
+        for (uint32_t y = 0; y < desc.fHeight; y++) {
+            memcpy(dst, src, trimRowBytes);
+            src += rowBytes;
+            dst += trimRowBytes;
+        }
+        // now point srcData to our trimmed version
+        srcData = trimStorage.get();
+    }
+#endif
+
+    if (fNPOTTextureSupport < kNonRendertarget_NPOTTextureType ||
+        (fNPOTTextureSupport == kNonRendertarget_NPOTTextureType &&
+         renderTarget)) {
+        glDesc.fAllocWidth  = GrNextPow2(desc.fWidth);
+        glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
+    }
+
+    if (renderTarget) {
+        glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth,
+                                        glDesc.fAllocWidth);
+        glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
+                                         glDesc.fAllocHeight);
+    }
+
+    GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
+#if GR_COLLECT_STATS
+    ++fStats.fTextureChngCnt;
+#endif
+
+    GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, glDesc.fUploadByteCount));
+    if (GrTexture::kIndex_8_PixelConfig == desc.fFormat &&
+        supports8BitPalette()) {
+        // ES only supports CompressedTexImage2D, not CompressedTexSubimage2D
+        GrAssert(desc.fWidth == glDesc.fAllocWidth);
+        GrAssert(desc.fHeight == glDesc.fAllocHeight);
+        GLsizei imageSize = glDesc.fAllocWidth * glDesc.fAllocHeight +
+                            kColorTableSize;
+        GR_GL(CompressedTexImage2D(GL_TEXTURE_2D, 0, glDesc.fUploadFormat,
+                                   glDesc.fAllocWidth, glDesc.fAllocHeight,
+                                   0, imageSize, srcData));
+        GrGL_RestoreResetRowLength();
+    } else {
+        if (NULL != srcData && (glDesc.fAllocWidth != desc.fWidth ||
+                                glDesc.fAllocHeight != desc.fHeight)) {
+            GR_GL(TexImage2D(GL_TEXTURE_2D, 0, internalFormat,
+                             glDesc.fAllocWidth, glDesc.fAllocHeight,
+                             0, glDesc.fUploadFormat, glDesc.fUploadType, NULL));
+            GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, desc.fWidth,
+                                desc.fHeight, glDesc.fUploadFormat,
+                                glDesc.fUploadType, srcData));
+            GrGL_RestoreResetRowLength();
+
+            uint32_t extraW = glDesc.fAllocWidth  - desc.fWidth;
+            uint32_t extraH = glDesc.fAllocHeight - desc.fHeight;
+            uint32_t maxTexels = extraW * extraH;
+            maxTexels = GrMax(extraW * desc.fHeight, maxTexels);
+            maxTexels = GrMax(desc.fWidth * extraH, maxTexels);
+
+            GrAutoSMalloc<128*128> texels(glDesc.fUploadByteCount * maxTexels);
+
+            uint32_t rowSize = desc.fWidth * glDesc.fUploadByteCount;
+            if (extraH) {
+                uint8_t* lastRowStart = (uint8_t*) srcData +
+                                        (desc.fHeight - 1) * rowSize;
+                uint8_t* extraRowStart = (uint8_t*)texels.get();
+
+                for (uint32_t i = 0; i < extraH; ++i) {
+                    memcpy(extraRowStart, lastRowStart, rowSize);
+                    extraRowStart += rowSize;
+                }
+                GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, 0, desc.fHeight, desc.fWidth,
+                                    extraH, glDesc.fUploadFormat, glDesc.fUploadType,
+                                    texels.get()));
+            }
+            if (extraW) {
+                uint8_t* edgeTexel = (uint8_t*)srcData + rowSize - glDesc.fUploadByteCount;
+                uint8_t* extraTexel = (uint8_t*)texels.get();
+                for (uint32_t j = 0; j < desc.fHeight; ++j) {
+                    for (uint32_t i = 0; i < extraW; ++i) {
+                        memcpy(extraTexel, edgeTexel, glDesc.fUploadByteCount);
+                        extraTexel += glDesc.fUploadByteCount;
+                    }
+                    edgeTexel += rowSize;
+                }
+                GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, desc.fWidth, 0, extraW,
+                                    desc.fHeight, glDesc.fUploadFormat,
+                                    glDesc.fUploadType, texels.get()));
+            }
+            if (extraW && extraH) {
+                uint8_t* cornerTexel = (uint8_t*)srcData + desc.fHeight * rowSize
+                                       - glDesc.fUploadByteCount;
+                uint8_t* extraTexel = (uint8_t*)texels.get();
+                for (uint32_t i = 0; i < extraW*extraH; ++i) {
+                    memcpy(extraTexel, cornerTexel, glDesc.fUploadByteCount);
+                    extraTexel += glDesc.fUploadByteCount;
+                }
+                GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, desc.fWidth, desc.fHeight,
+                                    extraW, extraH, glDesc.fUploadFormat,
+                                    glDesc.fUploadType, texels.get()));
+            }
+
+        } else {
+            GR_GL(TexImage2D(GL_TEXTURE_2D, 0, internalFormat, glDesc.fAllocWidth,
+                             glDesc.fAllocHeight, 0, glDesc.fUploadFormat,
+                             glDesc.fUploadType, srcData));
+            GrGL_RestoreResetRowLength();
+        }
+    }
+
+    glDesc.fOrientation = GrGLTexture::kTopDown_Orientation;
+
+    GrGLRenderTarget::GLRenderTargetIDs rtIDs;
+    rtIDs.fStencilRenderbufferID = 0;
+    rtIDs.fMSColorRenderbufferID = 0;
+    rtIDs.fRTFBOID = 0;
+    rtIDs.fTexFBOID = 0;
+    rtIDs.fOwnIDs = true;
+    GLenum msColorRenderbufferFormat = -1;
+
+    if (renderTarget) {
+#if GR_COLLECT_STATS
+        ++fStats.fRenderTargetCreateCnt;
+#endif
+        bool failed = true;
+        GLenum status;
+        GLint err;
+
+        // If need have both RT flag and srcData we have
+        // to invert the data before uploading because FBO
+        // will be rendered bottom up
+        GrAssert(NULL == srcData);
+        glDesc.fOrientation =  GrGLTexture::kBottomUp_Orientation;
+
+        GR_GLEXT(fExts, GenFramebuffers(1, &rtIDs.fTexFBOID));
+        GrAssert(rtIDs.fTexFBOID);
+
+        // If we are using multisampling and any extension other than the IMG
+        // one we will create two FBOs. We render to one and then resolve to
+        // the texture bound to the other. The IMG extension does an implicit
+        // resolve.
+        if (samples > 1 && kIMG_MSFBO != fMSFBOType && kNone_MSFBO != fMSFBOType) {
+            GR_GLEXT(fExts, GenFramebuffers(1, &rtIDs.fRTFBOID));
+            GrAssert(0 != rtIDs.fRTFBOID);
+            GR_GLEXT(fExts, GenRenderbuffers(1, &rtIDs.fMSColorRenderbufferID));
+            GrAssert(0 != rtIDs.fMSColorRenderbufferID);
+            if (!fboInternalFormat(desc.fFormat, &msColorRenderbufferFormat)) {
+                GR_GLEXT(fExts,
+                         DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID));
+                GR_GL(DeleteTextures(1, &glDesc.fTextureID));
+                GR_GLEXT(fExts, DeleteFramebuffers(1, &rtIDs.fTexFBOID));
+                GR_GLEXT(fExts, DeleteFramebuffers(1, &rtIDs.fRTFBOID));
+                fHWDrawState.fTexture = NULL;
+                return return_null_texture();
+            }
+        } else {
+            rtIDs.fRTFBOID = rtIDs.fTexFBOID;
+        }
+        int attempts = 1;
+        if (!(kNoPathRendering_TextureFlag & desc.fFlags)) {
+            GR_GLEXT(fExts, GenRenderbuffers(1, &rtIDs.fStencilRenderbufferID));
+            GrAssert(0 != rtIDs.fStencilRenderbufferID);
+            attempts = GR_ARRAY_COUNT(GR_GL_STENCIL_FORMAT_ARRAY);
+        }
+
+        // need to unbind the texture before we call FramebufferTexture2D
+        GR_GL(BindTexture(GL_TEXTURE_2D, 0));
+#if GR_COLLECT_STATS
+        ++fStats.fTextureChngCnt;
+#endif
+
+        fHWDrawState.fTexture = NULL;
+
+        err = ~GL_NO_ERROR;
+        for (int i = 0; i < attempts; ++i) {
+            if (rtIDs.fStencilRenderbufferID) {
+                GR_GLEXT(fExts, BindRenderbuffer(GR_RENDERBUFFER,
+                                                 rtIDs.fStencilRenderbufferID));
+                if (samples > 1) {
+                    GR_GLEXT_NO_ERR(fExts, RenderbufferStorageMultisample(
+                                                GR_RENDERBUFFER,
+                                                samples,
+                                                GR_GL_STENCIL_FORMAT_ARRAY[i],
+                                                glDesc.fAllocWidth,
+                                                glDesc.fAllocHeight));
+                } else {
+                    GR_GLEXT_NO_ERR(fExts, RenderbufferStorage(
+                                                GR_RENDERBUFFER,
+                                                GR_GL_STENCIL_FORMAT_ARRAY[i],
+                                                glDesc.fAllocWidth,
+                                                glDesc.fAllocHeight));
+                }
+                err = glGetError();
+                if (err != GL_NO_ERROR) {
+                    continue;
+                }
+            }
+            if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) {
+                GrAssert(samples > 1);
+                GR_GLEXT(fExts, BindRenderbuffer(GR_RENDERBUFFER,
+                                                 rtIDs.fMSColorRenderbufferID));
+                GR_GLEXT_NO_ERR(fExts, RenderbufferStorageMultisample(
+                                                   GR_RENDERBUFFER,
+                                                   samples,
+                                                   msColorRenderbufferFormat,
+                                                   glDesc.fAllocWidth,
+                                                   glDesc.fAllocHeight));
+                err = glGetError();
+                if (err != GL_NO_ERROR) {
+                    continue;
+                }
+            }
+            GR_GLEXT(fExts, BindFramebuffer(GR_FRAMEBUFFER, rtIDs.fTexFBOID));
+
+#if GR_COLLECT_STATS
+            ++fStats.fRenderTargetChngCnt;
+#endif
+            if (kIMG_MSFBO == fMSFBOType && samples > 1) {
+                GR_GLEXT(fExts, FramebufferTexture2DMultisample(
+                                                         GR_FRAMEBUFFER,
+                                                         GR_COLOR_ATTACHMENT0,
+                                                         GL_TEXTURE_2D,
+                                                         glDesc.fTextureID,
+                                                         0,
+                                                         samples));
+
+            } else {
+                GR_GLEXT(fExts, FramebufferTexture2D(GR_FRAMEBUFFER,
+                                                     GR_COLOR_ATTACHMENT0,
+                                                     GL_TEXTURE_2D,
+                                                     glDesc.fTextureID, 0));
+            }
+            if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) {
+                GLenum status = GR_GLEXT(fExts,
+                                         CheckFramebufferStatus(GR_FRAMEBUFFER));
+                if (status != GR_FRAMEBUFFER_COMPLETE) {
+                    GrPrintf("-- glCheckFramebufferStatus %x %d %d\n",
+                             status, desc.fWidth, desc.fHeight);
+                    continue;
+                }
+                GR_GLEXT(fExts, BindFramebuffer(GR_FRAMEBUFFER, rtIDs.fRTFBOID));
+            #if GR_COLLECT_STATS
+                ++fStats.fRenderTargetChngCnt;
+            #endif
+                GR_GLEXT(fExts, FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                                 GR_COLOR_ATTACHMENT0,
+                                                 GR_RENDERBUFFER,
+                                                 rtIDs.fMSColorRenderbufferID));
+
+            }
+            if (rtIDs.fStencilRenderbufferID) {
+                // bind the stencil to rt fbo if present, othewise the tex fbo
+                GR_GLEXT(fExts, FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                                 GR_STENCIL_ATTACHMENT,
+                                                 GR_RENDERBUFFER,
+                                                 rtIDs.fStencilRenderbufferID));
+            }
+            status = GR_GLEXT(fExts, CheckFramebufferStatus(GR_FRAMEBUFFER));
+
+#if GR_GL_DESKTOP
+            // On some implementations you have to be bound as DEPTH_STENCIL.
+            // (Even binding to DEPTH and STENCIL separately with the same
+            // buffer doesn't work.)
+            if (rtIDs.fStencilRenderbufferID &&
+                status != GR_FRAMEBUFFER_COMPLETE) {
+                GR_GLEXT(fExts, FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                                        GR_STENCIL_ATTACHMENT,
+                                                        GR_RENDERBUFFER,
+                                                        0));
+                GR_GLEXT(fExts,
+                         FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                                 GR_DEPTH_STENCIL_ATTACHMENT,
+                                                 GR_RENDERBUFFER,
+                                                 rtIDs.fStencilRenderbufferID));
+                status = GR_GLEXT(fExts, CheckFramebufferStatus(GR_FRAMEBUFFER));
+            }
+#endif
+            if (status != GR_FRAMEBUFFER_COMPLETE) {
+                GrPrintf("-- glCheckFramebufferStatus %x %d %d\n",
+                         status, desc.fWidth, desc.fHeight);
+#if GR_GL_DESKTOP
+                if (rtIDs.fStencilRenderbufferID) {
+                    GR_GLEXT(fExts, FramebufferRenderbuffer(GR_FRAMEBUFFER,
+                                                     GR_DEPTH_STENCIL_ATTACHMENT,
+                                                     GR_RENDERBUFFER,
+                                                     0));
+                }
+#endif
+                continue;
+            }
+            // we're successful!
+            failed = false;
+            break;
+        }
+        if (failed) {
+            if (rtIDs.fStencilRenderbufferID) {
+                GR_GLEXT(fExts,
+                         DeleteRenderbuffers(1, &rtIDs.fStencilRenderbufferID));
+            }
+            if (rtIDs.fMSColorRenderbufferID) {
+                GR_GLEXT(fExts,
+                         DeleteRenderbuffers(1, &rtIDs.fMSColorRenderbufferID));
+            }
+            if (rtIDs.fRTFBOID != rtIDs.fTexFBOID) {
+                GR_GLEXT(fExts, DeleteFramebuffers(1, &rtIDs.fRTFBOID));
+            }
+            if (rtIDs.fTexFBOID) {
+                GR_GLEXT(fExts, DeleteFramebuffers(1, &rtIDs.fTexFBOID));
+            }
+            GR_GL(DeleteTextures(1, &glDesc.fTextureID));
+            return return_null_texture();
+        }
+    }
+#ifdef TRACE_TEXTURE_CREATION
+    GrPrintf("--- new texture [%d] size=(%d %d) bpp=%d\n",
+             tex->fTextureID, width, height, tex->fUploadByteCount);
+#endif
+    GrGLTexture* tex = new GrGLTexture(glDesc, rtIDs, this);
+
+    if (0 != rtIDs.fTexFBOID) {
+        GrRenderTarget* rt = tex->asRenderTarget();
+        // We've messed with FBO state but may not have set the correct viewport
+        // so just dirty the rendertarget state to force a resend.
+        fHWDrawState.fRenderTarget = NULL;
+
+        // clear the new stencil buffer if we have one
+        if (!(desc.fFlags & kNoPathRendering_TextureFlag)) {
+            GrRenderTarget* rtSave = fCurrDrawState.fRenderTarget;
+            fCurrDrawState.fRenderTarget = rt;
+            eraseStencil(0, ~0);
+            fCurrDrawState.fRenderTarget = rtSave;
+        }
+    }
+    return tex;
+}
+
+GrRenderTarget* GrGpuGL::defaultRenderTarget() {
+    return fDefaultRenderTarget;
+}
+
+GrVertexBuffer* GrGpuGL::createVertexBuffer(uint32_t size, bool dynamic) {
+    GLuint id;
+    GR_GL(GenBuffers(1, &id));
+    if (id) {
+        GR_GL(BindBuffer(GL_ARRAY_BUFFER, id));
+        GrGLClearErr();
+        // make sure driver can allocate memory for this buffer
+        GR_GL_NO_ERR(BufferData(GL_ARRAY_BUFFER, size, NULL,
+                                dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        if (glGetError() != GL_NO_ERROR) {
+            GR_GL(DeleteBuffers(1, &id));
+            // deleting bound buffer does implicit bind to 0
+            fHWGeometryState.fVertexBuffer = NULL;
+            return NULL;
+        }
+        GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(id, this,
+                                                              size, dynamic);
+        fHWGeometryState.fVertexBuffer = vertexBuffer;
+        return vertexBuffer;
+    }
+    return NULL;
+}
+
+GrIndexBuffer* GrGpuGL::createIndexBuffer(uint32_t size, bool dynamic) {
+    GLuint id;
+    GR_GL(GenBuffers(1, &id));
+    if (id) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, id));
+        GrGLClearErr();
+        // make sure driver can allocate memory for this buffer
+        GR_GL_NO_ERR(BufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL,
+                                dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW));
+        if (glGetError() != GL_NO_ERROR) {
+            GR_GL(DeleteBuffers(1, &id));
+            // deleting bound buffer does implicit bind to 0
+            fHWGeometryState.fIndexBuffer = NULL;
+            return NULL;
+        }
+        GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(id, this,
+                                                         size, dynamic);
+        fHWGeometryState.fIndexBuffer = indexBuffer;
+        return indexBuffer;
+    }
+    return NULL;
+}
+
+void GrGpuGL::setDefaultRenderTargetSize(uint32_t width, uint32_t height) {
+    GrIRect viewport(0, height, width, 0);
+    if (viewport != fDefaultRenderTarget->viewport()) {
+        fDefaultRenderTarget->setViewport(viewport);
+        if (fHWDrawState.fRenderTarget == fDefaultRenderTarget) {
+            fHWDrawState.fRenderTarget = NULL;
+        }
+    }
+}
+
+void GrGpuGL::flushScissor(const GrIRect* rect) {
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    const GrIRect& vp =
+            ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->viewport();
+
+    if (NULL != rect &&
+        rect->contains(vp)) {
+        rect = NULL;
+    }
+
+    if (NULL != rect) {
+        GrIRect scissor;
+        // viewport is already in GL coords
+        // create a scissor in GL coords (top > bottom)
+        scissor.setLTRB(vp.fLeft + rect->fLeft,
+                        vp.fTop  - rect->fTop,
+                        vp.fLeft + rect->fRight,
+                        vp.fTop  - rect->fBottom);
+
+        if (fHWBounds.fScissorRect != scissor) {
+            GR_GL(Scissor(scissor.fLeft, scissor.fBottom,
+                          scissor.width(), -scissor.height()));
+            fHWBounds.fScissorRect = scissor;
+        }
+
+        if (!fHWBounds.fScissorEnabled) {
+            GR_GL(Enable(GL_SCISSOR_TEST));
+            fHWBounds.fScissorEnabled = true;
+        }
+    } else {
+        if (fHWBounds.fScissorEnabled) {
+            GR_GL(Disable(GL_SCISSOR_TEST));
+            fHWBounds.fScissorEnabled = false;
+        }
+    }
+}
+
+void GrGpuGL::setSamplerStateImm(const GrSamplerState& state) {
+
+    GLenum filter = state.isFilter() ? GL_LINEAR : GL_NEAREST;
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter));
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter));
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                        GrGLTexture::gWrapMode2GLWrap[state.getWrapX()]));
+    GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                        GrGLTexture::gWrapMode2GLWrap[state.getWrapY()]));
+
+}
+
+void GrGpuGL::eraseColor(GrColor color) {
+    flushRenderTarget();
+    if (fHWBounds.fScissorEnabled) {
+        GR_GL(Disable(GL_SCISSOR_TEST));
+    }
+    GR_GL(ColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE));
+    GR_GL(ClearColor(GrColorUnpackR(color)/255.f,
+                     GrColorUnpackG(color)/255.f,
+                     GrColorUnpackB(color)/255.f,
+                     GrColorUnpackA(color)/255.f));
+    GR_GL(Clear(GL_COLOR_BUFFER_BIT));
+    fHWBounds.fScissorEnabled = false;
+    fWriteMaskChanged = true;
+}
+
+void GrGpuGL::eraseStencil(uint32_t value, uint32_t mask) {
+    flushRenderTarget();
+    if (fHWBounds.fScissorEnabled) {
+        GR_GL(Disable(GL_SCISSOR_TEST));
+    }
+    GR_GL(StencilMask(mask));
+    GR_GL(ClearStencil(value));
+    GR_GL(Clear(GL_STENCIL_BUFFER_BIT));
+    fHWBounds.fScissorEnabled = false;
+    fWriteMaskChanged = true;
+}
+
+void GrGpuGL::eraseStencilClip() {
+    GLint stencilBitCount;
+    GR_GL(GetIntegerv(GL_STENCIL_BITS, &stencilBitCount));
+    GrAssert(stencilBitCount > 0);
+    GLint clipStencilMask  = (1 << (stencilBitCount - 1));
+    eraseStencil(0, clipStencilMask);
+}
+
+void GrGpuGL::forceRenderTargetFlush() {
+    flushRenderTarget();
+}
+
+bool GrGpuGL::readPixels(int left, int top, int width, int height,
+                         GrTexture::PixelConfig config, void* buffer) {
+    GLenum internalFormat;  // we don't use this for glReadPixels
+    GLenum format;
+    GLenum type;
+    if (!this->canBeTexture(config, &internalFormat, &format, &type)) {
+        return false;
+    }
+
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    const GrIRect& vp = ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->viewport();
+
+    // Brian says that viewport rects are already upside down (grrrrr)
+    glReadPixels(left, -vp.height() - top - height, width, height,
+                 format, type, buffer);
+
+    // now reverse the order of the rows, since GL's are bottom-to-top, but our
+    // API presents top-to-bottom
+    {
+        size_t stride = width * GrTexture::BytesPerPixel(config);
+        GrAutoMalloc rowStorage(stride);
+        void* tmp = rowStorage.get();
+
+        const int halfY = height >> 1;
+        char* top = reinterpret_cast<char*>(buffer);
+        char* bottom = top + (height - 1) * stride;
+        for (int y = 0; y < halfY; y++) {
+            memcpy(tmp, top, stride);
+            memcpy(top, bottom, stride);
+            memcpy(bottom, tmp, stride);
+            top += stride;
+            bottom -= stride;
+        }
+    }
+    return true;
+}
+
+void GrGpuGL::flushRenderTarget() {
+    if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) {
+        GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget;
+        GR_GLEXT(fExts, BindFramebuffer(GR_FRAMEBUFFER, rt->renderFBOID()));
+    #if GR_COLLECT_STATS
+        ++fStats.fRenderTargetChngCnt;
+    #endif
+        rt->setDirty(true);
+    #if GR_DEBUG
+        GLenum status = GR_GLEXT(fExts, CheckFramebufferStatus(GR_FRAMEBUFFER));
+        if (status != GR_FRAMEBUFFER_COMPLETE) {
+            GrPrintf("-- glCheckFramebufferStatus %x\n", status);
+        }
+    #endif
+        fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget;
+        const GrIRect& vp = rt->viewport();
+        fRenderTargetChanged = true;
+        if (fHWBounds.fViewportRect != vp) {
+            GR_GL(Viewport(vp.fLeft,
+                           vp.fBottom,
+                           vp.width(),
+                           -vp.height()));
+            fHWBounds.fViewportRect = vp;
+        }
+    }
+}
+
+GLenum gPrimitiveType2GLMode[] = {
+    GL_TRIANGLES,
+    GL_TRIANGLE_STRIP,
+    GL_TRIANGLE_FAN,
+    GL_POINTS,
+    GL_LINES,
+    GL_LINE_STRIP
+};
+
+void GrGpuGL::drawIndexedHelper(PrimitiveType type,
+                                uint32_t startVertex,
+                                uint32_t startIndex,
+                                uint32_t vertexCount,
+                                uint32_t indexCount) {
+    GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
+
+    GLvoid* indices = (GLvoid*)(sizeof(uint16_t) * startIndex);
+    if (kReserved_GeometrySrcType == fGeometrySrc.fIndexSrc) {
+        indices = (GLvoid*)((intptr_t)indices + (intptr_t)fIndices.get());
+    } else if (kArray_GeometrySrcType == fGeometrySrc.fIndexSrc) {
+        indices = (GLvoid*)((intptr_t)indices +
+                            (intptr_t)fGeometrySrc.fIndexArray);
+    }
+
+    GR_GL(DrawElements(gPrimitiveType2GLMode[type], indexCount,
+                       GL_UNSIGNED_SHORT, indices));
+}
+
+void GrGpuGL::drawNonIndexedHelper(PrimitiveType type,
+                                   uint32_t startVertex,
+                                   uint32_t vertexCount) {
+    GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
+
+    GR_GL(DrawArrays(gPrimitiveType2GLMode[type], 0, vertexCount));
+}
+
+#if !defined(SK_GL_HAS_COLOR4UB)
+static inline GrFixed byte2fixed(unsigned value) {
+    return (value + (value >> 7)) << 8;
+}
+#endif
+
+void GrGpuGL::resolveTextureRenderTarget(GrGLTexture* texture) {
+    GrGLRenderTarget* rt = (GrGLRenderTarget*) texture->asRenderTarget();
+
+    if (NULL != rt && rt->needsResolve()) {
+        GrAssert(kNone_MSFBO != fMSFBOType);
+        GrAssert(rt->textureFBOID() != rt->renderFBOID());
+        GR_GLEXT(fExts, BindFramebuffer(GR_READ_FRAMEBUFFER,
+                                        rt->renderFBOID()));
+        GR_GLEXT(fExts, BindFramebuffer(GR_DRAW_FRAMEBUFFER,
+                                        rt->textureFBOID()));
+    #if GR_COLLECT_STATS
+        ++fStats.fRenderTargetChngCnt;
+    #endif
+        // make sure we go through set render target
+        fHWDrawState.fRenderTarget = NULL;
+
+        GLint left = 0;
+        GLint right = texture->contentWidth();
+        // we will have rendered to the top of the FBO.
+        GLint top = texture->allocHeight();
+        GLint bottom = texture->allocHeight() - texture->contentHeight();
+        if (kApple_MSFBO == fMSFBOType) {
+            GR_GL(Enable(GL_SCISSOR_TEST));
+            GR_GL(Scissor(left, bottom, right-left, top-bottom));
+            GR_GLEXT(fExts, ResolveMultisampleFramebuffer());
+            fHWBounds.fScissorRect.setEmpty();
+            fHWBounds.fScissorEnabled = true;
+        } else {
+            GR_GLEXT(fExts, BlitFramebuffer(left, bottom, right, top,
+                                     left, bottom, right, top,
+                                     GL_COLOR_BUFFER_BIT, GL_NEAREST));
+        }
+        rt->setDirty(false);
+
+    }
+}
+
+void GrGpuGL::flushStencil() {
+
+    // use stencil for clipping if clipping is enabled and the clip
+    // has been written into the stencil.
+    bool stencilClip = fClipState.fClipInStencil &&
+                       (kClip_StateBit & fCurrDrawState.fFlagBits);
+    bool stencilChange =
+        fWriteMaskChanged                                         ||
+        fHWStencilClip != stencilClip                             ||
+        fHWDrawState.fStencilPass != fCurrDrawState.fStencilPass  ||
+        (kNone_StencilPass != fCurrDrawState.fStencilPass &&
+         (StencilPass)kSetClip_StencilPass != fCurrDrawState.fStencilPass &&
+         fHWDrawState.fReverseFill != fCurrDrawState.fReverseFill);
+
+    if (stencilChange) {
+        GLint stencilBitCount;
+        GLint clipStencilMask;
+        GLint pathStencilMask;
+        GR_GL(GetIntegerv(GL_STENCIL_BITS, &stencilBitCount));
+        GrAssert(stencilBitCount > 0 ||
+                 kNone_StencilPass == fCurrDrawState.fStencilPass);
+        clipStencilMask  = (1 << (stencilBitCount - 1));
+        pathStencilMask = clipStencilMask - 1;
+        switch (fCurrDrawState.fStencilPass) {
+            case kNone_StencilPass:
+                if (stencilClip) {
+                    GR_GL(Enable(GL_STENCIL_TEST));
+                    GR_GL(StencilFunc(GL_EQUAL,
+                                      clipStencilMask,
+                                      clipStencilMask));
+                    GR_GL(StencilOp(GL_KEEP, GL_KEEP, GL_KEEP));
+                } else {
+                    GR_GL(Disable(GL_STENCIL_TEST));
+                }
+                GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+                if (!fSingleStencilPassForWinding) {
+                    GR_GL(Disable(GL_CULL_FACE));
+                }
+                break;
+            case kEvenOddStencil_StencilPass:
+                GR_GL(Enable(GL_STENCIL_TEST));
+                if (stencilClip) {
+                    GR_GL(StencilFunc(GL_EQUAL, clipStencilMask, clipStencilMask));
+                } else {
+                    GR_GL(StencilFunc(GL_ALWAYS, 0x0, 0x0));
+                }
+                GR_GL(StencilMask(pathStencilMask));
+                GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+                GR_GL(StencilOp(GL_KEEP, GL_INVERT, GL_INVERT));
+                GR_GL(ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
+                if (!fSingleStencilPassForWinding) {
+                    GR_GL(Disable(GL_CULL_FACE));
+                }
+                break;
+            case kEvenOddColor_StencilPass: {
+                GR_GL(Enable(GL_STENCIL_TEST));
+                GLint  funcRef  = 0;
+                GLuint funcMask = pathStencilMask;
+                if (stencilClip) {
+                    funcRef  |= clipStencilMask;
+                    funcMask |= clipStencilMask;
+                }
+                if (!fCurrDrawState.fReverseFill) {
+                    funcRef |= pathStencilMask;
+                }
+                glStencilFunc(GL_EQUAL, funcRef, funcMask);
+                glStencilMask(pathStencilMask);
+                GR_GL(StencilOp(GL_ZERO, GL_ZERO, GL_ZERO));
+                GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+                if (!fSingleStencilPassForWinding) {
+                    GR_GL(Disable(GL_CULL_FACE));
+                }
+                } break;
+            case kWindingStencil1_StencilPass:
+                GR_GL(Enable(GL_STENCIL_TEST));
+                if (fHasStencilWrap) {
+                    if (stencilClip) {
+                        GR_GL(StencilFunc(GL_EQUAL,
+                                          clipStencilMask,
+                                          clipStencilMask));
+                    } else {
+                        GR_GL(StencilFunc(GL_ALWAYS, 0x0, 0x0));
+                    }
+                    if (fSingleStencilPassForWinding) {
+                        GR_GL(StencilOpSeparate(GL_FRONT, GL_KEEP,
+                                                GL_INCR_WRAP, GL_INCR_WRAP));
+                        GR_GL(StencilOpSeparate(GL_BACK,  GL_KEEP,
+                                                GL_DECR_WRAP, GL_DECR_WRAP));
+                    } else {
+                        GR_GL(StencilOp(GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP));
+                        GR_GL(Enable(GL_CULL_FACE));
+                        GR_GL(CullFace(GL_BACK));
+                    }
+                } else {
+                    // If we don't have wrap then we use the Func to detect
+                    // values that would wrap (0 on decr and mask on incr). We
+                    // make the func fail on these values and use the sfail op
+                    // to effectively wrap by inverting.
+                    // This applies whether we are doing a two-pass (front faces
+                    // followed by back faces) or a single pass (separate func/op)
+
+                    // Note that in the case where we are also using stencil to
+                    // clip this means we will write into the path bits in clipped
+                    // out pixels. We still apply the clip bit in the color pass
+                    // stencil func so we don't draw color outside the clip.
+                    // We also will clear the stencil bits in clipped pixels by
+                    // using zero in the sfail op with write mask set to the
+                    // path mask.
+                    GR_GL(Enable(GL_STENCIL_TEST));
+                    if (fSingleStencilPassForWinding) {
+                        GR_GL(StencilFuncSeparate(GL_FRONT,
+                                                  GL_NOTEQUAL,
+                                                  pathStencilMask,
+                                                  pathStencilMask));
+                        GR_GL(StencilFuncSeparate(GL_BACK,
+                                                  GL_NOTEQUAL,
+                                                  0x0,
+                                                  pathStencilMask));
+                        GR_GL(StencilOpSeparate(GL_FRONT, GL_INVERT,
+                                                GL_INCR, GL_INCR));
+                        GR_GL(StencilOpSeparate(GL_BACK,  GL_INVERT,
+                                                GL_DECR, GL_DECR));
+                    } else {
+                        GR_GL(StencilFunc(GL_NOTEQUAL,
+                                          pathStencilMask,
+                                          pathStencilMask));
+                        GR_GL(StencilOp(GL_INVERT, GL_INCR, GL_INCR));
+                        GR_GL(Enable(GL_CULL_FACE));
+                        GR_GL(CullFace(GL_BACK));
+                    }
+                }
+                GR_GL(StencilMask(pathStencilMask));
+                GR_GL(ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
+                break;
+            case kWindingStencil2_StencilPass:
+                GrAssert(!fSingleStencilPassForWinding);
+                GR_GL(Enable(GL_STENCIL_TEST));
+                if (fHasStencilWrap) {
+                    if (stencilClip) {
+                        GR_GL(StencilFunc(GL_EQUAL,
+                                          clipStencilMask,
+                                          clipStencilMask));
+                    } else {
+                        GR_GL(StencilFunc(GL_ALWAYS, 0x0, 0x0));
+                    }
+                    GR_GL(StencilOp(GL_DECR_WRAP, GL_DECR_WRAP, GL_DECR_WRAP));
+                } else {
+                    GR_GL(StencilFunc(GL_NOTEQUAL, 0x0, pathStencilMask));
+                    GR_GL(StencilOp(GL_INVERT, GL_DECR, GL_DECR));
+                }
+                GR_GL(StencilMask(pathStencilMask));
+                GR_GL(Enable(GL_CULL_FACE));
+                GR_GL(CullFace(GL_FRONT));
+                GR_GL(ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
+                break;
+            case kWindingColor_StencilPass: {
+                GR_GL(Enable(GL_STENCIL_TEST));
+                GLint  funcRef   = 0;
+                GLuint funcMask  = pathStencilMask;
+                GLenum funcFunc;
+                if (stencilClip) {
+                    funcRef  |= clipStencilMask;
+                    funcMask |= clipStencilMask;
+                }
+                if (fCurrDrawState.fReverseFill) {
+                    funcFunc = GL_EQUAL;
+                } else {
+                    funcFunc = GL_LESS;
+                }
+                GR_GL(StencilFunc(funcFunc, funcRef, funcMask));
+                GR_GL(StencilMask(pathStencilMask));
+                // must zero in sfail because winding w/o wrap will write
+                // path stencil bits in clipped out pixels
+                GR_GL(StencilOp(GL_ZERO, GL_ZERO, GL_ZERO));
+                GR_GL(ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+                if (!fSingleStencilPassForWinding) {
+                    GR_GL(Disable(GL_CULL_FACE));
+                }
+                } break;
+            case kSetClip_StencilPass:
+                GR_GL(Enable(GL_STENCIL_TEST));
+                GR_GL(StencilFunc(GL_ALWAYS, clipStencilMask, clipStencilMask));
+                GR_GL(StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE));
+                GR_GL(StencilMask(clipStencilMask));
+                GR_GL(ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
+                if (!fSingleStencilPassForWinding) {
+                    GR_GL(Disable(GL_CULL_FACE));
+                }
+                break;
+            default:
+                GrAssert(!"Unexpected stencil pass.");
+                break;
+
+        }
+        fHWDrawState.fStencilPass = fCurrDrawState.fStencilPass;
+        fHWDrawState.fReverseFill = fCurrDrawState.fReverseFill;
+        fWriteMaskChanged = false;
+        fHWStencilClip = stencilClip;
+    }
+}
+
+void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
+
+    bool usingTexture = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
+
+    // bind texture and set sampler state
+    if (usingTexture) {
+        GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTexture;
+
+        if (NULL != nextTexture) {
+            // if we created a rt/tex and rendered to it without using a texture
+            // and now we're texuring from the rt it will still be the last bound
+            // texture, but it needs resolving. So keep this out of the last
+            // != next check.
+            resolveTextureRenderTarget(nextTexture);
+
+            if (fHWDrawState.fTexture != nextTexture) {
+
+                GR_GL(BindTexture(GL_TEXTURE_2D, nextTexture->textureID()));
+            #if GR_COLLECT_STATS
+                ++fStats.fTextureChngCnt;
+            #endif
+                //GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
+                fHWDrawState.fTexture = nextTexture;
+            }
+            const GrSamplerState& lastSampler = nextTexture->samplerState();
+            if (lastSampler.isFilter() != fCurrDrawState.fSamplerState.isFilter()) {
+                GLenum filter = fCurrDrawState.fSamplerState.isFilter() ?
+                                                                    GL_LINEAR :
+                                                                    GL_NEAREST;
+                GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+                                    filter));
+                GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+                                    filter));
+            }
+            if (lastSampler.getWrapX() != fCurrDrawState.fSamplerState.getWrapX()) {
+                GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                                    GrGLTexture::gWrapMode2GLWrap[
+                                             fCurrDrawState.fSamplerState.getWrapX()]));
+            }
+            if (lastSampler.getWrapY() != fCurrDrawState.fSamplerState.getWrapY()) {
+                GR_GL(TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                                    GrGLTexture::gWrapMode2GLWrap[
+                                             fCurrDrawState.fSamplerState.getWrapY()]));
+            }
+            nextTexture->setSamplerState(fCurrDrawState.fSamplerState);
+        } else {
+            GrAssert(!"Rendering with texture vert flag set but no texture");
+            if (NULL != fHWDrawState.fTexture) {
+                GR_GL(BindTexture(GL_TEXTURE_2D, 0));
+                //            GrPrintf("---- bindtexture 0\n");
+            #if GR_COLLECT_STATS
+                ++fStats.fTextureChngCnt;
+            #endif
+                fHWDrawState.fTexture = NULL;
+            }
+        }
+    }
+
+    flushRenderTarget();
+
+    if ((fCurrDrawState.fFlagBits & kDither_StateBit) !=
+        (fHWDrawState.fFlagBits & kDither_StateBit)) {
+        if (fCurrDrawState.fFlagBits & kDither_StateBit) {
+            GR_GL(Enable(GL_DITHER));
+        } else {
+            GR_GL(Disable(GL_DITHER));
+        }
+    }
+
+#if GR_GL_DESKTOP
+    // ES doesn't support toggling GL_MULTISAMPLE and doesn't have
+    // smooth lines.
+    if (fRenderTargetChanged ||
+        (fCurrDrawState.fFlagBits & kAntialias_StateBit) !=
+        (fHWDrawState.fFlagBits & kAntialias_StateBit)) {
+        GLint msaa = 0;
+        // only perform query if we know MSAA is supported.
+        // calling on non-MSAA target caused a crash in one environment,
+        // though I don't think it should.
+        if (!fAASamples[kHigh_AALevel]) {
+            GR_GL(GetIntegerv(GL_SAMPLE_BUFFERS, &msaa));
+        }
+        if (fCurrDrawState.fFlagBits & kAntialias_StateBit) {
+            if (msaa) {
+                GR_GL(Enable(GL_MULTISAMPLE));
+            } else {
+                GR_GL(Enable(GL_LINE_SMOOTH));
+            }
+        } else {
+            if (msaa) {
+                GR_GL(Disable(GL_MULTISAMPLE));
+            }
+            GR_GL(Disable(GL_LINE_SMOOTH));
+        }
+    }
+#endif
+
+    bool blendOff = canDisableBlend();
+    if (fHWBlendDisabled != blendOff) {
+        if (blendOff) {
+            GR_GL(Disable(GL_BLEND));
+        } else {
+            GR_GL(Enable(GL_BLEND));
+        }
+        fHWBlendDisabled = blendOff;
+    }
+
+    if (!blendOff) {
+        if (fHWDrawState.fSrcBlend != fCurrDrawState.fSrcBlend ||
+              fHWDrawState.fDstBlend != fCurrDrawState.fDstBlend) {
+            GR_GL(BlendFunc(gXfermodeCoeff2Blend[fCurrDrawState.fSrcBlend],
+                            gXfermodeCoeff2Blend[fCurrDrawState.fDstBlend]));
+            fHWDrawState.fSrcBlend = fCurrDrawState.fSrcBlend;
+            fHWDrawState.fDstBlend = fCurrDrawState.fDstBlend;
+        }
+    }
+
+    // check for circular rendering
+    GrAssert(!usingTexture ||
+             NULL == fCurrDrawState.fRenderTarget ||
+             NULL == fCurrDrawState.fTexture ||
+             fCurrDrawState.fTexture->asRenderTarget() != fCurrDrawState.fRenderTarget);
+
+    flushStencil();
+
+    fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits;
+}
+
+void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) {
+    fHWGeometryState.fVertexBuffer = buffer;
+}
+
+void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
+    GrAssert(!(kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc &&
+               buffer == fGeometrySrc.fVertexBuffer));
+
+    if (fHWGeometryState.fVertexBuffer == buffer) {
+        // deleting bound buffer does implied bind to 0
+        fHWGeometryState.fVertexBuffer = NULL;
+    }
+}
+
+void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
+    fGeometrySrc.fIndexBuffer = buffer;
+}
+
+void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
+    GrAssert(!(kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc &&
+               buffer == fGeometrySrc.fIndexBuffer));
+
+    if (fHWGeometryState.fIndexBuffer == buffer) {
+        // deleting bound buffer does implied bind to 0
+        fHWGeometryState.fIndexBuffer = NULL;
+    }
+}
+
+void GrGpuGL::notifyTextureBind(GrGLTexture* texture) {
+    fHWDrawState.fTexture = texture;
+#if GR_COLLECT_STATS
+    ++fStats.fTextureChngCnt;
+#endif
+}
+
+void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
+    GrAssert(NULL != renderTarget);
+
+    // if the bound FBO is destroyed we can't rely on the implicit bind to 0
+    // a) we want the default RT which may not be FBO 0
+    // b) we set more state than just FBO based on the RT
+    // So trash the HW state to force an RT flush next time
+    if (fCurrDrawState.fRenderTarget == renderTarget) {
+        fCurrDrawState.fRenderTarget = (GrRenderTarget*)&fDefaultRenderTarget;
+    }
+    if (fHWDrawState.fRenderTarget == renderTarget) {
+        fHWDrawState.fRenderTarget = NULL;
+    }
+    if (fClipState.fStencilClipTarget == renderTarget) {
+        fClipState.fStencilClipTarget = NULL;
+    }
+}
+
+void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
+    if (fCurrDrawState.fTexture == texture) {
+        fCurrDrawState.fTexture = NULL;
+    }
+    if (fHWDrawState.fTexture == texture) {
+        // deleting bound texture does implied bind to 0
+        fHWDrawState.fTexture = NULL;
+   }
+}
+
+void GrGpuGL::notifyTextureRemoveRenderTarget(GrGLTexture* texture) {
+    GrAssert(NULL != texture->asRenderTarget());
+
+    // if there is a pending resolve, perform it.
+    resolveTextureRenderTarget(texture);
+}
+
+bool GrGpuGL::canBeTexture(GrTexture::PixelConfig config,
+                           GLenum* internalFormat,
+                           GLenum* format,
+                           GLenum* type) {
+    switch (config) {
+        case GrTexture::kRGBA_8888_PixelConfig:
+        case GrTexture::kRGBX_8888_PixelConfig: // todo: can we tell it our X?
+            *format = SK_GL_32BPP_COLOR_FORMAT;
+            *internalFormat = GL_RGBA;
+            *type = GL_UNSIGNED_BYTE;
+            break;
+        case GrTexture::kRGB_565_PixelConfig:
+            *format = GL_RGB;
+            *internalFormat = GL_RGB;
+            *type = GL_UNSIGNED_SHORT_5_6_5;
+            break;
+        case GrTexture::kRGBA_4444_PixelConfig:
+            *format = GL_RGBA;
+            *internalFormat = GL_RGBA;
+            *type = GL_UNSIGNED_SHORT_4_4_4_4;
+            break;
+        case GrTexture::kIndex_8_PixelConfig:
+            if (this->supports8BitPalette()) {
+                *format = GR_PALETTE8_RGBA8;
+                *internalFormat = GR_PALETTE8_RGBA8;
+                *type = GL_UNSIGNED_BYTE;   // unused I think
+            } else {
+                return false;
+            }
+            break;
+        case GrTexture::kAlpha_8_PixelConfig:
+            *format = GL_ALPHA;
+            *internalFormat = GL_ALPHA;
+            *type = GL_UNSIGNED_BYTE;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+
+/* On ES the internalFormat and format must match for TexImage and we use
+   GL_RGB, GL_RGBA for color formats. We also generally like having the driver
+   decide the internalFormat. However, on ES internalFormat for
+   RenderBufferStorage* has to be a specific format (not a base format like
+   GL_RGBA).
+ */
+bool GrGpuGL::fboInternalFormat(GrTexture::PixelConfig config, GLenum* format) {
+    switch (config) {
+        case GrTexture::kRGBA_8888_PixelConfig:
+        case GrTexture::kRGBX_8888_PixelConfig:
+            if (fRGBA8Renderbuffer) {
+                *format = GR_RGBA8;
+                return true;
+            } else {
+                return false;
+            }
+#if GR_GL_ES // ES2 supports 565. ES1 supports it with FBO extension
+             // desktop GL has no such internal format
+        case GrTexture::kRGB_565_PixelConfig:
+            *format = GR_RGB565;
+            return true;
+#endif
+        case GrTexture::kRGBA_4444_PixelConfig:
+            *format = GL_RGBA4;
+            return true;
+        default:
+            return false;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrGLCheckErr(const char* location, const char* call) {
+    uint32_t err =  glGetError();
+    if (GL_NO_ERROR != err) {
+        GrPrintf("---- glGetError %x", err);
+        if (NULL != location) {
+            GrPrintf(" at\n\t%s", location);
+        }
+        if (NULL != call) {
+            GrPrintf("\n\t\t%s", call);
+        }
+        GrPrintf("\n");
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef void (*glProc)(void);
+
+void get_gl_proc(const char procName[], glProc *address) {
+#if GR_WIN32_BUILD
+    *address = wglGetProcAddress(procName);
+    GrAssert(NULL != *address);
+#elif GR_MAC_BUILD || GR_IOS_BUILD
+    GrAssert(!"Extensions don't need to be initialized!");
+#elif GR_ANDROID_BUILD
+    *address = eglGetProcAddress(procName);
+    GrAssert(NULL != *address);
+#elif GR_LINUX_BUILD
+    GR_STATIC_ASSERT(!"Add environment-dependent implementation here");
+    //*address = glXGetProcAddressARB(procName);
+    //*address = eglGetProcAddress(procName);
+#elif GR_QNX_BUILD
+    *address = eglGetProcAddress(procName);
+    GrAssert(NULL != *address);
+#else
+    // hopefully we're on a system with EGL
+    *address = eglGetProcAddress(procName);
+    GrAssert(NULL != *address);
+#endif
+}
+
+#define GET_PROC(EXT_STRUCT, PROC_NAME, EXT_TAG) \
+    get_gl_proc("gl" #PROC_NAME #EXT_TAG, (glProc*)&EXT_STRUCT-> PROC_NAME);
+
+extern void GrGLInitExtensions(GrGLExts* exts) {
+    exts->GenFramebuffers                   = NULL;
+    exts->BindFramebuffer                   = NULL;
+    exts->FramebufferTexture2D              = NULL;
+    exts->CheckFramebufferStatus            = NULL;
+    exts->DeleteFramebuffers                = NULL;
+    exts->RenderbufferStorage               = NULL;
+    exts->GenRenderbuffers                  = NULL;
+    exts->DeleteRenderbuffers               = NULL;
+    exts->FramebufferRenderbuffer           = NULL;
+    exts->BindRenderbuffer                  = NULL;
+    exts->RenderbufferStorageMultisample    = NULL;
+    exts->BlitFramebuffer                   = NULL;
+    exts->ResolveMultisampleFramebuffer     = NULL;
+    exts->FramebufferTexture2DMultisample   = NULL;
+    exts->MapBuffer                         = NULL;
+    exts->UnmapBuffer                       = NULL;
+
+#if GR_MAC_BUILD
+    exts->GenFramebuffers                   = glGenFramebuffers;
+    exts->BindFramebuffer                   = glBindFramebuffer;
+    exts->FramebufferTexture2D              = glFramebufferTexture2D;
+    exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
+    exts->DeleteFramebuffers                = glDeleteFramebuffers;
+    exts->RenderbufferStorage               = glRenderbufferStorage;
+    exts->GenRenderbuffers                  = glGenRenderbuffers;
+    exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
+    exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
+    exts->BindRenderbuffer                  = glBindRenderbuffer;
+    exts->RenderbufferStorageMultisample    = glRenderbufferStorageMultisample;
+    exts->BlitFramebuffer                   = glBlitFramebuffer;
+    exts->MapBuffer                         = glMapBuffer;
+    exts->UnmapBuffer                       = glUnmapBuffer;
+#elif GR_IOS_BUILD
+    exts->GenFramebuffers                   = glGenFramebuffers;
+    exts->BindFramebuffer                   = glBindFramebuffer;
+    exts->FramebufferTexture2D              = glFramebufferTexture2D;
+    exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
+    exts->DeleteFramebuffers                = glDeleteFramebuffers;
+    exts->RenderbufferStorage               = glRenderbufferStorage;
+    exts->GenRenderbuffers                  = glGenRenderbuffers;
+    exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
+    exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
+    exts->BindRenderbuffer                  = glBindRenderbuffer;
+    exts->RenderbufferStorageMultisample    = glRenderbufferStorageMultisampleAPPLE;
+    exts->ResolveMultisampleFramebuffer     = glResolveMultisampleFramebufferAPPLE;
+    exts->MapBuffer                         = glMapBufferOES;
+    exts->UnmapBuffer                       = glUnmapBufferOES;
+#else
+    GLint major, minor;
+    gl_version(&major, &minor);
+    #if GR_GL_DESKTOP
+    if (major >= 3) {// FBO, FBOMS, and FBOBLIT part of 3.0
+        exts->GenFramebuffers                   = glGenFramebuffers;
+        exts->BindFramebuffer                   = glBindFramebuffer;
+        exts->FramebufferTexture2D              = glFramebufferTexture2D;
+        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
+        exts->DeleteFramebuffers                = glDeleteFramebuffers;
+        exts->RenderbufferStorage               = glRenderbufferStorage;
+        exts->GenRenderbuffers                  = glGenRenderbuffers;
+        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
+        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
+        exts->BindRenderbuffer                  = glBindRenderbuffer;
+        exts->RenderbufferStorageMultisample    = glRenderbufferStorageMultisample;
+        exts->BlitFramebuffer                   = glBlitFramebuffer;
+    } else if (has_gl_extension("GL_ARB_framebuffer_object")) {
+        GET_PROC(exts, GenFramebuffers, ARB);
+        GET_PROC(exts, BindFramebuffer, ARB);
+        GET_PROC(exts, FramebufferTexture2D, ARB);
+        GET_PROC(exts, CheckFramebufferStatus, ARB);
+        GET_PROC(exts, DeleteFramebuffers, ARB);
+        GET_PROC(exts, RenderbufferStorage, ARB);
+        GET_PROC(exts, GenRenderbuffers, ARB);
+        GET_PROC(exts, DeleteRenderbuffers, ARB);
+        GET_PROC(exts, FramebufferRenderbuffer, ARB);
+        GET_PROC(exts, BindRenderbuffer, ARB);
+        GET_PROC(exts, RenderbufferStorageMultisample, ARB);
+        GET_PROC(exts, BlitFramebuffer, ARB);
+    } else {
+        // we require some form of FBO
+        GrAssert(has_gl_extension("GL_EXT_framebuffer_object"));
+        GET_PROC(exts, GenFramebuffers, EXT);
+        GET_PROC(exts, BindFramebuffer, EXT);
+        GET_PROC(exts, FramebufferTexture2D, EXT);
+        GET_PROC(exts, CheckFramebufferStatus, EXT);
+        GET_PROC(exts, DeleteFramebuffers, EXT);
+        GET_PROC(exts, RenderbufferStorage, EXT);
+        GET_PROC(exts, GenRenderbuffers, EXT);
+        GET_PROC(exts, DeleteRenderbuffers, EXT);
+        GET_PROC(exts, FramebufferRenderbuffer, EXT);
+        GET_PROC(exts, BindRenderbuffer, EXT);
+        if (has_gl_extension("GL_EXT_framebuffer_multisample")) {
+            GET_PROC(exts, RenderbufferStorageMultisample, EXT);
+        }
+        if (has_gl_extension("GL_EXT_framebuffer_blit")) {
+            GET_PROC(exts, BlitFramebuffer, EXT);
+        }
+    }
+    // we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
+    exts->MapBuffer     = glMapBuffer;
+    exts->UnmapBuffer   = glUnmapBuffer;
+    #else // !GR_GL_DESKTOP
+    if (major >= 2) {// ES 2.0 supports FBO
+        exts->GenFramebuffers                   = glGenFramebuffers;
+        exts->BindFramebuffer                   = glBindFramebuffer;
+        exts->FramebufferTexture2D              = glFramebufferTexture2D;
+        exts->CheckFramebufferStatus            = glCheckFramebufferStatus;
+        exts->DeleteFramebuffers                = glDeleteFramebuffers;
+        exts->RenderbufferStorage               = glRenderbufferStorage;
+        exts->GenRenderbuffers                  = glGenRenderbuffers;
+        exts->DeleteRenderbuffers               = glDeleteRenderbuffers;
+        exts->FramebufferRenderbuffer           = glFramebufferRenderbuffer;
+        exts->BindRenderbuffer                  = glBindRenderbuffer;
+    } else {
+        // we require some form of FBO
+        GrAssert(has_gl_extension("GL_OES_framebuffer_object"));
+
+        GET_PROC(exts, GenFramebuffers, OES);
+        GET_PROC(exts, BindFramebuffer, OES);
+        GET_PROC(exts, FramebufferTexture2D, OES);
+        GET_PROC(exts, CheckFramebufferStatus, OES);
+        GET_PROC(exts, DeleteFramebuffers, OES);
+        GET_PROC(exts, RenderbufferStorage, OES);
+        GET_PROC(exts, GenRenderbuffers, OES);
+        GET_PROC(exts, DeleteRenderbuffers, OES);
+        GET_PROC(exts, FramebufferRenderbuffer, OES);
+        GET_PROC(exts, BindRenderbuffer, OES);
+    }
+    if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
+        GET_PROC(exts, ResolveMultisampleFramebuffer, APPLE);
+    }
+    if (has_gl_extension("GL_IMG_multisampled_render_to_texture")) {
+        GET_PROC(exts, FramebufferTexture2DMultisample, IMG);
+    }
+    if (has_gl_extension("GL_OES_mapbuffer")) {
+        GET_PROC(exts, MapBuffer, OES);
+        GET_PROC(exts, UnmapBuffer, OES);
+    }
+    #endif // !GR_GL_DESKTOP
+#endif // BUILD
+}
+
+bool gPrintGL = true;
+
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
new file mode 100644
index 0000000..bedb85a
--- /dev/null
+++ b/gpu/src/GrGpuGL.h
@@ -0,0 +1,188 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGL_DEFINED
+#define GrGpuGL_DEFINED
+
+#include "GrGpu.h"
+#include "GrGLConfig.h"
+#include "GrGLTexture.h"
+
+#include "GrGLVertexBuffer.h"
+#include "GrGLIndexBuffer.h"
+
+class GrGpuGL : public GrGpu {
+public:
+            GrGpuGL();
+    virtual ~GrGpuGL();
+
+    // overrides from GrGpu
+    virtual void resetContext();
+
+    virtual GrTexture* createTexture(const TextureDesc& desc,
+                                     const void* srcData, size_t rowBytes);
+    virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
+    virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
+
+    virtual GrRenderTarget* createPlatformRenderTarget(
+                                                 intptr_t platformRenderTarget,
+                                                 int width, int height);
+
+    virtual GrRenderTarget* defaultRenderTarget();
+
+    virtual void setDefaultRenderTargetSize(uint32_t width, uint32_t height);
+
+    virtual void eraseColor(GrColor color);
+
+    virtual void forceRenderTargetFlush();
+
+    virtual bool readPixels(int left, int top, int width, int height,
+                            GrTexture::PixelConfig, void* buffer);
+
+    /**
+     * Gets the struct containing the GL extensions for the context
+     * underlying the GrGpuGL
+     *
+     * @param struct containing extension function pointers
+     */
+    const GrGLExts& extensions() { return fExts; }
+
+protected:
+    struct {
+        const void*
+        fPositionPtr;
+        GrVertexLayout          fVertexLayout;
+        const GrVertexBuffer*   fVertexBuffer;
+        const GrIndexBuffer*    fIndexBuffer;
+    } fHWGeometryState;
+
+    DrawState   fHWDrawState;
+    bool        fHWStencilClip;
+
+    virtual void drawIndexedHelper(PrimitiveType type,
+                                   uint32_t startVertex,
+                                   uint32_t startIndex,
+                                   uint32_t vertexCount,
+                                   uint32_t indexCount);
+
+    virtual void drawNonIndexedHelper(PrimitiveType type,
+                                      uint32_t vertexCount,
+                                      uint32_t numVertices);
+
+    virtual void flushScissor(const GrIRect* rect);
+
+    void eraseStencil(uint32_t value, uint32_t mask);
+    virtual void eraseStencilClip();
+
+    // flushes state that is common to fixed and programmable GL
+    // dither
+    // line smoothing
+    // blend func
+    // texture binding
+    // sampler state (filtering, tiling)
+    // FBO binding
+    // line width
+    void flushGLStateCommon(PrimitiveType type);
+
+    // pushes the filtering and tiling modes to GL
+    void setSamplerStateImm(const GrSamplerState& samplerState);
+
+    // set when this class changes the rendertarget.
+    // Subclass should notice at flush time, take appropriate action,
+    // and set false.
+    bool fRenderTargetChanged;
+
+    // set by eraseColor or eraseStencil. Picked up in in flushStencil.
+    bool fWriteMaskChanged;
+
+    // last scissor / viewport scissor state seen by the GL.
+    BoundsState fHWBounds;
+
+private:
+    GrGLExts fExts;
+
+    GrGLRenderTarget* fDefaultRenderTarget;
+
+    void resetContextHelper();
+
+    // notify callbacks to update state tracking when related
+    // objects are bound to GL or deleted outside of the class
+    void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
+    void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer);
+    void notifyIndexBufferBind(const GrGLIndexBuffer* buffer);
+    void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer);
+    void notifyTextureBind(GrGLTexture* texture);
+    void notifyTextureDelete(GrGLTexture* texture);
+    void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
+    void notifyTextureRemoveRenderTarget(GrGLTexture* texture);
+
+    void flushRenderTarget();
+    void flushStencil();
+    void resolveTextureRenderTarget(GrGLTexture* texture);
+
+    bool canBeTexture(GrTexture::PixelConfig config,
+                      GLenum* internalFormat,
+                      GLenum* format,
+                      GLenum* type);
+    bool fboInternalFormat(GrTexture::PixelConfig config, GLenum* format);
+
+    friend class GrGLVertexBuffer;
+    friend class GrGLIndexBuffer;
+    friend class GrGLTexture;
+    friend class GrGLRenderTarget;
+
+    bool fHWBlendDisabled;
+
+    GLuint fAASamples[4];
+    enum {
+        kNone_MSFBO = 0,
+        kDesktop_MSFBO,
+        kApple_MSFBO,
+        kIMG_MSFBO
+    } fMSFBOType;
+
+    // Do we have stencil wrap ops.
+    bool fHasStencilWrap;
+
+    // ES requires an extension to support RGBA8 in RenderBufferStorage
+    bool fRGBA8Renderbuffer;
+
+    typedef GrGpu INHERITED;
+};
+
+bool has_gl_extension(const char* ext);
+void gl_version(int* major, int* minor);
+
+/**
+ *  GrGL_RestoreResetRowLength() will reset GL_UNPACK_ROW_LENGTH to 0. We write
+ *  this wrapper, since GL_UNPACK_ROW_LENGTH is not available on all GL versions
+ */
+#if GR_GL_DESKTOP
+    static inline void GrGL_RestoreResetRowLength() {
+        GR_GL(PixelStorei(GL_UNPACK_ROW_LENGTH, 0));
+    }
+#else
+    #define GrGL_RestoreResetRowLength()
+#endif
+
+#if SK_TextGLType != GL_FIXED
+    #define SK_GL_HAS_COLOR4UB
+#endif
+
+#endif
+
+
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
new file mode 100644
index 0000000..77bec40
--- /dev/null
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -0,0 +1,342 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLConfig.h"
+
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+
+#include "GrGpuGLFixed.h"
+#include "GrGpuVertex.h"
+
+#define SKIP_CACHE_CHECK    true
+
+struct GrGpuMatrix {
+    GrScalar    fMat[16];
+    
+    void reset() {
+        Gr_bzero(fMat, sizeof(fMat));
+        fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
+    }
+    
+    void set(const GrMatrix& m) {
+        Gr_bzero(fMat, sizeof(fMat));
+        fMat[0]  = m[GrMatrix::kScaleX];
+        fMat[4]  = m[GrMatrix::kSkewX];
+        fMat[12] = m[GrMatrix::kTransX];
+        
+        fMat[1]  = m[GrMatrix::kSkewY];
+        fMat[5]  = m[GrMatrix::kScaleY];
+        fMat[13] = m[GrMatrix::kTransY];
+        
+        fMat[3]  = m[GrMatrix::kPersp0];
+        fMat[7]  = m[GrMatrix::kPersp1];
+        fMat[15] = m[GrMatrix::kPersp2];
+        
+        fMat[10] = GR_Scalar1;    // z-scale
+    }
+};
+
+// these must match the order in the corresponding enum in GrGpu.h
+static const GLenum gMatrixMode2Enum[] = {
+    GL_MODELVIEW, GL_TEXTURE
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrGpuGLFixed::GrGpuGLFixed() {
+    resetContextHelper();
+}
+
+GrGpuGLFixed::~GrGpuGLFixed() {
+}
+
+void GrGpuGLFixed::resetContext() {
+    INHERITED::resetContext();
+    resetContextHelper();
+}
+
+void GrGpuGLFixed::resetContextHelper() {
+    GR_GL(Disable(GL_TEXTURE_2D));
+
+    GR_GL(EnableClientState(GL_VERTEX_ARRAY));    
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,   GL_MODULATE));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,      GL_TEXTURE0));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,      GL_PRIMARY_COLOR));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,  GL_SRC_COLOR));
+
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR));
+    GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA));
+    
+    // this changes between GL_SRC_COLR and GL_SRC_ALPHA depending upon
+    // whether we have a (premultiplied) RGBA texture or just an ALPHA texture
+    //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,  GL_SRC_COLOR);
+    fHWRGBOperand0 = (TextureEnvRGBOperands) -1;    
+
+    GR_GL(ClientActiveTexture(GL_TEXTURE0));
+
+    fHWGeometryState.fVertexLayout = 0;
+    fHWGeometryState.fPositionPtr  = (void*) ~0;
+    GR_GL(EnableClientState(GL_VERTEX_ARRAY));
+    GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+    GR_GL(ShadeModel(GL_FLAT));
+    GR_GL(DisableClientState(GL_COLOR_ARRAY));
+    
+    GrGLClearErr();
+    fTextVerts = false;
+
+    fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal    
+    fBaseVertex = 0xffffffff;
+}
+
+
+void GrGpuGLFixed::flushProjectionMatrix() {
+    float mat[16];
+    Gr_bzero(mat, sizeof(mat));
+    
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    
+    mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
+    mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
+    mat[10] = -1.f;
+    mat[15] = 1;
+    
+    mat[12] = -1.f;
+    mat[13] = 1.f;
+    
+    GR_GL(MatrixMode(GL_PROJECTION));
+    GR_GL(LoadMatrixf(mat));
+}
+
+bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
+    
+    bool usingTexture = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
+
+    if (usingTexture && fCurrDrawState.fSamplerState.isGradient()) {
+        unimpl("Fixed pipe doesn't support radial/sweep gradients");
+        return false;
+    }
+    
+    flushGLStateCommon(type);
+
+    if (fRenderTargetChanged) {    
+        flushProjectionMatrix();
+        fRenderTargetChanged = false;
+    }
+
+    bool wasUsingTexture = VertexHasTexCoords(fHWGeometryState.fVertexLayout);
+    if (usingTexture != wasUsingTexture) {
+        if (usingTexture) {
+            GR_GL(Enable(GL_TEXTURE_2D));
+        } else {
+            GR_GL(Disable(GL_TEXTURE_2D));
+        }
+    }
+    
+    uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
+    uint32_t prevVertColor = (fHWGeometryState.fVertexLayout & 
+                              kColor_VertexLayoutBit);
+    
+    if (vertColor != prevVertColor) {
+        if (vertColor) {
+            GrAssert(fCurrDrawState.fSamplerState.getSampleMode() != 
+                     GrSamplerState::kAlphaMod_SampleMode);
+            GR_GL(ShadeModel(GL_SMOOTH));
+            // invalidate the immediate mode color
+            fHWDrawState.fColor = GrColor_ILLEGAL;
+        } else {
+            GR_GL(ShadeModel(GL_FLAT));
+        }
+    }
+
+    if (kPoints_PrimitiveType == type &&
+        fHWDrawState.fPointSize != fCurrDrawState.fPointSize) {
+        GR_GL(PointSize(fCurrDrawState.fPointSize));
+        fHWDrawState.fPointSize = fCurrDrawState.fPointSize;
+    }
+    
+    if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
+        GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
+                       GrColorUnpackG(fCurrDrawState.fColor),
+                       GrColorUnpackB(fCurrDrawState.fColor),
+                       GrColorUnpackA(fCurrDrawState.fColor)));
+        fHWDrawState.fColor = fCurrDrawState.fColor;
+    }
+
+    // set texture environment, decide whether we are modulating by RGB or A.
+    if (usingTexture) {
+        GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTexture;
+        if (NULL != texture) {
+            TextureEnvRGBOperands nextRGBOperand0 = 
+                (texture->uploadFormat() == GL_ALPHA) ? 
+                    kAlpha_TextureEnvRGBOperand : 
+                    kColor_TextureEnvRGBOperand;
+            if (fHWRGBOperand0 != nextRGBOperand0) {
+                GR_GL(TexEnvi(GL_TEXTURE_ENV, 
+                              GL_OPERAND0_RGB,
+                              (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ? 
+                                GL_SRC_ALPHA : 
+                                GL_SRC_COLOR));
+                fHWRGBOperand0 = nextRGBOperand0;
+            }
+            
+            if (fHWTextureOrientation != texture->orientation() ||
+                fHWDrawState.fMatrixModeCache[kTexture_MatrixMode] != 
+                fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]) {
+                GrGpuMatrix glm;
+                if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
+                    GrMatrix m(
+                        GR_Scalar1, 0, 0,
+                        0, -GR_Scalar1, GR_Scalar1,
+                        0, 0, GrMatrix::I()[8]
+                    );
+                    m.preConcat(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+                    glm.set(m);
+                } else {
+                    glm.set(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+                }
+                GR_GL(MatrixMode(gMatrixMode2Enum[kTexture_MatrixMode]));
+                GR_GL(LoadMatrixf(glm.fMat));
+                fHWDrawState.fMatrixModeCache[kTexture_MatrixMode] = 
+                    fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
+                fHWTextureOrientation = texture->orientation();
+            }
+        } else {
+            GrAssert(!"Rendering with texture vert flag set but no bound texture");
+            return false;
+        }
+    }
+
+    if (fHWDrawState.fMatrixModeCache[kModelView_MatrixMode] != 
+        fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
+        GrGpuMatrix glm;
+        glm.set(fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
+        GR_GL(MatrixMode(gMatrixMode2Enum[kModelView_MatrixMode]));
+        GR_GL(LoadMatrixf(glm.fMat));
+        fHWDrawState.fMatrixModeCache[kModelView_MatrixMode] = 
+            fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    }
+    return true;
+}
+
+void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
+                                 uint32_t startIndex,
+                                 uint32_t vertexCount,
+                                 uint32_t indexCount) {
+    
+    int newColorOffset, newTexCoordOffset;
+    
+    GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
+                                             &newTexCoordOffset, 
+                                             &newColorOffset);
+    int oldColorOffset, oldTexCoordOffset;
+    GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
+                                             &oldTexCoordOffset, 
+                                             &oldColorOffset);
+    
+    const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
+    
+    if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+        GrAssert(NULL != fGeometrySrc.fVertexBuffer);
+        GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
+        if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
+            GrGLVertexBuffer* buf = 
+            (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
+            GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
+            fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        }
+    } else { 
+        if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+            posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray + 
+                             (intptr_t)posPtr);
+        } else {
+            GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
+            posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);            
+        }
+        if (NULL != fHWGeometryState.fVertexBuffer) {
+            GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
+            fHWGeometryState.fVertexBuffer = NULL;
+        }
+    }
+    
+    if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
+        GrAssert(NULL != fGeometrySrc.fIndexBuffer);
+        GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
+        if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
+            GrGLIndexBuffer* buf = 
+            (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+            GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
+            fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+        }
+    } else if (NULL != fHWGeometryState.fIndexBuffer) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+        fHWGeometryState.fIndexBuffer = NULL;
+    }
+    
+    GLenum scalarType;
+    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+        scalarType = GrGLTextType;
+    } else {
+        scalarType = GrGLType;
+    }
+    
+    bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
+    bool scalarChange = 
+        (GrGLTextType != GrGLType) &&
+        (kTextFormat_VertexLayoutBit &
+         (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout));
+    bool strideChange = newStride != oldStride;
+    bool posChange = baseChange || scalarChange || strideChange;
+    
+    if (posChange) {
+        GR_GL(VertexPointer(2, scalarType, newStride, posPtr));
+        fHWGeometryState.fPositionPtr = posPtr;
+    }
+    
+    // need to enable array if tex coord offset is 0 (using positions as coords)
+    if (newTexCoordOffset >= 0) {
+        GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffset;
+        if (oldTexCoordOffset < 0) {
+            GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
+        }
+        if (posChange || newTexCoordOffset != oldTexCoordOffset) {
+            GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
+        }
+    } else if (oldTexCoordOffset >= 0) {
+        GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+    }
+    
+    if (newColorOffset > 0) {
+        GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+        if (oldColorOffset <= 0) {
+            GR_GL(EnableClientState(GL_COLOR_ARRAY));
+        }
+        if (posChange || newColorOffset != oldColorOffset) {
+            GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorPtr));
+        }
+    } else if (oldColorOffset > 0) {
+        GR_GL(DisableClientState(GL_COLOR_ARRAY));
+    }
+    
+    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+}
+
+#endif
+
diff --git a/gpu/src/GrGpuGLFixed.h b/gpu/src/GrGpuGLFixed.h
new file mode 100644
index 0000000..f3a0332
--- /dev/null
+++ b/gpu/src/GrGpuGLFixed.h
@@ -0,0 +1,68 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGLFixed_DEFINED
+#define GrGpuGLFixed_DEFINED
+
+#include "GrGpuGL.h"
+
+// Fixed Pipeline OpenGL or OpenGL ES 1.x
+class GrGpuGLFixed : public GrGpuGL {
+public:
+             GrGpuGLFixed();
+    virtual ~GrGpuGLFixed();
+    
+    virtual void resetContext();
+
+protected:
+    // overrides from GrGpu
+    virtual bool flushGraphicsState(PrimitiveType type);
+    virtual void setupGeometry(uint32_t startVertex,
+                               uint32_t startIndex,
+                               uint32_t vertexCount,
+                               uint32_t indexCount);
+
+private:
+    void resetContextHelper();
+
+    // when the texture is GL_RGBA we set the GL_COMBINE texture
+    // environment rgb operand 0 to be GL_COLOR to modulate each incoming frag's
+    // RGB by the texture's RGB. When the texture is GL_ALPHA we set
+    // the operand to GL_ALPHA so that the incoming frag's RGB is modulated
+    // by the texture's alpha.
+    enum TextureEnvRGBOperands {
+        kAlpha_TextureEnvRGBOperand,
+        kColor_TextureEnvRGBOperand,
+    };
+    TextureEnvRGBOperands fHWRGBOperand0;
+
+    void flushProjectionMatrix();
+
+    // are the currently bound vertex buffers/arrays laid
+    // out for text or other drawing.
+    bool fTextVerts;
+
+    // On GL we have to build the base vertex offset into the
+    // glVertexPointer/glTexCoordPointer/etc
+    int fBaseVertex;
+
+    GrGLTexture::Orientation fHWTextureOrientation;
+
+    typedef GrGpuGL INHERITED;
+};
+
+#endif
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
new file mode 100644
index 0000000..8f4bfaf
--- /dev/null
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -0,0 +1,937 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLConfig.h"
+
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+
+#include "GrGpuGLShaders.h"
+#include "GrGpuVertex.h"
+#include "GrMemory.h"
+
+#define ATTRIBUTE_MATRIX        0
+
+#define ATTRIBUTE_TEXT_COLOR    1
+
+#if ATTRIBUTE_MATRIX
+    #define DECL_MATRIX(name) "attribute mat3 " #name ";\n"
+#else
+    #define DECL_MATRIX(name) "uniform mat3 " #name ";\n"
+#endif
+
+#define SKIP_CACHE_CHECK    true
+
+#if GR_SUPPORT_GLES2
+    #define GR_PRECISION            "mediump"
+    #define GR_SHADER_PRECISION     "precision mediump float;\n"
+#else
+    #define GR_PRECISION            ""
+    #define GR_SHADER_PRECISION     ""
+#endif
+
+static const char* gvshad[] = {
+    // 0: kTextureVertCoords_Program, kTextureVertCoordsProj_Program,
+    //    kRadialTextureVertCoords_Program, kSweepTextureVertCoords_Program
+    "attribute vec2 aPosition;\n"
+    "attribute vec4 aColor;\n"
+    "varying vec3 vTexture;\n"
+    "varying vec4 vColor;\n"
+    DECL_MATRIX(viewM)
+    DECL_MATRIX(texM)
+    "void main() {\n"
+    "   vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "   gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "   gl_PointSize = 1.0;\n"
+    "   vTexture = texM * vec3(aPosition,1);\n"
+    "   vColor = aColor;\n"
+    "}\n",
+
+    // 1: kTextureTexCoords_Program, kTextureTexCoordsProj_Program,
+    //    kRadialTextureTexCoords_Program, kSweepTextureTexCoords_Program
+    "attribute vec2 aPosition;\n"
+    "attribute vec2 aTexture;\n"
+    "attribute vec4 aColor;\n"
+    "varying vec3 vTexture;\n"
+    "varying vec4 vColor;\n"
+    DECL_MATRIX(viewM)
+    DECL_MATRIX(texM)
+    "void main() {\n"
+    "   vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "   gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "   gl_PointSize = 1.0;\n"
+    "   vTexture = texM * vec3(aTexture,1);\n"
+    "   vColor = aColor;\n"
+    "}\n",
+
+     // 2: kText_Program
+    "attribute vec2 aPosition;\n"
+    "attribute vec2 aTexture;\n"    
+    "varying vec2 vTexture;\n"
+    DECL_MATRIX(viewM)
+#if ATTRIBUTE_TEXT_COLOR
+    "varying vec4 vColor;\n"
+    "attribute vec4 aColor;\n"
+#endif
+    "void main() {\n"
+    "   vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "   gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "   vTexture = aTexture;\n"
+#if ATTRIBUTE_TEXT_COLOR
+    "   vColor = aColor;\n"
+#endif
+    "}\n",
+
+    // 3: kNoTexture_Program
+    "attribute vec2 aPosition;\n"
+    "attribute vec4 aColor;\n"
+    "varying vec4 vColor;\n"
+    DECL_MATRIX(viewM)
+    "void main() {\n"
+    "   vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "   gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "   gl_PointSize = 1.0;\n"
+    "   vColor = aColor;\n"
+    "}\n",
+
+    // 4: kTextureVertCoordsNoColor_Program
+    "attribute vec2 aPosition;\n"
+    "attribute vec4 aColor;\n"
+    "varying vec3 vTexture;\n"
+    DECL_MATRIX(viewM)
+    DECL_MATRIX(texM)
+    "void main() {\n"
+    "   vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "   gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "   vTexture = texM * vec3(aPosition,1);\n"
+    "}\n",
+
+    // 5: kTextureTexCoordsNoColor_Program
+    "attribute vec2 aPosition;\n"
+    "attribute vec2 aTexture;\n"
+    "varying vec3 vTexture;\n"
+    DECL_MATRIX(viewM)
+    DECL_MATRIX(texM)
+    "void main() {\n"
+    "   vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "   gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "   gl_PointSize = 1.0;\n"
+    "   vTexture = texM * vec3(aTexture,1);\n"
+    "}\n",
+
+    // 6: kTwoPointRadialTextureVertCoords_Program
+    "uniform " GR_PRECISION " float uParams[6];\n" 
+        // 0 is t^2 term of quadratic 
+        // 1 is one-half the inverse of above
+        // 2 is x offset of the second circle (post tex-matrix)
+        // 3 is the radius of the first circle (post tex-matrix)
+        // 4 is the first circle radius squared
+        // 5 is 1 to use + in the quadratic eq or -1 to use -
+    DECL_MATRIX(viewM)
+    DECL_MATRIX(texM)
+    "attribute vec2 aPosition;\n"
+    "attribute vec4 aColor;\n"
+    "varying vec4 vColor;\n"
+    "varying float vB;\n"           // t coeffecient of quadratic.
+    "varying vec2 t;\n"             // coordinates in canonical space
+    "void main() {\n"
+    "    vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "    gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "    t = vec2(texM * vec3(aPosition,1));\n"
+    "    vColor = aColor;\n"
+    "    vB = 2.0 * (uParams[2] * t.x - uParams[3]);\n"
+    "}\n",
+
+    // 6: kTwoPointRadialTextureVertCoords_Program
+    "uniform " GR_PRECISION " float uParams[6];\n" 
+    DECL_MATRIX(viewM)
+    DECL_MATRIX(texM)
+    "attribute vec2 aPosition;\n"
+    "attribute vec2 aTexture;\n"
+    "attribute vec4 aColor;\n"
+    "varying vec4 vColor;\n"
+    "varying float vB;\n"           // t coeffecient of quadratic.
+    "varying vec2 t;\n"             // coordinates in canonical space
+    "void main() {\n"
+    "    vec3 pos3 = viewM*vec3(aPosition,1);\n"
+    "    gl_Position = vec4(pos3.xy,0,pos3.z);\n"
+    "    t = vec2(texM * vec3(aTexture,1));\n"
+    "    vColor = aColor;\n"
+    "    vB = 2.0 * (uParams[2] * t.x - uParams[3]);\n"
+    "}\n",
+};
+
+static const char* gfshad[] = {
+    // 0: kTextureVertCoords_Program, kTextureTexCoords_Program
+    GR_SHADER_PRECISION
+    "varying vec3 vTexture;\n"
+    "varying vec4 vColor;\n"
+    "uniform sampler2D sTexture;\n"
+    "void main() {\n"
+    "   gl_FragColor = vColor * texture2D(sTexture, vTexture.xy);\n"
+    "}\n",
+
+    // 1: kTextureVertCoordsProj_Program, kTextureTexCoordsProj_Program
+    GR_SHADER_PRECISION
+    "varying vec3 vTexture;\n"
+    "varying vec4 vColor;\n"
+    "uniform sampler2D sTexture;\n"
+    "void main() {\n"
+    // On Brian's PC laptop with Intel Gfx texture2DProj seems to be broken
+    // but it works everywhere else tested.
+#if GR_GLSL_2DPROJ_BROKEN
+    "   gl_FragColor = vColor * texture2D(sTexture, vTexture.xy / vTexture.z);\n"
+#else
+    "   gl_FragColor = vColor * texture2DProj(sTexture, vTexture);\n"
+#endif
+    
+    "}\n",
+
+    // 2: kText_Program
+    GR_SHADER_PRECISION
+    "varying vec2 vTexture;\n"
+#if ATTRIBUTE_TEXT_COLOR
+    "varying vec4 vColor;\n"
+#else
+    "uniform vec4 uColor;\n"
+#endif
+    "uniform sampler2D sTexture;\n"
+    "void main() {\n"
+#if ATTRIBUTE_TEXT_COLOR
+    "   gl_FragColor = vColor * texture2D(sTexture, vTexture).a;\n"
+#else
+    "   gl_FragColor = uColor * texture2D(sTexture, vTexture).a;\n"
+#endif
+    "}\n",
+
+    // 3: kNoTexture_Program
+    GR_SHADER_PRECISION
+    "varying vec4 vColor;\n"
+    "void main() {\n"
+    "   gl_FragColor = vColor;\n"
+    "}\n",
+
+    // 4: kTextureVertCoordsNoColor_Program
+    GR_SHADER_PRECISION
+    "varying vec3 vTexture;\n"
+    "uniform sampler2D sTexture;\n"
+    "void main() {\n"
+    "   gl_FragColor = texture2D(sTexture, vTexture.xy);\n"
+    "}\n",
+
+    // 5: kRadialTextureVertCoords_Program, kRadialTextureTexCoords_Program
+    GR_SHADER_PRECISION
+    "varying vec3 vTexture;\n"
+    "varying vec4 vColor;\n"
+    "uniform sampler2D sTexture;\n"
+    "void main() {\n"
+    "   gl_FragColor = vColor * texture2D(sTexture, vec2(length(vTexture.xy), 0.5));\n"
+    "}\n",
+
+    // 6: kSweepTextureVertCoords_Program, kSweepTextureTexCoords_Program
+    GR_SHADER_PRECISION
+    "varying vec3 vTexture;\n"
+    "varying vec4 vColor;\n"
+    "uniform sampler2D sTexture;\n"
+    "void main() {\n"
+    "   vec2 t = vec2(atan(-vTexture.y, -vTexture.x)*0.1591549430918 + 0.5,\n"
+    "                 0.5);\n"
+    "   gl_FragColor = vColor * texture2D(sTexture, t);\n"
+    "}\n",
+    
+    // 7: kTwoPointRadialTextureVertCoords_Program, kTwoPointRadialTextureTexCoords_Program
+    GR_SHADER_PRECISION
+    "varying vec4 vColor;\n"
+    "varying float vB;\n"             // t coeffecient of quadratic.
+    "varying vec2 t;\n"               // coordinates in canonical radial gradient space
+    "uniform sampler2D sTexture;\n"
+    "uniform float uParams[6];\n" 
+    "void main() {\n"
+        "float c = t.x*t.x + t.y*t.y - uParams[4];\n"
+        "float ac4 = uParams[0] * c * 4.0;\n"
+        "float root = sqrt(abs(vB * vB - ac4));\n"
+        "float t = (-vB + uParams[5] * root) * uParams[1];\n"
+        "gl_FragColor = vColor * texture2D(sTexture, vec2(t,0.5))\n;"
+    "}\n",
+};
+
+// determines which frag/vert shaders are used for each program in Programs enum
+
+static const struct {
+    int fVShaderIdx;
+    int fFShaderIdx;
+    bool fHasTexMatrix;
+    bool fHasTexCoords;
+    bool fTwoPointRadial;
+    GrGpuGLShaders::ColorType fColorType;    
+} gProgramLoadData[] = {
+    // kTextureVertCoords_Program
+    {0, 0, true,  false, false, GrGpuGLShaders::kAttrib_ColorType }, 
+    // kTextureVertCoordsProj_Program
+    {0, 1, true,  false, false, GrGpuGLShaders::kAttrib_ColorType }, 
+    // kTextureTexCoords_Program
+    {1, 0, true,  true,  false, GrGpuGLShaders::kAttrib_ColorType }, 
+    // kTextureTexCoordsProj_Program
+    {1, 1, true,  true,  false, GrGpuGLShaders::kAttrib_ColorType }, 
+    // kTextureVertCoordsNoColor_Program
+    {4, 4, true,  false, false, GrGpuGLShaders::kNone_ColorType },
+    // kTextureTexCoordsNoColor_Program
+    {5, 4, true,  false, false, GrGpuGLShaders::kNone_ColorType },
+    // kText_Program
+#if ATTRIBUTE_TEXT_COLOR
+    {2, 2, false, true,  false, GrGpuGLShaders::kAttrib_ColorType },
+#else
+    {2, 2, false, true,  false, GrGpuGLShaders::kUniform_ColorType },
+#endif
+    // kRadialTextureVertCoords_Program
+    {0, 5, true,  false, false, GrGpuGLShaders::kAttrib_ColorType }, 
+    // kRadialTextureTexCoords_Program
+    {1, 5, true,  true,  false, GrGpuGLShaders::kAttrib_ColorType },
+    // kSweepTextureVertCoords_Program
+    {0, 6, true,  false, false, GrGpuGLShaders::kAttrib_ColorType }, 
+    // kSweepTextureTexCoords_Program
+    {1, 6, true,  true,  false, GrGpuGLShaders::kAttrib_ColorType },
+    // kTwoPointRadialTextureVertCoords_Program
+    {6, 7, true,  false, true,  GrGpuGLShaders::kAttrib_ColorType },
+    // kTwoPointRadialTextureTexCoords_Program
+    {7, 7, true,  true,  true,  GrGpuGLShaders::kAttrib_ColorType },
+    // kNoTexture_Program
+    {3, 3, false, false, false, GrGpuGLShaders::kAttrib_ColorType },
+};
+
+#define GR_GL_POS_ATTR_LOCATION 0
+#define GR_GL_TEX_ATTR_LOCATION 1
+#define GR_GL_COL_ATTR_LOCATION 2
+#if ATTRIBUTE_MATRIX
+    #define GR_GL_MAT_ATTR_LOCATION 3
+    #define GR_GL_TEXMAT_ATTR_LOCATION 6
+#endif
+
+GLuint GrGpuGLShaders::loadShader(GLenum type, const char* src) {
+    GLuint shader = GR_GL(CreateShader(type));
+    if (0 == shader) {
+        return 0;
+    }
+
+    GLint compiled;
+    GR_GL(ShaderSource(shader, 1, &src, NULL));
+    GR_GL(CompileShader(shader));
+    GR_GL(GetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
+
+    if (!compiled) {
+        GLint infoLen;
+        GR_GL(GetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+        if (infoLen > 0) {            
+            GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get()));
+            GrPrintf((char*)log.get());
+        }
+        GrAssert(!"Shader compilation failed!");
+        GR_GL(DeleteShader(shader));
+        return 0;
+    }
+    return shader;
+}
+
+bool GrGpuGLShaders::createProgram(GLuint vshader, GLuint fshader,
+                                   bool hasTexMatrix,
+                                   bool hasTexCoords,
+                                   GrGpuGLShaders::ColorType colorType,
+                                   bool twoPointRadial,
+                                   ProgramData* program) {
+    program->fProgramID = GR_GL(CreateProgram());
+    program->fVShaderID = vshader;
+    program->fFShaderID = fshader;
+
+    GrAssert(0 != program->fProgramID);
+    
+    GR_GL(AttachShader(program->fProgramID, vshader));
+    GR_GL(AttachShader(program->fProgramID, fshader));
+
+    GR_GL(BindAttribLocation(program->fProgramID, 
+                             GR_GL_POS_ATTR_LOCATION, 
+                             "aPosition"));
+    if (hasTexCoords) {
+        GR_GL(BindAttribLocation(program->fProgramID, 
+                                 GR_GL_TEX_ATTR_LOCATION, 
+                                 "aTexture"));
+    }
+#if ATTRIBUTE_MATRIX
+    if (hasTexMatrix) {
+        GR_GL(BindAttribLocation(program->fProgramID, 
+                                 GR_GL_TEXMAT_ATTR_LOCATION, 
+                                 "texM"));
+        // set to something arbitrary to signal to flush that program
+        // uses the texture matrix.
+        program->fTexMatrixLocation = 1000;
+    }
+#endif
+    if (colorType == kAttrib_ColorType) {
+        GR_GL(BindAttribLocation(program->fProgramID, 
+                                 GR_GL_COL_ATTR_LOCATION, 
+                                 "aColor"));
+    }
+#if ATTRIBUTE_MATRIX
+    GR_GL(BindAttribLocation(program->fProgramID,
+                             GR_GL_MAT_ATTR_LOCATION, 
+                             "viewM"));
+#endif
+
+    GR_GL(LinkProgram(program->fProgramID));
+
+    GLint linked;
+    GR_GL(GetProgramiv(program->fProgramID, GL_LINK_STATUS, &linked));
+    if (!linked) {
+        GLint infoLen;
+        GR_GL(GetProgramiv(program->fProgramID, GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
+        if (infoLen > 0) {            
+            GR_GL(GetProgramInfoLog(program->fProgramID,
+                                    infoLen+1, 
+                                    NULL, 
+                                    (char*)log.get()));
+            GrPrintf((char*)log.get());
+        }
+        GrAssert(!"Error linking program");
+        GR_GL(DeleteProgram(program->fProgramID));
+        program->fProgramID = 0;
+        return false;
+    }
+    program->fColorType = colorType;
+
+#if !ATTRIBUTE_MATRIX
+    program->fMatrixLocation =
+        GR_GL(GetUniformLocation(program->fProgramID, "viewM"));
+    program->fTexMatrixLocation = 
+        GR_GL(GetUniformLocation(program->fProgramID, "texM"));
+#endif
+    program->fColorLocation = 
+        GR_GL(GetUniformLocation(program->fProgramID, "uColor"));
+    program->fTwoPointParamsLocation = 
+        GR_GL(GetUniformLocation(program->fProgramID, "uParams"));
+    
+    GLint samplerLocation = 
+                GR_GL(GetUniformLocation(program->fProgramID, "sTexture"));
+
+#if !ATTRIBUTE_MATRIX   
+    if (-1 == program->fMatrixLocation)    {
+        GrAssert(!"Cannot find matrix uniform in program");
+        GR_GL(DeleteProgram(program->fProgramID));
+        program->fProgramID = 0;
+        return false;
+    }
+#endif
+
+    bool hasTexture = hasTexCoords || hasTexMatrix;
+
+    if (-1 == samplerLocation && hasTexture) {
+        GrAssert(!"Expected to find texture sampler");
+        GR_GL(DeleteProgram(program->fProgramID));
+        program->fProgramID = 0;
+        return false;
+    } else if (-1 != samplerLocation && !hasTexture) {
+        GrAssert(!"unexpectedly found texture sampler");
+    }
+#if !ATTRIBUTE_MATRIX
+    if (-1 == program->fTexMatrixLocation && hasTexMatrix) {
+        GrAssert(!"Expected to find texture matrix");
+        GR_GL(DeleteProgram(program->fProgramID));
+        program->fProgramID = 0;
+        return false;
+    } else if (-1 != program->fTexMatrixLocation && !hasTexMatrix) {
+        GrAssert(!"unexpectedly found texture matrix");
+    }
+#endif
+
+    if (-1 == program->fColorLocation && 
+        (kUniform_ColorType == colorType)) {
+        GR_GL(DeleteProgram(program->fProgramID));
+        program->fProgramID = 0;
+        return false;
+    } else if (-1 != program->fColorLocation && 
+        (kUniform_ColorType != colorType)) {
+        GrAssert(!"Unexpectedly found color uniform");
+    }
+    
+    if (twoPointRadial) {
+        if (-1 == program->fTwoPointParamsLocation) {
+            GrAssert(!"Didn't find expected uniform for 2pt radial gradient");
+            GR_GL(DeleteProgram(program->fProgramID));
+            program->fProgramID = 0;
+            return false;
+        }
+    } else {
+        GrAssert(-1 == program->fTwoPointParamsLocation);
+    }
+    
+    GR_GL(UseProgram(program->fProgramID));
+    if (-1 != samplerLocation) {
+        GR_GL(Uniform1i(samplerLocation, 0));
+    }
+    
+    return true;
+}
+
+GrGpuGLShaders::GrGpuGLShaders() {
+    
+    resetContextHelper();
+    
+    GLuint vshadIDs[GR_ARRAY_COUNT(gvshad)];
+    for (size_t s = 0; s < GR_ARRAY_COUNT(gvshad); ++s) {
+        vshadIDs[s] = loadShader(GL_VERTEX_SHADER, gvshad[s]);
+    }
+
+    GLuint fshadIDs[GR_ARRAY_COUNT(gfshad)];
+    for (size_t s = 0; s < GR_ARRAY_COUNT(gfshad); ++s) {
+        fshadIDs[s] = loadShader(GL_FRAGMENT_SHADER, gfshad[s]);
+    }
+
+    GR_STATIC_ASSERT(kProgramCount == GR_ARRAY_COUNT(gProgramLoadData));
+    for (int p = 0; p < kProgramCount; ++p) {
+        GR_DEBUGCODE(bool result = )
+        createProgram(vshadIDs[gProgramLoadData[p].fVShaderIdx], 
+                      fshadIDs[gProgramLoadData[p].fFShaderIdx],
+                      gProgramLoadData[p].fHasTexMatrix,
+                      gProgramLoadData[p].fHasTexCoords,
+                      gProgramLoadData[p].fColorType,
+                      gProgramLoadData[p].fTwoPointRadial,
+                      &fPrograms[p]);
+        GR_DEBUGASSERT(result);
+        
+        for (int m = 0; m < kMatrixModeCount; ++m) {
+            fPrograms[p].fMatrixModeCache[m].setScale(GR_ScalarMax, 
+                                                      GR_ScalarMax); // illegal
+        };
+        fPrograms[p].fColor = GrColor_ILLEGAL;
+        fPrograms[p].fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
+        
+        // these aren't strictly invalid, just really unlikely.
+        fPrograms[p].fRadial2CenterX1 = GR_ScalarMin;
+        fPrograms[p].fRadial2Radius0  = GR_ScalarMin;
+        fPrograms[p].fRadial2PosRoot  = true; // arbitrary
+    }
+}
+
+GrGpuGLShaders::~GrGpuGLShaders() {
+    // shaders get deleted once for each program that uses them, do we care? 
+    // probably not
+    for (int i = 0; i < kProgramCount; ++i) {
+        GR_GL(DeleteProgram(fPrograms[i].fProgramID));
+        GR_GL(DeleteShader(fPrograms[i].fVShaderID));
+        GR_GL(DeleteShader(fPrograms[i].fFShaderID));
+    }
+}
+
+void GrGpuGLShaders::resetContext() {
+    INHERITED::resetContext();
+    resetContextHelper();
+}
+
+void GrGpuGLShaders::resetContextHelper() {
+    fHWProgram = (Programs)-1;
+    fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
+
+    fHWGeometryState.fVertexLayout = 0;
+    fHWGeometryState.fPositionPtr  = (void*) ~0;
+    GR_GL(DisableVertexAttribArray(GR_GL_COL_ATTR_LOCATION));
+    GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
+    GR_GL(EnableVertexAttribArray(GR_GL_POS_ATTR_LOCATION));
+}
+
+
+void GrGpuGLShaders::flushMatrix(GLint location) {
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrMatrix m (
+        GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
+        0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
+        0, 0, GrMatrix::I()[8]);
+    m.setConcat(m, fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
+    
+    // ES doesn't allow you to pass true to the transpose param, 
+    // so do our own transpose
+    GrScalar mt[]  = {
+        m[GrMatrix::kScaleX],
+        m[GrMatrix::kSkewY],
+        m[GrMatrix::kPersp0],
+        m[GrMatrix::kSkewX],
+        m[GrMatrix::kScaleY],
+        m[GrMatrix::kPersp1],
+        m[GrMatrix::kTransX],
+        m[GrMatrix::kTransY],
+        m[GrMatrix::kPersp2]
+    };
+#if ATTRIBUTE_MATRIX
+    glVertexAttrib4fv(GR_GL_MAT_ATTR_LOCATION+0, mt+0);
+    glVertexAttrib4fv(GR_GL_MAT_ATTR_LOCATION+1, mt+3);
+    glVertexAttrib4fv(GR_GL_MAT_ATTR_LOCATION+2, mt+6);
+#else 
+    GR_GL(UniformMatrix3fv(location,1,false,mt));
+#endif
+}
+
+void GrGpuGLShaders::flushTexMatrix(GLint location, 
+                                    GrGLTexture::Orientation orientation) {
+    GrMatrix* m;
+    GrMatrix temp;
+    if (GrGLTexture::kBottomUp_Orientation == orientation) {
+        temp.setAll(
+            GR_Scalar1, 0, 0,
+            0, -GR_Scalar1, GR_Scalar1,
+            0, 0, GrMatrix::I()[8]
+        );
+        temp.preConcat(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+        m = &temp;
+    } else {
+        GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
+        m = &fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
+    }
+
+    // ES doesn't allow you to pass true to the transpose param,
+    // so do our own transpose
+    GrScalar mt[]  = {
+        (*m)[GrMatrix::kScaleX],
+        (*m)[GrMatrix::kSkewY],
+        (*m)[GrMatrix::kPersp0],
+        (*m)[GrMatrix::kSkewX],
+        (*m)[GrMatrix::kScaleY],
+        (*m)[GrMatrix::kPersp1],
+        (*m)[GrMatrix::kTransX],
+        (*m)[GrMatrix::kTransY],
+        (*m)[GrMatrix::kPersp2]
+    };
+#if ATTRIBUTE_MATRIX
+    glVertexAttrib4fv(GR_GL_TEXMAT_ATTR_LOCATION+0, mt+0);
+    glVertexAttrib4fv(GR_GL_TEXMAT_ATTR_LOCATION+1, mt+3);
+    glVertexAttrib4fv(GR_GL_TEXMAT_ATTR_LOCATION+2, mt+6);
+#else 
+    GR_GL(UniformMatrix3fv(location,1,false,mt));
+#endif 
+}
+
+void GrGpuGLShaders::flushTwoPointRadial(GLint paramsLocation,
+                                         const GrSamplerState& state) {
+    GrScalar centerX1 = state.getRadial2CenterX1();
+    GrScalar radius0 = state.getRadial2Radius0();
+
+    GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
+
+    float unis[6] = {
+        GrScalarToFloat(a),
+        1 / (2.f * unis[0]),
+        GrScalarToFloat(centerX1),
+        GrScalarToFloat(radius0),
+        GrScalarToFloat(GrMul(radius0, radius0)),
+        state.isRadial2PosRoot() ? 1.f : -1.f
+    };
+    GR_GL(Uniform1fv(paramsLocation, 6, unis));
+}
+
+void GrGpuGLShaders::flushProgram(PrimitiveType type) {
+
+    Programs nextProgram = kNoTexture_Program;
+
+    if (!VertexHasTexCoords(fGeometrySrc.fVertexLayout)) {
+        goto HAVE_NEXT_PROGRAM;
+    }
+
+    GrAssert(fCurrDrawState.fTexture);
+
+    switch (fCurrDrawState.fSamplerState.getSampleMode()) {
+        case GrSamplerState::kRadial_SampleMode:
+            GrAssert(!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective());
+            if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+                nextProgram = kRadialTextureVertCoords_Program;
+            } else {
+                nextProgram = kRadialTextureTexCoords_Program;
+            }
+            break;
+        case GrSamplerState::kSweep_SampleMode:
+            GrAssert(!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective());
+            if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+                nextProgram = kSweepTextureVertCoords_Program;
+            } else {
+                nextProgram = kSweepTextureTexCoords_Program;
+            }
+            break;
+        case GrSamplerState::kRadial2_SampleMode:
+            GrAssert(!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective());
+            if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+                nextProgram = kTwoPointRadialTextureVertCoords_Program;
+            } else {
+                nextProgram = kTwoPointRadialTextureTexCoords_Program;
+            }
+            break;
+        case GrSamplerState::kAlphaMod_SampleMode:
+            GrAssert(((GrGLTexture*)fCurrDrawState.fTexture)->orientation() == 
+                     GrGLTexture::kTopDown_Orientation);
+            (((GrGLTexture*)fCurrDrawState.fTexture)->uploadFormat() == GL_ALPHA);
+            
+            nextProgram = kText_Program;
+            break;
+        case GrSamplerState::kNormal_SampleMode: {
+            GR_DEBUGCODE(GrGLTexture* tex = (GrGLTexture*)fCurrDrawState.fTexture;)
+            GrAssert(tex);
+
+            bool persp = fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective();
+
+            if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
+                nextProgram = persp ? kTextureVertCoordsProj_Program : 
+                                      kTextureVertCoords_Program;
+            } else {
+                nextProgram = persp ? kTextureTexCoordsProj_Program : 
+                                      kTextureTexCoords_Program;
+            }
+            // check for case when frag shader can skip the color modulation
+            if (!persp && !(fGeometrySrc.fVertexLayout
+                            & kColor_VertexLayoutBit) &&
+                0xffffffff == fCurrDrawState.fColor) {
+                switch (nextProgram) {
+                case kTextureVertCoords_Program:
+                    nextProgram = kTextureVertCoordsNoColor_Program;
+                    break;
+                case kTextureTexCoords_Program:
+                    nextProgram = kTextureTexCoordsNoColor_Program;
+                    break;
+                default:
+                    GrAssert("Unexpected");
+                    break;
+                }
+            }
+        } break;
+        default:
+            GrAssert(!"Unknown samplemode");
+            break;
+    }
+
+HAVE_NEXT_PROGRAM:
+    if (fHWProgram != nextProgram) {
+        GR_GL(UseProgram(fPrograms[nextProgram].fProgramID));
+        fHWProgram = nextProgram;
+#if GR_COLLECT_STATS
+        ++fStats.fProgChngCnt;
+#endif
+    }
+}
+
+bool GrGpuGLShaders::flushGraphicsState(PrimitiveType type) {
+    
+    flushGLStateCommon(type);
+
+    if (fRenderTargetChanged) {
+        // our coords are in pixel space and the GL matrices map to NDC
+        // so if the viewport changed, our matrix is now wrong.
+#if ATTRIBUTE_MATRIX
+        fHWDrawState.fMatrixModeCache[kModelView_MatrixMode].setScale(GR_ScalarMax,
+                                                                      GR_ScalarMax);
+#else
+        // we assume all shader matrices may be wrong after viewport changes
+        for (int p = 0; p < kProgramCount; ++p) {
+            // set to illegal matrix
+            fPrograms[p].fMatrixModeCache[kModelView_MatrixMode].setScale(GR_ScalarMax, 
+                                                                          GR_ScalarMax); 
+        }
+#endif
+        fRenderTargetChanged = false;
+    }
+    
+    flushProgram(type);
+
+    if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+        // invalidate the immediate mode color
+        fHWDrawState.fColor = GrColor_ILLEGAL;    
+    } else {
+        // if we don't have per-vert colors either set the color attr
+        // or color uniform (depending on which program).
+        if (-1 != fPrograms[fHWProgram].fColorLocation) {
+            GrAssert(kUniform_ColorType == fPrograms[fHWProgram].fColorType);
+            if (fPrograms[fHWProgram].fColor != fCurrDrawState.fColor) {
+                float c[] = {
+                    GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+                    GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+                    GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+                    GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+                };
+                GR_GL(Uniform4fv(fPrograms[fHWProgram].fColorLocation, 1, c));
+                fPrograms[fHWProgram].fColor = fCurrDrawState.fColor;
+            }
+        } else if (kAttrib_ColorType == fPrograms[fHWProgram].fColorType && 
+                   fHWDrawState.fColor != fCurrDrawState.fColor) {
+            // OpenGL ES only supports the float varities of glVertexAttrib
+            float c[] = {
+                GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+            };
+            GR_GL(VertexAttrib4fv(GR_GL_COL_ATTR_LOCATION, c));
+            fHWDrawState.fColor = fCurrDrawState.fColor;
+        }
+    }
+
+#if ATTRIBUTE_MATRIX
+    GrMatrix* currentMats = fHWDrawState.fMatrixModeCache;
+    GrGLTexture::Orientation& orientation = fTextureOrientation; 
+#else
+    GrMatrix* currentMats = fPrograms[fHWProgram].fMatrixModeCache;
+    GrGLTexture::Orientation& orientation = 
+                                    fPrograms[fHWProgram].fTextureOrientation;
+#endif
+
+    if (currentMats[kModelView_MatrixMode] !=
+          fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
+        flushMatrix(fPrograms[fHWProgram].fMatrixLocation);
+        currentMats[kModelView_MatrixMode] = 
+            fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    }
+
+    GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTexture;
+    if (NULL != texture) {
+        if (-1 != fPrograms[fHWProgram].fTexMatrixLocation &&
+            (currentMats[kTexture_MatrixMode] !=
+             fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode] ||
+             orientation != texture->orientation())) {
+            flushTexMatrix(fPrograms[fHWProgram].fTexMatrixLocation,
+                           texture->orientation());
+            currentMats[kTexture_MatrixMode] = 
+                        fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
+            orientation = texture->orientation();
+        }
+    }
+
+    const GrSamplerState& sampler = fCurrDrawState.fSamplerState;
+    if (-1 != fPrograms[fHWProgram].fTwoPointParamsLocation &&
+        (fPrograms[fHWProgram].fRadial2CenterX1 != sampler.getRadial2CenterX1() ||
+         fPrograms[fHWProgram].fRadial2Radius0  != sampler.getRadial2Radius0()  ||
+         fPrograms[fHWProgram].fRadial2PosRoot  != sampler.isRadial2PosRoot())) {
+            
+        flushTwoPointRadial(fPrograms[fHWProgram].fTwoPointParamsLocation,
+                            sampler);
+        fPrograms[fHWProgram].fRadial2CenterX1 = sampler.getRadial2CenterX1();
+        fPrograms[fHWProgram].fRadial2Radius0 = sampler.getRadial2Radius0();
+        fPrograms[fHWProgram].fRadial2PosRoot = sampler.isRadial2PosRoot();
+    }
+    
+    return true;
+}
+
+void GrGpuGLShaders::setupGeometry(uint32_t startVertex,
+                                   uint32_t startIndex,
+                                   uint32_t vertexCount,
+                                   uint32_t indexCount) {
+
+    int newColorOffset, newTexCoordOffset;
+    
+    GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
+                                             &newTexCoordOffset, 
+                                             &newColorOffset);
+    int oldColorOffset, oldTexCoordOffset;
+    GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
+                                             &oldTexCoordOffset, 
+                                             &oldColorOffset);
+    
+    const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
+    
+    if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+        GrAssert(NULL != fGeometrySrc.fVertexBuffer);
+        GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
+        if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
+            GrGLVertexBuffer* buf = 
+            (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
+            GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
+            fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        }
+    } else { 
+        if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+            posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray + 
+                             (intptr_t)posPtr);
+        } else {
+            GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
+            posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);            
+        }
+        if (NULL != fHWGeometryState.fVertexBuffer) {
+            GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
+            fHWGeometryState.fVertexBuffer = NULL;
+        }
+    }
+    
+    if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
+        GrAssert(NULL != fGeometrySrc.fIndexBuffer);
+        GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
+        if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
+            GrGLIndexBuffer* buf = 
+            (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+            GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
+            fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+        }
+    } else if (NULL != fHWGeometryState.fIndexBuffer) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+        fHWGeometryState.fIndexBuffer = NULL;
+    }
+    
+    GLenum scalarType;
+    bool texCoordNorm;
+    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+        scalarType = GrGLTextType;
+        texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
+    } else {
+        scalarType = GrGLType;
+        texCoordNorm = false;
+    }
+    
+    bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
+    bool scalarChange = (GrGLTextType != GrGLType) &&
+                        (kTextFormat_VertexLayoutBit & 
+                         (fHWGeometryState.fVertexLayout ^ 
+                          fGeometrySrc.fVertexLayout));
+    bool strideChange = newStride != oldStride;
+    bool posChange = baseChange || scalarChange || strideChange;
+    
+    if (posChange) {
+        GR_GL(VertexAttribPointer(GR_GL_POS_ATTR_LOCATION, 2, scalarType,
+                                  false, newStride, posPtr));
+        fHWGeometryState.fPositionPtr = posPtr;
+    }
+    
+    if (newTexCoordOffset > 0) {
+        GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffset;
+        if (oldTexCoordOffset <= 0) {
+            GR_GL(EnableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
+        }
+        if (posChange || newTexCoordOffset != oldTexCoordOffset) {
+            GR_GL(VertexAttribPointer(GR_GL_TEX_ATTR_LOCATION, 2, scalarType,
+                                      texCoordNorm, newStride, texCoordPtr));
+        }
+    } else if (oldTexCoordOffset > 0) {
+        GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
+    }
+    
+    if (newColorOffset > 0) {
+        GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+        if (oldColorOffset <= 0) {
+            GR_GL(EnableVertexAttribArray(GR_GL_COL_ATTR_LOCATION));
+        }
+        if (posChange || newColorOffset != oldColorOffset) {
+            GR_GL(VertexAttribPointer(GR_GL_COL_ATTR_LOCATION, 4, 
+                                      GL_UNSIGNED_BYTE,
+                                      true, newStride, colorPtr));
+        }
+    } else if (oldColorOffset > 0) {
+        GR_GL(DisableVertexAttribArray(GR_GL_COL_ATTR_LOCATION));
+    }
+    
+    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+}
+#endif
diff --git a/gpu/src/GrGpuGLShaders.h b/gpu/src/GrGpuGLShaders.h
new file mode 100644
index 0000000..cba387b
--- /dev/null
+++ b/gpu/src/GrGpuGLShaders.h
@@ -0,0 +1,153 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGLShaders_DEFINED
+#define GrGpuGLShaders_DEFINED
+
+#include "GrGpuGL.h"
+
+// Programmable OpenGL or OpenGL ES 2.0
+class GrGpuGLShaders : public GrGpuGL {
+public:
+             GrGpuGLShaders();
+    virtual ~GrGpuGLShaders();
+    
+    virtual void resetContext();
+
+    // type of colors used by a program
+    enum ColorType {
+        kNone_ColorType,
+        kAttrib_ColorType,
+        kUniform_ColorType,
+    };
+protected:
+    // overrides from GrGpu
+    virtual bool flushGraphicsState(PrimitiveType type);
+    virtual void setupGeometry(uint32_t startVertex,
+                               uint32_t startIndex,
+                               uint32_t vertexCount,
+                               uint32_t indexCount);
+    
+private:
+    void resetContextHelper();
+    
+    // sets the texture matrix uniform for currently bound program
+    void flushTexMatrix(GLint location, 
+                        GrGLTexture::Orientation orientation);
+    // sets the MVP matrix uniform for currently bound program
+    void flushMatrix(GLint location);
+    
+    void flushTwoPointRadial(GLint paramsLocation, const GrSamplerState&);
+    
+    // reads shader from array and compiles it with GL, returns shader ID or 0 if failed
+    GLuint loadShader(GLenum type, const char* src);
+    
+    struct ProgramData;
+    // creates a GL program with two shaders attached. 
+    // Gets the relevant uniform locations.
+    // Sets the texture sampler if present to texture 0
+    // Binds the program
+    // returns true if succeeded.
+    bool createProgram(GLuint vshader,
+                       GLuint fshader,
+                       bool hasTexMatrix,
+                       bool hasTexCoords,
+                       ColorType colorType,
+                       bool twoPointRadial,
+                       ProgramData* program);
+
+    // called at flush time to setup the appropriate program
+    void flushProgram(PrimitiveType type);
+
+    enum Programs {
+        // use vertex coordinates         
+        kTextureVertCoords_Program = 0,
+        kTextureVertCoordsProj_Program,
+        
+        // use separate tex coords
+        kTextureTexCoords_Program,
+        kTextureTexCoordsProj_Program,
+
+        // constant color texture, no proj
+        // verts as a tex coords
+        kTextureVertCoordsNoColor_Program,        
+
+        // constant color texture, no proj
+        // separate tex coords
+        kTextureTexCoordsNoColor_Program,
+
+        // special program for text glyphs
+        kText_Program,
+
+        // programs for radial texture lookup
+        kRadialTextureVertCoords_Program,
+        kRadialTextureTexCoords_Program,
+
+        // programs for sweep texture lookup
+        kSweepTextureVertCoords_Program,
+        kSweepTextureTexCoords_Program, 
+        
+        // programs for two-point radial lookup
+        kTwoPointRadialTextureVertCoords_Program,
+        kTwoPointRadialTextureTexCoords_Program,
+        
+        // color only drawing
+        kNoTexture_Program,
+
+        kProgramCount
+    };
+
+    // Records per-program information
+    // we can specify the attribute locations so that they are constant
+    // across our shaders. But the driver determines the uniform locations 
+    // at link time. We don't need to remember the sampler uniform location
+    // because we will bind a texture slot to it and never change it
+    // Uniforms are program-local so we can't rely on fHWState to hold the 
+    // previous uniform state after a program change.
+    struct ProgramData {
+        // IDs
+        GLuint    fVShaderID;
+        GLuint    fFShaderID;
+        GLuint    fProgramID;
+        
+        // shader uniform locations (-1 if shader doesn't use them)
+        GLint     fMatrixLocation;
+        GLint     fTexMatrixLocation;
+        GLint     fColorLocation;
+        GLint     fTwoPointParamsLocation;
+        
+        ColorType fColorType;
+
+        // these reflect the current values of uniforms
+        // (GL uniform values travel with program)
+        GrMatrix                    fMatrixModeCache[kMatrixModeCount];
+        GrColor                     fColor;
+        GrGLTexture::Orientation    fTextureOrientation;
+        GrScalar                    fRadial2CenterX1;
+        GrScalar                    fRadial2Radius0;
+        bool                        fRadial2PosRoot;
+    };
+    
+    ProgramData fPrograms[kProgramCount];
+    Programs    fHWProgram;
+    
+    GrGLTexture::Orientation  fTextureOrientation;
+
+    typedef GrGpuGL INHERITED;
+};
+
+#endif
diff --git a/gpu/src/GrGpuGLShaders2.cpp b/gpu/src/GrGpuGLShaders2.cpp
new file mode 100644
index 0000000..0a15be1
--- /dev/null
+++ b/gpu/src/GrGpuGLShaders2.cpp
@@ -0,0 +1,1388 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrGLConfig.h"
+
+#if GR_SUPPORT_GLES2 || GR_SUPPORT_GLDESKTOP
+
+#include "GrGpuGLShaders2.h"
+#include "GrGpuVertex.h"
+#include "GrMemory.h"
+#include "GrStringBuilder.h"
+
+
+#define ATTRIBUTE_MATRIX        0
+
+#define SKIP_COLOR_MODULATE_OPT 0
+
+#define PRINT_SHADERS           0
+
+#define SKIP_CACHE_CHECK    true
+
+#if GR_SUPPORT_GLES2
+    #define GR_PRECISION                "mediump"
+    const char GR_SHADER_PRECISION[] =  "precision mediump float;\n";
+#else
+    #define GR_PRECISION                ""
+    const char GR_SHADER_PRECISION[] =  "";
+#endif
+
+#define POS_ATTR_LOCATION 0
+#define TEX_ATTR_LOCATION 1
+#define COL_ATTR_LOCATION 2
+#if ATTRIBUTE_MATRIX
+#define VIEWMAT_ATTR_LOCATION 3
+#define TEXMAT_ATTR_LOCATION(X) (6 + 3 * (X))
+#define BOGUS_MATRIX_UNI_LOCATION 1000
+#endif
+
+const int GrGpuGLShaders2::NUM_STAGES = 1;
+
+struct GrGpuGLShaders2::StageUniLocations {
+    GLint fTextureMatrixUni;
+    GLint fSamplerUni;
+    GLint fRadial2Uni;
+};
+
+struct GrGpuGLShaders2::UniLocations {
+    GLint fViewMatrixUni;
+    StageUniLocations fStages[NUM_STAGES];
+};
+
+// Records per-program information
+// we can specify the attribute locations so that they are constant
+// across our shaders. But the driver determines the uniform locations
+// at link time. We don't need to remember the sampler uniform location
+// because we will bind a texture slot to it and never change it
+// Uniforms are program-local so we can't rely on fHWState to hold the
+// previous uniform state after a program change.
+struct  GrGpuGLShaders2::Program {
+    // IDs
+    GLuint    fVShaderID;
+    GLuint    fFShaderID;
+    GLuint    fProgramID;
+
+    // shader uniform locations (-1 if shader doesn't use them)
+    UniLocations fUniLocations;
+
+    // these reflect the current values of uniforms
+    // (GL uniform values travel with program)
+    GrMatrix                    fViewMatrix;
+    GrMatrix                    fTextureMatrix[NUM_STAGES];
+    GrGLTexture::Orientation    fTextureOrientation[NUM_STAGES];
+    GrScalar                    fRadial2CenterX1[NUM_STAGES];
+    GrScalar                    fRadial2Radius0[NUM_STAGES];
+    bool                        fRadial2PosRoot[NUM_STAGES];
+
+};
+
+// must be tightly packed
+struct GrGpuGLShaders2::StageDesc {
+    enum OptFlagBits {
+        kNoPerspective_OptFlagBit  = 0x1,
+        kIdentityMatrix_OptFlagBit = 0x2,
+    };
+    int fOptFlags : 8;
+    bool fEnabled;
+    enum Modulation {
+        kColor_Modulation,
+        kAlpha_Modulation,
+    } fModulation : 8;
+    enum CoordMapping {
+        kIdentity_CoordMapping,
+        kRadialGradient_CoordMapping,
+        kSweepGradient_CoordMapping,
+        kRadial2Gradient_CoordMapping,
+    } fCoordMapping : 8;
+};
+
+// must be tightly packed
+struct GrGpuGLShaders2::ProgramDesc {
+    GrVertexLayout fVertexLayout;
+    enum {
+        kNotPoints_OptFlagBit = 0x1,
+        kVertexColorAllOnes_OptFlagBit = 0x2,
+    };
+    // we're assuming optflags and layout pack into 32 bits
+    GR_STATIC_ASSERT(2 == sizeof(GrVertexLayout));
+    int fOptFlags : 16;
+
+    StageDesc fStages[NUM_STAGES];
+
+    bool operator == (const ProgramDesc& desc) const {
+        // keep 4-byte aligned and tightly packed
+        GR_STATIC_ASSERT(4 == sizeof(StageDesc));
+        GR_STATIC_ASSERT(2 + 2 + 4 * NUM_STAGES == sizeof(ProgramDesc));
+        return 0 == memcmp(this, &desc, sizeof(ProgramDesc));
+    }
+};
+
+#include "GrTHashCache.h"
+
+class GrGpuGLShaders2::ProgramCache : public ::GrNoncopyable {
+private:
+    struct Entry;
+    class HashKey {
+    public:
+        HashKey();
+        HashKey(const ProgramDesc& desc);
+        static const HashKey& GetKey(const Entry&);
+        static bool EQ(const Entry&, const HashKey&);
+        static bool LT(const Entry&, const HashKey&);
+        bool operator <(const HashKey& key) const;
+        bool operator ==(const HashKey& key) const;
+        uint32_t getHash() const;
+    private:
+        ProgramDesc fDesc;
+        uint32_t fHash;
+    };
+
+    struct Entry {
+        Program     fProgram;
+        HashKey     fKey;
+        uint32_t    fLRUStamp;
+    };
+
+    // if hash bits is changed, need to change hash function
+    GrTHashTable<Entry, HashKey, 8> fHashCache;
+
+    static const int MAX_ENTRIES = 16;
+    Entry        fEntries[MAX_ENTRIES];
+    int          fCount;
+    uint32_t     fCurrLRUStamp;
+
+public:
+    ProgramCache() {
+        fCount        = 0;
+        fCurrLRUStamp = 0;
+    }
+
+    ~ProgramCache() {
+        for (int i = 0; i < fCount; ++i) {
+            GrGpuGLShaders2::DeleteProgram(&fEntries[i].fProgram);
+        }
+    }
+
+    void abandon() {
+        fCount = 0;
+    }
+
+    void invalidateViewMatrices() {
+        for (int i = 0; i < fCount; ++i) {
+            // set to illegal matrix
+            fEntries[i].fProgram.fViewMatrix.setScale(GR_ScalarMax,
+                                                      GR_ScalarMax);
+        }
+    }
+
+    Program* getProgram(const ProgramDesc& desc) {
+        HashKey key(desc);
+        Entry* entry = fHashCache.find(key);
+        if (NULL == entry) {
+            if (fCount < MAX_ENTRIES) {
+                entry = fEntries + fCount;
+                ++fCount;
+            } else {
+                GrAssert(MAX_ENTRIES == fCount);
+                entry = fEntries;
+                for (int i = 1; i < MAX_ENTRIES; ++i) {
+                    if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
+                        entry = fEntries + i;
+                    }
+                }
+                fHashCache.remove(entry->fKey, entry);
+                GrGpuGLShaders2::DeleteProgram(&entry->fProgram);
+            }
+            entry->fKey = key;
+            GrGpuGLShaders2::GenProgram(desc, &entry->fProgram);
+            fHashCache.insert(entry->fKey, entry);
+        }
+
+        entry->fLRUStamp = fCurrLRUStamp;
+        if (UINT32_MAX == fCurrLRUStamp) {
+            // wrap around! just trash our LRU, one time hit.
+            for (int i = 0; i < fCount; ++i) {
+                fEntries[i].fLRUStamp = 0;
+            }
+        }
+        ++fCurrLRUStamp;
+        return &entry->fProgram;
+    }
+};
+
+GrGpuGLShaders2::ProgramCache::HashKey::HashKey() {
+}
+
+static uint32_t ror(uint32_t x) {
+    return (x >> 8) | (x << 24);
+}
+
+
+GrGpuGLShaders2::ProgramCache::HashKey::HashKey(const ProgramDesc& desc) {
+    fDesc = desc;
+    // if you change the size of the desc, need to update the hash function
+    GR_STATIC_ASSERT(8 == sizeof(ProgramDesc));
+
+    uint32_t* d = (uint32_t*) &fDesc;
+    fHash = d[0] ^ ror(d[1]);
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::EQ(const Entry& entry,
+                                                const HashKey& key) {
+    return entry.fKey == key;
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::LT(const Entry& entry,
+                                                const HashKey& key) {
+    return entry.fKey < key;
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::operator ==(const HashKey& key) const {
+    return fDesc == key.fDesc;
+}
+
+bool GrGpuGLShaders2::ProgramCache::HashKey::operator <(const HashKey& key) const {
+    return memcmp(&fDesc, &key.fDesc, sizeof(HashKey)) < 0;
+}
+
+uint32_t GrGpuGLShaders2::ProgramCache::HashKey::getHash() const {
+    return fHash;
+}
+
+
+struct GrGpuGLShaders2::ShaderCodeSegments {
+    GrSStringBuilder<256> fVSUnis;
+    GrSStringBuilder<256> fVSAttrs;
+    GrSStringBuilder<256> fVaryings;
+    GrSStringBuilder<256> fFSUnis;
+    GrSStringBuilder<512> fVSCode;
+    GrSStringBuilder<512> fFSCode;
+};
+// for variable names etc
+typedef GrSStringBuilder<16> GrTokenString;
+
+#if ATTRIBUTE_MATRIX
+    #define VIEW_MATRIX_NAME "aViewM"
+#else
+    #define VIEW_MATRIX_NAME "uViewM"
+#endif
+
+#define POS_ATTR_NAME "aPosition"
+#define COL_ATTR_NAME "aColor"
+#define TEX_ATTR_NAME "aTexture"
+
+static inline const char* float_vector_type(int count) {
+    static const char* FLOAT_VECS[] = {"ERROR", "float", "vec2", "vec3", "vec4"};
+    GrAssert(count >= 1 && count < GR_ARRAY_COUNT(FLOAT_VECS));
+    return FLOAT_VECS[count];
+}
+
+static inline const char* vector_homog_coord(int count) {
+    static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
+    GrAssert(count >= 1 && count < GR_ARRAY_COUNT(HOMOGS));
+    return HOMOGS[count];
+}
+
+static inline const char* vector_nonhomog_coords(int count) {
+    static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
+    GrAssert(count >= 1 && count < GR_ARRAY_COUNT(NONHOMOGS));
+    return NONHOMOGS[count];
+}
+
+static inline const char* vector_all_coords(int count) {
+    static const char* ALL[] = {"ERROR", "", ".xy", ".xyz", ".xyzw"};
+    GrAssert(count >= 1 && count < GR_ARRAY_COUNT(ALL));
+    return ALL[count];
+}
+
+static void tex_matrix_name(int stage, GrStringBuilder* s) {
+#if ATTRIBUTE_MATRIX
+    *s = "aTexM";
+#else
+    *s = "uTexM";
+#endif
+    s->appendInt(stage);
+}
+
+static void sampler_name(int stage, GrStringBuilder* s) {
+    *s = "uSampler";
+    s->appendInt(stage);
+}
+
+static void stage_varying_name(int stage, GrStringBuilder* s) {
+    *s = "vStage";
+    s->appendInt(stage);
+}
+
+static void radial2_param_name(int stage, GrStringBuilder* s) {
+    *s = "uRadial2Params";
+    s->appendInt(stage);
+}
+
+static void radial2_varying_name(int stage, GrStringBuilder* s) {
+    *s = "vB";
+    s->appendInt(stage);
+}
+
+#include "GrRandom.h"
+
+void GrGpuGLShaders2::ProgramUnitTest() {
+    static const uint16_t VFORMATS[] = {
+        0,
+        kSeparateTexCoord_VertexLayoutBit,
+        kPositionAsTexCoord_VertexLayoutBit,
+        kSeparateTexCoord_VertexLayoutBit | kColor_VertexLayoutBit,
+        kPositionAsTexCoord_VertexLayoutBit | kColor_VertexLayoutBit,
+        kTextFormat_VertexLayoutBit
+    };
+    static const int PROG_OPTS[] = {
+        0,
+        ProgramDesc::kNotPoints_OptFlagBit,
+        ProgramDesc::kVertexColorAllOnes_OptFlagBit,
+        ProgramDesc::kNotPoints_OptFlagBit | ProgramDesc::kVertexColorAllOnes_OptFlagBit
+    };
+    static const int STAGE_OPTS[] = {
+        0,
+        StageDesc::kNoPerspective_OptFlagBit,
+        StageDesc::kIdentity_CoordMapping
+    };
+    static const int STAGE_MODULATES[] = {
+        StageDesc::kColor_Modulation,
+        StageDesc::kAlpha_Modulation
+    };
+    static const int STAGE_COORD_MAPPINGS[] = {
+        StageDesc::kIdentity_CoordMapping,
+        StageDesc::kRadialGradient_CoordMapping,
+        StageDesc::kSweepGradient_CoordMapping,
+        StageDesc::kRadial2Gradient_CoordMapping
+    };
+    ProgramDesc pdesc;
+    memset(&pdesc, 0, sizeof(pdesc));
+
+    static const int NUM_TESTS = 1024;
+
+    // GrRandoms nextU() values have patterns in the low bits
+    // So using nextU() % array_count might never take some values.
+    GrRandom random;
+    for (int t = 0; t < NUM_TESTS; ++t) {
+        int x = (int)(random.nextF() * GR_ARRAY_COUNT(VFORMATS));
+        pdesc.fVertexLayout = VFORMATS[x];
+        x = (int)(random.nextF() * GR_ARRAY_COUNT(PROG_OPTS));
+        pdesc.fOptFlags = PROG_OPTS[x];
+        for (int s = 0; s < NUM_STAGES; ++s) {
+            x = (int)(random.nextF() * 2.f);
+            pdesc.fStages[s].fEnabled = x;
+            x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
+            pdesc.fStages[s].fOptFlags = STAGE_OPTS[x];
+            x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES));
+            pdesc.fStages[s].fModulation = STAGE_MODULATES[x];
+            x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_COORD_MAPPINGS));
+            pdesc.fStages[s].fCoordMapping = STAGE_COORD_MAPPINGS[x];
+        }
+        Program program;
+        GenProgram(pdesc, &program);
+        DeleteProgram(&program);
+    }
+}
+
+void GrGpuGLShaders2::GenStageCode(int stageNum,
+                                   const StageDesc& desc,
+                                   const char* fsInColor, // NULL means no incoming color
+                                   const char* fsOutColor,
+                                   const char* vsInCoord,
+                                   ShaderCodeSegments* segments,
+                                   StageUniLocations* locations) {
+
+    GrAssert(stageNum >= 0 && stageNum <= 9);
+
+    GrTokenString varyingName;
+    stage_varying_name(stageNum, &varyingName);
+
+    // First decide how many coords are needed to access the texture
+    // Right now it's always 2 but we could start using 1D textures for
+    // gradients.
+    static const int coordDims = 2;
+    int varyingDims;
+    /// Vertex Shader Stuff
+
+    // decide whether we need a matrix to transform texture coords
+    // and whether the varying needs a perspective coord.
+    GrTokenString texMName;
+    tex_matrix_name(stageNum, &texMName);
+    if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
+        varyingDims = coordDims;
+    } else {
+    #if ATTRIBUTE_MATRIX
+        segments->fVSAttrs += "attribute mat3 ";
+        segments->fVSAttrs += texMName;
+        segments->fVSAttrs += ";\n";
+    #else
+        segments->fVSUnis += "uniform mat3 ";
+        segments->fVSUnis += texMName;
+        segments->fVSUnis += ";\n";
+        locations->fTextureMatrixUni = 1;
+    #endif
+        if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
+            varyingDims = coordDims;
+        } else {
+            varyingDims = coordDims + 1;
+        }
+    }
+
+    GrTokenString samplerName;
+    sampler_name(stageNum, &samplerName);
+    segments->fFSUnis += "uniform sampler2D ";
+    segments->fFSUnis += samplerName;
+    segments->fFSUnis += ";\n";
+    locations->fSamplerUni = 1;
+
+    segments->fVaryings += "varying ";
+    segments->fVaryings += float_vector_type(varyingDims);
+    segments->fVaryings += " ";
+    segments->fVaryings += varyingName;
+    segments->fVaryings += ";\n";
+
+    if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
+        GrAssert(varyingDims == coordDims);
+        segments->fVSCode += "\t";
+        segments->fVSCode += varyingName;
+        segments->fVSCode += " = ";
+        segments->fVSCode += vsInCoord;
+        segments->fVSCode += ";\n";
+    } else {
+        segments->fVSCode += "\t";
+        segments->fVSCode += varyingName;
+        segments->fVSCode += " = (";
+        segments->fVSCode += texMName;
+        segments->fVSCode += " * vec3(";
+        segments->fVSCode += vsInCoord;
+        segments->fVSCode += ", 1))";
+        segments->fVSCode += vector_all_coords(varyingDims);
+        segments->fVSCode += ";\n";
+    }
+
+    GrTokenString radial2ParamsName;
+    radial2_param_name(stageNum, &radial2ParamsName);
+    // for radial grads without perspective we can pass the linear
+    // part of the quadratic as a varying.
+    GrTokenString radial2VaryingName;
+    radial2_varying_name(stageNum, &radial2VaryingName);
+
+    if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping) {
+
+        segments->fVSUnis += "uniform " GR_PRECISION " float ";
+        segments->fVSUnis += radial2ParamsName;
+        segments->fVSUnis += "[6];\n";
+
+        segments->fFSUnis += "uniform " GR_PRECISION " float ";
+        segments->fFSUnis += radial2ParamsName;
+        segments->fFSUnis += "[6];\n";
+        locations->fRadial2Uni = 1;
+
+        // if there is perspective we don't interpolate this
+        if (varyingDims == coordDims) {
+            GrAssert(2 == coordDims);
+            segments->fVaryings += "varying float ";
+            segments->fVaryings += radial2VaryingName;
+            segments->fVaryings += ";\n";
+
+            segments->fVSCode += "\t";
+            segments->fVSCode += radial2VaryingName;
+            segments->fVSCode += " = 2.0 * (";
+            segments->fVSCode += radial2ParamsName;
+            segments->fVSCode += "[2] * ";
+            segments->fVSCode += varyingName;
+            segments->fVSCode += ".x ";
+            segments->fVSCode += " - ";
+            segments->fVSCode += radial2ParamsName;
+            segments->fVSCode += "[3]);\n";
+        }
+    }
+
+    /// Fragment Shader Stuff
+    GrTokenString fsCoordName;
+    // function used to access the shader, may be made projective
+    GrTokenString texFunc("texture2D");
+    if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
+                          StageDesc::kNoPerspective_OptFlagBit)) {
+        GrAssert(varyingDims == coordDims);
+        fsCoordName = varyingName;
+    } else {
+        // if we have to do some non-matrix op on the varyings to get
+        // our final tex coords then when in perspective we have to
+        // do an explicit divide
+        if  (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping) {
+            texFunc += "Proj";
+            fsCoordName = varyingName;
+        } else {
+            fsCoordName = "tCoord";
+            fsCoordName.appendInt(stageNum);
+
+            segments->fFSCode += "\t";
+            segments->fFSCode += float_vector_type(coordDims);
+            segments->fFSCode += " ";
+            segments->fFSCode += fsCoordName;
+            segments->fFSCode += " = ";
+            segments->fFSCode += varyingName;
+            segments->fFSCode += vector_nonhomog_coords(varyingDims);
+            segments->fFSCode += " / ";
+            segments->fFSCode += varyingName;
+            segments->fFSCode += vector_homog_coord(varyingDims);
+            segments->fFSCode += ";\n";
+        }
+    }
+
+    GrSStringBuilder<96> sampleCoords;
+    switch (desc.fCoordMapping) {
+    case StageDesc::kIdentity_CoordMapping:
+        sampleCoords = fsCoordName;
+        break;
+    case StageDesc::kSweepGradient_CoordMapping:
+        sampleCoords = "vec2(atan(-";
+        sampleCoords += fsCoordName;
+        sampleCoords += ".y, -";
+        sampleCoords += fsCoordName;
+        sampleCoords += ".x)*0.1591549430918 + 0.5, 0.5)";
+        break;
+    case StageDesc::kRadialGradient_CoordMapping:
+        sampleCoords = "vec2(length(";
+        sampleCoords += fsCoordName;
+        sampleCoords += ".xy), 0.5)";
+        break;
+    case StageDesc::kRadial2Gradient_CoordMapping: {
+        GrTokenString cName    = "c";
+        GrTokenString ac4Name  = "ac4";
+        GrTokenString rootName = "root";
+
+        cName.appendInt(stageNum);
+        ac4Name.appendInt(stageNum);
+        rootName.appendInt(stageNum);
+
+        GrTokenString bVar;
+        if (coordDims == varyingDims) {
+            bVar = radial2VaryingName;
+            GrAssert(2 == varyingDims);
+        } else {
+            GrAssert(3 == varyingDims);
+            bVar = "b";
+            bVar.appendInt(stageNum);
+            segments->fFSCode += "\tfloat ";
+            segments->fFSCode += bVar;
+            segments->fFSCode += " = 2.0 * (";
+            segments->fFSCode += radial2ParamsName;
+            segments->fFSCode += "[2] * ";
+            segments->fFSCode += fsCoordName;
+            segments->fFSCode += ".x ";
+            segments->fFSCode += " - ";
+            segments->fFSCode += radial2ParamsName;
+            segments->fFSCode += "[3]);\n";
+        }
+
+        segments->fFSCode += "\tfloat ";
+        segments->fFSCode += cName;
+        segments->fFSCode += " = dot(";
+        segments->fFSCode += fsCoordName;
+        segments->fFSCode += ", ";
+        segments->fFSCode += fsCoordName;
+        segments->fFSCode += ") + ";
+        segments->fFSCode += " - ";
+        segments->fFSCode += radial2ParamsName;
+        segments->fFSCode += "[4];\n";
+
+        segments->fFSCode += "\tfloat ";
+        segments->fFSCode += ac4Name;
+        segments->fFSCode += " = ";
+        segments->fFSCode += radial2ParamsName;
+        segments->fFSCode += "[0] * 4.0 * ";
+        segments->fFSCode += cName;
+        segments->fFSCode += ";\n";
+
+        segments->fFSCode += "\tfloat ";
+        segments->fFSCode += rootName;
+        segments->fFSCode += " = sqrt(abs(";
+        segments->fFSCode += bVar;
+        segments->fFSCode += " * ";
+        segments->fFSCode += bVar;
+        segments->fFSCode += " - ";
+        segments->fFSCode += ac4Name;
+        segments->fFSCode += "));\n";
+
+        sampleCoords = "vec2((-";
+        sampleCoords += bVar;
+        sampleCoords += " + ";
+        sampleCoords += radial2ParamsName;
+        sampleCoords += "[5] * ";
+        sampleCoords += rootName;
+        sampleCoords += ") * ";
+        sampleCoords += radial2ParamsName;
+        sampleCoords += "[1], 0.5)\n";
+        break;}
+    };
+
+    segments->fFSCode += "\t";
+    segments->fFSCode += fsOutColor;
+    segments->fFSCode += " = ";
+    if (NULL != fsInColor) {
+        segments->fFSCode += fsInColor;
+        segments->fFSCode += " * ";
+    }
+    segments->fFSCode += texFunc;
+    segments->fFSCode += "(";
+    segments->fFSCode += samplerName;
+    segments->fFSCode += ", ";
+    segments->fFSCode += sampleCoords;
+    segments->fFSCode += ")";
+    if (desc.fModulation == StageDesc::kAlpha_Modulation) {
+        segments->fFSCode += ".aaaa";
+    }
+    segments->fFSCode += ";\n";
+
+}
+
+void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
+                                 Program* program) {
+
+    ShaderCodeSegments segments;
+    const uint32_t& layout = desc.fVertexLayout;
+
+    memset(&program->fUniLocations, 0, sizeof(UniLocations));
+
+    bool haveColor = !(ProgramDesc::kVertexColorAllOnes_OptFlagBit &
+                       desc.fOptFlags);
+
+#if ATTRIBUTE_MATRIX
+    segments.fVSAttrs = "attribute mat3 " VIEW_MATRIX_NAME ";\n"
+#else
+    segments.fVSUnis  = "uniform mat3 " VIEW_MATRIX_NAME ";\n";
+    segments.fVSAttrs = "";
+#endif
+    segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
+    if (haveColor) {
+        segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
+        segments.fVaryings = "varying vec4 vColor;\n";
+    } else {
+        segments.fVaryings = "";
+    }
+
+    segments.fVSCode   = "void main() {\n"
+                         "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
+                         "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
+    if (haveColor) {
+        segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n";
+    }
+
+    if (!(desc.fOptFlags & ProgramDesc::kNotPoints_OptFlagBit)){
+        segments.fVSCode += "\tgl_PointSize = 1.0;\n";
+    }
+    segments.fFSCode   = "void main() {\n";
+
+    bool textureCoordAttr = false;
+    static const char* IN_COORDS[] = {POS_ATTR_NAME, TEX_ATTR_NAME};
+    const char* inCoords = NULL;
+    if ((kSeparateTexCoord_VertexLayoutBit | kTextFormat_VertexLayoutBit) &
+        layout) {
+        segments.fVSAttrs += "attribute vec2 " TEX_ATTR_NAME ";\n";
+        inCoords = IN_COORDS[1];
+        textureCoordAttr = true;
+    } else if (kPositionAsTexCoord_VertexLayoutBit & layout) {
+        inCoords = IN_COORDS[0];
+    }
+
+    GrTokenString inColor = "vColor";
+    GR_STATIC_ASSERT(NUM_STAGES <= 9);
+    int numActiveStages = 0;
+    for (int i = 0; i < NUM_STAGES; ++i) {
+        if (desc.fStages[i].fEnabled) {
+            ++numActiveStages;
+        }
+    }
+    if (NULL != inCoords && numActiveStages) {
+        int currActiveStage = 0;
+        for (int i = 0; i < NUM_STAGES; ++i) {
+            if (desc.fStages[i].fEnabled) {
+                GrTokenString outColor;
+                if (currActiveStage < (numActiveStages - 1)) {
+                    outColor = "color";
+                    outColor.appendInt(currActiveStage);
+                    segments.fFSCode += "\tvec4 ";
+                    segments.fFSCode += outColor;
+                    segments.fFSCode += ";\n";
+                } else {
+                    outColor = "gl_FragColor";
+                }
+                GenStageCode(i,
+                             desc.fStages[i],
+                             haveColor ? inColor.cstr() : NULL,
+                             outColor.cstr(),
+                             inCoords,
+                             &segments,
+                             &program->fUniLocations.fStages[i]);
+                ++currActiveStage;
+                inColor = outColor;
+                haveColor = true;
+            }
+        }
+    } else {
+        segments.fFSCode += "\tgl_FragColor = ";
+        if (haveColor) {
+            segments.fFSCode += inColor;
+        } else {
+            segments.fFSCode += "vec4(1,1,1,1)";
+        }
+        segments.fFSCode += ";\n";
+    }
+    segments.fFSCode += "}\n";
+    segments.fVSCode += "}\n";
+
+
+    const char* strings[4];
+    int lengths[4];
+    int stringCnt = 0;
+
+    if (segments.fVSUnis.length()) {
+        strings[stringCnt] = segments.fVSUnis.cstr();
+        lengths[stringCnt] = segments.fVSUnis.length();
+        ++stringCnt;
+    }
+    if (segments.fVSAttrs.length()) {
+        strings[stringCnt] = segments.fVSAttrs.cstr();
+        lengths[stringCnt] = segments.fVSAttrs.length();
+        ++stringCnt;
+    }
+    if (segments.fVaryings.length()) {
+        strings[stringCnt] = segments.fVaryings.cstr();
+        lengths[stringCnt] = segments.fVaryings.length();
+        ++stringCnt;
+    }
+
+    GrAssert(segments.fVSCode.length());
+    strings[stringCnt] = segments.fVSCode.cstr();
+    lengths[stringCnt] = segments.fVSCode.length();
+    ++stringCnt;
+
+#if PRINT_SHADERS
+    GrPrintf("%s%s%s%s\n",
+             segments.fVSUnis.cstr(),
+             segments.fVSAttrs.cstr(),
+             segments.fVaryings.cstr(),
+             segments.fVSCode.cstr());
+#endif
+    program->fVShaderID = CompileShader(GL_VERTEX_SHADER,
+                                        stringCnt,
+                                        strings,
+                                        lengths);
+
+    stringCnt = 0;
+
+    if (GR_ARRAY_COUNT(GR_SHADER_PRECISION) > 1) {
+        strings[stringCnt] = GR_SHADER_PRECISION;
+        lengths[stringCnt] = GR_ARRAY_COUNT(GR_SHADER_PRECISION) - 1;
+        ++stringCnt;
+    }
+    if (segments.fFSUnis.length()) {
+        strings[stringCnt] = segments.fFSUnis.cstr();
+        lengths[stringCnt] = segments.fFSUnis.length();
+        ++stringCnt;
+    }
+    if (segments.fVaryings.length()) {
+        strings[stringCnt] = segments.fVaryings.cstr();
+        lengths[stringCnt] = segments.fVaryings.length();
+        ++stringCnt;
+    }
+
+    GrAssert(segments.fFSCode.length());
+    strings[stringCnt] = segments.fFSCode.cstr();
+    lengths[stringCnt] = segments.fFSCode.length();
+    ++stringCnt;
+
+#if PRINT_SHADERS
+    GrPrintf("%s%s%s%s\n",
+             GR_SHADER_PRECISION,
+             segments.fFSUnis.cstr(),
+             segments.fVaryings.cstr(),
+             segments.fFSCode.cstr());
+#endif
+    program->fFShaderID = CompileShader(GL_FRAGMENT_SHADER,
+                                        stringCnt,
+                                        strings,
+                                        lengths);
+
+    program->fProgramID = GR_GL(CreateProgram());
+    const GLint& progID = program->fProgramID;
+
+    GR_GL(AttachShader(progID, program->fVShaderID));
+    GR_GL(AttachShader(progID, program->fFShaderID));
+
+    // Bind the attrib locations to same values for all shaders
+    GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME));
+    if (textureCoordAttr) {
+        GR_GL(BindAttribLocation(progID, TEX_ATTR_LOCATION, TEX_ATTR_NAME));
+    }
+
+#if ATTRIBUTE_MATRIX
+    // set unis to a bogus value so that checks against -1 before
+    // flushing will pass.
+    GR_GL(BindAttribLocation(progID,
+                             VIEWMAT_ATTR_LOCATION,
+                             VIEW_MATRIX_NAME));
+
+    program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION;
+
+    for (int i = 0; i < NUM_STAGES; ++i) {
+        if (desc.fStages[i].fEnabled) {
+            GR_GL(BindAttribLocation(progID,
+                                     TEXMAT_ATTR_LOCATION(i),
+                                     tex_matrix_name(i).cstr()));
+            program->fUniLocations.fStages[i].fTextureMatrixUni =
+                                                    BOGUS_MATRIX_UNI_LOCATION;
+        }
+    }
+#endif
+
+    GR_GL(BindAttribLocation(progID, COL_ATTR_LOCATION, COL_ATTR_NAME));
+
+    GR_GL(LinkProgram(progID));
+
+    GLint linked;
+    GR_GL(GetProgramiv(progID, GL_LINK_STATUS, &linked));
+    if (!linked) {
+        GLint infoLen;
+        GR_GL(GetProgramiv(progID, GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
+        if (infoLen > 0) {
+            GR_GL(GetProgramInfoLog(progID,
+                                    infoLen+1,
+                                    NULL,
+                                    (char*)log.get()));
+            GrPrintf((char*)log.get());
+        }
+        GrAssert(!"Error linking program");
+        GR_GL(DeleteProgram(progID));
+        program->fProgramID = 0;
+        return;
+    }
+
+    // Get uniform locations
+#if !ATTRIBUTE_MATRIX
+    program->fUniLocations.fViewMatrixUni =
+                    GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
+    GrAssert(-1 != program->fUniLocations.fViewMatrixUni);
+#endif
+    for (int i = 0; i < NUM_STAGES; ++i) {
+        StageUniLocations& locations = program->fUniLocations.fStages[i];
+        if (desc.fStages[i].fEnabled) {
+#if !ATTRIBUTE_MATRIX
+            if (locations.fTextureMatrixUni) {
+                GrTokenString texMName;
+                tex_matrix_name(i, &texMName);
+                locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
+                                                progID,
+                                                texMName.cstr()));
+                GrAssert(-1 != locations.fTextureMatrixUni);
+            } else {
+                locations.fTextureMatrixUni = -1;
+
+            }
+#endif
+
+            if (locations.fSamplerUni) {
+                GrTokenString samplerName;
+                sampler_name(i, &samplerName);
+                locations.fSamplerUni = GR_GL(GetUniformLocation(
+                                                     progID,
+                                                     samplerName.cstr()));
+                GrAssert(-1 != locations.fSamplerUni);
+            } else {
+                locations.fSamplerUni = -1;
+            }
+
+            if (locations.fRadial2Uni) {
+                GrTokenString radial2ParamName;
+                radial2_param_name(i, &radial2ParamName);
+                locations.fRadial2Uni = GR_GL(GetUniformLocation(
+                                             progID,
+                                             radial2ParamName.cstr()));
+                GrAssert(-1 != locations.fRadial2Uni);
+            } else {
+                locations.fRadial2Uni = -1;
+            }
+        } else {
+            locations.fSamplerUni = -1;
+            locations.fRadial2Uni = -1;
+            locations.fTextureMatrixUni = -1;
+        }
+    }
+    GR_GL(UseProgram(progID));
+
+    // init sampler unis and set bogus values for state tracking
+    for (int i = 0; i < NUM_STAGES; ++i) {
+        if (-1 != program->fUniLocations.fStages[i].fSamplerUni) {
+            GR_GL(Uniform1i(program->fUniLocations.fStages[i].fSamplerUni, i));
+        }
+        program->fTextureMatrix[i].setScale(GR_ScalarMax, GR_ScalarMax);
+        program->fRadial2CenterX1[i] = GR_ScalarMax;
+        program->fRadial2Radius0[i] = -GR_ScalarMax;
+    }
+    program->fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax);
+}
+
+void GrGpuGLShaders2::getProgramDesc(PrimitiveType primType, ProgramDesc* desc) {
+
+    // Must initialize all fields or cache will have false negatives!
+    desc->fVertexLayout = fGeometrySrc.fVertexLayout;
+    desc->fStages[0].fEnabled = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
+    for (int i = 1; i < NUM_STAGES; ++i) {
+        desc->fStages[i].fEnabled       = false;
+        desc->fStages[i].fOptFlags      = 0;
+        desc->fStages[i].fCoordMapping  = 0;
+        desc->fStages[i].fModulation    = 0;
+    }
+
+    if (primType != kPoints_PrimitiveType) {
+        desc->fOptFlags = ProgramDesc::kNotPoints_OptFlagBit;
+    } else {
+        desc->fOptFlags = 0;
+    }
+#if SKIP_COLOR_MODULATE_OPT
+    if (!(desc->fVertexLayout & kColor_VertexLayoutBit) &&
+        (0xffffffff == fCurrDrawState.fColor)) {
+        desc->fOptFlags |= ProgramDesc::kVertexColorAllOnes_OptFlagBit;
+    }
+#endif
+
+    StageDesc& stage = desc->fStages[0];
+
+    if (stage.fEnabled) {
+        GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTexture;
+        GrAssert(NULL != texture);
+        // we matrix to invert when orientation is TopDown, so make sure
+        // we aren't in that case before flagging as identity.
+        if (fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].isIdentity() &&
+            GrGLTexture::kTopDown_Orientation == texture->orientation()) {
+            stage.fOptFlags = StageDesc::kIdentityMatrix_OptFlagBit;
+        } else if (!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective()) {
+            stage.fOptFlags = StageDesc::kNoPerspective_OptFlagBit;
+        } else {
+            stage.fOptFlags = 0;
+        }
+        switch (fCurrDrawState.fSamplerState.getSampleMode()) {
+        case GrSamplerState::kNormal_SampleMode:
+            stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
+            stage.fModulation = StageDesc::kColor_Modulation;
+            break;
+        case GrSamplerState::kAlphaMod_SampleMode:
+            stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
+            stage.fModulation = StageDesc::kAlpha_Modulation;
+            break;
+        case GrSamplerState::kRadial_SampleMode:
+            stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
+            stage.fModulation = StageDesc::kColor_Modulation;
+            break;
+        case GrSamplerState::kRadial2_SampleMode:
+            stage.fCoordMapping = StageDesc::kRadial2Gradient_CoordMapping;
+            stage.fModulation = StageDesc::kColor_Modulation;
+            break;
+        case GrSamplerState::kSweep_SampleMode:
+            stage.fCoordMapping = StageDesc::StageDesc::kSweepGradient_CoordMapping;
+            stage.fModulation = StageDesc::kColor_Modulation;
+            break;
+        default:
+            GrAssert(!"Unexpected sample mode!");
+            break;
+        }
+    } else {
+        stage.fOptFlags     = 0;
+        stage.fCoordMapping = 0;
+        stage.fModulation   = 0;
+    }
+}
+
+GLuint GrGpuGLShaders2::CompileShader(GLenum type,
+                                      int stringCnt,
+                                      const char** strings,
+                                      int* stringLengths) {
+    GLuint shader = GR_GL(CreateShader(type));
+    if (0 == shader) {
+        return 0;
+    }
+
+    GLint compiled;
+    GR_GL(ShaderSource(shader, stringCnt, strings, stringLengths));
+    GR_GL(CompileShader(shader));
+    GR_GL(GetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
+
+    if (!compiled) {
+        GLint infoLen;
+        GR_GL(GetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+        if (infoLen > 0) {
+            GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get()));
+            for (int i = 0; i < stringCnt; ++i) {
+                if (NULL == stringLengths || stringLengths[i] < 0) {
+                    GrPrintf(strings[i]);
+                } else {
+                    GrPrintf("%.*s", stringLengths[i], strings[i]);
+                }
+            }
+            GrPrintf("\n%s", log.get());
+        }
+        GrAssert(!"Shader compilation failed!");
+        GR_GL(DeleteShader(shader));
+        return 0;
+    }
+    return shader;
+}
+
+void GrGpuGLShaders2::DeleteProgram(Program* program) {
+    GR_GL(DeleteShader(program->fVShaderID));
+    GR_GL(DeleteShader(program->fFShaderID));
+    GR_GL(DeleteProgram(program->fProgramID));
+    GR_DEBUGCODE(memset(program, 0, sizeof(Program)));
+}
+
+
+GrGpuGLShaders2::GrGpuGLShaders2() {
+
+    resetContextHelper();
+
+    fProgram = NULL;
+    fProgramCache = new ProgramCache();
+
+#if GR_DEBUG
+    ProgramUnitTest();
+#endif
+}
+
+GrGpuGLShaders2::~GrGpuGLShaders2() {
+    delete fProgramCache;
+}
+
+void GrGpuGLShaders2::resetContext() {
+    INHERITED::resetContext();
+    resetContextHelper();
+}
+
+void GrGpuGLShaders2::resetContextHelper() {
+    fTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
+
+    fHWGeometryState.fVertexLayout = 0;
+    fHWGeometryState.fPositionPtr  = (void*) ~0;
+    GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
+    GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION));
+    GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION));
+
+    fHWProgramID = 0;
+}
+
+void GrGpuGLShaders2::flushViewMatrix() {
+    GrAssert(NULL != fCurrDrawState.fRenderTarget);
+    GrMatrix m (
+        GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
+        0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
+        0, 0, GrMatrix::I()[8]);
+    m.setConcat(m, fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
+
+    // ES doesn't allow you to pass true to the transpose param,
+    // so do our own transpose
+    GrScalar mt[]  = {
+        m[GrMatrix::kScaleX],
+        m[GrMatrix::kSkewY],
+        m[GrMatrix::kPersp0],
+        m[GrMatrix::kSkewX],
+        m[GrMatrix::kScaleY],
+        m[GrMatrix::kPersp1],
+        m[GrMatrix::kTransX],
+        m[GrMatrix::kTransY],
+        m[GrMatrix::kPersp2]
+    };
+#if ATTRIBUTE_MATRIX
+    glVertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0);
+    glVertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3);
+    glVertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6);
+#else
+    GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fViewMatrixUni,1,false,mt));
+#endif
+}
+
+void GrGpuGLShaders2::flushTextureMatrix() {
+
+    GrAssert(NULL != fCurrDrawState.fTexture);
+    GrGLTexture::Orientation orientation =
+         ((GrGLTexture*)fCurrDrawState.fTexture)->orientation();
+
+    GrMatrix* m;
+    GrMatrix temp;
+    if (GrGLTexture::kBottomUp_Orientation == orientation) {
+        temp.setAll(
+            GR_Scalar1, 0, 0,
+            0, -GR_Scalar1, GR_Scalar1,
+            0, 0, GrMatrix::I()[8]
+        );
+        temp.preConcat(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+        m = &temp;
+    } else {
+        GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
+        m = &fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
+    }
+
+    // ES doesn't allow you to pass true to the transpose param,
+    // so do our own transpose
+    GrScalar mt[]  = {
+        (*m)[GrMatrix::kScaleX],
+        (*m)[GrMatrix::kSkewY],
+        (*m)[GrMatrix::kPersp0],
+        (*m)[GrMatrix::kSkewX],
+        (*m)[GrMatrix::kScaleY],
+        (*m)[GrMatrix::kPersp1],
+        (*m)[GrMatrix::kTransX],
+        (*m)[GrMatrix::kTransY],
+        (*m)[GrMatrix::kPersp2]
+    };
+#if ATTRIBUTE_MATRIX
+    glVertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0);
+    glVertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3);
+    glVertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6);
+#else
+    GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fStages[0].fTextureMatrixUni,
+                           1,
+                           false,
+                           mt));
+#endif
+}
+
+void GrGpuGLShaders2::flushRadial2() {
+
+    const GrSamplerState& sampler = fCurrDrawState.fSamplerState;
+
+    GrScalar centerX1 = sampler.getRadial2CenterX1();
+    GrScalar radius0 = sampler.getRadial2Radius0();
+
+    GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
+
+    float unis[6] = {
+        GrScalarToFloat(a),
+        1 / (2.f * unis[0]),
+        GrScalarToFloat(centerX1),
+        GrScalarToFloat(radius0),
+        GrScalarToFloat(GrMul(radius0, radius0)),
+        sampler.isRadial2PosRoot() ? 1.f : -1.f
+    };
+    GR_GL(Uniform1fv(fProgram->fUniLocations.fStages[0].fRadial2Uni, 6, unis));
+}
+
+void GrGpuGLShaders2::flushProgram(PrimitiveType type) {
+    ProgramDesc desc;
+    getProgramDesc(type, &desc);
+    fProgram = fProgramCache->getProgram(desc);
+
+    if (fHWProgramID != fProgram->fProgramID) {
+        GR_GL(UseProgram(fProgram->fProgramID));
+        fHWProgramID = fProgram->fProgramID;
+#if GR_COLLECT_STATS
+        ++fStats.fProgChngCnt;
+#endif
+    }
+}
+
+bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) {
+
+    flushGLStateCommon(type);
+
+    if (fRenderTargetChanged) {
+        // our coords are in pixel space and the GL matrices map to NDC
+        // so if the viewport changed, our matrix is now wrong.
+#if ATTRIBUTE_MATRIX
+        fHWDrawState.fMatrixModeCache[kModelView_MatrixMode].setScale(GR_ScalarMax,
+                                                                      GR_ScalarMax);
+#else
+        // we assume all shader matrices may be wrong after viewport changes
+        fProgramCache->invalidateViewMatrices();
+#endif
+        fRenderTargetChanged = false;
+    }
+
+    flushProgram(type);
+
+    if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+        // invalidate the immediate mode color
+        fHWDrawState.fColor = GrColor_ILLEGAL;
+    } else {
+        if (fHWDrawState.fColor != fCurrDrawState.fColor) {
+            // OpenGL ES only supports the float varities of glVertexAttrib
+            float c[] = {
+                GrColorUnpackR(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackG(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackB(fCurrDrawState.fColor) / 255.f,
+                GrColorUnpackA(fCurrDrawState.fColor) / 255.f
+            };
+            GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c));
+            fHWDrawState.fColor = fCurrDrawState.fColor;
+        }
+    }
+
+#if ATTRIBUTE_MATRIX
+    GrMatrix& currViewMatrix = fHWDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    GrMatrix& currTextureMatrix = fHWDrawState.fMatrixModeCache[kTexture_MatrixMode];
+    GrGLTexture::Orientation& orientation = fTextureOrientation;
+#else
+    GrMatrix& currViewMatrix = fProgram->fViewMatrix;
+    GrMatrix& currTextureMatrix = fProgram->fTextureMatrix[0];
+    GrGLTexture::Orientation& orientation =  fProgram->fTextureOrientation[0];
+#endif
+
+    if (currViewMatrix != fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
+        flushViewMatrix();
+        currViewMatrix = fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
+    }
+
+    GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTexture;
+    if (NULL != texture) {
+        if (-1 != fProgram->fUniLocations.fStages[0].fTextureMatrixUni &&
+            (currTextureMatrix !=
+                        fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode] ||
+             orientation != texture->orientation())) {
+            flushTextureMatrix();
+            currTextureMatrix = fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
+            orientation = texture->orientation();
+        }
+    }
+
+    const GrSamplerState& sampler = fCurrDrawState.fSamplerState;
+    if (-1 != fProgram->fUniLocations.fStages[0].fRadial2Uni &&
+        (fProgram->fRadial2CenterX1[0] != sampler.getRadial2CenterX1() ||
+         fProgram->fRadial2Radius0[0]  != sampler.getRadial2Radius0()  ||
+         fProgram->fRadial2PosRoot[0]  != sampler.isRadial2PosRoot())) {
+
+        flushRadial2();
+
+        fProgram->fRadial2CenterX1[0] = sampler.getRadial2CenterX1();
+        fProgram->fRadial2Radius0[0]  = sampler.getRadial2Radius0();
+        fProgram->fRadial2PosRoot[0]  = sampler.isRadial2PosRoot();
+    }
+
+    return true;
+}
+
+void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
+                                   uint32_t startIndex,
+                                   uint32_t vertexCount,
+                                   uint32_t indexCount) {
+
+    int newColorOffset, newTexCoordOffset;
+
+    GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
+                                             &newTexCoordOffset,
+                                             &newColorOffset);
+    int oldColorOffset, oldTexCoordOffset;
+    GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
+                                             &oldTexCoordOffset,
+                                             &oldColorOffset);
+
+    const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
+
+    if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+        GrAssert(NULL != fGeometrySrc.fVertexBuffer);
+        GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
+        if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
+            GrGLVertexBuffer* buf =
+            (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
+            GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
+            fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        }
+    } else {
+        if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+            posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray +
+                             (intptr_t)posPtr);
+        } else {
+            GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
+            posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);
+        }
+        if (NULL != fHWGeometryState.fVertexBuffer) {
+            GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
+            fHWGeometryState.fVertexBuffer = NULL;
+        }
+    }
+
+    if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
+        GrAssert(NULL != fGeometrySrc.fIndexBuffer);
+        GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
+        if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
+            GrGLIndexBuffer* buf =
+            (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+            GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
+            fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+        }
+    } else if (NULL != fHWGeometryState.fIndexBuffer) {
+        GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+        fHWGeometryState.fIndexBuffer = NULL;
+    }
+
+    GLenum scalarType;
+    bool texCoordNorm;
+    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+        scalarType = GrGLTextType;
+        texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
+    } else {
+        scalarType = GrGLType;
+        texCoordNorm = false;
+    }
+
+    bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
+    bool scalarChange = (GrGLTextType != GrGLType) &&
+                        (kTextFormat_VertexLayoutBit &
+                         (fHWGeometryState.fVertexLayout ^
+                          fGeometrySrc.fVertexLayout));
+    bool strideChange = newStride != oldStride;
+    bool posChange = baseChange || scalarChange || strideChange;
+
+    if (posChange) {
+        GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType,
+                                  false, newStride, posPtr));
+        fHWGeometryState.fPositionPtr = posPtr;
+    }
+
+    if (newTexCoordOffset > 0) {
+        GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffset;
+        if (oldTexCoordOffset <= 0) {
+            GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION));
+        }
+        if (posChange || newTexCoordOffset != oldTexCoordOffset) {
+            GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION, 2, scalarType,
+                                      texCoordNorm, newStride, texCoordPtr));
+        }
+    } else if (oldTexCoordOffset > 0) {
+        GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION));
+    }
+
+    if (newColorOffset > 0) {
+        GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+        if (oldColorOffset <= 0) {
+            GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION));
+        }
+        if (posChange || newColorOffset != oldColorOffset) {
+            GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
+                                      GL_UNSIGNED_BYTE,
+                                      true, newStride, colorPtr));
+        }
+    } else if (oldColorOffset > 0) {
+        GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
+    }
+
+    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+}
+#endif
+
diff --git a/gpu/src/GrGpuGLShaders2.h b/gpu/src/GrGpuGLShaders2.h
new file mode 100644
index 0000000..c484544
--- /dev/null
+++ b/gpu/src/GrGpuGLShaders2.h
@@ -0,0 +1,102 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrGpuGLShaders2_DEFINED
+#define GrGpuGLShaders2_DEFINED
+
+#include "GrGpuGL.h"
+
+// Programmable OpenGL or OpenGL ES 2.0
+class GrGpuGLShaders2 : public GrGpuGL {
+public:
+             GrGpuGLShaders2();
+    virtual ~GrGpuGLShaders2();
+
+    virtual void resetContext();
+
+protected:
+    // overrides from GrGpu
+    virtual bool flushGraphicsState(PrimitiveType type);
+    virtual void setupGeometry(uint32_t startVertex,
+                               uint32_t startIndex,
+                               uint32_t vertexCount,
+                               uint32_t indexCount);
+
+private:
+    static const int NUM_STAGES;
+
+    void resetContextHelper();
+
+    // sets the texture matrix uniform for currently bound program
+    void flushTextureMatrix();
+    // sets the MVP matrix uniform for currently bound program
+    void flushViewMatrix();
+
+    // flushes the parameters to two point radial gradient
+    void flushRadial2();
+
+    // called at flush time to setup the appropriate program
+    void flushProgram(PrimitiveType type);
+
+    struct Program;
+
+    struct StageDesc;
+    struct ProgramDesc;
+
+    struct UniLocations;
+    struct StageUniLocations;
+
+    struct ShaderCodeSegments;
+
+    class ProgramCache;
+
+    // gets a description of needed shader
+    void getProgramDesc(PrimitiveType primType, ProgramDesc* desc);
+
+    // generates and compiles a program from a description and vertex layout
+    // will change GL's bound program
+    static void GenProgram(const ProgramDesc& desc, Program* program);
+
+    // generates code for a stage of the shader
+    static void GenStageCode(int stageNum,
+                             const StageDesc& desc,
+                             const char* psInColor,
+                             const char* psOutColor,
+                             const char* vsInCoord,
+                             ShaderCodeSegments* segments,
+                             StageUniLocations* locations);
+
+    // Compiles a GL shader, returns shader ID or 0 if failed
+    // params have same meaning as glShaderSource
+    static GLuint CompileShader(GLenum type, int stringCnt,
+                                             const char** strings,
+                                             int* stringLengths);
+    static void DeleteProgram(Program* program);
+
+    void ProgramUnitTest();
+
+    GrGLTexture::Orientation  fTextureOrientation;
+
+    ProgramCache*   fProgramCache;
+    Program*        fProgram;
+    GLuint          fHWProgramID;
+
+    typedef GrGpuGL INHERITED;
+};
+
+#endif
+
diff --git a/gpu/src/GrInOrderDrawBuffer.cpp b/gpu/src/GrInOrderDrawBuffer.cpp
new file mode 100644
index 0000000..3f25f2f
--- /dev/null
+++ b/gpu/src/GrInOrderDrawBuffer.cpp
@@ -0,0 +1,345 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrInOrderDrawBuffer.h"
+#include "GrTexture.h"
+#include "GrVertexBufferAllocPool.h"
+#include "GrGpu.h"
+
+GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* pool) :
+        fDraws(DRAWS_BLOCK_SIZE, fDrawsStorage),
+        fStates(STATES_BLOCK_SIZE, fStatesStorage),
+        fClips(CLIPS_BLOCK_SIZE, fClipsStorage),
+        fClipChanged(true),
+        fCPUVertices((NULL == pool) ? 0 : VERTEX_BLOCK_SIZE),
+        fBufferVertices(pool),
+        fIndices(INDEX_BLOCK_SIZE),
+        fCurrReservedVertices(NULL),
+        fCurrReservedIndices(NULL),
+        fCurrVertexBuffer(NULL),
+        fReservedVertexBytes(0),
+        fReservedIndexBytes(0),
+        fUsedReservedVertexBytes(0),
+        fUsedReservedIndexBytes(0) {
+    GrAssert(NULL == pool || pool->getGpu()->supportsBufferLocking());
+}
+
+GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
+    reset();
+}
+
+void GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) {
+    this->copyDrawState(target);
+    this->setClip(target.getClip());
+}
+
+void GrInOrderDrawBuffer::drawIndexed(PrimitiveType type,
+                                      uint32_t startVertex,
+                                      uint32_t startIndex,
+                                      uint32_t vertexCount,
+                                      uint32_t indexCount) {
+
+    if (!vertexCount || !indexCount) {
+        return;
+    }
+
+    Draw& draw = fDraws.push_back();
+    draw.fType          = type;
+    draw.fStartVertex   = startVertex;
+    draw.fStartIndex    = startIndex;
+    draw.fVertexCount   = vertexCount;
+    draw.fIndexCount    = indexCount;
+    draw.fClipChanged   = grabClip();
+    draw.fStateChange   = grabState();
+
+    draw.fVertexLayout = fGeometrySrc.fVertexLayout;
+    switch (fGeometrySrc.fVertexSrc) {
+    case kArray_GeometrySrcType:
+        draw.fUseVertexBuffer = false;
+        draw.fVertexArray = fGeometrySrc.fVertexArray;
+        break;
+    case kReserved_GeometrySrcType: {
+        draw.fUseVertexBuffer = NULL != fBufferVertices;
+        if (draw.fUseVertexBuffer) {
+            draw.fVertexBuffer = fCurrVertexBuffer;
+            draw.fStartVertex += fCurrStartVertex;
+        } else {
+            draw.fVertexArray = fCurrReservedVertices;
+        }
+        size_t vertexBytes = (vertexCount + startVertex) *
+                             VertexSize(fGeometrySrc.fVertexLayout);
+        fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
+                                         vertexBytes);
+        } break;
+    case kBuffer_GeometrySrcType:
+        draw.fUseVertexBuffer = true;
+        draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        break;
+    }
+
+    switch (fGeometrySrc.fIndexSrc) {
+    case kArray_GeometrySrcType:
+        draw.fUseIndexBuffer = false;
+        draw.fIndexArray = fGeometrySrc.fIndexArray;
+        break;
+    case kReserved_GeometrySrcType: {
+        draw.fUseIndexBuffer = false;
+        draw.fIndexArray = fCurrReservedIndices;
+        size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
+        fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
+        } break;
+    case kBuffer_GeometrySrcType:
+        draw.fUseIndexBuffer = true;
+        draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+        break;
+    }
+}
+
+void GrInOrderDrawBuffer::drawNonIndexed(PrimitiveType type,
+                                         uint32_t startVertex,
+                                         uint32_t vertexCount) {
+    if (!vertexCount) {
+        return;
+    }
+
+    Draw& draw = fDraws.push_back();
+    draw.fType          = type;
+    draw.fStartVertex   = startVertex;
+    draw.fStartIndex    = 0;
+    draw.fVertexCount   = vertexCount;
+    draw.fIndexCount    = 0;
+
+    draw.fClipChanged   = grabClip();
+    draw.fStateChange   = grabState();
+
+    draw.fVertexLayout = fGeometrySrc.fVertexLayout;
+    switch (fGeometrySrc.fVertexSrc) {
+    case kArray_GeometrySrcType:
+        draw.fUseVertexBuffer = false;
+        draw.fVertexArray = fGeometrySrc.fVertexArray;
+        break;
+    case kReserved_GeometrySrcType: {
+        draw.fUseVertexBuffer = NULL != fBufferVertices;
+        if (draw.fUseVertexBuffer) {
+            draw.fVertexBuffer = fCurrVertexBuffer;
+            draw.fStartVertex += fCurrStartVertex;
+        } else {
+            draw.fVertexArray = fCurrReservedVertices;
+        }
+        size_t vertexBytes = (vertexCount + startVertex) *
+                             VertexSize(fGeometrySrc.fVertexLayout);
+        fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
+                                         vertexBytes);
+        } break;
+    case kBuffer_GeometrySrcType:
+        draw.fUseVertexBuffer = true;
+        draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        break;
+    }
+}
+
+void GrInOrderDrawBuffer::reset() {
+    GrAssert(!fReservedGeometry.fLocked);
+    uint32_t numStates = fStates.count();
+    for (uint32_t i = 0; i < numStates; ++i) {
+        GrTexture* tex = accessSavedDrawState(fStates[i]).fTexture;
+        if (NULL != tex) {
+            tex->unref();
+        }
+    }
+    fDraws.reset();
+    fStates.reset();
+    if (NULL == fBufferVertices) {
+        fCPUVertices.reset();
+    } else {
+        fBufferVertices->reset();
+    }
+    fIndices.reset();
+    fClips.reset();
+}
+
+void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
+    GrAssert(NULL != target);
+    GrAssert(target != this); // not considered and why?
+
+    uint32_t numDraws = fDraws.count();
+    if (!numDraws) {
+        return;
+    }
+
+    if (NULL != fBufferVertices) {
+        fBufferVertices->unlock();
+    }
+
+    GrDrawTarget::AutoStateRestore asr(target);
+    GrDrawTarget::AutoClipRestore acr(target);
+    // important to not mess with reserve/lock geometry in the target with this
+    // on the stack.
+    GrDrawTarget::AutoGeometrySrcRestore agsr(target);
+
+    uint32_t currState = ~0;
+    uint32_t currClip  = ~0;
+
+    for (uint32_t i = 0; i < numDraws; ++i) {
+        const Draw& draw = fDraws[i];
+        if (draw.fStateChange) {
+            ++currState;
+            target->restoreDrawState(fStates[currState]);
+        }
+        if (draw.fClipChanged) {
+            ++currClip;
+            target->setClip(fClips[currClip]);
+        }
+        if (draw.fUseVertexBuffer) {
+            target->setVertexSourceToBuffer(draw.fVertexBuffer, draw.fVertexLayout);
+        } else {
+            target->setVertexSourceToArray(draw.fVertexArray, draw.fVertexLayout);
+        }
+        if (draw.fIndexCount) {
+            if (draw.fUseIndexBuffer) {
+                target->setIndexSourceToBuffer(draw.fIndexBuffer);
+            } else {
+                target->setIndexSourceToArray(draw.fIndexArray);
+            }
+            target->drawIndexed(draw.fType,
+                                draw.fStartVertex,
+                                draw.fStartIndex,
+                                draw.fVertexCount,
+                                draw.fIndexCount);
+        } else {
+            target->drawNonIndexed(draw.fType,
+                                   draw.fStartVertex,
+                                   draw.fVertexCount);
+        }
+    }
+}
+
+bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
+                                        int32_t* vertexCount,
+                                        int32_t* indexCount) const {
+    bool flush = false;
+    if (NULL != indexCount) {
+        *indexCount  = -1;
+    }
+    if (NULL != vertexCount) {
+        if (NULL != fBufferVertices) {
+            // we will recommend a flush if the verts could fit in a single
+            // preallocated vertex buffer but none are left and it can't fit
+            // in the current VB (which may not be prealloced).
+            if (*vertexCount > fBufferVertices->currentBufferVertices(vertexLayout) &&
+                (!fBufferVertices->preallocatedBuffersRemaining() &&
+                 *vertexCount <= fBufferVertices->preallocatedBufferVertices(vertexLayout))) {
+
+                flush = true;
+            }
+            *vertexCount = fBufferVertices->currentBufferVertices(vertexLayout);
+        } else {
+            *vertexCount = -1;
+        }
+    }
+    return flush;
+}
+
+bool GrInOrderDrawBuffer::acquireGeometryHelper(GrVertexLayout vertexLayout,
+                                                void**         vertices,
+                                                void**         indices) {
+    if (fReservedGeometry.fVertexCount) {
+        fReservedVertexBytes = VertexSize(vertexLayout) *
+                               fReservedGeometry.fVertexCount;
+        if (NULL == fBufferVertices) {
+            fCurrReservedVertices = fCPUVertices.alloc(fReservedVertexBytes);
+        } else {
+            fCurrReservedVertices = fBufferVertices->alloc(vertexLayout,
+                                                           fReservedGeometry.fVertexCount,
+                                                           &fCurrVertexBuffer,
+                                                           &fCurrStartVertex);
+        }
+        if (NULL != vertices) {
+            *vertices = fCurrReservedVertices;
+        }
+        if (NULL == fCurrReservedVertices) {
+            return false;
+        }
+    }
+    if (fReservedGeometry.fIndexCount) {
+        fReservedIndexBytes = sizeof(uint16_t) * fReservedGeometry.fIndexCount;
+        fCurrReservedIndices = fIndices.alloc(fReservedIndexBytes);
+        if (NULL != indices) {
+            *indices = fCurrReservedIndices;
+        }
+        if (NULL == fCurrReservedIndices) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void GrInOrderDrawBuffer::releaseGeometryHelper() {
+    GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
+    GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
+
+    size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
+    if (NULL == fBufferVertices) {
+        fCPUVertices.release(vertexSlack);
+    } else {
+        fBufferVertices->release(vertexSlack);
+        GR_DEBUGCODE(fCurrVertexBuffer = NULL);
+        GR_DEBUGCODE(fCurrStartVertex  = 0);
+    }
+
+    fIndices.release(fReservedIndexBytes - fUsedReservedIndexBytes);
+
+    fCurrReservedVertices = NULL;
+    fCurrReservedIndices  = NULL;
+    fReservedVertexBytes = 0;
+    fReservedIndexBytes  = 0;
+    fUsedReservedVertexBytes = 0;
+    fUsedReservedIndexBytes  = 0;
+}
+
+bool GrInOrderDrawBuffer::grabState() {
+    bool newState;
+    if (fStates.empty()) {
+        newState = true;
+    } else {
+        const DrawState& old = accessSavedDrawState(fStates.back());
+        newState = old != fCurrDrawState;
+    }
+    if (newState) {
+        if (NULL != fCurrDrawState.fTexture) {
+            fCurrDrawState.fTexture->ref();
+        }
+        saveCurrentDrawState(&fStates.push_back());
+    }
+    return newState;
+}
+
+bool GrInOrderDrawBuffer::grabClip() {
+    if ((fCurrDrawState.fFlagBits & kClip_StateBit) &&
+        (fClipChanged || fClips.empty())) {
+
+        fClips.push_back() = fClip;
+        fClipChanged = false;
+        return true;
+    }
+    return false;
+}
+
+void GrInOrderDrawBuffer::clipWillChange(const GrClip& clip)  {
+    fClipChanged = true;
+}
+
diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp
new file mode 100644
index 0000000..e4360cd
--- /dev/null
+++ b/gpu/src/GrMatrix.cpp
@@ -0,0 +1,767 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrMatrix.h"
+#include "GrRect.h"
+#include <stddef.h>
+
+#if GR_SCALAR_IS_FLOAT
+    const GrScalar GrMatrix::gRESCALE(GR_Scalar1);
+#else
+    GR_STATIC_ASSERT(GR_SCALAR_IS_FIXED);
+    // fixed point isn't supported right now
+    GR_STATIC_ASSERT(false);
+const GrScalar GrMatrix::gRESCALE(1 << 30);
+#endif
+
+const GrMatrix::MapProc GrMatrix::gMapProcs[] = {
+// Scales are not both zero
+    &GrMatrix::mapIdentity,
+    &GrMatrix::mapScale,
+    &GrMatrix::mapTranslate,
+    &GrMatrix::mapScaleAndTranslate,
+    &GrMatrix::mapSkew,
+    &GrMatrix::mapScaleAndSkew,
+    &GrMatrix::mapSkewAndTranslate,
+    &GrMatrix::mapNonPerspective,
+    // no optimizations for perspective matrices
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapPerspective,
+    
+// Scales are zero (every other is invalid because kScale_TypeBit must be set if
+// kZeroScale_TypeBit is set)
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapZero,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSetToTranslate,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSwappedScale,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapSwappedScaleAndTranslate,
+    
+    // no optimizations for perspective matrices
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapZero,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+    &GrMatrix::mapInvalid,
+    &GrMatrix::mapPerspective,
+};
+
+const GrMatrix& GrMatrix::I() {
+    struct FakeMatrix {
+        int fTypeMask;
+        GrScalar fM[9];
+    };
+
+#if 0
+    GR_STATIC_ASSERT(offsetof(FakeMatrix, fTypeMask) == offsetof(GrMatrix, fTypeMask));
+    GR_STATIC_ASSERT(offsetof(FakeMatrix, fM) == offsetof(GrMatrix, fM));
+#endif
+
+    GR_STATIC_ASSERT(sizeof(FakeMatrix) == sizeof(GrMatrix));
+    static const FakeMatrix I = {0,
+                                 {GR_Scalar1, 0,          0,
+                                  0,          GR_Scalar1, 0,
+                                  0,          0,          gRESCALE}};
+    return *(const GrMatrix*)&I;
+}
+
+void GrMatrix::setIdentity() {
+    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = 0;
+    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = 0;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = 0; 
+}
+
+void GrMatrix::setTranslate(GrScalar dx, GrScalar dy) {
+    fM[0] = GR_Scalar1; fM[1] = 0;          fM[2] = dx;
+    fM[3] = 0;          fM[4] = GR_Scalar1; fM[5] = dy;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = kTranslate_TypeBit;
+}
+
+void GrMatrix::setScale(GrScalar sx, GrScalar sy) {
+    fM[0] = sx; fM[1] = 0;  fM[2] = 0;
+    fM[3] = 0;  fM[4] = sy; fM[5] = 0;
+    fM[6] = 0;  fM[7] = 0;  fM[8] = gRESCALE;
+    fTypeMask = kScale_TypeBit;
+}
+
+void GrMatrix::setSkew(GrScalar skx, GrScalar sky) {
+    fM[0] = GR_Scalar1; fM[1] = skx;        fM[2] = 0;
+    fM[3] = sky;        fM[4] = GR_Scalar1; fM[5] = 0;
+    fM[6] = 0;          fM[7] = 0;          fM[8] = gRESCALE;
+    fTypeMask = kSkew_TypeBit;
+}
+
+void GrMatrix::setConcat(const GrMatrix& a, const GrMatrix& b) {
+    if (a.isIdentity()) {
+        if (this != &b) {
+            for (int i = 0; i < 9; ++i) {
+                fM[i] = b.fM[i];
+            }
+            fTypeMask = b.fTypeMask;
+        }
+        return;
+    }
+    
+    if (b.isIdentity()) {
+        GrAssert(!a.isIdentity());
+        if (this != &a) {
+            for (int i = 0; i < 9; ++i) {
+                    fM[i] = a.fM[i];
+            }
+            fTypeMask = a.fTypeMask;
+        }
+        return;
+    }
+    
+    // a and/or b could be this
+    GrMatrix tmp;
+    
+    // could do more optimizations based on type bits. Hopefully this call is
+    // low frequency.
+    // TODO: make this work for fixed point
+    if (!((b.fTypeMask | a.fTypeMask) & kPerspective_TypeBit)) {
+        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3];
+        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4];
+        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * gRESCALE;
+        
+        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3];
+        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4];
+        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * gRESCALE;
+   
+        tmp.fM[6] = 0;
+        tmp.fM[7] = 0;
+        tmp.fM[8] = gRESCALE * gRESCALE; 
+    } else {
+        tmp.fM[0] = a.fM[0] * b.fM[0] + a.fM[1] * b.fM[3] + a.fM[2] * b.fM[6];
+        tmp.fM[1] = a.fM[0] * b.fM[1] + a.fM[1] * b.fM[4] + a.fM[2] * b.fM[7];
+        tmp.fM[2] = a.fM[0] * b.fM[2] + a.fM[1] * b.fM[5] + a.fM[2] * b.fM[8];
+
+        tmp.fM[3] = a.fM[3] * b.fM[0] + a.fM[4] * b.fM[3] + a.fM[5] * b.fM[6];
+        tmp.fM[4] = a.fM[3] * b.fM[1] + a.fM[4] * b.fM[4] + a.fM[5] * b.fM[7];
+        tmp.fM[5] = a.fM[3] * b.fM[2] + a.fM[4] * b.fM[5] + a.fM[5] * b.fM[8];
+
+        tmp.fM[6] = a.fM[6] * b.fM[0] + a.fM[7] * b.fM[3] + a.fM[8] * b.fM[6];
+        tmp.fM[7] = a.fM[6] * b.fM[1] + a.fM[7] * b.fM[4] + a.fM[8] * b.fM[7];
+        tmp.fM[8] = a.fM[6] * b.fM[2] + a.fM[7] * b.fM[5] + a.fM[8] * b.fM[8];
+    }
+    *this = tmp;
+    setTypeMask();
+}
+
+void GrMatrix::preConcat(const GrMatrix& m) {
+    setConcat(*this, m);
+}
+
+void GrMatrix::postConcat(const GrMatrix& m) {
+    setConcat(m, *this);
+}
+
+double GrMatrix::determinant() const {
+    if (fTypeMask & kPerspective_TypeBit) {
+        return  fM[0]*((double)fM[4]*fM[8] - (double)fM[5]*fM[7]) + 
+                fM[1]*((double)fM[5]*fM[6] - (double)fM[3]*fM[8]) + 
+                fM[2]*((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
+    } else {
+        return (double)fM[0]*fM[4]*gRESCALE - 
+               (double)fM[1]*fM[3]*gRESCALE;
+    }
+}
+
+bool GrMatrix::invert(GrMatrix* inverted) const {
+    
+    if (isIdentity()) {
+        if (inverted != this) {
+            inverted->setIdentity();
+        }
+        return true;
+    }
+    static const double MIN_DETERMINANT_SQUARED = 1.e-16;
+    
+    // could do more optimizations based on type bits. Hopefully this call is
+    // low frequency.
+    
+    double det = determinant();
+
+    // check if we can't be inverted
+    if (det*det <= MIN_DETERMINANT_SQUARED) {
+        return false;
+    } else if (NULL == inverted) {
+        return true;
+    }
+
+    double t[9];
+    
+    if (fTypeMask & kPerspective_TypeBit) {
+        t[0] = ((double)fM[4]*fM[8] - (double)fM[5]*fM[7]); 
+        t[1] = ((double)fM[2]*fM[7] - (double)fM[1]*fM[8]);
+        t[2] = ((double)fM[1]*fM[5] - (double)fM[2]*fM[4]);
+        t[3] = ((double)fM[5]*fM[6] - (double)fM[3]*fM[8]);
+        t[4] = ((double)fM[0]*fM[8] - (double)fM[2]*fM[6]);
+        t[5] = ((double)fM[2]*fM[3] - (double)fM[0]*fM[5]);
+        t[6] = ((double)fM[3]*fM[7] - (double)fM[4]*fM[6]);
+        t[7] = ((double)fM[1]*fM[6] - (double)fM[0]*fM[7]);
+        t[8] = ((double)fM[0]*fM[4] - (double)fM[1]*fM[3]);
+        det = 1.0 / det;
+        for (int i = 0; i < 9; ++i) {
+            inverted->fM[i] = (GrScalar)(t[i] * det);
+        }
+    } else {
+        t[0] =  (double)fM[4]*gRESCALE; 
+        t[1] = -(double)fM[1]*gRESCALE;
+        t[2] =  (double)fM[1]*fM[5] - (double)fM[2]*fM[4];
+        t[3] = -(double)fM[3]*gRESCALE;
+        t[4] =  (double)fM[0]*gRESCALE;
+        t[5] =  (double)fM[2]*fM[3] - (double)fM[0]*fM[5];
+        //t[6] = 0.0;
+        //t[7] = 0.0;
+        t[8] = (double)fM[0]*fM[4] - (double)fM[1]*fM[3];
+        det = 1.0 / det;
+        for (int i = 0; i < 6; ++i) {
+            inverted->fM[i] = (GrScalar)(t[i] * det);
+        }
+        inverted->fM[6] = 0;
+        inverted->fM[7] = 0;
+        inverted->fM[8] = (GrScalar)(t[8] * det);
+    }
+    inverted->setTypeMask();
+    return true;
+}
+
+void GrMatrix::mapRect(GrRect* dst, const GrRect& src) const {
+    GrPoint srcPts[4], dstPts[4];
+    srcPts[0].set(src.fLeft, src.fTop);
+    srcPts[1].set(src.fRight, src.fTop);
+    srcPts[2].set(src.fRight, src.fBottom);
+    srcPts[3].set(src.fLeft, src.fBottom);
+    this->mapPoints(dstPts, srcPts, 4);
+    dst->setBounds(dstPts, 4);
+}
+
+bool GrMatrix::hasPerspective() const {
+    GrAssert(!!(kPerspective_TypeBit & fTypeMask) ==
+             (fM[kPersp0] != 0 || fM[kPersp1] != 0 || fM[kPersp2] != gRESCALE));
+    return 0 != (kPerspective_TypeBit & fTypeMask);
+}
+
+bool GrMatrix::isIdentity() const {
+    GrAssert((0 == fTypeMask) == 
+             (GR_Scalar1 == fM[kScaleX] && 0          == fM[kSkewX]  && 0          == fM[kTransX] &&
+              0          == fM[kSkewY]  && GR_Scalar1 == fM[kScaleY] && 0          == fM[kTransY] &&
+              0          == fM[kPersp0] && 0          == fM[kPersp1] && gRESCALE == fM[kPersp2]));
+    return (0 == fTypeMask);
+}
+
+
+GrScalar GrMatrix::getMaxStretch() const {
+
+    if (fTypeMask & kPerspective_TypeBit) {
+        return -GR_Scalar1;
+    }
+
+    GrScalar stretch;
+    
+    if (isIdentity()) {
+        stretch = GR_Scalar1;
+    } else if (!(fTypeMask & kSkew_TypeBit)) {
+        stretch = GrMax(GrScalarAbs(fM[kScaleX]), GrScalarAbs(fM[kScaleY]));
+    } else if (fTypeMask & kZeroScale_TypeBit) {        
+        stretch = GrMax(GrScalarAbs(fM[kSkewX]), GrScalarAbs(fM[kSkewY]));
+    } else {            
+        // ignore the translation part of the matrix, just look at 2x2 portion.
+        // compute singular values, take largest abs value.
+        // [a b; b c] = A^T*A 
+        GrScalar a = GrMul(fM[kScaleX], fM[kScaleX]) + GrMul(fM[kSkewY],  fM[kSkewY]);
+        GrScalar b = GrMul(fM[kScaleX], fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kSkewY]);
+        GrScalar c = GrMul(fM[kSkewX],  fM[kSkewX]) +  GrMul(fM[kScaleY], fM[kScaleY]);
+        // eigenvalues of A^T*A are the squared singular values of A.
+        // characteristic equation is det((A^T*A) - l*I) = 0
+        // l^2 - (a + c)l + (ac-b^2)
+        // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
+        // and roots are guaraunteed to be pos and real).
+        GrScalar largerRoot;
+        GrScalar bSqd = GrMul(b,b);
+        // TODO: fixed point tolerance value.
+        if (bSqd < 1e-10) { // will be true if upper left 2x2 is orthogonal, which is common, so save some math
+            largerRoot = GrMax(a, c);
+        } else {
+            GrScalar aminusc = a - c;
+            GrScalar apluscdiv2 = (a + c) / 2;
+            GrScalar x = sqrtf(GrMul(aminusc,aminusc) + GrMul(4,(bSqd))) / 2;
+            largerRoot = apluscdiv2 + x;
+        }
+        
+        stretch = sqrtf(largerRoot);
+    }
+#if GR_DEBUG && 0
+    // test a bunch of vectors. None should be scaled by more than stretch 
+    // (modulo some error) and we should find a vector that is scaled by almost
+    // stretch.
+    GrPoint pt;
+    GrScalar max = 0;
+    for (int i = 0; i < 1000; ++i) {
+        GrScalar x = (float)rand() / RAND_MAX;
+        GrScalar y = sqrtf(1 - (x*x));
+        pt.fX = fM[kScaleX]*x + fM[kSkewX]*y;
+        pt.fY = fM[kSkewY]*x + fM[kScaleY]*y;
+        GrScalar d = pt.distanceToOrigin(); 
+        GrAssert(d <= (1.0001 * stretch));
+        max = GrMax(max, pt.distanceToOrigin());
+    }
+    GrAssert((stretch - max) < .05*stretch);
+#endif
+    return stretch;
+}
+
+bool GrMatrix::operator == (const GrMatrix& m) const {
+    if (fTypeMask != m.fTypeMask) {
+        return false;
+    }
+    if (!fTypeMask) {
+        return true;
+    }
+    for (int i = 0; i < 9; ++i) {
+        if (m.fM[i] != fM[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+bool GrMatrix::operator != (const GrMatrix& m) const {
+    return !(*this == m);
+}
+
+void GrMatrix::setTypeMask()
+{
+    fTypeMask = 0;
+    if (0 != fM[kPersp0] || 0 != fM[kPersp1] || gRESCALE != fM[kPersp2]) {
+        fTypeMask |= kPerspective_TypeBit;
+    }
+    if (GR_Scalar1 != fM[kScaleX] || GR_Scalar1 != fM[kScaleY]) {
+        fTypeMask |= kScale_TypeBit;
+        if (0 == fM[kScaleX] && 0 == fM[kScaleY]) {
+            fTypeMask |= kZeroScale_TypeBit;
+        }
+    }
+    if (0 != fM[kSkewX] || 0 != fM[kSkewY]) {
+        fTypeMask |= kSkew_TypeBit;
+    }
+    if (0 != fM[kTransX] || 0 != fM[kTransY]) {
+        fTypeMask |= kTranslate_TypeBit;
+    }    
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Matrix transformation procs
+//////
+
+void GrMatrix::mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i] = src[i];
+        }
+    }
+}
+
+void GrMatrix::mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]);
+        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]);
+    }
+}
+
+
+void GrMatrix::mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = src[i].fX + fM[kTransX];
+        dst[i].fY = src[i].fY + fM[kTransY];
+    }
+}
+
+void GrMatrix::mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + fM[kTransX];
+        dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + fM[kTransY];
+    }
+}
+
+void GrMatrix::mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fX, fM[kScaleX]) + GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fY, fM[kScaleY]) + GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = src[i].fX + GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = src[i].fY + GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];           
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+            dst[i].fY = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        GrScalar x, y, w;
+        x = GrMul(fM[kScaleX], src[i].fX) + GrMul(fM[kSkewX], src[i].fY) + fM[kTransX];
+        y = GrMul(fM[kSkewY], src[i].fX) + GrMul(fM[kScaleY], src[i].fY) + fM[kTransY];
+        w = GrMul(fM[kPersp0], src[i].fX) + GrMul(fM[kPersp1], src[i].fY) + fM[kPersp2];
+        // TODO need fixed point invert
+        if (w) {
+            w = 1 / w;
+        }
+        dst[i].fX = GrMul(x, w);
+        dst[i].fY = GrMul(y, w);            
+    }
+}
+
+void GrMatrix::mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    GrAssert(0);
+}
+
+void GrMatrix::mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    memset(dst, 0, sizeof(GrPoint)*count);
+}
+
+void GrMatrix::mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    for (uint32_t i = 0; i < count; ++i) {
+        dst[i].fX = fM[kTransX];
+        dst[i].fY = fM[kTransY];           
+    }
+}
+
+void GrMatrix::mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]);
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]);
+            dst[i].fX = newX;
+        }
+    }
+}
+
+void GrMatrix::mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const {
+    if (src != dst) {
+        for (uint32_t i = 0; i < count; ++i) {
+            dst[i].fX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+        }
+    } else {
+        for (uint32_t i = 0; i < count; ++i) {
+            GrScalar newX = GrMul(src[i].fY, fM[kSkewX]) + fM[kTransX];
+            dst[i].fY = GrMul(src[i].fX, fM[kSkewY]) + fM[kTransY];
+            dst[i].fX = newX;
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Unit test
+//////
+
+#include "GrRandom.h"
+
+#if GR_DEBUG
+enum MatrixType {
+    kRotate_MatrixType,
+    kScaleX_MatrixType,
+    kScaleY_MatrixType,
+    kSkewX_MatrixType,
+    kSkewY_MatrixType,
+    kTranslateX_MatrixType,
+    kTranslateY_MatrixType,
+    kSwapScaleXY_MatrixType,
+    kPersp_MatrixType,
+    
+    kMatrixTypeCount
+};
+
+static void create_matrix(GrMatrix* matrix, GrRandom& rand) {
+    MatrixType type = (MatrixType)(rand.nextU() % kMatrixTypeCount);
+    switch (type) {
+        case kRotate_MatrixType: {
+            float angle = rand.nextF() * 2 *3.14159265358979323846f;
+            GrScalar cosa = GrFloatToScalar(cosf(angle));
+            GrScalar sina = GrFloatToScalar(sinf(angle));
+            matrix->setAll(cosa,      -sina,           0, 
+                           sina,       cosa,           0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kScaleX_MatrixType: {
+            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(scale,      0,              0, 
+                           0,          GR_Scalar1,     0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kScaleY_MatrixType: {
+            GrScalar scale = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, 0,              0, 
+                           0,          scale,          0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kSkewX_MatrixType: {
+            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, skew,           0, 
+                           0,          GR_Scalar1,     0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;            
+        case kSkewY_MatrixType: {
+            GrScalar skew = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(GR_Scalar1, 0,              0, 
+                           skew,       GR_Scalar1,     0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kTranslateX_MatrixType: {
+            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
+            matrix->setAll(GR_Scalar1, 0,              trans, 
+                           0,          GR_Scalar1,     0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;            
+        case kTranslateY_MatrixType: {
+            GrScalar trans = GrFloatToScalar(rand.nextF(-10, 10));
+            matrix->setAll(GR_Scalar1, 0,              0, 
+                           0,          GR_Scalar1,     trans, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break; 
+        case kSwapScaleXY_MatrixType: {
+            GrScalar xy = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar yx = GrFloatToScalar(rand.nextF(-2, 2));
+            matrix->setAll(0,          xy,             0, 
+                           yx,         0,              0, 
+                           0,          0,              GrMatrix::I()[8]);
+        } break;
+        case kPersp_MatrixType: {
+            GrScalar p0 = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar p1 = GrFloatToScalar(rand.nextF(-2, 2));
+            GrScalar p2 = GrFloatToScalar(rand.nextF(-0.5f, 0.75f));
+            matrix->setAll(GR_Scalar1, 0,              0, 
+                           0,          GR_Scalar1,     0, 
+                           p0,         p1,             GrMul(p2,GrMatrix::I()[8]));
+        } break;
+        default:
+            GrAssert(0);
+            break;
+    }
+}
+#endif
+
+void GrMatrix::UnitTest() {
+    GrRandom rand;
+
+    // Create a bunch of matrices and test point mapping, max stretch calc, 
+    // inversion and multiply-by-inverse.
+#if GR_DEBUG
+    for (int i = 0; i < 10000; ++i) {
+        GrMatrix a, b;
+        a.setIdentity();
+        int num = rand.nextU() % 6;
+        // force testing of I and swapXY
+        if (0 == i) {
+            num = 0;
+            GrAssert(a.isIdentity());
+        } else if (1 == i) {
+            num = 0;
+            a.setAll(0, GR_Scalar1, 0,
+                     GR_Scalar1, 0, 0, 
+                     0, 0, I()[8]);
+        }
+        for (int j = 0; j < num; ++j) {
+            create_matrix(&b, rand);
+            a.preConcat(b);
+        }
+        
+        GrScalar maxStretch = a.getMaxStretch();
+        if (maxStretch > 0) {
+            maxStretch = GrMul(GR_Scalar1 + GR_Scalar1 / 100, maxStretch);
+        }
+        GrPoint origin = a.mapPoint(GrPoint(0,0));
+
+        for (int j = 0; j < 9; ++j) {
+            int mask, origMask = a.fTypeMask;
+            GrScalar old = a[j];
+            
+            a.set(j, GR_Scalar1);
+            mask = a.fTypeMask;
+            a.setTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, 0);
+            mask = a.fTypeMask;
+            a.setTypeMask();
+            GrAssert(mask == a.fTypeMask);
+
+            a.set(j, 10 * GR_Scalar1);
+            mask = a.fTypeMask;
+            a.setTypeMask();
+            GrAssert(mask == a.fTypeMask);
+            
+            a.set(j, old);            
+            GrAssert(a.fTypeMask == origMask);
+        }
+                     
+        for (int j = 0; j < 100; ++j) {
+            GrPoint pt;
+            pt.fX = GrFloatToScalar(rand.nextF(-10, 10));
+            pt.fY = GrFloatToScalar(rand.nextF(-10, 10));            
+            
+            GrPoint t0, t1, t2;
+            t0 = a.mapPoint(pt);             // map to a new point
+            t1 = pt;
+            a.mapPoints(&t1, &t1, 1);        // in place
+            a.mapPerspective(&t2, &pt, 1);   // full mult
+            GrAssert(t0 == t1 && t1 == t2);
+            if (maxStretch >= 0.f) {
+                GrVec vec;
+                vec.setBetween(t0, origin);
+                GrScalar stretch = vec.length() / pt.distanceToOrigin();
+                GrAssert(stretch <= maxStretch);
+            }
+        }
+        double det = a.determinant();
+        if (fabs(det) > 1e-3 && a.invert(&b)) {
+            GrMatrix c;
+            c.setConcat(a,b);
+            for (int i = 0; i < 9; ++i) {
+                GrScalar diff = GrScalarAbs(c[i] - I()[i]);
+                GrAssert(diff < (5*GR_Scalar1 / 100));
+            }
+        }
+    }
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+int Gr_clz(uint32_t n) {
+    if (0 == n) {
+        return 32;
+    }
+
+    int count = 0;
+    if (0 == (n & 0xFFFF0000)) {
+        count += 16;
+        n <<= 16;
+    }
+    if (0 == (n & 0xFF000000)) {
+        count += 8;
+        n <<= 8;
+    }
+    if (0 == (n & 0xF0000000)) {
+        count += 4;
+        n <<= 4;
+    }
+    if (0 == (n & 0xC0000000)) {
+        count += 2;
+        n <<= 2;
+    }
+    if (0 == (n & 0x80000000)) {
+        count += 1;
+    }
+    return count;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#include "GrRect.h"
+
+void GrRect::setBounds(const GrPoint pts[], int count) {
+    if (count <= 0) {
+        this->setEmpty();
+    } else {
+        GrScalar L, R, T, B;
+        L = R = pts[0].fX;
+        T = B = pts[0].fY;
+        for (int i = 1; i < count; i++) {
+            GrScalar x = pts[i].fX;
+            GrScalar y = pts[i].fY;
+            if (x < L) {
+                L = x;
+            } else if (x > R) {
+                R = x;
+            }
+            if (y < T) {
+                T = y;
+            } else if (y > B) {
+                B = y;
+            }
+        }
+        this->setLTRB(L, T, R, B);
+    }
+}
+
+
diff --git a/gpu/src/GrMemory.cpp b/gpu/src/GrMemory.cpp
new file mode 100644
index 0000000..3da924a
--- /dev/null
+++ b/gpu/src/GrMemory.cpp
@@ -0,0 +1,36 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrMemory.h"
+
+#include <stdlib.h>
+
+void* GrMalloc(size_t bytes) {
+    void* ptr = ::malloc(bytes);
+    if (NULL == ptr) {
+        ::exit(-1);
+    }
+    return ptr;
+}
+
+void GrFree(void* ptr) {
+    if (ptr) {
+        ::free(ptr);
+    }
+}
+
+
diff --git a/gpu/src/GrPath.cpp b/gpu/src/GrPath.cpp
new file mode 100644
index 0000000..7b117eb
--- /dev/null
+++ b/gpu/src/GrPath.cpp
@@ -0,0 +1,173 @@
+#include "GrPath.h"
+
+GrPath::GrPath() {}
+
+GrPath::GrPath(const GrPath& src) {
+}
+
+GrPath::GrPath(GrPathIter& iter) {
+    this->resetFromIter(&iter);
+}
+
+GrPath::~GrPath() {
+}
+
+void GrPath::ensureMoveTo() {
+    if (fVerbs.isEmpty() || this->wasLastVerb(kClose)) {
+        *fVerbs.append() = kMove;
+        fPts.append()->set(0, 0);
+    }
+}
+
+void GrPath::moveTo(GrScalar x, GrScalar y) {
+    if (this->wasLastVerb(kMove)) {
+        // overwrite prev kMove value
+        fPts[fPts.count() - 1].set(x, y);
+    } else {
+        *fVerbs.append() = kMove;
+        fPts.append()->set(x, y);
+    }
+}
+
+void GrPath::lineTo(GrScalar x, GrScalar y) {
+    this->ensureMoveTo();
+    *fVerbs.append() = kLine;
+    fPts.append()->set(x, y);
+}
+
+void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
+    this->ensureMoveTo();
+    *fVerbs.append() = kQuad;
+    fPts.append()->set(x0, y0);
+    fPts.append()->set(x1, y1);
+}
+
+void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+                     GrScalar x2, GrScalar y2) {
+    this->ensureMoveTo();
+    *fVerbs.append() = kCubic;
+    fPts.append()->set(x0, y0);
+    fPts.append()->set(x1, y1);
+    fPts.append()->set(x2, y2);
+}
+
+void GrPath::close() {
+    if (!fVerbs.isEmpty() && !this->wasLastVerb(kClose)) {
+        // should we allow kMove followed by kClose?
+        *fVerbs.append() = kClose;
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void GrPath::resetFromIter(GrPathIter* iter) {
+    fPts.reset();
+    fVerbs.reset();
+
+    GrPoint pts[4];
+    GrPathIter::Command cmd;
+
+    while ((cmd = iter->next(pts)) != GrPathIter::kEnd_Command) {
+        switch (cmd) {
+            case GrPathIter::kMove_Command:
+                this->moveTo(pts[0].fX, pts[0].fY);
+                break;
+            case GrPathIter::kLine_Command:
+                this->lineTo(pts[1].fX, pts[1].fY);
+                break;
+            case GrPathIter::kQuadratic_Command:
+                this->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
+                break;
+            case GrPathIter::kCubic_Command:
+                this->cubicTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
+                              pts[3].fX, pts[3].fY);
+                break;
+            case GrPathIter::kClose_Command:
+                this->close();
+                break;
+            case GrPathIter::kEnd_Command:
+                // never get here, but include it to avoid the warning
+                break;
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrPath::Iter::Iter(const GrPath& path) : fPath(path) {
+    this->rewind();
+}
+
+GrPathIter::Command GrPath::Iter::next(GrPoint points[]) {
+    if (fVerbIndex == fPath.fVerbs.count()) {
+        GrAssert(fPtIndex == fPath.fPts.count());
+        return GrPathIter::kEnd_Command;
+    } else {
+        GrAssert(fVerbIndex < fPath.fVerbs.count());
+    }
+
+    uint8_t cmd = fPath.fVerbs[fVerbIndex++];
+    const GrPoint* srcPts = fPath.fPts.begin() + fPtIndex;
+
+    switch (cmd) {
+        case kMove:
+            if (points) {
+                points[0] = srcPts[0];
+            }
+            fLastPt = srcPts[0];
+            GrAssert(fPtIndex <= fPath.fPts.count() + 1);
+            fPtIndex += 1;
+            break;
+        case kLine:
+            if (points) {
+                points[0] = fLastPt;
+                points[1] = srcPts[0];
+            }
+            fLastPt = srcPts[0];
+            GrAssert(fPtIndex <= fPath.fPts.count() + 1);
+            fPtIndex += 1;
+            break;
+        case kQuad:
+            if (points) {
+                points[0] = fLastPt;
+                points[1] = srcPts[0];
+                points[2] = srcPts[1];
+            }
+            fLastPt = srcPts[2];
+            GrAssert(fPtIndex <= fPath.fPts.count() + 2);
+            fPtIndex += 2;
+            break;
+        case kCubic:
+            if (points) {
+                points[0] = fLastPt;
+                points[1] = srcPts[0];
+                points[2] = srcPts[1];
+                points[3] = srcPts[2];
+            }
+            fLastPt = srcPts[2];
+            GrAssert(fPtIndex <= fPath.fPts.count() + 3);
+            fPtIndex += 3;
+            break;
+        case kClose:
+            break;
+        default:
+            GrAssert(!"unknown grpath verb");
+            break;
+    }
+    return (GrPathIter::Command)cmd;
+}
+
+GrPathIter::ConvexHint GrPath::Iter::hint() const {
+    return fPath.getConvexHint();
+}
+
+GrPathIter::Command GrPath::Iter::next() {
+    return this->next(NULL);
+}
+
+void GrPath::Iter::rewind() {
+    fVerbIndex = fPtIndex = 0;
+}
+
+
+
diff --git a/gpu/src/GrPrintf_printf.cpp b/gpu/src/GrPrintf_printf.cpp
new file mode 100644
index 0000000..ad239ec
--- /dev/null
+++ b/gpu/src/GrPrintf_printf.cpp
@@ -0,0 +1,36 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTypes.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+void GrPrintf(const char format[], ...) {
+    const size_t MAX_BUFFER_SIZE = 2048;
+
+    char buffer[MAX_BUFFER_SIZE + 1];
+    va_list args;
+
+    va_start(args, format);
+    vsnprintf(buffer, MAX_BUFFER_SIZE, format, args);
+    va_end(args);
+
+    printf("%s", buffer);
+}
+
+
diff --git a/gpu/src/GrPrintf_skia.cpp b/gpu/src/GrPrintf_skia.cpp
new file mode 100644
index 0000000..fa8b6a7
--- /dev/null
+++ b/gpu/src/GrPrintf_skia.cpp
@@ -0,0 +1,39 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTypes.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "SkTypes.h"
+
+void GrPrintf(const char format[], ...) {
+    const size_t MAX_BUFFER_SIZE = 512;
+
+    char buffer[MAX_BUFFER_SIZE + 1];
+    va_list args;
+
+    va_start(args, format);
+    vsnprintf(buffer, MAX_BUFFER_SIZE, format, args);
+    va_end(args);
+
+    // skia has already mapped this to do the "right thing"
+    SkDebugf("%s", buffer);
+}
+
+
diff --git a/gpu/src/GrQuadIndexTable.h b/gpu/src/GrQuadIndexTable.h
new file mode 100644
index 0000000..7389466
--- /dev/null
+++ b/gpu/src/GrQuadIndexTable.h
@@ -0,0 +1,98 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+/*
+    These are our vertex-indices for a series of "quads", which we implement
+    as a series of pairs of triangles. See setRectFan() for the
+    vertex order.
+
+    The largest value is 255, so we could store these in any size
+    (byte, short, int). Since the table is small, we just choose the size
+    that we think will be fastest (e.g. some drivers don't have native support
+    for byte-indices, so byte may not be the fastest)
+*/
+static const uint16_t gQuadIndexTable[] = {
+      0,   1,   2,   0,   2,   3,
+      4,   5,   6,   4,   6,   7,
+      8,   9,  10,   8,  10,  11,
+     12,  13,  14,  12,  14,  15,
+     16,  17,  18,  16,  18,  19,
+     20,  21,  22,  20,  22,  23,
+     24,  25,  26,  24,  26,  27,
+     28,  29,  30,  28,  30,  31,
+     32,  33,  34,  32,  34,  35,
+     36,  37,  38,  36,  38,  39,
+     40,  41,  42,  40,  42,  43,
+     44,  45,  46,  44,  46,  47,
+     48,  49,  50,  48,  50,  51,
+     52,  53,  54,  52,  54,  55,
+     56,  57,  58,  56,  58,  59,
+     60,  61,  62,  60,  62,  63,
+     64,  65,  66,  64,  66,  67,
+     68,  69,  70,  68,  70,  71,
+     72,  73,  74,  72,  74,  75,
+     76,  77,  78,  76,  78,  79,
+     80,  81,  82,  80,  82,  83,
+     84,  85,  86,  84,  86,  87,
+     88,  89,  90,  88,  90,  91,
+     92,  93,  94,  92,  94,  95,
+     96,  97,  98,  96,  98,  99,
+    100, 101, 102, 100, 102, 103,
+    104, 105, 106, 104, 106, 107,
+    108, 109, 110, 108, 110, 111,
+    112, 113, 114, 112, 114, 115,
+    116, 117, 118, 116, 118, 119,
+    120, 121, 122, 120, 122, 123,
+    124, 125, 126, 124, 126, 127,
+    128, 129, 130, 128, 130, 131,
+    132, 133, 134, 132, 134, 135,
+    136, 137, 138, 136, 138, 139,
+    140, 141, 142, 140, 142, 143,
+    144, 145, 146, 144, 146, 147,
+    148, 149, 150, 148, 150, 151,
+    152, 153, 154, 152, 154, 155,
+    156, 157, 158, 156, 158, 159,
+    160, 161, 162, 160, 162, 163,
+    164, 165, 166, 164, 166, 167,
+    168, 169, 170, 168, 170, 171,
+    172, 173, 174, 172, 174, 175,
+    176, 177, 178, 176, 178, 179,
+    180, 181, 182, 180, 182, 183,
+    184, 185, 186, 184, 186, 187,
+    188, 189, 190, 188, 190, 191,
+    192, 193, 194, 192, 194, 195,
+    196, 197, 198, 196, 198, 199,
+    200, 201, 202, 200, 202, 203,
+    204, 205, 206, 204, 206, 207,
+    208, 209, 210, 208, 210, 211,
+    212, 213, 214, 212, 214, 215,
+    216, 217, 218, 216, 218, 219,
+    220, 221, 222, 220, 222, 223,
+    224, 225, 226, 224, 226, 227,
+    228, 229, 230, 228, 230, 231,
+    232, 233, 234, 232, 234, 235,
+    236, 237, 238, 236, 238, 239,
+    240, 241, 242, 240, 242, 243,
+    244, 245, 246, 244, 246, 247,
+    248, 249, 250, 248, 250, 251,
+    252, 253, 254, 252, 254, 255,
+};
+
+#define GR_COUNT_QUADINDEXTABLE    GR_ARRAY_COUNT(gQuadIndexTable)
+
+
+
diff --git a/gpu/src/GrRectanizer.cpp b/gpu/src/GrRectanizer.cpp
new file mode 100644
index 0000000..cb6576a
--- /dev/null
+++ b/gpu/src/GrRectanizer.cpp
@@ -0,0 +1,130 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrRectanizer.h"
+#include "GrTBSearch.h"
+
+#define MIN_HEIGHT_POW2     2
+
+class GrRectanizerPow2 : public GrRectanizer {
+public:
+    GrRectanizerPow2(int w, int h) : GrRectanizer(w, h) {
+        fNextStripY = 0;
+        fAreaSoFar = 0;
+        Gr_bzero(fRows, sizeof(fRows));
+    }
+
+    virtual ~GrRectanizerPow2() {
+    }
+
+    virtual bool addRect(int w, int h, GrIPoint16* loc);
+
+    virtual float percentFull() const {
+        return fAreaSoFar / ((float)this->width() * this->height());
+    }
+
+    virtual int stripToPurge(int height) const { return -1; }
+    virtual void purgeStripAtY(int yCoord) { }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    struct Row {
+        GrIPoint16  fLoc;
+        int         fRowHeight;
+        
+        bool canAddWidth(int width, int containerWidth) const {
+            return fLoc.fX + width <= containerWidth;
+        }
+    };
+
+    Row fRows[16];
+
+    static int HeightToRowIndex(int height) {
+        GrAssert(height >= MIN_HEIGHT_POW2);
+        return 32 - Gr_clz(height - 1);
+    }
+
+    int fNextStripY;
+    int32_t fAreaSoFar;
+
+    bool canAddStrip(int height) const {
+        return fNextStripY + height <= this->height();
+    }
+
+    void initRow(Row* row, int rowHeight) {
+        row->fLoc.set(0, fNextStripY);
+        row->fRowHeight = rowHeight;
+        fNextStripY += rowHeight;
+    }
+};
+
+bool GrRectanizerPow2::addRect(int width, int height, GrIPoint16* loc) {
+    if ((unsigned)width > (unsigned)this->width() ||
+        (unsigned)height > (unsigned)this->height()) {
+        return false;
+    }
+
+    int32_t area = width * height;
+
+    /*
+        We use bsearch, but there may be more than one row with the same height,
+        so we actually search for height-1, which can only be a pow2 itself if
+        height == 2. Thus we set a minimum height.
+     */
+    height = GrNextPow2(height);
+    if (height < MIN_HEIGHT_POW2) {
+        height = MIN_HEIGHT_POW2;
+    }
+
+    Row* row = &fRows[HeightToRowIndex(height)];
+    GrAssert(row->fRowHeight == 0 || row->fRowHeight == height);
+
+    if (0 == row->fRowHeight) {
+        if (!this->canAddStrip(height)) {
+            return false;
+        }
+        this->initRow(row, height);
+    } else {
+        if (!row->canAddWidth(width, this->width())) {
+            if (!this->canAddStrip(height)) {
+                return false;
+            }
+            // that row is now "full", so retarget our Row record for
+            // another one
+            this->initRow(row, height);
+        }
+    }
+
+    GrAssert(row->fRowHeight == height);
+    GrAssert(row->canAddWidth(width, this->width()));
+    *loc = row->fLoc;
+    row->fLoc.fX += width;
+
+    GrAssert(row->fLoc.fX <= this->width());
+    GrAssert(row->fLoc.fY <= this->height());
+    GrAssert(fNextStripY <= this->height());
+    fAreaSoFar += area;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRectanizer* GrRectanizer::Factory(int width, int height) {
+    return new GrRectanizerPow2(width, height);
+}
+
+
diff --git a/gpu/src/GrRectanizer_fifo.cpp b/gpu/src/GrRectanizer_fifo.cpp
new file mode 100644
index 0000000..6b1cad2
--- /dev/null
+++ b/gpu/src/GrRectanizer_fifo.cpp
@@ -0,0 +1,130 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrRectanizer.h"
+#include "GrTBSearch.h"
+
+#define MIN_HEIGHT_POW2     2
+
+class GrRectanizerFIFO : public GrRectanizer {
+public:
+    GrRectanizerFIFO(int w, int h) : GrRectanizer(w, h) {
+        fNextStripY = 0;
+        fAreaSoFar = 0;
+        Gr_bzero(fRows, sizeof(fRows));
+    }
+    
+    virtual ~GrRectanizerFIFO() {
+    }
+    
+    virtual bool addRect(int w, int h, GrIPoint16* loc);
+    
+    virtual float percentFull() const {
+        return fAreaSoFar / ((float)this->width() * this->height());
+    }
+    
+    virtual int stripToPurge(int height) const { return -1; }
+    virtual void purgeStripAtY(int yCoord) { }
+    
+    ///////////////////////////////////////////////////////////////////////////
+    
+    struct Row {
+        GrIPoint16  fLoc;
+        int         fRowHeight;
+        
+        bool canAddWidth(int width, int containerWidth) const {
+            return fLoc.fX + width <= containerWidth;
+        }
+    };
+    
+    Row fRows[16];
+    
+    static int HeightToRowIndex(int height) {
+        GrAssert(height >= MIN_HEIGHT_POW2);
+        return 32 - Gr_clz(height - 1);
+    }
+    
+    int fNextStripY;
+    int32_t fAreaSoFar;
+    
+    bool canAddStrip(int height) const {
+        return fNextStripY + height <= this->height();
+    }
+    
+    void initRow(Row* row, int rowHeight) {
+        row->fLoc.set(0, fNextStripY);
+        row->fRowHeight = rowHeight;
+        fNextStripY += rowHeight;
+    }
+};
+
+bool GrRectanizerFIFO::addRect(int width, int height, GrIPoint16* loc) {
+    if ((unsigned)width > (unsigned)this->width() ||
+        (unsigned)height > (unsigned)this->height()) {
+        return false;
+    }
+    
+    int32_t area = width * height;
+    
+    /*
+     We use bsearch, but there may be more than one row with the same height,
+     so we actually search for height-1, which can only be a pow2 itself if
+     height == 2. Thus we set a minimum height.
+     */
+    height = GrNextPow2(height);
+    if (height < MIN_HEIGHT_POW2) {
+        height = MIN_HEIGHT_POW2;
+    }
+    
+    Row* row = &fRows[HeightToRowIndex(height)];
+    GrAssert(row->fRowHeight == 0 || row->fRowHeight == height);
+    
+    if (0 == row->fRowHeight) {
+        if (!this->canAddStrip(height)) {
+            return false;
+        }
+        this->initRow(row, height);
+    } else {
+        if (!row->canAddWidth(width, this->width())) {
+            if (!this->canAddStrip(height)) {
+                return false;
+            }
+            // that row is now "full", so retarget our Row record for
+            // another one
+            this->initRow(row, height);
+        }
+    }
+    
+    GrAssert(row->fRowHeight == height);
+    GrAssert(row->canAddWidth(width, this->width()));
+    *loc = row->fLoc;
+    row->fLoc.fX += width;
+    
+    GrAssert(row->fLoc.fX <= this->width());
+    GrAssert(row->fLoc.fY <= this->height());
+    GrAssert(fNextStripY <= this->height());
+    fAreaSoFar += area;
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRectanizer* GrRectanizer::Factory(int width, int height) {
+    return new GrRectanizerFIFO(width, height);
+}
+
+
diff --git a/gpu/src/GrTextContext.cpp b/gpu/src/GrTextContext.cpp
new file mode 100644
index 0000000..d5fa1cc
--- /dev/null
+++ b/gpu/src/GrTextContext.cpp
@@ -0,0 +1,244 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAtlas.h"
+#include "GrClipIterator.h"
+#include "GrContext.h"
+#include "GrTextContext.h"
+#include "GrTextStrike.h"
+#include "GrTextStrike_impl.h"
+#include "GrFontScaler.h"
+
+static const GrVertexLayout VLAYOUT = GrDrawTarget::kTextFormat_VertexLayoutBit;
+
+void GrTextContext::flushGlyphs() {
+    if (fCurrVertex > 0) {
+        GrDrawTarget::AutoStateRestore asr(fDrawTarget);
+
+        // setup our sampler state for our text texture/atlas
+
+        GrSamplerState sampler(GrSamplerState::kRepeat_WrapMode,
+                               GrSamplerState::kRepeat_WrapMode,
+                               GrSamplerState::kAlphaMod_SampleMode,
+                               !fExtMatrix.isIdentity());
+        fDrawTarget->setSamplerState(sampler);
+
+        GrAssert(GrIsALIGN4(fCurrVertex));
+        int nIndices = fCurrVertex + (fCurrVertex >> 1);
+        GrAssert(fCurrTexture);
+        fDrawTarget->setTexture(fCurrTexture);
+        fDrawTarget->setTextureMatrix(GrMatrix::I());
+        fDrawTarget->setIndexSourceToBuffer(fContext->quadIndexBuffer());
+
+        fDrawTarget->drawIndexed(GrDrawTarget::kTriangles_PrimitiveType,
+                                 0, 0, fCurrVertex, nIndices);
+
+        fDrawTarget->releaseReservedGeometry();
+        fVertices = NULL;
+        fMaxVertices = 0;
+        fCurrVertex = 0;
+        fCurrTexture->unref();
+        fCurrTexture = NULL;
+    }
+}
+
+GrTextContext::GrTextContext(GrContext* context, const GrMatrix* extMatrix) {
+    fContext = context;
+    fStrike = NULL;
+
+    fCurrTexture = NULL;
+    fCurrVertex = 0;
+    fClipRect = context->getClip().getBounds();
+
+    if (NULL != extMatrix) {
+        fExtMatrix = *extMatrix;
+    } else {
+        fExtMatrix = GrMatrix::I();
+    }
+    if (!fExtMatrix.isIdentity()) {
+        GrMatrix inverse;
+        GrRect r;
+        r.set(fClipRect);
+        if (fExtMatrix.invert(&inverse)) {
+            inverse.mapRect(&r);
+            r.roundOut(&fClipRect);
+        }
+    }
+
+    fContext->getViewMatrix(&fOrigViewMatrix);
+    fContext->setViewMatrix(fExtMatrix);
+
+    fVertices = NULL;
+    fMaxVertices = 0;
+    fDrawTarget = fContext->getTextTarget();
+}
+
+GrTextContext::~GrTextContext() {
+    this->flushGlyphs();
+    fContext->setViewMatrix(fOrigViewMatrix);
+}
+
+void GrTextContext::flush() {
+    this->flushGlyphs();
+}
+
+static inline void setRectFan(GrGpuTextVertex v[4], int l, int t, int r, int b,
+                              int stride) {
+    v[0 * stride].setI(l, t);
+    v[1 * stride].setI(l, b);
+    v[2 * stride].setI(r, b);
+    v[3 * stride].setI(r, t);
+}
+
+void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
+                                    GrFixed vx, GrFixed vy,
+                                    GrFontScaler* scaler) {
+    if (NULL == fStrike) {
+        fStrike = fContext->getFontCache()->getStrike(scaler);
+    }
+
+    GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
+    if (NULL == glyph || glyph->fBounds.isEmpty()) {
+        return;
+    }
+
+    vx += GrIntToFixed(glyph->fBounds.fLeft);
+    vy += GrIntToFixed(glyph->fBounds.fTop);
+
+    // keep them as ints until we've done the clip-test
+    GrFixed width = glyph->fBounds.width();
+    GrFixed height = glyph->fBounds.height();
+
+    // check if we clipped out
+    if (true || NULL == glyph->fAtlas) {
+        int x = vx >> 16;
+        int y = vy >> 16;
+        if (fClipRect.quickReject(x, y, x + width, y + height)) {
+//            Gr_clz(3);    // so we can set a break-point in the debugger
+            return;
+        }
+    }
+
+    if (NULL == glyph->fAtlas) {
+        if (fStrike->getGlyphAtlas(glyph, scaler)) {
+            goto HAS_ATLAS;
+        }
+        // try to purge
+        fContext->getFontCache()->purgeExceptFor(fStrike);
+        if (fStrike->getGlyphAtlas(glyph, scaler)) {
+            goto HAS_ATLAS;
+        }
+
+        // Draw as a path, so we flush any accumulated glyphs first
+        this->flushGlyphs();
+
+        if (NULL == glyph->fPath) {
+
+            GrPath* path = new GrPath;
+            if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
+                // flag the glyph as being dead?
+                delete path;
+                return;
+            }
+            glyph->fPath = path;
+        }
+        GrPath::Iter iter(*glyph->fPath);
+        bool useTexture = false;
+        GrPoint translate;
+        translate.set(GrFixedToScalar(vx - GrIntToFixed(glyph->fBounds.fLeft)),
+                      GrFixedToScalar(vy - GrIntToFixed(glyph->fBounds.fTop)));
+        fContext->drawPath(&iter, GrContext::kWinding_PathFill,
+                              useTexture, &translate);
+        return;
+    }
+
+HAS_ATLAS:
+    GrAssert(glyph->fAtlas);
+
+    // now promote them to fixed
+    width = GrIntToFixed(width);
+    height = GrIntToFixed(height);
+
+    GrTexture* texture = glyph->fAtlas->texture();
+    GrAssert(texture);
+
+    if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
+        this->flushGlyphs();
+        fCurrTexture = texture;
+        fCurrTexture->ref();
+    }
+
+    if (NULL == fVertices) {
+        // If we need to reserve vertices allow the draw target to suggest
+        // a number of verts to reserve and whether to perform a flush.
+        fMaxVertices = kMinRequestedVerts;
+        bool flush = fDrawTarget->geometryHints(VLAYOUT,
+                                               &fMaxVertices,
+                                               NULL);
+        if (flush) {
+            this->flushGlyphs();
+            fContext->flushText();
+            fDrawTarget = fContext->getTextTarget();
+            fMaxVertices = kDefaultRequestedVerts;
+            // ignore return, no point in flushing again.
+            fDrawTarget->geometryHints(VLAYOUT,
+                                       &fMaxVertices,
+                                       NULL);
+        }
+
+        if (fMaxVertices < kMinRequestedVerts) {
+            fMaxVertices = kDefaultRequestedVerts;
+        } else if (fMaxVertices > (fContext->maxQuadsInIndexBuffer() * 4)) {
+            // don't exceed the limit of the index buffer
+            fMaxVertices = (fContext->maxQuadsInIndexBuffer() * 4);
+        }
+        bool success = fDrawTarget->reserveAndLockGeometry(VLAYOUT,
+                                                           fMaxVertices, 0,
+                                                           (void**)&fVertices,
+                                                           NULL);
+        GrAlwaysAssert(success);
+    }
+
+    GrFixed tx = GrIntToFixed(glyph->fAtlasLocation.fX);
+    GrFixed ty = GrIntToFixed(glyph->fAtlasLocation.fY);
+
+#if GR_GL_TEXT_TEXTURE_NORMALIZED
+    int x = vx >> 16;
+    int y = vy >> 16;
+    int w = width >> 16;
+    int h = height >> 16;
+
+    setRectFan(&fVertices[2*fCurrVertex], x, y, x + w, y + h, 2);
+    setRectFan(&fVertices[2*fCurrVertex+1],
+               texture->normalizeFixedX(tx),
+               texture->normalizeFixedY(ty),
+               texture->normalizeFixedX(tx + width),
+               texture->normalizeFixedY(ty + height),
+               2);
+#else
+    fVertices[2*fCurrVertex].setXRectFan(vx, vy, vx + width, vy + height,
+                                        2 * sizeof(GrGpuTextVertex));
+    fVertices[2*fCurrVertex+1].setXRectFan(texture->normalizeFixedX(tx),
+                                          texture->normalizeFixedY(ty),
+                                          texture->normalizeFixedX(tx + width),
+                                          texture->normalizeFixedY(ty + height),
+                                          2 * sizeof(GrGpuTextVertex));
+#endif
+    fCurrVertex += 4;
+}
+
+
diff --git a/gpu/src/GrTextStrike.cpp b/gpu/src/GrTextStrike.cpp
new file mode 100644
index 0000000..c2d81d5
--- /dev/null
+++ b/gpu/src/GrTextStrike.cpp
@@ -0,0 +1,204 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrAtlas.h"
+#include "GrGpu.h"
+#include "GrMemory.h"
+#include "GrRectanizer.h"
+#include "GrTextStrike.h"
+#include "GrTextStrike_impl.h"
+#include "GrRect.h"
+
+GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
+    gpu->ref();
+    fAtlasMgr = NULL;
+
+    fHead = fTail = NULL;
+}
+
+GrFontCache::~GrFontCache() {
+    fCache.deleteAll();
+    delete fAtlasMgr;
+    fGpu->unref();
+}
+
+GrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
+                                          const Key& key) {
+    if (NULL == fAtlasMgr) {
+        fAtlasMgr = new GrAtlasMgr(fGpu);
+    }
+    GrTextStrike* strike = new GrTextStrike(this, scaler->getKey(), fAtlasMgr);
+    fCache.insert(key, strike);
+
+    if (fHead) {
+        fHead->fPrev = strike;
+    } else {
+        GrAssert(NULL == fTail);
+        fTail = strike;
+    }
+    strike->fPrev = NULL;
+    strike->fNext = fHead;
+    fHead = strike;
+
+    return strike;
+}
+
+void GrFontCache::abandonAll() {
+    fCache.deleteAll();
+    if (fAtlasMgr) {
+        fAtlasMgr->abandonAll();
+        delete fAtlasMgr;
+        fAtlasMgr = NULL;
+    }
+}
+
+void GrFontCache::freeAll() {
+    fCache.deleteAll();
+    delete fAtlasMgr;
+    fAtlasMgr = NULL;
+}
+
+void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
+    GrTextStrike* strike = fTail;
+    if (strike == preserveStrike) {
+        strike = strike->fPrev;
+    }
+    if (strike) {
+        int index = fCache.slowFindIndex(strike);
+        GrAssert(index >= 0);
+        fCache.removeAt(index, strike->fFontScalerKey->getHash());
+        this->detachStrikeFromList(strike);
+        delete strike;
+    }
+}
+
+#if GR_DEBUG
+void GrFontCache::validate() const {
+    int count = fCache.count();
+    if (0 == count) {
+        GrAssert(!fHead);
+        GrAssert(!fTail);
+    } else if (1 == count) {
+        GrAssert(fHead == fTail);
+    } else {
+        GrAssert(fHead != fTail);
+    }
+
+    int count2 = 0;
+    const GrTextStrike* strike = fHead;
+    while (strike) {
+        count2 += 1;
+        strike = strike->fNext;
+    }
+    GrAssert(count == count2);
+
+    count2 = 0;
+    strike = fTail;
+    while (strike) {
+        count2 += 1;
+        strike = strike->fPrev;
+    }
+    GrAssert(count == count2);
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+    static int gCounter;
+#endif
+
+/*
+    The text strike is specific to a given font/style/matrix setup, which is
+    represented by the GrHostFontScaler object we are given in getGlyph().
+
+    We map a 32bit glyphID to a GrGlyph record, which in turn points to a
+    atlas and a position within that texture.
+ */
+
+GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
+                           GrAtlasMgr* atlasMgr) : fPool(64) {
+    fFontScalerKey = key;
+    fFontScalerKey->ref();
+
+    fFontCache = cache;     // no need to ref, it won't go away before we do
+    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
+    fAtlas = NULL;
+
+#if GR_DEBUG
+    GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
+    gCounter += 1;
+#endif
+}
+
+static void FreeGlyph(GrGlyph*& glyph) { glyph->free(); }
+
+GrTextStrike::~GrTextStrike() {
+    GrAtlas::FreeLList(fAtlas);
+    fFontScalerKey->unref();
+    fCache.getArray().visit(FreeGlyph);
+
+#if GR_DEBUG
+    gCounter -= 1;
+    GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
+#endif
+}
+
+GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
+                                     GrFontScaler* scaler) {
+    GrIRect bounds;
+    if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
+        return NULL;
+    }
+
+    GrGlyph* glyph = fPool.alloc();
+    glyph->init(packed, bounds);
+    fCache.insert(packed, glyph);
+    return glyph;
+}
+
+bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
+    GrAssert(glyph);
+    GrAssert(scaler);
+    GrAssert(fCache.contains(glyph));
+    if (glyph->fAtlas) {
+        return true;
+    }
+
+    GrAutoRef ar(scaler);
+    
+    size_t size = glyph->fBounds.area();
+    GrAutoSMalloc<1024> storage(size);
+    if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
+                                     glyph->height(), glyph->width(),
+                                     storage.get())) {
+        return false;
+    }
+
+    GrAtlas* atlas = fAtlasMgr->addToAtlas(fAtlas, glyph->width(),
+                                           glyph->height(), storage.get(),
+                                           &glyph->fAtlasLocation);
+    if (NULL == atlas) {
+        return false;
+    }
+
+    // update fAtlas as well, since they may be chained in a linklist
+    glyph->fAtlas = fAtlas = atlas;
+    return true;
+}
+
+
diff --git a/gpu/src/GrTextStrike_impl.h b/gpu/src/GrTextStrike_impl.h
new file mode 100644
index 0000000..7e03e2a
--- /dev/null
+++ b/gpu/src/GrTextStrike_impl.h
@@ -0,0 +1,113 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef GrTextStrike_impl_DEFINED
+#define GrTextStrike_impl_DEFINED
+
+class GrFontCache::Key {
+public:
+    Key(GrFontScaler* scaler) {
+        fFontScalerKey = scaler->getKey();
+    }
+    
+    uint32_t getHash() const { return fFontScalerKey->getHash(); }
+    
+    static bool LT(const GrTextStrike& strike, const Key& key) {
+        return *strike.getFontScalerKey() < *key.fFontScalerKey;
+    }
+    static bool EQ(const GrTextStrike& strike, const Key& key) {
+        return *strike.getFontScalerKey() == *key.fFontScalerKey;
+    }
+    
+private:
+    const GrKey* fFontScalerKey;
+};
+
+void GrFontCache::detachStrikeFromList(GrTextStrike* strike) {
+    if (strike->fPrev) {
+        GrAssert(fHead != strike);
+        strike->fPrev->fNext = strike->fNext;
+    } else {
+        GrAssert(fHead == strike);
+        fHead = strike->fNext;
+    }
+
+    if (strike->fNext) {
+        GrAssert(fTail != strike);
+        strike->fNext->fPrev = strike->fPrev;
+    } else {
+        GrAssert(fTail == strike);
+        fTail = strike->fPrev;
+    }
+}
+
+GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler) {
+    this->validate();
+    
+    Key key(scaler);
+    GrTextStrike* strike = fCache.find(key);
+    if (NULL == strike) {
+        strike = this->generateStrike(scaler, key);
+    } else if (strike->fPrev) {
+        // Need to put the strike at the head of its dllist, since that is how
+        // we age the strikes for purging (we purge from the back of the list
+        this->detachStrikeFromList(strike);
+        // attach at the head
+        fHead->fPrev = strike;
+        strike->fNext = fHead;
+        strike->fPrev = NULL;
+        fHead = strike;
+    }
+
+    this->validate();
+    return strike;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  This Key just wraps a glyphID, and matches the protocol need for
+ *  GrTHashTable
+ */
+class GrTextStrike::Key {
+public:
+    Key(GrGlyph::PackedID id) : fPackedID(id) {}
+    
+    uint32_t getHash() const { return fPackedID; }
+    
+    static bool LT(const GrGlyph& glyph, const Key& key) {
+        return glyph.fPackedID < key.fPackedID;
+    }
+    static bool EQ(const GrGlyph& glyph, const Key& key) {
+        return glyph.fPackedID == key.fPackedID;
+    }
+    
+private:
+    GrGlyph::PackedID fPackedID;
+};
+
+GrGlyph* GrTextStrike::getGlyph(GrGlyph::PackedID packed,
+                                GrFontScaler* scaler) {
+    GrGlyph* glyph = fCache.find(packed);
+    if (NULL == glyph) {
+        glyph = this->generateGlyph(packed, scaler);
+    }
+    return glyph;
+}
+
+#endif
+
diff --git a/gpu/src/GrTextureCache.cpp b/gpu/src/GrTextureCache.cpp
new file mode 100644
index 0000000..3ba3339
--- /dev/null
+++ b/gpu/src/GrTextureCache.cpp
@@ -0,0 +1,297 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrTextureCache.h"
+#include "GrTexture.h"
+
+GrTextureEntry::GrTextureEntry(const GrTextureKey& key, GrTexture* texture)
+        : fKey(key), fTexture(texture) {
+    fLockCount = 0;
+    fPrev = fNext = NULL;
+
+    // we assume ownership of the texture, and will unref it when we die
+    GrAssert(texture);
+}
+
+GrTextureEntry::~GrTextureEntry() {
+    fTexture->unref();
+}
+
+#if GR_DEBUG
+void GrTextureEntry::validate() const {
+    GrAssert(fLockCount >= 0);
+    GrAssert(fTexture);
+    fTexture->validate();
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTextureCache::GrTextureCache(int maxCount, size_t maxBytes) : 
+        fMaxCount(maxCount),
+        fMaxBytes(maxBytes) {
+    fEntryCount          = 0;
+    fEntryBytes          = 0;
+    fClientDetachedCount = 0;
+    fClientDetachedBytes = 0;
+
+    fHead = fTail = NULL;
+}
+
+GrTextureCache::~GrTextureCache() {
+    GrAutoTextureCacheValidate atcv(this);
+    
+    this->deleteAll(kFreeTexture_DeleteMode);
+}
+
+void GrTextureCache::internalDetach(GrTextureEntry* entry, 
+                                    bool clientDetach) {
+    GrTextureEntry* prev = entry->fPrev;
+    GrTextureEntry* next = entry->fNext;
+
+    if (prev) {
+        prev->fNext = next;
+    } else {
+        fHead = next;
+    }
+    if (next) {
+        next->fPrev = prev;
+    } else {
+        fTail = prev;
+    }
+
+    // update our stats
+    if (clientDetach) {
+        fClientDetachedCount += 1;
+        fClientDetachedBytes += entry->texture()->sizeInBytes();
+    } else {
+        fEntryCount -= 1;
+        fEntryBytes -= entry->texture()->sizeInBytes();
+    }
+}
+
+void GrTextureCache::attachToHead(GrTextureEntry* entry, 
+                                  bool clientReattach) {
+    entry->fPrev = NULL;
+    entry->fNext = fHead;
+    if (fHead) {
+        fHead->fPrev = entry;
+    }
+    fHead = entry;
+    if (NULL == fTail) {
+        fTail = entry;
+    }
+
+    // update our stats
+    if (clientReattach) {
+        fClientDetachedCount -= 1;
+        fClientDetachedBytes -= entry->texture()->sizeInBytes();
+    } else {
+        fEntryCount += 1;
+        fEntryBytes += entry->texture()->sizeInBytes();
+    }
+}
+
+class GrTextureCache::Key {
+    typedef GrTextureEntry T;
+
+    const GrTextureKey& fKey;
+public:
+    Key(const GrTextureKey& key) : fKey(key) {}
+
+    uint32_t getHash() const { return fKey.hashIndex(); }
+    
+    static bool LT(const T& entry, const Key& key) {
+        return entry.key() < key.fKey;
+    }
+    static bool EQ(const T& entry, const Key& key) {
+        return entry.key() == key.fKey;
+    }
+#if GR_DEBUG
+    static uint32_t GetHash(const T& entry) {
+        return entry.key().hashIndex();
+    }
+    static bool LT(const T& a, const T& b) {
+        return a.key() < b.key();
+    }
+    static bool EQ(const T& a, const T& b) {
+        return a.key() == b.key();
+    }
+#endif
+};
+
+GrTextureEntry* GrTextureCache::findAndLock(const GrTextureKey& key) {
+    GrAutoTextureCacheValidate atcv(this);
+
+    GrTextureEntry* entry = fCache.find(key);
+    if (entry) {
+        this->internalDetach(entry, false);
+        this->attachToHead(entry, false);
+        // mark the entry as "busy" so it doesn't get purged
+        entry->lock();
+    }
+    return entry;
+}
+
+GrTextureEntry* GrTextureCache::createAndLock(const GrTextureKey& key,
+                                              GrTexture* texture) {
+    GrAutoTextureCacheValidate atcv(this);
+
+    GrTextureEntry* entry = new GrTextureEntry(key, texture);
+
+    this->attachToHead(entry, false);
+    fCache.insert(key, entry);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+    GrPrintf("--- add texture to cache %p, count=%d bytes= %d %d\n",
+             entry, fEntryCount, texture->sizeInBytes(), fEntryBytes);
+#endif
+
+    // mark the entry as "busy" so it doesn't get purged
+    entry->lock();
+    this->purgeAsNeeded();
+    return entry;
+}
+
+void GrTextureCache::detach(GrTextureEntry* entry) {
+    internalDetach(entry, true);
+    fCache.remove(entry->fKey, entry);
+}
+
+void GrTextureCache::reattachAndUnlock(GrTextureEntry* entry) {
+    attachToHead(entry, true);
+    fCache.insert(entry->key(), entry);
+    unlock(entry);
+}
+
+void GrTextureCache::unlock(GrTextureEntry* entry) {
+    GrAutoTextureCacheValidate atcv(this);
+    
+    GrAssert(entry);
+    GrAssert(entry->isLocked());
+    GrAssert(fCache.find(entry->key()));
+
+    entry->unlock();
+    this->purgeAsNeeded();
+}
+
+void GrTextureCache::purgeAsNeeded() {
+    GrAutoTextureCacheValidate atcv(this);
+    
+    GrTextureEntry* entry = fTail;
+    while (entry) {
+        if (fEntryCount <= fMaxCount && fEntryBytes <= fMaxBytes) {
+            break;
+        }
+
+        GrTextureEntry* prev = entry->fPrev;
+        if (!entry->isLocked()) {
+            // remove from our cache
+            fCache.remove(entry->fKey, entry);
+            
+            // remove from our llist
+            this->internalDetach(entry, false);
+
+#if GR_DUMP_TEXTURE_UPLOAD
+            GrPrintf("--- ~texture from cache %p [%d %d]\n", entry->texture(),
+                     entry->texture()->contentWidth(),
+                     entry->texture()->contentHeight());
+#endif
+            delete entry;
+        }
+        entry = prev;
+    }
+}
+
+void GrTextureCache::deleteAll(DeleteMode mode) {
+    GrAssert(!fClientDetachedCount);
+    GrAssert(!fClientDetachedBytes);
+    
+    GrTextureEntry* entry = fHead;
+    while (entry) {
+        GrAssert(!entry->isLocked());
+
+        GrTextureEntry* next = entry->fNext;
+        if (kAbandonTexture_DeleteMode == mode) {
+            entry->texture()->abandon();
+        }
+        delete entry;
+        entry = next;
+    }
+
+    fCache.removeAll();
+    fHead = fTail = NULL;
+    fEntryCount = 0;
+    fEntryBytes = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+static int countMatches(const GrTextureEntry* head, const GrTextureEntry* target) {
+    const GrTextureEntry* entry = head;
+    int count = 0;
+    while (entry) {
+        if (target == entry) {
+            count += 1;
+        }
+        entry = entry->next();
+    }
+    return count;
+}
+
+void GrTextureCache::validate() const {
+    GrAssert(!fHead == !fTail);
+    GrAssert(!fEntryCount == !fEntryBytes);
+    GrAssert(!fClientDetachedBytes == !fClientDetachedBytes); 
+    GrAssert(fClientDetachedBytes <= fEntryBytes);
+    GrAssert(fClientDetachedCount <= fEntryCount);
+    GrAssert((fEntryCount - fClientDetachedCount) == fCache.count());
+    GrAssert(fEntryBytes >= 0);
+    GrAssert(fEntryCount >= 0);
+    GrAssert(fClientDetachedCount >= 0);
+    GrAssert(fClientDetachedBytes >= 0);
+    
+    fCache.validate();
+
+    GrTextureEntry* entry = fHead;
+    int count = 0;
+    size_t bytes = 0;
+    while (entry) {
+        entry->validate();
+        GrAssert(fCache.find(entry->key()));
+        count += 1;
+        bytes += entry->texture()->sizeInBytes();
+        entry = entry->fNext;
+    }
+    GrAssert(count == fEntryCount - fClientDetachedCount);
+    GrAssert(bytes == fEntryBytes  - fClientDetachedBytes);
+
+    count = 0;
+    for (entry = fTail; entry; entry = entry->fPrev) {
+        count += 1;
+    }
+    GrAssert(count == fEntryCount - fClientDetachedCount);
+
+    for (int i = 0; i < count; i++) {
+        int matches = countMatches(fHead, fCache.getArray()[i]);
+        GrAssert(1 == matches);
+    }
+}
+#endif
+
+
diff --git a/gpu/src/GrTouchGesture.cpp b/gpu/src/GrTouchGesture.cpp
new file mode 100644
index 0000000..0eaedc7
--- /dev/null
+++ b/gpu/src/GrTouchGesture.cpp
@@ -0,0 +1,243 @@
+#include "GrTouchGesture.h"
+#include "SkMatrix.h"
+#include "SkTime.h"
+
+#include <math.h>
+
+static const SkMSec MAX_DBL_TAP_INTERVAL = 300;
+static const float MAX_DBL_TAP_DISTANCE = 100;
+static const float MAX_JITTER_RADIUS = 2;
+
+// if true, then ignore the touch-move, 'cause its probably just jitter
+static bool close_enough_for_jitter(float x0, float y0, float x1, float y1) {
+    return  sk_float_abs(x0 - x1) <= MAX_JITTER_RADIUS &&
+            sk_float_abs(y0 - y1) <= MAX_JITTER_RADIUS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTouchGesture::GrTouchGesture() {
+    this->reset();
+}
+
+GrTouchGesture::~GrTouchGesture() {
+}
+
+void GrTouchGesture::reset() {
+    fTouches.reset();
+    fState = kEmpty_State;
+    fLocalM.reset();
+    fGlobalM.reset();
+
+    fLastUpT = SkTime::GetMSecs() - 2*MAX_DBL_TAP_INTERVAL;
+    fLastUpP.set(0, 0);
+}
+
+void GrTouchGesture::flushLocalM() {
+    fGlobalM.postConcat(fLocalM);
+    fLocalM.reset();
+}
+
+const SkMatrix& GrTouchGesture::localM() {
+    if (fFlinger.isActive()) {
+        if (!fFlinger.evaluateMatrix(&fLocalM)) {
+            this->flushLocalM();
+        }
+    }
+    return fLocalM;
+}
+
+void GrTouchGesture::appendNewRec(void* owner, float x, float y) {
+    Rec* rec = fTouches.append();
+    rec->fOwner = owner;
+    rec->fStartX = rec->fPrevX = rec->fLastX = x;
+    rec->fStartY = rec->fPrevY = rec->fLastY = y;
+    rec->fLastT = rec->fPrevT = SkTime::GetMSecs();
+}
+
+void GrTouchGesture::touchBegin(void* owner, float x, float y) {
+//    GrPrintf("--- %d touchBegin %p %g %g\n", fTouches.count(), owner, x, y);
+
+    int index = this->findRec(owner);
+    if (index >= 0) {
+        this->flushLocalM();
+        fTouches.removeShuffle(index);
+        GrPrintf("---- already exists, removing\n");
+    }
+
+    if (fTouches.count() == 2) {
+        return;
+    }
+
+    this->flushLocalM();
+    fFlinger.stop();
+
+    this->appendNewRec(owner, x, y);
+
+    switch (fTouches.count()) {
+        case 1:
+            fState = kTranslate_State;
+            break;
+        case 2:
+            fState = kZoom_State;
+            break;
+        default:
+            break;
+    }
+}
+
+int GrTouchGesture::findRec(void* owner) const {
+    for (int i = 0; i < fTouches.count(); i++) {
+        if (owner == fTouches[i].fOwner) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static float center(float pos0, float pos1) {
+    return (pos0 + pos1) * 0.5f;
+}
+
+static const float MAX_ZOOM_SCALE = 4;
+static const float MIN_ZOOM_SCALE = 0.25f;
+
+float GrTouchGesture::limitTotalZoom(float scale) const {
+    // this query works 'cause we know that we're square-scale w/ no skew/rotation
+    const float curr = fGlobalM[0];
+    
+    if (scale > 1 && curr * scale > MAX_ZOOM_SCALE) {
+        scale = MAX_ZOOM_SCALE / curr;
+    } else if (scale < 1 && curr * scale < MIN_ZOOM_SCALE) {
+        scale = MIN_ZOOM_SCALE / curr;
+    }
+    return scale;
+}
+
+void GrTouchGesture::touchMoved(void* owner, float x, float y) {
+//    GrPrintf("--- %d touchMoved %p %g %g\n", fTouches.count(), owner, x, y);
+
+    GrAssert(kEmpty_State != fState);
+
+    int index = this->findRec(owner);
+    if (index < 0) {
+        // not found, so I guess we should add it...
+        GrPrintf("---- add missing begin\n");
+        this->appendNewRec(owner, x, y);
+        index = fTouches.count() - 1;
+    }
+
+    Rec& rec = fTouches[index];
+
+    // not sure how valuable this is
+    if (fTouches.count() == 2) {
+        if (close_enough_for_jitter(rec.fLastX, rec.fLastY, x, y)) {
+//            GrPrintf("--- drop touchMove, withing jitter tolerance %g %g\n", rec.fLastX - x, rec.fLastY - y);
+            return;
+        }
+    }
+
+    rec.fPrevX = rec.fLastX; rec.fLastX = x;
+    rec.fPrevY = rec.fLastY; rec.fLastY = y;
+    rec.fPrevT = rec.fLastT; rec.fLastT = SkTime::GetMSecs();
+
+    switch (fTouches.count()) {
+        case 1: {
+            float dx = rec.fLastX - rec.fStartX;
+            float dy = rec.fLastY - rec.fStartY;
+            dx = (float)sk_float_round2int(dx);
+            dy = (float)sk_float_round2int(dy);
+            fLocalM.setTranslate(dx, dy);
+        } break;
+        case 2: {
+            GrAssert(kZoom_State == fState);
+            const Rec& rec0 = fTouches[0];
+            const Rec& rec1 = fTouches[1];
+            
+            float scale = this->computePinch(rec0, rec1);
+            scale = this->limitTotalZoom(scale);
+
+            fLocalM.setTranslate(-center(rec0.fStartX, rec1.fStartX),
+                                 -center(rec0.fStartY, rec1.fStartY));
+            fLocalM.postScale(scale, scale);
+            fLocalM.postTranslate(center(rec0.fLastX, rec1.fLastX),
+                                  center(rec0.fLastY, rec1.fLastY));
+        } break;
+        default:
+            break;
+    }
+}
+
+void GrTouchGesture::touchEnd(void* owner) {
+//    GrPrintf("--- %d touchEnd   %p\n", fTouches.count(), owner);
+
+    int index = this->findRec(owner);
+    if (index < 0) {
+        GrPrintf("--- not found\n");
+        return;
+    }
+
+    const Rec& rec = fTouches[index];
+    if (this->handleDblTap(rec.fLastX, rec.fLastY)) {
+        return;
+    }
+
+    // count() reflects the number before we removed the owner
+    switch (fTouches.count()) {
+        case 1: {
+            this->flushLocalM();
+            float dx = rec.fLastX - rec.fPrevX;
+            float dy = rec.fLastY - rec.fPrevY;
+            float dur = (rec.fLastT - rec.fPrevT) * 0.001f;
+            if (dur > 0) {
+                fFlinger.reset(dx / dur, dy / dur);
+            }
+            fState = kEmpty_State;
+        } break;
+        case 2:
+            this->flushLocalM();
+            GrAssert(kZoom_State == fState);
+            fState = kEmpty_State;
+            break;
+        default:
+            GrAssert(kZoom_State == fState);
+            break;
+    }
+
+    fTouches.removeShuffle(index);
+}
+
+float GrTouchGesture::computePinch(const Rec& rec0, const Rec& rec1) {
+    double dx = rec0.fStartX - rec1.fStartX;
+    double dy = rec0.fStartY - rec1.fStartY;
+    double dist0 = sqrt(dx*dx + dy*dy);
+
+    dx = rec0.fLastX - rec1.fLastX;
+    dy = rec0.fLastY - rec1.fLastY;
+    double dist1 = sqrt(dx*dx + dy*dy);
+
+    double scale = dist1 / dist0;
+    return (float)scale;
+}
+
+bool GrTouchGesture::handleDblTap(float x, float y) {
+    bool found = false;
+    SkMSec now = SkTime::GetMSecs();
+    if (now - fLastUpT <= MAX_DBL_TAP_INTERVAL) {
+        if (SkPoint::Length(fLastUpP.fX - x,
+                            fLastUpP.fY - y) <= MAX_DBL_TAP_DISTANCE) {
+            fFlinger.stop();
+            fLocalM.reset();
+            fGlobalM.reset();
+            fTouches.reset();
+            fState = kEmpty_State;
+            found = true;
+        }
+    }
+
+    fLastUpT = now;
+    fLastUpP.set(x, y);
+    return found;
+}
+
+
diff --git a/gpu/src/GrVertexBufferAllocPool.cpp b/gpu/src/GrVertexBufferAllocPool.cpp
new file mode 100644
index 0000000..b6f08c9
--- /dev/null
+++ b/gpu/src/GrVertexBufferAllocPool.cpp
@@ -0,0 +1,220 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrVertexBufferAllocPool.h"
+#include "GrVertexBuffer.h"
+#include "GrGpu.h"
+
+#define GrVertexBufferAllocPool_MIN_BLOCK_SIZE      ((size_t)1 << 10)
+
+GrVertexBufferAllocPool::GrVertexBufferAllocPool(GrGpu* gpu,
+                                                 size_t blockSize,
+                                                 int preallocBufferCnt) :
+        fBlocks(GrMax(8, 2*preallocBufferCnt)) {
+    GrAssert(NULL != gpu);
+    fGpu = gpu;
+    fGpu->ref();
+    fBufferPtr = NULL;
+    fMinBlockSize = GrMax(GrVertexBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
+
+    fPreallocBuffersInUse = 0;
+    fFirstPreallocBuffer = 0;
+    for (int i = 0; i < preallocBufferCnt; ++i) {
+        GrVertexBuffer* buffer = gpu->createVertexBuffer(fMinBlockSize, true);
+        if (NULL != buffer) {
+            *fPreallocBuffers.append() = buffer;
+            buffer->ref();
+        }
+    }
+}
+
+GrVertexBufferAllocPool::~GrVertexBufferAllocPool() {
+    fPreallocBuffers.unrefAll();
+    while (!fBlocks.empty()) {
+        destroyBlock();
+    }
+    fGpu->unref();
+}
+
+void GrVertexBufferAllocPool::reset() {
+    while (!fBlocks.empty()) {
+        destroyBlock();
+    }
+    if (fPreallocBuffers.count()) {
+        // must set this after above loop.
+        fFirstPreallocBuffer = (fFirstPreallocBuffer + fPreallocBuffersInUse) %
+                               fPreallocBuffers.count();
+    }
+    GrAssert(0 == fPreallocBuffersInUse);
+}
+
+void GrVertexBufferAllocPool::unlock() {
+    GrAssert((NULL == fBufferPtr) ? (!fBlocks.empty() ||
+                                     !fBlocks.back().fVertexBuffer->isLocked()) :
+                                    (!fBlocks.empty() &&
+                                     fBlocks.back().fVertexBuffer->isLocked()));
+    if (NULL != fBufferPtr) {
+        GrAssert(!fBlocks.empty());
+        GrAssert(fBlocks.back().fVertexBuffer->isLocked());
+        fBufferPtr = NULL;
+        fBlocks.back().fVertexBuffer->unlock();
+    }
+#if GR_DEBUG
+    for (uint32_t i = 0; i < fBlocks.count(); ++i) {
+        GrAssert(!fBlocks[i].fVertexBuffer->isLocked());
+    }
+#endif
+}
+
+void* GrVertexBufferAllocPool::alloc(GrVertexLayout layout,
+                                     uint32_t vertexCount,
+                                     GrVertexBuffer** buffer,
+                                     uint32_t* startVertex) {
+    GrAssert(NULL != buffer);
+    size_t vSize = GrDrawTarget::VertexSize(layout);
+    size_t bytes = vSize * vertexCount;
+
+    if (NULL != fBufferPtr) {
+        GrAssert(!fBlocks.empty());
+        GrAssert(fBlocks.back().fVertexBuffer->isLocked());
+        BufferBlock& back = fBlocks.back();
+        uint32_t usedBytes = back.fVertexBuffer->size() - back.fBytesFree;
+        uint32_t pad = GrUIAlignUpPad(usedBytes, layout);
+        if ((bytes + pad) <= back.fBytesFree) {
+            usedBytes += pad;
+            *startVertex = usedBytes / vSize;
+            *buffer = back.fVertexBuffer;
+            back.fBytesFree -= bytes + pad;
+            return (void*)((intptr_t)fBufferPtr + usedBytes);
+        }
+    }
+
+    if (!createBlock(GrMax(bytes, fMinBlockSize))) {
+        return NULL;
+    }
+    *startVertex = 0;
+    GrAssert(NULL != fBufferPtr);
+    BufferBlock& back = fBlocks.back();
+    *buffer = back.fVertexBuffer;
+    back.fBytesFree -= bytes;
+    return fBufferPtr;
+}
+
+int GrVertexBufferAllocPool::currentBufferVertices(GrVertexLayout layout) const {
+    if (NULL != fBufferPtr) {
+        GrAssert(!fBlocks.empty());
+        const BufferBlock& back = fBlocks.back();
+        GrAssert(back.fVertexBuffer->isLocked());
+        return back.fBytesFree / GrDrawTarget::VertexSize(layout);
+    } else if (fPreallocBuffersInUse < fPreallocBuffers.count()) {
+        return fMinBlockSize / GrDrawTarget::VertexSize(layout);
+    }
+    return 0;
+}
+
+int GrVertexBufferAllocPool::preallocatedBuffersRemaining() const {
+    return fPreallocBuffers.count() - fPreallocBuffersInUse;
+}
+
+int GrVertexBufferAllocPool::preallocatedBufferVertices(GrVertexLayout layout) const {
+    return fPreallocBuffers.count() ?
+                        (fMinBlockSize / GrDrawTarget::VertexSize(layout)) :
+                        0;
+}
+
+int GrVertexBufferAllocPool::preallocatedBufferCount() const {
+    return fPreallocBuffers.count();
+}
+
+void GrVertexBufferAllocPool::release(size_t bytes) {
+    if (NULL != fBufferPtr) {
+        GrAssert(!fBlocks.empty());
+        BufferBlock& back = fBlocks.back();
+        GrAssert(back.fVertexBuffer->isLocked());
+        size_t bytesUsed = back.fVertexBuffer->size() - back.fBytesFree;
+        if (bytes >= bytesUsed) {
+            destroyBlock();
+            bytes -= bytesUsed;
+        } else {
+            back.fBytesFree += bytes;
+            return;
+        }
+    }
+    GrAssert(NULL == fBufferPtr);
+    GrAssert(fBlocks.empty() ||
+             !fBlocks.back().fVertexBuffer->isLocked());
+    // we don't honor release if it is within an already unlocked VB
+    // Our VB semantics say locking a VB discards its previous content
+    while (!fBlocks.empty() &&
+           bytes >= fBlocks.back().fVertexBuffer->size()) {
+        bytes -= fBlocks.back().fVertexBuffer->size();
+        destroyBlock();
+    }
+}
+
+bool GrVertexBufferAllocPool::createBlock(size_t size) {
+    GrAssert(size >= GrVertexBufferAllocPool_MIN_BLOCK_SIZE);
+
+    BufferBlock& block = fBlocks.push_back();
+
+    if (size == fMinBlockSize &&
+        fPreallocBuffersInUse < fPreallocBuffers.count()) {
+
+        uint32_t nextBuffer = (fPreallocBuffersInUse + fFirstPreallocBuffer) %
+                              fPreallocBuffers.count();
+        block.fVertexBuffer = fPreallocBuffers[nextBuffer];
+        block.fVertexBuffer->ref();
+        ++fPreallocBuffersInUse;
+    } else {
+        block.fVertexBuffer = fGpu->createVertexBuffer(size, true);
+        if (NULL == block.fVertexBuffer) {
+            fBlocks.pop_back();
+            return false;
+        }
+    }
+
+    block.fBytesFree = size;
+    if (NULL != fBufferPtr) {
+        GrAssert(fBlocks.count() > 1);
+        BufferBlock& prev = fBlocks.fromBack(1);
+        GrAssert(prev.fVertexBuffer->isLocked());
+        fBufferPtr = NULL;
+        prev.fVertexBuffer->unlock();
+    }
+    fBufferPtr = block.fVertexBuffer->lock();
+    return true;
+}
+
+void GrVertexBufferAllocPool::destroyBlock() {
+    GrAssert(!fBlocks.empty());
+
+    BufferBlock& block = fBlocks.back();
+    if (fPreallocBuffersInUse > 0) {
+        uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
+                                       fFirstPreallocBuffer +
+                                       (fPreallocBuffers.count() - 1)) %
+                                      fPreallocBuffers.count();
+        if (block.fVertexBuffer == fPreallocBuffers[prevPreallocBuffer]) {
+            --fPreallocBuffersInUse;
+        }
+    }
+    block.fVertexBuffer->unref();
+    fBlocks.pop_back();
+    fBufferPtr = NULL;
+}
+
+
diff --git a/gpu/src/app-android.cpp b/gpu/src/app-android.cpp
new file mode 100644
index 0000000..eea9a4d
--- /dev/null
+++ b/gpu/src/app-android.cpp
@@ -0,0 +1,387 @@
+#include <jni.h>
+#include <sys/time.h>
+#include <time.h>
+#include <android/log.h>
+#include <stdint.h>
+
+#include "GrContext.h"
+#include "SkGpuCanvas.h"
+#include "SkPaint.h"
+#include "SkString.h"
+#include "SkTime.h"
+
+#include "GrGLConfig.h"
+
+static GrContext* make_context() {
+    SkDebugf("---- before create\n");
+    GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+//    GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
+    SkDebugf("---- after create %p\n", ctx);
+    return ctx;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void gr_run_unittests() {}
+
+#include "FlingState.h"
+#include "GrTouchGesture.h"
+#include "SkView.h"
+
+typedef SkView* (*SkViewFactory)();
+
+// these values must match those in Ganesh.java
+enum TouchState {
+    kUnknown_TouchState,
+    kDown_TouchState,
+    kMoved_TouchState,
+    kUp_TouchState
+};
+
+struct State {
+    State();
+    ~State();
+
+    int countSlides() const { return fFactory.count(); }
+    const char* getSlideTitle(int index) const;
+    void chooseSlide(int index) {
+        SkDebugf("----- index %d\n", index);
+        if (index < fFactory.count()) {
+            this->setView(fFactory[index]());
+        }
+    }
+
+    void setViewport(int w, int h);
+    int getWidth() const { return fViewport.fX; }
+    int getHeight() const { return fViewport.fY; }
+    
+    void handleTouch(void*, TouchState, float x, float y);
+    void applyMatrix(SkCanvas*);
+
+    SkView* getView() const { return fView; }
+
+private:
+    SkView*     fView;
+    SkIPoint    fViewport;
+    
+    GrTouchGesture fGesture;
+
+    SkTDArray<SkViewFactory> fFactory;
+
+    void setView(SkView* view) {
+        SkSafeUnref(fView);
+        fView = view;
+
+        view->setVisibleP(true);
+        view->setClipToBounds(false);
+        view->setSize(SkIntToScalar(fViewport.fX),
+                      SkIntToScalar(fViewport.fY));
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SampleCode.h"
+
+SkViewRegister* SkViewRegister::gHead;
+SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
+    static bool gOnce;
+    if (!gOnce) {
+        gHead = NULL;
+        gOnce = true;
+    }
+    
+    fChain = gHead;
+    gHead = this;
+}
+
+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);
+}
+
+void SampleCode::TitleR(SkEvent* evt, const char title[]) {
+    GrAssert(evt && TitleQ(*evt));
+    evt->setString(gTitleEvtName, title);
+}
+
+bool SampleCode::PrefSizeQ(const SkEvent& evt) {
+    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
+}
+
+void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
+    GrAssert(evt && PrefSizeQ(*evt));
+    SkScalar size[2];
+    size[0] = width;
+    size[1] = height;
+    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) {
+    // 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 = ::fmod(value, SkScalarToDouble(period));
+    }
+    return SkDoubleToScalar(value);
+}
+
+static void drawIntoCanvas(State* state, SkCanvas* canvas) {
+    gAnimTime = SkTime::GetMSecs();
+    SkView* view = state->getView();
+    view->draw(canvas);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void resetGpuState();
+
+State::State() {
+    fViewport.set(0, 0);
+
+    const SkViewRegister* reg = SkViewRegister::Head();
+    while (reg) {
+        *fFactory.append() = reg->factory();
+        reg = reg->next();
+    }
+
+    SkDebugf("----- %d slides\n", fFactory.count());
+    fView = NULL;
+    this->chooseSlide(0);
+}
+
+State::~State() {
+    SkSafeUnref(fView);
+}
+
+void State::setViewport(int w, int h) {
+    fViewport.set(w, h);
+    if (fView) {
+        fView->setSize(SkIntToScalar(w), SkIntToScalar(h));
+    }
+    resetGpuState();
+}
+
+const char* State::getSlideTitle(int index) const {
+    SkEvent evt(gTitleEvtName);
+    evt.setFast32(index);
+    {
+        SkView* view = fFactory[index]();
+        view->doQuery(&evt);
+        view->unref();
+    }
+    return evt.findString(gTitleEvtName);
+}
+
+void State::handleTouch(void* owner, TouchState state, float x, float y) {
+    switch (state) {
+        case kDown_TouchState:
+            fGesture.touchBegin(owner, x, y);
+            break;
+        case kMoved_TouchState:
+            fGesture.touchMoved(owner, x, y);
+            break;
+        case kUp_TouchState:
+            fGesture.touchEnd(owner);
+            break;
+    }
+}
+
+void State::applyMatrix(SkCanvas* canvas) {
+    const SkMatrix& localM = fGesture.localM();
+    if (localM.getType() & SkMatrix::kScale_Mask) {
+        canvas->setExternalMatrix(&localM);
+    }
+    canvas->concat(localM);
+    canvas->concat(fGesture.globalM());
+}
+
+static State* get_state() {
+    static State* gState;
+    if (NULL == gState) {
+        gState = new State;
+    }
+    return gState;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static GrContext* gContext;
+static int gWidth;
+static int gHeight;
+static float gX, gY;
+
+static void resetGpuState() {
+    if (NULL == gContext) {
+        SkDebugf("creating context for first time\n");
+        gContext = make_context();
+    } else {
+        SkDebugf("------ gContext refcnt=%d\n", gContext->refcnt());
+        gContext->abandonAllTextures();
+        gContext->unref();
+        gContext = make_context();
+    }
+}
+
+static void doDraw() {
+    if (NULL == gContext) {
+        gContext = make_context();
+    }
+
+    State* state = get_state();
+    SkBitmap viewport;
+    viewport.setConfig(SkBitmap::kARGB_8888_Config,
+                       state->getWidth(), state->getHeight());
+
+    SkGpuCanvas canvas(gContext);
+
+    canvas.setBitmapDevice(viewport);
+    state->applyMatrix(&canvas);
+
+    drawIntoCanvas(state, &canvas);
+
+    GrGLCheckErr();
+    GrGLClearErr();
+//    gContext->checkError();
+//    gContext->clearError();
+
+    if (true) {
+        static const int FRAME_COUNT = 32;
+        static SkMSec gDuration;
+
+        static SkMSec gNow;
+        static int gFrameCounter;
+        if (++gFrameCounter == FRAME_COUNT) {
+            gFrameCounter = 0;
+            SkMSec now = SkTime::GetMSecs();
+
+            gDuration = now - gNow;
+            gNow = now;
+        }
+
+        int fps = (FRAME_COUNT * 1000) / gDuration;
+        SkString str;
+        str.printf("FPS=%3d MS=%3d", fps, gDuration / FRAME_COUNT);
+        
+        SkGpuCanvas c(gContext);
+        c.setBitmapDevice(viewport);
+
+        SkPaint p;
+        p.setAntiAlias(true);
+        SkRect r = { 0, 0, 110, 16 };
+        p.setColor(SK_ColorWHITE);
+        c.drawRect(r, p);
+        p.setColor(SK_ColorBLACK);
+        c.drawText(str.c_str(), str.size(), 4, 12, p);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
+                                                           JNIEnv*, jobject);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
+                                                                             jint w, jint h);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
+                                        jint id, jint type, jfloat x, jfloat y);
+
+    JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject);
+    JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv*, jobject, jint index);
+    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index);
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
+                                                            JNIEnv*, jobject) {
+    SkDebugf("------ nativeSurfaceCreated\n");
+    resetGpuState();
+    SkDebugf("------ end nativeSurfaceCreated\n");
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
+                                                       jint w, jint h) {
+    State* state = get_state();
+    SkDebugf("---- state.setviewport %p %d %d\n", state, w, h);
+    state->setViewport(w, h);
+    SkDebugf("---- end setviewport\n");
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) {
+    doDraw();
+}
+
+union IntPtr {
+    jint    fInt;
+    void*   fPtr;
+};
+static void* int2ptr(jint n) {
+    IntPtr data;
+    data.fInt = n;
+    return data.fPtr;
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
+                                      jint id, jint type, jfloat x, jfloat y) {
+    get_state()->handleTouch(int2ptr(id), (TouchState)type, x, y);
+}
+
+////////////
+
+JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
+    return get_state()->countSlides();
+}
+
+JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) {
+    return env->NewStringUTF(get_state()->getSlideTitle(index));
+}
+
+JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) {
+    get_state()->chooseSlide(index);
+}
+
+
+
+
+
diff --git a/gpu/src/gr_files.mk b/gpu/src/gr_files.mk
new file mode 100644
index 0000000..f9ca49e
--- /dev/null
+++ b/gpu/src/gr_files.mk
@@ -0,0 +1,23 @@
+SOURCE := \
+    GrAllocPool.cpp \
+    GrAtlas.cpp \
+    GrClip.cpp \
+    GrContext.cpp \
+    GrDrawTarget.cpp \
+    GrGLIndexBuffer.cpp	\
+    GrGLTexture.cpp \
+    GrGLVertexBuffer.cpp \
+    GrGpu.cpp \
+    GrGpuGLShaders.cpp \
+    GrGpuGLFixed.cpp \
+    GrGpuFactory.cpp \
+    GrGpuGL.cpp \
+    GrInOrderDrawBuffer.cpp \
+    GrMatrix.cpp \
+    GrMemory.cpp \
+    GrPath.cpp \
+    GrRectanizer_fifo.cpp \
+    GrTextureCache.cpp \
+    GrTextContext.cpp \
+    GrTextStrike.cpp \
+    GrVertexBufferAllocPool.cpp
diff --git a/gpu/src/gr_hello_world.cpp b/gpu/src/gr_hello_world.cpp
new file mode 100644
index 0000000..5638e19
--- /dev/null
+++ b/gpu/src/gr_hello_world.cpp
@@ -0,0 +1,30 @@
+#include "SkGLCanvas.h"
+#include "SkBitmap.h"
+#include "SkPaint.h"
+#include "SkGpuGLShaders.h"
+
+extern "C" {
+    void gr_hello_world();
+}
+
+void gr_hello_world() {
+    static GrGpu* gGpu;
+    if (NULL == gGpu) {
+        gGpu = new SkGpuGLShaders;
+    }
+
+    SkGLCanvas canvas(gGpu);
+    SkBitmap bm;
+
+    bm.setConfig(SkBitmap::kARGB_8888_Config, WIDTH, HEIGHT);
+    canvas.setBitmapDevice(bm);
+
+    canvas.drawColor(SK_ColorWHITE);
+
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setTextSize(30);
+    canvas.drawText("Hello Kno", 9, 40, 40, paint);
+}
+
+
diff --git a/gpu/src/gr_unittests.cpp b/gpu/src/gr_unittests.cpp
new file mode 100644
index 0000000..a9fd40d
--- /dev/null
+++ b/gpu/src/gr_unittests.cpp
@@ -0,0 +1,143 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrClip.h"
+#include "GrTDArray.h"
+#include "GrTBSearch.h"
+#include "GrMatrix.h"
+
+static void dump(const GrTDArray<int>& array) {
+#if 0
+    for (int i = 0; i < array.count(); i++) {
+        printf(" %d", array[i]);
+    }
+    printf("\n");
+#endif
+}
+
+static void test_tdarray() {
+    GrTDArray<int> array;
+    
+    *array.append() = 0; dump(array);
+    *array.append() = 2; dump(array);
+    *array.append() = 4; dump(array);
+    *array.append() = 6; dump(array);
+    GrAssert(array.count() == 4);
+
+    *array.insert(0) = -1; dump(array);
+    *array.insert(2) = 1; dump(array);
+    *array.insert(4) = 3; dump(array);
+    *array.insert(7) = 7; dump(array);
+    GrAssert(array.count() == 8);
+    array.remove(3); dump(array);
+    array.remove(0); dump(array);
+    array.removeShuffle(4); dump(array);
+    array.removeShuffle(1); dump(array);
+    GrAssert(array.count() == 4);
+}
+
+static bool LT(const int& elem, int value) {
+    return elem < value;
+}
+static bool EQ(const int& elem, int value) {
+    return elem == value;
+}
+
+static void test_bsearch() {
+    const int array[] = {
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99
+    };
+
+    for (size_t n = 0; n < GR_ARRAY_COUNT(array); n++) {
+        for (size_t i = 0; i < n; i++) {
+            int index = GrTBSearch<int, int>(array, n, array[i]);
+            GrAssert(index == i);
+            index = GrTBSearch<int, int>(array, n, -array[i]);
+            GrAssert(index < 0);
+        }
+    }
+}
+
+static void dump(const GrClip& clip, const char message[]) {
+    GrPrintf("--- dump clip %s\n", message);
+    GrClipIter iter(clip);
+    while (!iter.isDone()) {
+        GrIRect r;
+        iter.getRect(&r);
+        GrPrintf("--- [%d %d %d %d]\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
+        iter.next();
+    }
+}
+
+static void test_clip() {
+    GrClip  clip;
+    GrAssert(clip.isEmpty());
+    GrAssert(!clip.isRect());
+    GrAssert(!clip.isComplex());
+    GrAssert(clip.getBounds().equalsLTRB(0, 0, 0, 0));
+    GrAssert(0 == clip.countRects());
+
+    clip.setRect(GrIRect(10, 10, 10, 10));
+    GrAssert(clip.isEmpty());
+    GrAssert(!clip.isRect());
+    GrAssert(!clip.isComplex());
+    GrAssert(clip.getBounds().equalsLTRB(0, 0, 0, 0));
+    GrAssert(0 == clip.countRects());
+    dump(clip, "empty");
+
+    clip.setRect(GrIRect(10, 10, 20, 20));
+    GrAssert(!clip.isEmpty());
+    GrAssert(clip.isRect());
+    GrAssert(!clip.isComplex());
+    GrAssert(clip.getBounds().equalsLTRB(10, 10, 20, 20));
+    GrAssert(1 == clip.countRects());
+    GrAssert(clip.getRects()[0] == clip.getBounds());
+    dump(clip, "rect");
+
+    clip.addRect(GrIRect(20, 20, 25, 25));
+    GrAssert(!clip.isEmpty());
+    GrAssert(!clip.isRect());
+    GrAssert(clip.isComplex());
+    GrAssert(clip.getBounds().equalsLTRB(10, 10, 25, 25));
+    GrAssert(2 == clip.countRects());
+    dump(clip, "complex");
+
+    GrClip c1(clip);
+    GrAssert(c1 == clip);
+    GrClip c2;
+    GrAssert(c2 != c1);
+    c2 = clip;
+    GrAssert(c2 == clip);
+
+    clip.setEmpty();
+    GrAssert(clip.isEmpty());
+    GrAssert(!clip.isRect());
+    GrAssert(!clip.isComplex());
+    GrAssert(clip.getBounds().equalsLTRB(0, 0, 0, 0));
+
+    GrAssert(c1 != clip);
+    GrAssert(c2 != clip);
+}
+
+void gr_run_unittests() {
+    test_tdarray();
+    test_bsearch();
+    test_clip();
+    GrMatrix::UnitTest();
+}
+
+
diff --git a/gpu/src/skia/SkGpuCanvas.cpp b/gpu/src/skia/SkGpuCanvas.cpp
new file mode 100644
index 0000000..19bda4d
--- /dev/null
+++ b/gpu/src/skia/SkGpuCanvas.cpp
@@ -0,0 +1,60 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrContext.h"
+
+#include "SkGpuCanvas.h"
+#include "SkGpuDevice.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuCanvas::SkGpuCanvas(GrContext* context) {
+    SkASSERT(context);
+    fContext = context;
+    fContext->ref();
+}
+
+SkGpuCanvas::~SkGpuCanvas() {
+    // call this now, while our override of restore() is in effect
+    this->restoreToCount(1);
+    fContext->flush(false);
+    fContext->unref();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkGpuCanvas::getViewport(SkIPoint* size) const {
+    if (size) {
+        SkDevice* device = this->getDevice();
+        if (device) {
+            size->set(device->width(), device->height());
+        } else {
+            size->set(0, 0);
+        }
+    }
+    return true;
+}
+
+SkDevice* SkGpuCanvas::createDevice(SkBitmap::Config config, int width, int height,
+                                    bool isOpaque, bool isLayer) {
+    SkBitmap bm;
+    bm.setConfig(config, width, height);
+    bm.setIsOpaque(isOpaque);
+    return new SkGpuDevice(this, bm, isLayer);
+}
+
+
diff --git a/gpu/src/skia/SkGpuDevice.cpp b/gpu/src/skia/SkGpuDevice.cpp
new file mode 100644
index 0000000..832fc6e
--- /dev/null
+++ b/gpu/src/skia/SkGpuDevice.cpp
@@ -0,0 +1,1048 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "GrContext.h"
+#include "GrTextContext.h"
+
+#include "SkGpuCanvas.h"
+#include "SkGpuDevice.h"
+#include "SkGrTexturePixelRef.h"
+
+#include "SkDrawProcs.h"
+#include "SkGlyphCache.h"
+
+#define CACHE_LAYER_TEXTURES 1
+
+#if 0
+    extern bool (*gShouldDrawProc)();
+    #define CHECK_SHOULD_DRAW(draw)                             \
+        do {                                                    \
+            if (gShouldDrawProc && !gShouldDrawProc()) return;  \
+            this->prepareRenderTarget(draw);                    \
+        } while (0)
+#else
+    #define CHECK_SHOULD_DRAW(draw) this->prepareRenderTarget(draw)
+#endif
+
+class SkAutoExtMatrix {
+public:
+    SkAutoExtMatrix(const SkMatrix* extMatrix) {
+        if (extMatrix) {
+            SkGr::SkMatrix2GrMatrix(*extMatrix, &fMatrix);
+            fExtMatrix = &fMatrix;
+        } else {
+            fExtMatrix = NULL;
+        }
+    }
+    const GrMatrix* extMatrix() const { return fExtMatrix; }
+
+private:
+    GrMatrix    fMatrix;
+    GrMatrix*   fExtMatrix; // NULL or &fMatrix
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuDevice::SkAutoCachedTexture::
+             SkAutoCachedTexture(SkGpuDevice* device,
+                                 const SkBitmap& bitmap,
+                                 const GrSamplerState& sampler,
+                                 GrTexture** texture) {
+    GrAssert(texture);
+    fTex = NULL;
+    *texture = this->set(device, bitmap, sampler);
+}
+
+SkGpuDevice::SkAutoCachedTexture::SkAutoCachedTexture() {
+    fTex = NULL;
+}
+
+GrTexture* SkGpuDevice::SkAutoCachedTexture::set(SkGpuDevice* device,
+                                                 const SkBitmap& bitmap,
+                                                 const GrSamplerState& sampler) {
+    if (fTex) {
+        fDevice->unlockCachedTexture(fTex);
+    }
+    fDevice = device;
+    GrTexture* texture = (GrTexture*)bitmap.getTexture();
+    if (texture) {
+        // return the native texture
+        fTex = NULL;
+        device->context()->setTexture(texture);
+    } else {
+        // look it up in our cache
+        fTex = device->lockCachedTexture(bitmap, sampler, &texture, false);
+    }
+    return texture;
+}
+
+SkGpuDevice::SkAutoCachedTexture::~SkAutoCachedTexture() {
+    if (fTex) {
+        fDevice->unlockCachedTexture(fTex);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool gDoTraceDraw;
+
+struct GrSkDrawProcs : public SkDrawProcs {
+public:
+    GrContext* fContext;
+    GrTextContext* fTextContext;
+    GrFontScaler* fFontScaler;  // cached in the skia glyphcache
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuDevice::SkGpuDevice(SkGpuCanvas* canvas, const SkBitmap& bitmap, bool isLayer)
+        : SkDevice(canvas, bitmap, false) {
+
+    fNeedPrepareRenderTarget = false;
+    fDrawProcs = NULL;
+
+    fContext = canvas->context();
+
+    fCache = NULL;
+    fTexture = NULL;
+    fRenderTarget = NULL;
+    fNeedClear = false;
+
+    if (isLayer) {
+        SkBitmap::Config c = bitmap.config();
+        if (c != SkBitmap::kRGB_565_Config) {
+            c = SkBitmap::kARGB_8888_Config;
+        }
+        SkBitmap bm;
+        bm.setConfig(c, this->width(), this->height());
+
+#if CACHE_LAYER_TEXTURES
+
+        fCache = this->lockCachedTexture(bm, GrSamplerState::ClampNoFilter(),
+                       &fTexture, true);
+        if (fCache) {
+            SkASSERT(NULL != fTexture);
+            SkASSERT(fTexture->isRenderTarget());
+        }
+#else
+        const GrGpu::TextureDesc desc = {
+            GrGpu::kRenderTarget_TextureFlag,
+            GrGpu::kNone_AALevel,
+            this->width(),
+            this->height(),
+            SkGr::Bitmap2PixelConfig(bm)
+        };
+
+        fTexture = fContext->createUncachedTexture(desc, NULL, 0);
+#endif
+        if (NULL != fTexture) {
+            fRenderTarget = fTexture->asRenderTarget();
+
+            GrAssert(NULL != fRenderTarget);
+
+            // we defer the actual clear until our gainFocus()
+            fNeedClear = true;
+
+            // wrap the bitmap with a pixelref to expose our texture
+            SkGrTexturePixelRef* pr = new SkGrTexturePixelRef(fTexture);
+            this->setPixelRef(pr, 0)->unref();
+        } else {
+            GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
+                     this->width(), this->height());
+        }
+    }
+
+    if (NULL == fRenderTarget) {
+        GrAssert(NULL == fCache);
+        GrAssert(NULL == fTexture);
+
+        fRenderTarget = fContext->currentRenderTarget();
+        fRenderTarget->ref();
+        fContext->setDefaultRenderTargetSize(this->width(), this->height());
+    }
+}
+
+SkGpuDevice::~SkGpuDevice() {
+    if (fDrawProcs) {
+        delete fDrawProcs;
+    }
+
+    if (fCache) {
+        GrAssert(NULL != fTexture);
+        GrAssert(fRenderTarget == fTexture->asRenderTarget());
+        // IMPORTANT: reattach the rendertarget/tex back to the cache.
+        fContext->reattachAndUnlockCachedTexture((GrTextureEntry*)fCache);
+    } else if (NULL != fTexture) {
+        GrAssert(!CACHE_LAYER_TEXTURES);
+        GrAssert(fRenderTarget == fTexture->asRenderTarget());
+        fTexture->unref();
+    } else if (NULL != fRenderTarget) {
+        fRenderTarget->unref();
+    }
+}
+
+void SkGpuDevice::bindDeviceToTargetHandle(intptr_t handle) {
+    if (fCache) {
+        GrAssert(NULL != fTexture);
+        GrAssert(fRenderTarget == fTexture->asRenderTarget());
+        // IMPORTANT: reattach the rendertarget/tex back to the cache.
+        fContext->reattachAndUnlockCachedTexture((GrTextureEntry*)fCache);
+    } else if (NULL != fTexture) {
+        GrAssert(!CACHE_LAYER_TEXTURES);
+        fTexture->unref();
+    } else if (NULL != fRenderTarget) {
+        fRenderTarget->unref();
+    }
+
+    fCache  = NULL;
+    fTexture = NULL;
+    fRenderTarget = fContext->createPlatformRenderTarget(handle,
+                                                         this->width(),
+                                                         this->height());
+}
+
+intptr_t SkGpuDevice::getLayerTextureHandle() const {
+    if (fTexture) {
+        return fTexture->getTextureHandle();
+    } else {
+        return 0;
+    }
+}
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGpuDevice::makeRenderTargetCurrent() {
+    fContext->setRenderTarget(fRenderTarget);
+    fContext->flush(true);
+    fNeedPrepareRenderTarget = true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkGpuDevice::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
+    SkIRect bounds;
+    bounds.set(0, 0, this->width(), this->height());
+    if (!bounds.intersect(srcRect)) {
+        return false;
+    }
+
+    const int w = bounds.width();
+    const int h = bounds.height();
+    SkBitmap tmp;
+    // note we explicitly specify our rowBytes to be snug (no gap between rows)
+    tmp.setConfig(SkBitmap::kARGB_8888_Config, w, h, w * 4);
+    if (!tmp.allocPixels()) {
+        return false;
+    }
+
+    SkAutoLockPixels alp(tmp);
+    fContext->setRenderTarget(fRenderTarget);
+    // we aren't setting the clip or matrix, so mark as dirty
+    // we don't need to set them for this call and don't have them anyway
+    fNeedPrepareRenderTarget = true;
+
+    if (!fContext->readPixels(bounds.fLeft, bounds.fTop,
+                              bounds.width(), bounds.height(),
+                              GrTexture::kRGBA_8888_PixelConfig,
+                              tmp.getPixels())) {
+        return false;
+    }
+
+    tmp.swap(*bitmap);
+    return true;
+}
+
+void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y) {
+    SkAutoLockPixels alp(bitmap);
+    if (!bitmap.readyToDraw()) {
+        return;
+    }
+    GrTexture::PixelConfig config = SkGr::BitmapConfig2PixelConfig(bitmap.config(),
+                                                                   bitmap.isOpaque());
+    fContext->setRenderTarget(fRenderTarget);
+    // we aren't setting the clip or matrix, so mark as dirty
+    // we don't need to set them for this call and don't have them anyway
+    fNeedPrepareRenderTarget = true;
+
+    fContext->writePixels(x, y, bitmap.width(), bitmap.height(),
+                          config, bitmap.getPixels(), bitmap.rowBytes());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
+                               const SkRegion& clip) {
+    GrMatrix grmat;
+    SkGr::SkMatrix2GrMatrix(matrix, &grmat);
+    context->setViewMatrix(grmat);
+
+    SkGrClipIterator iter;
+    iter.reset(clip);
+    GrClip grc(&iter);
+    if (context->getClip() == grc) {
+    } else {
+        context->setClip(grc);
+    }
+}
+
+// call this ever each draw call, to ensure that the context reflects our state,
+// and not the state from some other canvas/device
+void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
+    if (fNeedPrepareRenderTarget ||
+        fContext->currentRenderTarget() != fRenderTarget) {
+
+        fContext->setRenderTarget(fRenderTarget);
+        convert_matrixclip(fContext, *draw.fMatrix, *draw.fClip);
+        fNeedPrepareRenderTarget = false;
+    }
+}
+
+void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip) {
+    this->INHERITED::setMatrixClip(matrix, clip);
+
+    convert_matrixclip(fContext, matrix, clip);
+}
+
+void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
+                            const SkRegion& clip) {
+    fContext->setRenderTarget(fRenderTarget);
+
+    this->INHERITED::gainFocus(canvas, matrix, clip);
+
+    convert_matrixclip(fContext, matrix, clip);
+
+    if (fNeedClear) {
+        fContext->eraseColor(0x0);
+        fNeedClear = false;
+    }
+}
+
+bool SkGpuDevice::bindDeviceAsTexture(SkPoint* max) {
+    if (NULL != fTexture) {
+        fContext->setTexture(fTexture);
+        if (NULL != max) {
+            max->set(SkFixedToScalar((width() << 16) /
+                                     fTexture->allocWidth()),
+                     SkFixedToScalar((height() << 16) /
+                                     fTexture->allocHeight()));
+        }
+        return true;
+    }
+    return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// must be in the same order as SkXfermode::Coeff in SkXfermode.h
+
+SkGpuDevice::AutoPaintShader::AutoPaintShader() {
+    fSuccess = false;
+    fTexture = NULL;
+}
+
+SkGpuDevice::AutoPaintShader::AutoPaintShader(SkGpuDevice* device,
+                                              const SkPaint& paint,
+                                              const SkMatrix& matrix) {
+    fSuccess = false;
+    fTexture = NULL;
+    this->init(device, paint, matrix);
+}
+
+void SkGpuDevice::AutoPaintShader::init(SkGpuDevice* device,
+                                        const SkPaint& paint,
+                                        const SkMatrix& ctm) {
+    fSuccess = true;
+    GrContext* ctx = device->context();
+    sk_gr_set_paint(ctx, paint); // should we pass true for justAlpha if we have a shader/texture?
+
+    SkShader* shader = paint.getShader();
+    if (NULL == shader) {
+        return;
+    }
+
+    if (!shader->setContext(device->accessBitmap(false), paint, ctm)) {
+        fSuccess = false;
+        return;
+    }
+
+    GrSamplerState::SampleMode sampleMode;
+    SkBitmap bitmap;
+    SkMatrix matrix;
+    SkShader::TileMode tileModes[2];
+    SkScalar twoPointParams[3];
+    SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, &matrix,
+                                                     tileModes, twoPointParams);
+
+    switch (bmptype) {
+    case SkShader::kNone_BitmapType:
+        SkDebugf("shader->asABitmap() == kNone_BitmapType");
+        return;
+    case SkShader::kDefault_BitmapType:
+        sampleMode = GrSamplerState::kNormal_SampleMode;
+        break;
+    case SkShader::kRadial_BitmapType:
+        sampleMode = GrSamplerState::kRadial_SampleMode;
+        break;
+    case SkShader::kSweep_BitmapType:
+        sampleMode = GrSamplerState::kSweep_SampleMode;
+        break;
+    case SkShader::kTwoPointRadial_BitmapType:
+        sampleMode = GrSamplerState::kRadial2_SampleMode;
+        break;
+    default:
+        SkASSERT("Unexpected return from asABitmap");
+        return;
+    }
+
+    bitmap.lockPixels();
+    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
+        return;
+    }
+
+    // see if we've already cached the bitmap from the shader
+    GrSamplerState samplerState(sk_tile_mode_to_grwrap(tileModes[0]),
+                                sk_tile_mode_to_grwrap(tileModes[1]),
+                                sampleMode,
+                                paint.isFilterBitmap());
+
+    if (GrSamplerState::kRadial2_SampleMode == sampleMode) {
+        samplerState.setRadial2Params(twoPointParams[0],
+                                      twoPointParams[1],
+                                      twoPointParams[2] < 0);
+    }
+
+    GrTexture* texture = fCachedTexture.set(device, bitmap, samplerState);
+    if (NULL == texture) {
+        return;
+    }
+
+    // the lock has already called setTexture for us
+    ctx->setSamplerState(samplerState);
+
+    // since our texture coords will be in local space, we wack the texture
+    // matrix to map them back into 0...1 before we load it
+    SkMatrix localM;
+    if (shader->getLocalMatrix(&localM)) {
+        SkMatrix inverse;
+        if (localM.invert(&inverse)) {
+            matrix.preConcat(inverse);
+        }
+    }
+    if (SkShader::kDefault_BitmapType == bmptype) {
+        GrScalar sx = (GR_Scalar1 * texture->contentWidth()) /
+                      (bitmap.width() * texture->allocWidth());
+        GrScalar sy = (GR_Scalar1 * texture->contentHeight()) /
+                      (bitmap.height() * texture->allocHeight());
+        matrix.postScale(sx, sy);
+
+    } else if (SkShader::kRadial_BitmapType == bmptype) {
+        GrScalar s = (GR_Scalar1 * texture->contentWidth()) /
+                     (bitmap.width() * texture->allocWidth());
+        matrix.postScale(s, s);
+    }
+    GrMatrix grmat;
+    SkGr::SkMatrix2GrMatrix(matrix, &grmat);
+    ctx->setTextureMatrix(grmat);
+
+    // since we're going to use a shader/texture, we don't want the color,
+    // just its alpha
+    ctx->setAlpha(paint.getAlpha());
+    // report that we have setup the texture
+    fSuccess = true;
+    fTexture = texture;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    AutoPaintShader   shader(this, paint, *draw.fMatrix);
+    if (shader.failed()) {
+        return;
+    }
+    fContext->drawFull(shader.useTex());
+}
+
+// must be in SkCanvas::PointMode order
+static const GrGpu::PrimitiveType gPointMode2PrimtiveType[] = {
+    GrGpu::kPoints_PrimitiveType,
+    GrGpu::kLines_PrimitiveType,
+    GrGpu::kLineStrip_PrimitiveType
+};
+
+void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
+                            size_t count, const SkPoint pts[], const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkScalar width = paint.getStrokeWidth();
+    if (width < 0) {
+        return;
+    }
+
+    // we only handle hairlines here, else we let the SkDraw call our drawPath()
+    if (width > 0) {
+        draw.drawPoints(mode, count, pts, paint, true);
+        return;
+    }
+
+    AutoPaintShader shader(this, paint, *draw.fMatrix);
+    if (shader.failed()) {
+        return;
+    }
+
+    GrVertexLayout layout = shader.useTex() ?
+                            GrDrawTarget::kPositionAsTexCoord_VertexLayoutBit :
+                            0;
+#if SK_SCALAR_IS_GR_SCALAR
+    fContext->setVertexSourceToArray(pts, layout);
+    fContext->drawNonIndexed(gPointMode2PrimtiveType[mode], 0, count);
+#else
+    GrPoint* v;
+    fContext->reserveAndLockGeometry(layout, count, 0, (void**)&v, NULL);
+    for (int i = 0; i < count; ++i) {
+        v[i].set(SkScalarToGrScalar(pts[i].fX), SkScalarToGrScalar(pts[i].fY));
+    }
+    fContext->drawNonIndexed(gPointMode2PrimtiveType[mode], layout, 0, count);
+    fContext->releaseReservedGeometry();
+#endif
+
+}
+
+void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
+                          const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    bool doStroke = paint.getStyle() == SkPaint::kStroke_Style;
+    SkScalar width = paint.getStrokeWidth();
+
+    /*
+        We have special code for hairline strokes, miter-strokes, and fills.
+        Anything else we just call our path code. (i.e. non-miter thick stroke)
+     */
+    if (doStroke && width > 0 && paint.getStrokeJoin() != SkPaint::kMiter_Join) {
+        SkPath path;
+        path.addRect(rect);
+        this->drawPath(draw, path, paint, NULL, true);
+        return;
+    }
+
+    AutoPaintShader shader(this, paint, *draw.fMatrix);
+    if (shader.failed()) {
+        return;
+    }
+
+    fContext->drawRect(Sk2Gr(rect), shader.useTex(), doStroke ? width : -1);
+}
+
+void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& path,
+                           const SkPaint& paint, const SkMatrix* prePathMatrix,
+                           bool pathIsMutable) {
+    CHECK_SHOULD_DRAW(draw);
+
+    AutoPaintShader shader(this, paint, *draw.fMatrix);
+    if (shader.failed()) {
+        return;
+    }
+
+    const SkPath* pathPtr = &path;
+    SkPath  tmpPath;
+
+    if (prePathMatrix) {
+        if (pathIsMutable) {
+            const_cast<SkPath*>(pathPtr)->transform(*prePathMatrix);
+        } else {
+            path.transform(*prePathMatrix, &tmpPath);
+            pathPtr = &tmpPath;
+        }
+    }
+
+    SkPath               fillPath;
+    GrContext::PathFills fill = GrContext::kHairLine_PathFill;
+
+    if (paint.getFillPath(*pathPtr, &fillPath)) {
+        switch (fillPath.getFillType()) {
+            case SkPath::kWinding_FillType:
+                fill = GrContext::kWinding_PathFill;
+                break;
+            case SkPath::kEvenOdd_FillType:
+                fill = GrContext::kEvenOdd_PathFill;
+                break;
+            case SkPath::kInverseWinding_FillType:
+                fill = GrContext::kInverseWinding_PathFill;
+                break;
+            case SkPath::kInverseEvenOdd_FillType:
+                fill = GrContext::kInverseEvenOdd_PathFill;
+                break;
+            default:
+                SkDebugf("Unsupported path fill type");
+                return;
+        }
+    }
+
+    SkGrPathIter iter(fillPath);
+    fContext->drawPath(&iter, fill, shader.useTex());
+}
+
+/*
+ *  This value must not exceed the GPU's texture dimension limit, but it can
+ *  be smaller, if that helps avoid very large single textures hurting the
+ *  cache.
+ */
+#define MAX_TEXTURE_DIM     512
+
+void SkGpuDevice::drawBitmap(const SkDraw& draw,
+                             const SkBitmap& bitmap,
+                             const SkIRect* srcRectPtr,
+                             const SkMatrix& m,
+                             const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkIRect srcRect;
+    if (NULL == srcRectPtr) {
+        srcRect.set(0, 0, bitmap.width(), bitmap.height());
+    } else {
+        srcRect = *srcRectPtr;
+    }
+
+    if (bitmap.getTexture() || (bitmap.width() <= MAX_TEXTURE_DIM &&
+                                bitmap.height() <= MAX_TEXTURE_DIM)) {
+        // take the fast case
+        this->internalDrawBitmap(draw, bitmap, srcRect, m, paint);
+        return;
+    }
+
+    // undo the translate done by SkCanvas
+    int DX = SkMax32(0, srcRect.fLeft);
+    int DY = SkMax32(0, srcRect.fTop);
+    // compute clip bounds in local coordinates
+    SkIRect clipRect;
+    {
+        SkRect r;
+        r.set(draw.fClip->getBounds());
+        SkMatrix matrix, inverse;
+        matrix.setConcat(*draw.fMatrix, m);
+        if (!matrix.invert(&inverse)) {
+            return;
+        }
+        inverse.mapRect(&r);
+        r.roundOut(&clipRect);
+        // apply the canvas' translate to our local clip
+        clipRect.offset(DX, DY);
+    }
+
+    int nx = bitmap.width() / MAX_TEXTURE_DIM;
+    int ny = bitmap.height() / MAX_TEXTURE_DIM;
+    for (int x = 0; x <= nx; x++) {
+        for (int y = 0; y <= ny; y++) {
+            SkIRect tileR;
+            tileR.set(x * MAX_TEXTURE_DIM, y * MAX_TEXTURE_DIM,
+                      (x + 1) * MAX_TEXTURE_DIM, (y + 1) * MAX_TEXTURE_DIM);
+            if (!SkIRect::Intersects(tileR, clipRect)) {
+                continue;
+            }
+
+            SkIRect srcR = tileR;
+            if (!srcR.intersect(srcRect)) {
+                continue;
+            }
+
+            SkBitmap tmpB;
+            if (bitmap.extractSubset(&tmpB, tileR)) {
+                // now offset it to make it "local" to our tmp bitmap
+                srcR.offset(-tileR.fLeft, -tileR.fTop);
+
+                SkMatrix tmpM(m);
+                {
+                    int dx = tileR.fLeft - DX + SkMax32(0, srcR.fLeft);
+                    int dy = tileR.fTop -  DY + SkMax32(0, srcR.fTop);
+                    tmpM.preTranslate(SkIntToScalar(dx), SkIntToScalar(dy));
+                }
+                this->internalDrawBitmap(draw, tmpB, srcR, tmpM, paint);
+            }
+        }
+    }
+}
+
+/*
+ *  This is called by drawBitmap(), which has to handle images that may be too
+ *  large to be represented by a single texture.
+ *
+ *  internalDrawBitmap assumes that the specified bitmap will fit in a texture.
+ */
+void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
+                                     const SkBitmap& bitmap,
+                                     const SkIRect& srcRect,
+                                     const SkMatrix& m,
+                                     const SkPaint& paint) {
+    SkASSERT(bitmap.width() <= MAX_TEXTURE_DIM &&
+             bitmap.height() <= MAX_TEXTURE_DIM);
+
+    SkAutoLockPixels alp(bitmap);
+    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
+        return;
+    }
+
+    GrSamplerState sampler(paint.isFilterBitmap()); // defaults to clamp
+    // the lock has already called setTexture for us
+    fContext->setSamplerState(sampler);
+
+    GrTexture* texture;
+    SkAutoCachedTexture act(this, bitmap, sampler, &texture);
+    if (NULL == texture) {
+        return;
+    }
+
+    GrVertexLayout layout = GrDrawTarget::kSeparateTexCoord_VertexLayoutBit;
+
+    GrPoint* vertex;
+    if (!fContext->reserveAndLockGeometry(layout, 4,
+                                          0, (void**)&vertex, NULL)) {
+        return;
+    }
+
+    {
+        GrMatrix grmat;
+        SkGr::SkMatrix2GrMatrix(m, &grmat);
+        vertex[0].setIRectFan(0, 0, srcRect.width(), srcRect.height(),
+                              2*sizeof(GrPoint));
+        grmat.mapPointsWithStride(vertex, 2*sizeof(GrPoint), 4);
+    }
+
+    SkScalar left   = SkFixedToScalar((srcRect.fLeft << 16) /
+                                      texture->allocWidth());
+    SkScalar right  = SkFixedToScalar((srcRect.fRight << 16) /
+                                      texture->allocWidth());
+    SkScalar top    = SkFixedToScalar((srcRect.fTop << 16) /
+                                      texture->allocHeight());
+    SkScalar bottom = SkFixedToScalar((srcRect.fBottom << 16) /
+                                      texture->allocHeight());
+    vertex[1].setRectFan(left, top, right, bottom, 2*sizeof(GrPoint));
+
+    fContext->setTextureMatrix(GrMatrix::I());
+    // now draw the mesh
+    sk_gr_set_paint(fContext, paint, true);
+    fContext->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType, 0, 4);
+    fContext->releaseReservedGeometry();
+}
+
+static void gl_drawSprite(GrContext* ctx,
+                          int x, int y, int w, int h, const SkPoint& max,
+                          const SkPaint& paint) {
+    GrAutoViewMatrix avm(ctx, GrMatrix::I());
+
+    ctx->setSamplerState(GrSamplerState::ClampNoFilter());
+    ctx->setTextureMatrix(GrMatrix::I());
+
+    GrPoint* vertex;
+    GrVertexLayout layout = GrGpu::kSeparateTexCoord_VertexLayoutBit;
+    if (!ctx->reserveAndLockGeometry(layout, 4, 0, (void**)&vertex, NULL)) {
+        return;
+    }
+
+    vertex[1].setRectFan(0, 0, max.fX, max.fY, 2*sizeof(GrPoint));
+
+    vertex[0].setIRectFan(x, y, x + w, y + h, 2*sizeof(GrPoint));
+
+    sk_gr_set_paint(ctx, paint, true);
+    // should look to use glDrawTexi() has we do for text...
+    ctx->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType, 0, 4);
+    ctx->releaseReservedGeometry();
+}
+
+void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+                            int left, int top, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkAutoLockPixels alp(bitmap);
+    if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
+        return;
+    }
+
+    SkPoint max;
+    GrTexture* texture;
+    SkAutoCachedTexture act(this, bitmap, GrSamplerState::ClampNoFilter(),
+                            &texture);
+
+    max.set(SkFixedToScalar((texture->contentWidth() << 16) /
+                             texture->allocWidth()),
+            SkFixedToScalar((texture->contentHeight() << 16) /
+                            texture->allocHeight()));
+    gl_drawSprite(fContext, left, top, bitmap.width(), bitmap.height(), max, paint);
+}
+
+void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
+                            int x, int y, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkPoint max;
+    if (((SkGpuDevice*)dev)->bindDeviceAsTexture(&max)) {
+        const SkBitmap& bm = dev->accessBitmap(false);
+        int w = bm.width();
+        int h = bm.height();
+        gl_drawSprite(fContext, x, y, w, h, max, paint);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// must be in SkCanvas::VertexMode order
+static const GrGpu::PrimitiveType gVertexMode2PrimitiveType[] = {
+    GrGpu::kTriangles_PrimitiveType,
+    GrGpu::kTriangleStrip_PrimitiveType,
+    GrGpu::kTriangleFan_PrimitiveType,
+};
+
+void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
+                              int vertexCount, const SkPoint vertices[],
+                              const SkPoint texs[], const SkColor colors[],
+                              SkXfermode* xmode,
+                              const uint16_t indices[], int indexCount,
+                              const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    sk_gr_set_paint(fContext, paint);
+
+    TexCache* cache = NULL;
+
+    bool useTexture = false;
+
+    AutoPaintShader autoShader;
+
+    if (texs) {
+        autoShader.init(this, paint, *draw.fMatrix);
+
+        if (autoShader.failed()) {
+            return;
+        }
+        useTexture = autoShader.useTex();
+    }
+
+    bool releaseVerts = false;
+    GrVertexLayout layout = 0;
+    if (useTexture) {
+        layout |= GrDrawTarget::kSeparateTexCoord_VertexLayoutBit;
+    }
+    if (NULL != colors) {
+        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+    }
+
+    #if SK_SCALAR_IS_GR_SCALAR
+    if (!layout) {
+        fContext->setVertexSourceToArray(vertices, layout);
+    } else
+    #endif
+    {
+        void* verts;
+        releaseVerts = true;
+        if (!fContext->reserveAndLockGeometry(layout, vertexCount, 0,
+                                              &verts, NULL)) {
+            return;
+        }
+        int texOffset, colorOffset;
+        uint32_t stride = GrDrawTarget::VertexSizeAndOffsets(layout,
+                                                             &texOffset,
+                                                             &colorOffset);
+        for (int i = 0; i < vertexCount; ++i) {
+            GrPoint* p = (GrPoint*)((intptr_t)verts + i * stride);
+            p->set(SkScalarToGrScalar(vertices[i].fX),
+                   SkScalarToGrScalar(vertices[i].fY));
+            if (texOffset > 0) {
+                GrPoint* t = (GrPoint*)((intptr_t)p + texOffset);
+                t->set(SkScalarToGrScalar(texs[i].fX),
+                       SkScalarToGrScalar(texs[i].fY));
+            }
+            if (colorOffset > 0) {
+                uint32_t* color = (uint32_t*) ((intptr_t)p + colorOffset);
+                *color = SkGr::SkColor2GrColor(colors[i]);
+            }
+        }
+    }
+    if (indices) {
+        fContext->setIndexSourceToArray(indices);
+        fContext->drawIndexed(gVertexMode2PrimitiveType[vmode], 0, 0,
+                                 vertexCount, indexCount);
+    } else {
+        fContext->drawNonIndexed(gVertexMode2PrimitiveType[vmode],
+                                 0, vertexCount);
+    }
+    if (cache) {
+        this->unlockCachedTexture(cache);
+    }
+    if (releaseVerts) {
+        fContext->releaseReservedGeometry();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void GlyphCacheAuxProc(void* data) {
+    delete (GrFontScaler*)data;
+}
+
+static GrFontScaler* get_gr_font_scaler(SkGlyphCache* cache) {
+    void* auxData;
+    GrFontScaler* scaler = NULL;
+    if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) {
+        scaler = (GrFontScaler*)auxData;
+    }
+    if (NULL == scaler) {
+        scaler = new SkGrFontScaler(cache);
+        cache->setAuxProc(GlyphCacheAuxProc, scaler);
+    }
+    return scaler;
+}
+
+static void SkGPU_Draw1Glyph(const SkDraw1Glyph& state,
+                             SkFixed fx, SkFixed fy,
+                             const SkGlyph& glyph) {
+    SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
+
+    GrSkDrawProcs* procs = (GrSkDrawProcs*)state.fDraw->fProcs;
+
+    if (NULL == procs->fFontScaler) {
+        procs->fFontScaler = get_gr_font_scaler(state.fCache);
+    }
+    procs->fTextContext->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), fx, 0),
+                                         SkIntToFixed(SkFixedFloor(fx)), fy,
+                                         procs->fFontScaler);
+}
+
+SkDrawProcs* SkGpuDevice::initDrawForText(const SkPaint& paint,
+                                          GrTextContext* context) {
+
+    // deferred allocation
+    if (NULL == fDrawProcs) {
+        fDrawProcs = new GrSkDrawProcs;
+        fDrawProcs->fD1GProc = SkGPU_Draw1Glyph;
+        fDrawProcs->fContext = fContext;
+    }
+
+    // init our (and GL's) state
+    fDrawProcs->fTextContext = context;
+    fDrawProcs->fFontScaler = NULL;
+    return fDrawProcs;
+}
+
+void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
+                          size_t byteLength, SkScalar x, SkScalar y,
+                          const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
+        // this guy will just call our drawPath()
+        draw.drawText((const char*)text, byteLength, x, y, paint);
+    } else {
+        SkAutoExtMatrix aem(draw.fExtMatrix);
+        SkDraw myDraw(draw);
+        sk_gr_set_paint(fContext, paint);
+        GrTextContext context(fContext, aem.extMatrix());
+        myDraw.fProcs = this->initDrawForText(paint, &context);
+        this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
+    }
+}
+
+void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
+                             size_t byteLength, const SkScalar pos[],
+                             SkScalar constY, int scalarsPerPos,
+                             const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
+        // this guy will just call our drawPath()
+        draw.drawPosText((const char*)text, byteLength, pos, constY,
+                         scalarsPerPos, paint);
+    } else {
+        SkAutoExtMatrix aem(draw.fExtMatrix);
+        SkDraw myDraw(draw);
+        sk_gr_set_paint(fContext, paint);
+        GrTextContext context(fContext, aem.extMatrix());
+        myDraw.fProcs = this->initDrawForText(paint, &context);
+        this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
+                                     scalarsPerPos, paint);
+    }
+}
+
+void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
+                                size_t len, const SkPath& path,
+                                const SkMatrix* m, const SkPaint& paint) {
+    CHECK_SHOULD_DRAW(draw);
+
+    SkASSERT(draw.fDevice == this);
+    draw.drawTextOnPath((const char*)text, len, path, m, paint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGpuDevice::TexCache* SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
+                                                  const GrSamplerState& sampler,
+                                                  GrTexture** texture,
+                                                  bool forDeviceRenderTarget) {
+    GrContext* ctx = this->context();
+    uint32_t p0, p1;
+    if (forDeviceRenderTarget) {
+        p0 = p1 = -1;
+    } else {
+        p0 = bitmap.getGenerationID();
+        p1 = bitmap.pixelRefOffset();
+    }
+
+    GrTexture* newTexture = NULL;
+    GrTextureKey key(p0, p1, bitmap.width(), bitmap.height());
+    GrTextureEntry* entry = ctx->findAndLockTexture(&key, sampler);
+
+    if (NULL == entry) {
+
+        if (forDeviceRenderTarget) {
+            const GrGpu::TextureDesc desc = {
+                GrGpu::kRenderTarget_TextureFlag,
+                GrGpu::kNone_AALevel,
+                bitmap.width(),
+                bitmap.height(),
+                SkGr::Bitmap2PixelConfig(bitmap)
+            };
+            entry = ctx->createAndLockTexture(&key, sampler, desc, NULL, 0);
+
+        } else {
+            entry = sk_gr_create_bitmap_texture(ctx, &key, sampler, bitmap);
+        }
+        if (NULL == entry) {
+            GrPrintf("---- failed to create texture for cache [%d %d]\n",
+                     bitmap.width(), bitmap.height());
+        }
+    }
+
+    if (NULL != entry) {
+        newTexture = entry->texture();
+        ctx->setTexture(newTexture);
+        if (texture) {
+            *texture = newTexture;
+        }
+        // IMPORTANT: We can't allow another SkGpuDevice to get this
+        // cache entry until this one is destroyed!
+        if (forDeviceRenderTarget) {
+            ctx->detachCachedTexture(entry);
+        }
+    }
+    return (TexCache*)entry;
+}
+
+void SkGpuDevice::unlockCachedTexture(TexCache* cache) {
+    this->context()->unlockTexture((GrTextureEntry*)cache);
+}
+
+
diff --git a/gpu/src/skia/SkGpuDevice.h b/gpu/src/skia/SkGpuDevice.h
new file mode 100644
index 0000000..e42e997
--- /dev/null
+++ b/gpu/src/skia/SkGpuDevice.h
@@ -0,0 +1,176 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#ifndef SkGpuDevice_DEFINED
+#define SkGpuDevice_DEFINED
+
+#include "SkGr.h"
+#include "SkDevice.h"
+#include "SkRegion.h"
+
+struct SkDrawProcs;
+class SkGpuCanvas;
+struct GrSkDrawProcs;
+class GrTextContext;
+
+/**
+ *  Subclass of SkDevice, which directs all drawing to the GrGpu owned by the
+ *  canvas.
+ */
+class SkGpuDevice : public SkDevice {
+public:
+    SkGpuDevice(SkGpuCanvas*, const SkBitmap& bitmap, bool isLayer);
+    virtual ~SkGpuDevice();
+ 
+    GrContext* context() const { return fContext; }
+
+    /**
+     *  If this device was built for rendering as a layer (i.e. offscreen),
+     *  then this will return the platform-specific handle to that GPU resource.
+     *  For example, in OpenGL, this will return the FBO's texture ID.
+     *  If this device was not built for rendering as a layer, then 0
+     *  is returned.
+     */
+    intptr_t getLayerTextureHandle() const;
+    
+    /**
+     * Attaches the device to a rendering surface. This device will then render
+     * to the surface.
+     * For example, in OpenGL, the device will interpret handle as an FBO ID
+     * and drawing to the device would direct GL to the FBO.
+     */
+    void bindDeviceToTargetHandle(intptr_t handle);
+
+    // call to set the clip to the specified rect
+    void scissor(const SkIRect&);
+
+    /**
+     *  Override from SkGpuDevice, so we can set our FBO to be the render target
+     *  The canvas parameter must be a SkGpuCanvas
+     */
+    virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&);
+
+    virtual SkGpuTexture* accessTexture() { return (SkGpuTexture*)fTexture; }
+
+    // overrides from SkDevice
+
+    virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
+    virtual void writePixels(const SkBitmap& bitmap, int x, int y);
+    
+    virtual void setMatrixClip(const SkMatrix& matrix, const SkRegion& clip);
+
+    virtual void drawPaint(const SkDraw&, const SkPaint& paint);
+    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+                            const SkPoint[], const SkPaint& paint);
+    virtual void drawRect(const SkDraw&, const SkRect& r,
+                          const SkPaint& paint);
+    virtual void drawPath(const SkDraw&, const SkPath& path,
+                          const SkPaint& paint, const SkMatrix* prePathMatrix,
+                          bool pathIsMutable);
+    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+                            const SkIRect* srcRectOrNull,
+                            const SkMatrix& matrix, const SkPaint& paint);
+    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+                            int x, int y, const SkPaint& paint);
+    virtual void drawText(const SkDraw&, const void* text, size_t len,
+                          SkScalar x, SkScalar y, const SkPaint& paint);
+    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+                             const SkScalar pos[], SkScalar constY,
+                             int scalarsPerPos, const SkPaint& paint);
+    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+                                const SkPath& path, const SkMatrix* matrix,
+                                const SkPaint& paint);
+    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+                              const SkPoint verts[], const SkPoint texs[],
+                              const SkColor colors[], SkXfermode* xmode,
+                              const uint16_t indices[], int indexCount,
+                              const SkPaint& paint);
+    virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
+                            const SkPaint&);
+    
+    virtual void flush() { fContext->flush(false); }
+    
+    /** 
+     * Make's this device's rendertarget current in the underlying 3D API.
+     * Also implicitly flushes.
+     */
+    virtual void makeRenderTargetCurrent();
+
+protected:
+    class TexCache;
+    TexCache* lockCachedTexture(const SkBitmap& bitmap,
+                                const GrSamplerState& sampler,
+                                GrTexture** texture,
+                                bool forDeviceRenderTarget = false);
+    void unlockCachedTexture(TexCache*);
+
+    class SkAutoCachedTexture {
+    public:
+        SkAutoCachedTexture();
+        SkAutoCachedTexture(SkGpuDevice* device,
+                            const SkBitmap& bitmap,
+                            const GrSamplerState& sampler,
+                            GrTexture** texture);
+        ~SkAutoCachedTexture();
+
+        GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState&);
+
+    private:
+        SkGpuDevice*    fDevice;
+        TexCache*       fTex;
+    };
+    friend class SkAutoTexCache;
+
+private:
+    GrContext*      fContext;
+    GrSkDrawProcs*  fDrawProcs;
+
+    // state for our offscreen render-target
+    TexCache*       fCache;
+    GrTexture*      fTexture;
+    GrRenderTarget* fRenderTarget;
+    bool            fNeedClear;
+    bool            fNeedPrepareRenderTarget;
+    
+    SkDrawProcs* initDrawForText(const SkPaint&, GrTextContext*);
+    bool bindDeviceAsTexture(SkPoint* max);
+
+    void prepareRenderTarget(const SkDraw&);
+    void internalDrawBitmap(const SkDraw&, const SkBitmap&,
+                            const SkIRect&, const SkMatrix&, const SkPaint&);
+        
+    class AutoPaintShader {
+    public:
+        AutoPaintShader();
+        AutoPaintShader(SkGpuDevice*, const SkPaint& paint, const SkMatrix&);
+
+        void init(SkGpuDevice*, const SkPaint& paint, const SkMatrix&);
+
+        bool failed() const { return !fSuccess; }
+        bool useTex() const { return fTexture != 0; }
+    private:
+        GrTexture*              fTexture;
+        SkAutoCachedTexture     fCachedTexture;
+        bool                    fSuccess;
+    };
+    friend class AutoPaintShader;
+
+    typedef SkDevice INHERITED;
+};
+
+#endif
+
diff --git a/gpu/src/skia/SkGr.cpp b/gpu/src/skia/SkGr.cpp
new file mode 100644
index 0000000..8849db7
--- /dev/null
+++ b/gpu/src/skia/SkGr.cpp
@@ -0,0 +1,206 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "SkGr.h"
+
+/*  Fill out buffer with the compressed format Ganesh expects from a colortable
+ based bitmap. [palette (colortable) + indices].
+ 
+ At the moment Ganesh only supports 8bit version. If Ganesh allowed we others 
+ we could detect that the colortable.count is <= 16, and then repack the
+ indices as nibbles to save RAM, but it would take more time (i.e. a lot
+ slower than memcpy), so skipping that for now.
+ 
+ Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big
+ as the colortable.count says it is.
+ */
+static void build_compressed_data(void* buffer, const SkBitmap& bitmap) {
+    SkASSERT(SkBitmap::kIndex8_Config == bitmap.config());
+  
+    SkAutoLockPixels apl(bitmap);
+    if (!bitmap.readyToDraw()) {
+        SkASSERT(!"bitmap not ready to draw!");
+        return;
+    }
+
+    SkColorTable* ctable = bitmap.getColorTable();
+    char* dst = (char*)buffer;
+    
+    memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
+    ctable->unlockColors(false);
+    
+    // always skip a full 256 number of entries, even if we memcpy'd fewer
+    dst += GrGpu::kColorTableSize;
+
+    if (bitmap.width() == bitmap.rowBytes()) {
+        memcpy(dst, bitmap.getPixels(), bitmap.getSize());
+    } else {
+        // need to trim off the extra bytes per row
+        size_t width = bitmap.width();
+        size_t rowBytes = bitmap.rowBytes();
+        const char* src = (const char*)bitmap.getPixels();
+        for (int y = 0; y < bitmap.height(); y++) {
+            memcpy(dst, src, width);
+            src += rowBytes;
+            dst += width;
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx, 
+                                            GrTextureKey* key,
+                                            const GrSamplerState& sampler,
+                                            const SkBitmap& origBitmap) {
+    SkAutoLockPixels alp(origBitmap);
+    if (!origBitmap.readyToDraw()) {
+        return NULL;
+    }
+
+    SkBitmap tmpBitmap;
+
+    const SkBitmap* bitmap = &origBitmap;
+    
+    GrGpu::TextureDesc desc = {
+        0,
+        GrGpu::kNone_AALevel,
+        bitmap->width(),
+        bitmap->height(),
+        SkGr::Bitmap2PixelConfig(*bitmap)
+    };
+    
+    if (SkBitmap::kIndex8_Config == bitmap->config()) {
+        // build_compressed_data doesn't do npot->pot expansion
+        // and paletted textures can't be sub-updated
+        if (ctx->supportsIndex8PixelConfig(sampler,
+                                           bitmap->width(), bitmap->height())) {
+            size_t imagesize = bitmap->width() * bitmap->height() + 
+                                GrGpu::kColorTableSize;
+            SkAutoMalloc storage(imagesize);
+        
+            build_compressed_data(storage.get(), origBitmap);
+
+            // our compressed data will be trimmed, so pass width() for its
+            // "rowBytes", since they are the same now.
+            return ctx->createAndLockTexture(key, sampler, desc, storage.get(),
+                                             bitmap->width());
+
+        } else {
+            origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
+            // now bitmap points to our temp, which has been promoted to 32bits
+            bitmap = &tmpBitmap;
+        }
+    } 
+
+    desc.fFormat = SkGr::Bitmap2PixelConfig(*bitmap);
+    return ctx->createAndLockTexture(key, sampler, desc, bitmap->getPixels(),
+                                     bitmap->rowBytes());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+  
+void sk_gr_set_paint(GrContext* ctx, const SkPaint& paint, bool justAlpha) {
+    ctx->setDither(paint.isDither());
+    ctx->setAntiAlias(paint.isAntiAlias());
+
+    if (justAlpha) {
+        ctx->setAlpha(paint.getAlpha());
+    } else {
+        ctx->setColor(SkGr::SkColor2GrColor(paint.getColor()));
+    }
+    
+    SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
+    SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
+    
+    SkXfermode* mode = paint.getXfermode();
+    if (mode) {
+        mode->asCoeff(&sm, &dm);
+    }   
+    ctx->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SkGrPathIter::Command SkGrPathIter::next(GrPoint pts[]) {
+    GrAssert(NULL != pts);
+#if SK_SCALAR_IS_GR_SCALAR
+    return sk_path_verb_to_gr_path_command(fIter.next((SkPoint*)pts));
+#else
+    Command cmd = sk_path_verb_to_gr_path_command(fIter.next(fPoints));
+    int n = NumCommandPoints(cmd);
+    for (int i = 0; i < n; ++i) {
+        pts[i].fX = SkScalarToGrScalar(fPoints[i].fX);
+        pts[i].fY = SkScalarToGrScalar(fPoints[i].fY);
+    }
+    return cmd;
+#endif
+}
+
+SkGrPathIter::Command SkGrPathIter::next() {
+    return sk_path_verb_to_gr_path_command(fIter.next(NULL));
+}
+
+void SkGrPathIter::rewind() {
+    fIter.setPath(fPath, false);
+}
+
+GrPathIter::ConvexHint SkGrPathIter::hint() const {
+    return fPath.isConvex() ? GrPathIter::kConvex_ConvexHint : 
+                              GrPathIter::kNone_ConvexHint;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void SkGrClipIterator::computeBounds(GrIRect* bounds) {
+    const SkRegion* rgn = fIter.rgn();
+    if (rgn) {
+        SkGr::SetIRect(bounds, rgn->getBounds());
+    } else {
+        bounds->setEmpty();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrTexture::PixelConfig SkGr::BitmapConfig2PixelConfig(SkBitmap::Config config,
+                                                    bool isOpaque) {
+    switch (config) {
+        case SkBitmap::kA8_Config:
+            return GrTexture::kAlpha_8_PixelConfig;
+        case SkBitmap::kIndex8_Config:
+            return GrTexture::kIndex_8_PixelConfig;
+        case SkBitmap::kRGB_565_Config:
+            return GrTexture::kRGB_565_PixelConfig;
+        case SkBitmap::kARGB_4444_Config:
+            return GrTexture::kRGBA_4444_PixelConfig;
+        case SkBitmap::kARGB_8888_Config:
+            if (isOpaque) {
+                return GrTexture::kRGBX_8888_PixelConfig;
+            } else {
+                return GrTexture::kRGBA_8888_PixelConfig;
+            }
+        default:
+            return GrTexture::kUnknown_PixelConfig;
+    }
+}
+
+void SkGr::AbandonAllTextures(GrContext* ctx) {
+    ctx->abandonAllTextures();
+}
+
+
diff --git a/gpu/src/skia/SkGrFontScaler.cpp b/gpu/src/skia/SkGrFontScaler.cpp
new file mode 100644
index 0000000..5c88717
--- /dev/null
+++ b/gpu/src/skia/SkGrFontScaler.cpp
@@ -0,0 +1,142 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "SkGr.h"
+#include "SkDescriptor.h"
+#include "SkGlyphCache.h"
+
+class SkGrDescKey : public GrKey {
+public:
+    explicit SkGrDescKey(const SkDescriptor& desc);
+    virtual ~SkGrDescKey();
+    
+protected:
+    // overrides
+    virtual bool lt(const GrKey& rh) const;
+    virtual bool eq(const GrKey& rh) const;
+    
+private:
+    SkDescriptor* fDesc;
+    enum {
+        kMaxStorageInts = 16
+    };
+    uint32_t fStorage[kMaxStorageInts];
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
+    size_t size = desc.getLength();
+    if (size <= sizeof(fStorage)) {
+        fDesc = (SkDescriptor*)fStorage;
+    } else {
+        fDesc = SkDescriptor::Alloc(size);
+    }
+    memcpy(fDesc, &desc, size);
+}
+
+SkGrDescKey::~SkGrDescKey() {
+    if (fDesc != (SkDescriptor*)fStorage) {
+        SkDescriptor::Free(fDesc);
+    }
+}
+
+bool SkGrDescKey::lt(const GrKey& rh) const {
+    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
+    size_t lenLH = fDesc->getLength();
+    size_t lenRH = srcDesc->getLength();
+    int cmp = memcmp(fDesc, srcDesc, SkMin32(lenLH, lenRH));
+    if (0 == cmp) {
+        return lenLH < lenRH;
+    } else {
+        return cmp < 0;
+    }
+}
+
+bool SkGrDescKey::eq(const GrKey& rh) const {
+    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
+    return fDesc->equals(*srcDesc);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
+    fStrike = strike;
+    fKey = NULL;
+}
+
+SkGrFontScaler::~SkGrFontScaler() {
+    GrSafeUnref(fKey);
+}
+
+const GrKey* SkGrFontScaler::getKey() {
+    if (NULL == fKey) {
+        fKey = new SkGrDescKey(fStrike->getDescriptor());
+    }
+    return fKey;
+}
+
+bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
+                                          GrIRect* bounds) {
+    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
+                                              GrGlyph::UnpackFixedX(packed),
+                                              GrGlyph::UnpackFixedY(packed));
+    bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
+    return true;
+    
+}
+
+bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
+                                         int width, int height,
+                                         int dstRB, void* dst) {
+    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
+                                              GrGlyph::UnpackFixedX(packed),
+                                              GrGlyph::UnpackFixedY(packed));
+    GrAssert(glyph.fWidth == width);
+    GrAssert(glyph.fHeight == height);
+    const void* src = fStrike->findImage(glyph);
+    if (NULL == src) {
+        return false;
+    }
+
+    int srcRB = glyph.rowBytes();
+    if (srcRB == dstRB) {
+        memcpy(dst, src, dstRB * height);
+    } else {
+        for (int y = 0; y < height; y++) {
+            memcpy(dst, src, width);
+            src = (const char*)src + srcRB;
+            dst = (char*)dst + dstRB;
+        }
+    }
+    return true;
+}
+
+bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, GrPath* path) {
+    
+    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
+    const SkPath* skPath = fStrike->findPath(glyph);
+    if (skPath) {
+        SkGrPathIter iter(*skPath);
+        path->resetFromIter(&iter);
+        return true;
+    }
+    return false;
+}
+
+
+
diff --git a/gpu/src/skia/SkGrTexturePixelRef.cpp b/gpu/src/skia/SkGrTexturePixelRef.cpp
new file mode 100644
index 0000000..da9ac1a
--- /dev/null
+++ b/gpu/src/skia/SkGrTexturePixelRef.cpp
@@ -0,0 +1,30 @@
+/*
+    Copyright 2010 Google Inc.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+ */
+
+
+#include "SkGrTexturePixelRef.h"
+#include "GrTexture.h"
+
+SkGrTexturePixelRef::SkGrTexturePixelRef(GrTexture* tex) {
+    fTexture = tex;
+    GrSafeRef(tex);
+}
+
+SkGrTexturePixelRef::~SkGrTexturePixelRef() {
+    GrSafeUnref(fTexture);
+}
+
+
diff --git a/gpu/src/skia/SkUIView.mm b/gpu/src/skia/SkUIView.mm
new file mode 100644
index 0000000..667a474
--- /dev/null
+++ b/gpu/src/skia/SkUIView.mm
@@ -0,0 +1,858 @@
+#import "SkUIView.h"
+#include <QuartzCore/QuartzCore.h>
+
+#include "SkGpuCanvas.h"
+#include "SkCGUtils.h"
+#include "GrContext.h"
+
+#define SKWIND_CONFIG       SkBitmap::kRGB_565_Config
+//#define SKWIND_CONFIG       SkBitmap::kARGB_8888_Config
+#define SKGL_CONFIG         kEAGLColorFormatRGB565
+//#define SKGL_CONFIG         kEAGLColorFormatRGBA8
+
+#define SHOW_FPS
+#define FORCE_REDRAW
+//#define DUMP_FPS_TO_PRINTF
+
+//#define USE_ACCEL_TO_ROTATE
+
+//#define SHOULD_COUNTER_INIT 334
+static int gShouldCounter;
+static bool should_draw() {
+    if (--gShouldCounter == 0) {
+   //     printf("\n");
+    }
+    return true;
+    return gShouldCounter >= 0;
+}
+#ifdef SHOULD_COUNTER_INIT
+    bool (*gShouldDrawProc)() = should_draw;
+#else
+    bool (*gShouldDrawProc)() = NULL;
+#endif
+
+//#define USE_GL_1
+#define USE_GL_2
+
+#if defined(USE_GL_1) || defined(USE_GL_2)
+    #define USE_GL
+#endif
+
+@implementation SkUIView
+
+
+@synthesize fWind;
+@synthesize fTitleLabel;
+@synthesize fBackend;
+@synthesize fComplexClip;
+@synthesize fUseWarp;
+
+#include "SkWindow.h"
+#include "SkEvent.h"
+
+static float gScreenScale = 1;
+
+extern SkOSWindow* create_sk_window(void* hwnd);
+
+#define kREDRAW_UIVIEW_GL "sk_redraw_uiview_gl_iOS"
+
+#define TITLE_HEIGHT  44
+
+static const float SCALE_FOR_ZOOM_LENS = 4.0;
+#define Y_OFFSET_FOR_ZOOM_LENS           200
+#define SIZE_FOR_ZOOM_LENS               250
+
+static const float MAX_ZOOM_SCALE = 4.0;
+static const float MIN_ZOOM_SCALE = 2.0 / MAX_ZOOM_SCALE;
+
+extern bool gDoTraceDraw;
+#define DO_TRACE_DRAW_MAX   100
+
+#ifdef SHOW_FPS
+struct FPSState {
+    static const int FRAME_COUNT = 60;
+
+    CFTimeInterval fNow0, fNow1;
+    CFTimeInterval fTime0, fTime1, fTotalTime;
+    int fFrameCounter;
+    int fDrawCounter;
+
+    FPSState() {
+        fTime0 = fTime1 = fTotalTime = 0;
+        fFrameCounter = 0;
+    }
+
+    void startDraw() {
+        fNow0 = CACurrentMediaTime();
+        
+        if (0 == fDrawCounter && false) {
+            gDoTraceDraw = true;
+            SkDebugf("\n");
+        }
+    }
+    
+    void endDraw() {
+        fNow1 = CACurrentMediaTime();
+
+        if (0 == fDrawCounter) {
+            gDoTraceDraw = true;
+        }
+        if (DO_TRACE_DRAW_MAX == ++fDrawCounter) {
+            fDrawCounter = 0;
+        }
+    }
+        
+    void flush(SkOSWindow* wind) {
+        CFTimeInterval now2 = CACurrentMediaTime();
+
+        fTime0 += fNow1 - fNow0;
+        fTime1 += now2 - fNow1;
+        
+        if (++fFrameCounter == FRAME_COUNT) {
+            CFTimeInterval totalNow = CACurrentMediaTime();
+            fTotalTime = totalNow - fTotalTime;
+            
+            SkMSec ms0 = (int)(1000 * fTime0 / FRAME_COUNT);
+            SkMSec msTotal = (int)(1000 * fTotalTime / FRAME_COUNT);
+            
+            SkString str;
+            str.printf("ms: %d [%d], fps: %3.1f", msTotal, ms0,
+                       FRAME_COUNT / fTotalTime);
+#ifdef DUMP_FPS_TO_PRINTF
+            SkDebugf("%s\n", str.c_str());
+#else
+            wind->setTitle(str.c_str());
+#endif
+
+            fTotalTime = totalNow;
+            fTime0 = fTime1 = 0;
+            fFrameCounter = 0;
+        }
+    }
+};
+
+static FPSState gFPS;
+
+    #define FPS_StartDraw() gFPS.startDraw()
+    #define FPS_EndDraw()   gFPS.endDraw()
+    #define FPS_Flush(wind)     gFPS.flush(wind)
+#else
+    #define FPS_StartDraw()
+    #define FPS_EndDraw()
+    #define FPS_Flush(wind)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_GL
++ (Class) layerClass
+{
+	return [CAEAGLLayer class];
+}
+#endif
+
+- (id)initWithMyDefaults {
+    fBackend = kGL_Backend;
+    fUseWarp = false;
+    fRedrawRequestPending = false;
+    fWind = create_sk_window(self);
+    fWind->setConfig(SKWIND_CONFIG);
+    fMatrix.reset();
+    fLocalMatrix.reset();
+    fNeedGestureEnded = false;
+    fNeedFirstPinch = true;
+    fZoomAround = false;
+    fComplexClip = false;
+
+    [self initGestures];
+
+#ifdef USE_GL
+    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+    eaglLayer.opaque = TRUE;
+    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+                                        [NSNumber numberWithBool:NO],
+                                        kEAGLDrawablePropertyRetainedBacking,
+                                        SKGL_CONFIG,
+                                        kEAGLDrawablePropertyColorFormat,
+                                        nil];
+
+#ifdef USE_GL_1
+    fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+#else
+    fGL.fContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+#endif
+
+    if (!fGL.fContext || ![EAGLContext setCurrentContext:fGL.fContext])
+    {
+        [self release];
+        return nil;
+    }
+    
+    // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
+    glGenFramebuffersOES(1, &fGL.fFramebuffer);
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fGL.fFramebuffer);
+
+    glGenRenderbuffersOES(1, &fGL.fRenderbuffer);
+    glGenRenderbuffersOES(1, &fGL.fStencilbuffer);
+
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
+    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
+#endif
+
+#ifdef USE_ACCEL_TO_ROTATE
+    fRotateMatrix.reset();
+    [UIAccelerometer sharedAccelerometer].delegate = self;
+    [UIAccelerometer sharedAccelerometer].updateInterval = 1 / 30.0;
+#endif
+    return self;
+}
+
+- (id)initWithCoder:(NSCoder*)coder {
+    if ((self = [super initWithCoder:coder])) {
+        self = [self initWithMyDefaults];
+    }
+    return self;
+}
+
+- (id)initWithFrame:(CGRect)frame {
+    if (self = [super initWithFrame:frame]) {
+        self = [self initWithMyDefaults];
+    }
+    return self;
+}
+
+#include "SkImageDecoder.h"
+#include "SkStream_NSData.h"
+
+static void zoom_around(SkCanvas* canvas, float cx, float cy, float zoom) {
+    float clipW = SIZE_FOR_ZOOM_LENS;
+    float clipH = SIZE_FOR_ZOOM_LENS;
+
+    SkRect r;
+    r.set(0, 0, clipW, clipH);
+    r.offset(cx - clipW/2, cy - clipH/2);
+
+    SkPaint paint;
+    paint.setColor(0xFF66AAEE);
+    paint.setStyle(SkPaint::kStroke_Style);
+    paint.setStrokeWidth(10);
+
+    // draw our "frame" around the zoom lens
+    canvas->drawRect(r, paint);
+
+    // now clip and scale the lens
+    canvas->clipRect(r);
+    canvas->translate(cx, cy);
+    canvas->scale(zoom, zoom);
+    canvas->translate(-cx, -cy);
+}
+
+- (void)drawWithCanvas:(SkCanvas*)canvas {
+    if (fComplexClip) {
+        canvas->drawColor(SK_ColorBLUE);
+
+        SkPath path;
+        static const SkRect r[] = {
+            { 50, 50, 250, 250 },
+            { 150, 150, 500, 600 }
+        };
+        for (size_t i = 0; i < GR_ARRAY_COUNT(r); i++) {
+            path.addRect(r[i]);
+        }
+        canvas->clipPath(path);
+    }
+    
+    // This is to consolidate multiple inval requests
+    fRedrawRequestPending = false;
+
+    if (fFlingState.isActive()) {
+        if (!fFlingState.evaluateMatrix(&fLocalMatrix)) {
+            [self flushLocalMatrix];
+        }
+    }
+
+    SkMatrix localMatrix = fLocalMatrix;
+#ifdef USE_ACCEL_TO_ROTATE
+    localMatrix.preConcat(fRotateMatrix);
+#endif
+
+    SkMatrix matrix;
+    matrix.setConcat(localMatrix, fMatrix);
+
+    const SkMatrix* localM = NULL;
+    if (localMatrix.getType() & SkMatrix::kScale_Mask) {
+        localM = &localMatrix;
+    }
+#ifdef USE_ACCEL_TO_ROTATE
+    localM = &localMatrix;
+#endif
+    canvas->setExternalMatrix(localM);
+
+#ifdef SHOULD_COUNTER_INIT
+    gShouldCounter = SHOULD_COUNTER_INIT;
+#endif
+
+    {
+        int saveCount = canvas->save();
+        canvas->concat(matrix);
+//        SkRect r = { 10, 10, 500, 600 }; canvas->clipRect(r);
+        fWind->draw(canvas);
+        canvas->restoreToCount(saveCount);
+    }
+
+    if (fZoomAround) {
+        zoom_around(canvas, fZoomAroundX, fZoomAroundY, SCALE_FOR_ZOOM_LENS);
+        canvas->concat(matrix);
+        fWind->draw(canvas);
+    }
+    
+#ifdef FORCE_REDRAW
+    fWind->inval(NULL);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+- (void)layoutSubviews {
+    int W, H;
+
+    gScreenScale = [UIScreen mainScreen].scale;
+
+#ifdef USE_GL
+    
+    CAEAGLLayer* eaglLayer = (CAEAGLLayer*)self.layer;
+    if ([self respondsToSelector:@selector(setContentScaleFactor:)]) {
+        self.contentScaleFactor = gScreenScale;
+    }
+    // Allocate color buffer backing based on the current layer size
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+    [fGL.fContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer];
+    
+    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &fGL.fWidth);
+    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &fGL.fHeight);
+
+    if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
+    {
+        NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+    }
+
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fStencilbuffer);
+    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_STENCIL_INDEX8_OES, fGL.fWidth, fGL.fHeight);
+
+    W = fGL.fWidth;
+    H = fGL.fHeight;
+#else
+    CGRect rect = [self bounds];
+    W = (int)CGRectGetWidth(rect);
+    H = (int)CGRectGetHeight(rect) - TITLE_HEIGHT;
+#endif
+
+    printf("---- layoutSubviews %d %d\n", W, H);
+    fWind->resize(W, H);
+    fWind->inval(NULL);
+}
+
+#ifdef USE_GL
+
+static GrContext* gCtx;
+static GrContext* get_global_grctx() {
+    // should be pthread-local at least
+    if (NULL == gCtx) {        
+#ifdef USE_GL_1
+        gCtx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
+#else
+        gCtx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+#endif
+    }
+    return gCtx;
+}
+
+#include "SkDevice.h"
+#include "SkShader.h"
+#include "SkGrTexturePixelRef.h"
+#include "GrMesh.h"
+#include "SkRandom.h"
+
+#include "GrAtlas.h"
+#include "GrTextStrike.h"
+
+static void show_fontcache(GrContext* ctx, SkCanvas* canvas) {
+#if 0
+    SkPaint paint;
+    const int SIZE = 64;
+    GrAtlas* plot[64][64];
+
+    paint.setAntiAlias(true);
+    paint.setTextSize(24);
+    paint.setTextAlign(SkPaint::kCenter_Align);
+
+    Gr_bzero(plot, sizeof(plot));
+
+    GrFontCache* cache = ctx->getFontCache();
+    GrTextStrike* strike = cache->getHeadStrike();
+    int count = 0;
+    while (strike) {
+        GrAtlas* atlas = strike->getAtlas();
+        while (atlas) {
+            int x = atlas->getPlotX();
+            int y = atlas->getPlotY();
+
+            SkRandom rand((intptr_t)strike);
+            SkColor c = rand.nextU() | 0x80808080;
+            paint.setColor(c);
+            paint.setAlpha(0x80);
+
+            SkRect r;
+            r.set(x * SIZE, y * SIZE, (x + 1)*SIZE, (y+1)*SIZE);
+            r.inset(1, 1);
+            canvas->drawRect(r, paint);
+            
+            paint.setColor(0xFF660000);
+            SkString label;
+            label.printf("%d", count);
+            canvas->drawText(label.c_str(), label.size(), r.centerX(),
+                             r.fTop + r.height() * 2 / 3, paint);
+            
+            atlas = atlas->nextAtlas();
+        }
+        strike = strike->fNext;
+        count += 1;
+    }
+#endif
+}
+
+void test_patch(SkCanvas* canvas, const SkBitmap& bm, SkScalar scale);
+
+static void draw_mesh(SkCanvas* canvas, const SkBitmap& bm) {
+    GrMesh fMesh;
+
+    SkRect r;
+    r.set(0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()));
+    
+    //        fMesh.init(bounds, fBitmap.width() / 40, fBitmap.height() / 40, texture);
+    fMesh.init(r, bm.width()/16, bm.height()/16, r);
+
+    SkPaint paint;
+    SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+    paint.setShader(s)->unref();
+    fMesh.draw(canvas, paint);
+}
+
+static void scale_about(SkCanvas* canvas, float sx, float sy, float px, float py) {
+    canvas->translate(px, py);
+    canvas->scale(sx, sy);
+    canvas->translate(-px, -py);
+}
+
+static float grInterp(float v0, float v1, float percent) {
+    return v0 + percent * (v1 - v0);
+}
+
+static void draw_device(SkCanvas* canvas, SkDevice* dev, float w, float h, float warp) {
+    canvas->save();
+    float s = grInterp(1, 0.8, warp);
+    scale_about(canvas, s, s, w/2, h/2);
+    test_patch(canvas, dev->accessBitmap(false), warp);
+    canvas->restore();
+}
+
+- (void)drawInGL {
+//    printf("------ drawInGL\n");
+    // This application only creates a single context which is already set current at this point.
+    // This call is redundant, but needed if dealing with multiple contexts.
+    [EAGLContext setCurrentContext:fGL.fContext];
+    
+    // This application only creates a single default framebuffer which is already bound at this point.
+    // This call is redundant, but needed if dealing with multiple framebuffers.
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, fGL.fFramebuffer);
+    
+    GLint scissorEnable;
+    glGetIntegerv(GL_SCISSOR_TEST, &scissorEnable);
+    glDisable(GL_SCISSOR_TEST);
+    glClearColor(0,0,0,0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    if (scissorEnable) {
+        glEnable(GL_SCISSOR_TEST);
+    }
+    
+    GrContext* ctx = get_global_grctx();
+    SkGpuCanvas origCanvas(ctx);
+    origCanvas.setBitmapDevice(fWind->getBitmap());
+    
+    //    gl->reset();
+    SkGpuCanvas glCanvas(ctx);
+    SkCanvas   rasterCanvas;
+
+    SkCanvas* canvas;
+    SkDevice* dev = NULL;
+    
+    switch (fBackend) {
+        case kRaster_Backend:
+            canvas = &rasterCanvas;
+            break;
+        case kGL_Backend:
+            canvas = &glCanvas;
+            break;
+    }
+
+    if (fUseWarp || fWarpState.isActive()) {
+        if (kGL_Backend == fBackend) {
+            dev = origCanvas.createDevice(fWind->getBitmap(), true);
+            canvas->setDevice(dev)->unref();
+        } else {
+            canvas->setBitmapDevice(fWind->getBitmap());
+            dev = canvas->getDevice();
+        }
+    } else {
+        canvas->setBitmapDevice(fWind->getBitmap());
+        dev = NULL;
+    }
+    
+    canvas->translate(0, TITLE_HEIGHT);
+
+    // if we're not "retained", then we have to always redraw everything.
+    // This call forces us to ignore the fDirtyRgn, and draw everywhere.
+    // If we are "retained", we can skip this call (as the raster case does)
+    fWind->forceInvalAll();
+
+    FPS_StartDraw();
+    [self drawWithCanvas:canvas];
+    FPS_EndDraw();
+
+    if (dev) {
+        draw_device(&origCanvas, dev, fWind->width(), fWind->height(),
+                    fWarpState.evaluate());
+    } else {
+        if (kRaster_Backend == fBackend) {
+            origCanvas.drawBitmap(fWind->getBitmap(), 0, 0, NULL);
+        }
+        // else GL - we're already on screen
+    }
+
+    show_fontcache(ctx, canvas);
+    ctx->flush(false);
+        
+    // This application only creates a single color renderbuffer which is already bound at this point.
+    // This call is redundant, but needed if dealing with multiple renderbuffers.
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, fGL.fRenderbuffer);
+    [fGL.fContext presentRenderbuffer:GL_RENDERBUFFER_OES];
+    
+#if GR_COLLECT_STATS
+    static int frame = 0;
+    if (!(frame % 100)) {
+        get_global_grctx()->printStats();
+    }
+    get_global_grctx()->resetStats();
+    ++frame;
+#endif
+    
+    FPS_Flush(fWind);
+
+#if 0
+    gCtx->deleteAllTextures(GrTextureCache::kAbandonTexture_DeleteMode);
+    gCtx->unref();
+    gCtx = NULL;
+#endif
+}
+
+#else   // raster case
+
+- (void)drawRect:(CGRect)rect {
+    CGContextRef cg = UIGraphicsGetCurrentContext();
+    SkCanvas* canvas = NULL;
+
+    FPS_StartDraw();
+    [self drawWithCanvas:canvas];
+
+    FPS_EndDraw();
+    SkCGDrawBitmap(cg, fWind->getBitmap(), 0, TITLE_HEIGHT);
+
+    FPS_Flush(fWind);
+
+}
+#endif
+
+- (void)setWarpState:(bool)useWarp {
+    fWarpState.stop();  // we should reverse from where we are if active...
+
+    const float duration = 0.5;
+    fUseWarp = useWarp;
+    if (useWarp) {
+        fWarpState.start(0, 1, duration);
+    } else {
+        fWarpState.start(1, 0, duration);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+- (void)flushLocalMatrix {
+    fMatrix.postConcat(fLocalMatrix);
+    fLocalMatrix.reset();
+    fFlingState.stop();
+    fNeedGestureEnded = false;
+    fNeedFirstPinch = true;
+}
+
+- (void)localMatrixWithGesture:(UIGestureRecognizer*)gesture {
+    fNeedGestureEnded = true;
+
+    switch (gesture.state) {
+        case UIGestureRecognizerStateCancelled:
+        case UIGestureRecognizerStateEnded:
+            [self flushLocalMatrix];
+            break;
+        case UIGestureRecognizerStateChanged: {
+            SkMatrix matrix;
+            matrix.setConcat(fLocalMatrix, fMatrix);
+        } break;
+        default:
+            break;
+    }
+}
+
+- (void)commonHandleGesture:(UIGestureRecognizer*)sender {
+    if (fFlingState.isActive()) {
+        [self flushLocalMatrix];
+    }
+
+    switch (sender.state) {
+        case UIGestureRecognizerStateBegan:
+            [self flushLocalMatrix];
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)handleDTapGesture:(UIGestureRecognizer*)sender {
+    [self flushLocalMatrix];
+    fMatrix.reset();
+}
+
+static float discretize(float x) {
+    return (int)x;
+}
+
+- (void)handlePanGesture:(UIPanGestureRecognizer*)sender {
+    [self commonHandleGesture:sender];
+
+    CGPoint delta = [sender translationInView:self];
+    delta.x *= gScreenScale;
+    delta.y *= gScreenScale;
+    // avoid flickering where the drawing might toggle in and out of a pixel
+    // center if translated by a fractional value
+    delta.x = discretize(delta.x);
+    delta.y = discretize(delta.y);
+    fLocalMatrix.setTranslate(delta.x, delta.y);
+    [self localMatrixWithGesture:sender];
+
+    if (UIGestureRecognizerStateEnded == sender.state) {
+        CGPoint velocity = [sender velocityInView:self];
+        fFlingState.reset(velocity.x, velocity.y);
+        fNeedGestureEnded = true;
+    }
+}
+
+- (float)limitTotalZoom:(float)scale {
+    // this query works 'cause we know that we're square-scale w/ no skew/rotation
+    const float curr = fMatrix[0];
+
+    if (scale > 1 && curr * scale > MAX_ZOOM_SCALE) {
+        scale = MAX_ZOOM_SCALE / curr;
+    } else if (scale < 1 && curr * scale < MIN_ZOOM_SCALE) {
+        scale = MIN_ZOOM_SCALE / curr;
+    }
+    return scale;
+}
+
+- (void)handleScaleGesture:(UIPinchGestureRecognizer*)sender {
+    [self commonHandleGesture:sender];
+
+    if ([sender numberOfTouches] == 2) {
+        float scale = sender.scale;
+        CGPoint p0 = [sender locationOfTouch:0 inView:self];
+        CGPoint p1 = [sender locationOfTouch:0 inView:self];
+        float cx = (p0.x + p1.x) * 0.5;
+        float cy = (p0.y + p1.y) * 0.5;
+
+        if (fNeedFirstPinch) {
+            fFirstPinchX = cx;
+            fFirstPinchY = cy;
+            fNeedFirstPinch = false;
+        }
+
+        scale = [self limitTotalZoom:scale];
+
+        fLocalMatrix.setTranslate(-fFirstPinchX, -fFirstPinchY);
+        fLocalMatrix.postScale(scale, scale);
+        fLocalMatrix.postTranslate(cx, cy);
+        [self localMatrixWithGesture:sender];
+    } else {
+        [self flushLocalMatrix];
+    }
+}
+
+- (void)handleLongPressGesture:(UILongPressGestureRecognizer*)sender {
+    [self commonHandleGesture:sender];
+
+    if ([sender numberOfTouches] == 0) {
+        fZoomAround = false;
+        return;
+    }
+
+    CGPoint pt = [sender locationOfTouch:0 inView:self];
+    switch (sender.state) {
+        case UIGestureRecognizerStateBegan:
+        case UIGestureRecognizerStateChanged:
+            fZoomAround = true;
+            fZoomAroundX = pt.x;
+            fZoomAroundY = pt.y - Y_OFFSET_FOR_ZOOM_LENS;
+            break;
+        case UIGestureRecognizerStateEnded:
+        case UIGestureRecognizerStateCancelled:
+            fZoomAround = false;
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)addAndReleaseGesture:(UIGestureRecognizer*)gesture {
+    [self addGestureRecognizer:gesture];
+    [gesture release];
+}
+
+- (void)initGestures {
+    UITapGestureRecognizer* tapG = [UITapGestureRecognizer alloc];
+    [tapG initWithTarget:self action:@selector(handleDTapGesture:)];
+    tapG.numberOfTapsRequired = 2;
+    [self addAndReleaseGesture:tapG];
+
+    UIPanGestureRecognizer* panG = [UIPanGestureRecognizer alloc];
+    [panG initWithTarget:self action:@selector(handlePanGesture:)];
+    [self addAndReleaseGesture:panG];
+    
+    UIPinchGestureRecognizer* pinchG = [UIPinchGestureRecognizer alloc];
+    [pinchG initWithTarget:self action:@selector(handleScaleGesture:)];
+    [self addAndReleaseGesture:pinchG];
+
+    UILongPressGestureRecognizer* longG = [UILongPressGestureRecognizer alloc];
+    [longG initWithTarget:self action:@selector(handleLongPressGesture:)];
+    [self addAndReleaseGesture:longG];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static float abs(float x) { return x < 0 ? -x : x; }
+
+static bool normalize(UIAcceleration* acc, float xy[]) {
+    float mag2 = acc.x*acc.x + acc.y*acc.y + acc.z*acc.z;
+    if (mag2 < 0.000001) {
+        return false;
+    }
+    if (abs((float)acc.z) > 0.9 * sqrt(mag2)) {
+        return false;
+    }
+
+    mag2 = acc.x*acc.x + acc.y*acc.y;
+    if (mag2 < 0.000001) {
+        return false;
+    }
+    float scale = 1 / sqrt(mag2);
+    xy[0] = acc.x * scale;
+    xy[1] = acc.y * scale;
+    return true;
+}
+
+static void normalize(float xy[]) {
+    float scale = 1 / sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
+    xy[0] *= scale;
+    xy[1] *= scale;
+}
+
+static float weighted_average(float newv, float oldv) {
+    return newv * 0.25 + oldv * 0.75;
+}
+
+- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acc {
+
+    float norm[2];
+    if (normalize(acc, norm)) {
+        float sinv = -norm[0];
+        float cosv = -norm[1];
+        // smooth
+        norm[0] = weighted_average(sinv, -fRotateMatrix[1]);
+        norm[1] = weighted_average(cosv, fRotateMatrix[0]);
+        normalize(norm);
+        fRotateMatrix.setSinCos(norm[0], norm[1], 400, 400);
+    }
+#if 0
+    NSDate *now = [NSDate date];
+    NSTimeInterval intervalDate = [now timeIntervalSinceDate:now_prev];
+    
+    velX += (acceleration.x * intervalDate);
+    distX += (velX * intervalDate);
+    //do other axis here too
+    
+    // setup for next UIAccelerometer event
+    now_prev = now;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+- (void)setSkTitle:(const char *)title {
+    if (fTitleLabel) {
+        fTitleLabel.text = [NSString stringWithUTF8String:title];
+        [fTitleLabel setNeedsDisplay];
+    }
+}
+
+- (BOOL)onHandleEvent:(const SkEvent&)evt {
+    if (evt.isType(kREDRAW_UIVIEW_GL)) {
+        [self drawInGL];
+        return true;
+    }
+    return false;
+}
+
+- (void)postInvalWithRect:(const SkIRect*)r {
+#ifdef USE_GL
+
+#if 1
+    if (!fRedrawRequestPending) {
+        fRedrawRequestPending = true;
+        /*
+            performSelectorOnMainThread seems to starve updating other views
+            (e.g. our FPS view in the titlebar), so we use the afterDelay
+            version
+         */
+        if (0) {
+            [self performSelectorOnMainThread:@selector(drawInGL) withObject:nil waitUntilDone:NO];
+        } else {
+            [self performSelector:@selector(drawInGL) withObject:nil afterDelay:0];
+        }
+    }
+#else
+    if (!fRedrawRequestPending) {
+        SkEvent* evt = new SkEvent(kREDRAW_UIVIEW_GL);
+        evt->post(fWind->getSinkID());
+        fRedrawRequestPending = true;
+    }
+#endif
+
+#else
+    if (r) {
+        [self setNeedsDisplayInRect:CGRectMake(r->fLeft, r->fTop,
+                                               r->width(), r->height())];
+    } else {
+        [self setNeedsDisplay];
+    }
+#endif
+}
+
+@end
diff --git a/gpu/src/skia/skgr_files.mk b/gpu/src/skia/skgr_files.mk
new file mode 100644
index 0000000..41896c0
--- /dev/null
+++ b/gpu/src/skia/skgr_files.mk
@@ -0,0 +1,7 @@
+SOURCE := \
+    SkGpuCanvas.cpp	\
+    SkGpuDevice.cpp \
+    SkGr.cpp \
+    SkGrTexturePixelRef.cpp \
+    SkGrFontScaler.cpp
+
