OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 typedef SkClipStack::Element Element; | 10 typedef SkClipStack::Element Element; |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 break; | 295 break; |
296 } else { | 296 } else { |
297 if (element->isAA()) { | 297 if (element->isAA()) { |
298 --numAAElements; | 298 --numAAElements; |
299 } | 299 } |
300 result->popHead(); | 300 result->popHead(); |
301 element = result->headIter().get(); | 301 element = result->headIter().get(); |
302 } | 302 } |
303 } | 303 } |
304 } | 304 } |
305 if (requiresAA) { | 305 *requiresAA = numAAElements > 0; |
306 *requiresAA = numAAElements > 0; | |
307 } | |
308 | 306 |
309 if (0 == result->count()) { | 307 if (0 == result->count()) { |
310 if (*initialState == GrReducedClip::kAllIn_InitialState) { | 308 if (*initialState == GrReducedClip::kAllIn_InitialState) { |
311 *resultGenID = SkClipStack::kWideOpenGenID; | 309 *resultGenID = SkClipStack::kWideOpenGenID; |
312 } else { | 310 } else { |
313 *resultGenID = SkClipStack::kEmptyGenID; | 311 *resultGenID = SkClipStack::kEmptyGenID; |
314 } | 312 } |
315 } | 313 } |
316 } | 314 } |
317 | 315 |
318 /* | 316 /* |
319 There are plenty of optimizations that could be added here. Maybe flips could be folded into | 317 There are plenty of optimizations that could be added here. Maybe flips could be folded into |
320 earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps | 318 earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps |
321 for the case where the bounds are kInsideOut_BoundsType. We could restrict earli er operations | 319 for the case where the bounds are kInsideOut_BoundsType. We could restrict earli er operations |
322 based on later intersect operations, and perhaps remove intersect-rects. We coul d optionally | 320 based on later intersect operations, and perhaps remove intersect-rects. We coul d optionally |
323 take a rect in case the caller knows a bound on what is to be drawn through this clip. | 321 take a rect in case the caller knows a bound on what is to be drawn through this clip. |
324 */ | 322 */ |
325 void GrReducedClip::ReduceClipStack(const SkClipStack& stack, | 323 void GrReducedClip::ReduceClipStack(const SkClipStack& stack, |
326 const SkIRect& queryBounds, | 324 const SkIRect& queryBounds, |
327 ElementList* result, | 325 ElementList* result, |
328 int32_t* resultGenID, | 326 int32_t* resultGenID, |
329 InitialState* initialState, | 327 InitialState* initialState, |
330 SkIRect* tighterBounds, | 328 SkIRect* tighterBounds, |
331 bool* requiresAA) { | 329 bool* requiresAA) { |
330 SkASSERT(tighterBounds); | |
331 SkASSERT(requiresAA); | |
332 result->reset(); | 332 result->reset(); |
333 | 333 |
334 // The clip established by the element list might be cached based on the las t | 334 // The clip established by the element list might be cached based on the las t |
335 // generation id. When we make early returns, we do not know what was the ge neration | 335 // generation id. When we make early returns, we do not know what was the ge neration |
336 // id that lead to the state. Make a conservative guess. | 336 // id that lead to the state. Make a conservative guess. |
337 *resultGenID = stack.getTopmostGenID(); | 337 *resultGenID = stack.getTopmostGenID(); |
338 | 338 |
339 if (stack.isWideOpen()) { | 339 if (stack.isWideOpen()) { |
340 *initialState = kAllIn_InitialState; | 340 *initialState = kAllIn_InitialState; |
341 return; | 341 return; |
(...skipping 10 matching lines...) Expand all Loading... | |
352 | 352 |
353 const SkIRect* bounds = &queryBounds; | 353 const SkIRect* bounds = &queryBounds; |
354 | 354 |
355 SkRect scalarQueryBounds = SkRect::Make(queryBounds); | 355 SkRect scalarQueryBounds = SkRect::Make(queryBounds); |
356 | 356 |
357 if (iior) { | 357 if (iior) { |
358 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); | 358 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); |
359 SkRect isectRect; | 359 SkRect isectRect; |
360 if (stackBounds.contains(scalarQueryBounds)) { | 360 if (stackBounds.contains(scalarQueryBounds)) { |
361 *initialState = GrReducedClip::kAllIn_InitialState; | 361 *initialState = GrReducedClip::kAllIn_InitialState; |
362 if (tighterBounds) { | 362 *tighterBounds = queryBounds; |
robertphillips
2016/07/07 20:30:48
missing ' ' ?
bsalomon
2016/07/07 23:53:13
Done.
| |
363 *tighterBounds = queryBounds; | 363 *requiresAA = false; |
364 } | |
365 if (requiresAA) { | |
366 *requiresAA = false; | |
367 } | |
368 } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) { | 364 } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) { |
369 // If the caller asked for tighter integer bounds we may be able to | 365 // If the caller asked for tighter integer bounds we may be able to |
370 // return kAllIn and give the bounds with no elements | 366 // return kAllIn and give the bounds with no elements |
371 if (tighterBounds) { | 367 isectRect.roundOut(tighterBounds); |
372 isectRect.roundOut(tighterBounds); | 368 SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); |
373 SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); | 369 if (scalarTighterBounds == isectRect) { |
374 if (scalarTighterBounds == isectRect) { | 370 // the round-out didn't add any area outside the clip rect. |
375 // the round-out didn't add any area outside the clip rect. | 371 *requiresAA = false; |
376 if (requiresAA) { | 372 *initialState = GrReducedClip::kAllIn_InitialState; |
377 *requiresAA = false; | 373 return; |
378 } | |
379 *initialState = GrReducedClip::kAllIn_InitialState; | |
380 return; | |
381 } | |
382 } | 374 } |
383 *initialState = kAllOut_InitialState; | 375 *initialState = kAllOut_InitialState; |
384 // iior should only be true if aa/non-aa status matches among all el ements. | 376 // iior should only be true if aa/non-aa status matches among all el ements. |
385 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); | 377 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); |
386 bool doAA = iter.prev()->isAA(); | 378 bool doAA = iter.prev()->isAA(); |
387 result->addToHead(isectRect, SkRegion::kReplace_Op, doAA); | 379 result->addToHead(isectRect, SkRegion::kReplace_Op, doAA); |
388 if (requiresAA) { | 380 *requiresAA = doAA; |
389 *requiresAA = doAA; | |
390 } | |
391 } else { | 381 } else { |
392 *initialState = kAllOut_InitialState; | 382 *initialState = kAllOut_InitialState; |
393 if (requiresAA) { | 383 *requiresAA = false; |
394 *requiresAA = false; | |
395 } | |
396 } | 384 } |
397 return; | 385 return; |
398 } else { | 386 } else { |
399 if (SkClipStack::kNormal_BoundsType == stackBoundsType) { | 387 if (SkClipStack::kNormal_BoundsType == stackBoundsType) { |
400 if (!SkRect::Intersects(stackBounds, scalarQueryBounds)) { | 388 if (!SkRect::Intersects(stackBounds, scalarQueryBounds)) { |
401 *initialState = kAllOut_InitialState; | 389 *initialState = kAllOut_InitialState; |
402 if (requiresAA) { | 390 *requiresAA = false; |
403 *requiresAA = false; | |
404 } | |
405 return; | 391 return; |
406 } | 392 } |
407 if (tighterBounds) { | 393 SkIRect stackIBounds; |
408 SkIRect stackIBounds; | 394 stackBounds.roundOut(&stackIBounds); |
409 stackBounds.roundOut(&stackIBounds); | 395 if (!tighterBounds->intersect(queryBounds, stackIBounds)) { |
410 if (!tighterBounds->intersect(queryBounds, stackIBounds)) { | 396 SkASSERT(0); |
411 SkASSERT(0); | 397 tighterBounds->setEmpty(); |
412 tighterBounds->setEmpty(); | |
413 } | |
414 bounds = tighterBounds; | |
415 } | 398 } |
399 bounds = tighterBounds; | |
416 } else { | 400 } else { |
417 if (stackBounds.contains(scalarQueryBounds)) { | 401 if (stackBounds.contains(scalarQueryBounds)) { |
418 *initialState = kAllOut_InitialState; | 402 *initialState = kAllOut_InitialState; |
419 // We know that the bounding box contains all the pixels that ar e outside the clip, | 403 // We know that the bounding box contains all the pixels that ar e outside the clip, |
420 // but we don't know that *all* the pixels in the box are outsid e the clip. So | 404 // but we don't know that *all* the pixels in the box are outsid e the clip. So |
421 // proceed to walking the stack. | 405 // proceed to walking the stack. |
422 } | 406 } |
423 if (tighterBounds) { | 407 *tighterBounds = queryBounds; |
424 *tighterBounds = queryBounds; | |
425 } | |
426 } | 408 } |
427 } | 409 } |
428 | 410 |
429 SkRect scalarBounds = SkRect::Make(*bounds); | 411 SkRect scalarBounds = SkRect::Make(*bounds); |
430 | 412 |
431 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the | 413 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the |
432 // helper that actually walks the stack. | 414 // helper that actually walks the stack. |
433 reduced_stack_walker(stack, scalarBounds, result, resultGenID, initialState, requiresAA); | 415 reduced_stack_walker(stack, scalarBounds, result, resultGenID, initialState, requiresAA); |
434 | 416 |
435 // The list that was computed in this function may be cached based on the ge n id of the last | 417 // The list that was computed in this function may be cached based on the ge n id of the last |
436 // element. | 418 // element. |
437 SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); | 419 SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); |
438 } | 420 } |
OLD | NEW |