Merge "Fix clipping and stencil layer issues"
This commit is contained in:
@ -356,7 +356,9 @@ void DisplayList::outputViewProperties(uint32_t level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
|
status_t DisplayList::setViewProperties(OpenGLRenderer& renderer, Rect& dirty,
|
||||||
|
int32_t flags, uint32_t level, DeferredDisplayList* deferredList) {
|
||||||
|
status_t status = DrawGlInfo::kStatusDone;
|
||||||
#if DEBUG_DISPLAYLIST
|
#if DEBUG_DISPLAYLIST
|
||||||
outputViewProperties(level);
|
outputViewProperties(level);
|
||||||
#endif
|
#endif
|
||||||
@ -377,6 +379,9 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mAlpha < 1 && !mCaching) {
|
if (mAlpha < 1 && !mCaching) {
|
||||||
|
// flush since we'll either enter a Layer, or set alpha, both not supported in deferral
|
||||||
|
status |= deferredList->flush(renderer, dirty, flags, level);
|
||||||
|
|
||||||
if (!mHasOverlappingRendering) {
|
if (!mHasOverlappingRendering) {
|
||||||
renderer.setAlpha(mAlpha);
|
renderer.setAlpha(mAlpha);
|
||||||
} else {
|
} else {
|
||||||
@ -392,9 +397,14 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mClipChildren && !mCaching) {
|
if (mClipChildren && !mCaching) {
|
||||||
|
if (CC_UNLIKELY(!renderer.hasRectToRectTransform())) {
|
||||||
|
// flush, since clip will likely be a region
|
||||||
|
status |= deferredList->flush(renderer, dirty, flags, level);
|
||||||
|
}
|
||||||
renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
|
renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
|
||||||
SkRegion::kIntersect_Op);
|
SkRegion::kIntersect_Op);
|
||||||
}
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level,
|
status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level,
|
||||||
@ -414,12 +424,7 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag
|
|||||||
DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
|
DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
|
||||||
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
|
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
|
||||||
|
|
||||||
if (mAlpha < 1 && !mCaching && CC_LIKELY(deferredList)) {
|
drawGlStatus |= setViewProperties(renderer, dirty, flags, level, deferredList);
|
||||||
// flush before a saveLayerAlpha/setAlpha
|
|
||||||
// TODO: make this cleaner
|
|
||||||
drawGlStatus |= deferredList->flush(renderer, dirty, flags, level);
|
|
||||||
}
|
|
||||||
setViewProperties(renderer, level);
|
|
||||||
|
|
||||||
if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
|
if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
|
||||||
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
|
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
|
||||||
|
@ -75,7 +75,8 @@ public:
|
|||||||
kReplayFlag_ClipChildren = 0x1
|
kReplayFlag_ClipChildren = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
|
status_t setViewProperties(OpenGLRenderer& renderer, Rect& dirty,
|
||||||
|
int32_t flags, uint32_t level, DeferredDisplayList* deferredList);
|
||||||
void outputViewProperties(uint32_t level);
|
void outputViewProperties(uint32_t level);
|
||||||
|
|
||||||
ANDROID_API size_t getSize();
|
ANDROID_API size_t getSize();
|
||||||
|
@ -100,7 +100,7 @@ public:
|
|||||||
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
|
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
|
||||||
uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) {
|
uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) {
|
||||||
status_t status = DrawGlInfo::kStatusDone;
|
status_t status = DrawGlInfo::kStatusDone;
|
||||||
if (deferredList && requiresDrawOpFlush()) {
|
if (deferredList && requiresDrawOpFlush(renderer)) {
|
||||||
// will be setting renderer state that affects ops in deferredList, so flush list first
|
// will be setting renderer state that affects ops in deferredList, so flush list first
|
||||||
status |= deferredList->flush(renderer, dirty, flags, level);
|
status |= deferredList->flush(renderer, dirty, flags, level);
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ public:
|
|||||||
* Returns true if it affects renderer drawing state in such a way to break deferral
|
* Returns true if it affects renderer drawing state in such a way to break deferral
|
||||||
* see OpenGLRenderer::disallowDeferral()
|
* see OpenGLRenderer::disallowDeferral()
|
||||||
*/
|
*/
|
||||||
virtual bool requiresDrawOpFlush() { return false; }
|
virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawOp : public DisplayListOp {
|
class DrawOp : public DisplayListOp {
|
||||||
@ -272,7 +272,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() { return "SaveLayer"; }
|
virtual const char* name() { return "SaveLayer"; }
|
||||||
virtual bool requiresDrawOpFlush() { return true; }
|
virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Rect mArea;
|
Rect mArea;
|
||||||
@ -294,7 +294,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() { return "SaveLayerAlpha"; }
|
virtual const char* name() { return "SaveLayerAlpha"; }
|
||||||
virtual bool requiresDrawOpFlush() { return true; }
|
virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Rect mArea;
|
Rect mArea;
|
||||||
@ -434,7 +434,16 @@ public:
|
|||||||
|
|
||||||
virtual const char* name() { return "ClipRect"; }
|
virtual const char* name() { return "ClipRect"; }
|
||||||
|
|
||||||
|
virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) {
|
||||||
|
// TODO: currently, we flush when we *might* cause a clip region to exist. Ideally, we
|
||||||
|
// should only flush when a non-rectangular clip would result
|
||||||
|
return !renderer.hasRectToRectTransform() || !hasRectToRectOp();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline bool hasRectToRectOp() {
|
||||||
|
return mOp == SkRegion::kIntersect_Op || mOp == SkRegion::kReplace_Op;
|
||||||
|
}
|
||||||
Rect mArea;
|
Rect mArea;
|
||||||
SkRegion::Op mOp;
|
SkRegion::Op mOp;
|
||||||
};
|
};
|
||||||
@ -455,7 +464,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() { return "ClipPath"; }
|
virtual const char* name() { return "ClipPath"; }
|
||||||
virtual bool requiresDrawOpFlush() { return true; }
|
virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkPath* mPath;
|
SkPath* mPath;
|
||||||
@ -478,7 +487,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() { return "ClipRegion"; }
|
virtual const char* name() { return "ClipRegion"; }
|
||||||
virtual bool requiresDrawOpFlush() { return true; }
|
virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkRegion* mRegion;
|
SkRegion* mRegion;
|
||||||
|
@ -1284,6 +1284,10 @@ void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGLRenderer::hasRectToRectTransform() {
|
||||||
|
return CC_LIKELY(mSnapshot->transform->rectToRect());
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
|
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
|
||||||
mSnapshot->transform->copyTo(*matrix);
|
mSnapshot->transform->copyTo(*matrix);
|
||||||
}
|
}
|
||||||
@ -1505,8 +1509,10 @@ void OpenGLRenderer::setupDraw(bool clear) {
|
|||||||
if (clear) clearLayerRegions();
|
if (clear) clearLayerRegions();
|
||||||
// Make sure setScissor & setStencil happen at the beginning of
|
// Make sure setScissor & setStencil happen at the beginning of
|
||||||
// this method
|
// this method
|
||||||
if (mDirtyClip && mCaches.scissorEnabled) {
|
if (mDirtyClip) {
|
||||||
setScissorFromClip();
|
if (mCaches.scissorEnabled) {
|
||||||
|
setScissorFromClip();
|
||||||
|
}
|
||||||
setStencilFromClip();
|
setStencilFromClip();
|
||||||
}
|
}
|
||||||
mDescription.reset();
|
mDescription.reset();
|
||||||
|
@ -198,6 +198,7 @@ public:
|
|||||||
virtual void scale(float sx, float sy);
|
virtual void scale(float sx, float sy);
|
||||||
virtual void skew(float sx, float sy);
|
virtual void skew(float sx, float sy);
|
||||||
|
|
||||||
|
bool hasRectToRectTransform();
|
||||||
ANDROID_API void getMatrix(SkMatrix* matrix);
|
ANDROID_API void getMatrix(SkMatrix* matrix);
|
||||||
virtual void setMatrix(SkMatrix* matrix);
|
virtual void setMatrix(SkMatrix* matrix);
|
||||||
virtual void concatMatrix(SkMatrix* matrix);
|
virtual void concatMatrix(SkMatrix* matrix);
|
||||||
|
@ -132,15 +132,6 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SkRegion::kUnion_Op: {
|
|
||||||
if (CC_UNLIKELY(!clipRegion->isEmpty())) {
|
|
||||||
ensureClipRegion();
|
|
||||||
clipped = clipRegionOp(r.left, r.top, r.right, r.bottom, SkRegion::kUnion_Op);
|
|
||||||
} else {
|
|
||||||
clipped = clipRect->unionWith(r);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SkRegion::kReplace_Op: {
|
case SkRegion::kReplace_Op: {
|
||||||
setClip(r.left, r.top, r.right, r.bottom);
|
setClip(r.left, r.top, r.right, r.bottom);
|
||||||
clipped = true;
|
clipped = true;
|
||||||
|
Reference in New Issue
Block a user