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

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

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