#include "SkGLDevice.h"
#include "SkGL.h"
#include "SkDrawProcs.h"
#include "SkRegion.h"
#include "SkThread.h"

#ifdef SK_GL_DEVICE_FBO
    #define USE_FBO_DEVICE
    #include "SkGLDevice_FBO.h"
#else
    #define USE_SWLAYER_DEVICE
    #include "SkGLDevice_SWLayer.h"
#endif

// maximum number of entries in our texture cache (before purging)
#define kTexCountMax_Default    256
// maximum number of bytes used (by gl) for the texture cache (before purging)
#define kTexSizeMax_Default     (4 * 1024 * 1024)

static void TRACE_DRAW(const char func[], SkGLDevice* device,
                       const SkDraw& draw) {
    //    SkDebugf("--- <%s> %p %p\n", func, canvas, draw.fDevice);
}

struct SkGLDrawProcs : public SkDrawProcs {
public:
    void init(const SkRegion* clip, int height) {
        fCurrQuad = 0;
        fCurrTexture = 0;
        fClip = clip;
        fViewportHeight = height;

        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(2, SK_TextGLType, 0, fTexs);
        glDisableClientState(GL_COLOR_ARRAY);
        glVertexPointer(2, SK_TextGLType, 0, fVerts);
    }

    GLenum texture() const { return fCurrTexture; }

    void flush() {
        if (fCurrQuad && fCurrTexture) {
            this->drawQuads();
        }
        fCurrQuad = 0;
    }

    void addQuad(GLuint texture, int x, int y, const SkGlyph& glyph,
                 SkFixed left, SkFixed right, SkFixed bottom) {
        SkASSERT((size_t)fCurrQuad <= SK_ARRAY_COUNT(fVerts));
        
        if (fCurrTexture != texture || fCurrQuad == SK_ARRAY_COUNT(fVerts)) {
            if (fCurrQuad && fCurrTexture) {
                this->drawQuads();
            }
            fCurrQuad = 0;
            fCurrTexture = texture;
        }
        
        fVerts[fCurrQuad].setIRectFan(x, y,
                                      x + glyph.fWidth, y + glyph.fHeight);
        fTexs[fCurrQuad].setXRectFan(left, 0, right, bottom);
        fCurrQuad += 4;
    }
    
    void drawQuads();

private:
    enum {
        MAX_QUADS = 32
    };
    
    SkGLTextVertex fVerts[MAX_QUADS * 4];
    SkGLTextVertex fTexs[MAX_QUADS * 4];
    
    // these are initialized in setupForText
    GLuint          fCurrTexture;    
    int             fCurrQuad;
    int             fViewportHeight;
    const SkRegion* fClip;
};

///////////////////////////////////////////////////////////////////////////////

SkDevice* SkGLDeviceFactory::newDevice(SkBitmap::Config config, int width,
                                       int height, bool isOpaque,
                                       bool isForLayer) {
    SkBitmap bitmap;

    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    bitmap.setIsOpaque(isOpaque);

#ifdef USE_FBO_DEVICE
    return SkNEW_ARGS(SkGLDevice_FBO, (bitmap, isForLayer));
#elif defined(USE_SWLAYER_DEVICE)
    if (isForLayer) {
        bitmap.allocPixels();
        if (!bitmap.isOpaque()) {
            bitmap.eraseColor(0);
        }
        return SkNEW_ARGS(SkGLDevice_SWLayer, (bitmap));
    } else {
        return SkNEW_ARGS(SkGLDevice, (bitmap, isForLayer));
    }
#else
    return SkNEW_ARGS(SkGLDevice, (bitmap, isForLayer));
#endif
}

SkGLDevice::SkGLDevice(const SkBitmap& bitmap, bool offscreen)
        : SkDevice(bitmap), fClipIter(bitmap.height()) {
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_SCISSOR_TEST);
    glEnableClientState(GL_VERTEX_ARRAY);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    fDrawProcs = NULL;
}

SkGLDevice::~SkGLDevice() {
    if (fDrawProcs) {
        SkDELETE(fDrawProcs);
    }
}

void SkGLDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip) {
    this->INHERITED::setMatrixClip(matrix, clip);
    
    fGLMatrix.set(matrix);
    fMatrix = matrix;
    fClip = clip;
    fDirty = true;
}

