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