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#include "SkRectPriv.h" 20 21GrRenderTarget::GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc, 22 GrRenderTargetFlags flags, 23 GrStencilAttachment* stencil) 24 : INHERITED(gpu, desc) 25 , fSampleCnt(desc.fSampleCnt) 26 , fStencilAttachment(stencil) 27 , fMultisampleSpecsID(0) 28 , fFlags(flags) { 29 SkASSERT(desc.fFlags & kRenderTarget_GrSurfaceFlag); 30 SkASSERT(!(fFlags & GrRenderTargetFlags::kMixedSampled) || fSampleCnt > 1); 31 SkASSERT(!(fFlags & GrRenderTargetFlags::kWindowRectsSupport) || 32 gpu->caps()->maxWindowRectangles() > 0); 33 fResolveRect = SkRectPriv::MakeILargestInverted(); 34} 35 36void GrRenderTarget::flagAsNeedingResolve(const SkIRect* rect) { 37 if (kCanResolve_ResolveType == getResolveType()) { 38 if (rect) { 39 fResolveRect.join(*rect); 40 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 41 fResolveRect.setEmpty(); 42 } 43 } else { 44 fResolveRect.setLTRB(0, 0, this->width(), this->height()); 45 } 46 } 47} 48 49void GrRenderTarget::overrideResolveRect(const SkIRect rect) { 50 fResolveRect = rect; 51 if (fResolveRect.isEmpty()) { 52 fResolveRect = SkRectPriv::MakeILargestInverted(); 53 } else { 54 if (!fResolveRect.intersect(0, 0, this->width(), this->height())) { 55 fResolveRect = SkRectPriv::MakeILargestInverted(); 56 } 57 } 58} 59 60void GrRenderTarget::flagAsResolved() { 61 fResolveRect = SkRectPriv::MakeILargestInverted(); 62} 63 64void GrRenderTarget::onRelease() { 65 SkSafeSetNull(fStencilAttachment); 66 67 INHERITED::onRelease(); 68} 69 70void GrRenderTarget::onAbandon() { 71 SkSafeSetNull(fStencilAttachment); 72 73 INHERITED::onAbandon(); 74} 75 76/////////////////////////////////////////////////////////////////////////////// 77 78bool GrRenderTargetPriv::attachStencilAttachment(sk_sp<GrStencilAttachment> stencil) { 79 if (!stencil && !fRenderTarget->fStencilAttachment) { 80 // No need to do any work since we currently don't have a stencil attachment and 81 // we're not actually adding one. 82 return true; 83 } 84 fRenderTarget->fStencilAttachment = stencil.release(); 85 if (!fRenderTarget->completeStencilAttachment()) { 86 SkSafeSetNull(fRenderTarget->fStencilAttachment); 87 return false; 88 } 89 return true; 90} 91 92int GrRenderTargetPriv::numStencilBits() const { 93 SkASSERT(this->getStencilAttachment()); 94 return this->getStencilAttachment()->bits(); 95} 96 97const GrGpu::MultisampleSpecs& 98GrRenderTargetPriv::getMultisampleSpecs(const GrPipeline& pipeline) const { 99 SkASSERT(fRenderTarget == pipeline.renderTarget()); // TODO: remove RT from pipeline. 100 GrGpu* gpu = fRenderTarget->getGpu(); 101 if (auto id = fRenderTarget->fMultisampleSpecsID) { 102 SkASSERT(gpu->queryMultisampleSpecs(pipeline).fUniqueID == id); 103 return gpu->getMultisampleSpecs(id); 104 } 105 const GrGpu::MultisampleSpecs& specs = gpu->queryMultisampleSpecs(pipeline); 106 fRenderTarget->fMultisampleSpecsID = specs.fUniqueID; 107 return specs; 108} 109 110