1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9 #include "GrRenderTarget.h" 10 11 #include "GrContext.h" 12 #include "GrContextPriv.h" 13 #include "GrRenderTargetContext.h" 14 #include "GrGpu.h" 15 #include "GrRenderTargetOpList.h" 16 #include "GrRenderTargetPriv.h" 17 #include "GrSamplePatternDictionary.h" 18 #include "GrStencilAttachment.h" 19 #include "GrStencilSettings.h" 20 #include "SkRectPriv.h" 21 22 GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, 23 GrStencilAttachment* stencil) 24 : INHERITED(gpu, desc) 25 , fSampleCnt(desc.fSampleCnt) 26 , fSamplePatternKey(GrSamplePatternDictionary::kInvalidSamplePatternKey) 27 , fStencilAttachment(stencil) { 28 SkASSERT(desc.fFlags & kRenderTarget_GrSurfaceFlag); 29 SkASSERT(!this->hasMixedSamples() || fSampleCnt > 1); 30 fResolveRect = SkRectPriv::MakeILargestInverted(); 31 } 32 33 GrRenderTarget::~GrRenderTarget() = default; 34 35 void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) { 36 if (kCanResolve_ResolveType == getResolveType()) { 37 if (rect) { 38 fResolveRect.join(*rect); 39 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 40 fResolveRect.setEmpty(); 41 } 42 } else { 43 fResolveRect.setLTRB(0, 0, this->width(), this->height()); 44 } 45 } 46 } 47 48 void GrRenderTarget::overrideResolveRect(const SkIRect rect) { 49 fResolveRect = rect; 50 if (fResolveRect.isEmpty()) { 51 fResolveRect = SkRectPriv::MakeILargestInverted(); 52 } else { 53 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 54 fResolveRect = SkRectPriv::MakeILargestInverted(); 55 } 56 } 57 } 58 59 void GrRenderTarget::flagAsResolved() { 60 fResolveRect = SkRectPriv::MakeILargestInverted(); 61 } 62 63 void GrRenderTarget::onRelease() { 64 fStencilAttachment = nullptr; 65 66 INHERITED::onRelease(); 67 } 68 69 void GrRenderTarget::onAbandon() { 70 fStencilAttachment = nullptr; 71 72 INHERITED::onAbandon(); 73 } 74 75 /////////////////////////////////////////////////////////////////////////////// 76 77 void GrRenderTargetPriv::attachStencilAttachment(sk_sp<GrStencilAttachment> stencil) { 78 if (!stencil && !fRenderTarget->fStencilAttachment) { 79 // No need to do any work since we currently don't have a stencil attachment and 80 // we're not actually adding one. 81 return; 82 } 83 fRenderTarget->fStencilAttachment = std::move(stencil); 84 if (!fRenderTarget->completeStencilAttachment()) { 85 fRenderTarget->fStencilAttachment = nullptr; 86 } 87 } 88 89 int GrRenderTargetPriv::numStencilBits() const { 90 SkASSERT(this->getStencilAttachment()); 91 return this->getStencilAttachment()->bits(); 92 } 93 94 int GrRenderTargetPriv::getSamplePatternKey(const GrPipeline& pipeline) const { 95 SkASSERT(fRenderTarget->fSampleCnt > 1); 96 if (GrSamplePatternDictionary::kInvalidSamplePatternKey == fRenderTarget->fSamplePatternKey) { 97 fRenderTarget->fSamplePatternKey = 98 fRenderTarget->getGpu()->findOrAssignSamplePatternKey(fRenderTarget, pipeline); 99 } 100 SkASSERT(GrSamplePatternDictionary::kInvalidSamplePatternKey 101 != fRenderTarget->fSamplePatternKey); 102 // Verify we always have the same sample pattern key every time this is called, regardless of 103 // pipeline state. 104 SkASSERT(fRenderTarget->getGpu()->findOrAssignSamplePatternKey(fRenderTarget, pipeline) 105 == fRenderTarget->fSamplePatternKey); 106 return fRenderTarget->fSamplePatternKey; 107 } 108