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