SkGLDevice::TexOrientation SkGLDevice::bindDeviceAsTexture() {
    return kNo_TexOrientation;
}

void SkGLDevice::gainFocus(SkCanvas* canvas) {
    this->INHERITED::gainFocus(canvas);

    const int w = this->width();
    const int h = this->height();
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    SkGL::Ortho(0, w, h, 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    fDirty = true;    
}

SkGLClipIter* SkGLDevice::updateMatrixClip() {
    bool useIter = false;

    // first handle the clip
    if (fDirty || !fClip.isRect()) {
        fClipIter.reset(fClip);
        useIter = true;
    } else if (fDirty) {
        // no iter means caller is not respecting complex clips :(
        SkGL::Scissor(fClip.getBounds(), this->height());
    }
    // else we're just a rect, and we've already call scissor

    // now handle the matrix
    if (fDirty) {
        MAKE_GL(glLoadMatrix)(fGLMatrix.fMat);
#if 0
        SkDebugf("--- gldevice update matrix %p %p\n", this, fFBO);
        for (int y = 0; y < 4; y++) {
            SkDebugf(" [ ");
            for (int x = 0; x < 4; x++) {
                SkDebugf("%g ", fGLMatrix.fMat[y*4 + x]);
            }
            SkDebugf("]\n");
        }
#endif
        fDirty = false;
    }

    return useIter ? &fClipIter : NULL;
}

///////////////////////////////////////////////////////////////////////////////

// must be in the same order as SkXfermode::Coeff in SkXfermode.h
SkGLDevice::AutoPaintShader::AutoPaintShader(SkGLDevice* device,
                                             const SkPaint& paint) {
    fDevice = device;
    fTexCache = device->setupGLPaintShader(paint);
}

SkGLDevice::AutoPaintShader::~AutoPaintShader() {
    if (fTexCache) {
        SkGLDevice::UnlockTexCache(fTexCache);
    }
}

SkGLDevice::TexCache* SkGLDevice::setupGLPaintShader(const SkPaint& paint) {
    SkGL::SetPaint(paint);
    
    SkShader* shader = paint.getShader();
    if (NULL == shader) {
        return NULL;
    }
    
    if (!shader->setContext(this->accessBitmap(false), paint, this->matrix())) {
        return NULL;
    }
    
    SkBitmap bitmap;
    SkMatrix matrix;
    SkShader::TileMode tileModes[2];
    if (!shader->asABitmap(&bitmap, &matrix, tileModes)) {
        SkGL_unimpl("shader->asABitmap() == false");
        return NULL;
    }
    
    bitmap.lockPixels();
    if (!bitmap.readyToDraw()) {
        return NULL;
    }
    
    // see if we've already cached the bitmap from the shader
    SkPoint max;
    GLuint name;
    TexCache* cache = SkGLDevice::LockTexCache(bitmap, &name, &max);
    // the lock has already called glBindTexture for us
    SkGL::SetTexParams(paint.isFilterBitmap(), tileModes[0], tileModes[1]);
    
    // 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);
        }
    }
    
    matrix.postScale(max.fX / bitmap.width(), max.fY / bitmap.height());
    glMatrixMode(GL_TEXTURE);
    SkGL::LoadMatrix(matrix);
    glMatrixMode(GL_MODELVIEW);
    
    // since we're going to use a shader/texture, we don't want the color,
    // just its alpha
    SkGL::SetAlpha(paint.getAlpha());
    // report that we have setup the texture
    return cache;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void SkGLDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
    TRACE_DRAW("coreDrawPaint", this, draw);
    
    AutoPaintShader   shader(this, paint);
    SkGLVertex        vertex[4];
    const SkGLVertex* texs = shader.useTex() ? vertex : NULL;
    
    // set vert to be big enough to fill the space, but not super-huge, to we
    // don't overflow fixed-point implementations
    {
        SkRect r;
        r.set(this->clip().getBounds());
        SkMatrix inverse;
        if (draw.fMatrix->invert(&inverse)) {
            inverse.mapRect(&r);
        }
        vertex->setRectFan(r);
    }
    
    SkGL::DrawVertices(4, GL_TRIANGLE_FAN, vertex, texs, NULL, NULL,
                       this->updateMatrixClip());
}

