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