Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/gpu/GrBackendSurface.cpp
Line
Count
Source (jump to first uncovered line)
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
#include "include/gpu/GrBackendSurface.h"
9
10
#include "include/private/GrTypesPriv.h"
11
#include "src/gpu/GrBackendSurfaceMutableStateImpl.h"
12
#include "src/gpu/gl/GrGLUtil.h"
13
14
#ifdef SK_DAWN
15
#include "include/gpu/dawn/GrDawnTypes.h"
16
#include "src/gpu/dawn/GrDawnUtil.h"
17
#endif
18
19
#ifdef SK_VULKAN
20
#include "include/gpu/vk/GrVkTypes.h"
21
#include "src/gpu/vk/GrVkImageLayout.h"
22
#include "src/gpu/vk/GrVkUtil.h"
23
#endif
24
#ifdef SK_METAL
25
#include "include/gpu/mtl/GrMtlTypes.h"
26
#include "src/gpu/mtl/GrMtlCppUtil.h"
27
#endif
28
#ifdef SK_DIRECT3D
29
#include "include/gpu/d3d/GrD3DTypes.h"
30
#include "src/gpu/d3d/GrD3DResourceState.h"
31
#include "src/gpu/d3d/GrD3DUtil.h"
32
#endif
33
34
GrBackendFormat::GrBackendFormat(const GrBackendFormat& that)
35
        : fBackend(that.fBackend)
36
        , fValid(that.fValid)
37
588k
        , fTextureType(that.fTextureType) {
38
588k
    if (!fValid) {
39
0
        return;
40
0
    }
41
42
588k
    switch (fBackend) {
43
0
#ifdef SK_GL
44
0
        case GrBackendApi::kOpenGL:
45
0
            fGLFormat = that.fGLFormat;
46
0
            break;
47
0
#endif
48
#ifdef SK_VULKAN
49
        case GrBackendApi::kVulkan:
50
            fVk = that.fVk;
51
            break;
52
#endif
53
#ifdef SK_METAL
54
        case GrBackendApi::kMetal:
55
            fMtlFormat = that.fMtlFormat;
56
            break;
57
#endif
58
#ifdef SK_DIRECT3D
59
        case GrBackendApi::kDirect3D:
60
            fDxgiFormat = that.fDxgiFormat;
61
            break;
62
#endif
63
#ifdef SK_DAWN
64
        case GrBackendApi::kDawn:
65
            fDawnFormat = that.fDawnFormat;
66
            break;
67
#endif
68
588k
        case GrBackendApi::kMock:
69
588k
            fMock = that.fMock;
70
588k
            break;
71
0
        default:
72
0
            SK_ABORT("Unknown GrBackend");
73
588k
    }
74
588k
}
75
76
11.2k
GrBackendFormat& GrBackendFormat::operator=(const GrBackendFormat& that) {
77
11.2k
    if (this != &that) {
78
11.2k
        this->~GrBackendFormat();
79
11.2k
        new (this) GrBackendFormat(that);
80
11.2k
    }
81
11.2k
    return *this;
82
11.2k
}
83
84
#ifdef SK_GL
85
86
0
static GrTextureType gl_target_to_gr_target(GrGLenum target) {
87
0
    switch (target) {
88
0
        case GR_GL_TEXTURE_NONE:
89
0
            return GrTextureType::kNone;
90
0
        case GR_GL_TEXTURE_2D:
91
0
            return  GrTextureType::k2D;
92
0
        case GR_GL_TEXTURE_RECTANGLE:
93
0
            return GrTextureType::kRectangle;
94
0
        case GR_GL_TEXTURE_EXTERNAL:
95
0
            return GrTextureType::kExternal;
96
0
        default:
97
0
            SkUNREACHABLE;
98
0
    }
99
0
}
100
101
GrBackendFormat::GrBackendFormat(GrGLenum format, GrGLenum target)
102
        : fBackend(GrBackendApi::kOpenGL)
103
        , fValid(true)
104
        , fGLFormat(format)
105
0
        , fTextureType(gl_target_to_gr_target(target)) {}
106
#endif
107
108
0
GrGLFormat GrBackendFormat::asGLFormat() const {
109
0
    if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
110
0
        return GrGLFormatFromGLEnum(fGLFormat);
111
0
    }
112
0
    return GrGLFormat::kUnknown;
113
0
}
114
115
0
GrBackendFormat GrBackendFormat::MakeVk(const GrVkYcbcrConversionInfo& ycbcrInfo) {
116
0
    SkASSERT(ycbcrInfo.isValid());
117
0
    return GrBackendFormat(ycbcrInfo.fFormat, ycbcrInfo);
118
0
}
Unexecuted instantiation: GrBackendFormat::MakeVk(GrVkYcbcrConversionInfo const&)
Unexecuted instantiation: GrBackendFormat::MakeVk(GrVkYcbcrConversionInfo const&)
119
120
GrBackendFormat::GrBackendFormat(VkFormat vkFormat, const GrVkYcbcrConversionInfo& ycbcrInfo)
121
        : fBackend(GrBackendApi::kVulkan)
122
#ifdef SK_VULKAN
123
        , fValid(true)
124
#else
125
        , fValid(false)
126
#endif
127
0
        , fTextureType(GrTextureType::k2D) {
128
0
    fVk.fFormat = vkFormat;
129
0
    fVk.fYcbcrConversionInfo = ycbcrInfo;
130
0
    if (fVk.fYcbcrConversionInfo.isValid() && fVk.fYcbcrConversionInfo.fExternalFormat) {
131
0
        fTextureType = GrTextureType::kExternal;
132
0
    }
133
0
}
134
135
0
bool GrBackendFormat::asVkFormat(VkFormat* format) const {
136
0
    SkASSERT(format);
137
0
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
138
0
        *format = fVk.fFormat;
139
0
        return true;
140
0
    }
141
0
    return false;
142
0
}
Unexecuted instantiation: GrBackendFormat::asVkFormat(VkFormat*) const
Unexecuted instantiation: GrBackendFormat::asVkFormat(VkFormat*) const
143
144
11.3k
const GrVkYcbcrConversionInfo* GrBackendFormat::getVkYcbcrConversionInfo() const {
145
11.3k
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
146
0
        return &fVk.fYcbcrConversionInfo;
147
0
    }
148
11.3k
    return nullptr;
149
11.3k
}
150
151
#ifdef SK_DAWN
152
GrBackendFormat::GrBackendFormat(wgpu::TextureFormat format)
153
        : fBackend(GrBackendApi::kDawn)
154
        , fValid(true)
155
        , fDawnFormat(format)
