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