Merge "Put Vulkan WebViews on a HW layer if stencil clip"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2f10a26aba
@@ -759,6 +759,8 @@ RecordingCanvas::RecordingCanvas() : INHERITED(1, 1), fDL(nullptr) {}
|
||||
void RecordingCanvas::reset(DisplayListData* dl, const SkIRect& bounds) {
|
||||
this->resetCanvas(bounds.right(), bounds.bottom());
|
||||
fDL = dl;
|
||||
mClipMayBeComplex = false;
|
||||
mSaveCount = mComplexSaveCount = 0;
|
||||
}
|
||||
|
||||
sk_sp<SkSurface> RecordingCanvas::onNewSurface(const SkImageInfo&, const SkSurfaceProps&) {
|
||||
@@ -770,6 +772,7 @@ void RecordingCanvas::onFlush() {
|
||||
}
|
||||
|
||||
void RecordingCanvas::willSave() {
|
||||
mSaveCount++;
|
||||
fDL->save();
|
||||
}
|
||||
SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
|
||||
@@ -778,6 +781,11 @@ SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLaye
|
||||
return SkCanvas::kNoLayer_SaveLayerStrategy;
|
||||
}
|
||||
void RecordingCanvas::willRestore() {
|
||||
mSaveCount--;
|
||||
if (mSaveCount < mComplexSaveCount) {
|
||||
mClipMayBeComplex = false;
|
||||
mComplexSaveCount = 0;
|
||||
}
|
||||
fDL->restore();
|
||||
}
|
||||
|
||||
@@ -798,17 +806,27 @@ void RecordingCanvas::didTranslate(SkScalar dx, SkScalar dy) {
|
||||
|
||||
void RecordingCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle style) {
|
||||
fDL->clipRect(rect, op, style == kSoft_ClipEdgeStyle);
|
||||
if (!getTotalMatrix().isScaleTranslate()) {
|
||||
setClipMayBeComplex();
|
||||
}
|
||||
this->INHERITED::onClipRect(rect, op, style);
|
||||
}
|
||||
void RecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle style) {
|
||||
if (rrect.getType() > SkRRect::kRect_Type || !getTotalMatrix().isScaleTranslate()) {
|
||||
setClipMayBeComplex();
|
||||
}
|
||||
fDL->clipRRect(rrect, op, style == kSoft_ClipEdgeStyle);
|
||||
this->INHERITED::onClipRRect(rrect, op, style);
|
||||
}
|
||||
void RecordingCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle style) {
|
||||
setClipMayBeComplex();
|
||||
fDL->clipPath(path, op, style == kSoft_ClipEdgeStyle);
|
||||
this->INHERITED::onClipPath(path, op, style);
|
||||
}
|
||||
void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
|
||||
if (region.isComplex() || !getTotalMatrix().isScaleTranslate()) {
|
||||
setClipMayBeComplex();
|
||||
}
|
||||
fDL->clipRegion(region, op);
|
||||
this->INHERITED::onClipRegion(region, op);
|
||||
}
|
||||
|
||||
@@ -203,10 +203,41 @@ public:
|
||||
|
||||
void drawVectorDrawable(VectorDrawableRoot* tree);
|
||||
|
||||
/**
|
||||
* If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
|
||||
* If the return value is true, then clip may or may not be complex (there is no guarantee).
|
||||
*/
|
||||
inline bool isClipMayBeComplex() { return mClipMayBeComplex; }
|
||||
|
||||
private:
|
||||
typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED;
|
||||
|
||||
inline void setClipMayBeComplex() {
|
||||
if (!mClipMayBeComplex) {
|
||||
mComplexSaveCount = mSaveCount;
|
||||
mClipMayBeComplex = true;
|
||||
}
|
||||
}
|
||||
|
||||
DisplayListData* fDL;
|
||||
|
||||
/**
|
||||
* mClipMayBeComplex tracks if the current clip is a rectangle. This flag is used to promote
|
||||
* FunctorDrawable to a layer, if it is clipped by a non-rect.
|
||||
*/
|
||||
bool mClipMayBeComplex = false;
|
||||
|
||||
/**
|
||||
* mSaveCount is the current level of our save tree.
|
||||
*/
|
||||
int mSaveCount = 0;
|
||||
|
||||
/**
|
||||
* mComplexSaveCount is the first save level, which has a complex clip. Every level below
|
||||
* mComplexSaveCount is assumed to have a complex clip and every level above mComplexSaveCount
|
||||
* is guaranteed to not be complex.
|
||||
*/
|
||||
int mComplexSaveCount = 0;
|
||||
};
|
||||
|
||||
} // namespace uirenderer
|
||||
|
||||
@@ -151,6 +151,7 @@ public:
|
||||
// parent may have already dictated that a descendant layer is needed
|
||||
bool functorsNeedLayer =
|
||||
ancestorDictatesFunctorsNeedLayer
|
||||
|| CC_UNLIKELY(isClipMayBeComplex())
|
||||
|
||||
// Round rect clipping forces layer for functors
|
||||
|| CC_UNLIKELY(getOutline().willRoundRectClip()) ||
|
||||
@@ -193,6 +194,12 @@ public:
|
||||
|
||||
bool isProjectionReceiver() const { return mPrimitiveFields.mProjectionReceiver; }
|
||||
|
||||
bool setClipMayBeComplex(bool isClipMayBeComplex) {
|
||||
return RP_SET(mPrimitiveFields.mClipMayBeComplex, isClipMayBeComplex);
|
||||
}
|
||||
|
||||
bool isClipMayBeComplex() const { return mPrimitiveFields.mClipMayBeComplex; }
|
||||
|
||||
bool setStaticMatrix(const SkMatrix* matrix) {
|
||||
delete mStaticMatrix;
|
||||
if (matrix) {
|
||||
@@ -563,6 +570,7 @@ private:
|
||||
bool mProjectBackwards = false;
|
||||
bool mProjectionReceiver = false;
|
||||
bool mAllowForceDark = true;
|
||||
bool mClipMayBeComplex = false;
|
||||
Rect mClipBounds;
|
||||
Outline mOutline;
|
||||
RevealClip mRevealClip;
|
||||
|
||||
@@ -73,7 +73,6 @@ bool SkiaDisplayList::prepareListAndChildren(
|
||||
RenderNode* childNode = child.getRenderNode();
|
||||
Matrix4 mat4(child.getRecordedMatrix());
|
||||
info.damageAccumulator->pushTransform(&mat4);
|
||||
// TODO: a layer is needed if the canvas is rotated or has a non-rect clip
|
||||
info.hasBackwardProjectedNodes = false;
|
||||
childFn(childNode, observer, info, functorsNeedLayer);
|
||||
hasBackwardProjectedNodesSubtree |= info.hasBackwardProjectedNodes;
|
||||
|
||||
@@ -113,6 +113,10 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
|
||||
// Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
|
||||
mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
|
||||
auto& renderNodeDrawable = mDisplayList->mChildNodes.back();
|
||||
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
|
||||
// Put Vulkan WebViews with non-rectangular clips in a HW layer
|
||||
renderNode->mutateStagingProperties().setClipMayBeComplex(mRecorder.isClipMayBeComplex());
|
||||
}
|
||||
drawDrawable(&renderNodeDrawable);
|
||||
|
||||
// use staging property, since recording on UI thread
|
||||
|
||||
Reference in New Issue
Block a user