• 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 #include "src/gpu/ganesh/GrTextureRenderTargetProxy.h"
9 
10 #include "src/gpu/ganesh/GrCaps.h"
11 #include "src/gpu/ganesh/GrRenderTarget.h"
12 #include "src/gpu/ganesh/GrSurface.h"
13 #include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
14 #include "src/gpu/ganesh/GrTexture.h"
15 #include "src/gpu/ganesh/GrTextureProxyPriv.h"
16 
17 #ifdef SK_DEBUG
18 #include "include/gpu/GrDirectContext.h"
19 #include "src/gpu/ganesh/GrDirectContextPriv.h"
20 #endif
21 
22 // Deferred version
23 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
24 // GrRenderTargetProxy) so its constructor must be explicitly called.
GrTextureRenderTargetProxy(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,int sampleCnt,GrMipmapped mipmapped,GrMipmapStatus mipmapStatus,SkBackingFit fit,skgpu::Budgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator,GrDDLProvider creatingProvider,std::string_view label)25 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
26                                                        const GrBackendFormat& format,
27                                                        SkISize dimensions,
28                                                        int sampleCnt,
29                                                        GrMipmapped mipmapped,
30                                                        GrMipmapStatus mipmapStatus,
31                                                        SkBackingFit fit,
32                                                        skgpu::Budgeted budgeted,
33                                                        GrProtected isProtected,
34                                                        GrInternalSurfaceFlags surfaceFlags,
35                                                        UseAllocator useAllocator,
36                                                        GrDDLProvider creatingProvider,
37                                                        std::string_view label)
38         : GrSurfaceProxy(
39                   format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator, label)
40         // for now textures w/ data are always wrapped
41         , GrRenderTargetProxy(caps,
42                               format,
43                               dimensions,
44                               sampleCnt,
45                               fit,
46                               budgeted,
47                               isProtected,
48                               surfaceFlags,
49                               useAllocator,
50                               label)
51         , GrTextureProxy(format,
52                          dimensions,
53                          mipmapped,
54                          mipmapStatus,
55                          fit,
56                          budgeted,
57                          isProtected,
58                          surfaceFlags,
59                          useAllocator,
60                          creatingProvider,
61                          label) {
62     this->initSurfaceFlags(caps);
63 }
64 
65 // Lazy-callback version
GrTextureRenderTargetProxy(const GrCaps & caps,LazyInstantiateCallback && callback,const GrBackendFormat & format,SkISize dimensions,int sampleCnt,GrMipmapped mipmapped,GrMipmapStatus mipmapStatus,SkBackingFit fit,skgpu::Budgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator,GrDDLProvider creatingProvider,std::string_view label)66 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
67                                                        LazyInstantiateCallback&& callback,
68                                                        const GrBackendFormat& format,
69                                                        SkISize dimensions,
70                                                        int sampleCnt,
71                                                        GrMipmapped mipmapped,
72                                                        GrMipmapStatus mipmapStatus,
73                                                        SkBackingFit fit,
74                                                        skgpu::Budgeted budgeted,
75                                                        GrProtected isProtected,
76                                                        GrInternalSurfaceFlags surfaceFlags,
77                                                        UseAllocator useAllocator,
78                                                        GrDDLProvider creatingProvider,
79                                                        std::string_view label)
80         : GrSurfaceProxy(std::move(callback),
81                          format,
82                          dimensions,
83                          fit,
84                          budgeted,
85                          isProtected,
86                          surfaceFlags,
87                          useAllocator,
88                          label)
89         // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
90         // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
91         , GrRenderTargetProxy(LazyInstantiateCallback(),
92                               format,
93                               dimensions,
94                               sampleCnt,
95                               fit,
96                               budgeted,
97                               isProtected,
98                               surfaceFlags,
99                               useAllocator,
100                               WrapsVkSecondaryCB::kNo,
101                               label)
102         , GrTextureProxy(LazyInstantiateCallback(),
103                          format,
104                          dimensions,
105                          mipmapped,
106                          mipmapStatus,
107                          fit,
108                          budgeted,
109                          isProtected,
110                          surfaceFlags,
111                          useAllocator,
112                          creatingProvider,
113                          label) {
114     this->initSurfaceFlags(caps);
115 }
116 
117 // Wrapped version
118 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
119 // GrRenderTargetProxy) so its constructor must be explicitly called.
GrTextureRenderTargetProxy(sk_sp<GrSurface> surf,UseAllocator useAllocator,GrDDLProvider creatingProvider)120 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrSurface> surf,
121                                                        UseAllocator useAllocator,
122                                                        GrDDLProvider creatingProvider)
123         : GrSurfaceProxy(surf, SkBackingFit::kExact, useAllocator)
124         , GrRenderTargetProxy(surf, useAllocator)
125         , GrTextureProxy(surf, useAllocator, creatingProvider) {
126     SkASSERT(surf->asTexture());
127     SkASSERT(surf->asRenderTarget());
128     SkASSERT(fSurfaceFlags == fTarget->flags());
129     SkASSERT((this->numSamples() <= 1 ||
130               fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) !=
131              this->requiresManualMSAAResolve());
132 }
133 
initSurfaceFlags(const GrCaps & caps)134 void GrTextureRenderTargetProxy::initSurfaceFlags(const GrCaps& caps) {
135     // FBO 0 should never be wrapped as a texture render target.
136     SkASSERT(!this->glRTFBOIDIs0());
137     if (this->numSamples() > 1 && !caps.msaaResolvesAutomatically())  {
138         // MSAA texture-render-targets always require manual resolve if we are not using a
139         // multisampled-render-to-texture extension.
140         //
141         // NOTE: This is the only instance where we need to set the manual resolve flag on a proxy.
142         // Any other proxies that require manual resolve (e.g., wrapRenderableBackendTexture() with
143         // a sample count)  will be wrapped, and the wrapped version of the GrSurface constructor
144         // will automatically get the manual resolve flag when copying the target GrSurface's flags.
145         fSurfaceFlags |= GrInternalSurfaceFlags::kRequiresManualMSAAResolve;
146     }
147 }
148 
onUninstantiatedGpuMemorySize() const149 size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
150     int colorSamplesPerPixel = this->numSamples();
151     if (colorSamplesPerPixel > 1) {
152         // Add one to account for the resolve buffer.
153         ++colorSamplesPerPixel;
154     }
155 
156     // TODO: do we have enough information to improve this worst case estimate?
157     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
158                                   colorSamplesPerPixel, this->proxyMipmapped(),
159                                   !this->priv().isExact());
160 }
161 
instantiate(GrResourceProvider * resourceProvider)162 bool GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
163     if (this->isLazy()) {
164         return false;
165     }
166 
167     const skgpu::UniqueKey& key = this->getUniqueKey();
168 
169     if (!this->instantiateImpl(resourceProvider, this->numSamples(), GrRenderable::kYes,
170                                this->mipmapped(), key.isValid() ? &key : nullptr)) {
171         return false;
172     }
173     if (key.isValid()) {
174         SkASSERT(key == this->getUniqueKey());
175     }
176 
177     SkASSERT(this->peekRenderTarget());
178     SkASSERT(this->peekTexture());
179 
180     return true;
181 }
182 
createSurface(GrResourceProvider * resourceProvider) const183 sk_sp<GrSurface> GrTextureRenderTargetProxy::createSurface(
184                                                     GrResourceProvider* resourceProvider) const {
185     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, this->numSamples(),
186                                                        GrRenderable::kYes, this->mipmapped());
187     if (!surface) {
188         return nullptr;
189     }
190     SkASSERT(surface->asRenderTarget());
191     SkASSERT(surface->asTexture());
192 
193     return surface;
194 }
195 
callbackDesc() const196 GrSurfaceProxy::LazySurfaceDesc GrTextureRenderTargetProxy::callbackDesc() const {
197     SkISize dims;
198     SkBackingFit fit;
199     if (this->isFullyLazy()) {
200         fit = SkBackingFit::kApprox;
201         dims = {-1, -1};
202     } else {
203         fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox;
204         dims = this->dimensions();
205     }
206     return {
207             dims,
208             fit,
209             GrRenderable::kYes,
210             this->mipmapped(),
211             this->numSamples(),
212             this->backendFormat(),
213             this->textureType(),
214             this->isProtected(),
215             this->isBudgeted(),
216             this->getLabel(),
217     };
218 }
219 
220 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)221 void GrTextureRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
222     // Anything checked here should also be checking the GrTextureProxy version
223     SkASSERT(surface->asTexture());
224     SkASSERT(GrMipmapped::kNo == this->proxyMipmapped() ||
225              GrMipmapped::kYes == surface->asTexture()->mipmapped());
226 
227     // Anything checked here should also be checking the GrRenderTargetProxy version
228     SkASSERT(surface->asRenderTarget());
229     SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples());
230 
231     SkASSERT(surface->asTexture()->textureType() == this->textureType());
232 
233     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
234     GrInternalSurfaceFlags surfaceFlags = surface->flags();
235 
236     // Only non-RT textures can be read only.
237     SkASSERT(!(proxyFlags & GrInternalSurfaceFlags::kReadOnly));
238     SkASSERT(!(surfaceFlags & GrInternalSurfaceFlags::kReadOnly));
239 
240     SkASSERT(((int)proxyFlags & kGrInternalTextureRenderTargetFlagsMask) ==
241              ((int)surfaceFlags & kGrInternalTextureRenderTargetFlagsMask));
242 
243     // We manually check the kVkRTSupportsInputAttachment since we only require it on the surface if
244     // the proxy has it set. If the proxy doesn't have the flag it is legal for the surface to
245     // have the flag.
246     if (proxyFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment) {
247         SkASSERT(surfaceFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment);
248     }
249 }
250 #endif
251 
252