summaryrefslogtreecommitdiff
path: root/libs/hwui/LayerBuilder.cpp
diff options
context:
space:
mode:
author Chris Craik <ccraik@google.com> 2016-03-28 12:54:07 -0700
committer Chris Craik <ccraik@google.com> 2016-03-29 13:30:15 -0700
commit80d2ade939153da87b3cd3b0a69a713bf68b64ba (patch)
tree40b554ece6ad2253c4176abc151e3c0d46d8db24 /libs/hwui/LayerBuilder.cpp
parentede7d958ab54a0701baa8ae8b494e8ea905c61c6 (diff)
Overdraw avoidance in new pipeline
bug:27873093 Adds the simple overdraw avoidance optimization to the new pipeline. This means when LayerBuilder defers draws that are opaque over the full area of the repaint region, it will discard all drawing content beneth. Also moves a lot of complexity out of BakedOpState's header. Change-Id: Iffca6d8e1b170ef31a5d6c83d25592670e02323d
Diffstat (limited to 'libs/hwui/LayerBuilder.cpp')
-rw-r--r--libs/hwui/LayerBuilder.cpp34
1 files changed, 25 insertions, 9 deletions
diff --git a/libs/hwui/LayerBuilder.cpp b/libs/hwui/LayerBuilder.cpp
index e6a95ff177a4..eea11bff7d8a 100644
--- a/libs/hwui/LayerBuilder.cpp
+++ b/libs/hwui/LayerBuilder.cpp
@@ -236,6 +236,21 @@ void LayerBuilder::deferLayerClear(const Rect& rect) {
mClearRects.push_back(rect);
}
+void LayerBuilder::onDeferOp(LinearAllocator& allocator, const BakedOpState* bakedState) {
+ if (bakedState->op->opId != RecordedOpId::CopyToLayerOp) {
+ // First non-CopyToLayer, so stop stashing up layer clears for unclipped save layers,
+ // and issue them together in one draw.
+ flushLayerClears(allocator);
+
+ if (CC_UNLIKELY(activeUnclippedSaveLayers.empty()
+ && bakedState->computedState.opaqueOverClippedBounds
+ && bakedState->computedState.clippedBounds.contains(repaintRect))) {
+ // discard all deferred drawing ops, since new one will occlude them
+ clear();
+ }
+ }
+}
+
void LayerBuilder::flushLayerClears(LinearAllocator& allocator) {
if (CC_UNLIKELY(!mClearRects.empty())) {
const int vertCount = mClearRects.size() * 4;
@@ -270,11 +285,7 @@ void LayerBuilder::flushLayerClears(LinearAllocator& allocator) {
void LayerBuilder::deferUnmergeableOp(LinearAllocator& allocator,
BakedOpState* op, batchid_t batchId) {
- if (batchId != OpBatchType::CopyToLayer) {
- // if first op after one or more unclipped saveLayers, flush the layer clears
- flushLayerClears(allocator);
- }
-
+ onDeferOp(allocator, op);
OpBatch* targetBatch = mBatchLookup[batchId];
size_t insertBatchIndex = mBatches.size();
@@ -295,10 +306,7 @@ void LayerBuilder::deferUnmergeableOp(LinearAllocator& allocator,
void LayerBuilder::deferMergeableOp(LinearAllocator& allocator,
BakedOpState* op, batchid_t batchId, mergeid_t mergeId) {
- if (batchId != OpBatchType::CopyToLayer) {
- // if first op after one or more unclipped saveLayers, flush the layer clears
- flushLayerClears(allocator);
- }
+ onDeferOp(allocator, op);
MergingOpBatch* targetBatch = nullptr;
// Try to merge with any existing batch with same mergeId
@@ -348,6 +356,14 @@ void LayerBuilder::replayBakedOpsImpl(void* arg,
}
}
+void LayerBuilder::clear() {
+ mBatches.clear();
+ for (int i = 0; i < OpBatchType::Count; i++) {
+ mBatchLookup[i] = nullptr;
+ mMergingBatchLookup[i].clear();
+ }
+}
+
void LayerBuilder::dump() const {
ALOGD("LayerBuilder %p, %ux%u buffer %p, blo %p, rn %p (%s)",
this, width, height, offscreenBuffer, beginLayerOp,