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 |