From c93e45cf045f41aea95f856173e4043d988a5a5c Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Wed, 16 Jul 2014 10:15:56 -0700 Subject: [PATCH] Build layer damage bounds for shadows bug:15538815 Change-Id: I703afeb7e31c28002bd1aff9ce448ec8cdc4e70d --- libs/hwui/AmbientShadow.cpp | 1 + libs/hwui/PathTessellator.cpp | 16 +++------------- libs/hwui/Rect.h | 7 +++++++ libs/hwui/SpotShadow.cpp | 1 + libs/hwui/TessellationCache.cpp | 2 -- libs/hwui/VertexBuffer.h | 20 ++++++++++++++++++++ 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp index 937b7c622c623..b9d7b12c115d2 100644 --- a/libs/hwui/AmbientShadow.cpp +++ b/libs/hwui/AmbientShadow.cpp @@ -136,6 +136,7 @@ void AmbientShadow::createAmbientShadow(bool isCasterOpaque, } } shadowVertexBuffer.setMode(mode); + shadowVertexBuffer.computeBounds(); #if DEBUG_SHADOW for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) { diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp index 310b1075f5d5f..804ec418117c7 100644 --- a/libs/hwui/PathTessellator.cpp +++ b/libs/hwui/PathTessellator.cpp @@ -794,16 +794,6 @@ void PathTessellator::tessellatePath(const SkPath &path, const SkPaint* paint, vertexBuffer.setBounds(bounds); } -static void expandRectToCoverVertex(Rect& rect, float x, float y) { - rect.left = fminf(rect.left, x); - rect.top = fminf(rect.top, y); - rect.right = fmaxf(rect.right, x); - rect.bottom = fmaxf(rect.bottom, y); -} -static void expandRectToCoverVertex(Rect& rect, const Vertex& vertex) { - expandRectToCoverVertex(rect, vertex.x, vertex.y); -} - template static void instanceVertices(VertexBuffer& srcBuffer, VertexBuffer& dstBuffer, const float* points, int count, Rect& bounds) { @@ -814,7 +804,7 @@ static void instanceVertices(VertexBuffer& srcBuffer, VertexBuffer& dstBuffer, dstBuffer.alloc(numPoints * verticesPerPoint + (numPoints - 1) * 2); for (int i = 0; i < count; i += 2) { - expandRectToCoverVertex(bounds, points[i + 0], points[i + 1]); + bounds.expandToCoverVertex(points[i + 0], points[i + 1]); dstBuffer.copyInto(srcBuffer, points[i + 0], points[i + 1]); } dstBuffer.createDegenerateSeparators(verticesPerPoint); @@ -896,8 +886,8 @@ void PathTessellator::tessellateLines(const float* points, int count, const SkPa } // calculate bounds - expandRectToCoverVertex(bounds, tempVerticesData[0]); - expandRectToCoverVertex(bounds, tempVerticesData[1]); + bounds.expandToCoverVertex(tempVerticesData[0].x, tempVerticesData[0].y); + bounds.expandToCoverVertex(tempVerticesData[1].x, tempVerticesData[1].y); } // since multiple objects tessellated into buffer, separate them with degen tris diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h index 846ebdcbd6d53..9311f992760cc 100644 --- a/libs/hwui/Rect.h +++ b/libs/hwui/Rect.h @@ -241,6 +241,13 @@ public: bottom = ceilf(bottom); } + void expandToCoverVertex(float x, float y) { + left = fminf(left, x); + top = fminf(top, y); + right = fmaxf(right, x); + bottom = fmaxf(bottom, y); + } + void dump(const char* label = NULL) const { ALOGD("%s[l=%f t=%f r=%f b=%f]", label ? label : "Rect", left, top, right, bottom); } diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index 06f6204e85fb9..82dbe7a1485a6 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -508,6 +508,7 @@ void SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3* poly, computeSpotShadow(isCasterOpaque, light, lightVertexCount, lightCenter, poly, polyLength, retStrips); retStrips.setMode(VertexBuffer::kTwoPolyRingShadow); + retStrips.computeBounds(); } /** diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp index 08b54ff0f619f..343f1aa9c1273 100644 --- a/libs/hwui/TessellationCache.cpp +++ b/libs/hwui/TessellationCache.cpp @@ -273,8 +273,6 @@ static void tessellateShadows( isCasterOpaque, casterPolygon, casterVertexCount, *drawTransform, lightCenter, lightRadius, casterBounds, *localClip, spotBuffer); - - // TODO: set ambientBuffer & spotBuffer's bounds for correct layer damage } class ShadowProcessor : public TaskProcessor { diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h index 55d566bfd9385..5875f25aa514d 100644 --- a/libs/hwui/VertexBuffer.h +++ b/libs/hwui/VertexBuffer.h @@ -62,6 +62,8 @@ public: mVertexCount = vertexCount; mByteCount = mVertexCount * sizeof(TYPE); mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; + memset(mBuffer, 0, sizeof(TYPE) * vertexCount); + mCleanupMethod = &(cleanup); return (TYPE*)mBuffer; @@ -79,6 +81,24 @@ public: } } + /** + * Brute force bounds computation, used only if the producer of this + * vertex buffer can't determine bounds more simply/efficiently + */ + template + void computeBounds() { + if (!mVertexCount) { + mBounds.setEmpty(); + return; + } + TYPE* current = (TYPE*)mBuffer; + TYPE* end = current + mVertexCount; + mBounds.set(current->x, current->y, current->x, current->y); + for (; current < end; current++) { + mBounds.expandToCoverVertex(current->x, current->y); + } + } + const void* getBuffer() const { return mBuffer; } const Rect& getBounds() const { return mBounds; } unsigned int getVertexCount() const { return mVertexCount; }