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