// must be in SkCanvas::PointMode order
static const GLenum gPointMode2GL[] = {
    GL_POINTS,
    GL_LINES,
    GL_LINE_STRIP
};

void SkGLDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
                            size_t count, const SkPoint pts[], const SkPaint& paint) {
    TRACE_DRAW("coreDrawPoints", this, draw);
    
    SkScalar width = paint.getStrokeWidth();
    if (width < 0) {
        return;
    }
    
    /*  We should really only use drawverts for hairlines, since gl and skia
     treat the thickness differently...
     */
    
    AutoPaintShader shader(this, paint);
    
    if (width <= 0) {
        width = SK_Scalar1;
    }
    
    if (SkCanvas::kPoints_PointMode == mode) {
        glPointSize(SkScalarToFloat(width));
    } else {
        glLineWidth(SkScalarToFloat(width));
    }
    
    const SkGLVertex* verts;
    
#if GLSCALAR_IS_SCALAR
    verts = (const SkGLVertex*)pts;
#else
    SkAutoSTMalloc<32, SkGLVertex> storage(count);
    SkGLVertex* v = storage.get();
    
    v->setPoints(pts, count);
    verts = v;
#endif
    
    const SkGLVertex* texs = shader.useTex() ? verts : NULL;
    
    SkGL::DrawVertices(count, gPointMode2GL[mode], verts, texs, NULL, NULL,
                       this->updateMatrixClip());
}

