1 /* 2 * Copyright 2017 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 #ifndef SkSurfaceCharacterization_DEFINED 9 #define SkSurfaceCharacterization_DEFINED 10 11 12 #include "include/core/SkColorSpace.h" 13 #include "include/core/SkImageInfo.h" 14 #include "include/core/SkRefCnt.h" 15 #include "include/core/SkSurfaceProps.h" 16 17 class SkColorSpace; 18 19 20 #if SK_SUPPORT_GPU 21 #include "include/gpu/GrBackendSurface.h" 22 #include "include/gpu/GrContextThreadSafeProxy.h" 23 #include "include/gpu/GrTypes.h" 24 25 /** \class SkSurfaceCharacterization 26 A surface characterization contains all the information Ganesh requires to makes its internal 27 rendering decisions. When passed into a SkDeferredDisplayListRecorder it will copy the 28 data and pass it on to the SkDeferredDisplayList if/when it is created. Note that both of 29 those objects (the Recorder and the DisplayList) will take a ref on the 30 GrContextThreadSafeProxy and SkColorSpace objects. 31 */ 32 class SK_API SkSurfaceCharacterization { 33 public: 34 enum class Textureable : bool { kNo = false, kYes = true }; 35 enum class MipMapped : bool { kNo = false, kYes = true }; 36 enum class UsesGLFBO0 : bool { kNo = false, kYes = true }; 37 // This flag indicates that the backing VkImage for this Vulkan surface will have the 38 // VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set. This bit allows skia to handle advanced blends 39 // more optimally in a shader by being able to directly read the dst values. 40 enum class VkRTSupportsInputAttachment : bool { kNo = false, kYes = true }; 41 // This flag indicates if the surface is wrapping a raw Vulkan secondary command buffer. 42 enum class VulkanSecondaryCBCompatible : bool { kNo = false, kYes = true }; 43 SkSurfaceCharacterization()44 SkSurfaceCharacterization() 45 : fCacheMaxResourceBytes(0) 46 , fOrigin(kBottomLeft_GrSurfaceOrigin) 47 , fSampleCnt(0) 48 , fIsTextureable(Textureable::kYes) 49 , fIsMipMapped(MipMapped::kYes) 50 , fUsesGLFBO0(UsesGLFBO0::kNo) 51 , fVulkanSecondaryCBCompatible(VulkanSecondaryCBCompatible::kNo) 52 , fIsProtected(GrProtected::kNo) 53 , fSurfaceProps(0, kUnknown_SkPixelGeometry) { 54 } 55 56 SkSurfaceCharacterization(SkSurfaceCharacterization&&) = default; 57 SkSurfaceCharacterization& operator=(SkSurfaceCharacterization&&) = default; 58 59 SkSurfaceCharacterization(const SkSurfaceCharacterization&) = default; 60 SkSurfaceCharacterization& operator=(const SkSurfaceCharacterization& other) = default; 61 bool operator==(const SkSurfaceCharacterization& other) const; 62 bool operator!=(const SkSurfaceCharacterization& other) const { 63 return !(*this == other); 64 } 65 66 /* 67 * Return a new surface characterization with the only difference being a different width 68 * and height 69 */ 70 SkSurfaceCharacterization createResized(int width, int height) const; 71 72 /* 73 * Return a new surface characterization with only a replaced color space 74 */ 75 SkSurfaceCharacterization createColorSpace(sk_sp<SkColorSpace>) const; 76 77 /* 78 * Return a new surface characterization with the backend format replaced. A colorType 79 * must also be supplied to indicate the interpretation of the new format. 80 */ 81 SkSurfaceCharacterization createBackendFormat(SkColorType colorType, 82 const GrBackendFormat& backendFormat) const; 83 84 /* 85 * Return a new surface characterization with just a different use of FBO0 (in GL) 86 */ 87 SkSurfaceCharacterization createFBO0(bool usesGLFBO0) const; 88 contextInfo()89 GrContextThreadSafeProxy* contextInfo() const { return fContextInfo.get(); } refContextInfo()90 sk_sp<GrContextThreadSafeProxy> refContextInfo() const { return fContextInfo; } cacheMaxResourceBytes()91 size_t cacheMaxResourceBytes() const { return fCacheMaxResourceBytes; } 92 isValid()93 bool isValid() const { return kUnknown_SkColorType != fImageInfo.colorType(); } 94 imageInfo()95 const SkImageInfo& imageInfo() const { return fImageInfo; } backendFormat()96 const GrBackendFormat& backendFormat() const { return fBackendFormat; } origin()97 GrSurfaceOrigin origin() const { return fOrigin; } dimensions()98 SkISize dimensions() const { return fImageInfo.dimensions(); } width()99 int width() const { return fImageInfo.width(); } height()100 int height() const { return fImageInfo.height(); } colorType()101 SkColorType colorType() const { return fImageInfo.colorType(); } sampleCount()102 int sampleCount() const { return fSampleCnt; } isTextureable()103 bool isTextureable() const { return Textureable::kYes == fIsTextureable; } isMipMapped()104 bool isMipMapped() const { return MipMapped::kYes == fIsMipMapped; } usesGLFBO0()105 bool usesGLFBO0() const { return UsesGLFBO0::kYes == fUsesGLFBO0; } vkRTSupportsInputAttachment()106 bool vkRTSupportsInputAttachment() const { 107 return VkRTSupportsInputAttachment::kYes == fVkRTSupportsInputAttachment; 108 } vulkanSecondaryCBCompatible()109 bool vulkanSecondaryCBCompatible() const { 110 return VulkanSecondaryCBCompatible::kYes == fVulkanSecondaryCBCompatible; 111 } isProtected()112 GrProtected isProtected() const { return fIsProtected; } colorSpace()113 SkColorSpace* colorSpace() const { return fImageInfo.colorSpace(); } refColorSpace()114 sk_sp<SkColorSpace> refColorSpace() const { return fImageInfo.refColorSpace(); } surfaceProps()115 const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; } 116 117 // Is the provided backend texture compatible with this surface characterization? 118 bool isCompatible(const GrBackendTexture&) const; 119 120 private: 121 friend class SkSurface_Gpu; // for 'set' & 'config' 122 friend class GrVkSecondaryCBDrawContext; // for 'set' & 'config' 123 friend class GrContextThreadSafeProxy; // for private ctor 124 friend class SkDeferredDisplayListRecorder; // for 'config' 125 friend class SkSurface; // for 'config' 126 127 SkDEBUGCODE(void validate() const;) 128 SkSurfaceCharacterization(sk_sp<GrContextThreadSafeProxy> contextInfo,size_t cacheMaxResourceBytes,const SkImageInfo & ii,const GrBackendFormat & backendFormat,GrSurfaceOrigin origin,int sampleCnt,Textureable isTextureable,MipMapped isMipMapped,UsesGLFBO0 usesGLFBO0,VkRTSupportsInputAttachment vkRTSupportsInputAttachment,VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible,GrProtected isProtected,const SkSurfaceProps & surfaceProps)129 SkSurfaceCharacterization(sk_sp<GrContextThreadSafeProxy> contextInfo, 130 size_t cacheMaxResourceBytes, 131 const SkImageInfo& ii, 132 const GrBackendFormat& backendFormat, 133 GrSurfaceOrigin origin, 134 int sampleCnt, 135 Textureable isTextureable, 136 MipMapped isMipMapped, 137 UsesGLFBO0 usesGLFBO0, 138 VkRTSupportsInputAttachment vkRTSupportsInputAttachment, 139 VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible, 140 GrProtected isProtected, 141 const SkSurfaceProps& surfaceProps) 142 : fContextInfo(std::move(contextInfo)) 143 , fCacheMaxResourceBytes(cacheMaxResourceBytes) 144 , fImageInfo(ii) 145 , fBackendFormat(backendFormat) 146 , fOrigin(origin) 147 , fSampleCnt(sampleCnt) 148 , fIsTextureable(isTextureable) 149 , fIsMipMapped(isMipMapped) 150 , fUsesGLFBO0(usesGLFBO0) 151 , fVkRTSupportsInputAttachment(vkRTSupportsInputAttachment) 152 , fVulkanSecondaryCBCompatible(vulkanSecondaryCBCompatible) 153 , fIsProtected(isProtected) 154 , fSurfaceProps(surfaceProps) { 155 if (fSurfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag) { 156 // Dynamic MSAA is not currently supported with DDL. 157 *this = {}; 158 } 159 SkDEBUGCODE(this->validate()); 160 } 161 set(sk_sp<GrContextThreadSafeProxy> contextInfo,size_t cacheMaxResourceBytes,const SkImageInfo & ii,const GrBackendFormat & backendFormat,GrSurfaceOrigin origin,int sampleCnt,Textureable isTextureable,MipMapped isMipMapped,UsesGLFBO0 usesGLFBO0,VkRTSupportsInputAttachment vkRTSupportsInputAttachment,VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible,GrProtected isProtected,const SkSurfaceProps & surfaceProps)162 void set(sk_sp<GrContextThreadSafeProxy> contextInfo, 163 size_t cacheMaxResourceBytes, 164 const SkImageInfo& ii, 165 const GrBackendFormat& backendFormat, 166 GrSurfaceOrigin origin, 167 int sampleCnt, 168 Textureable isTextureable, 169 MipMapped isMipMapped, 170 UsesGLFBO0 usesGLFBO0, 171 VkRTSupportsInputAttachment vkRTSupportsInputAttachment, 172 VulkanSecondaryCBCompatible vulkanSecondaryCBCompatible, 173 GrProtected isProtected, 174 const SkSurfaceProps& surfaceProps) { 175 if (surfaceProps.flags() & SkSurfaceProps::kDynamicMSAA_Flag) { 176 // Dynamic MSAA is not currently supported with DDL. 177 *this = {}; 178 } else { 179 fContextInfo = contextInfo; 180 fCacheMaxResourceBytes = cacheMaxResourceBytes; 181 182 fImageInfo = ii; 183 fBackendFormat = backendFormat; 184 fOrigin = origin; 185 fSampleCnt = sampleCnt; 186 fIsTextureable = isTextureable; 187 fIsMipMapped = isMipMapped; 188 fUsesGLFBO0 = usesGLFBO0; 189 fVkRTSupportsInputAttachment = vkRTSupportsInputAttachment; 190 fVulkanSecondaryCBCompatible = vulkanSecondaryCBCompatible; 191 fIsProtected = isProtected; 192 fSurfaceProps = surfaceProps; 193 } 194 SkDEBUGCODE(this->validate()); 195 } 196 197 sk_sp<GrContextThreadSafeProxy> fContextInfo; 198 size_t fCacheMaxResourceBytes; 199 200 SkImageInfo fImageInfo; 201 GrBackendFormat fBackendFormat; 202 GrSurfaceOrigin fOrigin; 203 int fSampleCnt; 204 Textureable fIsTextureable; 205 MipMapped fIsMipMapped; 206 UsesGLFBO0 fUsesGLFBO0; 207 VkRTSupportsInputAttachment fVkRTSupportsInputAttachment; 208 VulkanSecondaryCBCompatible fVulkanSecondaryCBCompatible; 209 GrProtected fIsProtected; 210 SkSurfaceProps fSurfaceProps; 211 }; 212 213 #else// !SK_SUPPORT_GPU 214 class GrBackendFormat; 215 216 class SK_API SkSurfaceCharacterization { 217 public: SkSurfaceCharacterization()218 SkSurfaceCharacterization() : fSurfaceProps(0, kUnknown_SkPixelGeometry) { } 219 createResized(int width,int height)220 SkSurfaceCharacterization createResized(int width, int height) const { 221 return *this; 222 } 223 createColorSpace(sk_sp<SkColorSpace>)224 SkSurfaceCharacterization createColorSpace(sk_sp<SkColorSpace>) const { 225 return *this; 226 } 227 createBackendFormat(SkColorType,const GrBackendFormat &)228 SkSurfaceCharacterization createBackendFormat(SkColorType, const GrBackendFormat&) const { 229 return *this; 230 } 231 createFBO0(bool usesGLFBO0)232 SkSurfaceCharacterization createFBO0(bool usesGLFBO0) const { 233 return *this; 234 } 235 236 bool operator==(const SkSurfaceCharacterization& other) const { return false; } 237 bool operator!=(const SkSurfaceCharacterization& other) const { 238 return !(*this == other); 239 } 240 cacheMaxResourceBytes()241 size_t cacheMaxResourceBytes() const { return 0; } 242 isValid()243 bool isValid() const { return false; } 244 width()245 int width() const { return 0; } height()246 int height() const { return 0; } stencilCount()247 int stencilCount() const { return 0; } isTextureable()248 bool isTextureable() const { return false; } isMipMapped()249 bool isMipMapped() const { return false; } usesGLFBO0()250 bool usesGLFBO0() const { return false; } vkRTSupportsAttachmentInput()251 bool vkRTSupportsAttachmentInput() const { return false; } vulkanSecondaryCBCompatible()252 bool vulkanSecondaryCBCompatible() const { return false; } colorSpace()253 SkColorSpace* colorSpace() const { return nullptr; } refColorSpace()254 sk_sp<SkColorSpace> refColorSpace() const { return nullptr; } surfaceProps()255 const SkSurfaceProps& surfaceProps()const { return fSurfaceProps; } 256 257 private: 258 SkSurfaceProps fSurfaceProps; 259 }; 260 261 #endif 262 263 #endif 264