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

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

Issue 1754563003: Begin weaning GrClipMaskManager off of GrDrawTarget (take 2) (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix fAuditTrail uses Created 4 years, 9 months 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/GrDrawContext.cpp » ('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 "GrCaps.h" 9 #include "GrCaps.h"
10 #include "GrDrawingManager.h" 10 #include "GrDrawingManager.h"
11 #include "GrDrawContext.h" 11 #include "GrDrawContextPriv.h"
12 #include "GrDrawTarget.h" 12 #include "GrDrawTarget.h"
13 #include "GrGpuResourcePriv.h" 13 #include "GrGpuResourcePriv.h"
14 #include "GrPaint.h" 14 #include "GrPaint.h"
15 #include "GrPathRenderer.h" 15 #include "GrPathRenderer.h"
16 #include "GrRenderTarget.h" 16 #include "GrRenderTarget.h"
17 #include "GrRenderTargetPriv.h" 17 #include "GrRenderTargetPriv.h"
18 #include "GrResourceProvider.h" 18 #include "GrResourceProvider.h"
19 #include "GrStencilAttachment.h" 19 #include "GrStencilAttachment.h"
20 #include "GrSWMaskHelper.h" 20 #include "GrSWMaskHelper.h"
21 #include "SkRasterClip.h" 21 #include "SkRasterClip.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 } 152 }
153 153
154 GrResourceProvider* GrClipMaskManager::resourceProvider() { 154 GrResourceProvider* GrClipMaskManager::resourceProvider() {
155 return fDrawTarget->cmmAccess().resourceProvider(); 155 return fDrawTarget->cmmAccess().resourceProvider();
156 } 156 }
157 /* 157 /*
158 * This method traverses the clip stack to see if the GrSoftwarePathRenderer 158 * This method traverses the clip stack to see if the GrSoftwarePathRenderer
159 * will be used on any element. If so, it returns true to indicate that the 159 * will be used on any element. If so, it returns true to indicate that the
160 * entire clip should be rendered in SW and then uploaded en masse to the gpu. 160 * entire clip should be rendered in SW and then uploaded en masse to the gpu.
161 */ 161 */
162 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, 162 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context,
163 const GrPipelineBuilder& pipelineBuilder,
163 const GrRenderTarget* rt, 164 const GrRenderTarget* rt,
164 const SkVector& clipToMaskOffset, 165 const SkVector& clipToMaskOffset,
165 const GrReducedClip::ElementList& elements ) { 166 const GrReducedClip::ElementList& elements ) {
166 // TODO: generalize this function so that when 167 // TODO: generalize this function so that when
167 // a clip gets complex enough it can just be done in SW regardless 168 // a clip gets complex enough it can just be done in SW regardless
168 // of whether it would invoke the GrSoftwarePathRenderer. 169 // of whether it would invoke the GrSoftwarePathRenderer.
169 170
170 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 171 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
171 // space. 172 // space.
172 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 173 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
173 174
174 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 175 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
175 const Element* element = iter.get(); 176 const Element* element = iter.get();
176 177
177 SkRegion::Op op = element->getOp(); 178 SkRegion::Op op = element->getOp();
178 bool invert = element->isInverseFilled(); 179 bool invert = element->isInverseFilled();
179 bool needsStencil = invert || 180 bool needsStencil = invert ||
180 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op; 181 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op;
181 182
182 if (PathNeedsSWRenderer(this->getContext(), pipelineBuilder.getStencil() .isDisabled(), 183 if (PathNeedsSWRenderer(context, pipelineBuilder.getStencil().isDisabled (),
183 rt, translate, element, nullptr, needsStencil)) { 184 rt, translate, element, nullptr, needsStencil)) {
184 return true; 185 return true;
185 } 186 }
186 } 187 }
187 return false; 188 return false;
188 } 189 }
189 190
190 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements, 191 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements,
191 bool abortIfAA, 192 bool abortIfAA,
192 SkVector& clipToRTOffset, 193 SkVector& clipToRTOffset,
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 if (intersect.intersect(clip.irect())) { 310 if (intersect.intersect(clip.irect())) {
310 *out = GrClip(intersect); 311 *out = GrClip(intersect);
311 } else { 312 } else {
312 *out = clip; 313 *out = clip;
313 } 314 }
314 break; 315 break;
315 } 316 }
316 } 317 }
317 } 318 }
318 319
320 bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilde r,
321 GrPipelineBuilder::AutoRestoreStencil* ars,
322 const SkIRect& clipScissor,
323 const SkRect* devBounds,
324 GrAppliedClip* out) {
325 if (kRespectClip_StencilClipMode == fClipMode) {
326 fClipMode = kIgnoreClip_StencilClipMode;
327 }
328
329 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
330
331 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
332 SkIRect devBoundsScissor;
333 const SkIRect* scissor = &clipScissor;
334 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
335 if (doDevBoundsClip) {
336 devBounds->roundOut(&devBoundsScissor);
337 if (devBoundsScissor.intersect(clipScissor)) {
338 scissor = &devBoundsScissor;
339 }
340 }
341
342 if (scissor->contains(clipSpaceRTIBounds)) {
343 // This counts as wide open
344 this->setPipelineBuilderStencil(pipelineBuilder, ars);
345 return true;
346 }
347
348 if (clipSpaceRTIBounds.intersect(*scissor)) {
349 out->fScissorState.set(clipSpaceRTIBounds);
350 this->setPipelineBuilderStencil(pipelineBuilder, ars);
351 return true;
352 }
353 return false;
354 }
355
319 //////////////////////////////////////////////////////////////////////////////// 356 ////////////////////////////////////////////////////////////////////////////////
320 // sort out what kind of clip mask needs to be created: alpha, stencil, 357 // sort out what kind of clip mask needs to be created: alpha, stencil,
321 // scissor, or entirely software 358 // scissor, or entirely software
322 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, 359 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
323 GrPipelineBuilder::AutoRestoreStencil* ars , 360 GrPipelineBuilder::AutoRestoreStencil* ars ,
324 const SkRect* devBounds, 361 const SkRect* devBounds,
325 GrAppliedClip* out) { 362 GrAppliedClip* out) {
326 if (kRespectClip_StencilClipMode == fClipMode) { 363 if (kRespectClip_StencilClipMode == fClipMode) {
327 fClipMode = kIgnoreClip_StencilClipMode; 364 fClipMode = kIgnoreClip_StencilClipMode;
328 } 365 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 // If the stencil buffer is multisampled we can use it to do everything. 469 // If the stencil buffer is multisampled we can use it to do everything.
433 if (!rt->isStencilBufferMultisampled() && requiresAA) { 470 if (!rt->isStencilBufferMultisampled() && requiresAA) {
434 SkAutoTUnref<GrTexture> result; 471 SkAutoTUnref<GrTexture> result;
435 472
436 // The top-left of the mask corresponds to the top-left corner of the bo unds. 473 // The top-left of the mask corresponds to the top-left corner of the bo unds.
437 SkVector clipToMaskOffset = { 474 SkVector clipToMaskOffset = {
438 SkIntToScalar(-clipSpaceIBounds.fLeft), 475 SkIntToScalar(-clipSpaceIBounds.fLeft),
439 SkIntToScalar(-clipSpaceIBounds.fTop) 476 SkIntToScalar(-clipSpaceIBounds.fTop)
440 }; 477 };
441 478
442 if (this->useSWOnlyPath(pipelineBuilder, rt, clipToMaskOffset, elements) ) { 479 if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOff set, elements)) {
443 // The clip geometry is complex enough that it will be more efficien t to create it 480 // The clip geometry is complex enough that it will be more efficien t to create it
444 // entirely in software 481 // entirely in software
445 result.reset(this->createSoftwareClipMask(genID, 482 result.reset(CreateSoftwareClipMask(this->getContext(),
446 initialState, 483 genID,
447 elements, 484 initialState,
448 clipToMaskOffset, 485 elements,
449 clipSpaceIBounds)); 486 clipToMaskOffset,
487 clipSpaceIBounds));
450 } else { 488 } else {
451 result.reset(this->createAlphaClipMask(genID, 489 result.reset(CreateAlphaClipMask(this->getContext(),
452 initialState, 490 genID,
453 elements, 491 initialState,
454 clipToMaskOffset, 492 elements,
455 clipSpaceIBounds)); 493 clipToMaskOffset,
456 // If createAlphaClipMask fails it means useSWOnlyPath has a bug 494 clipSpaceIBounds));
495 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug
457 SkASSERT(result); 496 SkASSERT(result);
458 } 497 }
459 498
460 if (result) { 499 if (result) {
461 // The mask's top left coord should be pinned to the rounded-out top left corner of 500 // The mask's top left coord should be pinned to the rounded-out top left corner of
462 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 501 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
463 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 502 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
464 rtSpaceMaskBounds.offset(-clip.origin()); 503 rtSpaceMaskBounds.offset(-clip.origin());
465 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds)); 504 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds));
466 this->setPipelineBuilderStencil(pipelineBuilder, ars); 505 this->setPipelineBuilderStencil(pipelineBuilder, ars);
(...skipping 14 matching lines...) Expand all
481 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 520 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
482 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 521 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
483 // use both stencil and scissor test to the bounds for the final draw. 522 // use both stencil and scissor test to the bounds for the final draw.
484 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 523 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
485 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 524 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
486 out->fScissorState.set(scissorSpaceIBounds); 525 out->fScissorState.set(scissorSpaceIBounds);
487 this->setPipelineBuilderStencil(pipelineBuilder, ars); 526 this->setPipelineBuilderStencil(pipelineBuilder, ars);
488 return true; 527 return true;
489 } 528 }
490 529
491 namespace { 530 static bool stencil_element(GrDrawContext* dc,
492 //////////////////////////////////////////////////////////////////////////////// 531 const SkIRect* scissorRect,
493 // Set a coverage drawing XPF on the pipelineBuilder for the given op and invert Coverage mode 532 const GrStencilSettings& ss,
494 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, 533 const SkMatrix& viewMatrix,
495 GrPipelineBuilder* pipelineBuilder) { 534 const SkClipStack::Element* element) {
496 SkASSERT(op <= SkRegion::kLastOp);
497 pipelineBuilder->setCoverageSetOpXPFactory(op, invertCoverage);
498 }
499 }
500
501 ////////////////////////////////////////////////////////////////////////////////
502 bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
503 const SkMatrix& viewMatrix,
504 GrTexture* target,
505 const SkClipStack::Element* element,
506 GrPathRenderer* pr) {
507
508 GrRenderTarget* rt = target->asRenderTarget();
509 pipelineBuilder->setRenderTarget(rt);
510
511 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
512 // which ignores color.
513 GrColor color = GrColor_WHITE;
514 535
515 // TODO: Draw rrects directly here. 536 // TODO: Draw rrects directly here.
516 switch (element->getType()) { 537 switch (element->getType()) {
517 case Element::kEmpty_Type: 538 case Element::kEmpty_Type:
518 SkDEBUGFAIL("Should never get here with an empty element."); 539 SkDEBUGFAIL("Should never get here with an empty element.");
519 break; 540 break;
520 case Element::kRect_Type: { 541 case Element::kRect_Type:
521 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers 542 return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss,
522 // the entire mask bounds and writes 0 outside the rect. 543 element->getOp(),
523 if (element->isAA()) { 544 element->isInverseFi lled(),
524 SkRect devRect = element->getRect(); 545 element->isAA(),
525 viewMatrix.mapRect(&devRect); 546 viewMatrix, element- >getRect());
526 547 break;
527 SkAutoTUnref<GrDrawBatch> batch(
528 GrRectBatchFactory::CreateAAFill(color, viewMatrix, elem ent->getRect(),
529 devRect));
530
531 fDrawTarget->drawBatch(*pipelineBuilder, batch);
532 } else {
533 draw_non_aa_rect(fDrawTarget, *pipelineBuilder, color, viewMatri x,
534 element->getRect());
535 }
536 return true;
537 }
538 default: { 548 default: {
539 SkPath path; 549 SkPath path;
540 element->asPath(&path); 550 element->asPath(&path);
541 if (path.isInverseFillType()) { 551 if (path.isInverseFillType()) {
542 path.toggleInverseFillType(); 552 path.toggleInverseFillType();
543 } 553 }
544 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
545 if (nullptr == pr) {
546 GrPathRendererChain::DrawType type;
547 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType :
548 GrPathRendererChain::kColor_DrawType;
549 554
550 GrPathRenderer::CanDrawPathArgs canDrawArgs; 555 return dc->drawContextPriv().drawAndStencilPath(scissorRect, ss,
551 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps (); 556 element->getOp(),
552 canDrawArgs.fViewMatrix = &viewMatrix; 557 element->isInverseFi lled(),
553 canDrawArgs.fPath = &path; 558 element->isAA(), vie wMatrix, path);
554 canDrawArgs.fStroke = &stroke;
555 canDrawArgs.fAntiAlias = element->isAA();;
556 canDrawArgs.fIsStencilDisabled = pipelineBuilder->getStencil().i sDisabled();
557 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl ed();
558
559 pr = this->getContext()->drawingManager()->getPathRenderer(canDr awArgs, false, type);
560 }
561 if (nullptr == pr) {
562 return false;
563 }
564 GrPathRenderer::DrawPathArgs args;
565 args.fTarget = fDrawTarget;
566 args.fResourceProvider = this->getContext()->resourceProvider();
567 args.fPipelineBuilder = pipelineBuilder;
568 args.fColor = color;
569 args.fViewMatrix = &viewMatrix;
570 args.fPath = &path;
571 args.fStroke = &stroke;
572 args.fAntiAlias = element->isAA();
573 pr->drawPath(args);
574 break; 559 break;
575 } 560 }
576 } 561 }
577 return true; 562
563 return false;
564 }
565
566 static void draw_element(GrDrawContext* dc,
567 const GrClip& clip, // TODO: can this just always be Wi deOpen?
568 const GrPaint &paint,
569 const SkMatrix& viewMatrix,
570 const SkClipStack::Element* element) {
571
572 // TODO: Draw rrects directly here.
573 switch (element->getType()) {
574 case Element::kEmpty_Type:
575 SkDEBUGFAIL("Should never get here with an empty element.");
576 break;
577 case Element::kRect_Type:
578 dc->drawRect(clip, paint, viewMatrix, element->getRect());
579 break;
580 default: {
581 SkPath path;
582 element->asPath(&path);
583 if (path.isInverseFillType()) {
584 path.toggleInverseFillType();
585 }
586
587 dc->drawPath(clip, paint, viewMatrix, path, GrStrokeInfo::FillInfo() );
588 break;
589 }
590 }
578 } 591 }
579 592
580 //////////////////////////////////////////////////////////////////////////////// 593 ////////////////////////////////////////////////////////////////////////////////
581 // Create a 8-bit clip mask in alpha 594 // Create a 8-bit clip mask in alpha
582 595
583 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey * key) { 596 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey * key) {
584 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 597 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
585 GrUniqueKey::Builder builder(key, kDomain, 3); 598 GrUniqueKey::Builder builder(key, kDomain, 3);
586 builder[0] = clipGenID; 599 builder[0] = clipGenID;
587 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); 600 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16);
588 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); 601 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16);
589 } 602 }
590 603
591 GrTexture* GrClipMaskManager::createCachedMask(int width, int height, const GrUn iqueKey& key, 604 GrTexture* GrClipMaskManager::CreateAlphaClipMask(GrContext* context,
592 bool renderTarget) { 605 int32_t elementsGenID,
593 GrSurfaceDesc desc;
594 desc.fWidth = width;
595 desc.fHeight = height;
596 desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFl ags;
597 if (!renderTarget || this->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig , false)) {
598 desc.fConfig = kAlpha_8_GrPixelConfig;
599 } else {
600 desc.fConfig = kRGBA_8888_GrPixelConfig;
601 }
602
603 GrTexture* texture = this->resourceProvider()->createApproxTexture(desc, 0);
604 if (!texture) {
605 return nullptr;
606 }
607 texture->resourcePriv().setUniqueKey(key);
608 return texture;
609 }
610
611 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
612 GrReducedClip::InitialState in itialState, 606 GrReducedClip::InitialState in itialState,
613 const GrReducedClip::ElementLi st& elements, 607 const GrReducedClip::ElementLi st& elements,
614 const SkVector& clipToMaskOffs et, 608 const SkVector& clipToMaskOffs et,
615 const SkIRect& clipSpaceIBound s) { 609 const SkIRect& clipSpaceIBound s) {
616 GrResourceProvider* resourceProvider = this->resourceProvider(); 610 GrResourceProvider* resourceProvider = context->resourceProvider();
617 GrUniqueKey key; 611 GrUniqueKey key;
618 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); 612 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
619 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { 613 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) {
620 return texture; 614 return texture;
621 } 615 }
622 616
623 // There's no texture in the cache. Let's try to allocate it then. 617 // There's no texture in the cache. Let's try to allocate it then.
624 SkAutoTUnref<GrTexture> texture(this->createCachedMask( 618 GrSurfaceDesc desc;
625 clipSpaceIBounds.width(), clipSpaceIBounds.height(), key, true)); 619 desc.fWidth = clipSpaceIBounds.width();
620 desc.fHeight = clipSpaceIBounds.height();
621 desc.fFlags = kRenderTarget_GrSurfaceFlag;
622 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
623 desc.fConfig = kAlpha_8_GrPixelConfig;
624 } else {
625 desc.fConfig = kRGBA_8888_GrPixelConfig;
626 }
627
628 SkAutoTUnref<GrTexture> texture(resourceProvider->createApproxTexture(desc, 0));
626 if (!texture) { 629 if (!texture) {
627 return nullptr; 630 return nullptr;
628 } 631 }
629 632
630 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 633 texture->resourcePriv().setUniqueKey(key);
631 // space. 634
632 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 635 SkAutoTUnref<GrDrawContext> dc(context->drawContext(texture->asRenderTarget( )));
636 if (!dc) {
637 return nullptr;
638 }
633 639
634 // The texture may be larger than necessary, this rect represents the part o f the texture 640 // The texture may be larger than necessary, this rect represents the part o f the texture
635 // we populate with a rasterization of the clip. 641 // we populate with a rasterization of the clip.
636 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 642 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
637 643
638 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 644 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
639 // clear the part that we care about. 645 // clear the part that we care about.
640 fDrawTarget->clear(&maskSpaceIBounds, 646 dc->clear(&maskSpaceIBounds,
641 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000, 647 GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
642 true, 648 true);
643 texture->asRenderTarget());
644 649
645 // When we use the stencil in the below loop it is important to have this cl ip installed. 650 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
651 // space.
652 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
653
654 // It is important that we use maskSpaceIBounds as the stencil rect in the b elow loop.
646 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first 655 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first
647 // pass must not set values outside of this bounds or stencil values outside the rect won't be 656 // pass must not set values outside of this bounds or stencil values outside the rect won't be
648 // cleared. 657 // cleared.
649 const GrClip clip(maskSpaceIBounds);
650 658
651 // walk through each clip element and perform its set op 659 // walk through each clip element and perform its set op
652 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 660 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
653 const Element* element = iter.get(); 661 const Element* element = iter.get();
654 SkRegion::Op op = element->getOp(); 662 SkRegion::Op op = element->getOp();
655 bool invert = element->isInverseFilled(); 663 bool invert = element->isInverseFilled();
656 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 664 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
657 665 #ifdef SK_DEBUG
658 GrPathRenderer* pr = GetPathRenderer(this->getContext(), 666 GrPathRenderer* pr = GetPathRenderer(context,
659 texture, translate, element); 667 texture, translate, element);
660 if (Element::kRect_Type != element->getType() && !pr) { 668 if (Element::kRect_Type != element->getType() && !pr) {
661 // useSWOnlyPath should now filter out all cases where gpu-side mask merging would 669 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would
662 // be performed (i.e., pr would be NULL for a non-rect path). Se e https://bug.skia.org/4519 670 // be performed (i.e., pr would be NULL for a non-rect path).
663 // for rationale and details. 671 // See https://bug.skia.org/4519 for rationale and details.
664 SkASSERT(0); 672 SkASSERT(0);
665 continue; 673 }
674 #endif
675
676 // draw directly into the result with the stencil set to make the pi xels affected
677 // by the clip shape be non-zero.
678 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
679 kReplace_StencilOp,
680 kReplace_StencilOp,
681 kAlways_StencilFunc,
682 0xffff,
683 0xffff,
684 0xffff)
685 if (!stencil_element(dc, &maskSpaceIBounds, kStencilInElement,
686 translate, element)) {
687 texture->resourcePriv().removeUniqueKey();
688 return nullptr;
666 } 689 }
667 690
668 { 691 // Draw to the exterior pixels (those with a zero stencil value).
669 GrPipelineBuilder pipelineBuilder; 692 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
670 693 kZero_StencilOp,
671 pipelineBuilder.setClip(clip); 694 kZero_StencilOp,
672 pipelineBuilder.setRenderTarget(texture->asRenderTarget()); 695 kEqual_StencilFunc,
673 SkASSERT(pipelineBuilder.getStencil().isDisabled()); 696 0xffff,
674 697 0x0000,
675 // draw directly into the result with the stencil set to make th e pixels affected 698 0xffff);
676 // by the clip shape be non-zero. 699 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDr awOutsideElement,
677 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, 700 op, !invert, false,
678 kReplace_StencilOp, 701 translate,
679 kReplace_StencilOp, 702 SkRect::Make(clipSpace IBounds))) {
680 kAlways_StencilFunc, 703 texture->resourcePriv().removeUniqueKey();
681 0xffff, 704 return nullptr;
682 0xffff,
683 0xffff);
684 pipelineBuilder.setStencil(kStencilInElement);
685 set_coverage_drawing_xpf(op, invert, &pipelineBuilder);
686
687 if (!this->drawElement(&pipelineBuilder, translate, texture, ele ment, pr)) {
688 texture->resourcePriv().removeUniqueKey();
689 return nullptr;
690 }
691 }
692
693 {
694 GrPipelineBuilder backgroundPipelineBuilder;
695 backgroundPipelineBuilder.setRenderTarget(texture->asRenderTarge t());
696
697 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder );
698 // Draw to the exterior pixels (those with a zero stencil value) .
699 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
700 kZero_StencilOp,
701 kZero_StencilOp,
702 kEqual_StencilFunc,
703 0xffff,
704 0x0000,
705 0xffff);
706 backgroundPipelineBuilder.setStencil(kDrawOutsideElement);
707
708 // The color passed in here does not matter since the coverageSe tOpXP won't read it.
709 draw_non_aa_rect(fDrawTarget, backgroundPipelineBuilder, GrColor _WHITE, translate,
710 SkRect::Make(clipSpaceIBounds));
711 } 705 }
712 } else { 706 } else {
713 GrPipelineBuilder pipelineBuilder; 707 // all the remaining ops can just be directly draw into the accumula tion buffer
708 GrPaint paint;
709 paint.setAntiAlias(element->isAA());
710 paint.setCoverageSetOpXPFactory(op, false);
714 711
715 // all the remaining ops can just be directly draw into the accumula tion buffer 712 draw_element(dc, GrClip::WideOpen(), paint, translate, element);
716 set_coverage_drawing_xpf(op, false, &pipelineBuilder);
717 // The color passed in here does not matter since the coverageSetOpX P won't read it.
718 this->drawElement(&pipelineBuilder, translate, texture, element);
719 } 713 }
720 } 714 }
721 715
722 return texture.detach(); 716 return texture.detach();
723 } 717 }
724 718
725 //////////////////////////////////////////////////////////////////////////////// 719 ////////////////////////////////////////////////////////////////////////////////
726 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 720 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
727 // (as opposed to canvas) coordinates 721 // (as opposed to canvas) coordinates
728 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, 722 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 } else { 1068 } else {
1075 finished = true; 1069 finished = true;
1076 } 1070 }
1077 } 1071 }
1078 if (!twoSided) { 1072 if (!twoSided) {
1079 settings->copyFrontSettingsToBack(); 1073 settings->copyFrontSettingsToBack();
1080 } 1074 }
1081 } 1075 }
1082 1076
1083 //////////////////////////////////////////////////////////////////////////////// 1077 ////////////////////////////////////////////////////////////////////////////////
1084 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, 1078 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
1079 int32_t elementsGenID,
1085 GrReducedClip::InitialState initialState, 1080 GrReducedClip::InitialState initialState,
1086 const GrReducedClip::Elemen tList& elements, 1081 const GrReducedClip::Elemen tList& elements,
1087 const SkVector& clipToMaskO ffset, 1082 const SkVector& clipToMaskO ffset,
1088 const SkIRect& clipSpaceIBo unds) { 1083 const SkIRect& clipSpaceIBo unds) {
1089 GrUniqueKey key; 1084 GrUniqueKey key;
1090 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); 1085 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
1091 GrResourceProvider* resourceProvider = this->resourceProvider(); 1086 GrResourceProvider* resourceProvider = context->resourceProvider();
1092 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { 1087 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) {
1093 return texture; 1088 return texture;
1094 } 1089 }
1095 1090
1096 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin 1091 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin
1097 // the top left corner of the resulting rect to the top left of the texture. 1092 // the top left corner of the resulting rect to the top left of the texture.
1098 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 1093 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
1099 1094
1100 GrSWMaskHelper helper(this->getContext()); 1095 GrSWMaskHelper helper(context);
1101 1096
1102 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 1097 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
1103 // space. 1098 // space.
1104 SkMatrix translate; 1099 SkMatrix translate;
1105 translate.setTranslate(clipToMaskOffset); 1100 translate.setTranslate(clipToMaskOffset);
1106 1101
1107 helper.init(maskSpaceIBounds, &translate, false); 1102 helper.init(maskSpaceIBounds, &translate, false);
1108 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0 0); 1103 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0 0);
1109 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 1104 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
1110 1105
(...skipping 23 matching lines...) Expand all
1134 if (Element::kRect_Type == element->getType()) { 1129 if (Element::kRect_Type == element->getType()) {
1135 helper.draw(element->getRect(), op, element->isAA(), 0xFF); 1130 helper.draw(element->getRect(), op, element->isAA(), 0xFF);
1136 } else { 1131 } else {
1137 SkPath path; 1132 SkPath path;
1138 element->asPath(&path); 1133 element->asPath(&path);
1139 helper.draw(path, stroke, op, element->isAA(), 0xFF); 1134 helper.draw(path, stroke, op, element->isAA(), 0xFF);
1140 } 1135 }
1141 } 1136 }
1142 1137
1143 // Allocate clip mask texture 1138 // Allocate clip mask texture
1144 GrTexture* result = this->createCachedMask(clipSpaceIBounds.width(), clipSpa ceIBounds.height(), 1139 GrSurfaceDesc desc;
1145 key, false); 1140 desc.fWidth = clipSpaceIBounds.width();
1146 if (nullptr == result) { 1141 desc.fHeight = clipSpaceIBounds.height();
1142 desc.fConfig = kAlpha_8_GrPixelConfig;
1143
1144 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 );
1145 if (!result) {
1147 return nullptr; 1146 return nullptr;
1148 } 1147 }
1148 result->resourcePriv().setUniqueKey(key);
1149
1149 helper.toTexture(result); 1150 helper.toTexture(result);
1150 1151
1151 return result; 1152 return result;
1152 } 1153 }
1153 1154
1154 //////////////////////////////////////////////////////////////////////////////// 1155 ////////////////////////////////////////////////////////////////////////////////
1155 1156
1156 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, 1157 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment,
1157 GrStencilSettings* settings) { 1158 GrStencilSettings* settings) {
1158 if (stencilAttachment) { 1159 if (stencilAttachment) {
1159 int stencilBits = stencilAttachment->bits(); 1160 int stencilBits = stencilAttachment->bits();
1160 this->adjustStencilParams(settings, fClipMode, stencilBits); 1161 this->adjustStencilParams(settings, fClipMode, stencilBits);
1161 } 1162 }
1162 } 1163 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrDrawContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698