summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arun <arun.demeure@imgtec.com> 2017-01-23 11:41:06 +0000
committer John Reck <jreck@google.com> 2017-05-05 15:11:27 +0000
commitb0a9477c8e07d4530f07c78a5d20b4cde0fe8d60 (patch)
treed5216a2fa307a657f2601057f49459b260449cee
parentcba224e83385c5141c9dfbf9f8cfee2d7fc83f31 (diff)
Reduce hwui CPU time by using glDrawRangeElements
The CPU overhead of glDrawElements in the GPU driver is significant with client-side vertex data (unique per draw call) as the driver has to calculate the mininimum and maximum indices from the index buffer in order to evaluate the range of vertex data required. This can be avoided by keeping track of the min-max in hwui and passing it with glDrawRangeElements. This requires OpenGL ES3.0 support (which is already checked for elsewhere in hwui). Test: manual - visual inspection on fugu (nexus player) Change-Id: I57bb1ddd239a1032f74f1cd2683bbe0970e84bd9
-rw-r--r--libs/hwui/Glop.h1
-rw-r--r--libs/hwui/GlopBuilder.cpp1
-rw-r--r--libs/hwui/renderstate/RenderState.cpp16
3 files changed, 15 insertions, 3 deletions
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 6433c86908e7..b95fd6311636 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -112,6 +112,7 @@ public:
} vertices;
int elementCount;
+ int vertexCount; // only used for meshes (for glDrawRangeElements)
TextureVertex mappedVertices[4];
} mesh;
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index e502725ddb09..8fcd1ea1f9fc 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -210,6 +210,7 @@ GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer)
alphaVertex ? kAlphaVertexStride : kVertexStride };
mOutGlop->mesh.elementCount = indices
? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount();
+ mOutGlop->mesh.vertexCount = vertexBuffer.getVertexCount(); // used for glDrawRangeElements()
return *this;
}
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 5e600644ca19..c4e8e4f2df6e 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -364,18 +364,28 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) {
const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position);
while (elementsCount > 0) {
GLsizei drawCount = std::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6);
+ GLsizei vertexCount = (drawCount / 6) * 4;
meshState().bindPositionVertexPointer(vertexData, vertices.stride);
if (vertices.attribFlags & VertexAttribFlags::TextureCoord) {
meshState().bindTexCoordsVertexPointer(
vertexData + kMeshTextureOffset, vertices.stride);
}
- glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr);
+ if (mCaches->extensions().getMajorGlVersion() >= 3) {
+ glDrawRangeElements(mesh.primitiveMode, 0, vertexCount-1, drawCount, GL_UNSIGNED_SHORT, nullptr);
+ } else {
+ glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr);
+ }
elementsCount -= drawCount;
- vertexData += (drawCount / 6) * 4 * vertices.stride;
+ vertexData += vertexCount * vertices.stride;
}
} else if (indices.bufferObject || indices.indices) {
- glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices);
+ if (mCaches->extensions().getMajorGlVersion() >= 3) {
+ // use glDrawRangeElements to reduce CPU overhead (otherwise the driver has to determine the min/max index values)
+ glDrawRangeElements(mesh.primitiveMode, 0, mesh.vertexCount-1, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices);
+ } else {
+ glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices);
+ }
} else {
glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount);
}