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