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