Loading libs/hwui/OpenGLRenderer.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -3226,11 +3226,13 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c const int casterVertexCount = casterVertices2d.size(); Vector3 casterPolygon[casterVertexCount]; float minZ = FLT_MAX; float maxZ = -FLT_MAX; for (int i = 0; i < casterVertexCount; i++) { const Vertex& point2d = casterVertices2d[i]; casterPolygon[i] = Vector3(point2d.x, point2d.y, 0); mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ); minZ = fmin(minZ, casterPolygon[i].z); maxZ = fmax(maxZ, casterPolygon[i].z); } // map the centroid of the caster into 3d Loading @@ -3248,6 +3250,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c } centroid3d.z += casterLift; } // Check whether we want to draw the shadow at all by checking the caster's // bounds against clip. // We only have ortho projection, so we can just ignore the Z in caster for // simple rejection calculation. Rect localClip = mSnapshot->getLocalClip(); Rect casterBounds(casterOutline->getBounds()); casterTransformXY.mapRect(casterBounds); bool isCasterOpaque = (casterAlpha == 1.0f); // draw caster's shadows if (mCaches.propertyAmbientShadowStrength > 0) { Loading @@ -3255,7 +3266,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c VertexBuffer ambientShadowVertexBuffer; VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow( isCasterOpaque, casterPolygon, casterVertexCount, centroid3d, ambientShadowVertexBuffer); casterBounds, localClip, maxZ, ambientShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint); } Loading @@ -3266,7 +3277,8 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale); VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow( isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale, *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer); *currentTransform(), getWidth(), getHeight(), casterBounds, localClip, spotShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint); } Loading libs/hwui/Rect.h +8 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define ANDROID_HWUI_RECT_H #include <cmath> #include <SkRect.h> #include <utils/Log.h> Loading Loading @@ -68,6 +69,13 @@ public: bottom(height) { } inline Rect(const SkRect& rect): left(rect.fLeft), top(rect.fTop), right(rect.fRight), bottom(rect.fBottom) { } friend int operator==(const Rect& a, const Rect& b) { return !memcmp(&a, &b, sizeof(a)); } Loading libs/hwui/ShadowTessellator.cpp +26 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,8 @@ static inline T max(T a, T b) { VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer) { const Vector3& centroid3d, const Rect& casterBounds, const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer) { ATRACE_CALL(); // A bunch of parameters to tweak the shadow. Loading @@ -43,6 +44,16 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, const float heightFactor = 1.0f / 128; const float geomFactor = 64; Rect ambientShadowBounds(casterBounds); ambientShadowBounds.outset(maxZ * geomFactor * heightFactor); if (!localClip.intersects(ambientShadowBounds)) { #if DEBUG_SHADOW ALOGD("Ambient shadow is out of clip rect!"); #endif return kVertexBufferMode_OnePolyRingShadow; } return AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon, casterVertexCount, centroid3d, heightFactor, geomFactor, shadowVertexBuffer); Loading @@ -52,7 +63,8 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& lightPosScale, const mat4& receiverTransform, int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) { int screenWidth, int screenHeight, const Rect& casterBounds, const Rect& localClip, VertexBuffer& shadowVertexBuffer) { ATRACE_CALL(); // A bunch of parameters to tweak the shadow. Loading @@ -73,6 +85,18 @@ VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque, const float lightSize = maximal / 4; const int lightVertexCount = 8; // Now light and caster are both in local space, we will check whether // the shadow is within the clip area. Rect lightRect = Rect(lightCenter.x - lightSize, lightCenter.y - lightSize, lightCenter.x + lightSize, lightCenter.y + lightSize); lightRect.unionWith(localClip); if (!lightRect.intersects(casterBounds)) { #if DEBUG_SHADOW ALOGD("Spot shadow is out of clip rect!"); #endif return kVertexBufferMode_OnePolyRingShadow; } VertexBufferMode mode = SpotShadow::createSpotShadow(isCasterOpaque, casterPolygon, casterVertexCount, lightCenter, lightSize, lightVertexCount, shadowVertexBuffer); Loading libs/hwui/ShadowTessellator.h +4 −2 Original line number Diff line number Diff line Loading @@ -66,12 +66,14 @@ class ShadowTessellator { public: static VertexBufferMode tessellateAmbientShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer); const Vector3& centroid3d, const Rect& casterBounds, const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer); static VertexBufferMode tessellateSpotShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& lightPosScale, const mat4& receiverTransform, int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer); int screenWidth, int screenHeight, const Rect& casterBounds, const Rect& localClip, VertexBuffer& shadowVertexBuffer); static void generateShadowIndices(uint16_t* shadowIndices); Loading Loading
libs/hwui/OpenGLRenderer.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -3226,11 +3226,13 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c const int casterVertexCount = casterVertices2d.size(); Vector3 casterPolygon[casterVertexCount]; float minZ = FLT_MAX; float maxZ = -FLT_MAX; for (int i = 0; i < casterVertexCount; i++) { const Vertex& point2d = casterVertices2d[i]; casterPolygon[i] = Vector3(point2d.x, point2d.y, 0); mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ); minZ = fmin(minZ, casterPolygon[i].z); maxZ = fmax(maxZ, casterPolygon[i].z); } // map the centroid of the caster into 3d Loading @@ -3248,6 +3250,15 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c } centroid3d.z += casterLift; } // Check whether we want to draw the shadow at all by checking the caster's // bounds against clip. // We only have ortho projection, so we can just ignore the Z in caster for // simple rejection calculation. Rect localClip = mSnapshot->getLocalClip(); Rect casterBounds(casterOutline->getBounds()); casterTransformXY.mapRect(casterBounds); bool isCasterOpaque = (casterAlpha == 1.0f); // draw caster's shadows if (mCaches.propertyAmbientShadowStrength > 0) { Loading @@ -3255,7 +3266,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c VertexBuffer ambientShadowVertexBuffer; VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow( isCasterOpaque, casterPolygon, casterVertexCount, centroid3d, ambientShadowVertexBuffer); casterBounds, localClip, maxZ, ambientShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint); } Loading @@ -3266,7 +3277,8 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale); VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow( isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale, *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer); *currentTransform(), getWidth(), getHeight(), casterBounds, localClip, spotShadowVertexBuffer); drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint); } Loading
libs/hwui/Rect.h +8 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #define ANDROID_HWUI_RECT_H #include <cmath> #include <SkRect.h> #include <utils/Log.h> Loading Loading @@ -68,6 +69,13 @@ public: bottom(height) { } inline Rect(const SkRect& rect): left(rect.fLeft), top(rect.fTop), right(rect.fRight), bottom(rect.fBottom) { } friend int operator==(const Rect& a, const Rect& b) { return !memcmp(&a, &b, sizeof(a)); } Loading
libs/hwui/ShadowTessellator.cpp +26 −2 Original line number Diff line number Diff line Loading @@ -35,7 +35,8 @@ static inline T max(T a, T b) { VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer) { const Vector3& centroid3d, const Rect& casterBounds, const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer) { ATRACE_CALL(); // A bunch of parameters to tweak the shadow. Loading @@ -43,6 +44,16 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, const float heightFactor = 1.0f / 128; const float geomFactor = 64; Rect ambientShadowBounds(casterBounds); ambientShadowBounds.outset(maxZ * geomFactor * heightFactor); if (!localClip.intersects(ambientShadowBounds)) { #if DEBUG_SHADOW ALOGD("Ambient shadow is out of clip rect!"); #endif return kVertexBufferMode_OnePolyRingShadow; } return AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon, casterVertexCount, centroid3d, heightFactor, geomFactor, shadowVertexBuffer); Loading @@ -52,7 +63,8 @@ VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& lightPosScale, const mat4& receiverTransform, int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) { int screenWidth, int screenHeight, const Rect& casterBounds, const Rect& localClip, VertexBuffer& shadowVertexBuffer) { ATRACE_CALL(); // A bunch of parameters to tweak the shadow. Loading @@ -73,6 +85,18 @@ VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque, const float lightSize = maximal / 4; const int lightVertexCount = 8; // Now light and caster are both in local space, we will check whether // the shadow is within the clip area. Rect lightRect = Rect(lightCenter.x - lightSize, lightCenter.y - lightSize, lightCenter.x + lightSize, lightCenter.y + lightSize); lightRect.unionWith(localClip); if (!lightRect.intersects(casterBounds)) { #if DEBUG_SHADOW ALOGD("Spot shadow is out of clip rect!"); #endif return kVertexBufferMode_OnePolyRingShadow; } VertexBufferMode mode = SpotShadow::createSpotShadow(isCasterOpaque, casterPolygon, casterVertexCount, lightCenter, lightSize, lightVertexCount, shadowVertexBuffer); Loading
libs/hwui/ShadowTessellator.h +4 −2 Original line number Diff line number Diff line Loading @@ -66,12 +66,14 @@ class ShadowTessellator { public: static VertexBufferMode tessellateAmbientShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer); const Vector3& centroid3d, const Rect& casterBounds, const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer); static VertexBufferMode tessellateSpotShadow(bool isCasterOpaque, const Vector3* casterPolygon, int casterVertexCount, const Vector3& lightPosScale, const mat4& receiverTransform, int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer); int screenWidth, int screenHeight, const Rect& casterBounds, const Rect& localClip, VertexBuffer& shadowVertexBuffer); static void generateShadowIndices(uint16_t* shadowIndices); Loading