aboutsummaryrefslogtreecommitdiffhomepage
path: root/obsolete/SkGLDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'obsolete/SkGLDevice.cpp')
-rw-r--r--obsolete/SkGLDevice.cpp960
1 files changed, 0 insertions, 960 deletions
diff --git a/obsolete/SkGLDevice.cpp b/obsolete/SkGLDevice.cpp
deleted file mode 100644
index d4606d936a..0000000000
--- a/obsolete/SkGLDevice.cpp
+++ /dev/null
@@ -1,960 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#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"
-
-SK_DECLARE_STATIC_MUTEX(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
-));
-}
-