156
        , fTextureType(GrTextureType::k2D) {
157
}
158
159
bool GrBackendFormat::asDawnFormat(wgpu::TextureFormat* format) const {
160
    SkASSERT(format);
161
    if (this->isValid() && GrBackendApi::kDawn == fBackend) {
162
        *format = fDawnFormat;
163
        return true;
164
    }
165
    return false;
166
}
167
#endif
168
169
#ifdef SK_METAL
170
GrBackendFormat::GrBackendFormat(GrMTLPixelFormat mtlFormat)
171
        : fBackend(GrBackendApi::kMetal)
172
        , fValid(true)
173
        , fMtlFormat(mtlFormat)
174
        , fTextureType(GrTextureType::k2D) {
175
}
176
177
GrMTLPixelFormat GrBackendFormat::asMtlFormat() const {
178
    if (this->isValid() && GrBackendApi::kMetal == fBackend) {
179
        return fMtlFormat;
180
    }
181
    // MTLPixelFormatInvalid == 0
182
    return GrMTLPixelFormat(0);
183
}
184
#endif
185
186
#ifdef SK_DIRECT3D
187
GrBackendFormat::GrBackendFormat(DXGI_FORMAT dxgiFormat)
188
    : fBackend(GrBackendApi::kDirect3D)
189
    , fValid(true)
190
    , fDxgiFormat(dxgiFormat)
191
    , fTextureType(GrTextureType::k2D) {
192
}
193
194
bool GrBackendFormat::asDxgiFormat(DXGI_FORMAT* dxgiFormat) const {
195
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
196
        *dxgiFormat = fDxgiFormat;
197
        return true;
198
    }
199
    return false;
200
}
201
#endif
202
203
GrBackendFormat::GrBackendFormat(GrColorType colorType, SkImage::CompressionType compression,
204
                                 bool isStencilFormat)
205
        : fBackend(GrBackendApi::kMock)
206
        , fValid(true)
207
499k
        , fTextureType(GrTextureType::k2D) {
208
499k
    fMock.fColorType = colorType;
209
499k
    fMock.fCompressionType = compression;
210
499k
    fMock.fIsStencilFormat = isStencilFormat;
211
499k
    SkASSERT(this->validateMock());
212
499k
}
213
214
0
uint32_t GrBackendFormat::channelMask() const {
215
0
    if (!this->isValid()) {
216
0
        return 0;
217
0
    }
218
0
    switch (fBackend) {
219
0
#ifdef SK_GL
220
0
        case GrBackendApi::kOpenGL:
221
0
            return GrGLFormatChannels(GrGLFormatFromGLEnum(fGLFormat));
222
0
#endif
223
#ifdef SK_VULKAN
224
        case GrBackendApi::kVulkan:
225
            return GrVkFormatChannels(fVk.fFormat);
226
#endif
227
#ifdef SK_METAL
228
        case GrBackendApi::kMetal:
229
            return GrMtlFormatChannels(fMtlFormat);
230
#endif
231
#ifdef SK_DAWN
232
        case GrBackendApi::kDawn:
233
            return GrDawnFormatChannels(fDawnFormat);
234
#endif
235
#ifdef SK_DIRECT3D
236
        case GrBackendApi::kDirect3D:
237
            return GrDxgiFormatChannels(fDxgiFormat);
238
#endif
239
0
        case GrBackendApi::kMock:
240
0
            return GrColorTypeChannelFlags(fMock.fColorType);
241
242
0
        default:
243
0
            return 0;
244
0
    }
245
0
}
246
247
0
GrColorFormatDesc GrBackendFormat::desc() const {
248
0
    if (!this->isValid()) {
249
0
        return GrColorFormatDesc::MakeInvalid();
250
0
    }
251
0
    switch (fBackend) {
252
0
#ifdef SK_GL
253
0
        case GrBackendApi::kOpenGL:
254
0
            return GrGLFormatDesc(GrGLFormatFromGLEnum(fGLFormat));
255
0
#endif
256
#ifdef SK_VULKAN
257
        case GrBackendApi::kVulkan:
258
            return GrVkFormatDesc(fVk.fFormat);
259
#endif
260
#ifdef SK_METAL
261
       case GrBackendApi::kMetal:
262
            return GrMtlFormatDesc(fMtlFormat);
263
#endif
264
#ifdef SK_DAWN
265
        case GrBackendApi::kDawn:
266
            return GrDawnFormatDesc(fDawnFormat);
267
#endif
268
#ifdef SK_DIRECT3D
269
        case GrBackendApi::kDirect3D:
270
            return GrDxgiFormatDesc(fDxgiFormat);
271
#endif
272
0
        case GrBackendApi::kMock:
273
0
            return GrGetColorTypeDesc(fMock.fColorType);
274
275
0
        default:
276
0
            return GrColorFormatDesc::MakeInvalid();
277
0
    }
278
0
}
279
280
#ifdef SK_DEBUG
281
0
bool GrBackendFormat::validateMock() const {
282
0
    int trueStates = 0;
283
0
    if (fMock.fCompressionType != SkImage::CompressionType::kNone) {
284
0
        trueStates++;
285
0
    }
286
0
    if (fMock.fColorType != GrColorType::kUnknown) {
287
0
        trueStates++;
288
0
    }
289
0
    if (fMock.fIsStencilFormat) {
290
0
        trueStates++;
291
0
    }
292
0
    return trueStates == 1;
293
0
}
294
#endif
295
296
1.48M
GrColorType GrBackendFormat::asMockColorType() const {
297
1.48M
    if (this->isValid() && GrBackendApi::kMock == fBackend) {
298
1.48M
        SkASSERT(this->validateMock());
299
1.48M
        return fMock.fColorType;
300
1.48M
    }
301
302
673
    return GrColorType::kUnknown;
303
673
}
304
305
1.98M
SkImage::CompressionType GrBackendFormat::asMockCompressionType() const {
306
1.98M
    if (this->isValid() && GrBackendApi::kMock == fBackend) {
307
1.98M
        SkASSERT(this->validateMock());
308
1.98M
        return fMock.fCompressionType;
309
1.98M
    }
310
311
673
    return SkImage::CompressionType::kNone;
312
673
}
313
314
73.3k
bool GrBackendFormat::isMockStencilFormat() const {
315
73.3k
    if (this->isValid() && GrBackendApi::kMock == fBackend) {
316
73.3k
        SkASSERT(this->validateMock());
317
73.3k
        return fMock.fIsStencilFormat;
318
73.3k
    }
319
320
0
    return false;
321
0
}
322
323
11.3k
GrBackendFormat GrBackendFormat::makeTexture2D() const {
324
11.3k
    GrBackendFormat copy = *this;
325
11.3k
    if (const GrVkYcbcrConversionInfo* ycbcrInfo = this->getVkYcbcrConversionInfo()) {
326
0
        if (ycbcrInfo->isValid()) {
327
            // If we have a ycbcr we remove it from the backend format and set the VkFormat to
328
            // R8G8B8A8_UNORM
329
0
            SkASSERT(copy.fBackend == GrBackendApi::kVulkan);
330
0
            copy.fVk.fYcbcrConversionInfo = GrVkYcbcrConversionInfo();
331
0
            copy.fVk.fFormat = VK_FORMAT_R8G8B8A8_UNORM;
332
0
        }
333
0
    }
334
11.3k
    copy.fTextureType = GrTextureType::k2D;
335
11.3k
    return copy;
336
11.3k
}
337
338
GrBackendFormat GrBackendFormat::MakeMock(GrColorType colorType,
339
                                          SkImage::CompressionType compression,
340
499k
                                          bool isStencilFormat) {
341
499k
    return GrBackendFormat(colorType, compression, isStencilFormat);
342
499k
}
343
344
17.7k
bool GrBackendFormat::operator==(const GrBackendFormat& that) const {
345
    // Invalid GrBackendFormats are never equal to anything.
346
17.7k
    if (!fValid || !that.fValid) {
347
0
        return false;
348
0
    }
349
350
17.7k
    if (fBackend != that.fBackend) {
351
0
        return false;
352
0
    }
353
354
17.7k
    switch (fBackend) {
355
0
#ifdef SK_GL
356
0
        case GrBackendApi::kOpenGL:
357
0
            return fGLFormat == that.fGLFormat;
358
0
            break;
359
0
#endif
360
#ifdef SK_VULKAN
361
        case GrBackendApi::kVulkan:
362
            return fVk.fFormat == that.fVk.fFormat &&
363
                   fVk.fYcbcrConversionInfo == that.fVk.fYcbcrConversionInfo;
364
            break;
365
#endif
366
#ifdef SK_METAL
367
        case GrBackendApi::kMetal:
368
            return fMtlFormat == that.fMtlFormat;
369
            break;
370
#endif
371
#ifdef SK_DAWN
372
        case GrBackendApi::kDawn:
373
            return fDawnFormat == that.fDawnFormat;
374
            break;
375
#endif
376
17.7k
        case GrBackendApi::kMock:
377
17.7k
            return fMock.fColorType == that.fMock.fColorType &&
378
17.6k
                   fMock.fCompressionType == that.fMock.fCompressionType;
379
#ifdef SK_DIRECT3D
380
        case GrBackendApi::kDirect3D:
381
            return fDxgiFormat == that.fDxgiFormat;
382
#endif
383
0
        default:
384
0
            SK_ABORT("Unknown GrBackend");
385
17.7k
    }
386
0
    return false;
387
17.7k
}
388
389
#if defined(SK_DEBUG) || GR_TEST_UTILS
390
#include "include/core/SkString.h"
391
392
#ifdef SK_GL
393
#include "src/gpu/gl/GrGLUtil.h"
394
#endif
395
#ifdef SK_VULKAN
396
#include "src/gpu/vk/GrVkUtil.h"
397
#endif
398
399
0
SkString GrBackendFormat::toStr() const {
400
0
    SkString str;
401
402
0
    if (!fValid) {
403
0
        str.append("invalid");
404
0
        return str;
405
0
    }
406
407
0
    str.appendf("%s-", GrBackendApiToStr(fBackend));
408
409
0
    switch (fBackend) {
410
0
        case GrBackendApi::kOpenGL:
411
0
#ifdef SK_GL
412
0
            str.append(GrGLFormatToStr(fGLFormat));
413
0
#endif
414
0
            break;
415
0
        case GrBackendApi::kVulkan:
416
#ifdef SK_VULKAN
417
            str.append(GrVkFormatToStr(fVk.fFormat));
418
#endif
419
0
            break;
420
0
        case GrBackendApi::kMetal:
421
#ifdef SK_METAL
422
            str.append(GrMtlFormatToStr(fMtlFormat));
423
#endif
424
0
            break;
425
0
        case GrBackendApi::kDirect3D:
426
#ifdef SK_DIRECT3D
427
            str.append(GrDxgiFormatToStr(fDxgiFormat));
428
#endif
429
0
            break;
430
0
        case GrBackendApi::kDawn:
431
#ifdef SK_DAWN
432
            str.append(GrDawnFormatToStr(fDawnFormat));
433
#endif
434
0
            break;
435
0
        case GrBackendApi::kMock:
436
0
            str.append(GrColorTypeToStr(fMock.fColorType));
437
0
            str.appendf("-");
438
0
            str.append(GrCompressionTypeToStr(fMock.fCompressionType));
439
0
            break;
440
0
    }
441
442
0
    return str;
443
0
}
444
#endif
445
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447
0
GrBackendTexture::GrBackendTexture() : fIsValid(false) {}
448
449
#ifdef SK_DAWN
450
GrBackendTexture::GrBackendTexture(int width,
451
                                   int height,
452
                                   const GrDawnTextureInfo& dawnInfo)
