Skia
2D Graphics Library
GrBackendSurface.h
Go to the documentation of this file.
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 
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
49 public:
50  bool isValid() const { return false; }
51 };
52 
53 // SkSurface and SkImage rely on a minimal version of these always being available
55 public:
57 
58  bool isValid() const { return false; }
59 };
60 
62 public:
64 
65  bool isValid() const { return false; }
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.
75  GrBackendFormat() {}
77  GrBackendFormat& operator=(const GrBackendFormat&);
78 
79  static GrBackendFormat MakeGL(GrGLenum format, GrGLenum target) {
80  return GrBackendFormat(format, target);
81  }
82 
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
90  static GrBackendFormat MakeDawn(wgpu::TextureFormat format) {
91  return GrBackendFormat(format);
92  }
93 #endif
94 
95 #ifdef SK_METAL
96  static GrBackendFormat MakeMtl(GrMTLPixelFormat format) {
97  return GrBackendFormat(format);
98  }
99 #endif
100 
101 #ifdef SK_DIRECT3D
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 
113  GrBackendApi backend() const { return fBackend; }
114  GrTextureType textureType() const { return fTextureType; }
115 
120  uint32_t channelMask() const;
121 
126  GrGLFormat asGLFormat() const;
127 
132  bool asVkFormat(VkFormat*) const;
133 
134  const GrVkYcbcrConversionInfo* getVkYcbcrConversionInfo() const;
135 
136 #ifdef SK_DAWN
137 
141  bool asDawnFormat(wgpu::TextureFormat*) const;
142 #endif
143 
144 #ifdef SK_METAL
145 
149  GrMTLPixelFormat asMtlFormat() const;
150 #endif
151 
152 #ifdef SK_DIRECT3D
153 
157  bool asDxgiFormat(DXGI_FORMAT*) const;
158 #endif
159 
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.
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 
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.
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 
280  SkISize dimensions() const { return {fWidth, fHeight}; }
281  int width() const { return fWidth; }
282  int height() const { return fHeight; }
283  bool hasMipmaps() const { return fMipmapped == GrMipmapped::kYes; }
285  bool hasMipMaps() const { return this->hasMipmaps(); }
286  GrBackendApi backend() const {return fBackend; }
287 
288  // If the backend API is GL, copies a snapshot of the GrGLTextureInfo struct into the passed in
289  // pointer and returns true. Otherwise returns false if the backend API is not GL.
290  bool getGLTextureInfo(GrGLTextureInfo*) const;
291 
292  // Call this to indicate that the texture parameters have been modified in the GL context
293  // externally to GrContext.
294  void glTextureParametersModified();
295 
296 #ifdef SK_DAWN
297  // If the backend API is Dawn, copies a snapshot of the GrDawnTextureInfo struct into the passed
298  // in pointer and returns true. Otherwise returns false if the backend API is not Dawn.
299  bool getDawnTextureInfo(GrDawnTextureInfo*) const;
300 #endif
301 
302  // If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo struct into the passed
303  // in pointer and returns true. This snapshot will set the fImageLayout to the current layout
304  // state. Otherwise returns false if the backend API is not Vulkan.
305  bool getVkImageInfo(GrVkImageInfo*) const;
306 
307  // Anytime the client changes the VkImageLayout of the VkImage captured by this
308  // GrBackendTexture, they must call this function to notify Skia of the changed layout.
309  void setVkImageLayout(VkImageLayout);
310 
311 #ifdef SK_METAL
312  // If the backend API is Metal, copies a snapshot of the GrMtlTextureInfo struct into the passed
313  // in pointer and returns true. Otherwise returns false if the backend API is not Metal.
314  bool getMtlTextureInfo(GrMtlTextureInfo*) const;
315 #endif
316 
317 #ifdef SK_DIRECT3D
318  // If the backend API is Direct3D, copies a snapshot of the GrD3DTextureResourceInfo struct into
319  // the passed in pointer and returns true. This snapshot will set the fResourceState to the
320  // current resource state. Otherwise returns false if the backend API is not D3D.
321  bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;
322 
323  // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
324  // GrBackendTexture, they must call this function to notify Skia of the changed layout.
325  void setD3DResourceState(GrD3DResourceStateEnum);
326 #endif
327 
328  // Get the GrBackendFormat for this texture (or an invalid format if this is not valid).
329  GrBackendFormat getBackendFormat() const;
330 
331  // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
332  // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
333  bool getMockTextureInfo(GrMockTextureInfo*) const;
334 
335  // If the client changes any of the mutable backend of the GrBackendTexture they should call
336  // this function to inform Skia that those values have changed. The backend API specific state
337  // that can be set from this function are:
338  //
339  // Vulkan: VkImageLayout and QueueFamilyIndex
340  void setMutableState(const GrBackendSurfaceMutableState&);
341 
342  // Returns true if we are working with protected content.
343  bool isProtected() const;
344 
345  // Returns true if the backend texture has been initialized.
346  bool isValid() const { return fIsValid; }
347 
348  // Returns true if both textures are valid and refer to the same API texture.
349  bool isSameTexture(const GrBackendTexture&);
350 
351 #if GR_TEST_UTILS
352  static bool TestingOnly_Equals(const GrBackendTexture& , const GrBackendTexture&);
353 #endif
354 
355 private:
356  friend class GrVkGpu; // for getMutableState
357  sk_sp<GrBackendSurfaceMutableStateImpl> getMutableState() const;
358 
359 #ifdef SK_GL
360  friend class GrGLTexture;
361  friend class GrGLGpu; // for getGLTextureParams
362  GrBackendTexture(int width,
363  int height,
364  GrMipmapped,
365  const GrGLTextureInfo,
367  sk_sp<GrGLTextureParameters> getGLTextureParams() const;
368 #endif
369 
370 #ifdef SK_VULKAN
371  friend class GrVkTexture;
372  GrBackendTexture(int width,
373  int height,
374  const GrVkImageInfo& vkInfo,
376 #endif
377 
378 #ifdef SK_DIRECT3D
379  friend class GrD3DTexture;
380  friend class GrD3DGpu; // for getGrD3DResourceState
381  GrBackendTexture(int width,
382  int height,
383  const GrD3DTextureResourceInfo& vkInfo,
385  sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
386 #endif
387 
388  // Free and release and resources being held by the GrBackendTexture.
389  void cleanup();
390 
391  bool fIsValid;
392  int fWidth; //<! width in pixels
393  int fHeight; //<! height in pixels
394  GrMipmapped fMipmapped;
395  GrBackendApi fBackend;
396 
397  union {
398 #ifdef SK_GL
399  GrGLBackendTextureInfo fGLInfo;
400 #endif
401  GrVkBackendSurfaceInfo fVkInfo;
402  GrMockTextureInfo fMockInfo;
403 #ifdef SK_DIRECT3D
404  GrD3DBackendSurfaceInfo fD3DInfo;
405 #endif
406  };
407 #ifdef SK_METAL
408  GrMtlTextureInfo fMtlInfo;
409 #endif
410 #ifdef SK_DAWN
411  GrDawnTextureInfo fDawnInfo;
412 #endif
413 
415 };
416 
418 public:
419  // Creates an invalid backend texture.
421 
422  // The GrGLTextureInfo must have a valid fFormat. If wrapping in an SkSurface we require the
423  // stencil bits to be either 0, 8 or 16.
424  GrBackendRenderTarget(int width,
425  int height,
426  int sampleCnt,
427  int stencilBits,
428  const GrGLFramebufferInfo& glInfo);
429 
430 #ifdef SK_DAWN
431  // If wrapping in an SkSurface we require the stencil bits to be either 0, 8 or 16.
432  GrBackendRenderTarget(int width,
433  int height,
434  int sampleCnt,
435  int stencilBits,
436  const GrDawnRenderTargetInfo& dawnInfo);
437 #endif
438 
439 #ifdef SK_VULKAN
440 
441  GrBackendRenderTarget(int width, int height, int sampleCnt, const GrVkImageInfo& vkInfo);
442 
443  GrBackendRenderTarget(int width, int height, const GrVkImageInfo& vkInfo);
444 #endif
445 
446 #ifdef SK_METAL
447  GrBackendRenderTarget(int width,
448  int height,
449  const GrMtlTextureInfo& mtlInfo);
451  GrBackendRenderTarget(int width,
452  int height,
453  int sampleCnt,
454  const GrMtlTextureInfo& mtlInfo);
455 #endif
456 
457 #ifdef SK_DIRECT3D
458  GrBackendRenderTarget(int width,
459  int height,
460  const GrD3DTextureResourceInfo& d3dInfo);
461 #endif
462 
463  GrBackendRenderTarget(int width,
464  int height,
465  int sampleCnt,
466  int stencilBits,
467  const GrMockRenderTargetInfo& mockInfo);
468 
470 
472  GrBackendRenderTarget& operator=(const GrBackendRenderTarget&);
473 
474  SkISize dimensions() const { return {fWidth, fHeight}; }
475  int width() const { return fWidth; }
476  int height() const { return fHeight; }
477  int sampleCnt() const { return fSampleCnt; }
478  int stencilBits() const { return fStencilBits; }
479  GrBackendApi backend() const {return fBackend; }
480  bool isFramebufferOnly() const { return fFramebufferOnly; }
481 
482  // If the backend API is GL, copies a snapshot of the GrGLFramebufferInfo struct into the passed
483  // in pointer and returns true. Otherwise returns false if the backend API is not GL.
484  bool getGLFramebufferInfo(GrGLFramebufferInfo*) const;
485 
486 #ifdef SK_DAWN
487  // If the backend API is Dawn, copies a snapshot of the GrDawnRenderTargetInfo struct into the
488  // passed-in pointer and returns true. Otherwise returns false if the backend API is not Dawn.
489  bool getDawnRenderTargetInfo(GrDawnRenderTargetInfo*) const;
490 #endif
491 
492  // If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo struct into the passed
493  // in pointer and returns true. This snapshot will set the fImageLayout to the current layout
494  // state. Otherwise returns false if the backend API is not Vulkan.
495  bool getVkImageInfo(GrVkImageInfo*) const;
496 
497  // Anytime the client changes the VkImageLayout of the VkImage captured by this
498  // GrBackendRenderTarget, they must call this function to notify Skia of the changed layout.
499  void setVkImageLayout(VkImageLayout);
500 
501 #ifdef SK_METAL
502  // If the backend API is Metal, copies a snapshot of the GrMtlTextureInfo struct into the passed
503  // in pointer and returns true. Otherwise returns false if the backend API is not Metal.
504  bool getMtlTextureInfo(GrMtlTextureInfo*) const;
505 #endif
506 
507 #ifdef SK_DIRECT3D
508  // If the backend API is Direct3D, copies a snapshot of the GrMtlTextureInfo struct into the
509  // passed in pointer and returns true. Otherwise returns false if the backend API is not D3D.
510  bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;
511 
512  // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
513  // GrBackendTexture, they must call this function to notify Skia of the changed layout.
514  void setD3DResourceState(GrD3DResourceStateEnum);
515 #endif
516 
517  // Get the GrBackendFormat for this render target (or an invalid format if this is not valid).
518  GrBackendFormat getBackendFormat() const;
519 
520  // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
521  // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
522  bool getMockRenderTargetInfo(GrMockRenderTargetInfo*) const;
523 
524  // If the client changes any of the mutable backend of the GrBackendTexture they should call
525  // this function to inform Skia that those values have changed. The backend API specific state
526  // that can be set from this function are:
527  //
528  // Vulkan: VkImageLayout and QueueFamilyIndex
529  void setMutableState(const GrBackendSurfaceMutableState&);
530 
531  // Returns true if we are working with protected content.
532  bool isProtected() const;
533 
534  // Returns true if the backend texture has been initialized.
535  bool isValid() const { return fIsValid; }
536 
537 
538 #if GR_TEST_UTILS
539  static bool TestingOnly_Equals(const GrBackendRenderTarget&, const GrBackendRenderTarget&);
540 #endif
541 
542 private:
543  friend class GrVkGpu; // for getMutableState
544  sk_sp<GrBackendSurfaceMutableStateImpl> getMutableState() const;
545 
546 #ifdef SK_VULKAN
547  friend class GrVkRenderTarget;
548  GrBackendRenderTarget(int width,
549  int height,
550  const GrVkImageInfo& vkInfo,
552 #endif
553 
554 #ifdef SK_DIRECT3D
555  friend class GrD3DGpu;
556  friend class GrD3DRenderTarget;
557  GrBackendRenderTarget(int width,
558  int height,
559  const GrD3DTextureResourceInfo& d3dInfo,
561  sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
562 #endif
563 
564  // Free and release and resources being held by the GrBackendTexture.
565  void cleanup();
566 
567  bool fIsValid;
568  bool fFramebufferOnly = false;
569  int fWidth; //<! width in pixels
570  int fHeight; //<! height in pixels
571 
572  int fSampleCnt;
573  int fStencilBits;
574 
575  GrBackendApi fBackend;
576 
577  union {
578 #ifdef SK_GL
579  GrGLFramebufferInfo fGLInfo;
580 #endif
581  GrVkBackendSurfaceInfo fVkInfo;
582  GrMockRenderTargetInfo fMockInfo;
583 #ifdef SK_DIRECT3D
584  GrD3DBackendSurfaceInfo fD3DInfo;
585 #endif
586  };
587 #ifdef SK_METAL
588  GrMtlTextureInfo fMtlInfo;
589 #endif
590 #ifdef SK_DAWN
591  GrDawnRenderTargetInfo fDawnInfo;
592 #endif
594 };
595 
596 #endif
597 
598 #endif
599 
operator==
bool operator==(const sk_sp< T > &a, const sk_sp< U > &b)
Definition: SkRefCnt.h:338
GrBackendRenderTarget::GrBackendRenderTarget
GrBackendRenderTarget()
Definition: GrBackendSurface.h:63
GrBackendRenderTarget
Definition: GrBackendSurface.h:61
operator!=
bool operator!=(const sk_sp< T > &a, const sk_sp< U > &b)
Definition: SkRefCnt.h:348
GrMipmapped
GrMipmapped
Used to say whether a texture has mip levels allocated or not.
Definition: GrTypes.h:169
sk_sp
Shared pointer class to wrap classes that support a ref()/unref() interface.
Definition: SkRefCnt.h:215
GrBackendFormat
Definition: GrBackendSurface.h:48
SK_API
#define SK_API
Definition: SkTypes.h:181
GrMipmapped::kYes
@ kYes
GrBackendRenderTarget::isFramebufferOnly
bool isFramebufferOnly() const
Definition: GrBackendSurface.h:66
SkISize
Definition: SkSize.h:13
GrBackendTexture::isValid
bool isValid() const
Definition: GrBackendSurface.h:58
GrBackendApi
GrBackendApi
Possible 3D APIs that may be used by Ganesh.
Definition: GrTypes.h:135
GrTypes.h
GrBackendFormat::isValid
bool isValid() const
Definition: GrBackendSurface.h:50
GrBackendTexture::GrBackendTexture
GrBackendTexture()
Definition: GrBackendSurface.h:56
GrBackendSurfaceMutableState.h
SkString
Definition: SkString.h:116
GrBackendTexture
Definition: GrBackendSurface.h:54
GrBackendSurfaceMutableState
Since Skia and clients can both modify gpu textures and their connected state, Skia needs a way for c...
Definition: GrBackendSurfaceMutableState.h:27
GrBackendRenderTarget::isValid
bool isValid() const
Definition: GrBackendSurface.h:65
GrBackendApi::kMock
@ kMock
Mock is a backend that does not draw anything.
SkImage::CompressionType
CompressionType
Definition: SkImage.h:197