/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef skgpu_graphite_TextureProxy_DEFINED #define skgpu_graphite_TextureProxy_DEFINED #include "include/core/SkRefCnt.h" #include "include/core/SkSize.h" #include "include/gpu/graphite/TextureInfo.h" #include "include/private/base/SkTo.h" #include enum SkColorType : int; namespace skgpu::graphite { class Caps; class ResourceProvider; class Texture; class TextureProxy : public SkRefCnt { public: TextureProxy() = delete; ~TextureProxy() override; int numSamples() const { return fInfo.numSamples(); } Mipmapped mipmapped() const { return fInfo.mipmapped(); } SkISize dimensions() const; const TextureInfo& textureInfo() const { return fInfo; } bool isLazy() const; bool isFullyLazy() const; bool isVolatile() const; bool isProtected() const; size_t uninstantiatedGpuMemorySize() const; bool instantiate(ResourceProvider*); /* * We currently only instantiate lazy proxies at insertion-time. Snap-time 'instantiate' * calls should be wrapped in 'InstantiateIfNotLazy'. * * Unlike Ganesh, in Graphite we do not update the proxy's dimensions with the instantiating * texture's dimensions. This means that when a fully-lazy proxy is instantiated and * deinstantiated, it goes back to being fully-lazy and without dimensions, and can be * re-instantiated with a new texture with different dimensions than the first. */ bool lazyInstantiate(ResourceProvider*); /* * For Lazy proxies this will return true. Otherwise, it will return the result of * calling instantiate on the texture proxy. */ static bool InstantiateIfNotLazy(ResourceProvider*, TextureProxy*); bool isInstantiated() const { return SkToBool(fTexture); } void deinstantiate(); sk_sp refTexture() const; const Texture* texture() const; Texture* texture() { return fTexture.get(); } static sk_sp Make(const Caps*, SkISize dimensions, SkColorType, Mipmapped, Protected, Renderable, skgpu::Budgeted); static sk_sp Make(const Caps*, SkISize dimensions, const TextureInfo&, skgpu::Budgeted); using LazyInstantiateCallback = std::function (ResourceProvider*)>; static sk_sp MakeLazy(const Caps*, SkISize dimensions, const TextureInfo&, skgpu::Budgeted, Volatile, LazyInstantiateCallback&&); static sk_sp MakeFullyLazy(const TextureInfo&, skgpu::Budgeted, Volatile, LazyInstantiateCallback&&); static sk_sp MakeStorage(const Caps*, SkISize dimensions, SkColorType, skgpu::Budgeted); static sk_sp Wrap(sk_sp); private: TextureProxy(SkISize dimensions, const TextureInfo& info, skgpu::Budgeted budgeted); TextureProxy(SkISize dimensions, const TextureInfo&, skgpu::Budgeted, Volatile, LazyInstantiateCallback&&); TextureProxy(sk_sp); #ifdef SK_DEBUG void validateTexture(const Texture*); #endif // In the following, 'fVolatile' and 'fLazyInstantiateCallback' can be accessed from // multiple threads so need to remain immutable. SkISize fDimensions; const TextureInfo fInfo; skgpu::Budgeted fBudgeted; const Volatile fVolatile; sk_sp fTexture; const LazyInstantiateCallback fLazyInstantiateCallback; }; // Volatile texture proxy that deinstantiates itself on destruction. class AutoDeinstantiateTextureProxy { public: AutoDeinstantiateTextureProxy(TextureProxy* textureProxy) : fTextureProxy(textureProxy) {} ~AutoDeinstantiateTextureProxy() { if (fTextureProxy) { fTextureProxy->deinstantiate(); } } private: TextureProxy* const fTextureProxy; }; } // namespace skgpu::graphite #endif // skgpu_graphite_TextureProxy_DEFINED