• 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     SkASSERT(!surface->asRenderTarget());
127     SkASSERT(surface->asTexture());
128     return surface;
129 }
130 
setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader)131 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
132     SkASSERT(!fTextureProxy->fDeferredUploader);
133     fTextureProxy->fDeferredUploader = std::move(uploader);
134 }
135 
scheduleUpload(GrOpFlushState * flushState)136 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
137     // The texture proxy's contents may already have been uploaded or instantiation may have failed
138     if (fTextureProxy->fDeferredUploader && fTextureProxy->isInstantiated()) {
139         fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
140     }
141 }
142 
resetDeferredUploader()143 void GrTextureProxyPriv::resetDeferredUploader() {
144     SkASSERT(fTextureProxy->fDeferredUploader);
145     fTextureProxy->fDeferredUploader.reset();
146 }
147 
mipmapped() const148 GrMipmapped GrTextureProxy::mipmapped() const {
149     if (this->isInstantiated()) {
150         return this->peekTexture()->mipmapped();
151     }
152     return fMipmapped;
153 }
154 
onUninstantiatedGpuMemorySize() const155 size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const {
156     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
157                                   /*colorSamplesPerPixel=*/1, this->proxyMipmapped(),
158                                   !this->priv().isExact());
159 }
160 
ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy * first,const GrSurfaceProxy * second)161 bool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy* first,
162                                                         const GrSurfaceProxy* second) {
163     // In order to be compatible, the proxies should also have the same texture type. This is
164     // checked explicitly since the GrBackendFormat == operator does not compare texture type
165     return first->backendFormat().textureType() == second->backendFormat().textureType() &&
166            first->backendFormat() == second->backendFormat();
167 }
168 
setUniqueKey(GrProxyProvider * proxyProvider,const GrUniqueKey & key)169 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
170     SkASSERT(key.isValid());
171     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
172 
173     if (fTarget && fSyncTargetKey) {
174         if (!fTarget->getUniqueKey().isValid()) {
175             fTarget->resourcePriv().setUniqueKey(key);
176         }
177         SkASSERT(fTarget->getUniqueKey() == key);
178     }
179 
180     fUniqueKey = key;
181     fProxyProvider = proxyProvider;
182 }
183 
clearUniqueKey()184 void GrTextureProxy::clearUniqueKey() {
185     fUniqueKey.reset();
186     fProxyProvider = nullptr;
187 }
188 
callbackDesc() const189 GrSurfaceProxy::LazySurfaceDesc GrTextureProxy::callbackDesc() const {
190     SkISize dims;
191     SkBackingFit fit;
192     if (this->isFullyLazy()) {
193         fit = SkBackingFit::kApprox;
194         dims = {-1, -1};
195     } else {
196         fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox;
197         dims = this->dimensions();
198     }
199     return {
200             dims,
201             fit,
202             GrRenderable::kNo,
203             fMipmapped,
204             1,
205             this->backendFormat(),
206             this->textureType(),
207             this->isProtected(),
208             this->isBudgeted(),
209     };
210 }
211 
212 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)213 void GrTextureProxy::onValidateSurface(const GrSurface* surface) {
214     SkASSERT(!surface->asRenderTarget());
215 
216     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
217     SkASSERT(surface->asTexture());
218     // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture.
219     SkASSERT(GrMipmapped::kNo == this->proxyMipmapped() ||
220              GrMipmapped::kYes == surface->asTexture()->mipmapped());
221 
222     SkASSERT(surface->asTexture()->textureType() == this->textureType());
223 
224     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
225     GrInternalSurfaceFlags surfaceFlags = surface->flags();
226     SkASSERT(((int)proxyFlags & kGrInternalTextureFlagsMask) ==
227              ((int)surfaceFlags & kGrInternalTextureFlagsMask));
228 }
229 
230 #endif
231 
232