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