Chromium Code Reviews| 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 } | 311 } |
| 312 result->popHead(); | 312 result->popHead(); |
| 313 element = result->headIter().get(); | 313 element = result->headIter().get(); |
| 314 } | 314 } |
| 315 } | 315 } |
| 316 } | 316 } |
| 317 *requiresAA = numAAElements > 0; | 317 *requiresAA = numAAElements > 0; |
| 318 | 318 |
| 319 if (0 == result->count()) { | 319 if (0 == result->count()) { |
| 320 if (initialState == InitialTriState::kAllIn) { | 320 if (initialState == InitialTriState::kAllIn) { |
| 321 *resultGenID = SkClipStack::kWideOpenGenID; | 321 *resultGenID = SkClipStack::kWideOpenGenID; |
|
csmartdalton
2016/08/16 05:18:49
In fact, this can be wrong if you have a clip with
bsalomon
2016/08/16 14:14:40
If I follow, I think it is correct. I think the fu
| |
| 322 } else { | 322 } else { |
| 323 *resultGenID = SkClipStack::kEmptyGenID; | 323 *resultGenID = SkClipStack::kEmptyGenID; |
| 324 } | 324 } |
| 325 } | 325 } |
| 326 | 326 |
| 327 SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); | 327 SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); |
| 328 SkASSERT(InitialTriState::kUnknown != initialState); | 328 SkASSERT(InitialTriState::kUnknown != initialState); |
| 329 return static_cast<GrReducedClip::InitialState>(initialState); | 329 return static_cast<GrReducedClip::InitialState>(initialState); |
| 330 } | 330 } |
| 331 | 331 |
| 332 /* | 332 /* |
| 333 There are plenty of optimizations that could be added here. Maybe flips could be folded into | 333 There are plenty of optimizations that could be added here. Maybe flips could be folded into |
| 334 earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps | 334 earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps |
| 335 for the case where the bounds are kInsideOut_BoundsType. We could restrict earli er operations | 335 for the case where the bounds are kInsideOut_BoundsType. We could restrict earli er operations |
| 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 fHasIBounds = false; | 346 fHasIBounds = false; |
| 347 | 347 |
| 348 if (stack.isWideOpen()) { | 348 if (stack.isWideOpen()) { |
| 349 fGenID = SkClipStack::kWideOpenGenID; | |
| 349 fInitialState = InitialState::kAllIn; | 350 fInitialState = InitialState::kAllIn; |
| 350 return; | 351 return; |
| 351 } | 352 } |
| 352 | 353 |
| 353 SkClipStack::BoundsType stackBoundsType; | 354 SkClipStack::BoundsType stackBoundsType; |
| 354 SkRect stackBounds; | 355 SkRect stackBounds; |
| 355 bool iior; | 356 bool iior; |
| 356 stack.getBounds(&stackBounds, &stackBoundsType, &iior); | 357 stack.getBounds(&stackBounds, &stackBoundsType, &iior); |
| 357 | 358 |
| 358 if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds) ) { | 359 if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds) ) { |
| 359 bool insideOut = SkClipStack::kInsideOut_BoundsType == stackBoundsType; | 360 if (SkClipStack::kInsideOut_BoundsType == stackBoundsType) { |
| 360 fInitialState = insideOut ? InitialState::kAllIn : InitialState::kAllOut ; | 361 fGenID = SkClipStack::kWideOpenGenID; |
| 362 fInitialState = InitialState::kAllIn; | |
| 363 } else { | |
| 364 fGenID = SkClipStack::kEmptyGenID; | |
| 365 fInitialState = InitialState::kAllOut; | |
| 366 } | |
| 361 return; | 367 return; |
| 362 } | 368 } |
| 363 | 369 |
| 364 if (iior) { | 370 if (iior) { |
| 365 // "Is intersection of rects" means the clip is a single rect indicated by the stack bounds. | 371 // "Is intersection of rects" means the clip is a single rect indicated by the stack bounds. |
| 366 // This should only be true if aa/non-aa status matches among all elemen ts. | |
| 367 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); | 372 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); |
| 373 if (GrClip::IsInsideClip(stackBounds, queryBounds)) { | |
| 374 fGenID = SkClipStack::kWideOpenGenID; | |
| 375 fInitialState = InitialState::kAllIn; | |
| 376 return; | |
| 377 } | |
| 378 // iior should only be true if aa/non-aa status matches among all elemen ts. | |
| 368 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); | 379 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); |
| 369 if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) { | 380 if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) { |
| 370 // The clip is a non-aa rect. This is the one spot where we can actu ally implement the | 381 // The clip is a non-aa rect. This is the one spot where we can actu ally implement the |
| 371 // clip (using fIBounds) rather than just telling the caller what it should be. | 382 // clip (using fIBounds) rather than just telling the caller what it should be. |
| 372 stackBounds.round(&fIBounds); | 383 stackBounds.round(&fIBounds); |
| 373 fHasIBounds = true; | 384 if (fIBounds.isEmpty()) { |
| 374 fInitialState = fIBounds.isEmpty() ? InitialState::kAllOut : Initial State::kAllIn; | 385 fGenID = SkClipStack::kEmptyGenID; |
| 375 return; | 386 fInitialState = InitialState::kAllOut; |
| 376 } | 387 } else { |
| 377 if (GrClip::IsInsideClip(stackBounds, queryBounds)) { | 388 fHasIBounds = true; |
| 378 fInitialState = InitialState::kAllIn; | 389 fInitialState = InitialState::kAllIn; |
| 390 } | |
| 379 return; | 391 return; |
| 380 } | 392 } |
| 381 | 393 |
| 382 SkRect tightBounds; | 394 SkRect tightBounds; |
| 383 SkAssertResult(tightBounds.intersect(stackBounds, queryBounds)); | 395 SkAssertResult(tightBounds.intersect(stackBounds, queryBounds)); |
| 384 fIBounds = GrClip::GetPixelIBounds(tightBounds); | 396 fIBounds = GrClip::GetPixelIBounds(tightBounds); |
| 385 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOu tsideClip above. | 397 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOu tsideClip above. |
| 386 fHasIBounds = true; | 398 fHasIBounds = true; |
| 387 | 399 |
| 388 // Implement the clip with an AA rect element. | 400 // Implement the clip with an AA rect element. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 402 | 414 |
| 403 fIBounds = GrClip::GetPixelIBounds(tighterQuery); | 415 fIBounds = GrClip::GetPixelIBounds(tighterQuery); |
| 404 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid eClip above. | 416 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid eClip above. |
| 405 fHasIBounds = true; | 417 fHasIBounds = true; |
| 406 | 418 |
| 407 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the | 419 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the |
| 408 // helper that actually walks the stack. | 420 // helper that actually walks the stack. |
| 409 fInitialState = reduced_stack_walker(stack, tighterQuery, fIBounds, &fElemen ts, &fGenID, | 421 fInitialState = reduced_stack_walker(stack, tighterQuery, fIBounds, &fElemen ts, &fGenID, |
| 410 &fRequiresAA); | 422 &fRequiresAA); |
| 411 } | 423 } |
| OLD | NEW |