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 "GrClipMaskManager.h" | 8 #include "GrClipMaskManager.h" |
9 #include "GrCaps.h" | 9 #include "GrCaps.h" |
10 #include "GrDrawingManager.h" | 10 #include "GrDrawingManager.h" |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 sk_sp<GrFragmentProcessor> clipFP; | 299 sk_sp<GrFragmentProcessor> clipFP; |
300 if (requiresAA && | 300 if (requiresAA && |
301 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf
fset, devBounds, | 301 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf
fset, devBounds, |
302 &clipFP)) { | 302 &clipFP)) { |
303 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 303 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
304 scissorSpaceIBounds.offset(-clip.origin()); | 304 scissorSpaceIBounds.offset(-clip.origin()); |
305 if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) { | 305 if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) { |
306 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds
); | 306 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds
); |
307 return true; | 307 return true; |
308 } | 308 } |
309 out->makeFPBased(std::move(clipFP)); | 309 out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds
)); |
310 return true; | 310 return true; |
311 } | 311 } |
312 } | 312 } |
313 | 313 |
314 // If the stencil buffer is multisampled we can use it to do everything. | 314 // If the stencil buffer is multisampled we can use it to do everything. |
315 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { | 315 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { |
316 sk_sp<GrTexture> result; | 316 sk_sp<GrTexture> result; |
317 | 317 |
318 // The top-left of the mask corresponds to the top-left corner of the bo
unds. | 318 // The top-left of the mask corresponds to the top-left corner of the bo
unds. |
319 SkVector clipToMaskOffset = { | 319 SkVector clipToMaskOffset = { |
(...skipping 20 matching lines...) Expand all Loading... |
340 clipSpaceIBounds); | 340 clipSpaceIBounds); |
341 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug | 341 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug |
342 SkASSERT(result); | 342 SkASSERT(result); |
343 } | 343 } |
344 | 344 |
345 if (result) { | 345 if (result) { |
346 // The mask's top left coord should be pinned to the rounded-out top
left corner of | 346 // The mask's top left coord should be pinned to the rounded-out top
left corner of |
347 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. | 347 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. |
348 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; | 348 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; |
349 rtSpaceMaskBounds.offset(-clip.origin()); | 349 rtSpaceMaskBounds.offset(-clip.origin()); |
350 out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds)
); | 350 out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds)
, |
| 351 SkRect::Make(rtSpaceMaskBounds)); |
351 return true; | 352 return true; |
352 } | 353 } |
353 // if alpha clip mask creation fails fall through to the non-AA code pat
hs | 354 // if alpha clip mask creation fails fall through to the non-AA code pat
hs |
354 } | 355 } |
355 | 356 |
356 // use the stencil clip if we can't represent the clip as a rectangle. | 357 // use the stencil clip if we can't represent the clip as a rectangle. |
357 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); | 358 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); |
358 CreateStencilClipMask(context, | 359 CreateStencilClipMask(context, |
359 drawContext, | 360 drawContext, |
360 genID, | 361 genID, |
361 initialState, | 362 initialState, |
362 elements, | 363 elements, |
363 clipSpaceIBounds, | 364 clipSpaceIBounds, |
364 clipSpaceToStencilSpaceOffset); | 365 clipSpaceToStencilSpaceOffset); |
365 | 366 |
366 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it | 367 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it |
367 // only guarantees that the stencil mask is correct within the bounds it was
passed, so we must | 368 // only guarantees that the stencil mask is correct within the bounds it was
passed, so we must |
368 // use both stencil and scissor test to the bounds for the final draw. | 369 // use both stencil and scissor test to the bounds for the final draw. |
369 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 370 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
370 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); | 371 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); |
371 out->makeScissoredStencil(true, scissorSpaceIBounds); | 372 out->makeScissoredStencil(scissorSpaceIBounds); |
372 return true; | 373 return true; |
373 } | 374 } |
374 | 375 |
375 static bool stencil_element(GrDrawContext* dc, | 376 static bool stencil_element(GrDrawContext* dc, |
376 const GrFixedClip& clip, | 377 const GrFixedClip& clip, |
377 const GrUserStencilSettings* ss, | 378 const GrUserStencilSettings* ss, |
378 const SkMatrix& viewMatrix, | 379 const SkMatrix& viewMatrix, |
379 const SkClipStack::Element* element) { | 380 const SkClipStack::Element* element) { |
380 | 381 |
381 // TODO: Draw rrects directly here. | 382 // TODO: Draw rrects directly here. |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 GrReducedClip::kAllIn_InitialState =
= initialState); | 588 GrReducedClip::kAllIn_InitialState =
= initialState); |
588 | 589 |
589 // walk through each clip element and perform its set op | 590 // walk through each clip element and perform its set op |
590 // with the existing clip. | 591 // with the existing clip. |
591 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { | 592 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { |
592 const Element* element = iter.get(); | 593 const Element* element = iter.get(); |
593 bool useHWAA = element->isAA() && drawContext->isStencilBufferMultis
ampled(); | 594 bool useHWAA = element->isAA() && drawContext->isStencilBufferMultis
ampled(); |
594 | 595 |
595 bool fillInverted = false; | 596 bool fillInverted = false; |
596 // enabled at bottom of loop | 597 // enabled at bottom of loop |
597 clip.enableStencilClip(false); | 598 clip.disableStencilClip(); |
598 | 599 |
599 // This will be used to determine whether the clip shape can be rend
ered into the | 600 // This will be used to determine whether the clip shape can be rend
ered into the |
600 // stencil with arbitrary stencil settings. | 601 // stencil with arbitrary stencil settings. |
601 GrPathRenderer::StencilSupport stencilSupport; | 602 GrPathRenderer::StencilSupport stencilSupport; |
602 | 603 |
603 SkRegion::Op op = element->getOp(); | 604 SkRegion::Op op = element->getOp(); |
604 | 605 |
605 GrPathRenderer* pr = nullptr; | 606 GrPathRenderer* pr = nullptr; |
606 SkPath clipPath; | 607 SkPath clipPath; |
607 if (Element::kRect_Type == element->getType()) { | 608 if (Element::kRect_Type == element->getType()) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 args.fIsAA = element->isAA(); | 684 args.fIsAA = element->isAA(); |
684 args.fShape = &shape; | 685 args.fShape = &shape; |
685 pr->stencilPath(args); | 686 pr->stencilPath(args); |
686 } | 687 } |
687 } | 688 } |
688 } | 689 } |
689 } | 690 } |
690 | 691 |
691 // now we modify the clip bit by rendering either the clip | 692 // now we modify the clip bit by rendering either the clip |
692 // element directly or a bounding rect of the entire clip. | 693 // element directly or a bounding rect of the entire clip. |
693 clip.enableStencilClip(true); | |
694 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass
; ++pass) { | 694 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass
; ++pass) { |
695 | 695 |
696 if (drawDirectToClip) { | 696 if (drawDirectToClip) { |
697 if (Element::kRect_Type == element->getType()) { | 697 if (Element::kRect_Type == element->getType()) { |
| 698 clip.enableStencilClip(element->getRect().makeOffset(tra
nslate.fX, |
| 699 tra
nslate.fY)); |
698 drawContext->drawContextPriv().stencilRect(clip, *pass,
useHWAA, viewMatrix, | 700 drawContext->drawContextPriv().stencilRect(clip, *pass,
useHWAA, viewMatrix, |
699 element->getR
ect()); | 701 element->getR
ect()); |
700 } else { | 702 } else { |
701 GrShape shape(clipPath, GrStyle::SimpleFill()); | 703 GrShape shape(clipPath, GrStyle::SimpleFill()); |
702 GrPaint paint; | 704 GrPaint paint; |
| 705 SkRect bounds = clipPath.getBounds(); |
| 706 bounds.offset(translate.fX, translate.fY); |
| 707 clip.enableStencilClip(bounds); |
703 paint.setXPFactory(GrDisableColorXPFactory::Make()); | 708 paint.setXPFactory(GrDisableColorXPFactory::Make()); |
704 paint.setAntiAlias(element->isAA()); | 709 paint.setAntiAlias(element->isAA()); |
705 GrPathRenderer::DrawPathArgs args; | 710 GrPathRenderer::DrawPathArgs args; |
706 args.fResourceProvider = context->resourceProvider(); | 711 args.fResourceProvider = context->resourceProvider(); |
707 args.fPaint = &paint; | 712 args.fPaint = &paint; |
708 args.fUserStencilSettings = *pass; | 713 args.fUserStencilSettings = *pass; |
709 args.fDrawContext = drawContext; | 714 args.fDrawContext = drawContext; |
710 args.fClip = &clip; | 715 args.fClip = &clip; |
711 args.fViewMatrix = &viewMatrix; | 716 args.fViewMatrix = &viewMatrix; |
712 args.fShape = &shape; | 717 args.fShape = &shape; |
713 args.fAntiAlias = false; | 718 args.fAntiAlias = false; |
714 args.fGammaCorrect = false; | 719 args.fGammaCorrect = false; |
715 pr->drawPath(args); | 720 pr->drawPath(args); |
716 } | 721 } |
717 } else { | 722 } else { |
718 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 723 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
719 // draw rect in clip space. | 724 // draw rect in clip space. |
| 725 SkRect bounds = SkRect::Make(clipSpaceIBounds); |
| 726 bounds.offset(translate.fX, translate.fY); |
| 727 clip.enableStencilClip(bounds); |
720 drawContext->drawContextPriv().stencilRect(clip, *pass, fals
e, viewMatrix, | 728 drawContext->drawContextPriv().stencilRect(clip, *pass, fals
e, viewMatrix, |
721 SkRect::Make(clip
SpaceIBounds)); | 729 SkRect::Make(clip
SpaceIBounds)); |
722 } | 730 } |
723 } | 731 } |
724 } | 732 } |
725 } | 733 } |
726 return true; | 734 return true; |
727 } | 735 } |
728 | 736 |
729 //////////////////////////////////////////////////////////////////////////////// | 737 //////////////////////////////////////////////////////////////////////////////// |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); | 805 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); |
798 if (!result) { | 806 if (!result) { |
799 return nullptr; | 807 return nullptr; |
800 } | 808 } |
801 result->resourcePriv().setUniqueKey(key); | 809 result->resourcePriv().setUniqueKey(key); |
802 | 810 |
803 helper.toTexture(result.get()); | 811 helper.toTexture(result.get()); |
804 | 812 |
805 return result; | 813 return result; |
806 } | 814 } |
OLD | NEW |