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