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