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