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