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/GrContext.h"
12 #include "src/gpu/GrContextPriv.h"
13 #include "src/gpu/GrDeferredProxyUploader.h"
14 #include "src/gpu/GrProxyProvider.h"
15 #include "src/gpu/GrSurfacePriv.h"
16 #include "src/gpu/GrTexturePriv.h"
17 
18 // Deferred version - no data
GrTextureProxy(const GrBackendFormat & format,const GrSurfaceDesc & srcDesc,GrSurfaceOrigin origin,GrMipMapped mipMapped,GrMipMapsStatus mipMapsStatus,const GrSwizzle & textureSwizzle,SkBackingFit fit,SkBudgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator)19 GrTextureProxy::GrTextureProxy(const GrBackendFormat& format,
20                                const GrSurfaceDesc& srcDesc,
21                                GrSurfaceOrigin origin,
22                                GrMipMapped mipMapped,
23                                GrMipMapsStatus mipMapsStatus,
24                                const GrSwizzle& textureSwizzle,
25                                SkBackingFit fit,
26                                SkBudgeted budgeted,
27                                GrProtected isProtected,
28                                GrInternalSurfaceFlags surfaceFlags,
29                                UseAllocator useAllocator)
30         : INHERITED(format, srcDesc, GrRenderable::kNo, origin, textureSwizzle, fit, budgeted,
31                     isProtected, surfaceFlags, useAllocator)
32         , fMipMapped(mipMapped)
33         , fMipMapsStatus(mipMapsStatus) SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
34         , fProxyProvider(nullptr)
35         , fDeferredUploader(nullptr) {}
36 
37 // Lazy-callback version
GrTextureProxy(LazyInstantiateCallback && callback,const GrBackendFormat & format,const GrSurfaceDesc & desc,GrSurfaceOrigin origin,GrMipMapped mipMapped,GrMipMapsStatus mipMapsStatus,const GrSwizzle & texSwizzle,SkBackingFit fit,SkBudgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator)38 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback,
39                                const GrBackendFormat& format,
40                                const GrSurfaceDesc& desc,
41                                GrSurfaceOrigin origin,
42                                GrMipMapped mipMapped,
43                                GrMipMapsStatus mipMapsStatus,
44                                const GrSwizzle& texSwizzle,
45                                SkBackingFit fit,
46                                SkBudgeted budgeted,
47                                GrProtected isProtected,
48                                GrInternalSurfaceFlags surfaceFlags,
49                                UseAllocator useAllocator)
50         : INHERITED(std::move(callback), format, desc, GrRenderable::kNo, origin, texSwizzle, fit,
51                     budgeted, isProtected, surfaceFlags, useAllocator)
52         , fMipMapped(mipMapped)
53         , fMipMapsStatus(mipMapsStatus) SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
54         , fProxyProvider(nullptr)
55         , fDeferredUploader(nullptr) {}
56 
57 // Wrapped version
GrTextureProxy(sk_sp<GrSurface> surf,GrSurfaceOrigin origin,const GrSwizzle & textureSwizzle,UseAllocator useAllocator)58 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf,
59                                GrSurfaceOrigin origin,
60                                const GrSwizzle& textureSwizzle,
61                                UseAllocator useAllocator)
62         : INHERITED(std::move(surf), origin, textureSwizzle, SkBackingFit::kExact, useAllocator)
63         , fMipMapped(fTarget->asTexture()->texturePriv().mipMapped())
64         , fMipMapsStatus(fTarget->asTexture()->texturePriv().mipMapsStatus())
65                   SkDEBUGCODE(, fInitialMipMapsStatus(fMipMapsStatus))
66         , fProxyProvider(nullptr)
67         , fDeferredUploader(nullptr) {
68     if (fTarget->getUniqueKey().isValid()) {
69         fProxyProvider = fTarget->asTexture()->getContext()->priv().proxyProvider();
70         fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget.get());
71     }
72 }
73 
~GrTextureProxy()74 GrTextureProxy::~GrTextureProxy() {
75     // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away
76     // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it.
77     fTarget = nullptr;
78 
79     // In DDL-mode, uniquely keyed proxies keep their key even after their originating
80     // proxy provider has gone away. In that case there is noone to send the invalid key
81     // message to (Note: in this case we don't want to remove its cached resource).
82     if (fUniqueKey.isValid() && fProxyProvider) {
83         fProxyProvider->processInvalidUniqueKey(fUniqueKey, this,
84                                                 GrProxyProvider::InvalidateGPUResource::kNo);
85     } else {
86         SkASSERT(!fProxyProvider);
87     }
88 }
89 
instantiate(GrResourceProvider * resourceProvider)90 bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) {
91     if (this->isLazy()) {
92         return false;
93     }
94     if (!this->instantiateImpl(resourceProvider, 1, /* needsStencil = */ false, GrRenderable::kNo,
95                                fMipMapped, fUniqueKey.isValid() ? &fUniqueKey : nullptr)) {
96         return false;
97     }
98 
99     SkASSERT(!this->peekRenderTarget());
100     SkASSERT(this->peekTexture());
101     return true;
102 }
103 
createSurface(GrResourceProvider * resourceProvider) const104 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const {
105     sk_sp<GrSurface> surface =
106             this->createSurfaceImpl(resourceProvider, 1,
107                                     /* needsStencil = */ false, GrRenderable::kNo, fMipMapped);
108     if (!surface) {
109         return nullptr;
110     }
111 
112     SkASSERT(!surface->asRenderTarget());
113     SkASSERT(surface->asTexture());
114     return surface;
115 }
116 
setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader)117 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) {
118     SkASSERT(!fTextureProxy->fDeferredUploader);
119     fTextureProxy->fDeferredUploader = std::move(uploader);
120 }
121 
scheduleUpload(GrOpFlushState * flushState)122 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) {
123     // The texture proxy's contents may already have been uploaded or instantiation may have failed
124     if (fTextureProxy->fDeferredUploader && fTextureProxy->isInstantiated()) {
125         fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy);
126     }
127 }
128 
resetDeferredUploader()129 void GrTextureProxyPriv::resetDeferredUploader() {
130     SkASSERT(fTextureProxy->fDeferredUploader);
131     fTextureProxy->fDeferredUploader.reset();
132 }
133 
highestFilterMode() const134 GrSamplerState::Filter GrTextureProxy::highestFilterMode() const {
135     return this->hasRestrictedSampling() ? GrSamplerState::Filter::kBilerp
136                                          : GrSamplerState::Filter::kMipMap;
137 }
138 
mipMapped() const139 GrMipMapped GrTextureProxy::mipMapped() const {
140     if (this->isInstantiated()) {
141         return this->peekTexture()->texturePriv().mipMapped();
142     }
143     return fMipMapped;
144 }
145 
onUninstantiatedGpuMemorySize(const GrCaps & caps) const146 size_t GrTextureProxy::onUninstantiatedGpuMemorySize(const GrCaps& caps) const {
147     return GrSurface::ComputeSize(caps, this->backendFormat(),  this->width(), this->height(),
148                                   1, this->proxyMipMapped(), !this->priv().isExact());
149 }
150 
ProxiesAreCompatibleAsDynamicState(const GrTextureProxy * first,const GrTextureProxy * second)151 bool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrTextureProxy* first,
152                                                         const GrTextureProxy* second) {
153     return first->config() == second->config() &&
154            first->textureType() == second->textureType() &&
155            first->backendFormat() == second->backendFormat();
156 }
157 
setUniqueKey(GrProxyProvider * proxyProvider,const GrUniqueKey & key)158 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
159     SkASSERT(key.isValid());
160     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
161 
162     if (fTarget && fSyncTargetKey) {
163         if (!fTarget->getUniqueKey().isValid()) {
164             fTarget->resourcePriv().setUniqueKey(key);
165         }
166         SkASSERT(fTarget->getUniqueKey() == key);
167     }
168 
169     fUniqueKey = key;
170     fProxyProvider = proxyProvider;
171 }
172 
clearUniqueKey()173 void GrTextureProxy::clearUniqueKey() {
174     fUniqueKey.reset();
175     fProxyProvider = nullptr;
176 }
177 
178 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)179 void GrTextureProxy::onValidateSurface(const GrSurface* surface) {
180     SkASSERT(!surface->asRenderTarget());
181 
182     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
183     SkASSERT(surface->asTexture());
184     // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture.
185     SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
186              GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
187 
188     SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
189 
190     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
191     GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
192     SkASSERT(((int)proxyFlags & kGrInternalTextureFlagsMask) ==
193              ((int)surfaceFlags & kGrInternalTextureFlagsMask));
194 }
195 
196 #endif
197 
198