diff options
author | 2017-03-06 13:51:43 -0800 | |
---|---|---|
committer | 2017-03-06 13:51:44 -0800 | |
commit | 49b403dc9c47ada51c8e5b883347682a868515f8 (patch) | |
tree | 1bc4b9b604b1e7f0ff468b2e67958bc07d916f9f /libs/hwui/BakedOpState.cpp | |
parent | 1e92e7fbfc128a3103e98f12d579ae01d027e2a4 (diff) |
Workaround arc textures drawing outside of bounds
Fixes: 34077513
Test: hwui unit tests passing
This fixes an issue where drawArc operations would cause artifacts by
drawing outside of the clip / screen damage area. We now more
conservatively clip drawArc operations specifically, as they tend to
draw into the outer parts of their path textures more than other
operations.
A more long term fix would involve alignment between draw operation
sizing (in terms of what's resolved in a BakedOpState), and
PathTexture sizing (which currently conservatively expands beyond
stroked op bounds).
Change-Id: I5aff39cc04382323b457b159974032f5f371251a
Diffstat (limited to 'libs/hwui/BakedOpState.cpp')
-rw-r--r-- | libs/hwui/BakedOpState.cpp | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp index 9f98241c6caa..9823a02dc847 100644 --- a/libs/hwui/BakedOpState.cpp +++ b/libs/hwui/BakedOpState.cpp @@ -31,7 +31,7 @@ static int computeClipSideFlags(const Rect& clip, const Rect& bounds) { } ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, - const RecordedOp& recordedOp, bool expandForStroke) { + const RecordedOp& recordedOp, bool expandForStroke, bool expandForPathTexture) { // resolvedMatrix = parentMatrix * localMatrix transform.loadMultiply(*snapshot.transform, recordedOp.localMatrix); @@ -40,6 +40,8 @@ ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& s if (CC_UNLIKELY(expandForStroke)) { // account for non-hairline stroke clippedBounds.outset(recordedOp.paint->getStrokeWidth() * 0.5f); + } else if (CC_UNLIKELY(expandForPathTexture)) { + clippedBounds.outset(1); } transform.mapRect(clippedBounds); if (CC_UNLIKELY(expandForStroke @@ -111,7 +113,7 @@ BakedOpState* BakedOpState::tryConstruct(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp) { if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr; BakedOpState* bakedState = allocator.create_trivial<BakedOpState>( - allocator, snapshot, recordedOp, false); + allocator, snapshot, recordedOp, false, false); if (bakedState->computedState.clippedBounds.isEmpty()) { // bounds are empty, so op is rejected allocator.rewindIfLastAlloc(bakedState); @@ -127,14 +129,14 @@ BakedOpState* BakedOpState::tryConstructUnbounded(LinearAllocator& allocator, } BakedOpState* BakedOpState::tryStrokeableOpConstruct(LinearAllocator& allocator, - Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior) { + Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior, + bool expandForPathTexture) { if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr; - bool expandForStroke = (strokeBehavior == StrokeBehavior::StyleDefined) - ? (recordedOp.paint && recordedOp.paint->getStyle() != SkPaint::kFill_Style) - : true; + bool expandForStroke = (strokeBehavior == StrokeBehavior::Forced + || (recordedOp.paint && recordedOp.paint->getStyle() != SkPaint::kFill_Style)); BakedOpState* bakedState = allocator.create_trivial<BakedOpState>( - allocator, snapshot, recordedOp, expandForStroke); + allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture); if (bakedState->computedState.clippedBounds.isEmpty()) { // bounds are empty, so op is rejected // NOTE: this won't succeed if a clip was allocated |