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

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

Issue 1977793004: Retract GrRenderTarget from AlphaClipMask code (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix memory leak Created 4 years, 7 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') | no next file » | 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"
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { 363 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
364 out->fScissorState.set(scissorSpaceIBounds); 364 out->fScissorState.set(scissorSpaceIBounds);
365 } 365 }
366 out->fClipCoverageFP.reset(clipFP); 366 out->fClipCoverageFP.reset(clipFP);
367 return true; 367 return true;
368 } 368 }
369 } 369 }
370 370
371 // If the stencil buffer is multisampled we can use it to do everything. 371 // If the stencil buffer is multisampled we can use it to do everything.
372 if (!rt->isStencilBufferMultisampled() && requiresAA) { 372 if (!rt->isStencilBufferMultisampled() && requiresAA) {
373 SkAutoTUnref<GrTexture> result; 373 sk_sp<GrTexture> result;
374 374
375 // The top-left of the mask corresponds to the top-left corner of the bo unds. 375 // The top-left of the mask corresponds to the top-left corner of the bo unds.
376 SkVector clipToMaskOffset = { 376 SkVector clipToMaskOffset = {
377 SkIntToScalar(-clipSpaceIBounds.fLeft), 377 SkIntToScalar(-clipSpaceIBounds.fLeft),
378 SkIntToScalar(-clipSpaceIBounds.fTop) 378 SkIntToScalar(-clipSpaceIBounds.fTop)
379 }; 379 };
380 380
381 if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOff set, elements)) { 381 if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOff set, elements)) {
382 // The clip geometry is complex enough that it will be more efficien t to create it 382 // The clip geometry is complex enough that it will be more efficien t to create it
383 // entirely in software 383 // entirely in software
384 result.reset(CreateSoftwareClipMask(this->getContext(), 384 result = CreateSoftwareClipMask(this->getContext(),
385 genID, 385 genID,
386 initialState, 386 initialState,
387 elements, 387 elements,
388 clipToMaskOffset, 388 clipToMaskOffset,
389 clipSpaceIBounds)); 389 clipSpaceIBounds);
390 } else { 390 } else {
391 result.reset(CreateAlphaClipMask(this->getContext(), 391 result = CreateAlphaClipMask(this->getContext(),
392 genID, 392 genID,
393 initialState, 393 initialState,
394 elements, 394 elements,
395 clipToMaskOffset, 395 clipToMaskOffset,
396 clipSpaceIBounds)); 396 clipSpaceIBounds);
397 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug 397 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug
398 SkASSERT(result); 398 SkASSERT(result);
399 } 399 }
400 400
401 if (result) { 401 if (result) {
402 // The mask's top left coord should be pinned to the rounded-out top left corner of 402 // The mask's top left coord should be pinned to the rounded-out top left corner of
403 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 403 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
404 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 404 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
405 rtSpaceMaskBounds.offset(-clip.origin()); 405 rtSpaceMaskBounds.offset(-clip.origin());
406 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds)); 406 out->fClipCoverageFP.reset(create_fp_for_mask(result.get(), rtSpaceM askBounds));
407 return true; 407 return true;
408 } 408 }
409 // if alpha clip mask creation fails fall through to the non-AA code pat hs 409 // if alpha clip mask creation fails fall through to the non-AA code pat hs
410 } 410 }
411 411
412 // use the stencil clip if we can't represent the clip as a rectangle. 412 // use the stencil clip if we can't represent the clip as a rectangle.
413 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); 413 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
414 this->createStencilClipMask(rt, 414 this->createStencilClipMask(rt,
415 genID, 415 genID,
416 initialState, 416 initialState,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 // Create a 8-bit clip mask in alpha 495 // Create a 8-bit clip mask in alpha
496 496
497 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey * key) { 497 static void GetClipMaskKey(int32_t clipGenID, const SkIRect& bounds, GrUniqueKey * key) {
498 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 498 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
499 GrUniqueKey::Builder builder(key, kDomain, 3); 499 GrUniqueKey::Builder builder(key, kDomain, 3);
500 builder[0] = clipGenID; 500 builder[0] = clipGenID;
501 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); 501 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16);
502 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); 502 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16);
503 } 503 }
504 504
505 GrTexture* GrClipMaskManager::CreateAlphaClipMask(GrContext* context, 505 sk_sp<GrTexture> GrClipMaskManager::CreateAlphaClipMask(GrContext* context,
506 int32_t elementsGenID, 506 int32_t elementsGenID,
507 GrReducedClip::InitialState in itialState, 507 GrReducedClip::InitialSt ate initialState,
508 const GrReducedClip::ElementLi st& elements, 508 const GrReducedClip::Ele mentList& elements,
509 const SkVector& clipToMaskOffs et, 509 const SkVector& clipToMa skOffset,
510 const SkIRect& clipSpaceIBound s) { 510 const SkIRect& clipSpace IBounds) {
511 GrResourceProvider* resourceProvider = context->resourceProvider(); 511 GrResourceProvider* resourceProvider = context->resourceProvider();
512 GrUniqueKey key; 512 GrUniqueKey key;
513 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); 513 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
514 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { 514 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) {
515 return texture; 515 return sk_sp<GrTexture>(texture);
516 } 516 }
517 517
518 // There's no texture in the cache. Let's try to allocate it then. 518 // There's no texture in the cache. Let's try to allocate it then.
519 GrSurfaceDesc desc; 519 GrPixelConfig config = kRGBA_8888_GrPixelConfig;
520 desc.fWidth = clipSpaceIBounds.width();
521 desc.fHeight = clipSpaceIBounds.height();
522 desc.fFlags = kRenderTarget_GrSurfaceFlag;
523 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 520 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
524 desc.fConfig = kAlpha_8_GrPixelConfig; 521 config = kAlpha_8_GrPixelConfig;
525 } else {
526 desc.fConfig = kRGBA_8888_GrPixelConfig;
527 } 522 }
528 523
529 SkAutoTUnref<GrTexture> texture(resourceProvider->createApproxTexture(desc, 0)); 524 sk_sp<GrDrawContext> dc(context->newDrawContext(SkBackingFit::kApprox,
530 if (!texture) { 525 clipSpaceIBounds.width(),
531 return nullptr; 526 clipSpaceIBounds.height(),
532 } 527 config));
533
534 texture->resourcePriv().setUniqueKey(key);
535
536 sk_sp<GrDrawContext> dc(context->drawContext(sk_ref_sp(texture->asRenderTarg et())));
537 if (!dc) { 528 if (!dc) {
538 return nullptr; 529 return nullptr;
539 } 530 }
540 531
541 // The texture may be larger than necessary, this rect represents the part o f the texture 532 // The texture may be larger than necessary, this rect represents the part o f the texture
542 // we populate with a rasterization of the clip. 533 // we populate with a rasterization of the clip.
543 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 534 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
544 535
545 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 536 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
546 // clear the part that we care about. 537 // clear the part that we care about.
547 dc->clear(&maskSpaceIBounds, 538 dc->clear(&maskSpaceIBounds,
548 GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, 539 GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
549 true); 540 true);
550 541
551 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 542 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
552 // space. 543 // space.
553 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 544 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
554 545
555 // It is important that we use maskSpaceIBounds as the stencil rect in the b elow loop. 546 // It is important that we use maskSpaceIBounds as the stencil rect in the b elow loop.
556 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first 547 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first
557 // pass must not set values outside of this bounds or stencil values outside the rect won't be 548 // pass must not set values outside of this bounds or stencil values outside the rect won't be
558 // cleared. 549 // cleared.
559 550
560 // walk through each clip element and perform its set op 551 // walk through each clip element and perform its set op
561 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 552 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
562 const Element* element = iter.get(); 553 const Element* element = iter.get();
563 SkRegion::Op op = element->getOp(); 554 SkRegion::Op op = element->getOp();
564 bool invert = element->isInverseFilled(); 555 bool invert = element->isInverseFilled();
565 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 556 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
566 #ifdef SK_DEBUG
567 GrPathRenderer* pr = GetPathRenderer(context,
568 texture, translate, element);
569 if (Element::kRect_Type != element->getType() && !pr) {
570 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would
571 // be performed (i.e., pr would be NULL for a non-rect path).
572 // See https://bug.skia.org/4519 for rationale and details.
573 SkASSERT(0);
574 }
575 #endif
576
577 GrFixedClip clip(maskSpaceIBounds); 557 GrFixedClip clip(maskSpaceIBounds);
578 558
579 // draw directly into the result with the stencil set to make the pi xels affected 559 // draw directly into the result with the stencil set to make the pi xels affected
580 // by the clip shape be non-zero. 560 // by the clip shape be non-zero.
581 static constexpr GrUserStencilSettings kStencilInElement( 561 static constexpr GrUserStencilSettings kStencilInElement(
582 GrUserStencilSettings::StaticInit< 562 GrUserStencilSettings::StaticInit<
583 0xffff, 563 0xffff,
584 GrUserStencilTest::kAlways, 564 GrUserStencilTest::kAlways,
585 0xffff, 565 0xffff,
586 GrUserStencilOp::kReplace, 566 GrUserStencilOp::kReplace,
587 GrUserStencilOp::kReplace, 567 GrUserStencilOp::kReplace,
588 0xffff>() 568 0xffff>()
589 ); 569 );
590 if (!stencil_element(dc.get(), clip, &kStencilInElement, 570 if (!stencil_element(dc.get(), clip, &kStencilInElement,
591 translate, element)) { 571 translate, element)) {
592 texture->resourcePriv().removeUniqueKey();
593 return nullptr; 572 return nullptr;
594 } 573 }
595 574
596 // Draw to the exterior pixels (those with a zero stencil value). 575 // Draw to the exterior pixels (those with a zero stencil value).
597 static constexpr GrUserStencilSettings kDrawOutsideElement( 576 static constexpr GrUserStencilSettings kDrawOutsideElement(
598 GrUserStencilSettings::StaticInit< 577 GrUserStencilSettings::StaticInit<
599 0x0000, 578 0x0000,
600 GrUserStencilTest::kEqual, 579 GrUserStencilTest::kEqual,
601 0xffff, 580 0xffff,
602 GrUserStencilOp::kZero, 581 GrUserStencilOp::kZero,
603 GrUserStencilOp::kZero, 582 GrUserStencilOp::kZero,
604 0xffff>() 583 0xffff>()
605 ); 584 );
606 if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideEle ment, 585 if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideEle ment,
607 op, !invert, false, 586 op, !invert, false,
608 translate, 587 translate,
609 SkRect::Make(clipSpace IBounds))) { 588 SkRect::Make(clipSpace IBounds))) {
610 texture->resourcePriv().removeUniqueKey();
611 return nullptr; 589 return nullptr;
612 } 590 }
613 } else { 591 } else {
614 // all the remaining ops can just be directly draw into the accumula tion buffer 592 // all the remaining ops can just be directly draw into the accumula tion buffer
615 GrPaint paint; 593 GrPaint paint;
616 paint.setAntiAlias(element->isAA()); 594 paint.setAntiAlias(element->isAA());
617 paint.setCoverageSetOpXPFactory(op, false); 595 paint.setCoverageSetOpXPFactory(op, false);
618 596
619 draw_element(dc.get(), GrNoClip(), paint, translate, element); 597 draw_element(dc.get(), GrNoClip(), paint, translate, element);
620 } 598 }
621 } 599 }
622 600
623 return texture.release(); 601 sk_sp<GrTexture> texture(dc->asTexture());
602 SkASSERT(texture);
603 texture->resourcePriv().setUniqueKey(key);
604 return texture;
624 } 605 }
625 606
626 //////////////////////////////////////////////////////////////////////////////// 607 ////////////////////////////////////////////////////////////////////////////////
627 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 608 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
628 // (as opposed to canvas) coordinates 609 // (as opposed to canvas) coordinates
629 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, 610 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
630 int32_t elementsGenID, 611 int32_t elementsGenID,
631 GrReducedClip::InitialState initia lState, 612 GrReducedClip::InitialState initia lState,
632 const GrReducedClip::ElementList& elements, 613 const GrReducedClip::ElementList& elements,
633 const SkIRect& clipSpaceIBounds, 614 const SkIRect& clipSpaceIBounds,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor _WHITE, viewMatrix, 781 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor _WHITE, viewMatrix,
801 SkRect::Make(clipSpaceIBounds)); 782 SkRect::Make(clipSpaceIBounds));
802 } 783 }
803 } 784 }
804 } 785 }
805 } 786 }
806 return true; 787 return true;
807 } 788 }
808 789
809 //////////////////////////////////////////////////////////////////////////////// 790 ////////////////////////////////////////////////////////////////////////////////
810 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context, 791 sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask(
811 int32_t elementsGenID, 792 GrContext* context,
812 GrReducedClip::InitialState initialState, 793 int32_t elementsGenID,
813 const GrReducedClip::Elemen tList& elements, 794 GrReducedClip::InitialState initialState,
814 const SkVector& clipToMaskO ffset, 795 const GrReducedClip::Element List& elements,
815 const SkIRect& clipSpaceIBo unds) { 796 const SkVector& clipToMaskOf fset,
797 const SkIRect& clipSpaceIBou nds) {
816 GrUniqueKey key; 798 GrUniqueKey key;
817 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); 799 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
818 GrResourceProvider* resourceProvider = context->resourceProvider(); 800 GrResourceProvider* resourceProvider = context->resourceProvider();
819 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { 801 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) {
820 return texture; 802 return sk_sp<GrTexture>(texture);
821 } 803 }
822 804
823 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin 805 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin
824 // the top left corner of the resulting rect to the top left of the texture. 806 // the top left corner of the resulting rect to the top left of the texture.
825 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 807 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
826 808
827 GrSWMaskHelper helper(context); 809 GrSWMaskHelper helper(context);
828 810
829 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 811 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
830 // space. 812 // space.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 helper.drawPath(path, GrStyle::SimpleFill(), op, element->isAA(), 0x FF); 848 helper.drawPath(path, GrStyle::SimpleFill(), op, element->isAA(), 0x FF);
867 } 849 }
868 } 850 }
869 851
870 // Allocate clip mask texture 852 // Allocate clip mask texture
871 GrSurfaceDesc desc; 853 GrSurfaceDesc desc;
872 desc.fWidth = clipSpaceIBounds.width(); 854 desc.fWidth = clipSpaceIBounds.width();
873 desc.fHeight = clipSpaceIBounds.height(); 855 desc.fHeight = clipSpaceIBounds.height();
874 desc.fConfig = kAlpha_8_GrPixelConfig; 856 desc.fConfig = kAlpha_8_GrPixelConfig;
875 857
876 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 ); 858 sk_sp<GrTexture> result(context->resourceProvider()->createApproxTexture(des c, 0));
877 if (!result) { 859 if (!result) {
878 return nullptr; 860 return nullptr;
879 } 861 }
880 result->resourcePriv().setUniqueKey(key); 862 result->resourcePriv().setUniqueKey(key);
881 863
882 helper.toTexture(result); 864 helper.toTexture(result.get());
883 865
884 return result; 866 return result;
885 } 867 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698