Loading libs/hwui/AmbientShadow.cpp +26 −16 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ namespace uirenderer { * Calculate the shadows as a triangle strips while alpha value as the * shadow values. * * @param isCasterOpaque Whether the caster is opaque. * @param vertices The shadow caster's polygon, which is represented in a Vector3 * array. * @param vertexCount The length of caster's polygon in terms of number of Loading @@ -43,17 +44,18 @@ namespace uirenderer { * @param shadowVertexBuffer Return an floating point array of (x, y, a) * triangle strips mode. */ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) { VertexBufferMode AmbientShadow::createAmbientShadow(bool isCasterOpaque, const Vector3* vertices, int vertexCount, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) { const int rays = SHADOW_RAY_COUNT; VertexBufferMode mode = kVertexBufferMode_OnePolyRingShadow; // Validate the inputs. if (vertexCount < 3 || heightFactor <= 0 || rays <= 0 || geomFactor <= 0) { #if DEBUG_SHADOW ALOGE("Invalid input for createAmbientShadow(), early return!"); ALOGW("Invalid input for createAmbientShadow(), early return!"); #endif return; return mode; // vertex buffer is empty, so any mode doesn't matter. } Vector<Vector2> dir; // TODO: use C++11 unique_ptr Loading @@ -75,7 +77,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount rayDist[i] = rayDistance; if (edgeIndex < 0 || edgeIndex >= vertexCount) { #if DEBUG_SHADOW ALOGE("Invalid edgeIndex!"); ALOGW("Invalid edgeIndex!"); #endif edgeIndex = 0; } Loading @@ -86,7 +88,8 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // The output buffer length basically is roughly rays * layers, but since we // need triangle strips, so we need to duplicate vertices to accomplish that. AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT); AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT); // Calculate the vertex of the shadows. // Loading @@ -95,6 +98,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // calculate the normal N, which should be perpendicular to the edge of the // polygon (represented by the neighbor intersection points) . // Shadow's vertices will be generated as : P + N * scale. const Vector2 centroid2d = Vector2(centroid3d.x, centroid3d.y); for (int rayIndex = 0; rayIndex < rays; rayIndex++) { Vector2 normal(1.0f, 0.0f); calculateNormal(rays, rayIndex, dir.array(), rayDist, normal); Loading @@ -102,7 +106,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // The vertex should be start from rayDist[i] then scale the // normalizeNormal! Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] + Vector2(centroid3d.x, centroid3d.y); centroid2d; // outer ring of points, expanded based upon height of each ray intersection float expansionDist = rayHeight[rayIndex] * heightFactor * Loading @@ -114,25 +118,31 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // inner ring of points float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor); AlphaVertex::set(&shadowVertices[rayIndex + rays], AlphaVertex::set(&shadowVertices[rays + rayIndex], intersection.x, intersection.y, opacity); } // If caster isn't opaque, we need to to fill the umbra by storing the umbra's // centroid in the innermost ring of vertices. if (!isCasterOpaque) { mode = kVertexBufferMode_TwoPolyRingShadow; float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor); AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1], centroid3d.x, centroid3d.y, centroidAlpha); AlphaVertex centroidXYA; AlphaVertex::set(¢roidXYA, centroid2d.x, centroid2d.y, centroidAlpha); for (int rayIndex = 0; rayIndex < rays; rayIndex++) { shadowVertices[2 * rays + rayIndex] = centroidXYA; } } #if DEBUG_SHADOW if (currentVertexIndex != SHADOW_VERTEX_COUNT) { ALOGE("number of vertex generated for ambient shadow is wrong! " "current: %d , expected: %d", currentVertexIndex, SHADOW_VERTEX_COUNT); } for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) { ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x, shadowVertices[i].y, shadowVertices[i].alpha); } #endif return mode; } /** Loading libs/hwui/AmbientShadow.h +4 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define ANDROID_HWUI_AMBIENT_SHADOW_H #include "Debug.h" #include "OpenGLRenderer.h" #include "Vector.h" #include "VertexBuffer.h" Loading @@ -34,9 +35,9 @@ namespace uirenderer { */ class AmbientShadow { public: static void createAmbientShadow(const Vector3* poly, int polyLength, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer); static VertexBufferMode createAmbientShadow(bool isCasterOpaque, const Vector3* poly, int polyLength, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer); private: static void calculateRayDirections(int rays, Vector2* dir); Loading libs/hwui/Caches.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -445,11 +445,11 @@ bool Caches::bindQuadIndicesBuffer() { bool Caches::bindShadowIndicesBuffer() { if (!mShadowStripsIndices) { uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT]; uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT]; ShadowTessellator::generateShadowIndices(shadowIndices); glGenBuffers(1, &mShadowStripsIndices); bool force = bindIndicesBufferInternal(mShadowStripsIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t), glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t), shadowIndices, GL_STATIC_DRAW); delete[] shadowIndices; Loading libs/hwui/OpenGLRenderer.cpp +14 −10 Original line number Diff line number Diff line Loading @@ -2414,9 +2414,12 @@ status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode, if (mode == kVertexBufferMode_Standard) { mCaches.unbindIndicesBuffer(); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount()); } else { } else if (mode == kVertexBufferMode_OnePolyRingShadow) { mCaches.bindShadowIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); } else if (mode == kVertexBufferMode_TwoPolyRingShadow) { mCaches.bindShadowIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); } if (isAA) { Loading Loading @@ -3245,14 +3248,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c } centroid3d.z += casterLift; } bool isCasterOpaque = (casterAlpha == 1.0f); // draw caster's shadows if (mCaches.propertyAmbientShadowStrength > 0) { paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0); VertexBuffer ambientShadowVertexBuffer; ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount, centroid3d, ambientShadowVertexBuffer); drawVertexBuffer(kVertexBufferMode_Shadow, ambientShadowVertexBuffer, &paint); VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow( isCasterOpaque, casterPolygon, casterVertexCount, centroid3d, ambientShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint); } if (mCaches.propertySpotShadowStrength > 0) { Loading @@ -3260,10 +3264,10 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c VertexBuffer spotShadowVertexBuffer; Vector3 lightPosScale(mCaches.propertyLightPosXScale, mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale); ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount, lightPosScale, *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer); drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint); VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow( isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale, *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint); } return DrawGlInfo::kStatusDrew; Loading libs/hwui/OpenGLRenderer.h +2 −1 Original line number Diff line number Diff line Loading @@ -119,7 +119,8 @@ enum ModelViewMode { enum VertexBufferMode { kVertexBufferMode_Standard = 0, kVertexBufferMode_Shadow = 1 kVertexBufferMode_OnePolyRingShadow = 1, kVertexBufferMode_TwoPolyRingShadow = 2 }; /////////////////////////////////////////////////////////////////////////////// Loading Loading
libs/hwui/AmbientShadow.cpp +26 −16 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ namespace uirenderer { * Calculate the shadows as a triangle strips while alpha value as the * shadow values. * * @param isCasterOpaque Whether the caster is opaque. * @param vertices The shadow caster's polygon, which is represented in a Vector3 * array. * @param vertexCount The length of caster's polygon in terms of number of Loading @@ -43,17 +44,18 @@ namespace uirenderer { * @param shadowVertexBuffer Return an floating point array of (x, y, a) * triangle strips mode. */ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) { VertexBufferMode AmbientShadow::createAmbientShadow(bool isCasterOpaque, const Vector3* vertices, int vertexCount, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) { const int rays = SHADOW_RAY_COUNT; VertexBufferMode mode = kVertexBufferMode_OnePolyRingShadow; // Validate the inputs. if (vertexCount < 3 || heightFactor <= 0 || rays <= 0 || geomFactor <= 0) { #if DEBUG_SHADOW ALOGE("Invalid input for createAmbientShadow(), early return!"); ALOGW("Invalid input for createAmbientShadow(), early return!"); #endif return; return mode; // vertex buffer is empty, so any mode doesn't matter. } Vector<Vector2> dir; // TODO: use C++11 unique_ptr Loading @@ -75,7 +77,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount rayDist[i] = rayDistance; if (edgeIndex < 0 || edgeIndex >= vertexCount) { #if DEBUG_SHADOW ALOGE("Invalid edgeIndex!"); ALOGW("Invalid edgeIndex!"); #endif edgeIndex = 0; } Loading @@ -86,7 +88,8 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // The output buffer length basically is roughly rays * layers, but since we // need triangle strips, so we need to duplicate vertices to accomplish that. AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT); AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT); // Calculate the vertex of the shadows. // Loading @@ -95,6 +98,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // calculate the normal N, which should be perpendicular to the edge of the // polygon (represented by the neighbor intersection points) . // Shadow's vertices will be generated as : P + N * scale. const Vector2 centroid2d = Vector2(centroid3d.x, centroid3d.y); for (int rayIndex = 0; rayIndex < rays; rayIndex++) { Vector2 normal(1.0f, 0.0f); calculateNormal(rays, rayIndex, dir.array(), rayDist, normal); Loading @@ -102,7 +106,7 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // The vertex should be start from rayDist[i] then scale the // normalizeNormal! Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] + Vector2(centroid3d.x, centroid3d.y); centroid2d; // outer ring of points, expanded based upon height of each ray intersection float expansionDist = rayHeight[rayIndex] * heightFactor * Loading @@ -114,25 +118,31 @@ void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount // inner ring of points float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor); AlphaVertex::set(&shadowVertices[rayIndex + rays], AlphaVertex::set(&shadowVertices[rays + rayIndex], intersection.x, intersection.y, opacity); } // If caster isn't opaque, we need to to fill the umbra by storing the umbra's // centroid in the innermost ring of vertices. if (!isCasterOpaque) { mode = kVertexBufferMode_TwoPolyRingShadow; float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor); AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1], centroid3d.x, centroid3d.y, centroidAlpha); AlphaVertex centroidXYA; AlphaVertex::set(¢roidXYA, centroid2d.x, centroid2d.y, centroidAlpha); for (int rayIndex = 0; rayIndex < rays; rayIndex++) { shadowVertices[2 * rays + rayIndex] = centroidXYA; } } #if DEBUG_SHADOW if (currentVertexIndex != SHADOW_VERTEX_COUNT) { ALOGE("number of vertex generated for ambient shadow is wrong! " "current: %d , expected: %d", currentVertexIndex, SHADOW_VERTEX_COUNT); } for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) { ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x, shadowVertices[i].y, shadowVertices[i].alpha); } #endif return mode; } /** Loading
libs/hwui/AmbientShadow.h +4 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define ANDROID_HWUI_AMBIENT_SHADOW_H #include "Debug.h" #include "OpenGLRenderer.h" #include "Vector.h" #include "VertexBuffer.h" Loading @@ -34,9 +35,9 @@ namespace uirenderer { */ class AmbientShadow { public: static void createAmbientShadow(const Vector3* poly, int polyLength, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer); static VertexBufferMode createAmbientShadow(bool isCasterOpaque, const Vector3* poly, int polyLength, const Vector3& centroid3d, float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer); private: static void calculateRayDirections(int rays, Vector2* dir); Loading
libs/hwui/Caches.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -445,11 +445,11 @@ bool Caches::bindQuadIndicesBuffer() { bool Caches::bindShadowIndicesBuffer() { if (!mShadowStripsIndices) { uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT]; uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT]; ShadowTessellator::generateShadowIndices(shadowIndices); glGenBuffers(1, &mShadowStripsIndices); bool force = bindIndicesBufferInternal(mShadowStripsIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t), glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t), shadowIndices, GL_STATIC_DRAW); delete[] shadowIndices; Loading
libs/hwui/OpenGLRenderer.cpp +14 −10 Original line number Diff line number Diff line Loading @@ -2414,9 +2414,12 @@ status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode, if (mode == kVertexBufferMode_Standard) { mCaches.unbindIndicesBuffer(); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount()); } else { } else if (mode == kVertexBufferMode_OnePolyRingShadow) { mCaches.bindShadowIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); } else if (mode == kVertexBufferMode_TwoPolyRingShadow) { mCaches.bindShadowIndicesBuffer(); glDrawElements(GL_TRIANGLE_STRIP, SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0); } if (isAA) { Loading Loading @@ -3245,14 +3248,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c } centroid3d.z += casterLift; } bool isCasterOpaque = (casterAlpha == 1.0f); // draw caster's shadows if (mCaches.propertyAmbientShadowStrength > 0) { paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0); VertexBuffer ambientShadowVertexBuffer; ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount, centroid3d, ambientShadowVertexBuffer); drawVertexBuffer(kVertexBufferMode_Shadow, ambientShadowVertexBuffer, &paint); VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow( isCasterOpaque, casterPolygon, casterVertexCount, centroid3d, ambientShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint); } if (mCaches.propertySpotShadowStrength > 0) { Loading @@ -3260,10 +3264,10 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c VertexBuffer spotShadowVertexBuffer; Vector3 lightPosScale(mCaches.propertyLightPosXScale, mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale); ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount, lightPosScale, *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer); drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint); VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow( isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale, *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint); } return DrawGlInfo::kStatusDrew; Loading
libs/hwui/OpenGLRenderer.h +2 −1 Original line number Diff line number Diff line Loading @@ -119,7 +119,8 @@ enum ModelViewMode { enum VertexBufferMode { kVertexBufferMode_Standard = 0, kVertexBufferMode_Shadow = 1 kVertexBufferMode_OnePolyRingShadow = 1, kVertexBufferMode_TwoPolyRingShadow = 2 }; /////////////////////////////////////////////////////////////////////////////// Loading