summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libs/hwui/DisplayList.cpp19
-rw-r--r--libs/hwui/DisplayList.h3
-rw-r--r--libs/hwui/DisplayListOp.h21
-rw-r--r--libs/hwui/OpenGLRenderer.cpp10
-rw-r--r--libs/hwui/OpenGLRenderer.h1
-rw-r--r--libs/hwui/Snapshot.cpp9
6 files changed, 38 insertions, 25 deletions
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 398f719..8bfbf22 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -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
outputViewProperties(level);
#endif
@@ -377,6 +379,9 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
}
}
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) {
renderer.setAlpha(mAlpha);
} else {
@@ -392,9 +397,14 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
}
}
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,
SkRegion::kIntersect_Op);
}
+ return status;
}
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, "",
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
- if (mAlpha < 1 && !mCaching && CC_LIKELY(deferredList)) {
- // flush before a saveLayerAlpha/setAlpha
- // TODO: make this cleaner
- drawGlStatus |= deferredList->flush(renderer, dirty, flags, level);
- }
- setViewProperties(renderer, level);
+ drawGlStatus |= setViewProperties(renderer, dirty, flags, level, deferredList);
if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 86c9ec0..f2a2383 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -75,7 +75,8 @@ public:
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);
ANDROID_API size_t getSize();
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 1bae0ff..93b281a 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -100,7 +100,7 @@ public:
virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
uint32_t level, bool caching, int multipliedAlpha, DeferredDisplayList* deferredList) {
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
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
* see OpenGLRenderer::disallowDeferral()
*/
- virtual bool requiresDrawOpFlush() { return false; }
+ virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return false; }
};
class DrawOp : public DisplayListOp {
@@ -272,7 +272,7 @@ public:
}
virtual const char* name() { return "SaveLayer"; }
- virtual bool requiresDrawOpFlush() { return true; }
+ virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
private:
Rect mArea;
@@ -294,7 +294,7 @@ public:
}
virtual const char* name() { return "SaveLayerAlpha"; }
- virtual bool requiresDrawOpFlush() { return true; }
+ virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
private:
Rect mArea;
@@ -434,7 +434,16 @@ public:
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:
+ inline bool hasRectToRectOp() {
+ return mOp == SkRegion::kIntersect_Op || mOp == SkRegion::kReplace_Op;
+ }
Rect mArea;
SkRegion::Op mOp;
};
@@ -455,7 +464,7 @@ public:
}
virtual const char* name() { return "ClipPath"; }
- virtual bool requiresDrawOpFlush() { return true; }
+ virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
private:
SkPath* mPath;
@@ -478,7 +487,7 @@ public:
}
virtual const char* name() { return "ClipRegion"; }
- virtual bool requiresDrawOpFlush() { return true; }
+ virtual bool requiresDrawOpFlush(OpenGLRenderer& renderer) { return true; }
private:
SkRegion* mRegion;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 6b614a7..e5a1a84 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1284,6 +1284,10 @@ void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
}
}
+bool OpenGLRenderer::hasRectToRectTransform() {
+ return CC_LIKELY(mSnapshot->transform->rectToRect());
+}
+
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
mSnapshot->transform->copyTo(*matrix);
}
@@ -1505,8 +1509,10 @@ void OpenGLRenderer::setupDraw(bool clear) {
if (clear) clearLayerRegions();
// Make sure setScissor & setStencil happen at the beginning of
// this method
- if (mDirtyClip && mCaches.scissorEnabled) {
- setScissorFromClip();
+ if (mDirtyClip) {
+ if (mCaches.scissorEnabled) {
+ setScissorFromClip();
+ }
setStencilFromClip();
}
mDescription.reset();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e12083c..80f2081 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -198,6 +198,7 @@ public:
virtual void scale(float sx, float sy);
virtual void skew(float sx, float sy);
+ bool hasRectToRectTransform();
ANDROID_API void getMatrix(SkMatrix* matrix);
virtual void setMatrix(SkMatrix* matrix);
virtual void concatMatrix(SkMatrix* matrix);
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 19a5db7..923913e 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -132,15 +132,6 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) {
}
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: {
setClip(r.left, r.top, r.right, r.bottom);
clipped = true;