| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrReducedClip.h" | 8 #include "GrReducedClip.h" |
| 9 | 9 |
| 10 #include "GrClip.h" | 10 #include "GrClip.h" |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 based on later intersect operations, and perhaps remove intersect-rects. We coul
d optionally | 336 based on later intersect operations, and perhaps remove intersect-rects. We coul
d optionally |
| 337 take a rect in case the caller knows a bound on what is to be drawn through this
clip. | 337 take a rect in case the caller knows a bound on what is to be drawn through this
clip. |
| 338 */ | 338 */ |
| 339 GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds
) { | 339 GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds
) { |
| 340 SkASSERT(!queryBounds.isEmpty()); | 340 SkASSERT(!queryBounds.isEmpty()); |
| 341 | 341 |
| 342 // The clip established by the element list might be cached based on the las
t | 342 // The clip established by the element list might be cached based on the las
t |
| 343 // generation id. When we make early returns, we do not know what was the ge
neration | 343 // generation id. When we make early returns, we do not know what was the ge
neration |
| 344 // id that lead to the state. Make a conservative guess. | 344 // id that lead to the state. Make a conservative guess. |
| 345 fGenID = stack.getTopmostGenID(); | 345 fGenID = stack.getTopmostGenID(); |
| 346 | 346 fHasIBounds = false; |
| 347 // TODO: instead devise a way of telling the caller to disregard some or all
of the clip bounds. | |
| 348 fIBounds = GrClip::GetPixelIBounds(queryBounds); | |
| 349 | 347 |
| 350 if (stack.isWideOpen()) { | 348 if (stack.isWideOpen()) { |
| 351 fInitialState = InitialState::kAllIn; | 349 fInitialState = InitialState::kAllIn; |
| 352 return; | 350 return; |
| 353 } | 351 } |
| 354 | 352 |
| 355 SkClipStack::BoundsType stackBoundsType; | 353 SkClipStack::BoundsType stackBoundsType; |
| 356 SkRect stackBounds; | 354 SkRect stackBounds; |
| 357 bool iior; | 355 bool iior; |
| 358 stack.getBounds(&stackBounds, &stackBoundsType, &iior); | 356 stack.getBounds(&stackBounds, &stackBoundsType, &iior); |
| 359 | 357 |
| 360 if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds)
) { | 358 if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds)
) { |
| 361 bool insideOut = SkClipStack::kInsideOut_BoundsType == stackBoundsType; | 359 bool insideOut = SkClipStack::kInsideOut_BoundsType == stackBoundsType; |
| 362 fInitialState = insideOut ? InitialState::kAllIn : InitialState::kAllOut
; | 360 fInitialState = insideOut ? InitialState::kAllIn : InitialState::kAllOut
; |
| 363 return; | 361 return; |
| 364 } | 362 } |
| 365 | 363 |
| 366 if (iior) { | 364 if (iior) { |
| 367 // "Is intersection of rects" means the clip is a single rect indicated
by the stack bounds. | 365 // "Is intersection of rects" means the clip is a single rect indicated
by the stack bounds. |
| 368 // This should only be true if aa/non-aa status matches among all elemen
ts. | 366 // This should only be true if aa/non-aa status matches among all elemen
ts. |
| 369 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); | 367 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); |
| 370 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); | 368 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); |
| 371 if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) { | 369 if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) { |
| 372 // The clip is a non-aa rect. This is the one spot where we can actu
ally implement the | 370 // The clip is a non-aa rect. This is the one spot where we can actu
ally implement the |
| 373 // clip (using fIBounds) rather than just telling the caller what it
should be. | 371 // clip (using fIBounds) rather than just telling the caller what it
should be. |
| 374 stackBounds.round(&fIBounds); | 372 stackBounds.round(&fIBounds); |
| 373 fHasIBounds = true; |
| 375 fInitialState = fIBounds.isEmpty() ? InitialState::kAllOut : Initial
State::kAllIn; | 374 fInitialState = fIBounds.isEmpty() ? InitialState::kAllOut : Initial
State::kAllIn; |
| 376 return; | 375 return; |
| 377 } | 376 } |
| 378 if (GrClip::IsInsideClip(stackBounds, queryBounds)) { | 377 if (GrClip::IsInsideClip(stackBounds, queryBounds)) { |
| 379 fInitialState = InitialState::kAllIn; | 378 fInitialState = InitialState::kAllIn; |
| 380 return; | 379 return; |
| 381 } | 380 } |
| 382 | 381 |
| 383 SkAssertResult(fIBounds.intersect(GrClip::GetPixelIBounds(stackBounds)))
; | 382 SkRect tightBounds; |
| 383 SkAssertResult(tightBounds.intersect(stackBounds, queryBounds)); |
| 384 fIBounds = GrClip::GetPixelIBounds(tightBounds); |
| 384 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOu
tsideClip above. | 385 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOu
tsideClip above. |
| 386 fHasIBounds = true; |
| 385 | 387 |
| 386 // Implement the clip with an AA rect element. | 388 // Implement the clip with an AA rect element. |
| 387 fElements.addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/); | 389 fElements.addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/); |
| 388 fRequiresAA = true; | 390 fRequiresAA = true; |
| 389 | 391 |
| 390 fInitialState = InitialState::kAllOut; | 392 fInitialState = InitialState::kAllOut; |
| 391 return; | 393 return; |
| 392 } | 394 } |
| 393 | 395 |
| 394 SkRect tighterQuery = queryBounds; | 396 SkRect tighterQuery = queryBounds; |
| 395 if (SkClipStack::kNormal_BoundsType == stackBoundsType) { | 397 if (SkClipStack::kNormal_BoundsType == stackBoundsType) { |
| 396 // Tighten the query by introducing a new clip at the stack's pixel boun
daries. (This new | 398 // Tighten the query by introducing a new clip at the stack's pixel boun
daries. (This new |
| 397 // clip will be enforced by the scissor through fIBounds.) | 399 // clip will be enforced by the scissor through fIBounds.) |
| 398 SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds
))); | 400 SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds
))); |
| 399 fIBounds = GrClip::GetPixelIBounds(tighterQuery); | |
| 400 } | 401 } |
| 401 | 402 |
| 403 fIBounds = GrClip::GetPixelIBounds(tighterQuery); |
| 402 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid
eClip above. | 404 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid
eClip above. |
| 405 fHasIBounds = true; |
| 403 | 406 |
| 404 // Now that we have determined the bounds to use and filtered out the trivia
l cases, call the | 407 // Now that we have determined the bounds to use and filtered out the trivia
l cases, call the |
| 405 // helper that actually walks the stack. | 408 // helper that actually walks the stack. |
| 406 fInitialState = reduced_stack_walker(stack, tighterQuery, fIBounds, &fElemen
ts, &fGenID, | 409 fInitialState = reduced_stack_walker(stack, tighterQuery, fIBounds, &fElemen
ts, &fGenID, |
| 407 &fRequiresAA); | 410 &fRequiresAA); |
| 408 } | 411 } |
| OLD | NEW |