453
        : fIsValid(true)
454
        , fWidth(width)
455
        , fHeight(height)
456
        , fMipmapped(GrMipmapped(dawnInfo.fLevelCount > 1))
457
        , fBackend(GrBackendApi::kDawn)
458
        , fTextureType(GrTextureType::k2D)
459
        , fDawnInfo(dawnInfo) {}
460
#endif
461
462
#ifdef SK_VULKAN
463
GrBackendTexture::GrBackendTexture(int width, int height, const GrVkImageInfo& vkInfo)
464
        : GrBackendTexture(width, height, vkInfo,
465
                           sk_sp<GrBackendSurfaceMutableStateImpl>(
466
                                   new GrBackendSurfaceMutableStateImpl(
467
                                        vkInfo.fImageLayout, vkInfo.fCurrentQueueFamily))) {}
468
469
static const VkImageUsageFlags kDefaultUsageFlags =
470
        VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
471
472
// We don't know if the backend texture is made renderable or not, so we default the usage flags
473
// to include color attachment as well.
474
static const VkImageUsageFlags kDefaultTexRTUsageFlags =
475
        kDefaultUsageFlags | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
476
477
static GrVkImageInfo apply_default_usage_flags(const GrVkImageInfo& info,
478
                                               VkImageUsageFlags defaultFlags) {
479
    if (info.fImageUsageFlags == 0) {
480
        GrVkImageInfo newInfo = info;
481
        newInfo.fImageUsageFlags = defaultFlags;
482
        return newInfo;
483
    }
484
    return info;
485
}
486
487
static GrTextureType vk_image_info_to_texture_type(const GrVkImageInfo& info) {
488
    if (info.fYcbcrConversionInfo.isValid() && info.fYcbcrConversionInfo.fExternalFormat != 0) {
489
        return GrTextureType::kExternal;
490
    }
491
    return GrTextureType::k2D;
492
}
493
494
GrBackendTexture::GrBackendTexture(int width,
495
                                   int height,
496
                                   const GrVkImageInfo& vkInfo,
497
                                   sk_sp<GrBackendSurfaceMutableStateImpl> mutableState)
