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