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