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/core/SkTextureCompressionType.h"
11 #include "include/gpu/GrTypes.h"
12 #include "include/gpu/MutableTextureState.h" // IWYU pragma: keep
13 #include "include/private/base/SkAssert.h"
14 #include "include/private/gpu/ganesh/GrTypesPriv.h"
15 #include "src/gpu/GpuTypesPriv.h"
16 #include "src/gpu/ganesh/GrBackendSurfacePriv.h"
17
18 #ifdef SK_DIRECT3D
19 #include "include/gpu/d3d/GrD3DTypes.h"
20 #include "src/gpu/ganesh/d3d/GrD3DResourceState.h"
21 #include "src/gpu/ganesh/d3d/GrD3DUtil.h"
22 #endif
23
24 #include <algorithm>
25 #include <new>
26
GrBackendFormat()27 GrBackendFormat::GrBackendFormat() : fValid(false) {}
28 GrBackendFormat::~GrBackendFormat() = default;
29
GrBackendFormat(const GrBackendFormat & that)30 GrBackendFormat::GrBackendFormat(const GrBackendFormat& that)
31 : fBackend(that.fBackend)
32 , fValid(that.fValid)
33 , fTextureType(that.fTextureType) {
34 if (!fValid) {
35 return;
36 }
37
38 switch (fBackend) {
39 case GrBackendApi::kOpenGL:
40 case GrBackendApi::kVulkan:
41 case GrBackendApi::kMetal:
42 fFormatData.reset();
43 that.fFormatData->copyTo(fFormatData);
44 break; // fFormatData is sufficient
45 #ifdef SK_DIRECT3D
46 case GrBackendApi::kDirect3D:
47 fDxgiFormat = that.fDxgiFormat;
48 break;
49 #endif
50 case GrBackendApi::kMock:
51 fMock = that.fMock;
52 break;
53 default:
54 SK_ABORT("Unknown GrBackend");
55 }
56 }
57
operator =(const GrBackendFormat & that)58 GrBackendFormat& GrBackendFormat::operator=(const GrBackendFormat& that) {
59 if (this != &that) {
60 this->~GrBackendFormat();
61 new (this) GrBackendFormat(that);
62 }
63 return *this;
64 }
65
66 #ifdef SK_DIRECT3D
GrBackendFormat(DXGI_FORMAT dxgiFormat)67 GrBackendFormat::GrBackendFormat(DXGI_FORMAT dxgiFormat)
68 : fBackend(GrBackendApi::kDirect3D)
69 , fValid(true)
70 , fDxgiFormat(dxgiFormat)
71 , fTextureType(GrTextureType::k2D) {
72 }
73
asDxgiFormat(DXGI_FORMAT * dxgiFormat) const74 bool GrBackendFormat::asDxgiFormat(DXGI_FORMAT* dxgiFormat) const {
75 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
76 *dxgiFormat = fDxgiFormat;
77 return true;
78 }
79 return false;
80 }
81 #endif
82
GrBackendFormat(GrColorType colorType,SkTextureCompressionType compression,bool isStencilFormat)83 GrBackendFormat::GrBackendFormat(GrColorType colorType, SkTextureCompressionType compression,
84 bool isStencilFormat)
85 : fBackend(GrBackendApi::kMock)
86 , fValid(true)
87 , fTextureType(GrTextureType::k2D) {
88 fMock.fColorType = colorType;
89 fMock.fCompressionType = compression;
90 fMock.fIsStencilFormat = isStencilFormat;
91 SkASSERT(this->validateMock());
92 }
93
channelMask() const94 uint32_t GrBackendFormat::channelMask() const {
95 if (!this->isValid()) {
96 return 0;
97 }
98 switch (fBackend) {
99 case GrBackendApi::kOpenGL:
100 case GrBackendApi::kVulkan:
101 case GrBackendApi::kMetal:
102 return fFormatData->channelMask();
103 #ifdef SK_DIRECT3D
104 case GrBackendApi::kDirect3D:
105 return GrDxgiFormatChannels(fDxgiFormat);
106 #endif
107 case GrBackendApi::kMock:
108 return GrColorTypeChannelFlags(fMock.fColorType);
109
110 default:
111 return 0;
112 }
113 }
114
desc() const115 GrColorFormatDesc GrBackendFormat::desc() const {
116 if (!this->isValid()) {
117 return GrColorFormatDesc::MakeInvalid();
118 }
119 switch (fBackend) {
120 case GrBackendApi::kOpenGL:
121 case GrBackendApi::kVulkan:
122 case GrBackendApi::kMetal:
123 return fFormatData->desc();
124 #ifdef SK_DIRECT3D
125 case GrBackendApi::kDirect3D:
126 return GrDxgiFormatDesc(fDxgiFormat);
127 #endif
128 case GrBackendApi::kMock:
129 return GrGetColorTypeDesc(fMock.fColorType);
130
131 default:
132 return GrColorFormatDesc::MakeInvalid();
133 }
134 }
135
136 #ifdef SK_DEBUG
validateMock() const137 bool GrBackendFormat::validateMock() const {
138 int trueStates = 0;
139 if (fMock.fCompressionType != SkTextureCompressionType::kNone) {
140 trueStates++;
141 }
142 if (fMock.fColorType != GrColorType::kUnknown) {
143 trueStates++;
144 }
145 if (fMock.fIsStencilFormat) {
146 trueStates++;
147 }
148 return trueStates == 1;
149 }
150 #endif
151
asMockColorType() const152 GrColorType GrBackendFormat::asMockColorType() const {
153 if (this->isValid() && GrBackendApi::kMock == fBackend) {
154 SkASSERT(this->validateMock());
155 return fMock.fColorType;
156 }
157
158 return GrColorType::kUnknown;
159 }
160
asMockCompressionType() const161 SkTextureCompressionType GrBackendFormat::asMockCompressionType() const {
162 if (this->isValid() && GrBackendApi::kMock == fBackend) {
163 SkASSERT(this->validateMock());
164 return fMock.fCompressionType;
165 }
166
167 return SkTextureCompressionType::kNone;
168 }
169
isMockStencilFormat() const170 bool GrBackendFormat::isMockStencilFormat() const {
171 if (this->isValid() && GrBackendApi::kMock == fBackend) {
172 SkASSERT(this->validateMock());
173 return fMock.fIsStencilFormat;
174 }
175
176 return false;
177 }
178
makeTexture2D() const179 GrBackendFormat GrBackendFormat::makeTexture2D() const {
180 GrBackendFormat copy = *this;
181 // TODO(b/293490566): Remove this kVulkan check once all backends are using fFormatData.
182 if (fBackend==GrBackendApi::kVulkan) {
183 copy.fFormatData->makeTexture2D();
184 }
185 copy.fTextureType = GrTextureType::k2D;
186 return copy;
187 }
188
MakeMock(GrColorType colorType,SkTextureCompressionType compression,bool isStencilFormat)189 GrBackendFormat GrBackendFormat::MakeMock(GrColorType colorType,
190 SkTextureCompressionType compression,
191 bool isStencilFormat) {
192 return GrBackendFormat(colorType, compression, isStencilFormat);
193 }
194
operator ==(const GrBackendFormat & that) const195 bool GrBackendFormat::operator==(const GrBackendFormat& that) const {
196 // Invalid GrBackendFormats are never equal to anything.
197 if (!fValid || !that.fValid) {
198 return false;
199 }
200
201 if (fBackend != that.fBackend) {
202 return false;
203 }
204
205 switch (fBackend) {
206 case GrBackendApi::kOpenGL:
207 case GrBackendApi::kVulkan:
208 case GrBackendApi::kMetal:
209 return fFormatData->equal(that.fFormatData.get());
210 case GrBackendApi::kMock:
211 return fMock.fColorType == that.fMock.fColorType &&
212 fMock.fCompressionType == that.fMock.fCompressionType;
213 #ifdef SK_DIRECT3D
214 case GrBackendApi::kDirect3D:
215 return fDxgiFormat == that.fDxgiFormat;
216 #endif
217 default:
218 SK_ABORT("Unknown GrBackend");
219 }
220 return false;
221 }
222
223 #if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
224 #include "include/core/SkString.h"
225
toStr() const226 SkString GrBackendFormat::toStr() const {
227 SkString str;
228
229 if (!fValid) {
230 str.append("invalid");
231 return str;
232 }
233
234 str.appendf("%s-", GrBackendApiToStr(fBackend));
235
236 switch (fBackend) {
237 case GrBackendApi::kOpenGL:
238 case GrBackendApi::kVulkan:
239 case GrBackendApi::kMetal:
240 str.append(fFormatData->toString());
241 break;
242 case GrBackendApi::kDirect3D:
243 #ifdef SK_DIRECT3D
244 str.append(GrDxgiFormatToStr(fDxgiFormat));
245 #endif
246 break;
247 case GrBackendApi::kMock:
248 str.append(GrColorTypeToStr(fMock.fColorType));
249 str.appendf("-");
250 str.append(skgpu::CompressionTypeToStr(fMock.fCompressionType));
251 break;
252 case GrBackendApi::kUnsupported:
253 break;
254 }
255
256 return str;
257 }
258 #endif
259
260 ///////////////////////////////////////////////////////////////////////////////////////////////////
GrBackendTexture()261 GrBackendTexture::GrBackendTexture() : fIsValid(false) {}
262
263 #ifdef SK_DIRECT3D
GrBackendTexture(int width,int height,const GrD3DTextureResourceInfo & d3dInfo,std::string_view label)264 GrBackendTexture::GrBackendTexture(int width,
265 int height,
266 const GrD3DTextureResourceInfo& d3dInfo,
267 std::string_view label)
268 : GrBackendTexture(width,
269 height,
270 d3dInfo,
271 sk_sp<GrD3DResourceState>(new GrD3DResourceState(
272 static_cast<D3D12_RESOURCE_STATES>(d3dInfo.fResourceState))),
273 label) {}
274
GrBackendTexture(int width,int height,const GrD3DTextureResourceInfo & d3dInfo,sk_sp<GrD3DResourceState> state,std::string_view label)275 GrBackendTexture::GrBackendTexture(int width,
276 int height,
277 const GrD3DTextureResourceInfo& d3dInfo,
278 sk_sp<GrD3DResourceState> state,
279 std::string_view label)
280 : fIsValid(true)
281 , fWidth(width)
282 , fHeight(height)
283 , fLabel(label)
284 , fMipmapped(skgpu::Mipmapped(d3dInfo.fLevelCount > 1))
285 , fBackend(GrBackendApi::kDirect3D)
286 , fTextureType(GrTextureType::k2D)
287 , fD3DInfo(d3dInfo, state.release()) {}
288 #endif
289
GrBackendTexture(int width,int height,skgpu::Mipmapped mipmapped,const GrMockTextureInfo & mockInfo,std::string_view label)290 GrBackendTexture::GrBackendTexture(int width,
291 int height,
292 skgpu::Mipmapped mipmapped,
293 const GrMockTextureInfo& mockInfo,
294 std::string_view label)
295 : fIsValid(true)
296 , fWidth(width)
297 , fHeight(height)
298 , fLabel(label)
299 , fMipmapped(mipmapped)
300 , fBackend(GrBackendApi::kMock)
301 , fTextureType(GrTextureType::k2D)
302 , fMockInfo(mockInfo) {}
303
~GrBackendTexture()304 GrBackendTexture::~GrBackendTexture() {
305 this->cleanup();
306 }
307
cleanup()308 void GrBackendTexture::cleanup() {
309 fTextureData.reset();
310 #ifdef SK_DIRECT3D
311 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
312 fD3DInfo.cleanup();
313 }
314 #endif
315 }
316
GrBackendTexture(const GrBackendTexture & that)317 GrBackendTexture::GrBackendTexture(const GrBackendTexture& that) : fIsValid(false) {
318 *this = that;
319 }
320
operator =(const GrBackendTexture & that)321 GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
322 if (this == &that) {
323 return *this;
324 }
325
326 if (!that.isValid()) {
327 this->cleanup();
328 fIsValid = false;
329 return *this;
330 } else if (fIsValid && this->fBackend != that.fBackend) {
331 this->cleanup();
332 fIsValid = false;
333 }
334 fWidth = that.fWidth;
335 fHeight = that.fHeight;
336 fMipmapped = that.fMipmapped;
337 fBackend = that.fBackend;
338 fTextureType = that.fTextureType;
339
340 switch (that.fBackend) {
341 case GrBackendApi::kOpenGL:
342 case GrBackendApi::kVulkan:
343 case GrBackendApi::kMetal:
344 fTextureData.reset();
345 that.fTextureData->copyTo(fTextureData);
346 break;
347 #ifdef SK_DIRECT3D
348 case GrBackendApi::kDirect3D:
349 fD3DInfo.assign(that.fD3DInfo, this->isValid());
350 break;
351 #endif
352 case GrBackendApi::kMock:
353 fMockInfo = that.fMockInfo;
354 break;
355 default:
356 SK_ABORT("Unknown GrBackend");
357 }
358 fIsValid = true;
359 return *this;
360 }
361
getMutableState() const362 sk_sp<skgpu::MutableTextureState> GrBackendTexture::getMutableState() const {
363 return fTextureData->getMutableState();
364 }
365
366 #ifdef SK_DIRECT3D
getD3DTextureResourceInfo(GrD3DTextureResourceInfo * outInfo) const367 bool GrBackendTexture::getD3DTextureResourceInfo(GrD3DTextureResourceInfo* outInfo) const {
368 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
369 *outInfo = fD3DInfo.snapTextureResourceInfo();
370 return true;
371 }
372 return false;
373 }
374
setD3DResourceState(GrD3DResourceStateEnum state)375 void GrBackendTexture::setD3DResourceState(GrD3DResourceStateEnum state) {
376 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
377 fD3DInfo.setResourceState(state);
378 }
379 }
380
getGrD3DResourceState() const381 sk_sp<GrD3DResourceState> GrBackendTexture::getGrD3DResourceState() const {
382 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
383 return fD3DInfo.getGrD3DResourceState();
384 }
385 return nullptr;
386 }
387 #endif
388
getMockTextureInfo(GrMockTextureInfo * outInfo) const389 bool GrBackendTexture::getMockTextureInfo(GrMockTextureInfo* outInfo) const {
390 if (this->isValid() && GrBackendApi::kMock == fBackend) {
391 *outInfo = fMockInfo;
392 return true;
393 }
394 return false;
395 }
396
setMutableState(const skgpu::MutableTextureState & state)397 void GrBackendTexture::setMutableState(const skgpu::MutableTextureState& state) {
398 fTextureData->setMutableState(state);
399 }
400
isProtected() const401 bool GrBackendTexture::isProtected() const {
402 if (!this->isValid()) {
403 return false;
404 }
405 if (this->backend() == GrBackendApi::kOpenGL || this->backend() == GrBackendApi::kVulkan) {
406 return fTextureData->isProtected();
407 }
408 if (this->backend() == GrBackendApi::kMock) {
409 return fMockInfo.isProtected();
410 }
411
412 return false;
413 }
414
isSameTexture(const GrBackendTexture & that)415 bool GrBackendTexture::isSameTexture(const GrBackendTexture& that) {
416 if (!this->isValid() || !that.isValid()) {
417 return false;
418 }
419 if (fBackend != that.fBackend) {
420 return false;
421 }
422 switch (fBackend) {
423 case GrBackendApi::kOpenGL:
424 case GrBackendApi::kVulkan:
425 case GrBackendApi::kMetal:
426 return fTextureData->isSameTexture(that.fTextureData.get());
427 #ifdef SK_DIRECT3D
428 case GrBackendApi::kDirect3D:
429 return fD3DInfo.snapTextureResourceInfo().fResource ==
430 that.fD3DInfo.snapTextureResourceInfo().fResource;
431 #endif
432 case GrBackendApi::kMock:
433 return fMockInfo.id() == that.fMockInfo.id();
434 default:
435 return false;
436 }
437 }
438
getBackendFormat() const439 GrBackendFormat GrBackendTexture::getBackendFormat() const {
440 if (!this->isValid()) {
441 return GrBackendFormat();
442 }
443 switch (fBackend) {
444 case GrBackendApi::kOpenGL:
445 case GrBackendApi::kVulkan:
446 case GrBackendApi::kMetal:
447 return fTextureData->getBackendFormat();
448 #ifdef SK_DIRECT3D
449 case GrBackendApi::kDirect3D: {
450 auto d3dInfo = fD3DInfo.snapTextureResourceInfo();
451 return GrBackendFormat::MakeDxgi(d3dInfo.fFormat);
452 }
453 #endif
454 case GrBackendApi::kMock:
455 return fMockInfo.getBackendFormat();
456 default:
457 return GrBackendFormat();
458 }
459 }
460
461 #if defined(GR_TEST_UTILS)
TestingOnly_Equals(const GrBackendTexture & t0,const GrBackendTexture & t1)462 bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBackendTexture& t1) {
463 if (!t0.isValid() || !t1.isValid()) {
464 return false; // two invalid backend textures are not considered equal
465 }
466
467 if (t0.fWidth != t1.fWidth ||
468 t0.fHeight != t1.fHeight ||
469 t0.fMipmapped != t1.fMipmapped ||
470 t0.fBackend != t1.fBackend) {
471 return false;
472 }
473
474 switch (t0.fBackend) {
475 case GrBackendApi::kOpenGL:
476 case GrBackendApi::kVulkan:
477 case GrBackendApi::kMetal:
478 return t0.fTextureData->equal(t1.fTextureData.get());
479 case GrBackendApi::kMock:
480 return t0.fMockInfo == t1.fMockInfo;
481 #ifdef SK_DIRECT3D
482 case GrBackendApi::kDirect3D:
483 return t0.fD3DInfo == t1.fD3DInfo;
484 #endif
485 default:
486 return false;
487 }
488 }
489 #endif
490
491 ////////////////////////////////////////////////////////////////////////////////////////////////////
492
GrBackendRenderTarget()493 GrBackendRenderTarget::GrBackendRenderTarget() : fIsValid(false) {}
494
495 #ifdef SK_DIRECT3D
GrBackendRenderTarget(int width,int height,const GrD3DTextureResourceInfo & d3dInfo)496 GrBackendRenderTarget::GrBackendRenderTarget(int width, int height,
497 const GrD3DTextureResourceInfo& d3dInfo)
498 : GrBackendRenderTarget(
499 width, height, d3dInfo,
500 sk_sp<GrD3DResourceState>(new GrD3DResourceState(
501 static_cast<D3D12_RESOURCE_STATES>(d3dInfo.fResourceState)))) {}
502
GrBackendRenderTarget(int width,int height,const GrD3DTextureResourceInfo & d3dInfo,sk_sp<GrD3DResourceState> state)503 GrBackendRenderTarget::GrBackendRenderTarget(int width,
504 int height,
505 const GrD3DTextureResourceInfo& d3dInfo,
506 sk_sp<GrD3DResourceState> state)
507 : fIsValid(true)
508 , fWidth(width)
509 , fHeight(height)
510 , fSampleCnt(std::max(1U, d3dInfo.fSampleCount))
511 , fStencilBits(0)
512 , fBackend(GrBackendApi::kDirect3D)
513 , fD3DInfo(d3dInfo, state.release()) {}
514 #endif
515
GrBackendRenderTarget(int width,int height,int sampleCnt,int stencilBits,const GrMockRenderTargetInfo & mockInfo)516 GrBackendRenderTarget::GrBackendRenderTarget(int width,
517 int height,
518 int sampleCnt,
519 int stencilBits,
520 const GrMockRenderTargetInfo& mockInfo)
521 : fIsValid(true)
522 , fWidth(width)
523 , fHeight(height)
524 , fSampleCnt(std::max(1, sampleCnt))
525 , fStencilBits(stencilBits)
526 , fBackend(GrBackendApi::kMock)
527 , fMockInfo(mockInfo) {}
528
~GrBackendRenderTarget()529 GrBackendRenderTarget::~GrBackendRenderTarget() {
530 this->cleanup();
531 }
532
cleanup()533 void GrBackendRenderTarget::cleanup() {
534 fRTData.reset();
535 #ifdef SK_DIRECT3D
536 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
537 fD3DInfo.cleanup();
538 }
539 #endif
540 }
541
GrBackendRenderTarget(const GrBackendRenderTarget & that)542 GrBackendRenderTarget::GrBackendRenderTarget(const GrBackendRenderTarget& that) : fIsValid(false) {
543 *this = that;
544 }
545
operator =(const GrBackendRenderTarget & that)546 GrBackendRenderTarget& GrBackendRenderTarget::operator=(const GrBackendRenderTarget& that) {
547 if (this == &that) {
548 return *this;
549 }
550
551 if (!that.isValid()) {
552 this->cleanup();
553 fIsValid = false;
554 return *this;
555 } else if (fIsValid && this->fBackend != that.fBackend) {
556 this->cleanup();
557 fIsValid = false;
558 }
559 fWidth = that.fWidth;
560 fHeight = that.fHeight;
561 fSampleCnt = that.fSampleCnt;
562 fStencilBits = that.fStencilBits;
563 fBackend = that.fBackend;
564
565 switch (that.fBackend) {
566 case GrBackendApi::kOpenGL:
567 case GrBackendApi::kVulkan:
568 case GrBackendApi::kMetal:
569 fRTData.reset();
570 that.fRTData->copyTo(fRTData);
571 break;
572 #ifdef SK_DIRECT3D
573 case GrBackendApi::kDirect3D:
574 fD3DInfo.assign(that.fD3DInfo, this->isValid());
575 break;
576 #endif
577 case GrBackendApi::kMock:
578 fMockInfo = that.fMockInfo;
579 break;
580 default:
581 SK_ABORT("Unknown GrBackend");
582 }
583 fIsValid = that.fIsValid;
584 return *this;
585 }
586
getMutableState() const587 sk_sp<skgpu::MutableTextureState> GrBackendRenderTarget::getMutableState() const {
588 return fRTData->getMutableState();
589 }
590
591 #ifdef SK_DIRECT3D
getD3DTextureResourceInfo(GrD3DTextureResourceInfo * outInfo) const592 bool GrBackendRenderTarget::getD3DTextureResourceInfo(GrD3DTextureResourceInfo* outInfo) const {
593 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
594 *outInfo = fD3DInfo.snapTextureResourceInfo();
595 return true;
596 }
597 return false;
598 }
599
setD3DResourceState(GrD3DResourceStateEnum state)600 void GrBackendRenderTarget::setD3DResourceState(GrD3DResourceStateEnum state) {
601 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
602 fD3DInfo.setResourceState(state);
603 }
604 }
605
getGrD3DResourceState() const606 sk_sp<GrD3DResourceState> GrBackendRenderTarget::getGrD3DResourceState() const {
607 if (this->isValid() && GrBackendApi::kDirect3D == fBackend) {
608 return fD3DInfo.getGrD3DResourceState();
609 }
610 return nullptr;
611 }
612 #endif
613
getBackendFormat() const614 GrBackendFormat GrBackendRenderTarget::getBackendFormat() const {
615 if (!this->isValid()) {
616 return GrBackendFormat();
617 }
618 switch (fBackend) {
619 case GrBackendApi::kOpenGL:
620 case GrBackendApi::kVulkan:
621 case GrBackendApi::kMetal:
622 return fRTData->getBackendFormat();
623 #ifdef SK_DIRECT3D
624 case GrBackendApi::kDirect3D: {
625 auto info = fD3DInfo.snapTextureResourceInfo();
626 return GrBackendFormat::MakeDxgi(info.fFormat);
627 }
628 #endif
629 case GrBackendApi::kMock:
630 return fMockInfo.getBackendFormat();
631 default:
632 return GrBackendFormat();
633 }
634 }
635
getMockRenderTargetInfo(GrMockRenderTargetInfo * outInfo) const636 bool GrBackendRenderTarget::getMockRenderTargetInfo(GrMockRenderTargetInfo* outInfo) const {
637 if (this->isValid() && GrBackendApi::kMock == fBackend) {
638 *outInfo = fMockInfo;
639 return true;
640 }
641 return false;
642 }
643
setMutableState(const skgpu::MutableTextureState & state)644 void GrBackendRenderTarget::setMutableState(const skgpu::MutableTextureState& state) {
645 fRTData->setMutableState(state);
646 }
647
isProtected() const648 bool GrBackendRenderTarget::isProtected() const {
649 if (!this->isValid()) {
650 return false;
651 }
652 if (this->backend() == GrBackendApi::kOpenGL || this->backend() == GrBackendApi::kVulkan) {
653 return fRTData->isProtected();
654 }
655 if (this->backend() == GrBackendApi::kMock) {
656 return fMockInfo.isProtected();
657 }
658
659 return false;
660 }
661
662 #if defined(GR_TEST_UTILS)
TestingOnly_Equals(const GrBackendRenderTarget & r0,const GrBackendRenderTarget & r1)663 bool GrBackendRenderTarget::TestingOnly_Equals(const GrBackendRenderTarget& r0,
664 const GrBackendRenderTarget& r1) {
665 if (!r0.isValid() || !r1.isValid()) {
666 return false; // two invalid backend rendertargets are not considered equal
667 }
668
669 if (r0.fWidth != r1.fWidth ||
670 r0.fHeight != r1.fHeight ||
671 r0.fSampleCnt != r1.fSampleCnt ||
672 r0.fStencilBits != r1.fStencilBits ||
673 r0.fBackend != r1.fBackend) {
674 return false;
675 }
676
677 switch (r0.fBackend) {
678 case GrBackendApi::kOpenGL:
679 case GrBackendApi::kVulkan:
680 case GrBackendApi::kMetal:
681 return r0.fRTData->equal(r1.fRTData.get());
682 case GrBackendApi::kMock:
683 return r0.fMockInfo == r1.fMockInfo;
684 #ifdef SK_DIRECT3D
685 case GrBackendApi::kDirect3D:
686 return r0.fD3DInfo == r1.fD3DInfo;
687 #endif
688 default:
689 return false;
690 }
691
692 SkASSERT(0);
693 return false;
694 }
695 #endif
696
~GrBackendFormatData()697 GrBackendFormatData::~GrBackendFormatData() {}
~GrBackendTextureData()698 GrBackendTextureData::~GrBackendTextureData() {}
~GrBackendRenderTargetData()699 GrBackendRenderTargetData::~GrBackendRenderTargetData() {}
700