1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h" 9cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxyPriv.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrDeferredProxyUploader.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourcePriv.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 16cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 17cb93a386Sopenharmony_ci#include "src/gpu/GrSurface.h" 18cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci// Deferred version - no data 21cb93a386Sopenharmony_ciGrTextureProxy::GrTextureProxy(const GrBackendFormat& format, 22cb93a386Sopenharmony_ci SkISize dimensions, 23cb93a386Sopenharmony_ci GrMipmapped mipMapped, 24cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus, 25cb93a386Sopenharmony_ci SkBackingFit fit, 26cb93a386Sopenharmony_ci SkBudgeted budgeted, 27cb93a386Sopenharmony_ci GrProtected isProtected, 28cb93a386Sopenharmony_ci GrInternalSurfaceFlags surfaceFlags, 29cb93a386Sopenharmony_ci UseAllocator useAllocator, 30cb93a386Sopenharmony_ci GrDDLProvider creatingProvider) 31cb93a386Sopenharmony_ci : INHERITED(format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator) 32cb93a386Sopenharmony_ci , fMipmapped(mipMapped) 33cb93a386Sopenharmony_ci , fMipmapStatus(mipmapStatus) 34cb93a386Sopenharmony_ci SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus)) 35cb93a386Sopenharmony_ci , fCreatingProvider(creatingProvider) 36cb93a386Sopenharmony_ci , fProxyProvider(nullptr) 37cb93a386Sopenharmony_ci , fDeferredUploader(nullptr) { 38cb93a386Sopenharmony_ci SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly)); 39cb93a386Sopenharmony_ci if (this->textureType() == GrTextureType::kExternal) { 40cb93a386Sopenharmony_ci fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly; 41cb93a386Sopenharmony_ci } 42cb93a386Sopenharmony_ci} 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci// Lazy-callback version 45cb93a386Sopenharmony_ciGrTextureProxy::GrTextureProxy(LazyInstantiateCallback&& callback, 46cb93a386Sopenharmony_ci const GrBackendFormat& format, 47cb93a386Sopenharmony_ci SkISize dimensions, 48cb93a386Sopenharmony_ci GrMipmapped mipMapped, 49cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus, 50cb93a386Sopenharmony_ci SkBackingFit fit, 51cb93a386Sopenharmony_ci SkBudgeted budgeted, 52cb93a386Sopenharmony_ci GrProtected isProtected, 53cb93a386Sopenharmony_ci GrInternalSurfaceFlags surfaceFlags, 54cb93a386Sopenharmony_ci UseAllocator useAllocator, 55cb93a386Sopenharmony_ci GrDDLProvider creatingProvider) 56cb93a386Sopenharmony_ci : INHERITED(std::move(callback), format, dimensions, fit, budgeted, isProtected, 57cb93a386Sopenharmony_ci surfaceFlags, useAllocator) 58cb93a386Sopenharmony_ci , fMipmapped(mipMapped) 59cb93a386Sopenharmony_ci , fMipmapStatus(mipmapStatus) 60cb93a386Sopenharmony_ci SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus)) 61cb93a386Sopenharmony_ci , fCreatingProvider(creatingProvider) 62cb93a386Sopenharmony_ci , fProxyProvider(nullptr) 63cb93a386Sopenharmony_ci , fDeferredUploader(nullptr) { 64cb93a386Sopenharmony_ci SkASSERT(!(fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly)); 65cb93a386Sopenharmony_ci if (this->textureType() == GrTextureType::kExternal) { 66cb93a386Sopenharmony_ci fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly; 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci// Wrapped version 71cb93a386Sopenharmony_ciGrTextureProxy::GrTextureProxy(sk_sp<GrSurface> surf, 72cb93a386Sopenharmony_ci UseAllocator useAllocator, 73cb93a386Sopenharmony_ci GrDDLProvider creatingProvider) 74cb93a386Sopenharmony_ci : INHERITED(std::move(surf), SkBackingFit::kExact, useAllocator) 75cb93a386Sopenharmony_ci , fMipmapped(fTarget->asTexture()->mipmapped()) 76cb93a386Sopenharmony_ci , fMipmapStatus(fTarget->asTexture()->mipmapStatus()) 77cb93a386Sopenharmony_ci SkDEBUGCODE(, fInitialMipmapStatus(fMipmapStatus)) 78cb93a386Sopenharmony_ci , fCreatingProvider(creatingProvider) 79cb93a386Sopenharmony_ci , fProxyProvider(nullptr) 80cb93a386Sopenharmony_ci , fDeferredUploader(nullptr) { 81cb93a386Sopenharmony_ci if (fTarget->getUniqueKey().isValid()) { 82cb93a386Sopenharmony_ci fProxyProvider = fTarget->asTexture()->getContext()->priv().proxyProvider(); 83cb93a386Sopenharmony_ci fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget.get()); 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci if (this->textureType() == GrTextureType::kExternal) { 86cb93a386Sopenharmony_ci fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly; 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci} 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ciGrTextureProxy::~GrTextureProxy() { 91cb93a386Sopenharmony_ci // Due to the order of cleanup the GrSurface this proxy may have wrapped may have gone away 92cb93a386Sopenharmony_ci // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it. 93cb93a386Sopenharmony_ci fTarget = nullptr; 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci // In DDL-mode, uniquely keyed proxies keep their key even after their originating 96cb93a386Sopenharmony_ci // proxy provider has gone away. In that case there is noone to send the invalid key 97cb93a386Sopenharmony_ci // message to (Note: in this case we don't want to remove its cached resource). 98cb93a386Sopenharmony_ci if (fUniqueKey.isValid() && fProxyProvider) { 99cb93a386Sopenharmony_ci sk_sp<GrGpuResource> invalidGpuResource; 100cb93a386Sopenharmony_ci auto direct = fProxyProvider->getfImageContext()->asDirectContext(); 101cb93a386Sopenharmony_ci if (direct) { 102cb93a386Sopenharmony_ci GrResourceProvider* resourceProvider = direct->priv().resourceProvider(); 103cb93a386Sopenharmony_ci if (resourceProvider) { 104cb93a386Sopenharmony_ci invalidGpuResource = resourceProvider->findByUniqueKey<GrGpuResource>(fUniqueKey); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci } 107cb93a386Sopenharmony_ci // less than 1024 Bytes resources will be delated 108cb93a386Sopenharmony_ci if (invalidGpuResource && invalidGpuResource->gpuMemorySize() < 1024) { 109cb93a386Sopenharmony_ci fProxyProvider->processInvalidUniqueKey( 110cb93a386Sopenharmony_ci fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kYes); 111cb93a386Sopenharmony_ci } else { 112cb93a386Sopenharmony_ci fProxyProvider->processInvalidUniqueKey( 113cb93a386Sopenharmony_ci fUniqueKey, this, GrProxyProvider::InvalidateGPUResource::kNo); 114cb93a386Sopenharmony_ci } 115cb93a386Sopenharmony_ci } else { 116cb93a386Sopenharmony_ci SkASSERT(!fProxyProvider); 117cb93a386Sopenharmony_ci } 118cb93a386Sopenharmony_ci} 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_cibool GrTextureProxy::instantiate(GrResourceProvider* resourceProvider) { 121cb93a386Sopenharmony_ci if (this->isLazy()) { 122cb93a386Sopenharmony_ci return false; 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci if (!this->instantiateImpl(resourceProvider, 1, GrRenderable::kNo, fMipmapped, 125cb93a386Sopenharmony_ci fUniqueKey.isValid() ? &fUniqueKey : nullptr)) { 126cb93a386Sopenharmony_ci return false; 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci SkASSERT(!this->peekRenderTarget()); 130cb93a386Sopenharmony_ci SkASSERT(this->peekTexture()); 131cb93a386Sopenharmony_ci return true; 132cb93a386Sopenharmony_ci} 133cb93a386Sopenharmony_ci 134cb93a386Sopenharmony_cisk_sp<GrSurface> GrTextureProxy::createSurface(GrResourceProvider* resourceProvider) const { 135cb93a386Sopenharmony_ci sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, 1, GrRenderable::kNo, 136cb93a386Sopenharmony_ci fMipmapped); 137cb93a386Sopenharmony_ci if (!surface) { 138cb93a386Sopenharmony_ci return nullptr; 139cb93a386Sopenharmony_ci } 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci if (fUserCacheTaget) { 142cb93a386Sopenharmony_ci if (!(surface->getUniqueKey().isValid()) && !(surface->resourcePriv().getScratchKey().isValid())) { 143cb93a386Sopenharmony_ci surface->resourcePriv().userRegisterResource(); 144cb93a386Sopenharmony_ci } 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci SkASSERT(!surface->asRenderTarget()); 148cb93a386Sopenharmony_ci SkASSERT(surface->asTexture()); 149cb93a386Sopenharmony_ci return surface; 150cb93a386Sopenharmony_ci} 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_civoid GrTextureProxyPriv::setDeferredUploader(std::unique_ptr<GrDeferredProxyUploader> uploader) { 153cb93a386Sopenharmony_ci SkASSERT(!fTextureProxy->fDeferredUploader); 154cb93a386Sopenharmony_ci fTextureProxy->fDeferredUploader = std::move(uploader); 155cb93a386Sopenharmony_ci} 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_civoid GrTextureProxyPriv::scheduleUpload(GrOpFlushState* flushState) { 158cb93a386Sopenharmony_ci // The texture proxy's contents may already have been uploaded or instantiation may have failed 159cb93a386Sopenharmony_ci if (fTextureProxy->fDeferredUploader && fTextureProxy->isInstantiated()) { 160cb93a386Sopenharmony_ci fTextureProxy->fDeferredUploader->scheduleUpload(flushState, fTextureProxy); 161cb93a386Sopenharmony_ci } 162cb93a386Sopenharmony_ci} 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_civoid GrTextureProxyPriv::resetDeferredUploader() { 165cb93a386Sopenharmony_ci SkASSERT(fTextureProxy->fDeferredUploader); 166cb93a386Sopenharmony_ci fTextureProxy->fDeferredUploader.reset(); 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ciGrMipmapped GrTextureProxy::mipmapped() const { 170cb93a386Sopenharmony_ci if (this->isInstantiated()) { 171cb93a386Sopenharmony_ci return this->peekTexture()->mipmapped(); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci return fMipmapped; 174cb93a386Sopenharmony_ci} 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_cisize_t GrTextureProxy::onUninstantiatedGpuMemorySize() const { 177cb93a386Sopenharmony_ci return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 178cb93a386Sopenharmony_ci /*colorSamplesPerPixel=*/1, this->proxyMipmapped(), 179cb93a386Sopenharmony_ci !this->priv().isExact()); 180cb93a386Sopenharmony_ci} 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_cibool GrTextureProxy::ProxiesAreCompatibleAsDynamicState(const GrSurfaceProxy* first, 183cb93a386Sopenharmony_ci const GrSurfaceProxy* second) { 184cb93a386Sopenharmony_ci // In order to be compatible, the proxies should also have the same texture type. This is 185cb93a386Sopenharmony_ci // checked explicitly since the GrBackendFormat == operator does not compare texture type 186cb93a386Sopenharmony_ci return first->backendFormat().textureType() == second->backendFormat().textureType() && 187cb93a386Sopenharmony_ci first->backendFormat() == second->backendFormat(); 188cb93a386Sopenharmony_ci} 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_civoid GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) { 191cb93a386Sopenharmony_ci SkASSERT(key.isValid()); 192cb93a386Sopenharmony_ci SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_ci if (fTarget && fSyncTargetKey) { 195cb93a386Sopenharmony_ci if (!fTarget->getUniqueKey().isValid()) { 196cb93a386Sopenharmony_ci fTarget->resourcePriv().setUniqueKey(key); 197cb93a386Sopenharmony_ci } 198cb93a386Sopenharmony_ci SkASSERT(fTarget->getUniqueKey() == key); 199cb93a386Sopenharmony_ci } 200cb93a386Sopenharmony_ci 201cb93a386Sopenharmony_ci fUniqueKey = key; 202cb93a386Sopenharmony_ci fProxyProvider = proxyProvider; 203cb93a386Sopenharmony_ci} 204cb93a386Sopenharmony_ci 205cb93a386Sopenharmony_civoid GrTextureProxy::clearUniqueKey() { 206cb93a386Sopenharmony_ci fUniqueKey.reset(); 207cb93a386Sopenharmony_ci fProxyProvider = nullptr; 208cb93a386Sopenharmony_ci} 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ciGrSurfaceProxy::LazySurfaceDesc GrTextureProxy::callbackDesc() const { 211cb93a386Sopenharmony_ci SkISize dims; 212cb93a386Sopenharmony_ci SkBackingFit fit; 213cb93a386Sopenharmony_ci if (this->isFullyLazy()) { 214cb93a386Sopenharmony_ci fit = SkBackingFit::kApprox; 215cb93a386Sopenharmony_ci dims = {-1, -1}; 216cb93a386Sopenharmony_ci } else { 217cb93a386Sopenharmony_ci fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox; 218cb93a386Sopenharmony_ci dims = this->dimensions(); 219cb93a386Sopenharmony_ci } 220cb93a386Sopenharmony_ci return { 221cb93a386Sopenharmony_ci dims, 222cb93a386Sopenharmony_ci fit, 223cb93a386Sopenharmony_ci GrRenderable::kNo, 224cb93a386Sopenharmony_ci fMipmapped, 225cb93a386Sopenharmony_ci 1, 226cb93a386Sopenharmony_ci this->backendFormat(), 227cb93a386Sopenharmony_ci this->textureType(), 228cb93a386Sopenharmony_ci this->isProtected(), 229cb93a386Sopenharmony_ci this->isBudgeted(), 230cb93a386Sopenharmony_ci }; 231cb93a386Sopenharmony_ci} 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_ci#ifdef SK_DEBUG 234cb93a386Sopenharmony_civoid GrTextureProxy::onValidateSurface(const GrSurface* surface) { 235cb93a386Sopenharmony_ci SkASSERT(!surface->asRenderTarget()); 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_ci // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version 238cb93a386Sopenharmony_ci SkASSERT(surface->asTexture()); 239cb93a386Sopenharmony_ci // It is possible to fulfill a non-mipmapped proxy with a mipmapped texture. 240cb93a386Sopenharmony_ci SkASSERT(GrMipmapped::kNo == this->proxyMipmapped() || 241cb93a386Sopenharmony_ci GrMipmapped::kYes == surface->asTexture()->mipmapped()); 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_ci SkASSERT(surface->asTexture()->textureType() == this->textureType()); 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_ci GrInternalSurfaceFlags proxyFlags = fSurfaceFlags; 246cb93a386Sopenharmony_ci GrInternalSurfaceFlags surfaceFlags = surface->flags(); 247cb93a386Sopenharmony_ci SkASSERT(((int)proxyFlags & kGrInternalTextureFlagsMask) == 248cb93a386Sopenharmony_ci ((int)surfaceFlags & kGrInternalTextureFlagsMask)); 249cb93a386Sopenharmony_ci} 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_ci#endif 252cb93a386Sopenharmony_ci 253