Fix line endings in Gr files and set svn eol style to LF


git-svn-id: http://skia.googlecode.com/svn/trunk@832 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index dbc7f6c..d14f374 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -1,792 +1,792 @@
-/*

-    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 "GrTypes.h"

-#include "GrTextureCache.h"

-#include "GrTextStrike.h"

-#include "GrMemory.h"

-#include "GrPathIter.h"

-#include "GrClipIterator.h"

-#include "GrIndexBuffer.h"

-#include "GrInOrderDrawBuffer.h"

-#include "GrBufferAllocPool.h"

-#include "GrPathRenderer.h"

-

-#define DEFER_TEXT_RENDERING 1

-

-#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)

-

-static const size_t MAX_TEXTURE_CACHE_COUNT = 128;

-static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;

-

-static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;

-static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;

-

-// We are currently only batching Text and drawRectToRect, both

-// of which use the quad index buffer.

-static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;

-static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;

-

-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::CreateGLShaderContext() {

-    return GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);

-}

-

-GrContext::~GrContext() {

-    fGpu->unref();

-    delete fTextureCache;

-    delete fFontCache;

-    delete fDrawBuffer;

-    delete fDrawBufferVBAllocPool;

-    delete fDrawBufferVBAllocPool;

-    delete fPathRenderer;

-}

-

-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;

-            }

-        }

-        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) {

-            GrDrawTarget::AutoStateRestore asr(fGpu);

-            fGpu->setRenderTarget(texture->asRenderTarget());

-            fGpu->setTexture(0, clampEntry->texture());

-            fGpu->setStencilPass(GrDrawTarget::kNone_StencilPass);

-            fGpu->setViewMatrix(GrMatrix::I());

-            fGpu->setAlpha(0xff);

-            fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);

-            fGpu->disableState(GrDrawTarget::kDither_StateBit |

-                               GrDrawTarget::kClip_StateBit   |

-                               GrDrawTarget::kAntialias_StateBit);

-            GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,

-                                          GrSamplerState::kClamp_WrapMode,

-                                          sampler.isFilter());

-            fGpu->setSamplerState(0, stretchSampler);

-

-            static const GrVertexLayout layout =

-                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);

-            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);

-

-            if (arg.succeeded()) {

-                GrPoint* verts = (GrPoint*) arg.vertices();

-                verts[0].setIRectFan(0, 0,

-                                     texture->width(),

-                                     texture->height(),

-                                     2*sizeof(GrPoint));

-                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));

-                fGpu->drawNonIndexed(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);

-}

-

-void GrContext::getTextureCacheLimits(int* maxTextures,

-                                      size_t* maxTextureBytes) const {

-    fTextureCache->getLimits(maxTextures, maxTextureBytes);

-}

-

-void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {

-    fTextureCache->setLimits(maxTextures, maxTextureBytes);

-}

-

-int GrContext::getMaxTextureDimension() {

-    return fGpu->maxTextureDimension();

-}

-

-///////////////////////////////////////////////////////////////////////////////

-

-GrRenderTarget* GrContext::createPlatformRenderTarget(

-                                                intptr_t platformRenderTarget,

-                                                int stencilBits,

-                                                int width, int height) {

-    return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits,

-                                            width, height);

-}

-

-bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,

-                                          int width, int height) {

-    if (!fGpu->supports8BitPalette()) {

-        return false;

-    }

-

-

-    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);

-

-    if (!isPow2) {

-        if (!fGpu->npotTextureSupport()) {

-            return false;

-        }

-

-        bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||

-                     sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;

-        if (tiled && !fGpu->npotTextureTileSupport()) {

-            return false;

-        }

-    }

-    return true;

-}

-

-////////////////////////////////////////////////////////////////////////////////

-

-void GrContext::setClip(const GrClip& clip) {

-    fGpu->setClip(clip);

-    fGpu->enableState(GrDrawTarget::kClip_StateBit);

-}

-

-void GrContext::setClip(const GrIRect& rect) {

-    GrClip clip;

-    clip.setRect(rect);

-    fGpu->setClip(clip);

-}

-

-////////////////////////////////////////////////////////////////////////////////

-

-void GrContext::eraseColor(GrColor color) {

-    fGpu->eraseColor(color);

-}

-

-void GrContext::drawPaint(const GrPaint& paint) {

-    // 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->drawRect(paint, r);

-}

-

-/*  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 GrPaint& paint,

-                         const GrRect& rect,

-                         GrScalar width,

-                         const GrMatrix* matrix) {

-

-    bool textured = NULL != paint.getTexture();

-

-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);

-

-    if (width >= 0) {

-        // TODO: consider making static vertex buffers for these cases.

-        // Hairline could be done by just adding closing vertex to

-        // unitSquareVertexBuffer()

-        GrVertexLayout layout = (textured) ?

-                                 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :

-                                 0;

-        static const int worstCaseVertCount = 10;

-        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);

-

-        if (!geo.succeeded()) {

-            return;

-        }

-

-        GrPrimitiveType primType;

-        int vertCount;

-        GrPoint* vertex = geo.positions();

-

-        if (width > 0) {

-            vertCount = 10;

-            primType = kTriangleStrip_PrimitiveType;

-            setStrokeRectStrip(vertex, rect, width);

-        } else {

-            // hairline

-            vertCount = 5;

-            primType = 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);

-        }

-

-        GrDrawTarget::AutoViewMatrixRestore avmr;

-        if (NULL != matrix) {

-            avmr.set(target);

-            target->preConcatViewMatrix(*matrix);

-            target->preConcatSamplerMatrix(0, *matrix);

-        }

-

-        target->drawNonIndexed(primType, 0, vertCount);

-    } else {

-        #if GR_STATIC_RECT_VB

-            GrVertexLayout layout = (textured) ?

-                            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :

-                            0;

-            target->setVertexSourceToBuffer(layout, 

-                                            fGpu->getUnitSquareVertexBuffer());

-            GrDrawTarget::AutoViewMatrixRestore avmr(target);

-            GrMatrix m;

-            m.setAll(rect.width(), 0,             rect.fLeft,

-                     0,            rect.height(), rect.fTop,

-                     0,            0,             GrMatrix::I()[8]);

-

-            if (NULL != matrix) {

-                m.postConcat(*matrix);

-            }

-

-            target->preConcatViewMatrix(m);

-

-            if (textured) {

-                target->preConcatSamplerMatrix(0, m);

-            }

-            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);

-        #else

-            target->drawSimpleRect(rect, matrix, textured ? 1 : 0);

-        #endif

-    }

-}

-

-void GrContext::drawRectToRect(const GrPaint& paint,

-                               const GrRect& dstRect,

-                               const GrRect& srcRect,

-                               const GrMatrix* dstMatrix,

-                               const GrMatrix* srcMatrix) {

-

-    if (NULL == paint.getTexture()) {

-        drawRect(paint, dstRect, -1, dstMatrix);

-        return;

-    }

-    

-    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);

-

-#if GR_STATIC_RECT_VB

-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);

-

-    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);

-    GrDrawTarget::AutoViewMatrixRestore avmr(target);

-

-    GrMatrix m;

-

-    m.setAll(dstRect.width(), 0,                dstRect.fLeft,

-             0,               dstRect.height(), dstRect.fTop,

-             0,               0,                GrMatrix::I()[8]);

-    if (NULL != dstMatrix) {

-        m.postConcat(*dstMatrix);

-    }

-    target->preConcatViewMatrix(m);

-

-    m.setAll(srcRect.width(), 0,                srcRect.fLeft,

-             0,               srcRect.height(), srcRect.fTop,

-             0,               0,                GrMatrix::I()[8]);

-    if (NULL != srcMatrix) {

-        m.postConcat(*srcMatrix);

-    }

-    target->preConcatSamplerMatrix(0, m);

-

-    target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer());

-    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);

-#else

-

-    GrDrawTarget* target;

-#if BATCH_RECT_TO_RECT 

-    target = this->prepareToDraw(paint, kBuffered_DrawCategory);

-#else 

-    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);

-#endif

-

-    const GrRect* srcRects[GrDrawTarget::kNumStages] = {NULL};

-    const GrMatrix* srcMatrices[GrDrawTarget::kNumStages] = {NULL};

-    srcRects[0] = &srcRect;

-    srcMatrices[0] = srcMatrix;

-

-    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);

-#endif

-}

-

-void GrContext::drawVertices(const GrPaint& paint,

-                             GrPrimitiveType primitiveType,

-                             int vertexCount,

-                             const GrPoint positions[],

-                             const GrPoint texCoords[],

-                             const GrColor colors[],

-                             const uint16_t indices[],

-                             int indexCount) {

-    GrVertexLayout layout = 0;

-    int vertexSize = sizeof(GrPoint);

-

-    GrDrawTarget::AutoReleaseGeometry geo;

-

-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);

-

-    if (NULL != paint.getTexture()) {

-        if (NULL == texCoords) {

-            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);

-        } else {

-            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);

-            vertexSize += sizeof(GrPoint);

-        }

-    }

-

-    if (NULL != colors) {

-        layout |= GrDrawTarget::kColor_VertexLayoutBit;

-        vertexSize += sizeof(GrColor);

-    }

-

-    if (sizeof(GrPoint) != vertexSize) {

-        if (!geo.set(target, layout, vertexCount, 0)) {

-            GrPrintf("Failed to get space for vertices!");

-            return;

-        }

-        int texOffsets[GrDrawTarget::kMaxTexCoords];

-        int colorOffset;

-        int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,

-                                                            texOffsets,

-                                                            &colorOffset);

-        void* curVertex = geo.vertices();

-

-        for (int i = 0; i < vertexCount; ++i) {

-            *((GrPoint*)curVertex) = positions[i];

-

-            if (texOffsets[0] > 0) {

-                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];

-            }

-            if (colorOffset > 0) {

-                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];

-            }

-            curVertex = (void*)((intptr_t)curVertex + vsize);

-        }

-    } else {

-        target->setVertexSourceToArray(layout, positions, vertexCount);

-    }

-

-    if (NULL != indices) {

-        target->setIndexSourceToArray(indices, indexCount);

-        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);

-    } else {

-        target->drawNonIndexed(primitiveType, 0, vertexCount);

-    }

-}

-

-

-////////////////////////////////////////////////////////////////////////////////

-

-void GrContext::drawPath(const GrPaint& paint,

-                         GrPathIter* path,

-                         GrPathFill fill,

-                         const GrPoint* translate) {

-

-

-    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);

-

-    GrDrawTarget::StageBitfield enabledStages = 0;

-    if (NULL != paint.getTexture()) {

-        enabledStages |= 1;

-    }

-    fPathRenderer->drawPath(target, enabledStages, path, fill, translate);

-}

-

-////////////////////////////////////////////////////////////////////////////////

-

-void GrContext::flush(bool flushRenderTarget) {

-    flushDrawBuffer();

-    if (flushRenderTarget) {

-        fGpu->forceRenderTargetFlush();

-    }

-}

-

-void GrContext::flushText() {

-    if (kText_DrawCategory == fLastDrawCategory) {

-        flushDrawBuffer();

-    }

-}

-

-void GrContext::flushDrawBuffer() {

-#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING

-    fDrawBuffer->playback(fGpu);

-    fDrawBuffer->reset();

-#endif

-}

-

-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) {

-

-    // TODO: when underlying api has a direct way to do this we should use it

-    // (e.g. glDrawPixels on desktop GL).

-

-    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);

-

-    fGpu->disableState(GrDrawTarget::kClip_StateBit);

-    fGpu->setAlpha(0xFF);

-    fGpu->setBlendFunc(kOne_BlendCoeff,

-                       kZero_BlendCoeff);

-    fGpu->setTexture(0, texture);

-

-    GrSamplerState sampler;

-    sampler.setClampNoFilter();

-    matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height);

-    sampler.setMatrix(matrix);

-    fGpu->setSamplerState(0, sampler);

-

-    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);

-    static const int VCOUNT = 4;

-

-    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);

-    if (!geo.succeeded()) {

-        return;

-    }

-    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);

-    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);

-}

-////////////////////////////////////////////////////////////////////////////////

-

-void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {

-    target->setTexture(0, paint.getTexture());

-    target->setSamplerState(0, paint.fSampler);

-    target->setColor(paint.fColor);

-

-    if (paint.fDither) {

-        target->enableState(GrDrawTarget::kDither_StateBit);

-    } else {

-        target->disableState(GrDrawTarget::kDither_StateBit);

-    }

-    if (paint.fAntiAlias) {

-        target->enableState(GrDrawTarget::kAntialias_StateBit);

-    } else {

-        target->disableState(GrDrawTarget::kAntialias_StateBit);

-    }

-    target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);

-}

-

-GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 

-                                       DrawCategory category) {

-    if (category != fLastDrawCategory) {

-        flushDrawBuffer();

-        fLastDrawCategory = category;

-    }

-    SetPaint(paint, fGpu);

-    GrDrawTarget* target = fGpu;

-    switch (category) {

-    case kText_DrawCategory:

-#if DEFER_TEXT_RENDERING

-        target = fDrawBuffer;

-        fDrawBuffer->initializeDrawStateAndClip(*fGpu);

-#else

-        target = fGpu;

-#endif

-        break;

-    case kUnbuffered_DrawCategory:

-        target = fGpu;

-        break;

-    case kBuffered_DrawCategory:

-        target = fDrawBuffer;

-        fDrawBuffer->initializeDrawStateAndClip(*fGpu);

-        break;

-    }

-    return target;

-}

-

-////////////////////////////////////////////////////////////////////////////////

-

-void GrContext::resetContext() {

-    fGpu->resetContext();

-}

-

-void GrContext::setRenderTarget(GrRenderTarget* target) {

-    flush(false);

-    fGpu->setRenderTarget(target);

-}

-

-GrRenderTarget* GrContext::getRenderTarget() {

-    return fGpu->getRenderTarget();

-}

-

-const GrRenderTarget* GrContext::getRenderTarget() const {

-    return fGpu->getRenderTarget();

-}

-

-const GrMatrix& GrContext::getMatrix() const {

-    return fGpu->getViewMatrix();

-}

-

-void GrContext::setMatrix(const GrMatrix& m) {

-    fGpu->setViewMatrix(m);

-}

-

-void GrContext::concatMatrix(const GrMatrix& m) const {

-    fGpu->preConcatViewMatrix(m);

-}

-

-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::resetStats() {

-    fGpu->resetStats();

-}

-

-const GrGpu::Stats& GrContext::getStats() const {

-    return fGpu->getStats();

-}

-

-void GrContext::printStats() const {

-    fGpu->printStats();

-}

-

-GrContext::GrContext(GrGpu* gpu) {

-    fGpu = gpu;

-    fGpu->ref();

-    fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,

-                                       MAX_TEXTURE_CACHE_BYTES);

-    fFontCache = new GrFontCache(fGpu);

-

-    fLastDrawCategory = kUnbuffered_DrawCategory;

-

-#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT

-    fDrawBufferVBAllocPool = 

-        new GrVertexBufferAllocPool(gpu, false,

-                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,

-                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);

-    fDrawBufferIBAllocPool = 

-        new GrIndexBufferAllocPool(gpu, false,

-                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 

-                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);

-

-    fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,

-                                          fDrawBufferIBAllocPool);

-#else

-    fDrawBuffer = NULL;

-    fDrawBufferVBAllocPool = NULL;

-    fDrawBufferIBAllocPool = NULL;

-#endif

-

-#if BATCH_RECT_TO_RECT

-    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());

-#endif

-    fPathRenderer = new GrDefaultPathRenderer(fGpu->supportsSingleStencilPassWinding());

-}

-

-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->npotTextureTileSupport()) {

-        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);

-

-        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||

-                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);

-

-        if (tiled && !isPow2) {

-            bits |= 1;

-            bits |= sampler.isFilter() ? 2 : 0;

-        }

-    }

-    key->finalize(bits);

-    return 0 != bits;

-}

-

-GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {

-    GrDrawTarget* target;

-#if DEFER_TEXT_RENDERING

-    target = prepareToDraw(paint, kText_DrawCategory);

-#else

-    target = prepareToDraw(paint, kUnbuffered_DrawCategory);

-#endif

-    SetPaint(paint, target);

-    return target;

-}

-

-const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {

-    return fGpu->getQuadIndexBuffer();

-}

+/*
+    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 "GrTypes.h"
+#include "GrTextureCache.h"
+#include "GrTextStrike.h"
+#include "GrMemory.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+#include "GrIndexBuffer.h"
+#include "GrInOrderDrawBuffer.h"
+#include "GrBufferAllocPool.h"
+#include "GrPathRenderer.h"
+
+#define DEFER_TEXT_RENDERING 1
+
+#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB)
+
+static const size_t MAX_TEXTURE_CACHE_COUNT = 128;
+static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
+
+static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18;
+static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4;
+
+// We are currently only batching Text and drawRectToRect, both
+// of which use the quad index buffer.
+static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0;
+static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0;
+
+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::CreateGLShaderContext() {
+    return GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
+}
+
+GrContext::~GrContext() {
+    fGpu->unref();
+    delete fTextureCache;
+    delete fFontCache;
+    delete fDrawBuffer;
+    delete fDrawBufferVBAllocPool;
+    delete fDrawBufferVBAllocPool;
+    delete fPathRenderer;
+}
+
+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;
+            }
+        }
+        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) {
+            GrDrawTarget::AutoStateRestore asr(fGpu);
+            fGpu->setRenderTarget(texture->asRenderTarget());
+            fGpu->setTexture(0, clampEntry->texture());
+            fGpu->setStencilPass(GrDrawTarget::kNone_StencilPass);
+            fGpu->setViewMatrix(GrMatrix::I());
+            fGpu->setAlpha(0xff);
+            fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
+            fGpu->disableState(GrDrawTarget::kDither_StateBit |
+                               GrDrawTarget::kClip_StateBit   |
+                               GrDrawTarget::kAntialias_StateBit);
+            GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
+                                          GrSamplerState::kClamp_WrapMode,
+                                          sampler.isFilter());
+            fGpu->setSamplerState(0, stretchSampler);
+
+            static const GrVertexLayout layout =
+                                GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+            GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
+
+            if (arg.succeeded()) {
+                GrPoint* verts = (GrPoint*) arg.vertices();
+                verts[0].setIRectFan(0, 0,
+                                     texture->width(),
+                                     texture->height(),
+                                     2*sizeof(GrPoint));
+                verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint));
+                fGpu->drawNonIndexed(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);
+}
+
+void GrContext::getTextureCacheLimits(int* maxTextures,
+                                      size_t* maxTextureBytes) const {
+    fTextureCache->getLimits(maxTextures, maxTextureBytes);
+}
+
+void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) {
+    fTextureCache->setLimits(maxTextures, maxTextureBytes);
+}
+
+int GrContext::getMaxTextureDimension() {
+    return fGpu->maxTextureDimension();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrRenderTarget* GrContext::createPlatformRenderTarget(
+                                                intptr_t platformRenderTarget,
+                                                int stencilBits,
+                                                int width, int height) {
+    return fGpu->createPlatformRenderTarget(platformRenderTarget, stencilBits,
+                                            width, height);
+}
+
+bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
+                                          int width, int height) {
+    if (!fGpu->supports8BitPalette()) {
+        return false;
+    }
+
+
+    bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+    if (!isPow2) {
+        if (!fGpu->npotTextureSupport()) {
+            return false;
+        }
+
+        bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
+                     sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
+        if (tiled && !fGpu->npotTextureTileSupport()) {
+            return false;
+        }
+    }
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::setClip(const GrClip& clip) {
+    fGpu->setClip(clip);
+    fGpu->enableState(GrDrawTarget::kClip_StateBit);
+}
+
+void GrContext::setClip(const GrIRect& rect) {
+    GrClip clip;
+    clip.setRect(rect);
+    fGpu->setClip(clip);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::eraseColor(GrColor color) {
+    fGpu->eraseColor(color);
+}
+
+void GrContext::drawPaint(const GrPaint& paint) {
+    // 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->drawRect(paint, r);
+}
+
+/*  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 GrPaint& paint,
+                         const GrRect& rect,
+                         GrScalar width,
+                         const GrMatrix* matrix) {
+
+    bool textured = NULL != paint.getTexture();
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (width >= 0) {
+        // TODO: consider making static vertex buffers for these cases.
+        // Hairline could be done by just adding closing vertex to
+        // unitSquareVertexBuffer()
+        GrVertexLayout layout = (textured) ?
+                                 GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
+                                 0;
+        static const int worstCaseVertCount = 10;
+        GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0);
+
+        if (!geo.succeeded()) {
+            return;
+        }
+
+        GrPrimitiveType primType;
+        int vertCount;
+        GrPoint* vertex = geo.positions();
+
+        if (width > 0) {
+            vertCount = 10;
+            primType = kTriangleStrip_PrimitiveType;
+            setStrokeRectStrip(vertex, rect, width);
+        } else {
+            // hairline
+            vertCount = 5;
+            primType = 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);
+        }
+
+        GrDrawTarget::AutoViewMatrixRestore avmr;
+        if (NULL != matrix) {
+            avmr.set(target);
+            target->preConcatViewMatrix(*matrix);
+            target->preConcatSamplerMatrix(0, *matrix);
+        }
+
+        target->drawNonIndexed(primType, 0, vertCount);
+    } else {
+        #if GR_STATIC_RECT_VB
+            GrVertexLayout layout = (textured) ?
+                            GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
+                            0;
+            target->setVertexSourceToBuffer(layout, 
+                                            fGpu->getUnitSquareVertexBuffer());
+            GrDrawTarget::AutoViewMatrixRestore avmr(target);
+            GrMatrix m;
+            m.setAll(rect.width(), 0,             rect.fLeft,
+                     0,            rect.height(), rect.fTop,
+                     0,            0,             GrMatrix::I()[8]);
+
+            if (NULL != matrix) {
+                m.postConcat(*matrix);
+            }
+
+            target->preConcatViewMatrix(m);
+
+            if (textured) {
+                target->preConcatSamplerMatrix(0, m);
+            }
+            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+        #else
+            target->drawSimpleRect(rect, matrix, textured ? 1 : 0);
+        #endif
+    }
+}
+
+void GrContext::drawRectToRect(const GrPaint& paint,
+                               const GrRect& dstRect,
+                               const GrRect& srcRect,
+                               const GrMatrix* dstMatrix,
+                               const GrMatrix* srcMatrix) {
+
+    if (NULL == paint.getTexture()) {
+        drawRect(paint, dstRect, -1, dstMatrix);
+        return;
+    }
+    
+    GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB);
+
+#if GR_STATIC_RECT_VB
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+    GrDrawTarget::AutoViewMatrixRestore avmr(target);
+
+    GrMatrix m;
+
+    m.setAll(dstRect.width(), 0,                dstRect.fLeft,
+             0,               dstRect.height(), dstRect.fTop,
+             0,               0,                GrMatrix::I()[8]);
+    if (NULL != dstMatrix) {
+        m.postConcat(*dstMatrix);
+    }
+    target->preConcatViewMatrix(m);
+
+    m.setAll(srcRect.width(), 0,                srcRect.fLeft,
+             0,               srcRect.height(), srcRect.fTop,
+             0,               0,                GrMatrix::I()[8]);
+    if (NULL != srcMatrix) {
+        m.postConcat(*srcMatrix);
+    }
+    target->preConcatSamplerMatrix(0, m);
+
+    target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer());
+    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
+#else
+
+    GrDrawTarget* target;
+#if BATCH_RECT_TO_RECT 
+    target = this->prepareToDraw(paint, kBuffered_DrawCategory);
+#else 
+    target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+#endif
+
+    const GrRect* srcRects[GrDrawTarget::kNumStages] = {NULL};
+    const GrMatrix* srcMatrices[GrDrawTarget::kNumStages] = {NULL};
+    srcRects[0] = &srcRect;
+    srcMatrices[0] = srcMatrix;
+
+    target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices);
+#endif
+}
+
+void GrContext::drawVertices(const GrPaint& paint,
+                             GrPrimitiveType primitiveType,
+                             int vertexCount,
+                             const GrPoint positions[],
+                             const GrPoint texCoords[],
+                             const GrColor colors[],
+                             const uint16_t indices[],
+                             int indexCount) {
+    GrVertexLayout layout = 0;
+    int vertexSize = sizeof(GrPoint);
+
+    GrDrawTarget::AutoReleaseGeometry geo;
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    if (NULL != paint.getTexture()) {
+        if (NULL == texCoords) {
+            layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+        } else {
+            layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
+            vertexSize += sizeof(GrPoint);
+        }
+    }
+
+    if (NULL != colors) {
+        layout |= GrDrawTarget::kColor_VertexLayoutBit;
+        vertexSize += sizeof(GrColor);
+    }
+
+    if (sizeof(GrPoint) != vertexSize) {
+        if (!geo.set(target, layout, vertexCount, 0)) {
+            GrPrintf("Failed to get space for vertices!");
+            return;
+        }
+        int texOffsets[GrDrawTarget::kMaxTexCoords];
+        int colorOffset;
+        int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout,
+                                                            texOffsets,
+                                                            &colorOffset);
+        void* curVertex = geo.vertices();
+
+        for (int i = 0; i < vertexCount; ++i) {
+            *((GrPoint*)curVertex) = positions[i];
+
+            if (texOffsets[0] > 0) {
+                *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i];
+            }
+            if (colorOffset > 0) {
+                *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
+            }
+            curVertex = (void*)((intptr_t)curVertex + vsize);
+        }
+    } else {
+        target->setVertexSourceToArray(layout, positions, vertexCount);
+    }
+
+    if (NULL != indices) {
+        target->setIndexSourceToArray(indices, indexCount);
+        target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+    } else {
+        target->drawNonIndexed(primitiveType, 0, vertexCount);
+    }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::drawPath(const GrPaint& paint,
+                         GrPathIter* path,
+                         GrPathFill fill,
+                         const GrPoint* translate) {
+
+
+    GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
+
+    GrDrawTarget::StageBitfield enabledStages = 0;
+    if (NULL != paint.getTexture()) {
+        enabledStages |= 1;
+    }
+    fPathRenderer->drawPath(target, enabledStages, path, fill, translate);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::flush(bool flushRenderTarget) {
+    flushDrawBuffer();
+    if (flushRenderTarget) {
+        fGpu->forceRenderTargetFlush();
+    }
+}
+
+void GrContext::flushText() {
+    if (kText_DrawCategory == fLastDrawCategory) {
+        flushDrawBuffer();
+    }
+}
+
+void GrContext::flushDrawBuffer() {
+#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING
+    fDrawBuffer->playback(fGpu);
+    fDrawBuffer->reset();
+#endif
+}
+
+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) {
+
+    // TODO: when underlying api has a direct way to do this we should use it
+    // (e.g. glDrawPixels on desktop GL).
+
+    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);
+
+    fGpu->disableState(GrDrawTarget::kClip_StateBit);
+    fGpu->setAlpha(0xFF);
+    fGpu->setBlendFunc(kOne_BlendCoeff,
+                       kZero_BlendCoeff);
+    fGpu->setTexture(0, texture);
+
+    GrSamplerState sampler;
+    sampler.setClampNoFilter();
+    matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height);
+    sampler.setMatrix(matrix);
+    fGpu->setSamplerState(0, sampler);
+
+    GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
+    static const int VCOUNT = 4;
+
+    GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0);
+    if (!geo.succeeded()) {
+        return;
+    }
+    ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height);
+    fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) {
+    target->setTexture(0, paint.getTexture());
+    target->setSamplerState(0, paint.fSampler);
+    target->setColor(paint.fColor);
+
+    if (paint.fDither) {
+        target->enableState(GrDrawTarget::kDither_StateBit);
+    } else {
+        target->disableState(GrDrawTarget::kDither_StateBit);
+    }
+    if (paint.fAntiAlias) {
+        target->enableState(GrDrawTarget::kAntialias_StateBit);
+    } else {
+        target->disableState(GrDrawTarget::kAntialias_StateBit);
+    }
+    target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
+}
+
+GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, 
+                                       DrawCategory category) {
+    if (category != fLastDrawCategory) {
+        flushDrawBuffer();
+        fLastDrawCategory = category;
+    }
+    SetPaint(paint, fGpu);
+    GrDrawTarget* target = fGpu;
+    switch (category) {
+    case kText_DrawCategory:
+#if DEFER_TEXT_RENDERING
+        target = fDrawBuffer;
+        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
+#else
+        target = fGpu;
+#endif
+        break;
+    case kUnbuffered_DrawCategory:
+        target = fGpu;
+        break;
+    case kBuffered_DrawCategory:
+        target = fDrawBuffer;
+        fDrawBuffer->initializeDrawStateAndClip(*fGpu);
+        break;
+    }
+    return target;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::resetContext() {
+    fGpu->resetContext();
+}
+
+void GrContext::setRenderTarget(GrRenderTarget* target) {
+    flush(false);
+    fGpu->setRenderTarget(target);
+}
+
+GrRenderTarget* GrContext::getRenderTarget() {
+    return fGpu->getRenderTarget();
+}
+
+const GrRenderTarget* GrContext::getRenderTarget() const {
+    return fGpu->getRenderTarget();
+}
+
+const GrMatrix& GrContext::getMatrix() const {
+    return fGpu->getViewMatrix();
+}
+
+void GrContext::setMatrix(const GrMatrix& m) {
+    fGpu->setViewMatrix(m);
+}
+
+void GrContext::concatMatrix(const GrMatrix& m) const {
+    fGpu->preConcatViewMatrix(m);
+}
+
+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::resetStats() {
+    fGpu->resetStats();
+}
+
+const GrGpu::Stats& GrContext::getStats() const {
+    return fGpu->getStats();
+}
+
+void GrContext::printStats() const {
+    fGpu->printStats();
+}
+
+GrContext::GrContext(GrGpu* gpu) {
+    fGpu = gpu;
+    fGpu->ref();
+    fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT,
+                                       MAX_TEXTURE_CACHE_BYTES);
+    fFontCache = new GrFontCache(fGpu);
+
+    fLastDrawCategory = kUnbuffered_DrawCategory;
+
+#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT
+    fDrawBufferVBAllocPool = 
+        new GrVertexBufferAllocPool(gpu, false,
+                                    DRAW_BUFFER_VBPOOL_BUFFER_SIZE,
+                                    DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS);
+    fDrawBufferIBAllocPool = 
+        new GrIndexBufferAllocPool(gpu, false,
+                                   DRAW_BUFFER_IBPOOL_BUFFER_SIZE, 
+                                   DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS);
+
+    fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool,
+                                          fDrawBufferIBAllocPool);
+#else
+    fDrawBuffer = NULL;
+    fDrawBufferVBAllocPool = NULL;
+    fDrawBufferIBAllocPool = NULL;
+#endif
+
+#if BATCH_RECT_TO_RECT
+    fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer());
+#endif
+    fPathRenderer = new GrDefaultPathRenderer(fGpu->supportsSingleStencilPassWinding());
+}
+
+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->npotTextureTileSupport()) {
+        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
+
+        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
+                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
+
+        if (tiled && !isPow2) {
+            bits |= 1;
+            bits |= sampler.isFilter() ? 2 : 0;
+        }
+    }
+    key->finalize(bits);
+    return 0 != bits;
+}
+
+GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) {
+    GrDrawTarget* target;
+#if DEFER_TEXT_RENDERING
+    target = prepareToDraw(paint, kText_DrawCategory);
+#else
+    target = prepareToDraw(paint, kUnbuffered_DrawCategory);
+#endif
+    SetPaint(paint, target);
+    return target;
+}
+
+const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
+    return fGpu->getQuadIndexBuffer();
+}