1 /* 2 * Copyright 2021 Google LLC 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 #ifndef skgpu_graphite_TextureInfo_DEFINED 9 #define skgpu_graphite_TextureInfo_DEFINED 10 11 #include "include/core/SkString.h" 12 #include "include/core/SkTextureCompressionType.h" 13 #include "include/gpu/graphite/GraphiteTypes.h" 14 #include "include/private/base/SkAPI.h" 15 #include "include/private/base/SkAnySubclass.h" 16 17 struct SkISize; 18 19 namespace skgpu::graphite { 20 21 enum class TextureFormat : uint8_t; 22 23 /** 24 * TextureInfo is a backend-agnostic wrapper around the properties of a texture, sans dimensions. 25 * It is designed this way to be compilable w/o bringing in a specific backend's build files, and 26 * without requiring heap allocations of virtual types. 27 */ 28 class SK_API TextureInfo { 29 private: 30 class Data; 31 friend class MtlTextureInfo; 32 friend class DawnTextureInfo; 33 friend class VulkanTextureInfo; 34 35 // Size is the largest of the Data subclasses assuming a 64-bit compiler. 36 inline constexpr static size_t kMaxSubclassSize = 112; 37 using AnyTextureInfoData = SkAnySubclass<Data, kMaxSubclassSize>; 38 39 // Base properties for all backend-specific properties. Clients managing textures directly 40 // should use the public subclasses of Data directly, e.g. MtlTextureInfo/DawnTextureInfo. 41 // 42 // Each backend subclass must expose to TextureInfo[Priv]: 43 // static constexpr BackendApi kBackend; 44 // Protected isProtected() const; 45 // TextureFormat viewFormat() const; 46 // bool serialize(SkWStream*) const; 47 // bool deserialize(SkStream*); 48 class Data { 49 public: 50 virtual ~Data() = default; 51 Data(uint32_t sampleCount,skgpu::Mipmapped mipmapped)52 Data(uint32_t sampleCount, skgpu::Mipmapped mipmapped) 53 : fSampleCount(sampleCount) 54 , fMipmapped(mipmapped) {} 55 56 Data() = default; 57 Data(const Data&) = default; 58 59 Data& operator=(const Data&) = default; 60 61 // NOTE: These fields are accessible via the backend-specific subclasses. 62 uint32_t fSampleCount = 1; 63 Mipmapped fMipmapped = Mipmapped::kNo; 64 65 private: 66 friend class TextureInfo; 67 friend class TextureInfoPriv; 68 69 virtual SkString toBackendString() const = 0; 70 71 virtual void copyTo(AnyTextureInfoData&) const = 0; 72 // Passed in TextureInfo will have data of the same backend type and subclass, and 73 // base properties of Data have already been checked for equality/compatibility. 74 virtual bool isCompatible(const TextureInfo& that, bool requireExact) const = 0; 75 }; 76 77 public: 78 TextureInfo() = default; 79 ~TextureInfo() = default; 80 81 TextureInfo(const TextureInfo&); 82 TextureInfo& operator=(const TextureInfo&); 83 84 bool operator==(const TextureInfo& that) const { 85 return this->isCompatible(that, /*requireExact=*/true); 86 } 87 bool operator!=(const TextureInfo& that) const { return !(*this == that); } 88 isValid()89 bool isValid() const { return fData.has_value(); } backend()90 BackendApi backend() const { 91 SkASSERT(fData.has_value() || fBackend == BackendApi::kUnsupported); 92 return fBackend; 93 } 94 numSamples()95 uint32_t numSamples() const { return fData.has_value() ? fData->fSampleCount : 1; } mipmapped()96 Mipmapped mipmapped() const { return fData.has_value() ? fData->fMipmapped : Mipmapped::kNo; } isProtected()97 Protected isProtected() const { return fProtected; } 98 99 // Return true if `that` describes a texture that is compatible with this info and can validly 100 // be used to fulfill a promise image that was created with this TextureInfo. canBeFulfilledBy(const TextureInfo & that)101 bool canBeFulfilledBy(const TextureInfo& that) const { 102 return this->isCompatible(that, /*requireExact=*/false); 103 } 104 105 // Return a string containing the full description of this TextureInfo. 106 SkString toString() const; 107 108 private: 109 friend class TextureInfoPriv; 110 111 template <typename BackendTextureData, 112 std::enable_if_t<std::is_base_of_v<Data, BackendTextureData>, bool> = true> TextureInfo(const BackendTextureData & data)113 explicit TextureInfo(const BackendTextureData& data) 114 : fBackend(BackendTextureData::kBackend) 115 , fViewFormat(data.viewFormat()) 116 , fProtected(data.isProtected()) { 117 fData.emplace<BackendTextureData>(data); 118 } 119 120 bool isCompatible(const TextureInfo& that, bool requireExact) const; 121 122 skgpu::BackendApi fBackend = BackendApi::kUnsupported; 123 AnyTextureInfoData fData; 124 125 // Derived properties from the backend data, cached to avoid a virtual function call 126 TextureFormat fViewFormat; 127 Protected fProtected = Protected::kNo; 128 }; 129 130 } // namespace skgpu::graphite 131 132 #endif // skgpu_graphite_TextureInfo_DEFINED 133