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 GrBackendSurface_DEFINED 9 #define GrBackendSurface_DEFINED 10 11 #include "include/gpu/GrTypes.h" 12 #include "include/gpu/gl/GrGLTypes.h" 13 #include "include/gpu/mock/GrMockTypes.h" 14 #include "include/gpu/vk/GrVkTypes.h" 15 #include "include/private/GrGLTypesPriv.h" 16 #include "include/private/GrVkTypesPriv.h" 17 18 #ifdef SK_DAWN 19 #include "include/gpu/dawn/GrDawnTypes.h" 20 #endif 21 22 class GrVkImageLayout; 23 class GrGLTextureParameters; 24 25 #ifdef SK_DAWN 26 #include "dawn/webgpu_cpp.h" 27 #endif 28 29 #ifdef SK_METAL 30 #include "include/gpu/mtl/GrMtlTypes.h" 31 #endif 32 33 #if GR_TEST_UTILS 34 class SkString; 35 #endif 36 37 #if !SK_SUPPORT_GPU 38 39 // SkSurfaceCharacterization always needs a minimal version of this 40 class SK_API GrBackendFormat { 41 public: isValid()42 bool isValid() const { return false; } 43 }; 44 45 // SkSurface and SkImage rely on a minimal version of these always being available 46 class SK_API GrBackendTexture { 47 public: GrBackendTexture()48 GrBackendTexture() {} 49 isValid()50 bool isValid() const { return false; } 51 }; 52 53 class SK_API GrBackendRenderTarget { 54 public: GrBackendRenderTarget()55 GrBackendRenderTarget() {} 56 isValid()57 bool isValid() const { return false; } isFramebufferOnly()58 bool isFramebufferOnly() const { return false; } 59 }; 60 #else 61 62 enum class GrGLFormat; 63 64 class SK_API GrBackendFormat { 65 public: 66 // Creates an invalid backend format. GrBackendFormat()67 GrBackendFormat() {} 68 69 GrBackendFormat(const GrBackendFormat& src); 70 MakeGL(GrGLenum format,GrGLenum target)71 static GrBackendFormat MakeGL(GrGLenum format, GrGLenum target) { 72 return GrBackendFormat(format, target); 73 } 74 MakeVk(VkFormat format)75 static GrBackendFormat MakeVk(VkFormat format) { 76 return GrBackendFormat(format, GrVkYcbcrConversionInfo()); 77 } 78 79 static GrBackendFormat MakeVk(const GrVkYcbcrConversionInfo& ycbcrInfo); 80 81 #ifdef SK_DAWN MakeDawn(wgpu::TextureFormat format)82 static GrBackendFormat MakeDawn(wgpu::TextureFormat format) { 83 return GrBackendFormat(format); 84 } 85 #endif 86 87 #ifdef SK_METAL MakeMtl(GrMTLPixelFormat format)88 static GrBackendFormat MakeMtl(GrMTLPixelFormat format) { 89 return GrBackendFormat(format); 90 } 91 #endif 92 93 static GrBackendFormat MakeMock(GrColorType colorType, SkImage::CompressionType compression); 94 95 bool operator==(const GrBackendFormat& that) const; 96 bool operator!=(const GrBackendFormat& that) const { return !(*this == that); } 97 backend()98 GrBackendApi backend() const { return fBackend; } textureType()99 GrTextureType textureType() const { return fTextureType; } 100 101 /** 102 * If the backend API is GL this gets the format as a GrGLFormat. Otherwise, returns 103 * GrGLFormat::kUnknown. 104 */ 105 GrGLFormat asGLFormat() const; 106 107 /** 108 * If the backend API is Vulkan this gets the format as a VkFormat and returns true. Otherwise, 109 * returns false. 110 */ 111 bool asVkFormat(VkFormat*) const; 112 113 const GrVkYcbcrConversionInfo* getVkYcbcrConversionInfo() const; 114 115 #ifdef SK_DAWN 116 /** 117 * If the backend API is Dawn this gets the format as a wgpu::TextureFormat and returns true. 118 * Otherwise, returns false. 119 */ 120 bool asDawnFormat(wgpu::TextureFormat*) const; 121 #endif 122 123 #ifdef SK_METAL 124 /** 125 * If the backend API is Metal this gets the format as a GrMtlPixelFormat. Otherwise, 126 * Otherwise, returns MTLPixelFormatInvalid. 127 */ 128 GrMTLPixelFormat asMtlFormat() const; 129 #endif 130 131 /** 132 * If the backend API is not Mock these two calls will return kUnknown and kNone, respectively. 133 * Otherwise, if the compression type is kNone then the GrColorType will be valid. If the 134 * compression type is anything other then kNone than the GrColorType will be kUnknown. 135 */ 136 GrColorType asMockColorType() const; 137 SkImage::CompressionType asMockCompressionType() const; 138 139 // If possible, copies the GrBackendFormat and forces the texture type to be Texture2D. If the 140 // GrBackendFormat was for Vulkan and it originally had a GrVkYcbcrConversionInfo, we will 141 // remove the conversion and set the format to be VK_FORMAT_R8G8B8A8_UNORM. 142 GrBackendFormat makeTexture2D() const; 143 144 // Returns true if the backend format has been initialized. isValid()145 bool isValid() const { return fValid; } 146 147 #if GR_TEST_UTILS 148 SkString toStr() const; 149 #endif 150 151 private: 152 GrBackendFormat(GrGLenum format, GrGLenum target); 153 154 GrBackendFormat(const VkFormat vkFormat, const GrVkYcbcrConversionInfo&); 155 156 #ifdef SK_DAWN 157 GrBackendFormat(wgpu::TextureFormat format); 158 #endif 159 160 #ifdef SK_METAL 161 GrBackendFormat(const GrMTLPixelFormat mtlFormat); 162 #endif 163 164 GrBackendFormat(GrColorType, SkImage::CompressionType); 165 166 GrBackendApi fBackend = GrBackendApi::kMock; 167 bool fValid = false; 168 169 union { 170 GrGLenum fGLFormat; // the sized, internal format of the GL resource 171 struct { 172 VkFormat fFormat; 173 GrVkYcbcrConversionInfo fYcbcrConversionInfo; 174 } fVk; 175 #ifdef SK_DAWN 176 wgpu::TextureFormat fDawnFormat; 177 #endif 178 179 #ifdef SK_METAL 180 GrMTLPixelFormat fMtlFormat; 181 #endif 182 struct { 183 GrColorType fColorType; 184 SkImage::CompressionType fCompressionType; 185 } fMock; 186 }; 187 GrTextureType fTextureType = GrTextureType::kNone; 188 }; 189 190 class SK_API GrBackendTexture { 191 public: 192 // Creates an invalid backend texture. GrBackendTexture()193 GrBackendTexture() : fIsValid(false) {} 194 195 // The GrGLTextureInfo must have a valid fFormat. 196 GrBackendTexture(int width, 197 int height, 198 GrMipMapped, 199 const GrGLTextureInfo& glInfo); 200 201 GrBackendTexture(int width, 202 int height, 203 const GrVkImageInfo& vkInfo); 204 205 #ifdef SK_METAL 206 GrBackendTexture(int width, 207 int height, 208 GrMipMapped, 209 const GrMtlTextureInfo& mtlInfo); 210 #endif 211 212 #ifdef SK_DAWN 213 GrBackendTexture(int width, 214 int height, 215 const GrDawnTextureInfo& dawnInfo); 216 #endif 217 218 GrBackendTexture(int width, 219 int height, 220 GrMipMapped, 221 const GrMockTextureInfo& mockInfo); 222 223 GrBackendTexture(const GrBackendTexture& that); 224 225 ~GrBackendTexture(); 226 227 GrBackendTexture& operator=(const GrBackendTexture& that); 228 dimensions()229 SkISize dimensions() const { return {fWidth, fHeight}; } width()230 int width() const { return fWidth; } height()231 int height() const { return fHeight; } hasMipMaps()232 bool hasMipMaps() const { return GrMipMapped::kYes == fMipMapped; } backend()233 GrBackendApi backend() const {return fBackend; } 234 235 // If the backend API is GL, copies a snapshot of the GrGLTextureInfo struct into the passed in 236 // pointer and returns true. Otherwise returns false if the backend API is not GL. 237 bool getGLTextureInfo(GrGLTextureInfo*) const; 238 239 // Call this to indicate that the texture parameters have been modified in the GL context 240 // externally to GrContext. 241 void glTextureParametersModified(); 242 243 #ifdef SK_DAWN 244 // If the backend API is Dawn, copies a snapshot of the GrDawnTextureInfo struct into the passed 245 // in pointer and returns true. Otherwise returns false if the backend API is not Dawn. 246 bool getDawnTextureInfo(GrDawnTextureInfo*) const; 247 #endif 248 249 // If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo struct into the passed 250 // in pointer and returns true. This snapshot will set the fImageLayout to the current layout 251 // state. Otherwise returns false if the backend API is not Vulkan. 252 bool getVkImageInfo(GrVkImageInfo*) const; 253 254 // Anytime the client changes the VkImageLayout of the VkImage captured by this 255 // GrBackendTexture, they must call this function to notify Skia of the changed layout. 256 void setVkImageLayout(VkImageLayout); 257 258 #ifdef SK_METAL 259 // If the backend API is Metal, copies a snapshot of the GrMtlTextureInfo struct into the passed 260 // in pointer and returns true. Otherwise returns false if the backend API is not Metal. 261 bool getMtlTextureInfo(GrMtlTextureInfo*) const; 262 #endif 263 264 // Get the GrBackendFormat for this texture (or an invalid format if this is not valid). 265 GrBackendFormat getBackendFormat() const; 266 267 // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed 268 // in pointer and returns true. Otherwise returns false if the backend API is not Mock. 269 bool getMockTextureInfo(GrMockTextureInfo*) const; 270 271 // Returns true if we are working with protected content. 272 bool isProtected() const; 273 274 // Returns true if the backend texture has been initialized. isValid()275 bool isValid() const { return fIsValid; } 276 277 // Returns true if both textures are valid and refer to the same API texture. 278 bool isSameTexture(const GrBackendTexture&); 279 280 #if GR_TEST_UTILS 281 static bool TestingOnly_Equals(const GrBackendTexture& , const GrBackendTexture&); 282 #endif 283 284 private: 285 286 #ifdef SK_GL 287 friend class GrGLTexture; 288 friend class GrGLGpu; // for getGLTextureParams 289 GrBackendTexture(int width, 290 int height, 291 GrMipMapped, 292 const GrGLTextureInfo, 293 sk_sp<GrGLTextureParameters>); 294 sk_sp<GrGLTextureParameters> getGLTextureParams() const; 295 #endif 296 297 #ifdef SK_VULKAN 298 friend class GrVkTexture; 299 friend class GrVkGpu; // for getGrVkImageLayout 300 GrBackendTexture(int width, 301 int height, 302 const GrVkImageInfo& vkInfo, 303 sk_sp<GrVkImageLayout> layout); 304 sk_sp<GrVkImageLayout> getGrVkImageLayout() const; 305 #endif 306 307 // Free and release and resources being held by the GrBackendTexture. 308 void cleanup(); 309 310 bool fIsValid; 311 int fWidth; //<! width in pixels 312 int fHeight; //<! height in pixels 313 GrMipMapped fMipMapped; 314 GrBackendApi fBackend; 315 316 union { 317 #ifdef SK_GL 318 GrGLBackendTextureInfo fGLInfo; 319 #endif 320 GrVkBackendSurfaceInfo fVkInfo; 321 GrMockTextureInfo fMockInfo; 322 }; 323 #ifdef SK_METAL 324 GrMtlTextureInfo fMtlInfo; 325 #endif 326 #ifdef SK_DAWN 327 GrDawnTextureInfo fDawnInfo; 328 #endif 329 }; 330 331 class SK_API GrBackendRenderTarget { 332 public: 333 // Creates an invalid backend texture. GrBackendRenderTarget()334 GrBackendRenderTarget() : fIsValid(false) {} 335 336 // The GrGLTextureInfo must have a valid fFormat. 337 GrBackendRenderTarget(int width, 338 int height, 339 int sampleCnt, 340 int stencilBits, 341 const GrGLFramebufferInfo& glInfo); 342 343 #ifdef SK_DAWN 344 GrBackendRenderTarget(int width, 345 int height, 346 int sampleCnt, 347 int stencilBits, 348 const GrDawnRenderTargetInfo& dawnInfo); 349 #endif 350 351 /** Deprecated, use version that does not take stencil bits. */ 352 GrBackendRenderTarget(int width, 353 int height, 354 int sampleCnt, 355 int stencilBits, 356 const GrVkImageInfo& vkInfo); 357 GrBackendRenderTarget(int width, int height, int sampleCnt, const GrVkImageInfo& vkInfo); 358 359 #ifdef SK_METAL 360 GrBackendRenderTarget(int width, 361 int height, 362 int sampleCnt, 363 const GrMtlTextureInfo& mtlInfo); 364 #endif 365 366 GrBackendRenderTarget(int width, 367 int height, 368 int sampleCnt, 369 int stencilBits, 370 const GrMockRenderTargetInfo& mockInfo); 371 372 ~GrBackendRenderTarget(); 373 374 GrBackendRenderTarget(const GrBackendRenderTarget& that); 375 GrBackendRenderTarget& operator=(const GrBackendRenderTarget&); 376 dimensions()377 SkISize dimensions() const { return {fWidth, fHeight}; } width()378 int width() const { return fWidth; } height()379 int height() const { return fHeight; } sampleCnt()380 int sampleCnt() const { return fSampleCnt; } stencilBits()381 int stencilBits() const { return fStencilBits; } backend()382 GrBackendApi backend() const {return fBackend; } isFramebufferOnly()383 bool isFramebufferOnly() const { return fFramebufferOnly; } 384 385 // If the backend API is GL, copies a snapshot of the GrGLFramebufferInfo struct into the passed 386 // in pointer and returns true. Otherwise returns false if the backend API is not GL. 387 bool getGLFramebufferInfo(GrGLFramebufferInfo*) const; 388 389 #ifdef SK_DAWN 390 // If the backend API is Dawn, copies a snapshot of the GrDawnRenderTargetInfo struct into the 391 // passed-in pointer and returns true. Otherwise returns false if the backend API is not Dawn. 392 bool getDawnRenderTargetInfo(GrDawnRenderTargetInfo*) const; 393 #endif 394 395 // If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo struct into the passed 396 // in pointer and returns true. This snapshot will set the fImageLayout to the current layout 397 // state. Otherwise returns false if the backend API is not Vulkan. 398 bool getVkImageInfo(GrVkImageInfo*) const; 399 400 // Anytime the client changes the VkImageLayout of the VkImage captured by this 401 // GrBackendRenderTarget, they must call this function to notify Skia of the changed layout. 402 void setVkImageLayout(VkImageLayout); 403 404 #ifdef SK_METAL 405 // If the backend API is Metal, copies a snapshot of the GrMtlTextureInfo struct into the passed 406 // in pointer and returns true. Otherwise returns false if the backend API is not Metal. 407 bool getMtlTextureInfo(GrMtlTextureInfo*) const; 408 #endif 409 410 // Get the GrBackendFormat for this render target (or an invalid format if this is not valid). 411 GrBackendFormat getBackendFormat() const; 412 413 // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed 414 // in pointer and returns true. Otherwise returns false if the backend API is not Mock. 415 bool getMockRenderTargetInfo(GrMockRenderTargetInfo*) const; 416 417 // Returns true if we are working with protected content. 418 bool isProtected() const; 419 420 // Returns true if the backend texture has been initialized. isValid()421 bool isValid() const { return fIsValid; } 422 423 424 #if GR_TEST_UTILS 425 static bool TestingOnly_Equals(const GrBackendRenderTarget&, const GrBackendRenderTarget&); 426 #endif 427 428 private: 429 friend class GrVkGpu; // for getGrVkImageLayout 430 sk_sp<GrVkImageLayout> getGrVkImageLayout() const; 431 432 friend class GrVkRenderTarget; 433 GrBackendRenderTarget(int width, int height, int sampleCnt, const GrVkImageInfo& vkInfo, 434 sk_sp<GrVkImageLayout> layout); 435 436 // Free and release and resources being held by the GrBackendTexture. 437 void cleanup(); 438 439 bool fIsValid; 440 bool fFramebufferOnly = false; 441 int fWidth; //<! width in pixels 442 int fHeight; //<! height in pixels 443 444 int fSampleCnt; 445 int fStencilBits; 446 447 GrBackendApi fBackend; 448 449 union { 450 #ifdef SK_GL 451 GrGLFramebufferInfo fGLInfo; 452 #endif 453 GrVkBackendSurfaceInfo fVkInfo; 454 GrMockRenderTargetInfo fMockInfo; 455 }; 456 #ifdef SK_METAL 457 GrMtlTextureInfo fMtlInfo; 458 #endif 459 #ifdef SK_DAWN 460 GrDawnRenderTargetInfo fDawnInfo; 461 #endif 462 }; 463 464 #endif 465 466 #endif 467 468