Optimize away unnecessary state changes
Change-Id: I0f6816f9f6234853575ecee5033186ad19e76380
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index a8ae5c6..ee6ef1a 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -147,12 +147,12 @@
this->renderTarget = renderTarget;
}
- void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false) {
- texture.setWrap(wrapS, wrapT, bindTexture, force, renderTarget);
+ void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
+ texture.setWrap(wrap, bindTexture, force, renderTarget);
}
- void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false) {
- texture.setFilter(min, mag,bindTexture, force, renderTarget);
+ void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
+ texture.setFilter(filter, bindTexture, force, renderTarget);
}
inline bool isCacheable() {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e38b479..6bf6004 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -294,8 +294,8 @@
if (renderTarget != layer->getRenderTarget()) {
layer->setRenderTarget(renderTarget);
layer->bindTexture();
- layer->setFilter(GL_NEAREST, GL_NEAREST, false, true);
- layer->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, false, true);
+ layer->setFilter(GL_NEAREST, false, true);
+ layer->setWrap(GL_CLAMP_TO_EDGE, false, true);
}
}
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 718c131..3c838fc 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -47,6 +47,8 @@
// TODO: This should be set in properties
#define ALPHA_THRESHOLD (0x7f / PANEL_BIT_DEPTH)
+#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
+
///////////////////////////////////////////////////////////////////////////////
// Globals
///////////////////////////////////////////////////////////////////////////////
@@ -665,10 +667,10 @@
const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
- layer->setFilter(GL_NEAREST, GL_NEAREST);
+ layer->setFilter(GL_NEAREST);
setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
} else {
- layer->setFilter(GL_LINEAR, GL_LINEAR);
+ layer->setFilter(GL_LINEAR);
setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom);
}
setupDrawTextureTransformUniforms(layer->getTexTransform());
@@ -702,9 +704,9 @@
y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
}
- layer->setFilter(GL_NEAREST, GL_NEAREST, true);
+ layer->setFilter(GL_NEAREST, true);
} else {
- layer->setFilter(GL_LINEAR, GL_LINEAR, true);
+ layer->setFilter(GL_LINEAR, true);
}
drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
@@ -760,10 +762,10 @@
const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
- layer->setFilter(GL_NEAREST, GL_NEAREST);
+ layer->setFilter(GL_NEAREST);
setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
} else {
- layer->setFilter(GL_LINEAR, GL_LINEAR);
+ layer->setFilter(GL_LINEAR);
setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
}
setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]);
@@ -1320,6 +1322,8 @@
y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
ignoreTransform = true;
filter = GL_NEAREST;
+ } else {
+ filter = FILTER(paint);
}
setupDraw();
@@ -1334,8 +1338,8 @@
setupDrawModelView(x, y, x + texture->width, y + texture->height, ignoreTransform);
setupDrawTexture(texture->id);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
- texture->setFilter(filter, filter);
+ texture->setWrap(GL_CLAMP_TO_EDGE);
+ texture->setFilter(filter);
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
@@ -1401,8 +1405,8 @@
if (!texture) return;
const AutoTexture autoCleanup(texture);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
- texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+ texture->setWrap(GL_CLAMP_TO_EDGE, true);
+ texture->setFilter(FILTER(paint), true);
int alpha;
SkXfermode::Mode mode;
@@ -1485,7 +1489,6 @@
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
const float width = texture->width;
const float height = texture->height;
@@ -1502,6 +1505,8 @@
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
+ texture->setWrap(GL_CLAMP_TO_EDGE, true);
+
if (mSnapshot->transform->isPureTranslate()) {
const float x = (int) floorf(dstLeft + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(dstTop + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -1509,17 +1514,16 @@
GLenum filter = GL_NEAREST;
// Enable linear filtering if the source rectangle is scaled
if (srcRight - srcLeft != dstRight - dstLeft || srcBottom - srcTop != dstBottom - dstTop) {
- filter = GL_LINEAR;
+ filter = FILTER(paint);
}
- texture->setFilter(filter, filter, true);
+ texture->setFilter(filter, true);
drawTextureMesh(x, y, x + (dstRight - dstLeft), y + (dstBottom - dstTop),
texture->id, alpha / 255.0f, mode, texture->blend,
&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
GL_TRIANGLE_STRIP, gMeshCount, false, true);
} else {
- texture->setFilter(GL_LINEAR, GL_LINEAR, true);
-
+ texture->setFilter(FILTER(paint), true);
drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f,
mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
GL_TRIANGLE_STRIP, gMeshCount);
@@ -1539,8 +1543,8 @@
Texture* texture = mCaches.textureCache.get(bitmap);
if (!texture) return;
const AutoTexture autoCleanup(texture);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
- texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+ texture->setWrap(GL_CLAMP_TO_EDGE, true);
+ texture->setFilter(GL_LINEAR, true);
int alpha;
SkXfermode::Mode mode;
@@ -2250,11 +2254,11 @@
x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
- layer->setFilter(GL_NEAREST, GL_NEAREST);
+ layer->setFilter(GL_NEAREST);
setupDrawModelViewTranslate(x, y,
x + layer->layer.getWidth(), y + layer->layer.getHeight(), true);
} else {
- layer->setFilter(GL_LINEAR, GL_LINEAR);
+ layer->setFilter(GL_LINEAR);
setupDrawModelViewTranslate(x, y,
x + layer->layer.getWidth(), y + layer->layer.getHeight());
}
@@ -2447,18 +2451,18 @@
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
+ texture->setWrap(GL_CLAMP_TO_EDGE, true);
if (mSnapshot->transform->isPureTranslate()) {
const float x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
- texture->setFilter(GL_NEAREST, GL_NEAREST, true);
+ texture->setFilter(GL_NEAREST, true);
drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL,
(GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, false, true);
} else {
- texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+ texture->setFilter(FILTER(paint), true);
drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
GL_TRIANGLE_STRIP, gMeshCount);
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index 0660b69..8b88d30 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -584,8 +584,8 @@
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
- texture->setFilter(GL_LINEAR, GL_LINEAR);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ texture->setFilter(GL_LINEAR);
+ texture->setWrap(GL_CLAMP_TO_EDGE);
}
}; // namespace uirenderer
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 2428295..32e7533 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -77,7 +77,7 @@
void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) {
glBindTexture(GL_TEXTURE_2D, texture->id);
- texture->setWrap(wrapS, wrapT);
+ texture->setWrapST(wrapS, wrapT);
}
void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
@@ -148,7 +148,7 @@
// ::updateTransforms() but we don't have the texture object
// available at that point. The optimization is not worth the
// effort for now.
- texture->setFilter(GL_LINEAR, GL_LINEAR);
+ texture->setFilter(GL_LINEAR);
glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 48229b6..a4aed07 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -40,7 +40,12 @@
firstWrap = true;
}
- void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false,
+ void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
+ GLenum renderTarget = GL_TEXTURE_2D) {
+ setWrapST(wrap, wrap, bindTexture, force, renderTarget);
+ }
+
+ void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
if (firstWrap || force || wrapS != this->wrapS || wrapT != this->wrapT) {
@@ -58,7 +63,12 @@
}
}
- void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false,
+ void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
+ GLenum renderTarget = GL_TEXTURE_2D) {
+ setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
+ }
+
+ void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, bool force = false,
GLenum renderTarget = GL_TEXTURE_2D) {
if (firstFilter || force || min != minFilter || mag != magFilter) {
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 018ce3e..711277a 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -217,11 +217,15 @@
texture->height = bitmap->height();
glBindTexture(GL_TEXTURE_2D, texture->id);
- glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
+ if (!regenerate) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
+ }
switch (bitmap->getConfig()) {
case SkBitmap::kA8_Config:
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ if (!regenerate) {
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ }
uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_BYTE, bitmap->getPixels());
texture->blend = true;
@@ -248,8 +252,10 @@
break;
}
- texture->setFilter(GL_LINEAR, GL_LINEAR);
- texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ if (!regenerate) {
+ texture->setFilter(GL_NEAREST);
+ texture->setWrap(GL_CLAMP_TO_EDGE);
+ }
}
void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,