Fix clip serialization crash
Can't safely rewind clip allocations, since those pointers are cached by
ClipArea. Instead add early rejection to handle most cases, and update
tests.
Change-Id: Ic32f95cf95602f427f25761a8da1583c4495f36d
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index 5c7b43f..3db28c9 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -99,6 +99,7 @@
public:
static BakedOpState* tryConstruct(LinearAllocator& allocator,
Snapshot& snapshot, const RecordedOp& recordedOp) {
+ if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
BakedOpState* bakedState = new (allocator) BakedOpState(
allocator, snapshot, recordedOp, false);
if (bakedState->computedState.clippedBounds.isEmpty()) {
@@ -118,6 +119,7 @@
static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator,
Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior) {
+ if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
bool expandForStroke = (strokeBehavior == StrokeBehavior::StyleDefined)
? (recordedOp.paint && recordedOp.paint->getStyle() != SkPaint::kFill_Style)
: true;
@@ -126,6 +128,7 @@
allocator, snapshot, recordedOp, expandForStroke);
if (bakedState->computedState.clippedBounds.isEmpty()) {
// bounds are empty, so op is rejected
+ // NOTE: this won't succeed if a clip was allocated
allocator.rewindIfLastAlloc(bakedState);
return nullptr;
}
@@ -134,7 +137,7 @@
static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator,
Snapshot& snapshot, const ShadowOp* shadowOpPtr) {
- if (snapshot.getRenderTargetClip().isEmpty()) return nullptr;
+ if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
// clip isn't empty, so construct the op
return new (allocator) BakedOpState(allocator, snapshot, shadowOpPtr);