498
        : fIsValid(true)
499
        , fWidth(width)
500
        , fHeight(height)
501
        , fMipmapped(GrMipmapped(vkInfo.fLevelCount > 1))
502
        , fBackend(GrBackendApi::kVulkan)
503
        , fTextureType(vk_image_info_to_texture_type(vkInfo))
504
        , fVkInfo(apply_default_usage_flags(vkInfo, kDefaultTexRTUsageFlags))
505
        , fMutableState(std::move(mutableState)) {}
506
#endif
507
508
#ifdef SK_GL
509
GrBackendTexture::GrBackendTexture(int width,
510
                                   int height,
511
                                   GrMipmapped mipmapped,
512
                                   const GrGLTextureInfo glInfo,
513
                                   sk_sp<GrGLTextureParameters> params)
514
        : fIsValid(true)
515
        , fWidth(width)
516
        , fHeight(height)
517
        , fMipmapped(mipmapped)
518
        , fBackend(GrBackendApi::kOpenGL)
519
        , fTextureType(gl_target_to_gr_target(glInfo.fTarget))
520
0
        , fGLInfo(glInfo, params.release()) {}
521
522
0
sk_sp<GrGLTextureParameters> GrBackendTexture::getGLTextureParams() const {
523
0
    if (fBackend != GrBackendApi::kOpenGL) {
524
0
        return nullptr;
525
0
    }
526
0
    return fGLInfo.refParameters();
527
0
}
528
#endif
529
530
#ifdef SK_METAL
531
GrBackendTexture::GrBackendTexture(int width,
532
                                   int height,
533
                                   GrMipmapped mipmapped,
534
                                   const GrMtlTextureInfo& mtlInfo)
535
        : fIsValid(true)
536
        , fWidth(width)
537
        , fHeight(height)
538
        , fMipmapped(mipmapped)
539
        , fBackend(GrBackendApi::kMetal)
540
        , fTextureType(GrTextureType::k2D)
541
        , fMtlInfo(mtlInfo) {}
542
#endif
543
544
#ifdef SK_DIRECT3D
545
GrBackendTexture::GrBackendTexture(int width, int height, const GrD3DTextureResourceInfo& d3dInfo)
546
        : GrBackendTexture(
547
                width, height, d3dInfo,
548
                sk_sp<GrD3DResourceState>(new GrD3DResourceState(
549
                        static_cast<D3D12_RESOURCE_STATES>(d3dInfo.fResourceState)))) {}
550
551
GrBackendTexture::GrBackendTexture(int width,
552
                                   int height,
553
                                   const GrD3DTextureResourceInfo& d3dInfo,
554
                                   sk_sp<GrD3DResourceState> state)
555
        : fIsValid(true)
556
        , fWidth(width)
557
        , fHeight(height)
558
        , fMipmapped(GrMipmapped(d3dInfo.fLevelCount > 1))
559
        , fBackend(GrBackendApi::kDirect3D)
560
        , fTextureType(GrTextureType::k2D)
561
        , fD3DInfo(d3dInfo, state.release()) {}
562
#endif
563
564
#ifdef SK_GL
565
GrBackendTexture::GrBackendTexture(int width,
566
                                   int height,
567
                                   GrMipmapped mipmapped,
568
                                   const GrGLTextureInfo& glInfo)
569
0
        : GrBackendTexture(width, height, mipmapped, glInfo, sk_make_sp<GrGLTextureParameters>()) {
570
    // Make no assumptions about client's texture's parameters.
571
0
    this->glTextureParametersModified();
572
0
}
573
#endif
574
575
GrBackendTexture::GrBackendTexture(int width,
576
                                   int height,
577
                                   GrMipmapped mipmapped,
578
                                   const GrMockTextureInfo& mockInfo)
579
        : fIsValid(true)
580
        , fWidth(width)
581
        , fHeight(height)
582
        , fMipmapped(mipmapped)
583
        , fBackend(GrBackendApi::kMock)
584
        , fTextureType(GrTextureType::k2D)
585
0
        , fMockInfo(mockInfo) {}
586
587
0
GrBackendTexture::~GrBackendTexture() {
588
0
    this->cleanup();
589
0
}
590
591
0
void GrBackendTexture::cleanup() {
592
0
#ifdef SK_GL
593
0
    if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
594
0
        fGLInfo.cleanup();
595
0
    }
596
0
#endif
597
#ifdef SK_VULKAN
598
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
599
        fVkInfo.cleanup();
600
    }
601
#endif
602
#ifdef SK_DIRECT3D
603
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
604
        fD3DInfo.cleanup();
605
    }
606
#endif
607
0
}
608
609
0
GrBackendTexture::GrBackendTexture(const GrBackendTexture& that) : fIsValid(false) {
610
0
    *this = that;
611
0
}
612
613
0
GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
614
0
    if (!that.isValid()) {
615
0
        this->cleanup();
616
0
        fIsValid = false;
617
0
        return *this;
618
0
    } else if (fIsValid && this->fBackend != that.fBackend) {
619
0
        this->cleanup();
620
0
        fIsValid = false;
621
0
    }
622
0
    fWidth = that.fWidth;
623
0
    fHeight = that.fHeight;
624
0
    fMipmapped = that.fMipmapped;
625
0
    fBackend = that.fBackend;
626
0
    fTextureType = that.fTextureType;
627
628
0
    switch (that.fBackend) {
629
0
#ifdef SK_GL
630
0
        case GrBackendApi::kOpenGL:
631
0
            fGLInfo.assign(that.fGLInfo, this->isValid());
632
0
            break;
633
0
#endif
634
#ifdef SK_VULKAN
635
        case GrBackendApi::kVulkan:
636
            fVkInfo.assign(that.fVkInfo, this->isValid());
637
            break;
638
#endif
639
#ifdef SK_METAL
640
        case GrBackendApi::kMetal:
641
            fMtlInfo = that.fMtlInfo;
642
            break;
643
#endif
644
#ifdef SK_DIRECT3D
645
        case GrBackendApi::kDirect3D:
646
            fD3DInfo.assign(that.fD3DInfo, this->isValid());
647
            break;
648
#endif
649
#ifdef SK_DAWN
650
        case GrBackendApi::kDawn:
651
            fDawnInfo = that.fDawnInfo;
652
            break;
653
#endif
654
0
        case GrBackendApi::kMock:
655
0
            fMockInfo = that.fMockInfo;
656
0
            break;
657
0
        default:
658
0
            SK_ABORT("Unknown GrBackend");
659
0
    }