/*  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(SkGLVertex verts[10], const SkRect& rect,
                               SkScalar width) {
    const SkScalar rad = SkScalarHalf(width);

    verts[0].setScalars(rect.fLeft + rad, rect.fTop + rad);
    verts[1].setScalars(rect.fLeft - rad, rect.fTop - rad);
    verts[2].setScalars(rect.fRight - rad, rect.fTop + rad);
    verts[3].setScalars(rect.fRight + rad, rect.fTop - rad);
    verts[4].setScalars(rect.fRight - rad, rect.fBottom - rad);
    verts[5].setScalars(rect.fRight + rad, rect.fBottom + rad);
    verts[6].setScalars(rect.fLeft + rad, rect.fBottom - rad);
    verts[7].setScalars(rect.fLeft - rad, rect.fBottom + rad);
    verts[8] = verts[0];
    verts[9] = verts[1];
}

void SkGLDevice::drawRect(const SkDraw& draw, const SkRect& rect,
                          const SkPaint& paint) {
    TRACE_DRAW("coreDrawRect", this, draw);

    bool doStroke = paint.getStyle() == SkPaint::kStroke_Style;

    if (doStroke) {
        if (paint.getStrokeJoin() != SkPaint::kMiter_Join) {
            SkGL_unimpl("non-miter stroke rect");
            return;
        }
    } else if (paint.getStrokeJoin() != SkPaint::kMiter_Join) {
        SkPath  path;
        path.addRect(rect);
        this->drawPath(draw, path, paint);
        return;
    }
    
    AutoPaintShader shader(this, paint);
    SkScalar width = paint.getStrokeWidth();
    SkGLVertex vertex[10];   // max needed for all cases
    int vertCount;
    GLenum vertMode;

    if (doStroke) {
        if (width > 0) {
            vertCount = 10;
            vertMode = GL_TRIANGLE_STRIP;
            setStrokeRectStrip(vertex, rect, width);
        } else {    // hairline
            vertCount = 5;
            vertMode = GL_LINE_STRIP;
            vertex[0].setScalars(rect.fLeft, rect.fTop);
            vertex[1].setScalars(rect.fRight, rect.fTop);
            vertex[2].setScalars(rect.fRight, rect.fBottom);
            vertex[3].setScalars(rect.fLeft, rect.fBottom);
            vertex[4].setScalars(rect.fLeft, rect.fTop);
            glLineWidth(1);
        }
    } else {
        vertCount = 4;
        vertMode = GL_TRIANGLE_FAN;
        vertex->setRectFan(rect);
    }

    const SkGLVertex* texs = shader.useTex() ? vertex : NULL;
    SkGL::DrawVertices(vertCount, vertMode, vertex, texs, NULL, NULL,
                       this->updateMatrixClip());
}

void SkGLDevice::drawPath(const SkDraw& draw, const SkPath& path,
                          const SkPaint& paint) {
    TRACE_DRAW("coreDrawPath", this, draw);
    if (paint.getStyle() == SkPaint::kStroke_Style) {
        SkGL_unimpl("stroke path");
        return;
    }
    
    AutoPaintShader shader(this, paint);
    
    SkGL::FillPath(path, paint, shader.useTex(), this->updateMatrixClip());
}

void SkGLDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
                            const SkMatrix& m, const SkPaint& paint) {
    TRACE_DRAW("coreDrawBitmap", this, draw);
    
    SkAutoLockPixels alp(bitmap);
    if (!bitmap.readyToDraw()) {
        return;
    }
    
    SkGLClipIter* iter = this->updateMatrixClip();
    
    SkPoint max;
    GLenum name;
    SkAutoLockTexCache(bitmap, &name, &max);
    // the lock has already called glBindTexture for us
    SkGL::SetTexParamsClamp(paint.isFilterBitmap());
    
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    SkGL::MultMatrix(m);
    
    SkGLVertex  pts[4], tex[4];
    
    pts->setIRectFan(0, 0, bitmap.width(), bitmap.height());
    tex->setRectFan(0, 0, max.fX, max.fY);
    
    // now draw the mesh
    SkGL::SetPaintAlpha(paint);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
    SkGL::DrawVertices(4, GL_TRIANGLE_FAN, pts, tex, NULL, NULL, iter);
    
    glPopMatrix();    
}

// move this guy into SkGL, so we can call it from SkGLDevice
static void gl_drawSprite(int x, int y, int w, int h, const SkPoint& max,
                          const SkPaint& paint, SkGLClipIter* iter) {
    SkGL::SetTexParamsClamp(false);
    
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    
    SkGLVertex  pts[4], tex[4];
    
    // if h < 0, then the texture is bottom-to-top, but since our projection
    // matrix always inverts Y, we have to re-invert our texture coord here
    if (h < 0) {
        h = -h;
        tex->setRectFan(0, max.fY, max.fX, 0);
    } else {
        tex->setRectFan(0, 0, max.fX, max.fY);
    }
    pts->setIRectFan(x, y, x + w, y + h);
    
    SkGL::SetPaintAlpha(paint);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
    // should look to use glDrawTexi() has we do for text...
    SkGL::DrawVertices(4, GL_TRIANGLE_FAN, pts, tex, NULL, NULL, iter);
    
    glPopMatrix();
}

void SkGLDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
                            int left, int top, const SkPaint& paint) {
    TRACE_DRAW("coreDrawSprite", this, draw);
    
    SkAutoLockPixels alp(bitmap);
    if (!bitmap.readyToDraw()) {
        return;
    }
    
    SkGLClipIter* iter = this->updateMatrixClip();
    
    SkPoint max;
    GLuint name;
    SkAutoLockTexCache(bitmap, &name, &max);    
    
    gl_drawSprite(left, top, bitmap.width(), bitmap.height(), max, paint, iter);
}

void SkGLDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
                            int x, int y, const SkPaint& paint) {
    TRACE_DRAW("coreDrawDevice", this, draw);
    
    SkGLDevice::TexOrientation to = ((SkGLDevice*)dev)->bindDeviceAsTexture();
    if (SkGLDevice::kNo_TexOrientation != to) {
        SkGLClipIter* iter = this->updateMatrixClip();
        
        const SkBitmap& bm = dev->accessBitmap(false);
        int w = bm.width();
        int h = bm.height();
        SkPoint max;
        
        max.set(SkFixedToScalar(w << (16 - SkNextLog2(bm.rowBytesAsPixels()))),
                SkFixedToScalar(h << (16 - SkNextLog2(h))));
        
        if (SkGLDevice::kBottomToTop_TexOrientation == to) {
            h = -h;
        }
        gl_drawSprite(x, y, w, h, max, paint, iter);
    }
}

///////////////////////////////////////////////////////////////////////////////

static const GLenum gVertexModeToGL[] = {
    GL_TRIANGLES,       // kTriangles_VertexMode,
    GL_TRIANGLE_STRIP,  // kTriangleStrip_VertexMode,
    GL_TRIANGLE_FAN     // kTriangleFan_VertexMode
};

#include "SkShader.h"

void SkGLDevice::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) {

    if (false) {
        SkRect bounds;
        SkIRect ibounds;
        
        bounds.set(vertices, vertexCount);
        bounds.round(&ibounds);
        
        SkDebugf("---- drawverts: %d pts, texs=%d colors=%d indices=%d bounds [%d %d]\n",
                 vertexCount, texs!=0, colors!=0, indexCount, ibounds.width(), ibounds.height());
    }
    
    SkGLClipIter* iter = this->updateMatrixClip();
    
    SkGL::SetPaint(paint);
    
    const SkGLVertex* glVerts;
    const SkGLVertex* glTexs = NULL;
    
#if GLSCALAR_IS_SCALAR
    glVerts = (const SkGLVertex*)vertices;
#else
    SkAutoSTMalloc<32, SkGLVertex> storage(vertexCount);
    storage.get()->setPoints(vertices, vertexCount);
    glVerts = storage.get();
#endif
    
    uint8_t* colorArray = NULL;
    if (colors) {
        colorArray = (uint8_t*)sk_malloc_throw(vertexCount*4);
        SkGL::SetRGBA(colorArray, colors, vertexCount);
    }
    SkAutoFree afca(colorArray);
    
    SkGLVertex* texArray = NULL;
    TexCache* cache = NULL;

    if (texs && paint.getShader()) {
        SkShader* shader = paint.getShader();
        
        //        if (!shader->setContext(this->accessBitmap(), paint, *draw.fMatrix)) {
        if (!shader->setContext(*draw.fBitmap, paint, *draw.fMatrix)) {
            goto DONE;
        }
        
        SkBitmap bitmap;
        SkMatrix matrix;
        SkShader::TileMode tileModes[2];
        if (shader->asABitmap(&bitmap, &matrix, tileModes)) {
            SkPoint max;
            GLuint name;
            cache = SkGLDevice::LockTexCache(bitmap, &name, &max);
            if (NULL == cache) {
                return;
            }

            matrix.postScale(max.fX / bitmap.width(), max.fY / bitmap.height());
            glMatrixMode(GL_TEXTURE);
            SkGL::LoadMatrix(matrix);
            glMatrixMode(GL_MODELVIEW);
            
#if GLSCALAR_IS_SCALAR
            glTexs = (const SkGLVertex*)texs;
#else
            texArray = (SkGLVertex*)sk_malloc_throw(vertexCount * sizeof(SkGLVertex));
            texArray->setPoints(texs, vertexCount);
            glTexs = texArray;
#endif
            
            SkGL::SetPaintAlpha(paint);
            SkGL::SetTexParams(paint.isFilterBitmap(),
                               tileModes[0], tileModes[1]);
        }
    }
DONE:
    SkAutoFree aftex(texArray);
    
    SkGL::DrawVertices(indices ? indexCount : vertexCount,
                       gVertexModeToGL[vmode],
                       glVerts, glTexs, colorArray, indices, iter);
    
    if (cache) {
        SkGLDevice::UnlockTexCache(cache);
    }
}

///////////////////////////////////////////////////////////////////////////////

#include "SkGlyphCache.h"
#include "SkGLTextCache.h"

void SkGLDevice::GlyphCacheAuxProc(void* data) {
    SkDebugf("-------------- delete text texture cache\n");
    SkDELETE((SkGLTextCache*)data);
}

#ifdef SK_SCALAR_IS_FIXED
#define SkDiv16ToScalar(numer, denom)    (SkIntToFixed(numer) / (denom))
#else
#define SkDiv16ToScalar(numer, denom)    SkScalarDiv(numer, denom)
#endif

// stolen from SkDraw.cpp - D1G_NoBounder_RectClip
static void SkGL_Draw1Glyph(const SkDraw1Glyph& state, const SkGlyph& glyph,
                            int x, int y) {
    SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);

    SkGLDrawProcs* procs = (SkGLDrawProcs*)state.fDraw->fProcs;
    
    x += glyph.fLeft;
    y += glyph.fTop;
    
    // check if we're clipped out (nothing to draw)
	SkIRect bounds;
	bounds.set(x, y, x + glyph.fWidth, y + glyph.fHeight);
    if (!SkIRect::Intersects(state.fClip->getBounds(), bounds)) {
        return;
    }
    
    // now dig up our texture cache
    
    SkGlyphCache* gcache = state.fCache;
    void* auxData;
    SkGLTextCache* textCache = NULL;
    
    if (gcache->getAuxProcData(SkGLDevice::GlyphCacheAuxProc, &auxData)) {
        textCache = (SkGLTextCache*)auxData;            
    }
    if (NULL == textCache) {
        // need to create one
        textCache = SkNEW(SkGLTextCache);
        gcache->setAuxProc(SkGLDevice::GlyphCacheAuxProc, textCache);
    }
    
    int offset;
    SkGLTextCache::Strike* strike = textCache->findGlyph(glyph, &offset);
    if (NULL == strike) {
        // make sure the glyph has an image
        uint8_t* aa = (uint8_t*)glyph.fImage;               
        if (NULL == aa) {
            aa = (uint8_t*)gcache->findImage(glyph);
            if (NULL == aa) {
                return; // can't rasterize glyph
            }
        }
        strike = textCache->addGlyphAndBind(glyph, aa, &offset);
        if (NULL == strike) {
            SkGL_unimpl("addGlyphAndBind failed, too big");
            // too big to cache, need to draw as is...
            return;
        }
    }
    
    const int shiftW = strike->widthShift();
    const int shiftH = strike->heightShift();
    
    SkFixed left = offset << (16 - shiftW);
    SkFixed right = (offset + glyph.fWidth) << (16 - shiftW);
    SkFixed bottom = glyph.fHeight << (16 - shiftH);

    procs->addQuad(strike->texture(), x, y, glyph, left, right, bottom);
}

#if 1
// matches the orientation used in SkGL::setRectFan. Too bad we can't rely on
// QUADS in android's GL
static const uint8_t gQuadIndices[] = {
    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
};
#else
static void generateQuadIndices(int n) {
    int index = 0;
    for (int i = 0; i < n; i++) {
        SkDebugf("    %3d, %3d, %3d, %3d, %3d, %3d,\n",
                 index, index + 1, index + 2, index, index + 2, index + 3);
        index += 4;
    }
}
#endif

void SkGLDrawProcs::drawQuads() {
    SkASSERT(SK_ARRAY_COUNT(gQuadIndices) == MAX_QUADS * 6);

    glBindTexture(GL_TEXTURE_2D, fCurrTexture);

#if 0
    static bool gOnce;
    if (!gOnce) {
        generateQuadIndices(MAX_QUADS);
        gOnce = true;
    }
#endif

    // convert from quad vertex count to triangle vertex count
    // 6/4 * n == n + (n >> 1) since n is always a multiple of 4
    SkASSERT((fCurrQuad & 3) == 0);
    int count = fCurrQuad + (fCurrQuad >> 1);

    if (fClip->isComplex()) {
        SkGLClipIter iter(fViewportHeight);
        iter.reset(*fClip);
        while (!iter.done()) {
            iter.scissor();
            glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, gQuadIndices);
            iter.next();
        }
    } else {
        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, gQuadIndices);
    }
}

void SkGLDevice::setupForText(SkDraw* draw, const SkPaint& paint) {
    // we handle complex clips in the SkDraw common code, so we don't check
    // for it here
    this->updateMatrixClip();
    
    SkGL::SetPaint(paint, false);
    
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    // deferred allocation
    if (NULL == fDrawProcs) {
        fDrawProcs = SkNEW(SkGLDrawProcs);
        fDrawProcs->fD1GProc = SkGL_Draw1Glyph;
    }

    // init our (and GL's) state
    fDrawProcs->init(draw->fClip, this->height());
    // assign to the caller's SkDraw
    draw->fProcs = fDrawProcs;

    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glShadeModel(GL_FLAT); 
}

void SkGLDevice::drawText(const SkDraw& draw, const void* text,
                          size_t byteLength, SkScalar x, SkScalar y,
                          const SkPaint& paint) {
    /*  Currently, perspective text is draw via paths, invoked directly by
     SkDraw. This can't work for us, since the bitmap that our draw points
     to has no pixels, so we just abort if we're in perspective.
     
     Better fix would be to...
     - have a callback inside draw to handle path drawing
     - option to have draw call the font cache, which we could patch (?)
     */
    if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
        SkGL_unimpl("drawText in perspective");
        return;
    }
    
    SkDraw myDraw(draw);
    this->setupForText(&myDraw, paint);
    this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint);
    fDrawProcs->flush();
    glPopMatrix();  // GL_MODELVIEW
}

