summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2011-12-13 13:11:32 -0800
committer Romain Guy <romainguy@google.com> 2011-12-13 13:11:32 -0800
commit15bc6437f8b4cf10dba55c7638d349e7b9563f4f (patch)
tree18e054e26a43a757fec54387571ae2d1aadbea1c
parent5009f65c9a676b64869e638e08ec0294e20d7e6e (diff)
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
-rw-r--r--libs/hwui/Caches.cpp39
-rw-r--r--libs/hwui/Caches.h9
-rw-r--r--libs/hwui/FontRenderer.cpp17
-rw-r--r--libs/hwui/FontRenderer.h9
-rw-r--r--libs/hwui/OpenGLRenderer.cpp52
-rw-r--r--libs/hwui/OpenGLRenderer.h4
6 files changed, 91 insertions, 39 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 4da576d51fa0..27039dd04311 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -73,9 +73,12 @@ void Caches::init() {
glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW);
mCurrentBuffer = meshBuffer;
+ mCurrentIndicesBuffer = 0;
mCurrentPositionPointer = this;
mCurrentTexCoordsPointer = this;
+ mTexCoordsArrayEnabled = false;
+
mRegionMesh = NULL;
blend = false;
@@ -243,6 +246,24 @@ bool Caches::unbindMeshBuffer() {
return false;
}
+bool Caches::bindIndicesBuffer(const GLuint buffer) {
+ if (mCurrentIndicesBuffer != buffer) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
+ mCurrentIndicesBuffer = buffer;
+ return true;
+ }
+ return false;
+}
+
+bool Caches::unbindIndicesBuffer() {
+ if (mCurrentIndicesBuffer) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ mCurrentIndicesBuffer = 0;
+ return true;
+ }
+ return false;
+}
+
void Caches::bindPositionVertexPointer(bool force, GLuint slot, GLvoid* vertices, GLsizei stride) {
if (force || vertices != mCurrentPositionPointer) {
glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
@@ -266,6 +287,20 @@ void Caches::resetTexCoordsVertexPointer() {
mCurrentTexCoordsPointer = this;
}
+void Caches::enableTexCoordsVertexArray() {
+ if (!mTexCoordsArrayEnabled) {
+ glEnableVertexAttribArray(Program::kBindingTexCoords);
+ mTexCoordsArrayEnabled = true;
+ }
+}
+
+void Caches::disbaleTexCoordsVertexArray() {
+ if (mTexCoordsArrayEnabled) {
+ glDisableVertexAttribArray(Program::kBindingTexCoords);
+ mTexCoordsArrayEnabled = false;
+ }
+}
+
TextureVertex* Caches::getRegionMesh() {
// Create the mesh, 2 triangles and 4 vertices per rectangle in the region
if (!mRegionMesh) {
@@ -284,13 +319,13 @@ TextureVertex* Caches::getRegionMesh() {
}
glGenBuffers(1, &mRegionMeshIndices);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
+ bindIndicesBuffer(mRegionMeshIndices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
regionIndices, GL_STATIC_DRAW);
delete[] regionIndices;
} else {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
+ bindIndicesBuffer(mRegionMeshIndices);
}
return mRegionMesh;
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 7ca198ad0090..61435932125e 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -150,6 +150,9 @@ public:
*/
bool unbindMeshBuffer();
+ bool bindIndicesBuffer(const GLuint buffer);
+ bool unbindIndicesBuffer();
+
/**
* Binds an attrib to the specified float vertex pointer.
* Assumes a stride of gMeshStride and a size of 2.
@@ -169,6 +172,9 @@ public:
void resetVertexPointers();
void resetTexCoordsVertexPointer();
+ void enableTexCoordsVertexArray();
+ void disbaleTexCoordsVertexArray();
+
/**
* Returns the mesh used to draw regions. Calling this method will
* bind a VBO of type GL_ELEMENT_ARRAY_BUFFER that contains the
@@ -214,9 +220,12 @@ public:
private:
GLuint mCurrentBuffer;
+ GLuint mCurrentIndicesBuffer;
void* mCurrentPositionPointer;
void* mCurrentTexCoordsPointer;
+ bool mTexCoordsArrayEnabled;
+
// Used to render layers
TextureVertex* mRegionMesh;
GLuint mRegionMeshIndices;
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index f04ea6f3cfb4..102aea69f748 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -22,6 +22,7 @@
#include <utils/Log.h>
+#include "Caches.h"
#include "Debug.h"
#include "FontRenderer.h"
@@ -536,9 +537,8 @@ void FontRenderer::initVertexArrayBuffers() {
}
glGenBuffers(1, &mIndexBufferID);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferID);
+ Caches::getInstance().bindIndicesBuffer(mIndexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeBytes, indexBufferData, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
free(indexBufferData);
@@ -597,7 +597,18 @@ void FontRenderer::checkTextureUpdate() {
void FontRenderer::issueDrawCommand() {
checkTextureUpdate();
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferID);
+ Caches& caches = Caches::getInstance();
+ if (!mDrawn) {
+ float* buffer = mTextMeshPtr;
+ int offset = 2;
+
+ bool force = caches.unbindMeshBuffer();
+ caches.bindPositionVertexPointer(force, caches.currentProgram->position, buffer);
+ caches.bindTexCoordsVertexPointer(force, caches.currentProgram->texCoords,
+ buffer + offset);
+ }
+
+ caches.bindIndicesBuffer(mIndexBufferID);
glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, NULL);
mDrawn = true;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index f945873ea962..2a5a78869f3d 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -178,15 +178,6 @@ public:
mGammaTable = gammaTable;
}
- inline float* getMeshBuffer() {
- checkInit();
- return mTextMeshPtr;
- }
-
- inline int getMeshTexCoordsOffset() const {
- return 2;
- }
-
void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index fcac053be110..59d3fcc2b0f6 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -144,6 +144,7 @@ void OpenGLRenderer::setViewport(int width, int height) {
glDisable(GL_DITHER);
glEnable(GL_SCISSOR_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
glEnableVertexAttribArray(Program::kBindingPosition);
}
@@ -199,7 +200,9 @@ void OpenGLRenderer::interrupt() {
}
}
mCaches.unbindMeshBuffer();
+ mCaches.unbindIndicesBuffer();
mCaches.resetVertexPointers();
+ mCaches.disbaleTexCoordsVertexArray();
}
void OpenGLRenderer::resume() {
@@ -212,7 +215,6 @@ void OpenGLRenderer::resume() {
dirtyClip();
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
mCaches.blend = true;
glEnable(GL_BLEND);
@@ -771,7 +773,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
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 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
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 @@ void OpenGLRenderer::setupDraw(bool clear) {
mColorA = mColorR = mColorG = mColorB = 0.0f;
mTextureUnit = 0;
mTrackDirtyRegions = true;
- mTexCoordsSlot = -1;
}
void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
@@ -1027,6 +1027,10 @@ void OpenGLRenderer::setupDrawWithExternalTexture() {
mDescription.hasExternalTexture = true;
}
+void OpenGLRenderer::setupDrawNoTexture() {
+ mCaches.disbaleTexCoordsVertexArray();
+}
+
void OpenGLRenderer::setupDrawAALine() {
mDescription.isAA = true;
}
@@ -1203,22 +1207,19 @@ void OpenGLRenderer::setupDrawColorFilterUniforms() {
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 @@ void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint v
}
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 @@ void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) {
bool force = mCaches.unbindMeshBuffer();
mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position,
vertices, gVertexStride);
+ mCaches.unbindIndicesBuffer();
}
/**
@@ -1267,6 +1279,7 @@ void OpenGLRenderer::setupDrawAALine(GLvoid* vertices, GLvoid* widthCoords,
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::setupDrawAALine(GLvoid* vertices, GLvoid* widthCoords,
}
void OpenGLRenderer::finishDrawTexture() {
- glDisableVertexAttribArray(mTexCoordsSlot);
}
///////////////////////////////////////////////////////////////////////////////
@@ -1624,6 +1636,7 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom
}
setupDraw();
+ setupDrawNoTexture();
setupDrawAALine();
setupDrawColor(color);
setupDrawColorFilter();
@@ -1734,6 +1747,7 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
getAlphaAndMode(paint, &alpha, &mode);
setupDraw();
+ setupDrawNoTexture();
if (isAA) {
setupDrawAALine();
}
@@ -1943,6 +1957,7 @@ void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
TextureVertex* vertex = &pointsData[0];
setupDraw();
+ setupDrawNoTexture();
setupDrawPoint(strokeWidth);
setupDrawColor(paint->getColor(), alpha);
setupDrawColorFilter();
@@ -2186,13 +2201,6 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
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 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
#endif
}
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glDisableVertexAttribArray(mCaches.currentProgram->texCoords);
-
drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
}
@@ -2437,6 +2442,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
}
setupDraw();
+ setupDrawNoTexture();
setupDrawColor(color);
setupDrawShader();
setupDrawColorFilter();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index cd9ff936f4f1..019e9b28b434 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -498,6 +498,7 @@ private:
*/
void setupDrawWithTexture(bool isAlpha8 = false);
void setupDrawWithExternalTexture();
+ void setupDrawNoTexture();
void setupDrawAALine();
void setupDrawPoint(float pointSize);
void setupDrawColor(int color);
@@ -530,6 +531,7 @@ private:
void setupDrawTextureTransform();
void setupDrawTextureTransformUniforms(mat4& transform);
void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
+ void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords);
void setupDrawVertices(GLvoid* vertices);
void setupDrawAALine(GLvoid* vertices, GLvoid* distanceCoords, GLvoid* lengthCoords,
float strokeWidth);
@@ -601,8 +603,6 @@ private:
GLuint mTextureUnit;
// Track dirty regions, true by default
bool mTrackDirtyRegions;
- // Texture coordinates slot
- int mTexCoordsSlot;
friend class DisplayListRenderer;