Merge "Code cleanup in FontRenderer" into jb-mr1-dev
This commit is contained in:
@@ -127,68 +127,34 @@ void FontRenderer::flushAllAndInvalidate() {
|
||||
mCacheTextures[i]->init();
|
||||
}
|
||||
|
||||
#if DEBUG_FONT_RENDERER
|
||||
#if DEBUG_FONT_RENDERER
|
||||
uint16_t totalGlyphs = 0;
|
||||
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
|
||||
totalGlyphs += mCacheTextures[i]->mNumGlyphs;
|
||||
totalGlyphs += mCacheTextures[i]->getGlyphCount();
|
||||
// Erase caches, just as a debugging facility
|
||||
if (mCacheTextures[i]->mTexture) {
|
||||
memset(mCacheTextures[i]->mTexture, 0,
|
||||
mCacheTextures[i]->mWidth * mCacheTextures[i]->mHeight);
|
||||
if (mCacheTextures[i]->getTexture()) {
|
||||
memset(mCacheTextures[i]->getTexture(), 0,
|
||||
mCacheTextures[i]->getWidth() * mCacheTextures[i]->getHeight());
|
||||
}
|
||||
}
|
||||
ALOGD("Flushing caches: glyphs cached = %d", totalGlyphs);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FontRenderer::deallocateTextureMemory(CacheTexture *cacheTexture) {
|
||||
if (cacheTexture && cacheTexture->mTexture) {
|
||||
glDeleteTextures(1, &cacheTexture->mTextureId);
|
||||
delete[] cacheTexture->mTexture;
|
||||
cacheTexture->mTexture = NULL;
|
||||
cacheTexture->mTextureId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderer::flushLargeCaches() {
|
||||
// Start from 1; don't deallocate smallest/default texture
|
||||
for (uint32_t i = 1; i < mCacheTextures.size(); i++) {
|
||||
CacheTexture* cacheTexture = mCacheTextures[i];
|
||||
if (cacheTexture->mTexture != NULL) {
|
||||
if (cacheTexture->getTexture()) {
|
||||
cacheTexture->init();
|
||||
for (uint32_t j = 0; j < mActiveFonts.size(); j++) {
|
||||
mActiveFonts[j]->invalidateTextureCache(cacheTexture);
|
||||
}
|
||||
deallocateTextureMemory(cacheTexture);
|
||||
cacheTexture->releaseTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderer::allocateTextureMemory(CacheTexture* cacheTexture) {
|
||||
int width = cacheTexture->mWidth;
|
||||
int height = cacheTexture->mHeight;
|
||||
|
||||
cacheTexture->mTexture = new uint8_t[width * height];
|
||||
|
||||
if (!cacheTexture->mTextureId) {
|
||||
glGenTextures(1, &cacheTexture->mTextureId);
|
||||
}
|
||||
|
||||
Caches::getInstance().activeTexture(0);
|
||||
glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
// Initialize texture dimensions
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
const GLenum filtering = cacheTexture->mLinearFiltering ? GL_LINEAR : GL_NEAREST;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
CacheTexture* FontRenderer::cacheBitmapInTexture(const SkGlyph& glyph,
|
||||
uint32_t* startX, uint32_t* startY) {
|
||||
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
|
||||
@@ -206,7 +172,7 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
|
||||
cachedGlyph->mIsValid = false;
|
||||
// If the glyph is too tall, don't cache it
|
||||
if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 >
|
||||
mCacheTextures[mCacheTextures.size() - 1]->mHeight) {
|
||||
mCacheTextures[mCacheTextures.size() - 1]->getHeight()) {
|
||||
ALOGE("Font size too large to fit in cache. width, height = %i, %i",
|
||||
(int) glyph.fWidth, (int) glyph.fHeight);
|
||||
return;
|
||||
@@ -240,14 +206,15 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
|
||||
uint32_t endX = startX + glyph.fWidth;
|
||||
uint32_t endY = startY + glyph.fHeight;
|
||||
|
||||
uint32_t cacheWidth = cacheTexture->mWidth;
|
||||
uint32_t cacheWidth = cacheTexture->getWidth();
|
||||
|
||||
if (!cacheTexture->mTexture) {
|
||||
if (!cacheTexture->getTexture()) {
|
||||
Caches::getInstance().activeTexture(0);
|
||||
// Large-glyph texture memory is allocated only as needed
|
||||
allocateTextureMemory(cacheTexture);
|
||||
cacheTexture->allocateTexture();
|
||||
}
|
||||
|
||||
uint8_t* cacheBuffer = cacheTexture->mTexture;
|
||||
uint8_t* cacheBuffer = cacheTexture->getTexture();
|
||||
uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage;
|
||||
unsigned int stride = glyph.rowBytes();
|
||||
|
||||
@@ -287,7 +254,8 @@ CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool alloc
|
||||
CacheTexture* cacheTexture = new CacheTexture(width, height);
|
||||
|
||||
if (allocate) {
|
||||
allocateTextureMemory(cacheTexture);
|
||||
Caches::getInstance().activeTexture(0);
|
||||
cacheTexture->allocateTexture();
|
||||
}
|
||||
|
||||
return cacheTexture;
|
||||
@@ -362,16 +330,16 @@ void FontRenderer::checkTextureUpdate() {
|
||||
// Iterate over all the cache textures and see which ones need to be updated
|
||||
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
|
||||
CacheTexture* cacheTexture = mCacheTextures[i];
|
||||
if (cacheTexture->mDirty && cacheTexture->mTexture != NULL) {
|
||||
if (cacheTexture->isDirty() && cacheTexture->getTexture()) {
|
||||
uint32_t xOffset = 0;
|
||||
uint32_t width = cacheTexture->mWidth;
|
||||
uint32_t height = cacheTexture->mHeight;
|
||||
void* textureData = cacheTexture->mTexture;
|
||||
uint32_t width = cacheTexture->getWidth();
|
||||
uint32_t height = cacheTexture->getHeight();
|
||||
void* textureData = cacheTexture->getTexture();
|
||||
|
||||
if (cacheTexture->mTextureId != lastTextureId) {
|
||||
if (cacheTexture->getTextureId() != lastTextureId) {
|
||||
lastTextureId = cacheTexture->getTextureId();
|
||||
caches.activeTexture(0);
|
||||
glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId);
|
||||
lastTextureId = cacheTexture->mTextureId;
|
||||
glBindTexture(GL_TEXTURE_2D, lastTextureId);
|
||||
}
|
||||
#if DEBUG_FONT_RENDERER
|
||||
ALOGD("glTextSubimage for cacheTexture %d: xOff, width height = %d, %d, %d",
|
||||
@@ -380,18 +348,14 @@ void FontRenderer::checkTextureUpdate() {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, 0, width, height,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
|
||||
|
||||
cacheTexture->mDirty = false;
|
||||
cacheTexture->setDirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
caches.activeTexture(0);
|
||||
glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId);
|
||||
if (mLinearFiltering != mCurrentCacheTexture->mLinearFiltering) {
|
||||
const GLenum filtering = mLinearFiltering ? GL_LINEAR : GL_NEAREST;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
mCurrentCacheTexture->mLinearFiltering = mLinearFiltering;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->getTextureId());
|
||||
|
||||
mCurrentCacheTexture->setLinearFiltering(mLinearFiltering, false);
|
||||
mLastCacheTexture = mCurrentCacheTexture;
|
||||
|
||||
mUploadTexture = false;
|
||||
|
||||
@@ -85,25 +85,18 @@ public:
|
||||
GLuint getTexture(bool linearFiltering = false) {
|
||||
checkInit();
|
||||
|
||||
if (linearFiltering != mCurrentCacheTexture->mLinearFiltering) {
|
||||
mCurrentCacheTexture->mLinearFiltering = linearFiltering;
|
||||
mLinearFiltering = linearFiltering;
|
||||
const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
|
||||
mCurrentCacheTexture->setLinearFiltering(linearFiltering);
|
||||
mLinearFiltering = linearFiltering;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->mTextureId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
|
||||
return mCurrentCacheTexture->mTextureId;
|
||||
return mCurrentCacheTexture->getTextureId();
|
||||
}
|
||||
|
||||
uint32_t getCacheSize() const {
|
||||
uint32_t size = 0;
|
||||
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
|
||||
CacheTexture* cacheTexture = mCacheTextures[i];
|
||||
if (cacheTexture != NULL && cacheTexture->mTexture != NULL) {
|
||||
size += cacheTexture->mWidth * cacheTexture->mHeight;
|
||||
if (cacheTexture && cacheTexture->getTexture()) {
|
||||
size += cacheTexture->getWidth() * cacheTexture->getHeight();
|
||||
}
|
||||
}
|
||||
return size;
|
||||
|
||||
@@ -103,8 +103,91 @@ public:
|
||||
mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
|
||||
}
|
||||
|
||||
void releaseTexture() {
|
||||
if (mTexture) {
|
||||
glDeleteTextures(1, &mTextureId);
|
||||
delete[] mTexture;
|
||||
mTexture = NULL;
|
||||
mTextureId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method assumes that the proper texture unit is active.
|
||||
*/
|
||||
void allocateTexture() {
|
||||
int width = mWidth;
|
||||
int height = mHeight;
|
||||
|
||||
mTexture = new uint8_t[width * height];
|
||||
|
||||
if (!mTextureId) {
|
||||
glGenTextures(1, &mTextureId);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureId);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
// Initialize texture dimensions
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, 0);
|
||||
|
||||
const GLenum filtering = getLinearFiltering() ? GL_LINEAR : GL_NEAREST;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
|
||||
|
||||
inline uint16_t getWidth() const {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
inline uint16_t getHeight() const {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
inline uint8_t* getTexture() const {
|
||||
return mTexture;
|
||||
}
|
||||
|
||||
inline GLuint getTextureId() const {
|
||||
return mTextureId;
|
||||
}
|
||||
|
||||
inline bool isDirty() const {
|
||||
return mDirty;
|
||||
}
|
||||
|
||||
inline void setDirty(bool dirty) {
|
||||
mDirty = dirty;
|
||||
}
|
||||
|
||||
inline bool getLinearFiltering() const {
|
||||
return mLinearFiltering;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method assumes that the proper texture unit is active.
|
||||
*/
|
||||
void setLinearFiltering(bool linearFiltering, bool bind = true) {
|
||||
if (linearFiltering != mLinearFiltering) {
|
||||
mLinearFiltering = linearFiltering;
|
||||
|
||||
const GLenum filtering = linearFiltering ? GL_LINEAR : GL_NEAREST;
|
||||
if (bind) glBindTexture(GL_TEXTURE_2D, getTextureId());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint16_t getGlyphCount() const {
|
||||
return mNumGlyphs;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t* mTexture;
|
||||
GLuint mTextureId;
|
||||
uint16_t mWidth;
|
||||
|
||||
@@ -48,10 +48,10 @@ Font::~Font() {
|
||||
}
|
||||
}
|
||||
|
||||
void Font::invalidateTextureCache(CacheTexture *cacheTexture) {
|
||||
void Font::invalidateTextureCache(CacheTexture* cacheTexture) {
|
||||
for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
|
||||
CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueAt(i);
|
||||
if (cacheTexture == NULL || cachedGlyph->mCacheTexture == cacheTexture) {
|
||||
if (cacheTexture || cachedGlyph->mCacheTexture == cacheTexture) {
|
||||
cachedGlyph->mIsValid = false;
|
||||
}
|
||||
}
|
||||
@@ -106,9 +106,9 @@ void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
|
||||
uint32_t endX = glyph->mStartX + glyph->mBitmapWidth;
|
||||
uint32_t endY = glyph->mStartY + glyph->mBitmapHeight;
|
||||
|
||||
CacheTexture *cacheTexture = glyph->mCacheTexture;
|
||||
uint32_t cacheWidth = cacheTexture->mWidth;
|
||||
const uint8_t* cacheBuffer = cacheTexture->mTexture;
|
||||
CacheTexture* cacheTexture = glyph->mCacheTexture;
|
||||
uint32_t cacheWidth = cacheTexture->getWidth();
|
||||
const uint8_t* cacheBuffer = cacheTexture->getTexture();
|
||||
|
||||
uint32_t cacheX = 0, cacheY = 0;
|
||||
int32_t bX = 0, bY = 0;
|
||||
@@ -392,8 +392,8 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
|
||||
glyph->mBitmapWidth = skiaGlyph.fWidth;
|
||||
glyph->mBitmapHeight = skiaGlyph.fHeight;
|
||||
|
||||
uint32_t cacheWidth = glyph->mCacheTexture->mWidth;
|
||||
uint32_t cacheHeight = glyph->mCacheTexture->mHeight;
|
||||
uint32_t cacheWidth = glyph->mCacheTexture->getWidth();
|
||||
uint32_t cacheHeight = glyph->mCacheTexture->getHeight();
|
||||
|
||||
glyph->mBitmapMinU = startX / (float) cacheWidth;
|
||||
glyph->mBitmapMinV = startY / (float) cacheHeight;
|
||||
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
// Cache of glyphs
|
||||
DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
|
||||
|
||||
void invalidateTextureCache(CacheTexture *cacheTexture = NULL);
|
||||
void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
|
||||
|
||||
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
|
||||
void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
|
||||
|
||||
Reference in New Issue
Block a user