void SkGLDevice::drawPosText(const SkDraw& draw, const void* text,
                             size_t byteLength, const SkScalar pos[],
                             SkScalar constY, int scalarsPerPos,
                             const SkPaint& paint) {
    if (draw.fMatrix->getType() & SkMatrix::kPerspective_Mask) {
        SkGL_unimpl("drawPosText in perspective");
        return;
    }
    
    SkDraw myDraw(draw);
    this->setupForText(&myDraw, paint);
    this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY,
                                 scalarsPerPos, paint);
    fDrawProcs->flush();
    glPopMatrix();  // GL_MODELVIEW
}

void SkGLDevice::drawTextOnPath(const SkDraw& draw, const void* text,
                                size_t byteLength, const SkPath& path,
                                const SkMatrix* m, const SkPaint& paint) {
    SkGL_unimpl("drawTextOnPath");
}

///////////////////////////////////////////////////////////////////////////////

#include "SkTextureCache.h"
#include "SkThread.h"

static SkMutex gTextureCacheMutex;
static SkTextureCache gTextureCache(kTexCountMax_Default, kTexSizeMax_Default);

SkGLDevice::TexCache* SkGLDevice::LockTexCache(const SkBitmap& bitmap,
                                                 GLuint* name, SkPoint* size) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);

    SkTextureCache::Entry* entry = gTextureCache.lock(bitmap);
    if (NULL != entry) {
        if (name) {
            *name = entry->name();
        }
        if (size) {
            *size = entry->texSize();
        }
    }
    return (TexCache*)entry;
}

