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