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