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

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: more nits 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
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrDrawState.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
366 GrTexture* target, 342 GrTexture* target,
367 const SkClipStack::Element* element, 343 const SkClipStack::Element* element,
368 GrPathRenderer* pr) { 344 GrPathRenderer* pr) {
369 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 345 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
370 346
371 drawState->setRenderTarget(target->asRenderTarget()); 347 drawState->setRenderTarget(target->asRenderTarget());
372 348
349 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
350 // which ignores color.
351 GrColor color = GrColor_WHITE;
352
373 // TODO: Draw rrects directly here. 353 // TODO: Draw rrects directly here.
374 switch (element->getType()) { 354 switch (element->getType()) {
375 case Element::kEmpty_Type: 355 case Element::kEmpty_Type:
376 SkDEBUGFAIL("Should never get here with an empty element."); 356 SkDEBUGFAIL("Should never get here with an empty element.");
377 break; 357 break;
378 case Element::kRect_Type: 358 case Element::kRect_Type:
379 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers 359 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers
380 // the entire mask bounds and writes 0 outside the rect. 360 // the entire mask bounds and writes 0 outside the rect.
381 if (element->isAA()) { 361 if (element->isAA()) {
382 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget, 362 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 void GrClipMaskManager::mergeMask(GrDrawState* drawState, 424 void GrClipMaskManager::mergeMask(GrDrawState* drawState,
445 GrTexture* dstMask, 425 GrTexture* dstMask,
446 GrTexture* srcMask, 426 GrTexture* srcMask,
447 SkRegion::Op op, 427 SkRegion::Op op,
448 const SkIRect& dstBound, 428 const SkIRect& dstBound,
449 const SkIRect& srcBound) { 429 const SkIRect& srcBound) {
450 SkAssertResult(drawState->setIdentityViewMatrix()); 430 SkAssertResult(drawState->setIdentityViewMatrix());
451 431
452 drawState->setRenderTarget(dstMask->asRenderTarget()); 432 drawState->setRenderTarget(dstMask->asRenderTarget());
453 433
454 setup_boolean_blendcoeffs(op, drawState); 434 // We want to invert the coverage here
435 set_coverage_drawing_xpf(op, false, drawState);
455 436
456 SkMatrix sampleM; 437 SkMatrix sampleM;
457 sampleM.setIDiv(srcMask->width(), srcMask->height()); 438 sampleM.setIDiv(srcMask->width(), srcMask->height());
458 439
459 drawState->addColorProcessor( 440 drawState->addCoverageProcessor(
460 GrTextureDomainEffect::Create(srcMask, 441 GrTextureDomainEffect::Create(srcMask,
461 sampleM, 442 sampleM,
462 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), 443 GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
463 GrTextureDomain::kDecal_Mode, 444 GrTextureDomain::kDecal_Mode,
464 GrTextureParams::kNone_FilterMode))->unref (); 445 GrTextureParams::kNone_FilterMode))->unref ();
446 // The color passed in here does not matter since the coverageSetOpXP won't read it.
465 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound) ); 447 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound) );
466 } 448 }
467 449
468 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { 450 GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
469 GrSurfaceDesc desc; 451 GrSurfaceDesc desc;
470 desc.fFlags = kRenderTarget_GrSurfaceFlag|kNoStencil_GrSurfaceFlag; 452 desc.fFlags = kRenderTarget_GrSurfaceFlag|kNoStencil_GrSurfaceFlag;
471 desc.fWidth = width; 453 desc.fWidth = width;
472 desc.fHeight = height; 454 desc.fHeight = height;
473 desc.fConfig = kAlpha_8_GrPixelConfig; 455 desc.fConfig = kAlpha_8_GrPixelConfig;
474 456
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds); 542 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
561 SkAutoTUnref<GrTexture> temp; 543 SkAutoTUnref<GrTexture> temp;
562 544
563 // walk through each clip element and perform its set op 545 // walk through each clip element and perform its set op
564 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 546 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
565 const Element* element = iter.get(); 547 const Element* element = iter.get();
566 SkRegion::Op op = element->getOp(); 548 SkRegion::Op op = element->getOp();
567 bool invert = element->isInverseFilled(); 549 bool invert = element->isInverseFilled();
568 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 550 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
569 GrDrawState drawState(translate); 551 GrDrawState drawState(translate);
570 // We're drawing a coverage mask and want coverage to be run through the blend function. 552 drawState.enableState(GrDrawState::kClip_StateBit);
571 drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
572 GrDrawState::kClip_StateBit);
573 553
574 GrPathRenderer* pr = NULL; 554 GrPathRenderer* pr = NULL;
575 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element); 555 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element);
576 GrTexture* dst; 556 GrTexture* dst;
577 // This is the bounds of the clip element in the space of the alpha- mask. The temporary 557 // 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 558 // 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 559 // touch the minimum number of pixels necessary and use decal mode t o combine it with
580 // the accumulator. 560 // the accumulator.
581 SkIRect maskSpaceElementIBounds; 561 SkIRect maskSpaceElementIBounds;
582 562
(...skipping 13 matching lines...) Expand all
596 fAACache.reset(); 576 fAACache.reset();
597 return NULL; 577 return NULL;
598 } 578 }
599 } 579 }
600 dst = temp; 580 dst = temp;
601 // clear the temp target and set blend to replace 581 // clear the temp target and set blend to replace
602 fClipTarget->clear(&maskSpaceElementIBounds, 582 fClipTarget->clear(&maskSpaceElementIBounds,
603 invert ? 0xffffffff : 0x00000000, 583 invert ? 0xffffffff : 0x00000000,
604 true, 584 true,
605 dst->asRenderTarget()); 585 dst->asRenderTarget());
606 setup_boolean_blendcoeffs(SkRegion::kReplace_Op, &drawState); 586 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &drawSta te);
607 } else { 587 } else {
608 // draw directly into the result with the stencil set to make th e pixels affected 588 // draw directly into the result with the stencil set to make th e pixels affected
609 // by the clip shape be non-zero. 589 // by the clip shape be non-zero.
610 dst = result; 590 dst = result;
611 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, 591 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
612 kReplace_StencilOp, 592 kReplace_StencilOp,
613 kReplace_StencilOp, 593 kReplace_StencilOp,
614 kAlways_StencilFunc, 594 kAlways_StencilFunc,
615 0xffff, 595 0xffff,
616 0xffff, 596 0xffff,
617 0xffff); 597 0xffff);
618 drawState.setStencil(kStencilInElement); 598 drawState.setStencil(kStencilInElement);
619 setup_boolean_blendcoeffs(op, &drawState); 599 set_coverage_drawing_xpf(op, invert, &drawState);
620 } 600 }
621 601
622 // We have to backup the drawstate because the drawElement call may call into 602 if (!this->drawElement(&drawState, dst, element, pr)) {
623 // renderers which consume it.
624 GrDrawState backupDrawState(drawState);
625
626 if (!this->drawElement(&drawState, invert ? GrColor_TRANS_BLACK :
627 GrColor_WHITE, dst, elem ent, pr)) {
628 fAACache.reset(); 603 fAACache.reset();
629 return NULL; 604 return NULL;
630 } 605 }
631 606
607 GrDrawState backgroundDrawState(translate);
608 backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
609 backgroundDrawState.setRenderTarget(result->asRenderTarget());
610
632 if (useTemp) { 611 if (useTemp) {
633 // Now draw into the accumulator using the real operation and th e temp buffer as a 612 // Now draw into the accumulator using the real operation and th e temp buffer as a
634 // texture 613 // texture
635 this->mergeMask(&backupDrawState, 614 this->mergeMask(&backgroundDrawState,
636 result, 615 result,
637 temp, 616 temp,
638 op, 617 op,
639 maskSpaceIBounds, 618 maskSpaceIBounds,
640 maskSpaceElementIBounds); 619 maskSpaceElementIBounds);
641 } else { 620 } else {
621 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState);
642 // Draw to the exterior pixels (those with a zero stencil value) . 622 // Draw to the exterior pixels (those with a zero stencil value) .
643 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, 623 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
644 kZero_StencilOp, 624 kZero_StencilOp,
645 kZero_StencilOp, 625 kZero_StencilOp,
646 kEqual_StencilFunc, 626 kEqual_StencilFunc,
647 0xffff, 627 0xffff,
648 0x0000, 628 0x0000,
649 0xffff); 629 0xffff);
650 backupDrawState.setStencil(kDrawOutsideElement); 630 backgroundDrawState.setStencil(kDrawOutsideElement);
651 fClipTarget->drawSimpleRect(&backupDrawState, 631 // The color passed in here does not matter since the coverageSe tOpXP won't read it.
652 invert ? GrColor_WHITE : GrColor_TRA NS_BLACK, 632 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds);
653 clipSpaceIBounds);
654 } 633 }
655 } else { 634 } else {
656 GrDrawState drawState(translate); 635 GrDrawState drawState(translate);
657 drawState.enableState(GrDrawState::kCoverageDrawing_StateBit | 636 drawState.enableState(GrDrawState::kClip_StateBit);
658 GrDrawState::kClip_StateBit);
659 637
660 // all the remaining ops can just be directly draw into the accumula tion buffer 638 // all the remaining ops can just be directly draw into the accumula tion buffer
661 setup_boolean_blendcoeffs(op, &drawState); 639 set_coverage_drawing_xpf(op, false, &drawState);
662 this->drawElement(&drawState, GrColor_WHITE, result, element); 640 // The color passed in here does not matter since the coverageSetOpX P won't read it.
641 this->drawElement(&drawState, result, element);
663 } 642 }
664 } 643 }
665 644
666 fCurrClipMaskType = kAlpha_ClipMaskType; 645 fCurrClipMaskType = kAlpha_ClipMaskType;
667 return result; 646 return result;
668 } 647 }
669 648
670 //////////////////////////////////////////////////////////////////////////////// 649 ////////////////////////////////////////////////////////////////////////////////
671 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 650 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
672 // (as opposed to canvas) coordinates 651 // (as opposed to canvas) coordinates
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 } 1060 }
1082 1061
1083 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer, 1062 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer,
1084 GrStencilSettings* settings) { 1063 GrStencilSettings* settings) {
1085 // TODO: dynamically attach a stencil buffer 1064 // TODO: dynamically attach a stencil buffer
1086 if (stencilBuffer) { 1065 if (stencilBuffer) {
1087 int stencilBits = stencilBuffer->bits(); 1066 int stencilBits = stencilBuffer->bits();
1088 this->adjustStencilParams(settings, fClipMode, stencilBits); 1067 this->adjustStencilParams(settings, fClipMode, stencilBits);
1089 } 1068 }
1090 } 1069 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrDrawState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698