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