Cleanup, added properties for the FontRenderer.
Change-Id: I909c74815d3ac394438ad8071d17fef5401dbeed
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index c3d2448..99b34dd 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -44,19 +44,33 @@
} while (head);
mHasNPot = hasExtension("GL_OES_texture_npot");
+ mHasDrawPath = hasExtension("GL_NV_draw_path");
+ mHasCoverageSample = hasExtension("GL_NV_coverage_sample");
+
+ mExtensions = buffer;
}
inline bool hasNPot() const { return mHasNPot; }
+ inline bool hasDrawPath() const { return mHasDrawPath; }
+ inline bool hasCoverageSample() const { return mHasCoverageSample; }
bool hasExtension(const char* extension) const {
const String8 s(extension);
return mExtensionList.indexOf(s) >= 0;
}
+ void dump() {
+ LOGD("Supported extensions:\n%s", mExtensions);
+ }
+
private:
SortedVector<String8> mExtensionList;
+ const char* mExtensions;
+
bool mHasNPot;
+ bool mHasDrawPath;
+ bool mHasCoverageSample;
}; // class Extensions
}; // namespace uirenderer
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 5ab89e2..24dee55 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -16,14 +16,24 @@
#define LOG_TAG "OpenGLRenderer"
-#include "FontRenderer.h"
-
#include <SkUtils.h>
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+#include "FontRenderer.h"
+
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+#define DEFAULT_TEXT_CACHE_WIDTH 1024
+#define DEFAULT_TEXT_CACHE_HEIGHT 256
+
+///////////////////////////////////////////////////////////////////////////////
// Font
///////////////////////////////////////////////////////////////////////////////
@@ -41,7 +51,7 @@
}
for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
- CachedGlyphInfo *glyph = mCachedGlyphs.valueAt(i);
+ CachedGlyphInfo* glyph = mCachedGlyphs.valueAt(i);
delete glyph;
}
}
@@ -53,19 +63,24 @@
}
void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y) {
- FontRenderer *state = mState;
-
int nPenX = x + glyph->mBitmapLeft;
int nPenY = y + glyph->mBitmapTop + glyph->mBitmapHeight;
- state->appendMeshQuad(nPenX, nPenY, 0, glyph->mBitmapMinU, glyph->mBitmapMaxV,
- nPenX + (int) glyph->mBitmapWidth, nPenY, 0, glyph->mBitmapMaxU, glyph->mBitmapMaxV,
- nPenX + (int) glyph->mBitmapWidth, nPenY - (int) glyph->mBitmapHeight,
- 0, glyph->mBitmapMaxU, glyph->mBitmapMinV, nPenX, nPenY - (int) glyph->mBitmapHeight,
- 0, glyph->mBitmapMinU, glyph->mBitmapMinV);
+ float u1 = glyph->mBitmapMinU;
+ float u2 = glyph->mBitmapMaxU;
+ float v1 = glyph->mBitmapMinV;
+ float v2 = glyph->mBitmapMaxV;
+
+ int width = (int) glyph->mBitmapWidth;
+ int height = (int) glyph->mBitmapHeight;
+
+ mState->appendMeshQuad(nPenX, nPenY, 0, u1, v2,
+ nPenX + width, nPenY, 0, u2, v2,
+ nPenX + width, nPenY - height, 0, u2, v1,
+ nPenX, nPenY - height, 0, u1, v1);
}
-void Font::renderUTF(SkPaint* paint, const char *text, uint32_t len, uint32_t start,
+void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
int numGlyphs, int x, int y) {
if (numGlyphs == 0 || text == NULL || len == 0) {
return;
@@ -77,13 +92,9 @@
glyphsLeft = numGlyphs;
}
- //size_t index = start;
- //size_t nextIndex = 0;
-
text += start;
while (glyphsLeft > 0) {
- //int32_t utfChar = utf32_at(text, len, index, &nextIndex);
int32_t utfChar = SkUTF16_NextUnichar((const uint16_t**) &text);
// Reached the end of the string or encountered
@@ -91,14 +102,11 @@
break;
}
- // Move to the next character in the array
- //index = nextIndex;
-
- CachedGlyphInfo *cachedGlyph = mCachedGlyphs.valueFor(utfChar);
-
+ CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(utfChar);
if (cachedGlyph == NULL) {
cachedGlyph = cacheGlyph(paint, utfChar);
}
+
// Is the glyph still in texture cache?
if (!cachedGlyph->mIsValid) {
const SkGlyph& skiaGlyph = paint->getUnicharMetrics(utfChar);
@@ -119,7 +127,7 @@
}
}
-void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph) {
+void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph) {
glyph->mAdvanceX = skiaGlyph.fAdvanceX;
glyph->mAdvanceY = skiaGlyph.fAdvanceY;
glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -128,11 +136,9 @@
uint32_t startX = 0;
uint32_t startY = 0;
- // Let the font state figure out where to put the bitmap
- FontRenderer *state = mState;
// Get the bitmap for the glyph
paint->findImage(skiaGlyph);
- glyph->mIsValid = state->cacheBitmap(skiaGlyph, &startX, &startY);
+ glyph->mIsValid = mState->cacheBitmap(skiaGlyph, &startX, &startY);
if (!glyph->mIsValid) {
return;
@@ -144,19 +150,19 @@
glyph->mBitmapWidth = skiaGlyph.fWidth;
glyph->mBitmapHeight = skiaGlyph.fHeight;
- uint32_t cacheWidth = state->getCacheWidth();
- uint32_t cacheHeight = state->getCacheHeight();
+ uint32_t cacheWidth = mState->getCacheWidth();
+ uint32_t cacheHeight = mState->getCacheHeight();
glyph->mBitmapMinU = (float) startX / (float) cacheWidth;
glyph->mBitmapMinV = (float) startY / (float) cacheHeight;
glyph->mBitmapMaxU = (float) endX / (float) cacheWidth;
glyph->mBitmapMaxV = (float) endY / (float) cacheHeight;
- state->mUploadTexture = true;
+ mState->mUploadTexture = true;
}
-Font::CachedGlyphInfo *Font::cacheGlyph(SkPaint* paint, int32_t glyph) {
- CachedGlyphInfo *newGlyph = new CachedGlyphInfo();
+Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, int32_t glyph) {
+ CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
mCachedGlyphs.add(glyph, newGlyph);
const SkGlyph& skiaGlyph = paint->getUnicharMetrics(glyph);
@@ -172,9 +178,9 @@
Vector<Font*> &activeFonts = state->mActiveFonts;
for (uint32_t i = 0; i < activeFonts.size(); i++) {
- Font *ithFont = activeFonts[i];
- if (ithFont->mFontId == fontId && ithFont->mFontSize == fontSize) {
- return ithFont;
+ Font* font = activeFonts[i];
+ if (font->mFontId == fontId && font->mFontSize == fontSize) {
+ return font;
}
}
@@ -188,14 +194,31 @@
///////////////////////////////////////////////////////////////////////////////
FontRenderer::FontRenderer() {
+ LOGD("Creating FontRenderer");
+
mInitialized = false;
mMaxNumberOfQuads = 1024;
mCurrentQuadIndex = 0;
mIndexBufferID = 0;
- mCacheWidth = 1024;
- mCacheHeight = 256;
+ mCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
+ mCacheHeight = DEFAULT_TEXT_CACHE_WIDTH;
+
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
+ LOGD(" Setting text cache width to %s pixels", property);
+ mCacheWidth = atoi(property);
+ } else {
+ LOGD(" Using default text cache width of %i pixels", mCacheWidth);
+ }
+
+ if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
+ LOGD(" Setting text cache width to %s pixels", property);
+ mCacheHeight = atoi(property);
+ } else {
+ LOGD(" Using default text cache height of %i pixels", mCacheHeight);
+ }
}
FontRenderer::~FontRenderer() {
@@ -225,7 +248,7 @@
}
}
-bool FontRenderer::cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
+bool FontRenderer::cacheBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY) {
// If the glyph is too tall, don't cache it
if (glyph.fWidth > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
LOGE("Font size to large to fit in cache. width, height = %i, %i",
@@ -273,8 +296,8 @@
uint32_t cacheWidth = mCacheWidth;
- unsigned char *cacheBuffer = mTextTexture;
- unsigned char *bitmapBuffer = (unsigned char*) glyph.fImage;
+ unsigned char* cacheBuffer = mTextTexture;
+ unsigned char* bitmapBuffer = (unsigned char*) glyph.fImage;
unsigned int stride = glyph.rowBytes();
uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
@@ -304,24 +327,24 @@
// Split up our cache texture into lines of certain widths
int nextLine = 0;
- mCacheLines.push(new CacheTextureLine(16, mCacheWidth, nextLine, 0));
+ mCacheLines.push(new CacheTextureLine(mCacheWidth, 16, nextLine, 0));
nextLine += mCacheLines.top()->mMaxHeight;
- mCacheLines.push(new CacheTextureLine(24, mCacheWidth, nextLine, 0));
+ mCacheLines.push(new CacheTextureLine(mCacheWidth, 24, nextLine, 0));
nextLine += mCacheLines.top()->mMaxHeight;
- mCacheLines.push(new CacheTextureLine(32, mCacheWidth, nextLine, 0));
+ mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0));
nextLine += mCacheLines.top()->mMaxHeight;
- mCacheLines.push(new CacheTextureLine(32, mCacheWidth, nextLine, 0));
+ mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0));
nextLine += mCacheLines.top()->mMaxHeight;
- mCacheLines.push(new CacheTextureLine(40, mCacheWidth, nextLine, 0));
+ mCacheLines.push(new CacheTextureLine(mCacheWidth, 40, nextLine, 0));
nextLine += mCacheLines.top()->mMaxHeight;
- mCacheLines.push(new CacheTextureLine(mCacheHeight - nextLine, mCacheWidth, nextLine, 0));
+ mCacheLines.push(new CacheTextureLine(mCacheWidth, mCacheHeight - nextLine, nextLine, 0));
}
// Avoid having to reallocate memory and render quad by quad
void FontRenderer::initVertexArrayBuffers() {
uint32_t numIndicies = mMaxNumberOfQuads * 6;
uint32_t indexBufferSizeBytes = numIndicies * sizeof(uint16_t);
- uint16_t *indexBufferData = (uint16_t*) malloc(indexBufferSizeBytes);
+ uint16_t* indexBufferData = (uint16_t*) malloc(indexBufferSizeBytes);
// Four verts, two triangles , six indices per quad
for (uint32_t i = 0; i < mMaxNumberOfQuads; i++) {
@@ -372,8 +395,8 @@
mUploadTexture = false;
}
- float *vtx = mTextMeshPtr;
- float *tex = vtx + 3;
+ float* vtx = mTextMeshPtr;
+ float* tex = vtx + 3;
// position is slot 0
uint32_t slot = 0;
@@ -396,7 +419,7 @@
const uint32_t vertsPerQuad = 4;
const uint32_t floatsPerVert = 5;
- float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
+ float* currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
(*currentPos++) = x1;
(*currentPos++) = y1;
@@ -434,8 +457,8 @@
mCurrentFont = Font::create(this, fontId, fontSize);
}
-void FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t len,
- uint32_t startIndex, int numGlyphs, int x, int y) {
+void FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
+ uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y) {
checkInit();
if (!mCurrentFont) {
@@ -444,7 +467,7 @@
}
mClip = clip;
- mCurrentFont->renderUTF(paint, text, len, startIndex, numGlyphs, x, y);
+ mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, x, y);
if (mCurrentQuadIndex != 0) {
issueDrawCommand();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 3d4d49c..c1cd7fb 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -27,19 +27,29 @@
#include <GLES2/gl2.h>
#include "Rect.h"
+#include "Properties.h"
namespace android {
namespace uirenderer {
class FontRenderer;
+/**
+ * Represents a font, defined by a Skia font id and a font size. A font is used
+ * to generate glyphs and cache them in the FontState.
+ */
class Font {
public:
~Font();
- void renderUTF(SkPaint* paint, const char *text, uint32_t len, uint32_t start,
+ /**
+ * Renders the specified string of text.
+ */
+ void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
int numGlyphs, int x, int y);
-
+ /**
+ * Creates a new font associated with the specified font state.
+ */
static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
protected:
@@ -90,8 +100,8 @@
void deinit();
void setFont(uint32_t fontId, float fontSize);
- void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t len,
- uint32_t startIndex, int numGlyphs, int x, int y);
+ void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
+ uint32_t len, int numGlyphs, int x, int y);
GLuint getTexture() {
checkInit();
@@ -107,10 +117,12 @@
uint32_t mCurrentRow;
uint32_t mCurrentCol;
- CacheTextureLine(uint16_t maxHeight, uint16_t maxWidth, uint32_t currentRow,
+ CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
uint32_t currentCol):
- mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
- mCurrentCol(currentCol) {
+ mMaxHeight(maxHeight),
+ mMaxWidth(maxWidth),
+ mCurrentRow(currentRow),
+ mCurrentCol(currentCol) {
}
bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 58a3a69..c6a2e33 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -27,6 +27,7 @@
#include <utils/Log.h>
#include "OpenGLRenderer.h"
+#include "Properties.h"
namespace android {
namespace uirenderer {
@@ -35,11 +36,6 @@
// Defines
///////////////////////////////////////////////////////////////////////////////
-// These properties are defined in mega-bytes
-#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
-#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
-#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
-
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
#define DEFAULT_LAYER_CACHE_SIZE 10.0f
#define DEFAULT_PATCH_CACHE_SIZE 100
@@ -555,7 +551,7 @@
const Rect& clip = mSnapshot->getLocalClip();
mFontRenderer.setFont(SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
- mFontRenderer.renderText(paint, &clip, text, count, 0, count, x, y);
+ mFontRenderer.renderText(paint, &clip, text, 0, count, count, x, y);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 6d30282..43e568f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -30,6 +30,7 @@
#include <utils/RefBase.h>
#include <utils/ResourceTypes.h>
+#include "Extensions.h"
#include "Matrix.h"
#include "Program.h"
#include "Rect.h"
@@ -40,7 +41,6 @@
#include "PatchCache.h"
#include "Vertex.h"
#include "FontRenderer.h"
-#include "Extensions.h"
namespace android {
namespace uirenderer {
@@ -362,6 +362,9 @@
float* mShaderPositions;
int mShaderCount;
+ // GL extensions
+ Extensions mExtensions;
+
// Font renderer
FontRenderer mFontRenderer;
@@ -370,8 +373,6 @@
LayerCache mLayerCache;
GradientCache mGradientCache;
PatchCache mPatchCache;
-
- Extensions mExtensions;
}; // class OpenGLRenderer
}; // namespace uirenderer
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
new file mode 100644
index 0000000..4f20a95
--- /dev/null
+++ b/libs/hwui/Properties.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PROPERTIES_H
+#define ANDROID_UI_PROPERTIES_H
+
+/**
+ * This file contains the list of system properties used to configure
+ * the OpenGLRenderer.
+ */
+
+// These properties are defined in mega-bytes
+#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
+#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
+#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
+
+// These properties are defined in pixels
+#define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
+#define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height"
+
+#endif // ANDROID_UI_PROPERTIES_H
+