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 "GrClipStackClip.h" | 8 #include "GrClipStackClip.h" |
9 | 9 |
10 #include "GrAppliedClip.h" | 10 #include "GrAppliedClip.h" |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 | 291 |
292 if (!reducedClip.windowRectangles().empty()) { | 292 if (!reducedClip.windowRectangles().empty()) { |
293 out->addWindowRectangles(reducedClip.windowRectangles(), fOrigin, | 293 out->addWindowRectangles(reducedClip.windowRectangles(), fOrigin, |
294 GrWindowRectsState::Mode::kExclusive); | 294 GrWindowRectsState::Mode::kExclusive); |
295 } | 295 } |
296 | 296 |
297 if (reducedClip.elements().isEmpty()) { | 297 if (reducedClip.elements().isEmpty()) { |
298 return InitialState::kAllIn == reducedClip.initialState(); | 298 return InitialState::kAllIn == reducedClip.initialState(); |
299 } | 299 } |
300 | 300 |
| 301 #ifdef SK_DEBUG |
301 SkASSERT(reducedClip.hasIBounds()); | 302 SkASSERT(reducedClip.hasIBounds()); |
| 303 SkIRect rtIBounds = SkIRect::MakeWH(renderTargetContext->width(), |
| 304 renderTargetContext->height()); |
| 305 SkIRect clipIBounds = reducedClip.ibounds().makeOffset(-fOrigin.x(), -fOrigi
n.y()); |
| 306 SkASSERT(rtIBounds.contains(clipIBounds)); // Mask shouldn't be larger than
the RT. |
| 307 #endif |
302 | 308 |
303 // An element count of 4 was chosen because of the common pattern in Blink o
f: | 309 // An element count of 4 was chosen because of the common pattern in Blink o
f: |
304 // isect RR | 310 // isect RR |
305 // diff RR | 311 // diff RR |
306 // isect convex_poly | 312 // isect convex_poly |
307 // isect convex_poly | 313 // isect convex_poly |
308 // when drawing rounded div borders. This could probably be tuned based on a | 314 // when drawing rounded div borders. This could probably be tuned based on a |
309 // configuration's relative costs of switching RTs to generate a mask vs | 315 // configuration's relative costs of switching RTs to generate a mask vs |
310 // longer shaders. | 316 // longer shaders. |
311 if (reducedClip.elements().count() <= kMaxAnalyticElements) { | 317 if (reducedClip.elements().count() <= kMaxAnalyticElements) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 return true; | 379 return true; |
374 } | 380 } |
375 | 381 |
376 //////////////////////////////////////////////////////////////////////////////// | 382 //////////////////////////////////////////////////////////////////////////////// |
377 // Create a 8-bit clip mask in alpha | 383 // Create a 8-bit clip mask in alpha |
378 | 384 |
379 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { | 385 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey
* key) { |
380 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); | 386 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
381 GrUniqueKey::Builder builder(key, kDomain, 3); | 387 GrUniqueKey::Builder builder(key, kDomain, 3); |
382 builder[0] = clipGenID; | 388 builder[0] = clipGenID; |
383 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); | 389 // SkToS16 because image filters outset layers to a size indicated by the fi
lter, which can |
384 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); | 390 // sometimes result in negative coordinates from clip space. |
| 391 builder[1] = SkToS16(bounds.fLeft) | (SkToS16(bounds.fRight) << 16); |
| 392 builder[2] = SkToS16(bounds.fTop) | (SkToS16(bounds.fBottom) << 16); |
385 } | 393 } |
386 | 394 |
387 sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, | 395 sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, |
388 const GrReducedClip& reduc
edClip) { | 396 const GrReducedClip& reduc
edClip) { |
389 GrResourceProvider* resourceProvider = context->resourceProvider(); | 397 GrResourceProvider* resourceProvider = context->resourceProvider(); |
390 GrUniqueKey key; | 398 GrUniqueKey key; |
391 GetClipMaskKey(reducedClip.elementsGenID(), reducedClip.ibounds(), &key); | 399 GetClipMaskKey(reducedClip.elementsGenID(), reducedClip.ibounds(), &key); |
392 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { | 400 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)
) { |
393 return sk_sp<GrTexture>(texture); | 401 return sk_sp<GrTexture>(texture); |
394 } | 402 } |
(...skipping 30 matching lines...) Expand all Loading... |
425 // the top left corner of the resulting rect to the top left of the texture. | 433 // the top left corner of the resulting rect to the top left of the texture. |
426 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.
height()); | 434 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.
height()); |
427 | 435 |
428 GrSWMaskHelper helper(texProvider); | 436 GrSWMaskHelper helper(texProvider); |
429 | 437 |
430 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip | 438 // Set the matrix so that rendered clip elements are transformed to mask spa
ce from clip |
431 // space. | 439 // space. |
432 SkMatrix translate; | 440 SkMatrix translate; |
433 translate.setTranslate(SkIntToScalar(-reducedClip.left()), SkIntToScalar(-re
ducedClip.top())); | 441 translate.setTranslate(SkIntToScalar(-reducedClip.left()), SkIntToScalar(-re
ducedClip.top())); |
434 | 442 |
435 helper.init(maskSpaceIBounds, &translate); | 443 if (!helper.init(maskSpaceIBounds, &translate)) { |
| 444 return nullptr; |
| 445 } |
436 helper.clear(InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x0
0); | 446 helper.clear(InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x0
0); |
437 | 447 |
438 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()
) { | 448 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()
) { |
439 const Element* element = iter.get(); | 449 const Element* element = iter.get(); |
440 SkCanvas::ClipOp op = element->getOp(); | 450 SkCanvas::ClipOp op = element->getOp(); |
441 | 451 |
442 if (SkCanvas::kIntersect_Op == op || SkCanvas::kReverseDifference_Op ==
op) { | 452 if (SkCanvas::kIntersect_Op == op || SkCanvas::kReverseDifference_Op ==
op) { |
443 // Intersect and reverse difference require modifying pixels outside
of the geometry | 453 // Intersect and reverse difference require modifying pixels outside
of the geometry |
444 // that is being "drawn". In both cases we erase all the pixels outs
ide of the geometry | 454 // that is being "drawn". In both cases we erase all the pixels outs
ide of the geometry |
445 // but leave the pixels inside the geometry alone. For reverse diffe
rence we invert all | 455 // but leave the pixels inside the geometry alone. For reverse diffe
rence we invert all |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); | 488 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); |
479 if (!result) { | 489 if (!result) { |
480 return nullptr; | 490 return nullptr; |
481 } | 491 } |
482 result->resourcePriv().setUniqueKey(key); | 492 result->resourcePriv().setUniqueKey(key); |
483 | 493 |
484 helper.toTexture(result.get()); | 494 helper.toTexture(result.get()); |
485 | 495 |
486 return result; | 496 return result; |
487 } | 497 } |
OLD | NEW |