660
0
    fMutableState = that.fMutableState;
661
0
    fIsValid = true;
662
0
    return *this;
663
0
}
664
665
0
sk_sp<GrBackendSurfaceMutableStateImpl> GrBackendTexture::getMutableState() const {
666
0
    return fMutableState;
667
0
}
668
669
#ifdef SK_DAWN
670
bool GrBackendTexture::getDawnTextureInfo(GrDawnTextureInfo* outInfo) const {
671
    if (this->isValid() && GrBackendApi::kDawn == fBackend) {
672
        *outInfo = fDawnInfo;
673
        return true;
674
    }
675
    return false;
676
}
677
#endif
678
679
0
bool GrBackendTexture::getVkImageInfo(GrVkImageInfo* outInfo) const {
680
#ifdef SK_VULKAN
681
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
682
        *outInfo = fVkInfo.snapImageInfo(fMutableState.get());
683
        return true;
684
    }
685
#endif
686
0
    return false;
687
0
}
688
689
0
void GrBackendTexture::setVkImageLayout(VkImageLayout layout) {
690
#ifdef SK_VULKAN
691
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
692
        fMutableState->setImageLayout(layout);
693
    }
694
#endif
695
0
}
696
697
#ifdef SK_METAL
698
bool GrBackendTexture::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
699
    if (this->isValid() && GrBackendApi::kMetal == fBackend) {
700
        *outInfo = fMtlInfo;
701
        return true;
702
    }
703
    return false;
704
}
705
#endif
706
707
#ifdef SK_DIRECT3D
708
bool GrBackendTexture::getD3DTextureResourceInfo(GrD3DTextureResourceInfo* outInfo) const {
709
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
710
        *outInfo = fD3DInfo.snapTextureResourceInfo();
711
        return true;
712
    }
713
    return false;
714
}
715
716
void GrBackendTexture::setD3DResourceState(GrD3DResourceStateEnum state) {
717
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
718
        fD3DInfo.setResourceState(state);
719
    }
720
}
721
722
sk_sp<GrD3DResourceState> GrBackendTexture::getGrD3DResourceState() const {
723
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
724
        return fD3DInfo.getGrD3DResourceState();
725
    }
726
    return nullptr;
727
}
728
#endif
729
730
0
bool GrBackendTexture::getGLTextureInfo(GrGLTextureInfo* outInfo) const {
731
0
#ifdef SK_GL
732
0
    if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
733
0
        *outInfo = fGLInfo.info();
734
0
        return true;
735
0
    } else if (this->isValid() && GrBackendApi::kMock == fBackend) {
736
        // Hack! This allows some blink unit tests to work when using the Mock GrContext.
737
        // Specifically, tests that rely on CanvasResourceProviderTextureGpuMemoryBuffer.
738
        // If that code ever goes away (or ideally becomes backend-agnostic), this can go away.
739
0
        *outInfo = GrGLTextureInfo{ GR_GL_TEXTURE_2D,
740
0
                                    static_cast<GrGLuint>(fMockInfo.id()),
741
0
                                    GR_GL_RGBA8 };
742
0
        return true;
743
0
    }
744
0
#endif
745
0
    return false;
746
0
}
747
748
0
void GrBackendTexture::glTextureParametersModified() {
749
0
#ifdef SK_GL
750
0
    if (this->isValid() && fBackend == GrBackendApi::kOpenGL) {
751
0
        fGLInfo.parameters()->invalidate();
752
0
    }
753
0
#endif
754
0
}
755
756
0
bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const {
757
0
    if (this->isValid() && GrBackendApi::kMock == fBackend) {
758
0
        *outInfo = fMockInfo;
759
0
        return true;
760
0
    }
761
0
    return false;
762
0
}
763
764
0
void GrBackendTexture::setMutableState(const GrBackendSurfaceMutableState& state) {
765
0
    fMutableState->set(state);
766
0
}
767
768
0
bool GrBackendTexture::isProtected() const {
769
0
    if (!this->isValid() || this->backend() != GrBackendApi::kVulkan) {
770
0
        return false;
771
0
    }
772
0
    return fVkInfo.isProtected();
773
0
}
774
775
0
bool GrBackendTexture::isSameTexture(const GrBackendTexture& that) {
776
0
    if (!this->isValid() || !that.isValid()) {
777
0
        return false;
778
0
    }
779
0
    if (fBackend != that.fBackend) {
780
0
        return false;
781
0
    }
782
0
    switch (fBackend) {
783
0
#ifdef SK_GL
784
0
        case GrBackendApi::kOpenGL:
785
0
            return fGLInfo.info().fID == that.fGLInfo.info().fID;
786
0
#endif
787
#ifdef SK_VULKAN
788
        case GrBackendApi::kVulkan:
789
            return fVkInfo.snapImageInfo(fMutableState.get()).fImage ==
790
                   that.fVkInfo.snapImageInfo(that.fMutableState.get()).fImage;
791
#endif
792
#ifdef SK_METAL
793
        case GrBackendApi::kMetal:
794
            return this->fMtlInfo.fTexture == that.fMtlInfo.fTexture;
795
#endif
796
#ifdef SK_DIRECT3D
797
        case GrBackendApi::kDirect3D:
798
            return fD3DInfo.snapTextureResourceInfo().fResource ==
799
                    that.fD3DInfo.snapTextureResourceInfo().fResource;
800
#endif
801
#ifdef SK_DAWN
802
        case GrBackendApi::kDawn: {
803
            return this->fDawnInfo.fTexture.Get() == that.fDawnInfo.fTexture.Get();
804
        }
805
#endif
806
0
        case GrBackendApi::kMock:
807
0
            return fMockInfo.id() == that.fMockInfo.id();
808
0
        default:
809
0
            return false;
810
0
    }
811
0
}
812
813
0
GrBackendFormat GrBackendTexture::getBackendFormat() const {
814
0
    if (!this->isValid()) {
815
0
        return GrBackendFormat();
816
0
    }
817
0
    switch (fBackend) {
818
0
#ifdef SK_GL
819
0
        case GrBackendApi::kOpenGL:
820
0
            return GrBackendFormat::MakeGL(fGLInfo.info().fFormat, fGLInfo.info().fTarget);
821
0
#endif
822
#ifdef SK_VULKAN
823
        case GrBackendApi::kVulkan: {
824
            auto info = fVkInfo.snapImageInfo(fMutableState.get());
825
            if (info.fYcbcrConversionInfo.isValid()) {
826
                SkASSERT(info.fFormat == info.fYcbcrConversionInfo.fFormat);
827
                return GrBackendFormat::MakeVk(info.fYcbcrConversionInfo);
828
            }
829
            return GrBackendFormat::MakeVk(info.fFormat);
830
        }
831
#endif
832
#ifdef SK_METAL
833
        case GrBackendApi::kMetal: {
834
            GrMtlTextureInfo mtlInfo;
835
            SkAssertResult(this->getMtlTextureInfo(&mtlInfo));
836
            return GrBackendFormat::MakeMtl(GrGetMTLPixelFormatFromMtlTextureInfo(mtlInfo));
837
        }
838
#endif
839
#ifdef SK_DIRECT3D
840
        case GrBackendApi::kDirect3D: {
841
            auto d3dInfo = fD3DInfo.snapTextureResourceInfo();
842
            return GrBackendFormat::MakeDxgi(d3dInfo.fFormat);
843
        }
844
#endif
845
#ifdef SK_DAWN
846
        case GrBackendApi::kDawn: {
847
            return GrBackendFormat::MakeDawn(fDawnInfo.fFormat);
848
        }
849
#endif
850
0
        case GrBackendApi::kMock:
851
0
            return fMockInfo.getBackendFormat();
852
0
        default:
853
0
            return GrBackendFormat();
854
0
    }
855
0
}
856
857
#if GR_TEST_UTILS
858
0
bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBackendTexture& t1) {
859
0
    if (!t0.isValid() || !t1.isValid()) {
860
0
        return false; // two invalid backend textures are not considered equal
861
0
    }
862
863
0
    if (t0.fWidth != t1.fWidth ||
864
0
        t0.fHeight != t1.fHeight ||
865
0
        t0.fMipmapped != t1.fMipmapped ||
866
0
        t0.fBackend != t1.fBackend) {
867
0
        return false;
868
0
    }
869
870
    // For our tests when checking equality we are assuming the both backendTexture objects will
871
    // be using the same mutable state object.
872
0
    if (t0.fMutableState != t1.fMutableState) {
873
0
        return false;
874
0
    }
875
876
0
    switch (t0.fBackend) {
877
0
#ifdef SK_GL
878
0
        case GrBackendApi::kOpenGL:
879
0
            return t0.fGLInfo.info() == t1.fGLInfo.info();
880
0
#endif
881
0
        case GrBackendApi::kMock:
882
0
            return t0.fMockInfo == t1.fMockInfo;
883
#ifdef SK_VULKAN
884
        case GrBackendApi::kVulkan:
885
            return t0.fVkInfo == t1.fVkInfo;
886
#endif
887
#ifdef SK_METAL
888
        case GrBackendApi::kMetal:
889
            return t0.fMtlInfo == t1.fMtlInfo;
890
#endif
891
#ifdef SK_DIRECT3D
892
        case GrBackendApi::kDirect3D:
893
            return t0.fD3DInfo == t1.fD3DInfo;
894
#endif
895
#ifdef SK_DAWN
896
        case GrBackendApi::kDawn:
897
            return t0.fDawnInfo == t1.fDawnInfo;
898
#endif
899
0
        default:
900
0
            return false;
901
0
    }
902
0
}
903
#endif
904
905
////////////////////////////////////////////////////////////////////////////////////////////////////
906
907
0
GrBackendRenderTarget::GrBackendRenderTarget() : fIsValid(false) {}
908
909
910
#ifdef SK_DAWN
911
GrBackendRenderTarget::GrBackendRenderTarget(int width,
912
                                             int height,
913
                                             int sampleCnt,
914
                                             int stencilBits,
915
                                             const GrDawnRenderTargetInfo& dawnInfo)