void SkGLDevice::UnlockTexCache(TexCache* cache) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    gTextureCache.unlock((SkTextureCache::Entry*)cache);
}

// public exposure of texture cache settings

size_t SkGLDevice::GetTextureCacheMaxCount() {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    return gTextureCache.getMaxCount();
}

size_t SkGLDevice::GetTextureCacheMaxSize() {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    return gTextureCache.getMaxSize();
}

void SkGLDevice::SetTextureCacheMaxCount(size_t count) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    gTextureCache.setMaxCount(count);
}

void SkGLDevice::SetTextureCacheMaxSize(size_t size) {
    SkAutoMutexAcquire amc(gTextureCacheMutex);
    gTextureCache.setMaxSize(size);
}

///////////////////////////////////////////////////////////////////////////////

#include "SkGLTextCache.h"

static bool deleteCachesProc(SkGlyphCache* cache, void* texturesAreValid) {
    void* auxData;
    if (cache->getAuxProcData(SkGLDevice::GlyphCacheAuxProc, &auxData)) {
        bool valid = texturesAreValid != NULL;
        SkGLTextCache* textCache = static_cast<SkGLTextCache*>(auxData);
        // call this before delete, in case valid is false
        textCache->deleteAllStrikes(valid);
        // now free the memory for the cache itself
        SkDELETE(textCache);
        // now remove the entry in the glyphcache (does not call the proc)
        cache->removeAuxProc(SkGLDevice::GlyphCacheAuxProc);
    }
    return false;   // keep going
}

void SkGLDevice::DeleteAllTextures() {
    // free the textures in our cache

    gTextureCacheMutex.acquire();
    gTextureCache.deleteAllCaches(true);
    gTextureCacheMutex.release();

    // now free the textures in the font cache

    SkGlyphCache::VisitAllCaches(deleteCachesProc, reinterpret_cast<void*>(true)
);
}

void SkGLDevice::AbandonAllTextures() {
    // abandon the textures in our cache

    gTextureCacheMutex.acquire();
    gTextureCache.deleteAllCaches(false);
    gTextureCacheMutex.release();

    // abandon the textures in the font cache

    SkGlyphCache::VisitAllCaches(deleteCachesProc, reinterpret_cast<void*>(false
));
}

