• 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 #ifdef SKIA_OHOS
101         //OH ISSUE :cache small Texture on UnUni devices
102         auto context = fProxyProvider->getfImageContext();
103         bool clearSmallTexture = true;
104         if (context) {
105             clearSmallTexture = context->priv().options().clearSmallTexture;
106             auto direct = context->asDirectContext();
107             if (direct) {
108                 GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
109                 if (resourceProvider) {
110                     invalidGpuResource = resourceProvider->findByUniqueKey<GrGpuResource>(fUniqueKey);
111                 }
112             }
113         }
114         // less than 1024 Bytes resources will be delated
115         if (invalidGpuResource && clearSmallTexture && invalidGpuResource->gpuMemorySize() < 1024) {
116             fProxyProvider->processInvalidUniqueKey(
117                 fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kYes);
118         } else {
119             fProxyProvider->processInvalidUniqueKey(
120                 fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kNo);
121         }
122 #else
123         auto direct = fProxyProvider->getfImageContext()->asDirectContext();
124         if (direct) {
125             GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
126             if (resourceProvider) {
127                 invalidGpuResource = resourceProvider->findByUniqueKey<GrGpuResource>(fUniqueKey);
128             }
129         }
130         // less than 1024 Bytes resources will be delated
131         if (invalidGpuResource && invalidGpuResource->gpuMemorySize() < 1024) {
132             fProxyProvider->processInvalidUniqueKey(
133                 fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kYes);
134         } else {
135             fProxyProvider->processInvalidUniqueKey(
136                 fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kNo);
137         }
138 #endif
139     } else {
140         SkASSERT(!fProxyProvider);
141     }
142 }
143 
instantiate(GrResourceProvider * resourceProvider)144 bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
145     if (this->isLazy()) {
146         return false;
147     }
148     if (!this->instantiateImpl(resourceProvider, 1, GrRenderable::kNo, fMipmapped,
149                                fUniqueKey.isValid() ? &fUniqueKey : nullptr)) {
150         return false;
151     }
152 
153     SkASSERT(!this->peekRenderTarget());
154     SkASSERT(this->peekTexture());
155     return true;
156 }
157 
createSurface(GrResourceProvider * resourceProvider) const158 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
159     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, 1, GrRenderable::kNo,
160                                                        fMipmapped);
161     if (!surface) {
162         return nullptr;
163     }
164 
165     if (fUserCacheTaget) {
166         if (!(surface->getUniqueKey().isValid()) && !(surface->resourcePriv().getScratchKey().isValid())) {
167             surface->resourcePriv().userRegisterResource();
168         }
169     }
170 
171     SkASSERT(!surface->asRenderTarget());
172     SkASSERT(surface->asTexture());
173     return surface;
174 }
175 
setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader)176 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
177     SkASSERT(!fTextureProxy->fDeferredUploader);
178     fTextureProxy->fDeferredUploader = std::move(uploader);
179 }
180 
scheduleUpload(GrOpFlushState * flushState)181 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
182     // The texture proxy's contents may already have been uploaded or instantiation may have failed
183     if (fTextureProxy->fDeferredUploader && fTextureProxy->isInstantiated()) {
184         fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
185     }
186 }
187 
resetDeferredUploader()188 void GrTextureProxyPriv::resetDeferredUploader() {
189     SkASSERT(fTextureProxy->fDeferredUploader);
190     fTextureProxy->fDeferredUploader.reset();
191 }
192 
mipmapped() const193 GrMipmapped GrTextureProxy::mipmapped() const {
194     if (this->isInstantiated()) {
195         return this->peekTexture()->mipmapped();
196     }
197     return fMipmapped;
198 }
199 
onUninstantiatedGpuMemorySize() const200 size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const {
201     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
202                                   /*colorSamplesPerPixel=*/1, this->proxyMipmapped(),
203                                   !this->priv().isExact());
204 }
205 
ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy * first,const GrSurfaceProxy * second)206 bool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy* first,
207                                                         const GrSurfaceProxy* second) {
208     // In order to be compatible, the proxies should also have the same texture type. This is
209     // checked explicitly since the GrBackendFormat == operator does not compare texture type
210     return first->backendFormat().textureType() == second->backendFormat().textureType() &&
211            first->backendFormat() == second->backendFormat();
212 }
213 
setUniqueKey(GrProxyProvider * proxyProvider,const GrUniqueKey & key)214 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
215     SkASSERT(key.isValid());
216     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
217 
218     if (fTarget && fSyncTargetKey) {
219         if (!fTarget->getUniqueKey().isValid()) {
220             fTarget->resourcePriv().setUniqueKey(key);
221         }
222         SkASSERT(fTarget->getUniqueKey() == key);
223     }
224 
225     fUniqueKey = key;
226     fProxyProvider = proxyProvider;
227 }
228 
clearUniqueKey()229 void GrTextureProxy::clearUniqueKey() {
230     fUniqueKey.reset();
231     fProxyProvider = nullptr;
232 }
233 
callbackDesc() const234 GrSurfaceProxy::LazySurfaceDesc GrTextureProxy::callbackDesc() const {
235     SkISize dims;
236     SkBackingFit fit;
237     if (this->isFullyLazy()) {
238         fit = SkBackingFit::kApprox;
239         dims = {-1, -1};
240     } else {
241         fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox;
242         dims = this->dimensions();
243     }
244     return {
245             dims,
246             fit,
247             GrRenderable::kNo,
248             fMipmapped,
249             1,
250             this->backendFormat(),
251             this->textureType(),
252             this->isProtected(),
253             this->isBudgeted(),
254     };
255 }
256 
257 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)258 void GrTextureProxy::onValidateSurface(const GrSurface* surface) {
259     SkASSERT(!surface->asRenderTarget());
260 
261     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
262     SkASSERT(surface->asTexture());
263     // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture.
264     SkASSERT(GrMipmapped::kNo == this->proxyMipmapped() ||
265              GrMipmapped::kYes == surface->asTexture()->mipmapped());
266 
267     SkASSERT(surface->asTexture()->textureType() == this->textureType());
268 
269     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
270     GrInternalSurfaceFlags surfaceFlags = surface->flags();
271     SkASSERT(((int)proxyFlags & kGrInternalTextureFlagsMask) ==
272              ((int)surfaceFlags & kGrInternalTextureFlagsMask));
273 }
274 
275 #endif
276 
277