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