916
        : fIsValid(true)
917
        , fFramebufferOnly(true)
918
        , fWidth(width)
919
        , fHeight(height)
920
        , fSampleCnt(sampleCnt)
921
        , fStencilBits(stencilBits)
922
        , fBackend(GrBackendApi::kDawn)
923
        , fDawnInfo(dawnInfo) {}
924
#endif
925
926
#ifdef SK_VULKAN
927
static GrVkImageInfo resolve_vkii_sample_count(const GrVkImageInfo& vkII, int sidebandSampleCnt) {
928
    auto result = vkII;
929
    result.fSampleCount = std::max({vkII.fSampleCount,
930
                                    static_cast<uint32_t>(sidebandSampleCnt),
931
                                    1U});
932
    return result;
933
}
934
935
GrBackendRenderTarget::GrBackendRenderTarget(int width,
936
                                             int height,
937
                                             int sampleCnt,
938
                                             const GrVkImageInfo& vkInfo)
939
        : GrBackendRenderTarget(width, height, resolve_vkii_sample_count(vkInfo, sampleCnt)) {}
940
941
GrBackendRenderTarget::GrBackendRenderTarget(int width,
942
                                             int height,
943
                                             const GrVkImageInfo& vkInfo)
944
        : GrBackendRenderTarget(width, height, vkInfo,
945
                                sk_sp<GrBackendSurfaceMutableStateImpl>(
946
                                        new GrBackendSurfaceMutableStateImpl(
947
                                                vkInfo.fImageLayout, vkInfo.fCurrentQueueFamily))) {}
948
949
static const VkImageUsageFlags kDefaultRTUsageFlags =
950
        kDefaultUsageFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
951
952
GrBackendRenderTarget::GrBackendRenderTarget(int width,
953
                                             int height,
954
                                             const GrVkImageInfo& vkInfo,
955
                                             sk_sp<GrBackendSurfaceMutableStateImpl> mutableState)
956
        : fIsValid(true)
957
        , fWidth(width)
958
        , fHeight(height)
959
        , fSampleCnt(std::max(1U, vkInfo.fSampleCount))
960
        , fStencilBits(0)  // We always create stencil buffers internally for vulkan
961
        , fBackend(GrBackendApi::kVulkan)
962
        , fVkInfo(apply_default_usage_flags(vkInfo, kDefaultRTUsageFlags))
963
        , fMutableState(mutableState) {}
964
#endif
965
966
#ifdef SK_METAL
967
GrBackendRenderTarget::GrBackendRenderTarget(int width, int height, const GrMtlTextureInfo& mtlInfo)
968
        : fIsValid(true)
969
        , fFramebufferOnly(false)  // TODO: set this from mtlInfo.fTexture->framebufferOnly
970
        , fWidth(width)
971
        , fHeight(height)
972
        , fSampleCnt(std::max(1, GrMtlTextureInfoSampleCount(mtlInfo)))
973
        , fStencilBits(0)
974
        , fBackend(GrBackendApi::kMetal)
975
        , fMtlInfo(mtlInfo) {}
976
977
GrBackendRenderTarget::GrBackendRenderTarget(int width, int height,
978
                                             int sampleCount,
979
                                             const GrMtlTextureInfo& mtlInfo)
