• 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/GrTextureProxy.h"
9 #include "src/gpu/ganesh/GrTextureProxyPriv.h"
10 
11 #include "include/core/SkSize.h"
12 #include "include/gpu/GpuTypes.h"
13 #include "include/gpu/ganesh/GrBackendSurface.h"
14 #include "include/gpu/ganesh/GrDirectContext.h"
15 #include "include/gpu/ganesh/GrTypes.h"
16 #include "src/gpu/SkBackingFit.h"
17 #include "src/gpu/ganesh/GrDeferredProxyUploader.h"
18 #include "src/gpu/ganesh/GrDirectContextPriv.h"
19 #include "src/gpu/ganesh/GrGpuResourcePriv.h"
20 #include "src/gpu/ganesh/GrProxyProvider.h"
21 #include "src/gpu/ganesh/GrResourceProvider.h"
22 #include "src/gpu/ganesh/GrSurface.h"
23 #include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
24 #include "src/gpu/ganesh/GrTexture.h"
25 
26 #include <utility>
27 
28 class GrOpFlushState;
29 
30 // Deferred version - no data
GrTextureProxy(const GrBackendFormat & format,SkISize dimensions,skgpu::Mipmapped mipmapped,GrMipmapStatus mipmapStatus,SkBackingFit fit,skgpu::Budgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator,GrDDLProvider creatingProvider,std::string_view label)31 GrTextureProxy::GrTextureProxy(const GrBackendFormat& format,
32                                SkISize dimensions,
33                                skgpu::Mipmapped mipmapped,
34                                GrMipmapStatus mipmapStatus,
35                                SkBackingFit fit,
36                                skgpu::Budgeted budgeted,
37                                GrProtected isProtected,
38                                GrInternalSurfaceFlags surfaceFlags,
39                                UseAllocator useAllocator,
40                                GrDDLProvider creatingProvider,
41                                std::string_view label)
42         : INHERITED(
43                   format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator, label)
44         , fMipmapped(mipmapped)
45         , fMipmapStatus(mipmapStatus) SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus))
46         , fCreatingProvider(creatingProvider)
47         , fProxyProvider(nullptr)
48         , fDeferredUploader(nullptr) {
49     SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
50     if (this->textureType() == GrTextureType::kExternal) {
51         fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
52     }
53 }
54 
55 // Lazy-callback version
GrTextureProxy(LazyInstantiateCallback && callback,const GrBackendFormat & format,SkISize dimensions,skgpu::Mipmapped mipmapped,GrMipmapStatus mipmapStatus,SkBackingFit fit,skgpu::Budgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator,GrDDLProvider creatingProvider,std::string_view label)56 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback,
57                                const GrBackendFormat& format,
58                                SkISize dimensions,
59                                skgpu::Mipmapped mipmapped,
60                                GrMipmapStatus mipmapStatus,
61                                SkBackingFit fit,
62                                skgpu::Budgeted budgeted,
63                                GrProtected isProtected,
64                                GrInternalSurfaceFlags surfaceFlags,
65                                UseAllocator useAllocator,
66                                GrDDLProvider creatingProvider,
67                                std::string_view label)
68         : INHERITED(std::move(callback),
69                     format,
70                     dimensions,
71                     fit,
72                     budgeted,
73                     isProtected,
74                     surfaceFlags,
75                     useAllocator,
76                     label)
77         , fMipmapped(mipmapped)
78         , fMipmapStatus(mipmapStatus) SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus))
79         , fCreatingProvider(creatingProvider)
80         , fProxyProvider(nullptr)
81         , fDeferredUploader(nullptr) {
82     SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly));
83     if (this->textureType() == GrTextureType::kExternal) {
84         fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
85     }
86 }
87 
88 // Wrapped version
GrTextureProxy(sk_sp<GrSurface> surf,UseAllocator useAllocator,GrDDLProvider creatingProvider)89 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf,
90                                UseAllocator useAllocator,
91                                GrDDLProvider creatingProvider)
92         : INHERITED(std::move(surf), SkBackingFit::kExact, useAllocator)
93         , fMipmapped(fTarget->asTexture()->mipmapped())
94         , fMipmapStatus(fTarget->asTexture()->mipmapStatus())
95         SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus))
96         , fCreatingProvider(creatingProvider)
97         , fProxyProvider(nullptr)
98         , fDeferredUploader(nullptr) {
99     if (fTarget->getUniqueKey().isValid()) {
100         fProxyProvider = fTarget->asTexture()->getContext()->priv().proxyProvider();
101         fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget.get());
102     }
103     if (this->textureType() == GrTextureType::kExternal) {
104         fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
105     }
106 }
107 
~GrTextureProxy()108 GrTextureProxy::~GrTextureProxy() {
109     // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away
110     // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it.
111     fTarget = nullptr;
112 
113     // In DDL-mode, uniquely keyed proxies keep their key even after their originating
114     // proxy provider has gone away. In that case there is noone to send the invalid key
115     // message to (Note: in this case we don't want to remove its cached resource).
116     if (fUniqueKey.isValid() && fProxyProvider) {
117         sk_sp<GrGpuResource> invalidGpuResource;
118         auto direct = fProxyProvider->getfImageContext()->asDirectContext();
119         if (direct) {
120             GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
121             if (resourceProvider) {
122                 invalidGpuResource = resourceProvider->findByUniqueKey<GrGpuResource>(fUniqueKey);
123             }
124         }
125         // less than 1024 Bytes resources will be delated
126         if (invalidGpuResource && invalidGpuResource->gpuMemorySize() < 1024) {
127             fProxyProvider->processInvalidUniqueKey(
128                 fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kYes);
129         } else {
130             fProxyProvider->processInvalidUniqueKey(
131                 fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kNo);
132         }
133     } else {
134         SkASSERT(!fProxyProvider);
135     }
136 }
137 
instantiate(GrResourceProvider * resourceProvider)138 bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
139     if (this->isLazy()) {
140         return false;
141     }
142     if (!this->instantiateImpl(resourceProvider, 1, GrRenderable::kNo, fMipmapped,
143                                fUniqueKey.isValid() ? &fUniqueKey : nullptr)) {
144         return false;
145     }
146 
147     SkASSERT(!this->peekRenderTarget());
148     SkASSERT(this->peekTexture());
149     return true;
150 }
151 
createSurface(GrResourceProvider * resourceProvider) const152 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
153     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, 1, GrRenderable::kNo,
154                                                        fMipmapped);
155     if (!surface) {
156         return nullptr;
157     }
158 
159     if (fUserCacheTaget) {
160         if (!(surface->getUniqueKey().isValid()) && !(surface->resourcePriv().getScratchKey().isValid())) {
161             surface->resourcePriv().userRegisterResource();
162         }
163     }
164 
165     SkASSERT(!surface->asRenderTarget());
166     SkASSERT(surface->asTexture());
167     return surface;
168 }
169 
setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader)170 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
171     SkASSERT(!fTextureProxy->fDeferredUploader);
172     fTextureProxy->fDeferredUploader = std::move(uploader);
173 }
174 
scheduleUpload(GrOpFlushState * flushState)175 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
176     // The texture proxy's contents may already have been uploaded or instantiation may have failed
177     if (fTextureProxy->fDeferredUploader && fTextureProxy->isInstantiated()) {
178         fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
179     }
180 }
181 
resetDeferredUploader()182 void GrTextureProxyPriv::resetDeferredUploader() {
183     SkASSERT(fTextureProxy->fDeferredUploader);
184     fTextureProxy->fDeferredUploader.reset();
185 }
186 
mipmapped() const187 skgpu::Mipmapped GrTextureProxy::mipmapped() const {
188     if (this->isInstantiated()) {
189         return this->peekTexture()->mipmapped();
190     }
191     return fMipmapped;
192 }
193 
textureType() const194 GrTextureType GrTextureProxy::textureType() const { return this->backendFormat().textureType(); }
195 
onUninstantiatedGpuMemorySize() const196 size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const {
197     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
198                                   /*colorSamplesPerPixel=*/1, this->proxyMipmapped(),
199                                   !this->priv().isExact());
200 }
201 
ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy * first,const GrSurfaceProxy * second)202 bool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy* first,
203                                                         const GrSurfaceProxy* second) {
204     // In order to be compatible, the proxies should also have the same texture type. This is
205     // checked explicitly since the GrBackendFormat == operator does not compare texture type
206     return first->backendFormat().textureType() == second->backendFormat().textureType() &&
207            first->backendFormat() == second->backendFormat();
208 }
209 
setUniqueKey(GrProxyProvider * proxyProvider,const skgpu::UniqueKey & key)210 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const skgpu::UniqueKey& key) {
211     SkASSERT(key.isValid());
212     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
213 
214     if (fTarget && fSyncTargetKey) {
215         if (!fTarget->getUniqueKey().isValid()) {
216             fTarget->resourcePriv().setUniqueKey(key);
217         }
218         SkASSERT(fTarget->getUniqueKey() == key);
219     }
220 
221     fUniqueKey = key;
222     fProxyProvider = proxyProvider;
223 }
224 
clearUniqueKey()225 void GrTextureProxy::clearUniqueKey() {
226     fUniqueKey.reset();
227     fProxyProvider = nullptr;
228 }
229 
callbackDesc() const230 GrSurfaceProxy::LazySurfaceDesc GrTextureProxy::callbackDesc() const {
231     SkISize dims;
232     SkBackingFit fit;
233     if (this->isFullyLazy()) {
234         fit = SkBackingFit::kApprox;
235         dims = {-1, -1};
236     } else {
237         fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox;
238         dims = this->dimensions();
239     }
240     return {
241             dims,
242             fit,
243             GrRenderable::kNo,
244             fMipmapped,
245             1,
246             this->backendFormat(),
247             this->textureType(),
248             this->isProtected(),
249             this->isBudgeted(),
250             this->getLabel(),
251     };
252 }
253 
254 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)255 void GrTextureProxy::onValidateSurface(const GrSurface* surface) {
256     SkASSERT(!surface->asRenderTarget());
257 
258     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
259     SkASSERT(surface->asTexture());
260     // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture.
261     SkASSERT(skgpu::Mipmapped::kNo == this->proxyMipmapped() ||
262              skgpu::Mipmapped::kYes == surface->asTexture()->mipmapped());
263 
264     SkASSERT(surface->asTexture()->textureType() == this->textureType());
265 
266     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
267     GrInternalSurfaceFlags surfaceFlags = surface->flags();
268     SkASSERT(((int)proxyFlags & kGrInternalTextureFlagsMask) ==
269              ((int)surfaceFlags & kGrInternalTextureFlagsMask));
270 }
271 
272 #endif
273 
274