summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-07-22 22:16:03 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-07-22 22:16:03 +0000
commit03903b3bc8fb592884421c2a5f8c6266ff2b4881 (patch)
treeff66d20e6583f40f9d587d45d225bf6601dcf98c
parent6944165014bf026e24aafe0cb359d7aad66bea7b (diff)
parent448455fe783b0a711340322dca272b8cc0ebe473 (diff)
downloadframeworks_base-03903b3bc8fb592884421c2a5f8c6266ff2b4881.zip
frameworks_base-03903b3bc8fb592884421c2a5f8c6266ff2b4881.tar.gz
frameworks_base-03903b3bc8fb592884421c2a5f8c6266ff2b4881.tar.bz2
Merge "Use global indices array to draw layers"
-rw-r--r--libs/hwui/Layer.cpp2
-rw-r--r--libs/hwui/Layer.h1
-rw-r--r--libs/hwui/LayerRenderer.cpp21
-rw-r--r--libs/hwui/OpenGLRenderer.cpp68
-rw-r--r--libs/hwui/OpenGLRenderer.h9
5 files changed, 54 insertions, 47 deletions
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 73082c1..bd371a3 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -31,7 +31,6 @@ namespace uirenderer {
Layer::Layer(const uint32_t layerWidth, const uint32_t layerHeight):
caches(Caches::getInstance()), texture(caches) {
mesh = NULL;
- meshIndices = NULL;
meshElementCount = 0;
cacheable = true;
dirty = false;
@@ -57,7 +56,6 @@ Layer::~Layer() {
deleteTexture();
delete[] mesh;
- delete[] meshIndices;
delete deferredList;
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index ebd5543..b70042f 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -277,7 +277,6 @@ struct Layer {
* If the layer can be rendered as a mesh, this is non-null.
*/
TextureVertex* mesh;
- uint16_t* meshIndices;
GLsizei meshElementCount;
/**
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index cfb1e97..f8076cc 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -130,10 +130,7 @@ void LayerRenderer::generateMesh() {
if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
if (mLayer->mesh) {
delete[] mLayer->mesh;
- delete[] mLayer->meshIndices;
-
mLayer->mesh = NULL;
- mLayer->meshIndices = NULL;
mLayer->meshElementCount = 0;
}
@@ -154,17 +151,11 @@ void LayerRenderer::generateMesh() {
if (mLayer->mesh && mLayer->meshElementCount < elementCount) {
delete[] mLayer->mesh;
- delete[] mLayer->meshIndices;
-
mLayer->mesh = NULL;
- mLayer->meshIndices = NULL;
}
- bool rebuildIndices = false;
if (!mLayer->mesh) {
mLayer->mesh = new TextureVertex[count * 4];
- mLayer->meshIndices = new uint16_t[elementCount];
- rebuildIndices = true;
}
mLayer->meshElementCount = elementCount;
@@ -173,7 +164,6 @@ void LayerRenderer::generateMesh() {
const float height = mLayer->layer.getHeight();
TextureVertex* mesh = mLayer->mesh;
- uint16_t* indices = mLayer->meshIndices;
for (size_t i = 0; i < count; i++) {
const android::Rect* r = &rects[i];
@@ -187,17 +177,6 @@ void LayerRenderer::generateMesh() {
TextureVertex::set(mesh++, r->right, r->top, u2, v1);
TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
-
- if (rebuildIndices) {
- uint16_t quad = i * 4;
- int index = i * 6;
- indices[index ] = quad; // top-left
- indices[index + 1] = quad + 1; // top-right
- indices[index + 2] = quad + 2; // bottom-left
- indices[index + 3] = quad + 2; // bottom-left
- indices[index + 4] = quad + 1; // top-right
- indices[index + 5] = quad + 3; // bottom-right
- }
}
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3e84273..06315ba 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -107,6 +107,15 @@ static const Blender gBlendsSwap[] = {
};
///////////////////////////////////////////////////////////////////////////////
+// Functions
+///////////////////////////////////////////////////////////////////////////////
+
+template<typename T>
+static inline T min(T a, T b) {
+ return a < b ? a : b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
///////////////////////////////////////////////////////////////////////////////
@@ -1284,7 +1293,6 @@ void OpenGLRenderer::drawRegionRects(const Region& region) {
void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
SkXfermode::Mode mode, bool dirty) {
- int count = 0;
Vector<float> rects;
SkRegion::Iterator it(region);
@@ -1294,11 +1302,10 @@ void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
rects.push(r.fTop);
rects.push(r.fRight);
rects.push(r.fBottom);
- count += 4;
it.next();
}
- drawColorRects(rects.array(), count, color, mode, true, dirty, false);
+ drawColorRects(rects.array(), rects.size(), color, mode, true, dirty, false);
}
void OpenGLRenderer::dirtyLayer(const float left, const float top,
@@ -1328,6 +1335,21 @@ void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
}
}
+void OpenGLRenderer::drawIndexedQuads(Vertex* mesh, GLsizei quadsCount) {
+ GLsizei elementsCount = quadsCount * 6;
+ while (elementsCount > 0) {
+ GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
+
+ setupDrawIndexedVertices(&mesh[0].position[0]);
+ glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL);
+
+ elementsCount -= drawCount;
+ // Though there are 4 vertices in a quad, we use 6 indices per
+ // quad to draw with GL_TRIANGLES
+ mesh += (drawCount / 6) * 4;
+ }
+}
+
void OpenGLRenderer::clearLayerRegions() {
const size_t count = mLayers.size();
if (count == 0) return;
@@ -1342,17 +1364,15 @@ void OpenGLRenderer::clearLayerRegions() {
// is likely different so we need to disable clipping here
bool scissorChanged = mCaches.disableScissor();
- Vertex mesh[count * 6];
+ Vertex mesh[count * 4];
Vertex* vertex = mesh;
for (uint32_t i = 0; i < count; i++) {
Rect* bounds = mLayers.itemAt(i);
- Vertex::set(vertex++, bounds->left, bounds->bottom);
Vertex::set(vertex++, bounds->left, bounds->top);
Vertex::set(vertex++, bounds->right, bounds->top);
Vertex::set(vertex++, bounds->left, bounds->bottom);
- Vertex::set(vertex++, bounds->right, bounds->top);
Vertex::set(vertex++, bounds->right, bounds->bottom);
delete bounds;
@@ -1368,9 +1388,8 @@ void OpenGLRenderer::clearLayerRegions() {
setupDrawProgram();
setupDrawPureColorUniforms();
setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true);
- setupDrawVertices(&mesh[0].position[0]);
- glDrawArrays(GL_TRIANGLES, 0, count * 6);
+ drawIndexedQuads(&mesh[0], count);
if (scissorChanged) mCaches.enableScissor();
} else {
@@ -1976,10 +1995,10 @@ void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, G
}
}
-void OpenGLRenderer::setupDrawVertices(GLvoid* vertices) {
+void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
bool force = mCaches.unbindMeshBuffer();
+ mCaches.bindIndicesBuffer();
mCaches.bindPositionVertexPointer(force, vertices, gVertexStride);
- mCaches.unbindIndicesBuffer();
}
void OpenGLRenderer::finishDrawTexture() {
@@ -3139,11 +3158,22 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) {
setupDrawModelViewTranslate(x, y,
x + layer->layer.getWidth(), y + layer->layer.getHeight());
}
- setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);
- DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
- glDrawElements(GL_TRIANGLES, layer->meshElementCount,
- GL_UNSIGNED_SHORT, layer->meshIndices));
+ TextureVertex* mesh = &layer->mesh[0];
+ GLsizei elementsCount = layer->meshElementCount;
+
+ while (elementsCount > 0) {
+ GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
+
+ setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
+ DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
+ glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL));
+
+ elementsCount -= drawCount;
+ // Though there are 4 vertices in a quad, we use 6 indices per
+ // quad to draw with GL_TRIANGLES
+ mesh += (drawCount / 6) * 4;
+ }
finishDrawTexture();
@@ -3361,8 +3391,7 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
float right = FLT_MIN;
float bottom = FLT_MIN;
- int vertexCount = 0;
- Vertex mesh[count * 6];
+ Vertex mesh[count];
Vertex* vertex = mesh;
for (int index = 0; index < count; index += 4) {
@@ -3371,15 +3400,11 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
float r = rects[index + 2];
float b = rects[index + 3];
- Vertex::set(vertex++, l, b);
Vertex::set(vertex++, l, t);
Vertex::set(vertex++, r, t);
Vertex::set(vertex++, l, b);
- Vertex::set(vertex++, r, t);
Vertex::set(vertex++, r, b);
- vertexCount += 6;
-
left = fminf(left, l);
top = fminf(top, t);
right = fmaxf(right, r);
@@ -3402,13 +3427,12 @@ status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color
setupDrawColorUniforms();
setupDrawShaderUniforms();
setupDrawColorFilterUniforms();
- setupDrawVertices((GLvoid*) &mesh[0].position[0]);
if (dirty && hasLayer()) {
dirtyLayer(left, top, right, bottom, currentTransform());
}
- glDrawArrays(GL_TRIANGLES, 0, vertexCount);
+ drawIndexedQuads(&mesh[0], count / 4);
return DrawGlInfo::kStatusDrew;
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 5e731b4..eb42540 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -850,6 +850,13 @@ private:
bool ignoreTransform, bool ignoreScale = false, bool dirty = true);
/**
+ * Draws the specified list of vertices as quads using indexed GL_TRIANGLES.
+ * If the number of vertices to draw exceeds the number of indices we have
+ * pre-allocated, this method will generate several glDrawElements() calls.
+ */
+ void drawIndexedQuads(Vertex* mesh, GLsizei quadsCount);
+
+ /**
* Draws text underline and strike-through if needed.
*
* @param text The text to decor
@@ -988,7 +995,7 @@ private:
void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords = NULL, GLuint vbo = 0);
void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors);
void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0);
- void setupDrawVertices(GLvoid* vertices);
+ void setupDrawIndexedVertices(GLvoid* vertices);
void finishDrawTexture();
void accountForClear(SkXfermode::Mode mode);