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