980
        : GrBackendRenderTarget(width, height, mtlInfo) {
981
    fSampleCnt = sampleCount;
982
}
983
#endif
984
985
#ifdef SK_DIRECT3D
986
GrBackendRenderTarget::GrBackendRenderTarget(int width, int height,
987
                                             const GrD3DTextureResourceInfo& d3dInfo)
988
        : GrBackendRenderTarget(
989
                width, height, d3dInfo,
990
                sk_sp<GrD3DResourceState>(new GrD3DResourceState(
991
                        static_cast<D3D12_RESOURCE_STATES>(d3dInfo.fResourceState)))) {}
992
993
GrBackendRenderTarget::GrBackendRenderTarget(int width,
994
                                             int height,
995
                                             const GrD3DTextureResourceInfo& d3dInfo,
996
                                             sk_sp<GrD3DResourceState> state)
997
        : fIsValid(true)
998
        , fWidth(width)
999
        , fHeight(height)
1000
        , fSampleCnt(std::max(1U, d3dInfo.fSampleCount))
1001
        , fStencilBits(0)
1002
        , fBackend(GrBackendApi::kDirect3D)
1003
        , fD3DInfo(d3dInfo, state.release()) {}
1004
#endif
1005
#ifdef SK_GL
1006
GrBackendRenderTarget::GrBackendRenderTarget(int width,
1007
                                             int height,
1008
                                             int sampleCnt,
1009
                                             int stencilBits,
1010
                                             const GrGLFramebufferInfo& glInfo)
1011
        : fWidth(width)
1012
        , fHeight(height)
1013
        , fSampleCnt(std::max(1, sampleCnt))
1014
        , fStencilBits(stencilBits)
1015
        , fBackend(GrBackendApi::kOpenGL)
1016
0
        , fGLInfo(glInfo) {
1017
0
    fIsValid = SkToBool(glInfo.fFormat); // the glInfo must have a valid format
1018
0
}
1019
#endif
1020
1021
GrBackendRenderTarget::GrBackendRenderTarget(int width,
1022
                                             int height,
1023
                                             int sampleCnt,
1024
                                             int stencilBits,
1025
                                             const GrMockRenderTargetInfo& mockInfo)
1026
        : fIsValid(true)
1027
        , fWidth(width)
1028
        , fHeight(height)
1029
        , fSampleCnt(std::max(1, sampleCnt))
1030
        , fStencilBits(stencilBits)
1031
0
        , fMockInfo(mockInfo) {}
1032
1033
0
GrBackendRenderTarget::~GrBackendRenderTarget() {
1034
0
    this->cleanup();
1035
0
}
1036
1037
0
void GrBackendRenderTarget::cleanup() {
1038
#ifdef SK_VULKAN
1039
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
1040
        fVkInfo.cleanup();
1041
    }
1042
#endif
1043
#ifdef SK_DIRECT3D
1044
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
1045
        fD3DInfo.cleanup();
1046
    }
1047
#endif
1048
0
}
1049
1050
0
GrBackendRenderTarget::GrBackendRenderTarget(const GrBackendRenderTarget& that) : fIsValid(false) {
1051
0
    *this = that;
1052
0
}
1053
1054
0
GrBackendRenderTarget& GrBackendRenderTarget::operator=(const GrBackendRenderTarget& that) {
1055
0
    if (!that.isValid()) {
1056
0
        this->cleanup();
1057
0
        fIsValid = false;
1058
0
        return *this;
1059
0
    } else if (fIsValid && this->fBackend != that.fBackend) {
1060
0
        this->cleanup();
1061
0
        fIsValid = false;
1062
0
    }
1063
0
    fWidth = that.fWidth;
1064
0
    fHeight = that.fHeight;
1065
0
    fSampleCnt = that.fSampleCnt;
1066
0
    fStencilBits = that.fStencilBits;
1067
0
    fBackend = that.fBackend;
1068
1069
0
    switch (that.fBackend) {
1070
0
#ifdef SK_GL
1071
0
        case GrBackendApi::kOpenGL:
1072
0
            fGLInfo = that.fGLInfo;
1073
0
            break;
1074
0
#endif
1075
#ifdef SK_VULKAN
1076
        case GrBackendApi::kVulkan:
1077
            fVkInfo.assign(that.fVkInfo, this->isValid());
1078
            break;
1079
#endif
1080
#ifdef SK_METAL
1081
        case GrBackendApi::kMetal:
1082
            fMtlInfo = that.fMtlInfo;
1083
            break;
1084
#endif
1085
#ifdef SK_DIRECT3D
1086
        case GrBackendApi::kDirect3D:
1087
            fD3DInfo.assign(that.fD3DInfo, this->isValid());
1088
            break;
1089
#endif
1090
#ifdef SK_DAWN
1091
        case GrBackendApi::kDawn:
1092
            fDawnInfo = that.fDawnInfo;
1093
            break;
1094
#endif
1095
0
        case GrBackendApi::kMock:
1096
0
            fMockInfo = that.fMockInfo;
1097
0
            break;
1098
0
        default:
1099
0
            SK_ABORT("Unknown GrBackend");
1100
0
    }
1101
0
    fMutableState = that.fMutableState;
1102
0
    fIsValid = that.fIsValid;
1103
0
    return *this;
1104
0
}
1105
1106
0
sk_sp<GrBackendSurfaceMutableStateImpl> GrBackendRenderTarget::getMutableState() const {
1107
0
    return fMutableState;
1108
0
}
1109
1110
#ifdef SK_DAWN
1111
bool GrBackendRenderTarget::getDawnRenderTargetInfo(GrDawnRenderTargetInfo* outInfo) const {
1112
    if (this->isValid() && GrBackendApi::kDawn == fBackend) {
1113
        *outInfo = fDawnInfo;
1114
        return true;
1115
    }
1116
    return false;
1117
}
1118
#endif
1119
1120
0
bool GrBackendRenderTarget::getVkImageInfo(GrVkImageInfo* outInfo) const {
1121
#ifdef SK_VULKAN
1122
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
1123
        *outInfo = fVkInfo.snapImageInfo(fMutableState.get());
1124
        return true;
1125
    }
1126
#endif
1127
0
    return false;
1128
0
}
1129
1130
0
void GrBackendRenderTarget::setVkImageLayout(VkImageLayout layout) {
1131
#ifdef SK_VULKAN
1132
    if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
1133
        fMutableState->setImageLayout(layout);
1134
    }
1135
#endif
1136
0
}
1137
1138
#ifdef SK_METAL
1139
bool GrBackendRenderTarget::getMtlTextureInfo(GrMtlTextureInfo* outInfo) const {
1140
    if (this->isValid() && GrBackendApi::kMetal == fBackend) {
1141
        *outInfo = fMtlInfo;
1142
        return true;
1143
    }
1144
    return false;
1145
}
1146
#endif
1147
1148
#ifdef SK_DIRECT3D
1149
bool GrBackendRenderTarget::getD3DTextureResourceInfo(GrD3DTextureResourceInfo* outInfo) const {
1150
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
1151
        *outInfo = fD3DInfo.snapTextureResourceInfo();
1152
        return true;
1153
    }
