diff options
author | Romain Guy <romainguy@google.com> | 2013-07-22 22:16:03 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-07-22 22:16:03 +0000 |
commit | 03903b3bc8fb592884421c2a5f8c6266ff2b4881 (patch) | |
tree | ff66d20e6583f40f9d587d45d225bf6601dcf98c | |
parent | 6944165014bf026e24aafe0cb359d7aad66bea7b (diff) | |
parent | 448455fe783b0a711340322dca272b8cc0ebe473 (diff) | |
download | frameworks_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.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 1 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 68 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 9 |
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); |