summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2014-07-29 12:50:14 -0700
committerChris Craik <ccraik@google.com>2014-07-30 17:15:50 +0000
commitaf4d04cab6d48ae0d6a5e79bd30f679af87abaad (patch)
treeb1fe9d83f5ccc32b1e0db8f002d2d3035368dfac /libs
parent3d1856f4449f02a9a3bda06738c3eb83df96f88b (diff)
downloadframeworks_base-af4d04cab6d48ae0d6a5e79bd30f679af87abaad.zip
frameworks_base-af4d04cab6d48ae0d6a5e79bd30f679af87abaad.tar.gz
frameworks_base-af4d04cab6d48ae0d6a5e79bd30f679af87abaad.tar.bz2
Use RoundRect clipping for circle reveal animation
bug:16630975 Also, remove inverse clipping feature from reveal animator. Change-Id: I770a4eb48cd123b0ca0f39d16a0f3eefd1be3653
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Animator.cpp9
-rw-r--r--libs/hwui/Animator.h2
-rw-r--r--libs/hwui/DisplayListOp.h8
-rwxr-xr-xlibs/hwui/OpenGLRenderer.cpp8
-rw-r--r--libs/hwui/RenderNode.cpp32
-rw-r--r--libs/hwui/RenderProperties.h13
-rw-r--r--libs/hwui/RevealClip.h19
-rw-r--r--libs/hwui/Snapshot.cpp29
-rw-r--r--libs/hwui/Snapshot.h6
-rw-r--r--libs/hwui/StatefulBaseRenderer.cpp19
-rw-r--r--libs/hwui/StatefulBaseRenderer.h2
11 files changed, 63 insertions, 84 deletions
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 24ed6cd..dd2e2fd 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -288,21 +288,20 @@ void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) {
LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
}
-RevealAnimator::RevealAnimator(int centerX, int centerY, bool inverseClip,
+RevealAnimator::RevealAnimator(int centerX, int centerY,
float startValue, float finalValue)
: BaseRenderNodeAnimator(finalValue)
, mCenterX(centerX)
- , mCenterY(centerY)
- , mInverseClip(inverseClip) {
+ , mCenterY(centerY) {
setStartValue(startValue);
}
float RevealAnimator::getValue(RenderNode* target) const {
- return target->properties().getRevealClip().radius();
+ return target->properties().getRevealClip().getRadius();
}
void RevealAnimator::setValue(RenderNode* target, float value) {
- target->animatorProperties().mutableRevealClip().set(true, mInverseClip,
+ target->animatorProperties().mutableRevealClip().set(true,
mCenterX, mCenterY, value);
}
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 9a080a7..b0dcf2d 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -171,7 +171,7 @@ private:
class RevealAnimator : public BaseRenderNodeAnimator {
public:
- ANDROID_API RevealAnimator(int centerX, int centerY, bool inverseClip,
+ ANDROID_API RevealAnimator(int centerX, int centerY,
float startValue, float finalValue);
protected:
virtual float getValue(RenderNode* target) const;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 9f66904..777a35a 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1535,10 +1535,9 @@ private:
class DrawShadowOp : public DrawOp {
public:
DrawShadowOp(const mat4& transformXY, const mat4& transformZ,
- float casterAlpha, bool casterUnclipped,
- const SkPath* casterOutline, const SkPath* revealClip)
+ float casterAlpha, const SkPath* casterOutline, const SkPath* revealClip)
: DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ),
- mCasterAlpha(casterAlpha), mCasterUnclipped(casterUnclipped) {
+ mCasterAlpha(casterAlpha) {
mOutline = *casterOutline;
if (revealClip) {
// intersect the outline with the convex reveal clip
@@ -1572,12 +1571,11 @@ public:
virtual const char* name() { return "DrawShadow"; }
private:
- bool isCasterOpaque() { return mCasterAlpha >= 1.0f && mCasterUnclipped; }
+ bool isCasterOpaque() { return mCasterAlpha >= 1.0f; }
const mat4 mTransformXY;
const mat4 mTransformZ;
const float mCasterAlpha;
- const bool mCasterUnclipped;
SkPath mOutline;
};
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index de777f0..5e6ae3f 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1742,12 +1742,12 @@ void OpenGLRenderer::setupDrawProgram() {
if (mDescription.hasRoundRectClip) {
// TODO: avoid doing this repeatedly, stashing state pointer in program
const RoundRectClipState* state = mSnapshot->roundRectClipState;
- const Rect& innerRect = state->outlineInnerRect;
+ const Rect& innerRect = state->innerRect;
glUniform4f(mCaches.currentProgram->getUniform("roundRectInnerRectLTRB"),
- innerRect.left, innerRect.top,
- innerRect.right, innerRect.bottom);
+ innerRect.left, innerRect.top,
+ innerRect.right, innerRect.bottom);
glUniform1f(mCaches.currentProgram->getUniform("roundRectRadius"),
- state->outlineRadius);
+ state->radius);
glUniformMatrix4fv(mCaches.currentProgram->getUniform("roundRectInvTransform"),
1, GL_FALSE, &state->matrix.data[0]);
}
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 1df2055..0662ca2 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -384,11 +384,15 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) {
handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
- if (CC_UNLIKELY(properties().hasClippingPath())) {
- ClipPathOp* op = new (handler.allocator()) ClipPathOp(
- properties().getClippingPath(), properties().getClippingPathOp());
- handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
+ // TODO: support both reveal clip and outline clip simultaneously
+ if (mProperties.getRevealClip().willClip()) {
+ Rect bounds;
+ mProperties.getRevealClip().getBounds(&bounds);
+ renderer.setClippingRoundRect(handler.allocator(), bounds, mProperties.getRevealClip().getRadius());
+ } else if (mProperties.getOutline().willClip()) {
+ renderer.setClippingOutline(handler.allocator(), &(mProperties.getOutline()));
}
+
}
/**
@@ -600,23 +604,11 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T&
applyViewPropertyTransforms(shadowMatrixZ, true);
const SkPath* outlinePath = properties().getOutline().getPath();
- const RevealClip& revealClip = properties().getRevealClip();
- const SkPath* revealClipPath = revealClip.hasConvexClip()
- ? revealClip.getPath() : NULL; // only pass the reveal clip's path if it's convex
-
+ const SkPath* revealClipPath = properties().getRevealClip().getPath();
if (revealClipPath && revealClipPath->isEmpty()) return;
- /**
- * 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 (handler.allocator()) DrawShadowOp(
- shadowMatrixXY, shadowMatrixZ,
- properties().getAlpha(), casterUnclipped,
+ shadowMatrixXY, shadowMatrixZ, properties().getAlpha(),
outlinePath, revealClipPath);
handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
}
@@ -828,10 +820,6 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
bool quickRejected = properties().getClipToBounds()
&& renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
if (!quickRejected) {
- if (mProperties.getOutline().willClip()) {
- renderer.setClippingOutline(alloc, &(mProperties.getOutline()));
- }
-
if (drawLayer) {
handler(new (alloc) DrawLayerOp(mLayer, 0, 0),
renderer.getSaveCount() - 1, properties().getClipToBounds());
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index f50e514..9898bde 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -546,19 +546,6 @@ public:
void updateMatrix();
- bool hasClippingPath() const {
- return mPrimitiveFields.mRevealClip.willClip();
- }
-
- const SkPath* getClippingPath() const {
- return mPrimitiveFields.mRevealClip.getPath();
- }
-
- SkRegion::Op getClippingPathOp() const {
- return mPrimitiveFields.mRevealClip.isInverseClip()
- ? SkRegion::kDifference_Op : SkRegion::kIntersect_Op;
- }
-
Outline& mutableOutline() {
return mPrimitiveFields.mOutline;
}
diff --git a/libs/hwui/RevealClip.h b/libs/hwui/RevealClip.h
index 07404cb..a9600f1 100644
--- a/libs/hwui/RevealClip.h
+++ b/libs/hwui/RevealClip.h
@@ -27,14 +27,12 @@ class RevealClip {
public:
RevealClip()
: mShouldClip(false)
- , mInverseClip(false)
, mX(0)
, mY(0)
, mRadius(0) {}
- void set(bool shouldClip, bool inverseClip, float x, float y, float radius) {
+ void set(bool shouldClip, float x, float y, float radius) {
mShouldClip = shouldClip;
- mInverseClip = inverseClip;
mX = x;
mY = y;
mRadius = radius;
@@ -45,21 +43,15 @@ public:
}
}
- bool hasConvexClip() const {
- return mShouldClip && !mInverseClip;
- }
-
- bool isInverseClip() const {
- return mInverseClip;
- }
-
bool willClip() const {
return mShouldClip;
}
- float radius() const {
- return mRadius;
+ void getBounds(Rect* outBounds) const {
+ outBounds->set(mX - mRadius, mY - mRadius,
+ mX + mRadius, mY + mRadius);
}
+ float getRadius() const { return mRadius; }
const SkPath* getPath() const {
if (!mShouldClip) return NULL;
@@ -69,7 +61,6 @@ public:
private:
bool mShouldClip;
- bool mInverseClip;
float mX;
float mY;
float mRadius;
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 80f7eca..6f19275 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -20,8 +20,6 @@
#include <SkCanvas.h>
-#include "utils/MathUtils.h"
-
namespace android {
namespace uirenderer {
@@ -207,23 +205,22 @@ void Snapshot::resetTransform(float x, float y, float z) {
}
///////////////////////////////////////////////////////////////////////////////
-// Clipping outline
+// Clipping round rect
///////////////////////////////////////////////////////////////////////////////
-void Snapshot::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
- Rect bounds;
- float radius;
- if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported
-
- if (!MathUtils::isPositive(radius)) return; // leave clipping up to rect clipping
+void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius) {
+ if (bounds.isEmpty()) {
+ clipRect->setEmpty();
+ return;
+ }
RoundRectClipState* state = new (allocator) RoundRectClipState;
// store the inverse drawing matrix
- Matrix4 outlineDrawingMatrix;
- outlineDrawingMatrix.load(getOrthoMatrix());
- outlineDrawingMatrix.multiply(*transform);
- state->matrix.loadInverse(outlineDrawingMatrix);
+ Matrix4 roundRectDrawingMatrix;
+ roundRectDrawingMatrix.load(getOrthoMatrix());
+ roundRectDrawingMatrix.multiply(*transform);
+ state->matrix.loadInverse(roundRectDrawingMatrix);
// compute area under rounded corners - only draws overlapping these rects need to be clipped
for (int i = 0 ; i < 4; i++) {
@@ -241,9 +238,9 @@ void Snapshot::setClippingOutline(LinearAllocator& allocator, const Outline* out
}
// store RR area
- bounds.inset(radius);
- state->outlineInnerRect = bounds;
- state->outlineRadius = radius;
+ state->innerRect = bounds;
+ state->innerRect.inset(radius);
+ state->radius = radius;
// store as immutable so, for this frame, pointer uniquely identifies this bundle of shader info
roundRectClipState = state;
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 5426e89..98e2440 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -57,8 +57,8 @@ public:
Matrix4 matrix;
Rect dangerRects[4];
- Rect outlineInnerRect;
- float outlineRadius;
+ Rect innerRect;
+ float radius;
};
/**
@@ -164,7 +164,7 @@ public:
/**
* Sets (and replaces) the current clipping outline
*/
- void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
+ void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius);
/**
* Indicates whether this snapshot should be ignored. A snapshot
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp
index 473005c..dc41157 100644
--- a/libs/hwui/StatefulBaseRenderer.cpp
+++ b/libs/hwui/StatefulBaseRenderer.cpp
@@ -20,6 +20,8 @@
#include "StatefulBaseRenderer.h"
+#include "utils/MathUtils.h"
+
namespace android {
namespace uirenderer {
@@ -189,9 +191,24 @@ bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
}
void StatefulBaseRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
- mSnapshot->setClippingOutline(allocator, outline);
+ Rect bounds;
+ float radius;
+ if (!outline->getAsRoundRect(&bounds, &radius)) return; // only RR supported
+
+ if (!MathUtils::isPositive(radius)) {
+ // TODO: consider storing this rect separately, so that this can't be replaced with clip ops
+ clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkRegion::kIntersect_Op);
+ return;
+ }
+ setClippingRoundRect(allocator, bounds, radius);
}
+void StatefulBaseRenderer::setClippingRoundRect(LinearAllocator& allocator,
+ const Rect& rect, float radius) {
+ mSnapshot->setClippingRoundRect(allocator, rect, radius);
+}
+
+
///////////////////////////////////////////////////////////////////////////////
// Quick Rejection
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
index 25cc832..6d83b4c 100644
--- a/libs/hwui/StatefulBaseRenderer.h
+++ b/libs/hwui/StatefulBaseRenderer.h
@@ -96,6 +96,8 @@ public:
* The clipping outline is independent from the regular clip.
*/
void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
+ void setClippingRoundRect(LinearAllocator& allocator,
+ const Rect& rect, float radius);
protected:
const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }