diff options
author | Chris Craik <ccraik@google.com> | 2014-03-26 13:19:14 -0700 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-03-27 16:01:04 -0700 |
commit | 024433f89684e1f9cb7b15ade7c480c9346fbe4d (patch) | |
tree | 981c0a0fdaa0b70be66899855806c1ce879b579e | |
parent | 1dd9c53a40b7c147767c63e10a47eb5cb6f8e197 (diff) | |
download | frameworks_base-024433f89684e1f9cb7b15ade7c480c9346fbe4d.zip frameworks_base-024433f89684e1f9cb7b15ade7c480c9346fbe4d.tar.gz frameworks_base-024433f89684e1f9cb7b15ade7c480c9346fbe4d.tar.bz2 |
Disable shadow overdraw avoidance in the inverse clip case
The caster is effectivly transparent, so skip the optimization just as
is done for alpha < 1.0
Change-Id: I3d294222adf0137e20c1fb5808313d487e92e0a8
-rw-r--r-- | libs/hwui/DisplayListOp.h | 14 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 11 |
4 files changed, 22 insertions, 9 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 9e367fc..239a5bc 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1548,14 +1548,16 @@ private: }; /** - * Not a canvas operation, used only by 3d / z ordering logic in DisplayList::iterate() + * Not a canvas operation, used only by 3d / z ordering logic in RenderNode::iterate() */ class DrawShadowOp : public DrawOp { public: - DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, + DrawShadowOp(const mat4& transformXY, const mat4& transformZ, + float casterAlpha, bool casterUnclipped, float fallbackWidth, float fallbackHeight, const SkPath* outline, const SkPath* revealClip) - : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), mAlpha(alpha), + : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), + mCasterAlpha(casterAlpha), mCasterUnclipped(casterUnclipped), mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight), mOutline(outline), mRevealClip(revealClip) {} @@ -1572,7 +1574,8 @@ public: Op(casterPerimeter, *mRevealClip, kIntersect_PathOp, &casterPerimeter); } - return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &casterPerimeter); + return renderer.drawShadow(mTransformXY, mTransformZ, + mCasterAlpha, mCasterUnclipped, &casterPerimeter); } virtual void output(int level, uint32_t logFlags) const { @@ -1584,7 +1587,8 @@ public: private: const mat4 mTransformXY; const mat4 mTransformZ; - const float mAlpha; + const float mCasterAlpha; + const bool mCasterUnclipped; const float mFallbackWidth; const float mFallbackHeight; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index d808735..619f331 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -3203,7 +3203,7 @@ static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& t } status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ, - float casterAlpha, const SkPath* casterPerimeter) { + float casterAlpha, bool casterUnclipped, const SkPath* casterPerimeter) { if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone; // TODO: use quickRejectWithScissor. For now, always force enable scissor. @@ -3260,7 +3260,7 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& c Rect casterBounds(casterPerimeter->getBounds()); casterTransformXY.mapRect(casterBounds); - bool isCasterOpaque = (casterAlpha == 1.0f); + bool isCasterOpaque = (casterAlpha == 1.0f) && casterUnclipped; // draw caster's shadows if (mCaches.propertyAmbientShadowStrength > 0) { paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 054767e..2debd2e 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -210,7 +210,7 @@ public: virtual status_t drawRects(const float* rects, int count, const SkPaint* paint); status_t drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ, - float casterAlpha, const SkPath* casterPerimeter); + float casterAlpha, bool casterUnclipped, const SkPath* casterPerimeter); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index e39e5ae..c24a7a1 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -416,8 +416,17 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl const SkPath* revealClipPath = revealClip.hasConvexClip() ? revealClip.getPath() : NULL; // only pass the reveal clip's path if it's convex + /** + * The drawing area of the caster is always the same as the its perimeter (which + * the shadow system uses) *except* in the inverse clip case. Inform the shadow + * system that the caster's drawing area (as opposed to its perimeter) has been + * clipped, so that it knows the caster can't be opaque. + */ + bool casterUnclipped = !revealClip.willClip() || revealClip.hasConvexClip(); + DisplayListOp* shadowOp = new (alloc) DrawShadowOp( - shadowMatrixXY, shadowMatrixZ, caster->properties().getAlpha(), + shadowMatrixXY, shadowMatrixZ, + caster->properties().getAlpha(), casterUnclipped, caster->properties().getWidth(), caster->properties().getHeight(), outlinePath, revealClipPath); handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds()); |