Reduce the number of GL commands generated by the UI
This optimization along with the previous one lets us render an
application like Gmail using only 30% of the number of GL commands
previously required
Change-Id: Ifee63edaf495e04490b5abd5433bb9a07bc327a8
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index fcac053..59d3fcc 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -144,6 +144,7 @@
glDisable(GL_DITHER);
glEnable(GL_SCISSOR_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
glEnableVertexAttribArray(Program::kBindingPosition);
}
@@ -199,7 +200,9 @@
}
}
mCaches.unbindMeshBuffer();
+ mCaches.unbindIndicesBuffer();
mCaches.resetVertexPointers();
+ mCaches.disbaleTexCoordsVertexArray();
}
void OpenGLRenderer::resume() {
@@ -212,7 +215,6 @@
dirtyClip();
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
mCaches.blend = true;
glEnable(GL_BLEND);
@@ -771,7 +773,7 @@
layer->setFilter(GL_LINEAR);
setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
}
- setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]);
+ setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
for (size_t i = 0; i < count; i++) {
const android::Rect* r = &rects[i];
@@ -800,7 +802,6 @@
glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, NULL);
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
finishDrawTexture();
#if DEBUG_LAYERS_AS_REGIONS
@@ -1015,7 +1016,6 @@
mColorA = mColorR = mColorG = mColorB = 0.0f;
mTextureUnit = 0;
mTrackDirtyRegions = true;
- mTexCoordsSlot = -1;
}
void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
@@ -1027,6 +1027,10 @@
mDescription.hasExternalTexture = true;
}
+void OpenGLRenderer::setupDrawNoTexture() {
+ mCaches.disbaleTexCoordsVertexArray();
+}
+
void OpenGLRenderer::setupDrawAALine() {
mDescription.isAA = true;
}
@@ -1203,22 +1207,19 @@
void OpenGLRenderer::setupDrawSimpleMesh() {
bool force = mCaches.bindMeshBuffer();
mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, 0);
+ mCaches.unbindIndicesBuffer();
}
void OpenGLRenderer::setupDrawTexture(GLuint texture) {
bindTexture(texture);
glUniform1i(mCaches.currentProgram->getUniform("sampler"), mTextureUnit++);
-
- mTexCoordsSlot = mCaches.currentProgram->texCoords;
- glEnableVertexAttribArray(mTexCoordsSlot);
+ mCaches.enableTexCoordsVertexArray();
}
void OpenGLRenderer::setupDrawExternalTexture(GLuint texture) {
bindExternalTexture(texture);
glUniform1i(mCaches.currentProgram->getUniform("sampler"), mTextureUnit++);
-
- mTexCoordsSlot = mCaches.currentProgram->texCoords;
- glEnableVertexAttribArray(mTexCoordsSlot);
+ mCaches.enableTexCoordsVertexArray();
}
void OpenGLRenderer::setupDrawTextureTransform() {
@@ -1239,8 +1240,18 @@
}
mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, vertices);
- if (mTexCoordsSlot >= 0) {
- mCaches.bindTexCoordsVertexPointer(force, mTexCoordsSlot, texCoords);
+ if (mCaches.currentProgram->texCoords >= 0) {
+ mCaches.bindTexCoordsVertexPointer(force, mCaches.currentProgram->texCoords, texCoords);
+ }
+
+ mCaches.unbindIndicesBuffer();
+}
+
+void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords) {
+ bool force = mCaches.unbindMeshBuffer();
+ mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, vertices);
+ if (mCaches.currentProgram->texCoords >= 0) {
+ mCaches.bindTexCoordsVertexPointer(force, mCaches.currentProgram->texCoords, texCoords);
}
}
@@ -1248,6 +1259,7 @@
bool force = mCaches.unbindMeshBuffer();
mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position,
vertices, gVertexStride);
+ mCaches.unbindIndicesBuffer();
}
/**
@@ -1267,6 +1279,7 @@
mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position,
vertices, gAAVertexStride);
mCaches.resetTexCoordsVertexPointer();
+ mCaches.unbindIndicesBuffer();
int widthSlot = mCaches.currentProgram->getAttrib("vtxWidth");
glEnableVertexAttribArray(widthSlot);
@@ -1285,7 +1298,6 @@
}
void OpenGLRenderer::finishDrawTexture() {
- glDisableVertexAttribArray(mTexCoordsSlot);
}
///////////////////////////////////////////////////////////////////////////////
@@ -1624,6 +1636,7 @@
}
setupDraw();
+ setupDrawNoTexture();
setupDrawAALine();
setupDrawColor(color);
setupDrawColorFilter();
@@ -1734,6 +1747,7 @@
getAlphaAndMode(paint, &alpha, &mode);
setupDraw();
+ setupDrawNoTexture();
if (isAA) {
setupDrawAALine();
}
@@ -1943,6 +1957,7 @@
TextureVertex* vertex = &pointsData[0];
setupDraw();
+ setupDrawNoTexture();
setupDrawPoint(strokeWidth);
setupDrawColor(paint->getColor(), alpha);
setupDrawColorFilter();
@@ -2186,13 +2201,6 @@
bool hasActiveLayer = false;
#endif
- float* buffer = fontRenderer.getMeshBuffer();
- int offset = fontRenderer.getMeshTexCoordsOffset();
-
- bool force = mCaches.unbindMeshBuffer();
- mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, buffer);
- mCaches.bindTexCoordsVertexPointer(force, mTexCoordsSlot, buffer + offset);
-
if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y,
hasActiveLayer ? &bounds : NULL)) {
#if RENDER_LAYERS_AS_REGIONS
@@ -2205,9 +2213,6 @@
#endif
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glDisableVertexAttribArray(mCaches.currentProgram->texCoords);
-
drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
}
@@ -2437,6 +2442,7 @@
}
setupDraw();
+ setupDrawNoTexture();
setupDrawColor(color);
setupDrawShader();
setupDrawColorFilter();