1154
    return false;
1155
}
1156
1157
void GrBackendRenderTarget::setD3DResourceState(GrD3DResourceStateEnum state) {
1158
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
1159
        fD3DInfo.setResourceState(state);
1160
    }
1161
}
1162
1163
sk_sp<GrD3DResourceState> GrBackendRenderTarget::getGrD3DResourceState() const {
1164
    if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
1165
        return fD3DInfo.getGrD3DResourceState();
1166
    }
1167
    return nullptr;
1168
}
1169
#endif
1170
1171
#ifdef SK_GL
1172
0
bool GrBackendRenderTarget::getGLFramebufferInfo(GrGLFramebufferInfo* outInfo) const {
1173
0
    if (this->isValid() && GrBackendApi::kOpenGL == fBackend) {
1174
0
        *outInfo = fGLInfo;
1175
0
        return true;
1176
0
    }
1177
0
    return false;
1178
0
}
1179
#endif
1180
1181
0
GrBackendFormat GrBackendRenderTarget::getBackendFormat() const {
1182
0
    if (!this->isValid()) {
1183
0
        return GrBackendFormat();
1184
0
    }
1185
0
    switch (fBackend) {
1186
0
#ifdef SK_GL
1187
0
        case GrBackendApi::kOpenGL:
1188
0
            return GrBackendFormat::MakeGL(fGLInfo.fFormat, GR_GL_TEXTURE_NONE);
1189
0
#endif
1190
#ifdef SK_VULKAN
1191
        case GrBackendApi::kVulkan: {
1192
            auto info = fVkInfo.snapImageInfo(fMutableState.get());
1193
            if (info.fYcbcrConversionInfo.isValid()) {
1194
                SkASSERT(info.fFormat == info.fYcbcrConversionInfo.fFormat);
1195
                return GrBackendFormat::MakeVk(info.fYcbcrConversionInfo);
1196
            }
1197
            return GrBackendFormat::MakeVk(info.fFormat);
1198
        }
1199
#endif
1200
#ifdef SK_METAL
1201
        case GrBackendApi::kMetal: {
1202
            GrMtlTextureInfo mtlInfo;
1203
            SkAssertResult(this->getMtlTextureInfo(&mtlInfo));
1204
            return GrBackendFormat::MakeMtl(GrGetMTLPixelFormatFromMtlTextureInfo(mtlInfo));
1205
        }
1206
#endif
1207
#ifdef SK_DIRECT3D
1208
        case GrBackendApi::kDirect3D: {
1209
            auto info = fD3DInfo.snapTextureResourceInfo();
1210
            return GrBackendFormat::MakeDxgi(info.fFormat);
1211
        }
1212
#endif
1213
#ifdef SK_DAWN
1214
        case GrBackendApi::kDawn: {
1215
            GrDawnRenderTargetInfo dawnInfo;
1216
            SkAssertResult(this->getDawnRenderTargetInfo(&dawnInfo));
1217
            return GrBackendFormat::MakeDawn(dawnInfo.fFormat);
1218
        }
1219
#endif
1220
0
        case GrBackendApi::kMock:
1221
0
            return fMockInfo.getBackendFormat();
1222
0
        default:
1223
0
            return GrBackendFormat();
1224
0
    }
1225
0
}
1226
1227
0
bool GrBackendRenderTarget::getMockRenderTargetInfo(GrMockRenderTargetInfo* outInfo) const {
1228
0
    if (this->isValid() && GrBackendApi::kMock == fBackend) {
1229
0
        *outInfo = fMockInfo;
1230
0
        return true;
1231
0
    }
1232
0
    return false;
1233
0
}
1234
1235
0
void GrBackendRenderTarget::setMutableState(const GrBackendSurfaceMutableState& state) {
1236
0
    fMutableState->set(state);
1237
0
}
1238
1239
0
bool GrBackendRenderTarget::isProtected() const {
1240
0
    if (!this->isValid() || this->backend() != GrBackendApi::kVulkan) {
1241
0
        return false;
1242
0
    }
1243
0
    return fVkInfo.isProtected();
1244
0
}
1245
1246
#if GR_TEST_UTILS
1247
bool GrBackendRenderTarget::TestingOnly_Equals(const GrBackendRenderTarget& r0,
1248
0
                                               const GrBackendRenderTarget& r1) {
1249
0
    if (!r0.isValid() || !r1.isValid()) {
1250
0
        return false; // two invalid backend rendertargets are not considered equal
1251
0
    }
1252
1253
0
    if (r0.fWidth != r1.fWidth ||
1254
0
        r0.fHeight != r1.fHeight ||
1255
0
        r0.fSampleCnt != r1.fSampleCnt ||
1256
0
        r0.fStencilBits != r1.fStencilBits ||
1257
0
        r0.fBackend != r1.fBackend) {
1258
0
        return false;
1259
0
    }
1260
1261
0
    switch (r0.fBackend) {
1262
0
#ifdef SK_GL
1263
0
        case GrBackendApi::kOpenGL:
1264
0
            return r0.fGLInfo == r1.fGLInfo;
1265
0
#endif
1266
0
        case GrBackendApi::kMock:
1267
0
            return r0.fMockInfo == r1.fMockInfo;
1268
#ifdef SK_VULKAN
1269
        case GrBackendApi::kVulkan:
1270
            return r0.fVkInfo == r1.fVkInfo;
1271
#endif
1272
#ifdef SK_METAL
1273
        case GrBackendApi::kMetal:
1274
            return r0.fMtlInfo == r1.fMtlInfo;
1275
#endif
1276
#ifdef SK_DIRECT3D
1277
        case GrBackendApi::kDirect3D:
1278
            return r0.fD3DInfo == r1.fD3DInfo;
1279
#endif
1280
#ifdef SK_DAWN
1281
        case GrBackendApi::kDawn:
1282
            return r0.fDawnInfo == r1.fDawnInfo;
1283
#endif
1284
0
        default:
1285
0
            return false;
1286
0
    }
1287
1288
0
    SkASSERT(0);
1289
0
    return false;
1290
0
}
Unexecuted instantiation: GrBackendRenderTarget::TestingOnly_Equals(GrBackendRenderTarget const&, GrBackendRenderTarget const&)
Unexecuted instantiation: GrBackendRenderTarget::TestingOnly_Equals(GrBackendRenderTarget const&, GrBackendRenderTarget const&)
1291
#endif