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, 21 GrRenderTargetFlags flags, 22 GrStencilAttachment* stencil) 23 : INHERITED(gpu, desc) 24 , fSampleCnt(desc.fSampleCnt) 25 , fStencilAttachment(stencil) 26 , fMultisampleSpecsID(0) 27 , fFlags(flags) { 28 SkASSERT(desc.fFlags & kRenderTarget_GrSurfaceFlag); 29 SkASSERT(!(fFlags & GrRenderTargetFlags::kMixedSampled) || fSampleCnt > 0); 30 SkASSERT(!(fFlags & GrRenderTargetFlags::kWindowRectsSupport) || 31 gpu->caps()->maxWindowRectangles() > 0); 32 fResolveRect.setLargestInverted(); 33 } 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.setLargestInverted(); 52 } else { 53 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 54 fResolveRect.setLargestInverted(); 55 } 56 } 57 } 58 59 void GrRenderTarget::onRelease() { 60 SkSafeSetNull(fStencilAttachment); 61 62 INHERITED::onRelease(); 63 } 64 65 void GrRenderTarget::onAbandon() { 66 SkSafeSetNull(fStencilAttachment); 67 68 INHERITED::onAbandon(); 69 } 70 71 /////////////////////////////////////////////////////////////////////////////// 72 73 bool GrRenderTargetPriv::attachStencilAttachment(GrStencilAttachment* stencil) { 74 if (!stencil && !fRenderTarget->fStencilAttachment) { 75 // No need to do any work since we currently don't have a stencil attachment and 76 // we're not actually adding one. 77 return true; 78 } 79 fRenderTarget->fStencilAttachment = stencil; 80 if (!fRenderTarget->completeStencilAttachment()) { 81 SkSafeSetNull(fRenderTarget->fStencilAttachment); 82 return false; 83 } 84 return true; 85 } 86 87 int GrRenderTargetPriv::numStencilBits() const { 88 SkASSERT(this->getStencilAttachment()); 89 return this->getStencilAttachment()->bits(); 90 } 91 92 const GrGpu::MultisampleSpecs& 93 GrRenderTargetPriv::getMultisampleSpecs(const GrPipeline& pipeline) const { 94 SkASSERT(fRenderTarget == pipeline.getRenderTarget()); // TODO: remove RT from pipeline. 95 GrGpu* gpu = fRenderTarget->getGpu(); 96 if (auto id = fRenderTarget->fMultisampleSpecsID) { 97 SkASSERT(gpu->queryMultisampleSpecs(pipeline).fUniqueID == id); 98 return gpu->getMultisampleSpecs(id); 99 } 100 const GrGpu::MultisampleSpecs& specs = gpu->queryMultisampleSpecs(pipeline); 101 fRenderTarget->fMultisampleSpecsID = specs.fUniqueID; 102 return specs; 103 } 104 105