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 "GrStencilAttachment.h" 18 #include "GrStencilSettings.h" 19 20 GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, Flags flags, 21 GrStencilAttachment* stencil) 22 : INHERITED(gpu, desc) 23 , fStencilAttachment(stencil) 24 , fMultisampleSpecsID(0) 25 , fFlags(flags) { 26 SkASSERT(!(fFlags & Flags::kMixedSampled) || fDesc.fSampleCnt > 0); 27 SkASSERT(!(fFlags & Flags::kWindowRectsSupport) || gpu->caps()->maxWindowRectangles() > 0); 28 fResolveRect.setLargestInverted(); 29 } 30 31 void GrRenderTarget::discard() { 32 // go through context so that all necessary flushing occurs 33 GrContext* context = this->getContext(); 34 if (!context) { 35 return; 36 } 37 38 sk_sp<GrRenderTargetContext> renderTargetContext( 39 context->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(this), nullptr)); 40 if (!renderTargetContext) { 41 return; 42 } 43 44 renderTargetContext->discard(); 45 } 46 47 void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) { 48 if (kCanResolve_ResolveType == getResolveType()) { 49 if (rect) { 50 fResolveRect.join(*rect); 51 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 52 fResolveRect.setEmpty(); 53 } 54 } else { 55 fResolveRect.setLTRB(0, 0, this->width(), this->height()); 56 } 57 } 58 } 59 60 void GrRenderTarget::overrideResolveRect(const SkIRect rect) { 61 fResolveRect = rect; 62 if (fResolveRect.isEmpty()) { 63 fResolveRect.setLargestInverted(); 64 } else { 65 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 66 fResolveRect.setLargestInverted(); 67 } 68 } 69 } 70 71 void GrRenderTarget::onRelease() { 72 SkSafeSetNull(fStencilAttachment); 73 74 INHERITED::onRelease(); 75 } 76 77 void GrRenderTarget::onAbandon() { 78 SkSafeSetNull(fStencilAttachment); 79 80 // The contents of this renderTarget are gone/invalid. It isn't useful to point back 81 // the creating opList. 82 this->setLastOpList(nullptr); 83 84 INHERITED::onAbandon(); 85 } 86 87 /////////////////////////////////////////////////////////////////////////////// 88 89 bool GrRenderTargetPriv::attachStencilAttachment(GrStencilAttachment* stencil) { 90 if (!stencil && !fRenderTarget->fStencilAttachment) { 91 // No need to do any work since we currently don't have a stencil attachment and 92 // we're not actually adding one. 93 return true; 94 } 95 fRenderTarget->fStencilAttachment = stencil; 96 if (!fRenderTarget->completeStencilAttachment()) { 97 SkSafeSetNull(fRenderTarget->fStencilAttachment); 98 return false; 99 } 100 return true; 101 } 102 103 int GrRenderTargetPriv::numStencilBits() const { 104 SkASSERT(this->getStencilAttachment()); 105 return this->getStencilAttachment()->bits(); 106 } 107 108 const GrGpu::MultisampleSpecs& 109 GrRenderTargetPriv::getMultisampleSpecs(const GrPipeline& pipeline) const { 110 SkASSERT(fRenderTarget == pipeline.getRenderTarget()); // TODO: remove RT from pipeline. 111 GrGpu* gpu = fRenderTarget->getGpu(); 112 if (auto id = fRenderTarget->fMultisampleSpecsID) { 113 SkASSERT(gpu->queryMultisampleSpecs(pipeline).fUniqueID == id); 114 return gpu->getMultisampleSpecs(id); 115 } 116 const GrGpu::MultisampleSpecs& specs = gpu->queryMultisampleSpecs(pipeline); 117 fRenderTarget->fMultisampleSpecsID = specs.fUniqueID; 118 return specs; 119 } 120 121