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 "GrTexturePriv.h" 16 17 // Deferred version 18 GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, GrMipMapped mipMapped, 19 SkBackingFit fit, SkBudgeted budgeted, const void* srcData, 20 size_t /*rowBytes*/, uint32_t flags) 21 : INHERITED(srcDesc, fit, budgeted, flags) 22 , fMipMapped(mipMapped) 23 , fProxyProvider(nullptr) 24 , fDeferredUploader(nullptr) { 25 SkASSERT(!srcData); // currently handled in Make() 26 } 27 28 // Lazy-callback version 29 GrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType, 30 const GrSurfaceDesc& desc, GrMipMapped mipMapped, SkBackingFit fit, 31 SkBudgeted budgeted, uint32_t flags) 32 : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags) 33 , fMipMapped(mipMapped) 34 , fProxyProvider(nullptr) 35 , fDeferredUploader(nullptr) { 36 } 37 38 // Wrapped version 39 GrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin) 40 : INHERITED(std::move(surf), origin, SkBackingFit::kExact) 41 , fMipMapped(fTarget->asTexture()->texturePriv().mipMapped()) 42 , fProxyProvider(nullptr) 43 , fDeferredUploader(nullptr) { 44 if (fTarget->getUniqueKey().isValid()) { 45 fProxyProvider = fTarget->asTexture()->getContext()->contextPriv().proxyProvider(); 46 fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget); 47 } 48 } 49 50 GrTextureProxy::~GrTextureProxy() { 51 // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away 52 // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it. 53 fTarget = nullptr; 54 if (fUniqueKey.isValid()) { 55 fProxyProvider->processInvalidProxyUniqueKey(fUniqueKey, this, false); 56 } else { 57 SkASSERT(!fProxyProvider); 58 } 59 } 60 61 bool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) { 62 if (LazyState::kNot != this->lazyInstantiationState()) { 63 return false; 64 } 65 if (!this->instantiateImpl(resourceProvider, 1, /* needsStencil = */ false, 66 kNone_GrSurfaceFlags, fMipMapped, 67 fUniqueKey.isValid() ? &fUniqueKey : nullptr)) { 68 return false; 69 } 70 71 SkASSERT(!fTarget->asRenderTarget()); 72 SkASSERT(fTarget->asTexture()); 73 return true; 74 } 75 76 sk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const { 77 sk_sp<GrSurface> surface= this->createSurfaceImpl(resourceProvider, 1, 78 /* needsStencil = */ false, 79 kNone_GrSurfaceFlags, 80 fMipMapped); 81 if (!surface) { 82 return nullptr; 83 } 84 85 SkASSERT(!surface->asRenderTarget()); 86 SkASSERT(surface->asTexture()); 87 return surface; 88 } 89 90 void GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) { 91 SkASSERT(!fTextureProxy->fDeferredUploader); 92 fTextureProxy->fDeferredUploader = std::move(uploader); 93 } 94 95 void GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) { 96 // The texture proxy's contents may already have been uploaded or instantiation may have failed 97 if (fTextureProxy->fDeferredUploader && fTextureProxy->fTarget) { 98 fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy); 99 } 100 } 101 102 void GrTextureProxyPriv::resetDeferredUploader() { 103 SkASSERT(fTextureProxy->fDeferredUploader); 104 fTextureProxy->fDeferredUploader.reset(); 105 } 106 107 // This method parallels the highest_filter_mode functions in GrGLTexture & GrVkTexture. 108 GrSamplerState::Filter GrTextureProxy::highestFilterMode() const { 109 if (fTarget) { 110 return fTarget->asTexture()->texturePriv().highestFilterMode(); 111 } 112 113 // In OpenGL, GR_GL_TEXTURE_RECTANGLE and GR_GL_TEXTURE_EXTERNAL (which have a highest filter 114 // mode of bilerp) can only be created via wrapping. 115 116 return GrSamplerState::Filter::kMipMap; 117 } 118 119 GrMipMapped GrTextureProxy::mipMapped() const { 120 if (this->priv().isInstantiated()) { 121 return this->priv().peekTexture()->texturePriv().mipMapped(); 122 } 123 return fMipMapped; 124 } 125 126 size_t GrTextureProxy::onUninstantiatedGpuMemorySize() const { 127 return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 1, 128 this->texPriv().proxyMipMapped(), !this->priv().isExact()); 129 } 130 131 void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) { 132 SkASSERT(key.isValid()); 133 SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey 134 135 if (fTarget) { 136 if (!fTarget->getUniqueKey().isValid()) { 137 fTarget->resourcePriv().setUniqueKey(key); 138 } 139 SkASSERT(fTarget->getUniqueKey() == key); 140 } 141 142 fUniqueKey = key; 143 fProxyProvider = proxyProvider; 144 } 145 146 void GrTextureProxy::clearUniqueKey() { 147 fUniqueKey.reset(); 148 fProxyProvider = nullptr; 149 } 150 151 #ifdef SK_DEBUG 152 void GrTextureProxy::validateLazySurface(const GrSurface* surface) { 153 SkASSERT(!surface->asRenderTarget()); 154 155 // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version 156 SkASSERT(surface->asTexture()); 157 SkASSERT(GrMipMapped::kNo == this->texPriv().proxyMipMapped() || 158 GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped()); 159 } 160 #endif 161 162