summaryrefslogtreecommitdiff
path: root/libs/hwui/OpenGLRenderer.cpp
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2013-03-20 16:31:12 -0700
committer Romain Guy <romainguy@google.com> 2013-03-20 16:35:05 -0700
commit257ae3502cfad43df681b1783528d645bdabc63f (patch)
treee257e21ddf04c544b0dbb6467d2d10a7c659ac1d /libs/hwui/OpenGLRenderer.cpp
parent10c4d99f04a399c78529d0ae66c1785b26a125c3 (diff)
Optimize text GL setup
Only performs the GL setup steps when at least one glyph is drawn. This change also skips various draw operations when the specified paint draws with alpha = 0. Change-Id: I9eda148b0503acffc552ee19196f5d52e958a1a2
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp114
1 files changed, 66 insertions, 48 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 8030d6672851..e7dfa666e2ab 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1726,7 +1726,7 @@ void OpenGLRenderer::setupDrawSimpleMesh() {
}
void OpenGLRenderer::setupDrawTexture(GLuint texture) {
- bindTexture(texture);
+ if (texture) bindTexture(texture);
mTextureUnit++;
mCaches.enableTexCoordsVertexArray();
}
@@ -2385,7 +2385,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;
}
@@ -2410,7 +2411,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) {
@@ -2430,7 +2432,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;
}
@@ -2451,7 +2454,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;
}
@@ -2487,7 +2491,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;
}
@@ -2563,6 +2568,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)) {
@@ -2599,31 +2646,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);
@@ -2716,40 +2748,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) {
@@ -2772,12 +2786,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();
@@ -2788,7 +2802,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);