summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2015-06-12 22:46:19 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-12 22:46:21 +0000
commit4c9dafbfecf00ba3dca0c5de61d889676bfdc7af (patch)
tree263d7d69e9728c60441e202abc338746088caf06 /libs
parent1a3048f3677680823b52d3b0d538917d08da8495 (diff)
parenta766cb2bce5db9108c0266fbebea6aa18d5713ff (diff)
downloadframeworks_base-4c9dafbfecf00ba3dca0c5de61d889676bfdc7af.zip
frameworks_base-4c9dafbfecf00ba3dca0c5de61d889676bfdc7af.tar.gz
frameworks_base-4c9dafbfecf00ba3dca0c5de61d889676bfdc7af.tar.bz2
Merge "Put WebViews with on a HW layer if stencil/shader clipping is needed" into mnc-dev
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/CanvasState.h5
-rw-r--r--libs/hwui/DisplayListCanvas.cpp8
-rw-r--r--libs/hwui/DisplayListOp.h17
-rw-r--r--libs/hwui/RenderNode.cpp30
-rw-r--r--libs/hwui/RenderNode.h4
-rw-r--r--libs/hwui/RenderProperties.h40
6 files changed, 85 insertions, 19 deletions
diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h
index 9354e94..b35db28 100644
--- a/libs/hwui/CanvasState.h
+++ b/libs/hwui/CanvasState.h
@@ -155,8 +155,9 @@ public:
inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); }
int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
- int getWidth() { return mWidth; }
- int getHeight() { return mHeight; }
+ int getWidth() const { return mWidth; }
+ int getHeight() const { return mHeight; }
+ bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }
inline const Snapshot* currentSnapshot() const {
return mSnapshot != nullptr ? mSnapshot.get() : mFirstSnapshot.get();
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 900a621..843c412 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -203,10 +203,10 @@ bool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
void DisplayListCanvas::drawRenderNode(RenderNode* renderNode) {
LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
-
- // dirty is an out parameter and should not be recorded,
- // it matters only when replaying the display list
- DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(renderNode, *mState.currentTransform());
+ DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(
+ renderNode,
+ *mState.currentTransform(),
+ mState.clipIsSimple());
addRenderNodeOp(op);
}
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index e9d6ebc..fb2852a 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1398,9 +1398,10 @@ class DrawRenderNodeOp : public DrawBoundedOp {
friend class RenderNode; // grant RenderNode access to info of child
friend class DisplayListData; // grant DisplayListData access to info of child
public:
- DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent)
+ DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent, bool clipIsSimple)
: DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr)
, mRenderNode(renderNode)
+ , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple())
, mTransformFromParent(transformFromParent)
, mSkipInOrderDraw(false) {}
@@ -1436,6 +1437,20 @@ public:
private:
RenderNode* mRenderNode;
+ /**
+ * This RenderNode was drawn into a DisplayList with the canvas in a state that will likely
+ * require rendering with stencil clipping. Either:
+ *
+ * 1) A path clip or rotated rect clip was in effect on the canvas at record time
+ * 2) The RenderNode was recorded with a non-simple canvas transform (e.g. rotation)
+ *
+ * Note: even if this is false, non-rect clipping may still be applied applied either due to
+ * property-driven rotation (either in this RenderNode, or any ancestor), or record time
+ * clipping in an ancestor. These are handled in RenderNode::prepareTreeImpl since they are
+ * dynamic (relative to a static DisplayList of a parent), and don't affect this flag.
+ */
+ bool mRecordedWithPotentialStencilClip;
+
///////////////////////////
// Properties below are used by RenderNode::computeOrderingImpl() and issueOperations()
///////////////////////////
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 75e700a..b4cbc36 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -120,7 +120,10 @@ void RenderNode::prepareTree(TreeInfo& info) {
ATRACE_CALL();
LOG_ALWAYS_FATAL_IF(!info.damageAccumulator, "DamageAccumulator missing");
- prepareTreeImpl(info);
+ // Functors don't correctly handle stencil usage of overdraw debugging - shove 'em in a layer.
+ bool functorsNeedLayer = Properties::debugOverdraw;
+
+ prepareTreeImpl(info, functorsNeedLayer);
}
void RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
@@ -219,7 +222,15 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
}
}
-void RenderNode::prepareTreeImpl(TreeInfo& info) {
+/**
+ * Traverse down the the draw tree to prepare for a frame.
+ *
+ * MODE_FULL = UI Thread-driven (thus properties must be synced), otherwise RT driven
+ *
+ * While traversing down the tree, functorsNeedLayer flag is set to true if anything that uses the
+ * stencil buffer may be needed. Views that use a functor to draw will be forced onto a layer.
+ */
+void RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) {
info.damageAccumulator->pushTransform(this);
if (info.mode == TreeInfo::MODE_FULL) {
@@ -229,11 +240,17 @@ void RenderNode::prepareTreeImpl(TreeInfo& info) {
if (CC_LIKELY(info.runAnimations)) {
animatorDirtyMask = mAnimatorManager.animate(info);
}
+
+ bool willHaveFunctor = info.mode == TreeInfo::MODE_FULL && mStagingDisplayListData
+ ? !mStagingDisplayListData->functors.isEmpty() : !mDisplayListData->functors.isEmpty();
+ bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence(
+ willHaveFunctor, functorsNeedLayer);
+
prepareLayer(info, animatorDirtyMask);
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingDisplayListChanges(info);
}
- prepareSubTree(info, mDisplayListData);
+ prepareSubTree(info, childFunctorsNeedLayer, mDisplayListData);
pushLayerUpdate(info);
info.damageAccumulator->popTransform();
@@ -313,7 +330,7 @@ void RenderNode::deleteDisplayListData() {
mDisplayListData = nullptr;
}
-void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
+void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayListData* subtree) {
if (subtree) {
TextureCache& cache = Caches::getInstance().textureCache;
info.out.hasFunctors |= subtree->functors.size();
@@ -324,7 +341,10 @@ void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
DrawRenderNodeOp* op = subtree->children()[i];
RenderNode* childNode = op->mRenderNode;
info.damageAccumulator->pushTransform(&op->mTransformFromParent);
- childNode->prepareTreeImpl(info);
+ bool childFunctorsNeedLayer = functorsNeedLayer
+ // Recorded with non-rect clip, or canvas-rotated by parent
+ || op->mRecordedWithPotentialStencilClip;
+ childNode->prepareTreeImpl(info, childFunctorsNeedLayer);
info.damageAccumulator->popTransform();
}
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index d0d81d9..025a4a4 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -235,10 +235,10 @@ private:
const char* mText;
};
- void prepareTreeImpl(TreeInfo& info);
+ void prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer);
void pushStagingPropertiesChanges(TreeInfo& info);
void pushStagingDisplayListChanges(TreeInfo& info);
- void prepareSubTree(TreeInfo& info, DisplayListData* subtree);
+ void prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayListData* subtree);
void applyLayerPropertiesToLayer(TreeInfo& info);
void prepareLayer(TreeInfo& info, uint32_t dirtyMask);
void pushLayerUpdate(TreeInfo& info);
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 65c1c4a..81cf2df 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -158,6 +158,32 @@ public:
}
}
+ /**
+ * Set internal layer state based on whether this layer
+ *
+ * Additionally, returns true if child RenderNodes with functors will need to use a layer
+ * to support clipping.
+ */
+ bool prepareForFunctorPresence(bool willHaveFunctor, bool ancestorDictatesFunctorsNeedLayer) {
+ // parent may have already dictated that a descendant layer is needed
+ bool functorsNeedLayer = ancestorDictatesFunctorsNeedLayer
+
+ // Round rect clipping forces layer for functors
+ || CC_UNLIKELY(getOutline().willClip())
+ || CC_UNLIKELY(getRevealClip().willClip())
+
+ // Complex matrices forces layer, due to stencil clipping
+ || CC_UNLIKELY(getTransformMatrix() && !getTransformMatrix()->isScaleTranslate())
+ || CC_UNLIKELY(getAnimationMatrix() && !getAnimationMatrix()->isScaleTranslate())
+ || CC_UNLIKELY(getStaticMatrix() && !getStaticMatrix()->isScaleTranslate());
+
+ mComputedFields.mNeedLayerForFunctors = (willHaveFunctor && functorsNeedLayer);
+
+ // If on a layer, will have consumed the need for isolating functors from stencil.
+ // Thus, it's safe to reset the flag until some descendent sets it.
+ return CC_LIKELY(effectiveLayerType() == LayerType::None) && functorsNeedLayer;
+ }
+
RenderProperties& operator=(const RenderProperties& other);
bool setClipToBounds(bool clipToBounds) {
@@ -580,15 +606,16 @@ public:
bool promotedToLayer() const {
const int maxTextureSize = Caches::getInstance().maxTextureSize;
return mLayerProperties.mType == LayerType::None
- && !MathUtils::isZero(mPrimitiveFields.mAlpha)
- && mPrimitiveFields.mAlpha < 1
- && mPrimitiveFields.mHasOverlappingRendering
&& mPrimitiveFields.mWidth <= maxTextureSize
- && mPrimitiveFields.mHeight <= maxTextureSize;
+ && mPrimitiveFields.mHeight <= maxTextureSize
+ && (mComputedFields.mNeedLayerForFunctors
+ || (!MathUtils::isZero(mPrimitiveFields.mAlpha)
+ && mPrimitiveFields.mAlpha < 1
+ && mPrimitiveFields.mHasOverlappingRendering));
}
LayerType effectiveLayerType() const {
- return promotedToLayer() ? LayerType::RenderLayer : mLayerProperties.mType;
+ return CC_UNLIKELY(promotedToLayer()) ? LayerType::RenderLayer : mLayerProperties.mType;
}
private:
@@ -636,6 +663,9 @@ private:
SkMatrix* mTransformMatrix;
Sk3DView mTransformCamera;
+
+ // Force layer on for functors to enable render features they don't yet support (clipping)
+ bool mNeedLayerForFunctors = false;
} mComputedFields;
};