summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2014-03-26 13:19:14 -0700
committerChris Craik <ccraik@google.com>2014-03-27 16:01:04 -0700
commit024433f89684e1f9cb7b15ade7c480c9346fbe4d (patch)
tree981c0a0fdaa0b70be66899855806c1ce879b579e
parent1dd9c53a40b7c147767c63e10a47eb5cb6f8e197 (diff)
downloadframeworks_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.h14
-rw-r--r--libs/hwui/OpenGLRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.h2
-rw-r--r--libs/hwui/RenderNode.cpp11
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());