summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-03-21 01:54:42 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-03-21 01:54:42 +0000
commit9eac52698b18d089e73c7ec2bf73a64a39504733 (patch)
tree5c3668fc72aefd1685d6d7bd5e82547290cce281 /libs
parent7564c716bbee6a4825ae747797068d0e7c370c0d (diff)
parent257ae3502cfad43df681b1783528d645bdabc63f (diff)
downloadframeworks_base-9eac52698b18d089e73c7ec2bf73a64a39504733.zip
frameworks_base-9eac52698b18d089e73c7ec2bf73a64a39504733.tar.gz
frameworks_base-9eac52698b18d089e73c7ec2bf73a64a39504733.tar.bz2
Merge "Optimize text GL setup" into jb-mr2-dev
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/FontRenderer.cpp12
-rw-r--r--libs/hwui/FontRenderer.h15
-rw-r--r--libs/hwui/OpenGLRenderer.cpp114
-rw-r--r--libs/hwui/OpenGLRenderer.h2
4 files changed, 83 insertions, 60 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 009dcb9..26c7e5d 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -21,6 +21,7 @@
#include <cutils/properties.h>
+#include <utils/Functor.h>
#include <utils/Log.h>
#include <RenderScript.h>
@@ -416,6 +417,8 @@ void FontRenderer::issueDrawCommand() {
CacheTexture* texture = mCacheTextures[i];
if (texture->canDraw()) {
if (first) {
+ if (mFunctor) (*mFunctor)(0, NULL);
+
checkTextureUpdate();
caches.bindIndicesBuffer(mIndexBufferID);
@@ -561,11 +564,12 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const ch
return image;
}
-void FontRenderer::initRender(const Rect* clip, Rect* bounds) {
+void FontRenderer::initRender(const Rect* clip, Rect* bounds, Functor* functor) {
checkInit();
mDrawn = false;
mBounds = bounds;
+ mFunctor = functor;
mClip = clip;
}
@@ -583,13 +587,13 @@ void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs, con
bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
- const float* positions, Rect* bounds) {
+ const float* positions, Rect* bounds, Functor* functor) {
if (!mCurrentFont) {
ALOGE("No font set");
return false;
}
- initRender(clip, bounds);
+ initRender(clip, bounds, functor);
mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y, positions);
finishRender();
@@ -604,7 +608,7 @@ bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char
return false;
}
- initRender(clip, bounds);
+ initRender(clip, bounds, NULL);
mCurrentFont->render(paint, text, startIndex, len, numGlyphs, path, hOffset, vOffset);
finishRender();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 080cc71..1da3b6c 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -38,6 +38,8 @@ namespace RSC {
class ScriptIntrinsicBlur;
}
+class Functor;
+
namespace android {
namespace uirenderer {
@@ -62,7 +64,8 @@ public:
// bounds is an out parameter
bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
- uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds);
+ uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds,
+ Functor* functor);
// bounds is an out parameter
bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds);
@@ -88,13 +91,8 @@ public:
DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
- GLuint getTexture(bool linearFiltering = false) {
- checkInit();
-
- mCurrentCacheTexture->setLinearFiltering(linearFiltering);
+ void setTextureFiltering(bool linearFiltering) {
mLinearFiltering = linearFiltering;
-
- return mCurrentCacheTexture->getTextureId();
}
uint32_t getCacheSize() const {
@@ -125,7 +123,7 @@ private:
void initVertexArrayBuffers();
void checkInit();
- void initRender(const Rect* clip, Rect* bounds);
+ void initRender(const Rect* clip, Rect* bounds, Functor* functor);
void finishRender();
void issueDrawCommand();
@@ -167,6 +165,7 @@ private:
uint32_t mMaxNumberOfQuads;
uint32_t mIndexBufferID;
+ Functor* mFunctor;
const Rect* mClip;
Rect* mBounds;
bool mDrawn;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index a78a035..bc28d65 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1752,7 +1752,7 @@ void OpenGLRenderer::setupDrawSimpleMesh() {
}
void OpenGLRenderer::setupDrawTexture(GLuint texture) {
- bindTexture(texture);
+ if (texture) bindTexture(texture);
mTextureUnit++;
mCaches.enableTexCoordsVertexArray();
}
@@ -2411,7 +2411,8 @@ status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* tex
status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* p) {
- if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
+ if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+ (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
return DrawGlInfo::kStatusDone;
}
@@ -2436,7 +2437,8 @@ status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float
status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) {
if (mSnapshot->isIgnored() || quickRejectPreStroke(x - radius, y - radius,
- x + radius, y + radius, p)) {
+ x + radius, y + radius, p) ||
+ (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
return DrawGlInfo::kStatusDone;
}
if (p->getPathEffect() != 0) {
@@ -2456,7 +2458,8 @@ status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p)
status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
SkPaint* p) {
- if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
+ if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+ (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
return DrawGlInfo::kStatusDone;
}
@@ -2477,7 +2480,8 @@ status_t OpenGLRenderer::drawOval(float left, float top, float right, float bott
status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
- if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
+ if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+ (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
return DrawGlInfo::kStatusDone;
}
@@ -2513,7 +2517,8 @@ status_t OpenGLRenderer::drawArc(float left, float top, float right, float botto
#define SkPaintDefaults_MiterLimit SkIntToScalar(4)
status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
- if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
+ if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+ (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
return DrawGlInfo::kStatusDone;
}
@@ -2589,6 +2594,48 @@ bool OpenGLRenderer::canSkipText(const SkPaint* paint) const {
return alpha == 0.0f && getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
}
+class TextSetupFunctor: public Functor {
+public:
+ TextSetupFunctor(OpenGLRenderer& renderer, float x, float y, bool pureTranslate,
+ int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
+ renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
+ alpha(alpha), mode(mode), paint(paint) {
+ }
+ ~TextSetupFunctor() { }
+
+ status_t operator ()(int what, void* data) {
+ renderer.setupDraw();
+ renderer.setupDrawTextGamma(paint);
+ renderer.setupDrawDirtyRegionsDisabled();
+ renderer.setupDrawWithTexture(true);
+ renderer.setupDrawAlpha8Color(paint->getColor(), alpha);
+ renderer.setupDrawColorFilter();
+ renderer.setupDrawShader();
+ renderer.setupDrawBlending(true, mode);
+ renderer.setupDrawProgram();
+ renderer.setupDrawModelView(x, y, x, y, pureTranslate, true);
+ // Calling setupDrawTexture with the name 0 will enable the
+ // uv attributes and increase the texture unit count
+ // texture binding will be performed by the font renderer as
+ // needed
+ renderer.setupDrawTexture(0);
+ renderer.setupDrawPureColorUniforms();
+ renderer.setupDrawColorFilterUniforms();
+ renderer.setupDrawShaderUniforms(pureTranslate);
+ renderer.setupDrawTextGammaUniforms();
+
+ return NO_ERROR;
+ }
+
+ OpenGLRenderer& renderer;
+ float x;
+ float y;
+ bool pureTranslate;
+ int alpha;
+ SkXfermode::Mode mode;
+ SkPaint* paint;
+};
+
status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
@@ -2625,31 +2672,16 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
if (pureTranslate && !linearFilter) {
linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
}
-
- mCaches.activeTexture(0);
- setupDraw();
- setupDrawTextGamma(paint);
- setupDrawDirtyRegionsDisabled();
- setupDrawWithTexture(true);
- setupDrawAlpha8Color(paint->getColor(), alpha);
- setupDrawColorFilter();
- setupDrawShader();
- setupDrawBlending(true, mode);
- setupDrawProgram();
- setupDrawModelView(x, y, x, y, pureTranslate, true);
- setupDrawTexture(fontRenderer.getTexture(linearFilter));
- setupDrawPureColorUniforms();
- setupDrawColorFilterUniforms();
- setupDrawShaderUniforms(pureTranslate);
- setupDrawTextGammaUniforms();
+ fontRenderer.setTextureFiltering(linearFilter);
const Rect* clip = pureTranslate ? mSnapshot->clipRect : &mSnapshot->getLocalClip();
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
const bool hasActiveLayer = hasLayer();
+ TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL)) {
+ positions, hasActiveLayer ? &bounds : NULL, &functor)) {
if (hasActiveLayer) {
if (!pureTranslate) {
currentTransform().mapRect(bounds);
@@ -2742,40 +2774,22 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
// Pick the appropriate texture filtering
bool linearFilter = !pureTranslate || fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
-
- // The font renderer will always use texture unit 0
- mCaches.activeTexture(0);
- setupDraw();
- setupDrawTextGamma(paint);
- setupDrawDirtyRegionsDisabled();
- setupDrawWithTexture(true);
- setupDrawAlpha8Color(paint->getColor(), alpha);
- setupDrawColorFilter();
- setupDrawShader();
- setupDrawBlending(true, mode);
- setupDrawProgram();
- setupDrawModelView(x, y, x, y, pureTranslate, true);
- // See comment above; the font renderer must use texture unit 0
- // assert(mTextureUnit == 0)
- setupDrawTexture(fontRenderer.getTexture(linearFilter));
- setupDrawPureColorUniforms();
- setupDrawColorFilterUniforms();
- setupDrawShaderUniforms(pureTranslate);
- setupDrawTextGammaUniforms();
+ fontRenderer.setTextureFiltering(linearFilter);
// TODO: Implement better clipping for scaled/rotated text
const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
bool status;
+ TextSetupFunctor functor(*this, x, y, pureTranslate, alpha, mode, paint);
if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
SkPaint paintCopy(*paint);
paintCopy.setTextAlign(SkPaint::kLeft_Align);
status = fontRenderer.renderPosText(&paintCopy, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL);
+ positions, hasActiveLayer ? &bounds : NULL, &functor);
} else {
status = fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
- positions, hasActiveLayer ? &bounds : NULL);
+ positions, hasActiveLayer ? &bounds : NULL, &functor);
}
if (status && hasActiveLayer) {
@@ -2798,12 +2812,12 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co
FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
fontRenderer.setFont(paint, mat4::identity());
+ fontRenderer.setTextureFiltering(true);
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
- mCaches.activeTexture(0);
setupDraw();
setupDrawTextGamma(paint);
setupDrawDirtyRegionsDisabled();
@@ -2814,7 +2828,11 @@ status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int co
setupDrawBlending(true, mode);
setupDrawProgram();
setupDrawModelView(0.0f, 0.0f, 0.0f, 0.0f, false, true);
- setupDrawTexture(fontRenderer.getTexture(true));
+ // Calling setupDrawTexture with the name 0 will enable the
+ // uv attributes and increase the texture unit count
+ // texture binding will be performed by the font renderer as
+ // needed
+ setupDrawTexture(0);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawShaderUniforms(false);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 01fcfc6..71bd6bb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -85,6 +85,7 @@ struct DeferredDisplayState {
///////////////////////////////////////////////////////////////////////////////
class DisplayList;
+class TextSetupFunctor;
class VertexBuffer;
/**
@@ -995,6 +996,7 @@ private:
String8 mName;
friend class DisplayListRenderer;
+ friend class TextSetupFunctor;
}; // class OpenGLRenderer