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