| Index: skia/gl/SkGLTextCache.cpp
|
| ===================================================================
|
| --- skia/gl/SkGLTextCache.cpp (revision 16859)
|
| +++ skia/gl/SkGLTextCache.cpp (working copy)
|
| @@ -1,191 +0,0 @@
|
| -#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() {
|
| - 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;
|
| - }
|
| - }
|
| - 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;
|
| -}
|
| -
|
|
|