summaryrefslogtreecommitdiff
path: root/libs/hwui/FrameBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/FrameBuilder.cpp')
-rw-r--r--libs/hwui/FrameBuilder.cpp59
1 files changed, 33 insertions, 26 deletions
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 4f51036b336e..04de98afe85c 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -782,39 +782,46 @@ void FrameBuilder::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) {
boundsTransform.mapRect(dstRect);
dstRect.doIntersect(mCanvasState.currentSnapshot()->getRenderTargetClip());
- // Allocate a holding position for the layer object (copyTo will produce, copyFrom will consume)
- OffscreenBuffer** layerHandle = mAllocator.create<OffscreenBuffer*>(nullptr);
-
- /**
- * First, defer an operation to copy out the content from the rendertarget into a layer.
- */
- auto copyToOp = mAllocator.create_trivial<CopyToLayerOp>(op, layerHandle);
- BakedOpState* bakedState = BakedOpState::directConstruct(mAllocator,
- &(currentLayer().viewportClip), dstRect, *copyToOp);
- currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::CopyToLayer);
-
- /**
- * Defer a clear rect, so that clears from multiple unclipped layers can be drawn
- * both 1) simultaneously, and 2) as long after the copyToLayer executes as possible
- */
- currentLayer().deferLayerClear(dstRect);
-
- /**
- * And stash an operation to copy that layer back under the rendertarget until
- * a balanced EndUnclippedLayerOp is seen
- */
- auto copyFromOp = mAllocator.create_trivial<CopyFromLayerOp>(op, layerHandle);
- bakedState = BakedOpState::directConstruct(mAllocator,
- &(currentLayer().viewportClip), dstRect, *copyFromOp);
- currentLayer().activeUnclippedSaveLayers.push_back(bakedState);
+ if (dstRect.isEmpty()) {
+ // Unclipped layer rejected - push a null op, so next EndUnclippedLayerOp is ignored
+ currentLayer().activeUnclippedSaveLayers.push_back(nullptr);
+ } else {
+ // Allocate a holding position for the layer object (copyTo will produce, copyFrom will consume)
+ OffscreenBuffer** layerHandle = mAllocator.create<OffscreenBuffer*>(nullptr);
+
+ /**
+ * First, defer an operation to copy out the content from the rendertarget into a layer.
+ */
+ auto copyToOp = mAllocator.create_trivial<CopyToLayerOp>(op, layerHandle);
+ BakedOpState* bakedState = BakedOpState::directConstruct(mAllocator,
+ &(currentLayer().repaintClip), dstRect, *copyToOp);
+ currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::CopyToLayer);
+
+ /**
+ * Defer a clear rect, so that clears from multiple unclipped layers can be drawn
+ * both 1) simultaneously, and 2) as long after the copyToLayer executes as possible
+ */
+ currentLayer().deferLayerClear(dstRect);
+
+ /**
+ * And stash an operation to copy that layer back under the rendertarget until
+ * a balanced EndUnclippedLayerOp is seen
+ */
+ auto copyFromOp = mAllocator.create_trivial<CopyFromLayerOp>(op, layerHandle);
+ bakedState = BakedOpState::directConstruct(mAllocator,
+ &(currentLayer().repaintClip), dstRect, *copyFromOp);
+ currentLayer().activeUnclippedSaveLayers.push_back(bakedState);
+ }
}
void FrameBuilder::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignored */) {
LOG_ALWAYS_FATAL_IF(currentLayer().activeUnclippedSaveLayers.empty(), "no layer to end!");
BakedOpState* copyFromLayerOp = currentLayer().activeUnclippedSaveLayers.back();
- currentLayer().deferUnmergeableOp(mAllocator, copyFromLayerOp, OpBatchType::CopyFromLayer);
currentLayer().activeUnclippedSaveLayers.pop_back();
+ if (copyFromLayerOp) {
+ currentLayer().deferUnmergeableOp(mAllocator, copyFromLayerOp, OpBatchType::CopyFromLayer);
+ }
}
} // namespace uirenderer