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 "src/gpu/GrRenderTarget.h"
10 
11 #include "include/gpu/GrContext.h"
12 #include "src/core/SkRectPriv.h"
13 #include "src/gpu/GrContextPriv.h"
14 #include "src/gpu/GrGpu.h"
15 #include "src/gpu/GrRenderTargetContext.h"
16 #include "src/gpu/GrRenderTargetPriv.h"
17 #include "src/gpu/GrSamplePatternDictionary.h"
18 #include "src/gpu/GrStencilAttachment.h"
19 #include "src/gpu/GrStencilSettings.h"
20 
GrRenderTarget(GrGpu * gpu,const SkISize & size,GrPixelConfig config,int sampleCount,GrProtected isProtected,GrStencilAttachment * stencil)21 GrRenderTarget::GrRenderTarget(GrGpu* gpu, const SkISize& size, GrPixelConfig config,
22                                int sampleCount, GrProtected isProtected,
23                                GrStencilAttachment* stencil)
24         : INHERITED(gpu, size, config, isProtected)
25         , fSampleCnt(sampleCount)
26         , fSamplePatternKey(GrSamplePatternDictionary::kInvalidSamplePatternKey)
27         , fStencilAttachment(stencil) {
28 }
29 
30 GrRenderTarget::~GrRenderTarget() = default;
31 
onRelease()32 void GrRenderTarget::onRelease() {
33     fStencilAttachment = nullptr;
34 
35     INHERITED::onRelease();
36 }
37 
onAbandon()38 void GrRenderTarget::onAbandon() {
39     fStencilAttachment = nullptr;
40 
41     INHERITED::onAbandon();
42 }
43 
44 ///////////////////////////////////////////////////////////////////////////////
45 
attachStencilAttachment(sk_sp<GrStencilAttachment> stencil)46 void GrRenderTargetPriv::attachStencilAttachment(sk_sp<GrStencilAttachment> stencil) {
47 #ifdef SK_DEBUG
48     if (1 == fRenderTarget->fSampleCnt) {
49         // TODO: We don't expect a mixed sampled render target to ever change its stencil buffer
50         // right now. But if it does swap in a stencil buffer with a different number of samples,
51         // and if we have a valid fSamplePatternKey, we will need to invalidate fSamplePatternKey
52         // here and add tests to make sure we it properly.
53         SkASSERT(GrSamplePatternDictionary::kInvalidSamplePatternKey ==
54                  fRenderTarget->fSamplePatternKey);
55     } else {
56         // Render targets with >1 color sample should never use mixed samples. (This would lead to
57         // different sample patterns, depending on stencil state.)
58         SkASSERT(!stencil || stencil->numSamples() == fRenderTarget->fSampleCnt);
59     }
60 #endif
61 
62     if (!stencil && !fRenderTarget->fStencilAttachment) {
63         // No need to do any work since we currently don't have a stencil attachment and
64         // we're not actually adding one.
65         return;
66     }
67 
68     fRenderTarget->fStencilAttachment = std::move(stencil);
69     if (!fRenderTarget->completeStencilAttachment()) {
70         fRenderTarget->fStencilAttachment = nullptr;
71     }
72 }
73 
numStencilBits() const74 int GrRenderTargetPriv::numStencilBits() const {
75     SkASSERT(this->getStencilAttachment());
76     return this->getStencilAttachment()->bits();
77 }
78 
getSamplePatternKey() const79 int GrRenderTargetPriv::getSamplePatternKey() const {
80 #ifdef SK_DEBUG
81     GrStencilAttachment* stencil = fRenderTarget->fStencilAttachment.get();
82     if (fRenderTarget->fSampleCnt <= 1) {
83         // If the color buffer is not multisampled, the sample pattern better come from the stencil
84         // buffer (mixed samples).
85         SkASSERT(stencil && stencil->numSamples() > 1);
86     } else {
87         // The color sample count and stencil count cannot both be unequal and both greater than
88         // one. If this were the case, there would be more than one sample pattern associated with
89         // the render target.
90         SkASSERT(!stencil || stencil->numSamples() == fRenderTarget->fSampleCnt);
91     }
92 #endif
93     if (GrSamplePatternDictionary::kInvalidSamplePatternKey == fRenderTarget->fSamplePatternKey) {
94         fRenderTarget->fSamplePatternKey =
95                 fRenderTarget->getGpu()->findOrAssignSamplePatternKey(fRenderTarget);
96     }
97     SkASSERT(GrSamplePatternDictionary::kInvalidSamplePatternKey
98                      != fRenderTarget->fSamplePatternKey);
99     return fRenderTarget->fSamplePatternKey;
100 }
101