• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 #ifndef GrRenderTargetProxy_DEFINED
9 #define GrRenderTargetProxy_DEFINED
10 
11 #include "include/private/GrTypesPriv.h"
12 #include "src/gpu/GrCaps.h"
13 #include "src/gpu/GrSurfaceProxy.h"
14 #include "src/gpu/GrSwizzle.h"
15 
16 class GrResourceProvider;
17 class GrRenderTargetProxyPriv;
18 
19 // This class delays the acquisition of RenderTargets until they are actually
20 // required
21 // Beware: the uniqueID of the RenderTargetProxy will usually be different than
22 // the uniqueID of the RenderTarget it represents!
23 class GrRenderTargetProxy : virtual public GrSurfaceProxy {
24 public:
asRenderTargetProxy()25     GrRenderTargetProxy* asRenderTargetProxy() override { return this; }
asRenderTargetProxy()26     const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; }
27 
28     // Actually instantiate the backing rendertarget, if necessary.
29     bool instantiate(GrResourceProvider*) override;
30 
canUseMixedSamples(const GrCaps & caps)31     bool canUseMixedSamples(const GrCaps& caps) const {
32         return caps.mixedSamplesSupport() && !this->glRTFBOIDIs0() &&
33                caps.internalMultisampleCount(this->backendFormat()) > 0 &&
34                this->canChangeStencilAttachment();
35     }
36 
37     /*
38      * Indicate that a draw to this proxy requires stencil, and how many stencil samples it needs.
39      * The number of stencil samples on this proxy will be equal to the largest sample count passed
40      * to this method.
41      */
setNeedsStencil(int8_t numStencilSamples)42     void setNeedsStencil(int8_t numStencilSamples) {
43         SkASSERT(numStencilSamples >= fSampleCnt);
44         fNumStencilSamples = SkTMax(numStencilSamples, fNumStencilSamples);
45     }
46 
47     /**
48      * Returns the number of stencil samples required by this proxy.
49      * NOTE: Once instantiated, the actual render target may have more samples, but it is guaranteed
50      * to have at least this many. (After a multisample stencil buffer has been attached to a render
51      * target, we never "downgrade" it to one with fewer samples.)
52      */
numStencilSamples()53     int numStencilSamples() const { return fNumStencilSamples; }
54 
55     /**
56      * Returns the number of samples/pixel in the color buffer (One if non-MSAA).
57      */
numSamples()58     int numSamples() const { return fSampleCnt; }
59 
60     int maxWindowRectangles(const GrCaps& caps) const;
61 
outputSwizzle()62     const GrSwizzle& outputSwizzle() const { return fOutputSwizzle; }
63 
wrapsVkSecondaryCB()64     bool wrapsVkSecondaryCB() const { return fWrapsVkSecondaryCB == WrapsVkSecondaryCB::kYes; }
65 
66     // TODO: move this to a priv class!
67     bool refsWrappedObjects() const;
68 
69     // Provides access to special purpose functions.
70     GrRenderTargetProxyPriv rtPriv();
71     const GrRenderTargetProxyPriv rtPriv() const;
72 
73 protected:
74     friend class GrProxyProvider;  // for ctors
75     friend class GrRenderTargetProxyPriv;
76 
77     // Deferred version
78     GrRenderTargetProxy(const GrCaps&, const GrBackendFormat&, const GrSurfaceDesc&,
79                         int sampleCount, GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
80                         const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted, GrProtected,
81                         GrInternalSurfaceFlags);
82 
83     enum class WrapsVkSecondaryCB : bool { kNo = false, kYes = true };
84 
85     // Lazy-callback version
86     // There are two main use cases for lazily-instantiated proxies:
87     //   basic knowledge - width, height, config, samples, origin are known
88     //   minimal knowledge - only config is known.
89     //
90     // The basic knowledge version is used for DDL where we know the type of proxy we are going to
91     // use, but we don't have access to the GPU yet to instantiate it.
92     //
93     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
94     // know the final size until flush time.
95     GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType,
96                         const GrBackendFormat&, const GrSurfaceDesc&, int sampleCount,
97                         GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
98                         const GrSwizzle& outputSwizzle, SkBackingFit, SkBudgeted, GrProtected,
99                         GrInternalSurfaceFlags, WrapsVkSecondaryCB wrapsVkSecondaryCB);
100 
101     // Wrapped version
102     GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin, const GrSwizzle& textureSwizzle,
103                         const GrSwizzle& outputSwizzle,
104                         WrapsVkSecondaryCB wrapsVkSecondaryCB = WrapsVkSecondaryCB::kNo);
105 
106     sk_sp<GrSurface> createSurface(GrResourceProvider*) const override;
107 
108 private:
setGLRTFBOIDIs0()109     void setGLRTFBOIDIs0() {
110         fSurfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
111     }
glRTFBOIDIs0()112     bool glRTFBOIDIs0() const {
113         return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0;
114     }
115     bool canChangeStencilAttachment() const;
116 
117     size_t onUninstantiatedGpuMemorySize() const override;
118     SkDEBUGCODE(void onValidateSurface(const GrSurface*) override;)
119 
120     // WARNING: Be careful when adding or removing fields here. ASAN is likely to trigger warnings
121     // when instantiating GrTextureRenderTargetProxy. The std::function in GrSurfaceProxy makes
122     // each class in the diamond require 16 byte alignment. Clang appears to layout the fields for
123     // each class to achieve the necessary alignment. However, ASAN checks the alignment of 'this'
124     // in the constructors, and always looks for the full 16 byte alignment, even if the fields in
125     // that particular class don't require it. Changing the size of this object can move the start
126     // address of other types, leading to this problem.
127     int8_t             fSampleCnt;
128     int8_t             fNumStencilSamples = 0;
129     WrapsVkSecondaryCB fWrapsVkSecondaryCB;
130     GrSwizzle          fOutputSwizzle;
131     // This is to fix issue in large comment above. Without the padding we end 6 bytes into a 16
132     // byte range, so the GrTextureProxy ends up starting 8 byte aligned by not 16. We add the
133     // padding here to get us right up to the 16 byte alignment (technically any padding of 3-10
134     // bytes would work since it always goes up to 8 byte alignment, but we use 10 to more explicit
135     // about what we're doing).
136     char               fDummyPadding[10];
137 
138     // For wrapped render targets the actual GrRenderTarget is stored in the GrIORefProxy class.
139     // For deferred proxies that pointer is filled in when we need to instantiate the
140     // deferred resource.
141 
142     typedef GrSurfaceProxy INHERITED;
143 };
144 
145 #endif
146