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