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 |