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