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 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkSize.h"
13 #include "include/gpu/GpuTypes.h"
14 #include "include/gpu/GrTypes.h"
15 #include "include/private/base/SkAPI.h"
16 #include "include/private/base/SkAnySubclass.h"
17 #include "include/private/gpu/ganesh/GrTypesPriv.h"
18 
19 #include "include/gpu/mock/GrMockTypes.h"
20 
21 enum class SkTextureCompressionType;
22 class GrBackendFormatData;
23 class GrBackendTextureData;
24 class GrBackendRenderTargetData;
25 
26 namespace skgpu {
27 class MutableTextureState;
28 class MutableTextureStateRef;
29 }
30 
31 #ifdef SK_METAL
32 #include "include/gpu/mtl/GrMtlTypes.h"
33 #endif
34 
35 #ifdef SK_DIRECT3D
36 #include "include/private/gpu/ganesh/GrD3DTypesMinimal.h"
37 class GrD3DResourceState;
38 #endif
39 
40 #if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
41 class SkString;
42 #endif
43 
44 #include <cstddef>
45 #include <cstdint>
46 #include <string>
47 #include <string_view>
48 
49 class SK_API GrBackendFormat {
50 public:
51  // Creates an invalid backend format.
56 
57 #ifdef SK_METAL
58  static GrBackendFormat MakeMtl(GrMTLPixelFormat format) {
59  return GrBackendFormat(format);
60  }
61 #endif
62 
63 #ifdef SK_DIRECT3D
64  static GrBackendFormat MakeDxgi(DXGI_FORMAT format) {
65  return GrBackendFormat(format);
66  }
67 #endif
68 
69  static GrBackendFormat MakeMock(GrColorType colorType,
70  SkTextureCompressionType compression,
71  bool isStencilFormat = false);
72 
73  bool operator==(const GrBackendFormat& that) const;
74  bool operator!=(const GrBackendFormat& that) const { return !(*this == that); }
75 
76  GrBackendApi backend() const { return fBackend; }
77  GrTextureType textureType() const { return fTextureType; }
78 
83  uint32_t channelMask() const;
84 
85  GrColorFormatDesc desc() const;
86 
87 #ifdef SK_METAL
92  GrMTLPixelFormat asMtlFormat() const;
93 #endif
94 
95 #ifdef SK_DIRECT3D
100  bool asDxgiFormat(DXGI_FORMAT*) const;
101 #endif
102 
108  GrColorType asMockColorType() const;
110  bool isMockStencilFormat() const;
111 
112  // If possible, copies the GrBackendFormat and forces the texture type to be Texture2D. If the
113  // GrBackendFormat was for Vulkan and it originally had a GrVkYcbcrConversionInfo, we will
114  // remove the conversion and set the format to be VK_FORMAT_R8G8B8A8_UNORM.
116 
117  // Returns true if the backend format has been initialized.
118  bool isValid() const { return fValid; }
119 
120 #if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
121  SkString toStr() const;
122 #endif
123 
124 private:
125  // Size determined by looking at the GrBackendFormatData subclasses, then guessing-and-checking.
126  // Compiler will complain if this is too small - in that case, just increase the number.
127  inline constexpr static size_t kMaxSubclassSize = 64;
128  using AnyFormatData = SkAnySubclass<GrBackendFormatData, kMaxSubclassSize>;
129 
130  friend class GrBackendSurfacePriv;
131  friend class GrBackendFormatData;
132 
133  // Used by internal factories. Should not be used externally. Use factories like
134  // GrBackendFormats::MakeGL instead.
135  template <typename FormatData>
136  GrBackendFormat(GrTextureType textureType, GrBackendApi api, const FormatData& formatData)
137  : fBackend(api), fValid(true), fTextureType(textureType) {
138  fFormatData.emplace<FormatData>(formatData);
139  }
140 
141 #ifdef SK_METAL
142  GrBackendFormat(const GrMTLPixelFormat mtlFormat);
143 #endif
144 
145 #ifdef SK_DIRECT3D
146  GrBackendFormat(DXGI_FORMAT dxgiFormat);
147 #endif
148 
149  GrBackendFormat(GrColorType, SkTextureCompressionType, bool isStencilFormat);
150 
151 #ifdef SK_DEBUG
152  bool validateMock() const;
153 #endif
154 
156  bool fValid = false;
157  AnyFormatData fFormatData;
158 
159  union {
160 #ifdef SK_METAL
161  GrMTLPixelFormat fMtlFormat;
162 #endif
163 
164 #ifdef SK_DIRECT3D
165  DXGI_FORMAT fDxgiFormat;
166 #endif
167  struct {
168  GrColorType fColorType;
171  } fMock;
172  };
173  GrTextureType fTextureType = GrTextureType::kNone;
174 };
175 
176 class SK_API GrBackendTexture {
177 public:
178  // Creates an invalid backend texture.
180 
181 #ifdef SK_METAL
182  GrBackendTexture(int width,
183  int height,
185  const GrMtlTextureInfo& mtlInfo,
186  std::string_view label = {});
187 #endif
188 
189 #ifdef SK_DIRECT3D
190  GrBackendTexture(int width,
191  int height,
192  const GrD3DTextureResourceInfo& d3dInfo,
193  std::string_view label = {});
194 #endif
195 
196  GrBackendTexture(int width,
197  int height,
199  const GrMockTextureInfo& mockInfo,
200  std::string_view label = {});
201 
203 
205 
207 
208  SkISize dimensions() const { return {fWidth, fHeight}; }
209  int width() const { return fWidth; }
210  int height() const { return fHeight; }
211  std::string_view getLabel() const { return fLabel; }
212  skgpu::Mipmapped mipmapped() const { return fMipmapped; }
213  bool hasMipmaps() const { return fMipmapped == skgpu::Mipmapped::kYes; }
215  bool hasMipMaps() const { return this->hasMipmaps(); }
216  GrBackendApi backend() const {return fBackend; }
217  GrTextureType textureType() const { return fTextureType; }
218 
219 #ifdef SK_METAL
220  // If the backend API is Metal, copies a snapshot of the GrMtlTextureInfo struct into the passed
221  // in pointer and returns true. Otherwise returns false if the backend API is not Metal.
222  bool getMtlTextureInfo(GrMtlTextureInfo*) const;
223 #endif
224 
225 #ifdef SK_DIRECT3D
226  // If the backend API is Direct3D, copies a snapshot of the GrD3DTextureResourceInfo struct into
227  // the passed in pointer and returns true. This snapshot will set the fResourceState to the
228  // current resource state. Otherwise returns false if the backend API is not D3D.
229  bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;
230 
231  // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
232  // GrBackendTexture, they must call this function to notify Skia of the changed layout.
233  void setD3DResourceState(GrD3DResourceStateEnum);
234 #endif
235 
236  // Get the GrBackendFormat for this texture (or an invalid format if this is not valid).
238 
239  // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
240  // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
241  bool getMockTextureInfo(GrMockTextureInfo*) const;
242 
243  // If the client changes any of the mutable backend of the GrBackendTexture they should call
244  // this function to inform Skia that those values have changed. The backend API specific state
245  // that can be set from this function are:
246  //
247  // Vulkan: VkImageLayout and QueueFamilyIndex
249 
250  // Returns true if we are working with protected content.
251  bool isProtected() const;
252 
253  // Returns true if the backend texture has been initialized.
254  bool isValid() const { return fIsValid; }
255 
256  // Returns true if both textures are valid and refer to the same API texture.
258 
259 #if defined(GR_TEST_UTILS)
260  static bool TestingOnly_Equals(const GrBackendTexture&, const GrBackendTexture&);
261 #endif
262 
263 private:
264  // Size determined by looking at the GrBackendTextureData subclasses, then guessing-and-checking.
265  // Compiler will complain if this is too small - in that case, just increase the number.
266  inline constexpr static size_t kMaxSubclassSize = 160;
267  using AnyTextureData = SkAnySubclass<GrBackendTextureData, kMaxSubclassSize>;
268 
269  friend class GrBackendSurfacePriv;
270  friend class GrBackendTextureData;
271 
272  // Used by internal factories. Should not be used externally. Use factories like
273  // GrBackendTextures::MakeGL instead.
274  template <typename TextureData>
275  GrBackendTexture(int width,
276  int height,
277  std::string_view label,
278  skgpu::Mipmapped mipped,
279  GrBackendApi backend,
280  GrTextureType texture,
281  const TextureData& textureData)
282  : fIsValid(true)
283  , fWidth(width)
284  , fHeight(height)
285  , fLabel(label)
286  , fMipmapped(mipped)
287  , fBackend(backend)
288  , fTextureType(texture) {
289  fTextureData.emplace<TextureData>(textureData);
290  }
291 
292  friend class GrVkGpu; // for getMutableState
293  sk_sp<skgpu::MutableTextureStateRef> getMutableState() const;
294 
295 #ifdef SK_DIRECT3D
296  friend class GrD3DTexture;
297  friend class GrD3DGpu; // for getGrD3DResourceState
298  GrBackendTexture(int width,
299  int height,
300  const GrD3DTextureResourceInfo& vkInfo,
302  std::string_view label = {});
303  sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
304 #endif
305 
306  // Free and release and resources being held by the GrBackendTexture.
307  void cleanup();
308 
309  bool fIsValid;
310  int fWidth; //<! width in pixels
311  int fHeight; //<! height in pixels
312  const std::string fLabel;
313  skgpu::Mipmapped fMipmapped;
314  GrBackendApi fBackend;
315  GrTextureType fTextureType;
316  AnyTextureData fTextureData;
317 
318  union {
319  GrMockTextureInfo fMockInfo;
320 #ifdef SK_DIRECT3D
321  GrD3DBackendSurfaceInfo fD3DInfo;
322 #endif
323  };
324 #ifdef SK_METAL
325  GrMtlTextureInfo fMtlInfo;
326 #endif
327 };
328 
329 class SK_API GrBackendRenderTarget {
330 public:
331  // Creates an invalid backend texture.
333 
334 #ifdef SK_METAL
335  GrBackendRenderTarget(int width,
336  int height,
337  const GrMtlTextureInfo& mtlInfo);
338 #endif
339 
340 #ifdef SK_DIRECT3D
341  GrBackendRenderTarget(int width,
342  int height,
343  const GrD3DTextureResourceInfo& d3dInfo);
344 #endif
345 
347  int height,
348  int sampleCnt,
349  int stencilBits,
350  const GrMockRenderTargetInfo& mockInfo);
351 
353 
356 
357  SkISize dimensions() const { return {fWidth, fHeight}; }
358  int width() const { return fWidth; }
359  int height() const { return fHeight; }
360  int sampleCnt() const { return fSampleCnt; }
361  int stencilBits() const { return fStencilBits; }
362  GrBackendApi backend() const {return fBackend; }
363  bool isFramebufferOnly() const { return fFramebufferOnly; }
364 
365 #ifdef SK_METAL
366  // If the backend API is Metal, copies a snapshot of the GrMtlTextureInfo struct into the passed
367  // in pointer and returns true. Otherwise returns false if the backend API is not Metal.
368  bool getMtlTextureInfo(GrMtlTextureInfo*) const;
369 #endif
370 
371 #ifdef SK_DIRECT3D
372  // If the backend API is Direct3D, copies a snapshot of the GrMtlTextureInfo struct into the
373  // passed in pointer and returns true. Otherwise returns false if the backend API is not D3D.
374  bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;
375 
376  // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
377  // GrBackendTexture, they must call this function to notify Skia of the changed layout.
378  void setD3DResourceState(GrD3DResourceStateEnum);
379 #endif
380 
381  // Get the GrBackendFormat for this render target (or an invalid format if this is not valid).
383 
384  // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
385  // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
386  bool getMockRenderTargetInfo(GrMockRenderTargetInfo*) const;
387 
388  // If the client changes any of the mutable backend of the GrBackendTexture they should call
389  // this function to inform Skia that those values have changed. The backend API specific state
390  // that can be set from this function are:
391  //
392  // Vulkan: VkImageLayout and QueueFamilyIndex
394 
395  // Returns true if we are working with protected content.
396  bool isProtected() const;
397 
398  // Returns true if the backend texture has been initialized.
399  bool isValid() const { return fIsValid; }
400 
401 #if defined(GR_TEST_UTILS)
402  static bool TestingOnly_Equals(const GrBackendRenderTarget&, const GrBackendRenderTarget&);
403 #endif
404 
405 private:
406  // Size determined by looking at the GrBackendRenderTargetData subclasses, then
407  // guessing-and-checking. Compiler will complain if this is too small - in that case, just
408  // increase the number.
409  inline constexpr static size_t kMaxSubclassSize = 160;
410  using AnyRenderTargetData = SkAnySubclass<GrBackendRenderTargetData, kMaxSubclassSize>;
411 
412  friend class GrBackendSurfacePriv;
413  friend class GrBackendRenderTargetData;
414 
415  // Used by internal factories. Should not be used externally. Use factories like
416  // GrBackendRenderTargets::MakeGL instead.
417  template <typename RenderTargetData>
418  GrBackendRenderTarget(int width,
419  int height,
420  int sampleCnt,
421  int stencilBits,
422  GrBackendApi backend,
423  bool framebufferOnly,
424  const RenderTargetData& rtData)
425  : fIsValid(true)
426  , fFramebufferOnly(framebufferOnly)
427  , fWidth(width)
428  , fHeight(height)
429  , fSampleCnt(sampleCnt)
430  , fStencilBits(stencilBits)
431  , fBackend(backend) {
432  fRTData.emplace<RenderTargetData>(rtData);
433  }
434 
435  friend class GrVkGpu; // for getMutableState
436  sk_sp<skgpu::MutableTextureStateRef> getMutableState() const;
437 
438 #ifdef SK_DIRECT3D
439  friend class GrD3DGpu;
440  friend class GrD3DRenderTarget;
441  GrBackendRenderTarget(int width,
442  int height,
443  const GrD3DTextureResourceInfo& d3dInfo,
445  sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
446 #endif
447 
448  // Free and release and resources being held by the GrBackendTexture.
449  void cleanup();
450 
451  bool fIsValid;
452  bool fFramebufferOnly = false;
453  int fWidth; //<! width in pixels
454  int fHeight; //<! height in pixels
455 
456  int fSampleCnt;
457  int fStencilBits;
458 
459  GrBackendApi fBackend;
460  AnyRenderTargetData fRTData;
461 
462  union {
463  GrMockRenderTargetInfo fMockInfo;
464 #ifdef SK_DIRECT3D
465  GrD3DBackendSurfaceInfo fD3DInfo;
466 #endif
467  };
468 #ifdef SK_METAL
469  GrMtlTextureInfo fMtlInfo;
470 #endif
471 };
472 
473 #endif
GrBackendApi
Possible 3D APIs that may be used by Ganesh.
Definition: GrTypes.h:96
@ kMock
Mock is a backend that does not draw anything.
SkTextureCompressionType
Definition: SkTextureCompressionType.h:20
Definition: GrBackendSurface.h:49
static GrBackendFormat MakeMock(GrColorType colorType, SkTextureCompressionType compression, bool isStencilFormat=false)
GrColorType fColorType
Definition: GrBackendSurface.h:168
bool isMockStencilFormat() const
bool operator==(const GrBackendFormat &that) const
GrColorFormatDesc desc() const
GrBackendFormat & operator=(const GrBackendFormat &)
GrBackendFormat(const GrBackendFormat &)
SkTextureCompressionType fCompressionType
Definition: GrBackendSurface.h:169
GrBackendApi backend() const
Definition: GrBackendSurface.h:76
bool isValid() const
Definition: GrBackendSurface.h:118
SkTextureCompressionType asMockCompressionType() const
GrColorType asMockColorType() const
If the backend API is not Mock these three calls will return kUnknown, kNone or false,...
GrTextureType textureType() const
Definition: GrBackendSurface.h:77
uint32_t channelMask() const
Gets the channels present in the format as a bitfield of SkColorChannelFlag values.
bool operator!=(const GrBackendFormat &that) const
Definition: GrBackendSurface.h:74
bool fIsStencilFormat
Definition: GrBackendSurface.h:170
GrBackendFormat makeTexture2D() const
Definition: GrBackendSurface.h:329
void setMutableState(const skgpu::MutableTextureState &)
bool isProtected() const
bool isFramebufferOnly() const
Definition: GrBackendSurface.h:363
GrBackendRenderTarget(const GrBackendRenderTarget &that)
GrBackendRenderTarget(int width, int height, int sampleCnt, int stencilBits, const GrMockRenderTargetInfo &mockInfo)
bool getMockRenderTargetInfo(GrMockRenderTargetInfo *) const
int width() const
Definition: GrBackendSurface.h:358
int stencilBits() const
Definition: GrBackendSurface.h:361
GrMockRenderTargetInfo fMockInfo
Definition: GrBackendSurface.h:463
GrBackendFormat getBackendFormat() const
int sampleCnt() const
Definition: GrBackendSurface.h:360
GrBackendRenderTarget & operator=(const GrBackendRenderTarget &)
GrBackendApi backend() const
Definition: GrBackendSurface.h:362
int height() const
Definition: GrBackendSurface.h:359
bool isValid() const
Definition: GrBackendSurface.h:399
SkISize dimensions() const
Definition: GrBackendSurface.h:357
Definition: GrBackendSurface.h:176
SkISize dimensions() const
Definition: GrBackendSurface.h:208
GrBackendTexture(int width, int height, skgpu::Mipmapped, const GrMockTextureInfo &mockInfo, std::string_view label={})
GrBackendFormat getBackendFormat() const
bool isSameTexture(const GrBackendTexture &)
skgpu::Mipmapped mipmapped() const
Definition: GrBackendSurface.h:212
GrBackendTexture(const GrBackendTexture &that)
bool hasMipmaps() const
Definition: GrBackendSurface.h:213
std::string_view getLabel() const
Definition: GrBackendSurface.h:211
GrBackendTexture & operator=(const GrBackendTexture &that)
bool getMockTextureInfo(GrMockTextureInfo *) const
bool isValid() const
Definition: GrBackendSurface.h:254
bool isProtected() const
GrTextureType textureType() const
Definition: GrBackendSurface.h:217
GrMockTextureInfo fMockInfo
Definition: GrBackendSurface.h:319
void setMutableState(const skgpu::MutableTextureState &)
bool hasMipMaps() const
deprecated alias of hasMipmaps().
Definition: GrBackendSurface.h:215
GrBackendApi backend() const
Definition: GrBackendSurface.h:216
int height() const
Definition: GrBackendSurface.h:210
int width() const
Definition: GrBackendSurface.h:209
Light weight class for managing strings.
Definition: SkString.h:118
Shared pointer class to wrap classes that support a ref()/unref() interface.
Definition: SkRefCnt.h:220
Since Skia and clients can both modify gpu textures and their connected state, Skia needs a way for c...
Definition: MutableTextureState.h:37
This file includes numerous public types that are used by all of our gpu backends.
Definition: SkCanvas.h:73
Mipmapped
Is the texture mipmapped or not.
Definition: GpuTypes.h:53
Definition: SkSize.h:15