diff --git a/obsolete/SkGL.cpp b/obsolete/SkGL.cpp deleted file mode 100644 index 63f9733b11..0000000000 --- a/obsolete/SkGL.cpp +++ /dev/null @@ -1,533 +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 "SkGL.h" -#include "SkColorPriv.h" -#include "SkGeometry.h" -#include "SkPaint.h" -#include "SkPath.h" -#include "SkTemplates.h" -#include "SkXfermode.h" - -//#define TRACE_TEXTURE_CREATION - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_GL_HAS_COLOR4UB -static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { - glColor4ub(r, g, b, a); -} - -void SkGL::SetAlpha(U8CPU alpha) { - glColor4ub(alpha, alpha, alpha, alpha); -} -#else -static inline SkFixed byte2fixed(U8CPU value) { - return (value + (value >> 7)) << 8; -} - -static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { - glColor4x(byte2fixed(r), byte2fixed(g), byte2fixed(b), byte2fixed(a)); -} - -void SkGL::SetAlpha(U8CPU alpha) { - SkFixed fa = byte2fixed(alpha); - glColor4x(fa, fa, fa, fa); -} -#endif - -void SkGL::SetColor(SkColor c) { - SkPMColor pm = SkPreMultiplyColor(c); - gl_pmcolor(SkGetPackedR32(pm), - SkGetPackedG32(pm), - SkGetPackedB32(pm), - SkGetPackedA32(pm)); -} - -static const GLenum gXfermodeCoeff2Blend[] = { - GL_ZERO, - GL_ONE, - GL_SRC_COLOR, - GL_ONE_MINUS_SRC_COLOR, - GL_DST_COLOR, - GL_ONE_MINUS_DST_COLOR, - GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, - GL_DST_ALPHA, - GL_ONE_MINUS_DST_ALPHA, -}; - -void SkGL::SetPaint(const SkPaint& paint, bool isPremul, bool justAlpha) { - if (justAlpha) { - SkGL::SetAlpha(paint.getAlpha()); - } else { - SkGL::SetColor(paint.getColor()); - } - - GLenum sm = GL_ONE; - GLenum dm = GL_ONE_MINUS_SRC_ALPHA; - - SkXfermode* mode = paint.getXfermode(); - SkXfermode::Coeff sc, dc; - if (mode && mode->asCoeff(&sc, &dc)) { - sm = gXfermodeCoeff2Blend[sc]; - dm = gXfermodeCoeff2Blend[dc]; - } - - // hack for text, which is not-premul (afaik) - if (!isPremul) { - if (GL_ONE == sm) { - sm = GL_SRC_ALPHA; - } - } - - glEnable(GL_BLEND); - glBlendFunc(sm, dm); - - if (paint.isDither()) { - glEnable(GL_DITHER); - } else { - glDisable(GL_DITHER); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkGL::DumpError(const char caller[]) { - GLenum err = glGetError(); - if (err) { - SkDebugf("---- glGetError(%s) %d\n", caller, err); - } -} - -void SkGL::SetRGBA(uint8_t rgba[], const SkColor src[], int count) { - for (int i = 0; i < count; i++) { - SkPMColor c = SkPreMultiplyColor(*src++); - *rgba++ = SkGetPackedR32(c); - *rgba++ = SkGetPackedG32(c); - *rgba++ = SkGetPackedB32(c); - *rgba++ = SkGetPackedA32(c); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkGL::Scissor(const SkIRect& r, int viewportHeight) { - glScissor(r.fLeft, viewportHeight - r.fBottom, r.width(), r.height()); -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkGL::Ortho(float left, float right, float bottom, float top, - float near, float far) { - - float mat[16]; - - sk_bzero(mat, sizeof(mat)); - - mat[0] = 2 / (right - left); - mat[5] = 2 / (top - bottom); - mat[10] = 2 / (near - far); - mat[15] = 1; - - mat[12] = (right + left) / (left - right); - mat[13] = (top + bottom) / (bottom - top); - mat[14] = (far + near) / (near - far); - - glMultMatrixf(mat); -} - -/////////////////////////////////////////////////////////////////////////////// - -static bool canBeTexture(const SkBitmap& bm, GLenum* format, GLenum* type) { - switch (bm.config()) { - case SkBitmap::kARGB_8888_Config: - *format = GL_RGBA; - *type = GL_UNSIGNED_BYTE; - break; - case SkBitmap::kRGB_565_Config: - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5; - break; - case SkBitmap::kARGB_4444_Config: - *format = GL_RGBA; - *type = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case SkBitmap::kIndex8_Config: -#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D - *format = GL_PALETTE8_RGBA8_OES; - *type = GL_UNSIGNED_BYTE; // unused I think -#else - // we promote index to argb32 - *format = GL_RGBA; - *type = GL_UNSIGNED_BYTE; -#endif - break; - case SkBitmap::kA8_Config: - *format = GL_ALPHA; - *type = GL_UNSIGNED_BYTE; - break; - default: - return false; - } - return true; -} - -#define SK_GL_SIZE_OF_PALETTE (256 * sizeof(SkPMColor)) - -size_t SkGL::ComputeTextureMemorySize(const SkBitmap& bitmap) { - int shift = 0; - size_t adder = 0; - switch (bitmap.config()) { - case SkBitmap::kARGB_8888_Config: - case SkBitmap::kRGB_565_Config: - case SkBitmap::kARGB_4444_Config: - case SkBitmap::kA8_Config: - // we're good as is - break; - case SkBitmap::kIndex8_Config: -#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D - // account for the colortable - adder = SK_GL_SIZE_OF_PALETTE; -#else - // we promote index to argb32 - shift = 2; -#endif - break; - default: - return 0; - } - return (bitmap.getSize() << shift) + adder; -} - -#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D -/* Fill out buffer with the compressed format GL expects from a colortable - based bitmap. [palette (colortable) + indices]. - - At the moment I always take the 8bit version, since that's what my data - is. I could detect that the colortable.count is <= 16, and then repack the - indices as nibbles to save RAM, but it would take more time (i.e. a lot - slower than memcpy), so I'm skipping that for now. - - GL wants a full 256 palette entry, even though my ctable is only as big - as the colortable.count says it is. I presume it is OK to leave any - trailing entries uninitialized, since none of my indices should exceed - ctable->count(). -*/ -static void build_compressed_data(void* buffer, const SkBitmap& bitmap) { - SkASSERT(SkBitmap::kIndex8_Config == bitmap.config()); - - SkColorTable* ctable = bitmap.getColorTable(); - uint8_t* dst = (uint8_t*)buffer; - - memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor)); - ctable->unlockColors(false); - - // always skip a full 256 number of entries, even if we memcpy'd fewer - dst += SK_GL_SIZE_OF_PALETTE; - memcpy(dst, bitmap.getPixels(), bitmap.getSafeSize()); // Just copy what we need. -} -#endif - -/* Return true if the bitmap cannot be supported in its current config as a - texture, and it needs to be promoted to ARGB32. - */ -static bool needToPromoteTo32bit(const SkBitmap& bitmap) { - if (bitmap.config() == SkBitmap::kIndex8_Config) { -#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D - const int w = bitmap.width(); - const int h = bitmap.height(); - if (SkNextPow2(w) == w && SkNextPow2(h) == h) { - // we can handle Indx8 if we're a POW2 - return false; - } -#endif - return true; // must promote to ARGB32 - } - return false; -} - -GLuint SkGL::BindNewTexture(const SkBitmap& origBitmap, SkPoint* max) { - SkBitmap tmpBitmap; - const SkBitmap* bitmap = &origBitmap; - - if (needToPromoteTo32bit(origBitmap)) { - origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config); - // now bitmap points to our temp, which has been promoted to 32bits - bitmap = &tmpBitmap; - } - - GLenum format, type; - if (!canBeTexture(*bitmap, &format, &type)) { - return 0; - } - - SkAutoLockPixels alp(*bitmap); - if (!bitmap->readyToDraw()) { - return 0; - } - - GLuint textureName; - glGenTextures(1, &textureName); - - glBindTexture(GL_TEXTURE_2D, textureName); - - // express rowbytes as a number of pixels for ow - int ow = bitmap->rowBytesAsPixels(); - int oh = bitmap->height(); - int nw = SkNextPow2(ow); - int nh = SkNextPow2(oh); - - glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel()); - - // check if we need to scale to create power-of-2 dimensions -#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D - if (SkBitmap::kIndex8_Config == bitmap->config()) { - size_t imagesize = bitmap->getSize() + SK_GL_SIZE_OF_PALETTE; - SkAutoMalloc storage(imagesize); - - build_compressed_data(storage.get(), *bitmap); - // we only support POW2 here (GLES 1.0 restriction) - SkASSERT(ow == nw); - SkASSERT(oh == nh); - glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0, - imagesize, storage.get()); - } else // fall through to non-compressed logic -#endif - { - if (ow != nw || oh != nh) { - glTexImage2D(GL_TEXTURE_2D, 0, format, nw, nh, 0, - format, type, NULL); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ow, oh, - format, type, bitmap->getPixels()); - } else { - // easy case, the bitmap is already pow2 - glTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0, - format, type, bitmap->getPixels()); - } - } - -#ifdef TRACE_TEXTURE_CREATION - SkDebugf("--- new texture [%d] size=(%d %d) bpp=%d\n", textureName, ow, oh, - bitmap->bytesPerPixel()); -#endif - - if (max) { - max->fX = SkFixedToScalar(bitmap->width() << (16 - SkNextLog2(nw))); - max->fY = SkFixedToScalar(oh << (16 - SkNextLog2(nh))); - } - return textureName; -} - -static const GLenum gTileMode2GLWrap[] = { - GL_CLAMP_TO_EDGE, - GL_REPEAT, -#if GL_VERSION_ES_CM_1_0 - GL_REPEAT // GLES doesn't support MIRROR -#else - GL_MIRRORED_REPEAT -#endif -}; - -void SkGL::SetTexParams(bool doFilter, - SkShader::TileMode tx, SkShader::TileMode ty) { - SkASSERT((unsigned)tx < SK_ARRAY_COUNT(gTileMode2GLWrap)); - SkASSERT((unsigned)ty < SK_ARRAY_COUNT(gTileMode2GLWrap)); - - GLenum filter = doFilter ? GL_LINEAR : GL_NEAREST; - - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gTileMode2GLWrap[tx]); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gTileMode2GLWrap[ty]); -} - -void SkGL::SetTexParamsClamp(bool doFilter) { - GLenum filter = doFilter ? GL_LINEAR : GL_NEAREST; - - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkGL::DrawVertices(int count, GLenum mode, - const SkGLVertex* SK_RESTRICT vertex, - const SkGLVertex* SK_RESTRICT texCoords, - const uint8_t* SK_RESTRICT colorArray, - const uint16_t* SK_RESTRICT indexArray, - SkGLClipIter* iter) { - SkASSERT(NULL != vertex); - - if (NULL != texCoords) { - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, SK_GLType, 0, texCoords); - } else { - glDisable(GL_TEXTURE_2D); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - if (NULL != colorArray) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, 0, colorArray); - glShadeModel(GL_SMOOTH); - } else { - glDisableClientState(GL_COLOR_ARRAY); - glShadeModel(GL_FLAT); - } - - glVertexPointer(2, SK_GLType, 0, vertex); - - if (NULL != indexArray) { - if (iter) { - while (!iter->done()) { - iter->scissor(); - glDrawElements(mode, count, GL_UNSIGNED_SHORT, indexArray); - iter->next(); - } - } else { - glDrawElements(mode, count, GL_UNSIGNED_SHORT, indexArray); - } - } else { - if (iter) { - while (!iter->done()) { - iter->scissor(); - glDrawArrays(mode, 0, count); - iter->next(); - } - } else { - glDrawArrays(mode, 0, count); - } - } -} - -void SkGL::PrepareForFillPath(SkPaint* paint) { - if (paint->getStrokeWidth() <= 0) { - paint->setStrokeWidth(SK_Scalar1); - } -} - -void SkGL::FillPath(const SkPath& path, const SkPaint& paint, bool useTex, - SkGLClipIter* iter) { - SkPaint p(paint); - SkPath fillPath; - - SkGL::PrepareForFillPath(&p); - p.getFillPath(path, &fillPath); - SkGL::DrawPath(fillPath, useTex, iter); -} - -// should return max of all contours, rather than the sum (to save temp RAM) -static int worst_case_edge_count(const SkPath& path) { - int edgeCount = 0; - - SkPath::Iter iter(path, true); - SkPath::Verb verb; - - while ((verb = iter.next(NULL)) != SkPath::kDone_Verb) { - switch (verb) { - case SkPath::kLine_Verb: - edgeCount += 1; - break; - case SkPath::kQuad_Verb: - edgeCount += 8; - break; - case SkPath::kCubic_Verb: - edgeCount += 16; - break; - default: - break; - } - } - return edgeCount; -} - -void SkGL::DrawPath(const SkPath& path, bool useTex, SkGLClipIter* clipIter) { - const SkRect& bounds = path.getBounds(); - if (bounds.isEmpty()) { - return; - } - - int maxPts = worst_case_edge_count(path); - // add 1 for center of fan, and 1 for closing edge - SkAutoSTMalloc<32, SkGLVertex> storage(maxPts + 2); - SkGLVertex* base = storage.get(); - SkGLVertex* vert = base; - SkGLVertex* texs = useTex ? base : NULL; - - SkPath::Iter pathIter(path, true); - SkPoint pts[4]; - - bool needEnd = false; - - for (;;) { - switch (pathIter.next(pts)) { - case SkPath::kMove_Verb: - if (needEnd) { - SkGL::DrawVertices(vert - base, GL_TRIANGLE_FAN, - base, texs, NULL, NULL, clipIter); - clipIter->safeRewind(); - vert = base; - } - needEnd = true; - // center of the FAN - vert->setScalars(bounds.centerX(), bounds.centerY()); - vert++; - // add first edge point - vert->setPoint(pts[0]); - vert++; - break; - case SkPath::kLine_Verb: - vert->setPoint(pts[1]); - vert++; - break; - case SkPath::kQuad_Verb: { - const int n = 8; - const SkScalar dt = SK_Scalar1 / n; - SkScalar t = dt; - for (int i = 1; i < n; i++) { - SkPoint loc; - SkEvalQuadAt(pts, t, &loc, NULL); - t += dt; - vert->setPoint(loc); - vert++; - } - vert->setPoint(pts[2]); - vert++; - break; - } - case SkPath::kCubic_Verb: { - const int n = 16; - const SkScalar dt = SK_Scalar1 / n; - SkScalar t = dt; - for (int i = 1; i < n; i++) { - SkPoint loc; - SkEvalCubicAt(pts, t, &loc, NULL, NULL); - t += dt; - vert->setPoint(loc); - vert++; - } - vert->setPoint(pts[3]); - vert++; - break; - } - case SkPath::kClose_Verb: - break; - case SkPath::kDone_Verb: - goto FINISHED; - } - } -FINISHED: - if (needEnd) { - SkGL::DrawVertices(vert - base, GL_TRIANGLE_FAN, base, texs, - NULL, NULL, clipIter); - } -} - diff --git a/obsolete/SkGL.h b/obsolete/SkGL.h deleted file mode 100644 index d0cbe7bfa5..0000000000 --- a/obsolete/SkGL.h +++ /dev/null @@ -1,314 +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. - */ -#ifndef SkGL_DEFINED -#define SkGL_DEFINED - -#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_SDL) - #include - #include - #include - // use FBOs for devices - #define SK_GL_DEVICE_FBO -#elif defined(ANDROID) - #include - #include - #include -#endif - -#include "SkColor.h" -#include "SkMatrix.h" -#include "SkShader.h" - -class SkPaint; -class SkPath; - -class SkGLClipIter; - -//#define TRACE_TEXTURE_CREATE - -static void SkGL_unimpl(const char str[]) { - SkDebugf("SkGL unimplemented: %s\n", str); -} -/////////////////////////////////////////////////////////////////////////////// - -#if GL_OES_compressed_paletted_texture - #define SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D -#endif - -#if GL_OES_fixed_point && defined(SK_SCALAR_IS_FIXED) - #define SK_GLType GL_FIXED -#else - #define SK_GLType GL_FLOAT -#endif - -#if SK_GLType == GL_FIXED - typedef SkFixed SkGLScalar; - - #define SkIntToGL(n) SkIntToFixed(n) - #define SkScalarToGL(x) SkScalarToFixed(x) - #define SK_GLScalar1 SK_Fixed1 - #define SkGLScalarMul(a, b) SkFixedMul(a, b) - #define MAKE_GL(name) name ## x - - #ifdef SK_SCALAR_IS_FIXED - #define GLSCALAR_IS_SCALAR 1 - #define SkPerspToGL(x) SkFractToFixed(x) - #else - #define GLSCALAR_IS_SCALAR 0 - #define SkPerspToGL(x) SkFractToFloat(x) - #endif -#else - typedef float SkGLScalar; - - #define SkIntToGL(n) (n) - #define SkScalarToGL(x) SkScalarToFloat(x) - #define SK_GLScalar1 (1.f) - #define SkGLScalarMul(a, b) ((a) * (b)) - #define MAKE_GL(name) name ## f - - #ifdef SK_SCALAR_IS_FLOAT - #define GLSCALAR_IS_SCALAR 1 - #define SkPerspToGL(x) (x) - #else - #define GLSCALAR_IS_SCALAR 0 - #define SkPerspToGL(x) SkFractToFloat(x) - #endif -#endif - -#if GL_OES_fixed_point - typedef SkFixed SkGLTextScalar; - #define SK_TextGLType GL_FIXED - - #define SkIntToTextGL(n) SkIntToFixed(n) - #define SkFixedToTextGL(x) (x) - - #define SK_glTexParameteri(target, pname, param) \ - glTexParameterx(target, pname, param) -#else - typedef float SkGLTextScalar; - #define SK_TextGLType SK_GLType - #define SK_GL_HAS_COLOR4UB - - #define SkIntToTextGL(n) SkIntToGL(n) - #define SkFixedToTextGL(x) SkFixedToFloat(x) - - - #define SK_glTexParameteri(target, pname, param) \ - glTexParameteri(target, pname, param) -#endif - -/////////////////////////////////////////////////////////////////////////////// - -// text has its own vertex class, since it may want to be in fixed point (given) -// that it starts with all integers) even when the default vertices are floats -struct SkGLTextVertex { - SkGLTextScalar fX; - SkGLTextScalar fY; - - void setI(int x, int y) { - fX = SkIntToTextGL(x); - fY = SkIntToTextGL(y); - } - - void setX(SkFixed x, SkFixed y) { - fX = SkFixedToTextGL(x); - fY = SkFixedToTextGL(y); - } - - // counter-clockwise fan - void setIRectFan(int l, int t, int r, int b) { - SkGLTextVertex* SK_RESTRICT v = this; - v[0].setI(l, t); - v[1].setI(l, b); - v[2].setI(r, b); - v[3].setI(r, t); - } - - // counter-clockwise fan - void setXRectFan(SkFixed l, SkFixed t, SkFixed r, SkFixed b) { - SkGLTextVertex* SK_RESTRICT v = this; - v[0].setX(l, t); - v[1].setX(l, b); - v[2].setX(r, b); - v[3].setX(r, t); - } -}; - -struct SkGLVertex { - SkGLScalar fX; - SkGLScalar fY; - - void setGL(SkGLScalar x, SkGLScalar y) { - fX = x; - fY = y; - } - - void setScalars(SkScalar x, SkScalar y) { - fX = SkScalarToGL(x); - fY = SkScalarToGL(y); - } - - void setPoint(const SkPoint& pt) { - fX = SkScalarToGL(pt.fX); - fY = SkScalarToGL(pt.fY); - } - - void setPoints(const SkPoint* SK_RESTRICT pts, int count) { - const SkScalar* SK_RESTRICT src = (const SkScalar*)pts; - SkGLScalar* SK_RESTRICT dst = (SkGLScalar*)this; - for (int i = 0; i < count; i++) { - *dst++ = SkScalarToGL(*src++); - *dst++ = SkScalarToGL(*src++); - } - } - - // counter-clockwise fan - void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { - SkGLVertex* v = this; - v[0].setScalars(l, t); - v[1].setScalars(l, b); - v[2].setScalars(r, b); - v[3].setScalars(r, t); - } - - // counter-clockwise fan - void setIRectFan(int l, int t, int r, int b) { - SkGLVertex* v = this; - v[0].setGL(SkIntToGL(l), SkIntToGL(t)); - v[1].setGL(SkIntToGL(l), SkIntToGL(b)); - v[2].setGL(SkIntToGL(r), SkIntToGL(b)); - v[3].setGL(SkIntToGL(r), SkIntToGL(t)); - } - - // counter-clockwise fan - void setRectFan(const SkRect& r) { - this->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom); - } - - // counter-clockwise fan - void setIRectFan(const SkIRect& r) { - this->setIRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom); - } -}; - -struct SkGLMatrix { - SkGLScalar fMat[16]; - - void reset() { - sk_bzero(fMat, sizeof(fMat)); - fMat[0] = fMat[5] = fMat[10] = fMat[15] = SK_GLScalar1; - } - - void set(const SkMatrix& m) { - sk_bzero(fMat, sizeof(fMat)); - fMat[0] = SkScalarToGL(m[SkMatrix::kMScaleX]); - fMat[4] = SkScalarToGL(m[SkMatrix::kMSkewX]); - fMat[12] = SkScalarToGL(m[SkMatrix::kMTransX]); - - fMat[1] = SkScalarToGL(m[SkMatrix::kMSkewY]); - fMat[5] = SkScalarToGL(m[SkMatrix::kMScaleY]); - fMat[13] = SkScalarToGL(m[SkMatrix::kMTransY]); - - fMat[3] = SkPerspToGL(m[SkMatrix::kMPersp0]); - fMat[7] = SkPerspToGL(m[SkMatrix::kMPersp1]); - fMat[15] = SkPerspToGL(m[SkMatrix::kMPersp2]); - - fMat[10] = SK_GLScalar1; // z-scale - } -}; - -class SkGL { -public: - static void SetColor(SkColor c); - static void SetAlpha(U8CPU alpha); - static void SetPaint(const SkPaint&, bool isPremul = true, - bool justAlpha = false); - static void SetPaintAlpha(const SkPaint& paint, bool isPremul = true) { - SetPaint(paint, isPremul, true); - } - - static void SetRGBA(uint8_t rgba[], const SkColor src[], int count); - static void DumpError(const char caller[]); - - static void Ortho(float left, float right, float bottom, float top, - float near, float far); - - static inline void Translate(SkScalar dx, SkScalar dy) { - MAKE_GL(glTranslate)(SkScalarToGL(dx), SkScalarToGL(dy), 0); - } - - static inline void Scale(SkScalar sx, SkScalar sy) { - MAKE_GL(glScale)(SkScalarToGL(sx), SkScalarToGL(sy), SK_GLScalar1); - } - - static inline void Rotate(SkScalar angle) { - MAKE_GL(glRotate)(SkScalarToGL(angle), 0, 0, SK_GLScalar1); - } - - static inline void MultMatrix(const SkMatrix& m) { - SkGLMatrix glm; - glm.set(m); - MAKE_GL(glMultMatrix)(glm.fMat); - } - - static inline void LoadMatrix(const SkMatrix& m) { - SkGLMatrix glm; - glm.set(m); - MAKE_GL(glLoadMatrix)(glm.fMat); - } - - static void Scissor(const SkIRect&, int viewportHeight); - - // return the byte size for the associated texture memory. This doesn't - // always == bitmap.getSize(), since on a given port we may have to change - // the format when the bitmap's pixels are copied over to GL - static size_t ComputeTextureMemorySize(const SkBitmap&); - // return 0 on failure - static GLuint BindNewTexture(const SkBitmap&, SkPoint* dimension); - - static void SetTexParams(bool filter, - SkShader::TileMode tx, SkShader::TileMode ty); - static void SetTexParamsClamp(bool filter); - - static void DrawVertices(int count, GLenum mode, - const SkGLVertex* SK_RESTRICT vertex, - const SkGLVertex* SK_RESTRICT texCoords, - const uint8_t* SK_RESTRICT colorArray, - const uint16_t* SK_RESTRICT indexArray, - SkGLClipIter*); - - static void PrepareForFillPath(SkPaint* paint); - static void FillPath(const SkPath& path, const SkPaint& paint, bool useTex, - SkGLClipIter*); - static void DrawPath(const SkPath& path, bool useTex, SkGLClipIter*); -}; - -#include "SkRegion.h" - -class SkGLClipIter : public SkRegion::Iterator { -public: - SkGLClipIter(int viewportHeight) : fViewportHeight(viewportHeight) {} - - // call rewind only if this is non-null - void safeRewind() { - if (this) { - this->rewind(); - } - } - - void scissor() { - SkASSERT(!this->done()); - SkGL::Scissor(this->rect(), fViewportHeight); - } - -private: - const int fViewportHeight; -}; - -#endif - diff --git a/obsolete/SkGLCanvas.cpp b/obsolete/SkGLCanvas.cpp deleted file mode 100644 index 2a76e75a7b..0000000000 --- a/obsolete/SkGLCanvas.cpp +++ /dev/null @@ -1,43 +0,0 @@ - -/* - * Copyright 2010 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#include "SkGLCanvas.h" -#include "SkGLDevice.h" - -SkGLCanvas::SkGLCanvas() : SkCanvas(SkNEW(SkGLDeviceFactory)) {} - -// static -size_t SkGLCanvas::GetTextureCacheMaxCount() { - return SkGLDevice::GetTextureCacheMaxCount(); -} - -// static -void SkGLCanvas::SetTextureCacheMaxCount(size_t count) { - SkGLDevice::SetTextureCacheMaxCount(count); -} - -// static -size_t SkGLCanvas::GetTextureCacheMaxSize() { - return SkGLDevice::GetTextureCacheMaxSize(); -} - -// static -void SkGLCanvas::SetTextureCacheMaxSize(size_t size) { - SkGLDevice::SetTextureCacheMaxSize(size); -} - -// static -void SkGLCanvas::DeleteAllTextures() { - SkGLDevice::DeleteAllTextures(); -} - -// static -void SkGLCanvas::AbandonAllTextures() { - SkGLDevice::AbandonAllTextures(); -} diff --git a/obsolete/SkGLCanvas.h b/obsolete/SkGLCanvas.h deleted file mode 100644 index 6500b06bfa..0000000000 --- a/obsolete/SkGLCanvas.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* - * Copyright 2010 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkGLCanvas_DEFINED -#define SkGLCanvas_DEFINED - -#include "SkCanvas.h" - -// Deprecated. You should now use SkGLDevice and SkGLDeviceFactory with -// SkCanvas. -class SkGLCanvas : public SkCanvas { -public: - SkGLCanvas(); - - static size_t GetTextureCacheMaxCount(); - static void SetTextureCacheMaxCount(size_t count); - - static size_t GetTextureCacheMaxSize(); - static void SetTextureCacheMaxSize(size_t size); - - static void DeleteAllTextures(); - - static void AbandonAllTextures(); -}; - -#endif 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(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(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(false -)); -} - diff --git a/obsolete/SkGLDevice.h b/obsolete/SkGLDevice.h deleted file mode 100644 index 0a7e097670..0000000000 --- a/obsolete/SkGLDevice.h +++ /dev/null @@ -1,170 +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. - */ -#ifndef SkGLDevice_DEFINED -#define SkGLDevice_DEFINED - -#include "SkDevice.h" -#include "SkGL.h" -#include "SkRegion.h" - -#ifdef SK_BUILD_FOR_MAC - #include -#elif defined(ANDROID) - #include -#endif - -class SkGLDeviceFactory : public SkDeviceFactory { -public: - virtual SkDevice* newDevice(SkBitmap::Config config, int width, int height, - bool isOpaque, bool isForLayer); -}; - -struct SkGLDrawProcs; - -class SkGLDevice : public SkDevice { -public: - SkGLDevice(const SkBitmap& bitmap, bool offscreen); - virtual ~SkGLDevice(); - - virtual SkDeviceFactory* getDeviceFactory() { - return SkNEW(SkGLDeviceFactory); - } - - virtual uint32_t getDeviceCapabilities() { return kGL_Capability; } - - // used to identify GLTextCache data in the glyphcache - static void GlyphCacheAuxProc(void* data); - - enum TexOrientation { - kNo_TexOrientation, - kTopToBottom_TexOrientation, - kBottomToTop_TexOrientation - }; - - /** Called when this device is no longer a candidate for a render target, - but will instead be used as a texture to be drawn. Be sure to call - the base impl if you override, as it will compute size and max. - */ - virtual TexOrientation bindDeviceAsTexture(); - - // returns true if complex - SkGLClipIter* updateMatrixClip(); - // call to set the clip to the specified rect - void scissor(const SkIRect&); - - // overrides from SkDevice - virtual void gainFocus(SkCanvas*); - virtual void setMatrixClip(const SkMatrix& matrix, const SkRegion& clip); - - virtual void drawPaint(const SkDraw&, const SkPaint& paint); - virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, - const SkPoint[], const SkPaint& paint); - virtual void drawRect(const SkDraw&, const SkRect& r, - const SkPaint& paint); - virtual void drawPath(const SkDraw&, const SkPath& path, - const SkPaint& paint); - virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint); - virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, - int x, int y, const SkPaint& paint); - virtual void drawText(const SkDraw&, const void* text, size_t len, - SkScalar x, SkScalar y, const SkPaint& paint); - virtual void drawPosText(const SkDraw&, const void* text, size_t len, - const SkScalar pos[], SkScalar constY, - int scalarsPerPos, const SkPaint& paint); - virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint); - virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, - const SkPoint verts[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint); - virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, - const SkPaint&); - - // settings for the global texture cache - - static size_t GetTextureCacheMaxCount(); - static void SetTextureCacheMaxCount(size_t count); - - static size_t GetTextureCacheMaxSize(); - static void SetTextureCacheMaxSize(size_t size); - - /** Call glDeleteTextures for all textures (including those for text) - This should be called while the gl-context is still valid. Its purpose - is to free up gl resources. Note that if a bitmap or text is drawn after - this call, new caches will be created. - */ - static void DeleteAllTextures(); - - /** Forget all textures without calling delete (including those for text). - This should be called if the gl-context has changed, and the texture - IDs that have been cached are no longer valid. - */ - static void AbandonAllTextures(); - -protected: - /** Return the current glmatrix, from a previous call to setMatrixClip */ - const SkMatrix& matrix() const { return fMatrix; } - /** Return the current clip, from a previous call to setMatrixClip */ - const SkRegion& clip() const { return fClip; } - -private: - SkGLMatrix fGLMatrix; - SkMatrix fMatrix; - SkRegion fClip; - bool fDirty; - - SkGLClipIter fClipIter; - SkGLDrawProcs* fDrawProcs; - - void setupForText(SkDraw* draw, const SkPaint& paint); - - // global texture cache methods - class TexCache; - static TexCache* LockTexCache(const SkBitmap&, GLuint* name, - SkPoint* size); - static void UnlockTexCache(TexCache*); - class SkAutoLockTexCache { - public: - SkAutoLockTexCache(const SkBitmap& bitmap, GLuint* name, - SkPoint* size) { - fTex = SkGLDevice::LockTexCache(bitmap, name, size); - } - ~SkAutoLockTexCache() { - if (fTex) { - SkGLDevice::UnlockTexCache(fTex); - } - } - TexCache* get() const { return fTex; } - private: - TexCache* fTex; - }; - friend class SkAutoTexCache; - - // returns cache if the texture is bound for the shader - TexCache* setupGLPaintShader(const SkPaint& paint); - - class AutoPaintShader { - public: - AutoPaintShader(SkGLDevice*, const SkPaint& paint); - ~AutoPaintShader(); - - bool useTex() const { return fTexCache != 0; } - private: - SkGLDevice* fDevice; - TexCache* fTexCache; - }; - friend class AutoPaintShader; - - typedef SkDevice INHERITED; -}; - -#endif - diff --git a/obsolete/SkGLDevice_FBO.cpp b/obsolete/SkGLDevice_FBO.cpp deleted file mode 100644 index 2cbafea836..0000000000 --- a/obsolete/SkGLDevice_FBO.cpp +++ /dev/null @@ -1,64 +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_FBO.h" -#include "SkRegion.h" - -SkGLDevice_FBO::SkGLDevice_FBO(const SkBitmap& bitmap, bool offscreen) - : SkGLDevice(bitmap, offscreen) { - fFBO = 0; - fTextureID = 0; - - if (offscreen) { - int nw = SkNextPow2(bitmap.rowBytesAsPixels()); - int nh = SkNextPow2(bitmap.height()); - - glGenFramebuffersEXT(1, &fFBO); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO); - - glGenTextures(1, &fTextureID); - glBindTexture(GL_TEXTURE_2D, fTextureID); - SkGL::SetTexParamsClamp(false); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nw, nh, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, fTextureID, 0); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - SkDebugf("-- glCheckFramebufferStatusEXT %x\n", status); - } - - // now reset back to "normal" drawing target - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } -} - -SkGLDevice_FBO::~SkGLDevice_FBO() { - if (fTextureID) { - glDeleteTextures(1, &fTextureID); - } - if (fFBO) { - glDeleteFramebuffersEXT(1, &fFBO); - } -} - -SkGLDevice::TexOrientation SkGLDevice_FBO::bindDeviceAsTexture() { - if (fTextureID) { - glBindTexture(GL_TEXTURE_2D, fTextureID); - return kBottomToTop_TexOrientation; - } - return kNo_TexOrientation; -} - -void SkGLDevice_FBO::gainFocus(SkCanvas* canvas) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO); - - // now we're ready for the viewport and projection matrix - this->INHERITED::gainFocus(canvas); -} - diff --git a/obsolete/SkGLDevice_FBO.h b/obsolete/SkGLDevice_FBO.h deleted file mode 100644 index c4ac6397e4..0000000000 --- a/obsolete/SkGLDevice_FBO.h +++ /dev/null @@ -1,30 +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. - */ -#ifndef SkGLDevice_FBO_DEFINED -#define SkGLDevice_FBO_DEFINED - -#include "SkGLDevice.h" - -class SkGLDevice_FBO : public SkGLDevice { -public: - SkGLDevice_FBO(const SkBitmap& bitmap, bool offscreen); - virtual ~SkGLDevice_FBO(); - - // overrides from SkGLDevice - virtual void gainFocus(SkCanvas*); - virtual TexOrientation bindDeviceAsTexture(); - -private: - GLuint fFBO; - GLuint fTextureID; - - typedef SkGLDevice INHERITED; -}; - -#endif - diff --git a/obsolete/SkGLDevice_SWLayer.cpp b/obsolete/SkGLDevice_SWLayer.cpp deleted file mode 100644 index 96e28ee1c5..0000000000 --- a/obsolete/SkGLDevice_SWLayer.cpp +++ /dev/null @@ -1,98 +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_SWLayer.h" -#include "SkRegion.h" - -SkGLDevice_SWLayer::SkGLDevice_SWLayer(const SkBitmap& bitmap) - : SkGLDevice(bitmap, true) { - fTextureID = 0; - - SkASSERT(bitmap.getPixels()); -} - -SkGLDevice_SWLayer::~SkGLDevice_SWLayer() { - if (fTextureID) { - glDeleteTextures(1, &fTextureID); - } -} - -SkGLDevice::TexOrientation SkGLDevice_SWLayer::bindDeviceAsTexture() { - const SkBitmap& bitmap = this->accessBitmap(false); - - if (0 == fTextureID) { - fTextureID = SkGL::BindNewTexture(bitmap, NULL); - } - return kTopToBottom_TexOrientation; -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkDraw.h" - -void SkGLDevice_SWLayer::drawPaint(const SkDraw& draw, const SkPaint& paint) { - draw.drawPaint(paint); -} - -void SkGLDevice_SWLayer::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count, - const SkPoint pts[], const SkPaint& paint) { - draw.drawPoints(mode, count, pts, paint); -} - -void SkGLDevice_SWLayer::drawRect(const SkDraw& draw, const SkRect& r, - const SkPaint& paint) { - draw.drawRect(r, paint); -} - -void SkGLDevice_SWLayer::drawPath(const SkDraw& draw, const SkPath& path, - const SkPaint& paint) { - draw.drawPath(path, paint); -} - -void SkGLDevice_SWLayer::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint) { - draw.drawBitmap(bitmap, matrix, paint); -} - -void SkGLDevice_SWLayer::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, - int x, int y, const SkPaint& paint) { - draw.drawSprite(bitmap, x, y, paint); -} - -void SkGLDevice_SWLayer::drawText(const SkDraw& draw, const void* text, size_t len, - SkScalar x, SkScalar y, const SkPaint& paint) { - draw.drawText((const char*)text, len, x, y, paint); -} - -void SkGLDevice_SWLayer::drawPosText(const SkDraw& draw, const void* text, size_t len, - const SkScalar xpos[], SkScalar y, - int scalarsPerPos, const SkPaint& paint) { - draw.drawPosText((const char*)text, len, xpos, y, scalarsPerPos, paint); -} - -void SkGLDevice_SWLayer::drawTextOnPath(const SkDraw& draw, const void* text, - size_t len, const SkPath& path, - const SkMatrix* matrix, - const SkPaint& paint) { - draw.drawTextOnPath((const char*)text, len, path, matrix, paint); -} - -void SkGLDevice_SWLayer::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, - int vertexCount, - const SkPoint verts[], const SkPoint textures[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint) { - draw.drawVertices(vmode, vertexCount, verts, textures, colors, xmode, - indices, indexCount, paint); -} - -void SkGLDevice_SWLayer::drawDevice(const SkDraw& draw, SkDevice* dev, - int x, int y, const SkPaint& paint) { - this->SkDevice::drawDevice(draw, dev, x, y, paint); -} - diff --git a/obsolete/SkGLDevice_SWLayer.h b/obsolete/SkGLDevice_SWLayer.h deleted file mode 100644 index 8c0543cdd2..0000000000 --- a/obsolete/SkGLDevice_SWLayer.h +++ /dev/null @@ -1,56 +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. - */ -#ifndef SkGLDevice_SWLayer_DEFINED -#define SkGLDevice_SWLayer_DEFINED - -#include "SkGLDevice.h" - -class SkGLDevice_SWLayer : public SkGLDevice { -public: - SkGLDevice_SWLayer(const SkBitmap& bitmap); - virtual ~SkGLDevice_SWLayer(); - - // overrides from SkGLDevice - virtual TexOrientation bindDeviceAsTexture(); - - // overrides from SkDevice - virtual void drawPaint(const SkDraw&, const SkPaint& paint); - virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, - const SkPoint[], const SkPaint& paint); - virtual void drawRect(const SkDraw&, const SkRect& r, - const SkPaint& paint); - virtual void drawPath(const SkDraw&, const SkPath& path, - const SkPaint& paint); - virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint); - virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, - int x, int y, const SkPaint& paint); - virtual void drawText(const SkDraw&, const void* text, size_t len, - SkScalar x, SkScalar y, const SkPaint& paint); - virtual void drawPosText(const SkDraw&, const void* text, size_t len, - const SkScalar pos[], SkScalar constY, - int scalarsPerPos, const SkPaint& paint); - virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint); - virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, - const SkPoint verts[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint); - virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, - const SkPaint&); - -private: - GLuint fTextureID; - - typedef SkGLDevice INHERITED; -}; - -#endif - diff --git a/obsolete/SkGLState.cpp b/obsolete/SkGLState.cpp deleted file mode 100644 index 72170697e6..0000000000 --- a/obsolete/SkGLState.cpp +++ /dev/null @@ -1,162 +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 "SkGLState.h" -#include "SkColorPriv.h" - -// here is our global instance -SkGLState SkGLState::gState; - -// this is an illegal pmcolor, since its alpha (0) is less than its red -#define UNKNOWN_PMCOLOR (SK_R32_MASK << SK_R32_SHIFT) - -#define UNKNOWN_GLENUM ((GLenum)-1) - -// MUST be in the same order as SkGLState::Caps enum -static const GLenum gCapsTable[] = { - GL_DITHER, - GL_TEXTURE_2D, -}; - -// MUST be in the same order as SkGLState::ClientState enum -static const GLenum gClientStateTable[] = { - GL_TEXTURE_COORD_ARRAY, - GL_COLOR_ARRAY, -}; - -static const GLenum gShadeModelTable[] = { - GL_FLAT, - GL_SMOOTH -}; - -/////////////////////////////////////////////////////////////////////////////// - -SkGLState::SkGLState() : - fCapsPtr(gCapsTable), - fClientPtr(gClientStateTable), - fShadePtr(gShadeModelTable) { - this->init(); -} - -void SkGLState::init() { - fCapBits = 0; - fClientStateBits = 0; - fShadeModel = UNKNOWN_GLENUM; - fScissorSize.set(-1, -1); - fPMColor = UNKNOWN_PMCOLOR; - fSrcBlend = fDstBlend = UNKNOWN_GLENUM; - fPointSize = fLineWidth = -1; -} - -void SkGLState::reset() { - this->init(); - - size_t i; - for (i = 0; i < SK_ARRAY_COUNT(gCapsTable); i++) { - glDisable(fCapsPtr[i]); - } - for (i = 0; i < SK_ARRAY_COUNT(gClientStateTable); i++) { - glDisableClientState(fClientPtr[i]); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkGLState::enable(Caps c) { - unsigned mask = 1 << c; - if ((fCapBits & mask) == 0) { - fCapBits |= mask; - glEnable(fCapsPtr[c]); - } -} - -void SkGLState::disable(Caps c) { - unsigned mask = 1 << c; - if (fCapBits & mask) { - fCapBits &= ~mask; - glDisable(fCapsPtr[c]); - } -} - -void SkGLState::enableClientState(ClientState c) { - unsigned mask = 1 << c; - if ((fClientStateBits & mask) == 0) { - fClientStateBits |= mask; - glEnableClientState(fClientPtr[c]); - } -} - -void SkGLState::disableClientState(ClientState c) { - unsigned mask = 1 << c; - if (fClientStateBits & mask) { - fClientStateBits &= ~mask; - glDisableClientState(fClientPtr[c]); - } -} - -void SkGLState::shadeModel(ShadeModel s) { - if (fShadeModel != s) { - fShadeModel = s; - glShadeModel(fShadePtr[s]); - } -} - -void SkGLState::scissor(int x, int y, int w, int h) { - SkASSERT(w >= 0 && h >= 0); - if (!fScissorLoc.equals(x, y) || !fScissorSize.equals(w, h)) { - fScissorLoc.set(x, y); - fScissorSize.set(w, h); - glScissor(x, y, w, h); - } -} - -void SkGLState::pointSize(float x) { - if (fPointSize != x) { - fPointSize = x; - glPointSize(x); - } -} - -void SkGLState::lineWidth(float x) { - if (fLineWidth != x) { - fLineWidth = x; - glLineWidth(x); - } -} - -void SkGLState::blendFunc(GLenum src, GLenum dst) { - if (fSrcBlend != src || fDstBlend != dst) { - fSrcBlend = src; - fDstBlend = dst; - glBlendFunc(src, dst); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_GL_HAS_COLOR4UB - static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { - glColor4ub(r, g, b, a); - } -#else - static inline SkFixed byte2fixed(U8CPU value) { - return ((value << 8) | value) + (value >> 7); - } - - static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { - glColor4x(byte2fixed(r), byte2fixed(g), byte2fixed(b), byte2fixed(a)); - } -#endif - -void SkGLState::pmColor(SkPMColor c) { - if (fPMColor != c) { - fPMColor = c; - gl_pmcolor(SkGetPackedR32(c), SkGetPackedG32(c), - SkGetPackedB32(c), SkGetPackedA32(c)); - } -} - diff --git a/obsolete/SkGLState.h b/obsolete/SkGLState.h deleted file mode 100644 index 96d8374e5a..0000000000 --- a/obsolete/SkGLState.h +++ /dev/null @@ -1,81 +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. - */ - -#ifndef SkGLState_DEFINED -#define SkGLState_DEFINED - -#include "SkGL.h" -#include "SkSize.h" - -class SkGLState { -public: - static SkGLState& GlobalState() { return gState; } - - SkGLState(); - - void reset(); - - // internally, these are bit_shifts, so they must be 0, 1, ... - enum Caps { - kDITHER, - kTEXTURE_2D, - }; - void enable(Caps); - void disable(Caps); - - // internally, these are bit_shifts, so they must be 0, 1, ... - enum ClientState { - kTEXTURE_COORD_ARRAY, - kCOLOR_ARRAY, - }; - void enableClientState(ClientState); - void disableClientState(ClientState); - - // we use -1 for unknown, so the enum must be >= 0 - enum ShadeModel { - kFLAT, - kSMOOTH, - }; - void shadeModel(ShadeModel); - - void scissor(int x, int y, int w, int h); - - void color(SkColor c) { - this->pmColor(SkPreMultiplyColor(c)); - } - void alpha(U8CPU a) { - this->pmColor((a << 24) | (a << 16) | (a << 8) | a); - } - void pmColor(SkPMColor); - - void blendFunc(GLenum src, GLenum dst); - - void pointSize(float); - void lineWidth(float); - -private: - void init(); - - unsigned fCapBits; - unsigned fClientStateBits; - int fShadeModel; - SkIPoint fScissorLoc; - SkISize fScissorSize; - SkPMColor fPMColor; - GLenum fSrcBlend, fDstBlend; - float fPointSize; - float fLineWidth; - - const GLenum* fCapsPtr; - const GLenum* fClientPtr; - const GLenum* fShadePtr; - - static SkGLState gState; -}; - -#endif diff --git a/obsolete/SkGLTextCache.cpp b/obsolete/SkGLTextCache.cpp deleted file mode 100644 index 830539418e..0000000000 --- a/obsolete/SkGLTextCache.cpp +++ /dev/null @@ -1,198 +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 "SkGLTextCache.h" -#include "SkScalerContext.h" -#include "SkTSearch.h" - -const GLenum gTextTextureFormat = GL_ALPHA; -const GLenum gTextTextureType = GL_UNSIGNED_BYTE; - -SkGLTextCache::Strike::Strike(Strike* next, int width, int height) { - fStrikeWidth = SkNextPow2(SkMax32(kMinStrikeWidth, width)); - fStrikeHeight = SkNextPow2(height); - fGlyphCount = 0; - fNextFreeOffsetX = 0; - fNext = next; - - fStrikeWidthShift = SkNextLog2(fStrikeWidth); - fStrikeHeightShift = SkNextLog2(fStrikeHeight); - - if (next) { - SkASSERT(next->fStrikeHeight == fStrikeHeight); - } - - // create an empty texture to receive glyphs - fTexName = 0; - glGenTextures(1, &fTexName); - glBindTexture(GL_TEXTURE_2D, fTexName); - glTexImage2D(GL_TEXTURE_2D, 0, gTextTextureFormat, - fStrikeWidth, fStrikeHeight, 0, - gTextTextureFormat, gTextTextureType, NULL); - - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -} - -SkGLTextCache::Strike::~Strike() { - if (fTexName != 0) { - glDeleteTextures(1, &fTexName); - } -} - -SkGLTextCache::Strike* -SkGLTextCache::Strike::findGlyph(const SkGlyph& glyph, int* offset) { - Strike* strike = this; - SkDEBUGCODE(const int height = SkNextPow2(glyph.fHeight);) - - do { - SkASSERT(height == strike->fStrikeHeight); - - int index = SkTSearch(strike->fGlyphIDArray, strike->fGlyphCount, - glyph.fID, sizeof(strike->fGlyphIDArray[0])); - if (index >= 0) { - if (offset) { - *offset = strike->fGlyphOffsetX[index]; - } - return strike; - } - strike = strike->fNext; - } while (NULL != strike); - return NULL; -} - -static void make_a_whole(void* buffer, int index, int count, size_t elemSize) { - SkASSERT(index >= 0 && index <= count); - size_t offset = index * elemSize; - memmove((char*)buffer + offset + elemSize, - (const char*)buffer + offset, - (count - index) * elemSize); -} - -SkGLTextCache::Strike* -SkGLTextCache::Strike::addGlyphAndBind(const SkGlyph& glyph, - const uint8_t image[], int* offset) { -#ifdef SK_DEBUG - SkASSERT(this->findGlyph(glyph, NULL) == NULL); - const int height = SkNextPow2(glyph.fHeight); - SkASSERT(height <= fStrikeHeight && height > (fStrikeHeight >> 1)); -#endif - - int rowBytes = glyph.rowBytes(); - SkASSERT(rowBytes >= glyph.fWidth); - - Strike* strike; - if (fGlyphCount == kMaxGlyphCount || - fNextFreeOffsetX + rowBytes >= fStrikeWidth) { - // this will bind the next texture for us -// SkDebugf("--- extend strike %p\n", this); - strike = SkNEW_ARGS(Strike, (this, rowBytes, glyph.fHeight)); - } else { - glBindTexture(GL_TEXTURE_2D, fTexName); - strike = this; - } - - uint32_t* idArray = strike->fGlyphIDArray; - uint16_t* offsetArray = strike->fGlyphOffsetX; - const int glyphCount = strike->fGlyphCount; - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexSubImage2D(GL_TEXTURE_2D, 0, strike->fNextFreeOffsetX, 0, rowBytes, - glyph.fHeight, gTextTextureFormat, gTextTextureType, - image); - - // need to insert the offset - int index = SkTSearch(idArray, glyphCount, glyph.fID, sizeof(idArray[0])); - SkASSERT(index < 0); - index = ~index; // this is where we should insert it - make_a_whole(idArray, index, glyphCount, sizeof(idArray)); - make_a_whole(offsetArray, index, glyphCount, sizeof(offsetArray[0])); - idArray[index] = glyph.fID; - offsetArray[index] = strike->fNextFreeOffsetX; - if (offset) { - *offset = strike->fNextFreeOffsetX; - } - -#if 0 - SkDebugf("--- strike %p glyph %x [%d %d] offset %d count %d\n", - strike, glyph.fID, glyph.fWidth, glyph.fHeight, - strike->fNextFreeOffsetX, glyphCount + 1); -#endif - - // now update our header - strike->fGlyphCount = glyphCount + 1; - strike->fNextFreeOffsetX += glyph.fWidth; - return strike; -} - -/////////////////////////////////////////////////////////////////////////////// - -SkGLTextCache::SkGLTextCache() { - sk_bzero(fStrikeList, sizeof(fStrikeList)); -} - -SkGLTextCache::~SkGLTextCache() { - this->deleteAllStrikes(true); -} - -void SkGLTextCache::deleteAllStrikes(bool texturesAreValid) { - for (size_t i = 0; i < SK_ARRAY_COUNT(fStrikeList); i++) { - Strike* strike = fStrikeList[i]; - while (strike != NULL) { - Strike* next = strike->fNext; - if (!texturesAreValid) { - strike->abandonTexture(); - } - SkDELETE(strike); - strike = next; - } - } - sk_bzero(fStrikeList, sizeof(fStrikeList)); -} - -SkGLTextCache::Strike* SkGLTextCache::findGlyph(const SkGlyph& glyph, - int* offset) { - SkASSERT(glyph.fWidth != 0); - SkASSERT(glyph.fHeight != 0); - - size_t index = SkNextLog2(glyph.fHeight); - if (index >= SK_ARRAY_COUNT(fStrikeList)) { - // too big for us to cache; - return NULL; - } - - Strike* strike = fStrikeList[index]; - if (strike) { - strike = strike->findGlyph(glyph, offset); - } - return strike; -} - -SkGLTextCache::Strike* SkGLTextCache::addGlyphAndBind(const SkGlyph& glyph, - const uint8_t image[], int* offset) { - SkASSERT(image != NULL); - SkASSERT(glyph.fWidth != 0); - SkASSERT(glyph.fHeight != 0); - - size_t index = SkNextLog2(glyph.fHeight); - if (index >= SK_ARRAY_COUNT(fStrikeList)) { - // too big for us to cache; - return NULL; - } - - Strike* strike = fStrikeList[index]; - if (NULL == strike) { - strike = SkNEW_ARGS(Strike, (NULL, glyph.rowBytes(), glyph.fHeight)); -// SkDebugf("--- create strike [%d] %p cache %p\n", index, strike, this); - } - strike = strike->addGlyphAndBind(glyph, image, offset); - fStrikeList[index] = strike; - return strike; -} - diff --git a/obsolete/SkGLTextCache.h b/obsolete/SkGLTextCache.h deleted file mode 100644 index 39472bc2e1..0000000000 --- a/obsolete/SkGLTextCache.h +++ /dev/null @@ -1,93 +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. - */ -#ifndef SkGLTextCache_DEFINED -#define SkGLTextCache_DEFINED - -#include "SkGL.h" - -class SkGlyph; - -class SkGLTextCache { -public: - SkGLTextCache(); - ~SkGLTextCache(); - - /** Delete all of the strikes in the cache. Pass true if the texture IDs are - still valid, in which case glDeleteTextures will be called. Pass false - if they are invalid (e.g. the gl-context has changed), in which case - they will just be abandoned. - */ - void deleteAllStrikes(bool texturesAreValid); - - class Strike { - public: - int width() const { return fStrikeWidth; } - int height() const { return fStrikeHeight; } - GLuint texture() const { return fTexName; } - int widthShift() const { return fStrikeWidthShift; } - int heightShift() const { return fStrikeHeightShift; } - - // call this to force us to ignore the texture name in our destructor - // only call it right before our destructor - void abandonTexture() { fTexName = 0; } - - private: - // if next is non-null, its height must match our height - Strike(Strike* next, int width, int height); - ~Strike(); - - Strike* findGlyph(const SkGlyph&, int* offset); - Strike* addGlyphAndBind(const SkGlyph&, const uint8_t*, int* offset); - - enum { - kMinStrikeWidth = 1024, - kMaxGlyphCount = 256 - }; - - Strike* fNext; - GLuint fTexName; - uint32_t fGlyphIDArray[kMaxGlyphCount]; // stores glyphIDs - uint16_t fGlyphOffsetX[kMaxGlyphCount]; // stores x-offsets - uint16_t fGlyphCount; - uint16_t fNextFreeOffsetX; - uint16_t fStrikeWidth; - uint16_t fStrikeHeight; - uint8_t fStrikeWidthShift; // pow2(fStrikeWidth) - uint8_t fStrikeHeightShift; // pow2(fStrikeHeight) - - friend class SkGLTextCache; - }; - - /** If found, returns the exact strike containing it (there may be more than - one with a given height), and sets offset to the offset for that glyph - (if not null). Does NOT bind the texture. - If not found, returns null and ignores offset param. - */ - Strike* findGlyph(const SkGlyph&, int* offset); - - /** Adds the specified glyph to this list of strikes, returning the new - head of the list. If offset is not null, it is set to the offset - for this glyph within the strike. The associated texture is bound - to the gl context. - */ - Strike* addGlyphAndBind(const SkGlyph&, const uint8_t image[], int* offset); - -private: - enum { - // greater than this we won't cache - kMaxGlyphHeightShift = 9, - - kMaxGlyphHeight = 1 << kMaxGlyphHeightShift, - kMaxStrikeListCount = kMaxGlyphHeightShift + 1 - }; - - // heads of the N families, one for each pow2 height - Strike* fStrikeList[kMaxStrikeListCount]; -}; - -#endif diff --git a/obsolete/SkTextureCache.cpp b/obsolete/SkTextureCache.cpp deleted file mode 100644 index 999bf1a94f..0000000000 --- a/obsolete/SkTextureCache.cpp +++ /dev/null @@ -1,370 +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 "SkTextureCache.h" - -//#define TRACE_HASH_HITS -//#define TRACE_TEXTURE_CACHE_PURGE - -SkTextureCache::Entry::Entry(const SkBitmap& bitmap) - : fName(0), fKey(bitmap), fPrev(NULL), fNext(NULL) { - - fMemSize = SkGL::ComputeTextureMemorySize(bitmap); - fLockCount = 0; -} - -SkTextureCache::Entry::~Entry() { - if (fName != 0) { - glDeleteTextures(1, &fName); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -SkTextureCache::SkTextureCache(size_t countMax, size_t sizeMax) - : fHead(NULL), fTail(NULL), - fTexCountMax(countMax), fTexSizeMax(sizeMax), - fTexCount(0), fTexSize(0) { - - sk_bzero(fHash, sizeof(fHash)); - this->validate(); -} - -SkTextureCache::~SkTextureCache() { -#ifdef SK_DEBUG - Entry* entry = fHead; - while (entry) { - SkASSERT(entry->lockCount() == 0); - entry = entry->fNext; - } -#endif - this->validate(); -} - -void SkTextureCache::deleteAllCaches(bool texturesAreValid) { - this->validate(); - - Entry* entry = fHead; - while (entry) { - Entry* next = entry->fNext; - if (!texturesAreValid) { - entry->abandonTexture(); - } - SkDELETE(entry); - entry = next; - } - - fSorted.reset(); - sk_bzero(fHash, sizeof(fHash)); - - fTexCount = 0; - fTexSize = 0; - - fTail = fHead = NULL; - - this->validate(); -} - -/////////////////////////////////////////////////////////////////////////////// - -int SkTextureCache::findInSorted(const Key& key) const { - int count = fSorted.count(); - if (count == 0) { - return ~0; - } - - Entry** sorted = fSorted.begin(); - int lo = 0; - int hi = count - 1; - while (lo < hi) { - int mid = (hi + lo) >> 1; - if (sorted[mid]->getKey() < key) { - lo = mid + 1; - } else { - hi = mid; - } - } - - // hi is now our best guess - const Entry* entry = sorted[hi]; - if (entry->getKey() == key) { - return hi; - } - - // return where to insert it - if (entry->getKey() < key) { - hi += 1; - } - return ~hi; // we twiddle to indicate not-found -} - -#ifdef TRACE_HASH_HITS -static int gHashHits; -static int gSortedHits; -#endif - -SkTextureCache::Entry* SkTextureCache::find(const Key& key, int* insert) const { - int count = fSorted.count(); - if (count == 0) { - *insert = 0; - return NULL; - } - - // check the hash first - int hashIndex = key.getHashIndex(); - Entry* entry = fHash[hashIndex]; - if (NULL != entry && entry->getKey() == key) { -#ifdef TRACE_HASH_HITS - gHashHits += 1; -#endif - return entry; - } - - int index = this->findInSorted(key); - if (index >= 0) { -#ifdef TRACE_HASH_HITS - gSortedHits += 1; -#endif - entry = fSorted[index]; - fHash[hashIndex] = entry; - return entry; - } - - // ~index is where to insert the entry - *insert = ~index; - return NULL; -} - -SkTextureCache::Entry* SkTextureCache::lock(const SkBitmap& bitmap) { - this->validate(); - - // call this before we call find(), so we don't reorder after find() and - // invalidate our index - this->purgeIfNecessary(SkGL::ComputeTextureMemorySize(bitmap)); - - Key key(bitmap); - int index; - Entry* entry = this->find(key, &index); - - if (NULL == entry) { - entry = SkNEW_ARGS(Entry, (bitmap)); - - entry->fName = SkGL::BindNewTexture(bitmap, &entry->fTexSize); - if (0 == entry->fName) { - SkDELETE(entry); - return NULL; - } - fHash[key.getHashIndex()] = entry; - *fSorted.insert(index) = entry; - - fTexCount += 1; - fTexSize += entry->memSize(); - } else { - // detach from our llist - Entry* prev = entry->fPrev; - Entry* next = entry->fNext; - if (prev) { - prev->fNext = next; - } else { - SkASSERT(fHead == entry); - fHead = next; - } - if (next) { - next->fPrev = prev; - } else { - SkASSERT(fTail == entry); - fTail = prev; - } - // now bind the texture - glBindTexture(GL_TEXTURE_2D, entry->fName); - } - - // add to head of llist for LRU - entry->fPrev = NULL; - entry->fNext = fHead; - if (NULL != fHead) { - SkASSERT(NULL == fHead->fPrev); - fHead->fPrev = entry; - } - fHead = entry; - if (NULL == fTail) { - fTail = entry; - } - - this->validate(); - entry->lock(); - -#ifdef TRACE_HASH_HITS - SkDebugf("---- texture cache hash=%d sorted=%d\n", gHashHits, gSortedHits); -#endif - return entry; -} - -void SkTextureCache::unlock(Entry* entry) { - this->validate(); - -#ifdef SK_DEBUG - SkASSERT(entry); - int index = this->findInSorted(entry->getKey()); - SkASSERT(fSorted[index] == entry); -#endif - - SkASSERT(entry->fLockCount > 0); - entry->unlock(); -} - -void SkTextureCache::purgeIfNecessary(size_t extraSize) { - this->validate(); - - size_t countMax = fTexCountMax; - size_t sizeMax = fTexSizeMax; - - // take extraSize into account, but watch for underflow of size_t - if (extraSize > sizeMax) { - sizeMax = 0; - } else { - sizeMax -= extraSize; - } - - Entry* entry = fTail; - while (entry) { - if (fTexCount <= countMax && fTexSize <= sizeMax) { - break; - } - - Entry* prev = entry->fPrev; - // don't purge an entry that is locked - if (entry->isLocked()) { - entry = prev; - continue; - } - - fTexCount -= 1; - fTexSize -= entry->memSize(); - - // remove from our sorted and hash arrays - int index = this->findInSorted(entry->getKey()); - SkASSERT(index >= 0); - fSorted.remove(index); - index = entry->getKey().getHashIndex(); - if (entry == fHash[index]) { - fHash[index] = NULL; - } - - // now detach it from our llist - Entry* next = entry->fNext; - if (prev) { - prev->fNext = next; - } else { - fHead = next; - } - if (next) { - next->fPrev = prev; - } else { - fTail = prev; - } - - // now delete it -#ifdef TRACE_TEXTURE_CACHE_PURGE - SkDebugf("---- purge texture cache %d size=%d\n", - entry->name(), entry->memSize()); -#endif - SkDELETE(entry); - - // keep going - entry = prev; - } - - this->validate(); -} - -void SkTextureCache::setMaxCount(size_t count) { - if (fTexCountMax != count) { - fTexCountMax = count; - this->purgeIfNecessary(0); - } -} - -void SkTextureCache::setMaxSize(size_t size) { - if (fTexSizeMax != size) { - fTexSizeMax = size; - this->purgeIfNecessary(0); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_DEBUG -void SkTextureCache::validate() const { - if (0 == fTexCount) { - SkASSERT(0 == fTexSize); - SkASSERT(NULL == fHead); - SkASSERT(NULL == fTail); - return; - } - - SkASSERT(fTexSize); // do we allow a zero-sized texture? - SkASSERT(fHead); - SkASSERT(fTail); - - SkASSERT(NULL == fHead->fPrev); - SkASSERT(NULL == fTail->fNext); - if (1 == fTexCount) { - SkASSERT(fHead == fTail); - } - - const Entry* entry = fHead; - size_t count = 0; - size_t size = 0; - size_t i; - - while (entry != NULL) { - SkASSERT(count < fTexCount); - SkASSERT(size < fTexSize); - size += entry->memSize(); - count += 1; - if (NULL == entry->fNext) { - SkASSERT(fTail == entry); - } - entry = entry->fNext; - } - SkASSERT(count == fTexCount); - SkASSERT(size == fTexSize); - - count = 0; - size = 0; - entry = fTail; - while (entry != NULL) { - SkASSERT(count < fTexCount); - SkASSERT(size < fTexSize); - size += entry->memSize(); - count += 1; - if (NULL == entry->fPrev) { - SkASSERT(fHead == entry); - } - entry = entry->fPrev; - } - SkASSERT(count == fTexCount); - SkASSERT(size == fTexSize); - - SkASSERT(count == (size_t)fSorted.count()); - for (i = 1; i < count; i++) { - SkASSERT(fSorted[i-1]->getKey() < fSorted[i]->getKey()); - } - - for (i = 0; i < kHashCount; i++) { - if (fHash[i]) { - size_t index = fHash[i]->getKey().getHashIndex(); - SkASSERT(index == i); - index = fSorted.find(fHash[i]); - SkASSERT((size_t)index < count); - } - } -} -#endif - - diff --git a/obsolete/SkTextureCache.h b/obsolete/SkTextureCache.h deleted file mode 100644 index aac3af4d1b..0000000000 --- a/obsolete/SkTextureCache.h +++ /dev/null @@ -1,168 +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. - */ -#ifndef SkTextureCache_DEFINED -#define SkTextureCache_DEFINED - -#include "SkBitmap.h" -#include "SkPoint.h" -#include "SkGL.h" -#include "SkTDArray.h" - -class SkTextureCache { -public: - SkTextureCache(size_t maxCount, size_t maxSize); - ~SkTextureCache(); - - size_t getMaxCount() { return fTexCountMax; } - size_t getMaxSize() { return fTexSizeMax; } - - void setMaxCount(size_t count); - void setMaxSize(size_t size); - - /** Deletes all the caches. Pass true if the texture IDs are still valid, - and if so, it will call glDeleteTextures. Pass false if the texture IDs - are invalid (e.g. the gl-context has changed), in which case they will - just be abandoned. - */ - void deleteAllCaches(bool texturesAreValid); - - static int HashMask() { return kHashMask; } - - class Key { - public: - Key(const SkBitmap& bm) { - fGenID = bm.getGenerationID(); - fOffset = bm.pixelRefOffset(); - fWH = (bm.width() << 16) | bm.height(); - this->computeHash(); - } - - int getHashIndex() const { return fHashIndex; } - - friend bool operator==(const Key& a, const Key& b) { - return a.fHash == b.fHash && - a.fGenID == b.fGenID && - a.fOffset == b.fOffset && - a.fWH == b.fWH; - } - - friend bool operator<(const Key& a, const Key& b) { - if (a.fHash < b.fHash) { - return true; - } else if (a.fHash > b.fHash) { - return false; - } - - if (a.fGenID < b.fGenID) { - return true; - } else if (a.fGenID > b.fGenID) { - return false; - } - - if (a.fOffset < b.fOffset) { - return true; - } else if (a.fOffset > b.fOffset) { - return false; - } - - return a.fWH < b.fWH; - } - - private: - void computeHash() { - uint32_t hash = fGenID ^ fOffset ^ fWH; - fHash = hash; - hash ^= hash >> 16; - fHashIndex = hash & SkTextureCache::HashMask(); - } - - uint32_t fHash; // computed from the other fields - uint32_t fGenID; - size_t fOffset; - uint32_t fWH; - // for indexing into the texturecache's fHash - int fHashIndex; - }; - - class Entry { - public: - GLuint name() const { return fName; } - SkPoint texSize() const { return fTexSize; } - size_t memSize() const { return fMemSize; } - const Key& getKey() const { return fKey; } - - // call this to clear the texture name, in case the context has changed - // in which case we should't reference or delete this texture in GL - void abandonTexture() { fName = 0; } - - private: - Entry(const SkBitmap& bitmap); - ~Entry(); - - int lockCount() const { return fLockCount; } - bool isLocked() const { return fLockCount > 0; } - - void lock() { fLockCount += 1; } - void unlock() { - SkASSERT(fLockCount > 0); - fLockCount -= 1; - } - - private: - GLuint fName; - SkPoint fTexSize; - Key fKey; - size_t fMemSize; - int fLockCount; - - Entry* fPrev; - Entry* fNext; - - friend class SkTextureCache; - }; - - Entry* lock(const SkBitmap&); - void unlock(Entry*); - -private: - void purgeIfNecessary(size_t extraSize); - -#ifdef SK_DEBUG - void validate() const; -#else - void validate() const {} -#endif - - Entry* fHead; - Entry* fTail; - - // limits for the cache - size_t fTexCountMax; - size_t fTexSizeMax; - - // current values for the cache - size_t fTexCount; - size_t fTexSize; - - enum { - kHashBits = 6, - kHashCount = 1 << kHashBits, - kHashMask = kHashCount - 1 - }; - mutable Entry* fHash[kHashCount]; - SkTDArray fSorted; - - /* If we find the key, return the entry and ignore index. If we don't, - return NULL and set index to the place to insert the entry in fSorted - */ - Entry* find(const Key&, int* index) const; - // returns index or <0 if not found. Does NOT update hash - int findInSorted(const Key& key) const; -}; - -#endif