Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: src/gpu/GrClipMaskManager.cpp

Issue 808813002: Add Coverage Drawing XP (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Clean up Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "GrAAConvexPathRenderer.h" 9 #include "GrAAConvexPathRenderer.h"
10 #include "GrAAHairLinePathRenderer.h" 10 #include "GrAAHairLinePathRenderer.h"
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 // use both stencil and scissor test to the bounds for the final draw. 323 // use both stencil and scissor test to the bounds for the final draw.
324 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 324 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
325 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 325 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
326 scissorState->set(scissorSpaceIBounds); 326 scissorState->set(scissorSpaceIBounds);
327 this->setDrawStateStencil(drawState, ars); 327 this->setDrawStateStencil(drawState, ars);
328 return true; 328 return true;
329 } 329 }
330 330
331 namespace { 331 namespace {
332 //////////////////////////////////////////////////////////////////////////////// 332 ////////////////////////////////////////////////////////////////////////////////
333 // set up the OpenGL blend function to perform the specified 333 // Set a coverage drawing XPF on the drawState for the given op and invertCovera ge mode
334 // boolean operation for alpha clip mask creation 334 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState* drawState) {
335 void setup_boolean_blendcoeffs(SkRegion::Op op, GrDrawState* drawState) { 335 SkASSERT(op <= SkRegion::kLastOp);
336 // TODO: once we have a coverageDrawing XP this will all use that instead of PD 336 drawState->setCoverageSetOpXPFactory(op, invertCoverage);
337 switch (op) {
338 case SkRegion::kReplace_Op:
339 drawState->setPorterDuffXPFactory(kOne_GrBlendCoeff, kZero_GrBlendCo eff);
340 break;
341 case SkRegion::kIntersect_Op:
342 drawState->setPorterDuffXPFactory(kDC_GrBlendCoeff, kZero_GrBlendCoe ff);
343 break;
344 case SkRegion::kUnion_Op:
345 drawState->setPorterDuffXPFactory(kOne_GrBlendCoeff, kISC_GrBlendCoe ff);
346 break;
347 case SkRegion::kXOR_Op:
348 drawState->setPorterDuffXPFactory(kIDC_GrBlendCoeff, kISC_GrBlendCoe ff);
349 break;
350 case SkRegion::kDifference_Op:
351 drawState->setPorterDuffXPFactory(kZero_GrBlendCoeff, kISC_GrBlendCo eff);
352 break;
353 case SkRegion::kReverseDifference_Op:
354 drawState->setPorterDuffXPFactory(kIDC_GrBlendCoeff, kZero_GrBlendCo eff);
355 break;
356 default:
357 SkASSERT(false);
358 break;
359 }
360 } 337 }
361 } 338 }
362 339
363 //////////////////////////////////////////////////////////////////////////////// 340 ////////////////////////////////////////////////////////////////////////////////
364 bool GrClipMaskManager::drawElement(GrDrawState* drawState, 341 bool GrClipMaskManager::drawElement(GrDrawState* drawState,
365 GrColor color, 342 GrColor color,
366 GrTexture* target, 343 GrTexture* target,
367 const SkClipStack::Element* element, 344 const SkClipStack::Element* element,
368 GrPathRenderer* pr) { 345 GrPathRenderer* pr) {
369 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 346 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 void GrClipMaskManager::mergeMask(GrDrawState* drawState, 421 void GrClipMaskManager::mergeMask(GrDrawState* drawState,
445 GrTexture* dstMask, 422 GrTexture* dstMask,
446 GrTexture* srcMask, 423 GrTexture* srcMask,
447 SkRegion::Op op, 424 SkRegion::Op op,
448 const SkIRect& dstBound, 425 const SkIRect& dstBound,
449 const SkIRect& srcBound) { 426 const SkIRect& srcBound) {
450 SkAssertResult(drawState->setIdentityViewMatrix()); 427 SkAssertResult(drawState->setIdentityViewMatrix());
451 428
452 drawState->setRenderTarget(dstMask->asRenderTarget()); 429 drawState->setRenderTarget(dstMask->asRenderTarget());
453 430
454 setup_boolean_blendcoeffs(op, drawState); 431 // We want to invert the coverage here
bsalomon 2014/12/16 17:35:56 we do??
egdaniel 2014/12/17 21:12:37 changed to false and changed to use coverageProces
432 set_coverage_drawing_xpf(op, true, drawState);
455 433
456 SkMatrix sampleM; 434 SkMatrix sampleM;
457 sampleM.setIDiv(srcMask->width(), srcMask->height()); 435 sampleM.setIDiv(srcMask->width(), srcMask->height());
458 436
459 drawState->addColorProcessor( 437 drawState->addColorProcessor(
460 GrTextureDomainEffect::Create(srcMask, 438 GrTextureDomainEffect::Create(srcMask,
461 sampleM, 439 sampleM,
462 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), 440 GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
463 GrTextureDomain::kDecal_Mode, 441 GrTextureDomain::kDecal_Mode,
464 GrTextureParams::kNone_FilterMode))->unref (); 442 GrTextureParams::kNone_FilterMode))->unref ();
443 // The color passed in here does not matter since the coverageSetOpXP won't read it.
465 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound) ); 444 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound) );
466 } 445 }
467 446
468 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { 447 GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
469 GrSurfaceDesc desc; 448 GrSurfaceDesc desc;
470 desc.fFlags = kRenderTarget_GrSurfaceFlag|kNoStencil_GrSurfaceFlag; 449 desc.fFlags = kRenderTarget_GrSurfaceFlag|kNoStencil_GrSurfaceFlag;
471 desc.fWidth = width; 450 desc.fWidth = width;
472 desc.fHeight = height; 451 desc.fHeight = height;
473 desc.fConfig = kAlpha_8_GrPixelConfig; 452 desc.fConfig = kAlpha_8_GrPixelConfig;
474 453
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds); 539 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
561 SkAutoTUnref<GrTexture> temp; 540 SkAutoTUnref<GrTexture> temp;
562 541
563 // walk through each clip element and perform its set op 542 // walk through each clip element and perform its set op
564 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 543 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
565 const Element* element = iter.get(); 544 const Element* element = iter.get();
566 SkRegion::Op op = element->getOp(); 545 SkRegion::Op op = element->getOp();
567 bool invert = element->isInverseFilled(); 546 bool invert = element->isInverseFilled();
568 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 547 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
569 GrDrawState drawState(translate); 548 GrDrawState drawState(translate);
570 // We're drawing a coverage mask and want coverage to be run through the blend function. 549 drawState.enableState(GrDrawState::kClip_StateBit);
571 drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
572 GrDrawState::kClip_StateBit);
573 550
574 GrPathRenderer* pr = NULL; 551 GrPathRenderer* pr = NULL;
575 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element); 552 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element);
576 GrTexture* dst; 553 GrTexture* dst;
577 // This is the bounds of the clip element in the space of the alpha- mask. The temporary 554 // This is the bounds of the clip element in the space of the alpha- mask. The temporary
578 // mask buffer can be substantially larger than the actually clip st ack element. We 555 // mask buffer can be substantially larger than the actually clip st ack element. We
579 // touch the minimum number of pixels necessary and use decal mode t o combine it with 556 // touch the minimum number of pixels necessary and use decal mode t o combine it with
580 // the accumulator. 557 // the accumulator.
581 SkIRect maskSpaceElementIBounds; 558 SkIRect maskSpaceElementIBounds;
582 559
(...skipping 13 matching lines...) Expand all
596 fAACache.reset(); 573 fAACache.reset();
597 return NULL; 574 return NULL;
598 } 575 }
599 } 576 }
600 dst = temp; 577 dst = temp;
601 // clear the temp target and set blend to replace 578 // clear the temp target and set blend to replace
602 fClipTarget->clear(&maskSpaceElementIBounds, 579 fClipTarget->clear(&maskSpaceElementIBounds,
603 invert ? 0xffffffff : 0x00000000, 580 invert ? 0xffffffff : 0x00000000,
604 true, 581 true,
605 dst->asRenderTarget()); 582 dst->asRenderTarget());
606 setup_boolean_blendcoeffs(SkRegion::kReplace_Op, &drawState); 583 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &drawSta te);
607 } else { 584 } else {
608 // draw directly into the result with the stencil set to make th e pixels affected 585 // draw directly into the result with the stencil set to make th e pixels affected
609 // by the clip shape be non-zero. 586 // by the clip shape be non-zero.
610 dst = result; 587 dst = result;
611 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, 588 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
612 kReplace_StencilOp, 589 kReplace_StencilOp,
613 kReplace_StencilOp, 590 kReplace_StencilOp,
614 kAlways_StencilFunc, 591 kAlways_StencilFunc,
615 0xffff, 592 0xffff,
616 0xffff, 593 0xffff,
617 0xffff); 594 0xffff);
618 drawState.setStencil(kStencilInElement); 595 drawState.setStencil(kStencilInElement);
619 setup_boolean_blendcoeffs(op, &drawState); 596 set_coverage_drawing_xpf(op, invert, &drawState);
620 } 597 }
621 598
622 // We have to backup the drawstate because the drawElement call may call into 599 // The color passed in here does not matter since the coverageSetOpX P won't read it.
623 // renderers which consume it. 600 if (!this->drawElement(&drawState, GrColor_WHITE, dst, element, pr)) {
bsalomon 2014/12/16 17:35:56 Can drawElement just not take a color then?
egdaniel 2014/12/17 21:12:37 Done.
624 GrDrawState backupDrawState(drawState);
625
626 if (!this->drawElement(&drawState, invert ? GrColor_TRANS_BLACK :
627 GrColor_WHITE, dst, elem ent, pr)) {
628 fAACache.reset(); 601 fAACache.reset();
629 return NULL; 602 return NULL;
630 } 603 }
631 604
605 // We have to make a new drawstate because the drawElement call may call into
bsalomon 2014/12/16 17:35:56 I'm not sure this comment adds much value. A new d
egdaniel 2014/12/17 21:12:37 removed
606 // renderers which consume it. We also need to use a different cover age drawing xp which
607 // inverts the coverage.
608 GrDrawState backgroundDrawState(translate);
609 backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
610 backgroundDrawState.setRenderTarget(result->asRenderTarget());
611
632 if (useTemp) { 612 if (useTemp) {
633 // Now draw into the accumulator using the real operation and th e temp buffer as a 613 // Now draw into the accumulator using the real operation and th e temp buffer as a
634 // texture 614 // texture
635 this->mergeMask(&backupDrawState, 615 this->mergeMask(&backgroundDrawState,
636 result, 616 result,
637 temp, 617 temp,
638 op, 618 op,
639 maskSpaceIBounds, 619 maskSpaceIBounds,
640 maskSpaceElementIBounds); 620 maskSpaceElementIBounds);
641 } else { 621 } else {
622 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState);
642 // Draw to the exterior pixels (those with a zero stencil value) . 623 // Draw to the exterior pixels (those with a zero stencil value) .
643 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, 624 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
644 kZero_StencilOp, 625 kZero_StencilOp,
645 kZero_StencilOp, 626 kZero_StencilOp,
646 kEqual_StencilFunc, 627 kEqual_StencilFunc,
647 0xffff, 628 0xffff,
648 0x0000, 629 0x0000,
649 0xffff); 630 0xffff);
650 backupDrawState.setStencil(kDrawOutsideElement); 631 backgroundDrawState.setStencil(kDrawOutsideElement);
651 fClipTarget->drawSimpleRect(&backupDrawState, 632 // The color passed in here does not matter since the coverageSe tOpXP won't read it.
652 invert ? GrColor_WHITE : GrColor_TRA NS_BLACK, 633 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds);
653 clipSpaceIBounds);
654 } 634 }
655 } else { 635 } else {
656 GrDrawState drawState(translate); 636 GrDrawState drawState(translate);
657 drawState.enableState(GrDrawState::kCoverageDrawing_StateBit | 637 drawState.enableState(GrDrawState::kClip_StateBit);
658 GrDrawState::kClip_StateBit);
659 638
660 // all the remaining ops can just be directly draw into the accumula tion buffer 639 // all the remaining ops can just be directly draw into the accumula tion buffer
661 setup_boolean_blendcoeffs(op, &drawState); 640 set_coverage_drawing_xpf(op, false, &drawState);
641 // The color passed in here does not matter since the coverageSetOpX P won't read it.
662 this->drawElement(&drawState, GrColor_WHITE, result, element); 642 this->drawElement(&drawState, GrColor_WHITE, result, element);
663 } 643 }
664 } 644 }
665 645
666 fCurrClipMaskType = kAlpha_ClipMaskType; 646 fCurrClipMaskType = kAlpha_ClipMaskType;
667 return result; 647 return result;
668 } 648 }
669 649
670 //////////////////////////////////////////////////////////////////////////////// 650 ////////////////////////////////////////////////////////////////////////////////
671 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 651 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 } 1061 }
1082 1062
1083 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer, 1063 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer,
1084 GrStencilSettings* settings) { 1064 GrStencilSettings* settings) {
1085 // TODO: dynamically attach a stencil buffer 1065 // TODO: dynamically attach a stencil buffer
1086 if (stencilBuffer) { 1066 if (stencilBuffer) {
1087 int stencilBits = stencilBuffer->bits(); 1067 int stencilBits = stencilBuffer->bits();
1088 this->adjustStencilParams(settings, fClipMode, stencilBits); 1068 this->adjustStencilParams(settings, fClipMode, stencilBits);
1089 } 1069 }
1090 } 1070 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698