1 | use std::fmt; |
2 | |
3 | use skia_bindings::{self as sb, GrBackendFormat, GrBackendRenderTarget, GrBackendTexture}; |
4 | |
5 | #[cfg (feature = "d3d" )] |
6 | use super::d3d; |
7 | #[cfg (feature = "gl" )] |
8 | use super::gl; |
9 | #[cfg (feature = "metal" )] |
10 | use super::mtl; |
11 | #[cfg (feature = "vulkan" )] |
12 | use super::vk; |
13 | use super::{BackendAPI, Mipmapped, MutableTextureState}; |
14 | use crate::{interop::AsStr, prelude::*, ISize}; |
15 | |
16 | pub type BackendFormat = Handle<GrBackendFormat>; |
17 | unsafe_send_sync!(BackendFormat); |
18 | |
19 | impl NativeDrop for GrBackendFormat { |
20 | fn drop(&mut self) { |
21 | unsafe { sb::C_GrBackendFormat_destruct(self) } |
22 | } |
23 | } |
24 | |
25 | impl NativeClone for GrBackendFormat { |
26 | fn clone(&self) -> Self { |
27 | unsafe { GrBackendFormat::new1(self) } |
28 | } |
29 | } |
30 | |
31 | impl fmt::Debug for BackendFormat { |
32 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
33 | let mut d: DebugStruct<'_, '_> = f.debug_struct(name:"BackendFormat" ); |
34 | d.field(name:"backend" , &self.backend()); |
35 | d.field(name:"channel_mask" , &self.channel_mask()); |
36 | #[cfg (feature = "gl" )] |
37 | d.field(name:"gl_format" , &self.as_gl_format()); |
38 | #[cfg (feature = "vulkan" )] |
39 | d.field("vk_format" , &self.as_vk_format()); |
40 | #[cfg (feature = "metal" )] |
41 | d.field(name:"mtl_format" , &self.as_mtl_format()); |
42 | #[cfg (feature = "d3d" )] |
43 | d.field(name:"dxgi_format" , &self.as_dxgi_format()); |
44 | d.finish() |
45 | } |
46 | } |
47 | |
48 | impl BackendFormat { |
49 | #[deprecated ( |
50 | note = "The creation of invalid BackendFormats isn't supported anymore" , |
51 | since = "0.37.0" |
52 | )] |
53 | pub fn new() -> Self { |
54 | Self::new_invalid() |
55 | } |
56 | |
57 | pub(crate) fn new_invalid() -> Self { |
58 | Self::construct(|bf| unsafe { sb::C_GrBackendFormat_Construct(bf) }) |
59 | } |
60 | |
61 | #[cfg (feature = "gl" )] |
62 | pub fn new_gl(format: gl::Enum, target: gl::Enum) -> Self { |
63 | Self::construct(|bf| unsafe { sb::C_GrBackendFormats_ConstructGL(bf, format, target) }) |
64 | .assert_valid() |
65 | } |
66 | |
67 | #[cfg (feature = "vulkan" )] |
68 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_formats::make_vk()" )] |
69 | pub fn new_vulkan( |
70 | format: vk::Format, |
71 | will_use_drm_format_modifiers: impl Into<Option<bool>>, |
72 | ) -> Self { |
73 | super::backend_formats::make_vk(format, will_use_drm_format_modifiers) |
74 | } |
75 | |
76 | #[cfg (feature = "vulkan" )] |
77 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_formats::make_vk_ycbcr()" )] |
78 | pub fn new_vulkan_ycbcr( |
79 | conversion_info: &vk::YcbcrConversionInfo, |
80 | will_use_drm_format_modifiers: impl Into<Option<bool>>, |
81 | ) -> Self { |
82 | super::backend_formats::make_vk_ycbcr(conversion_info, will_use_drm_format_modifiers) |
83 | } |
84 | |
85 | #[cfg (feature = "metal" )] |
86 | pub fn new_metal(format: mtl::PixelFormat) -> Self { |
87 | Self::construct(|bf| unsafe { sb::C_GrBackendFormat_ConstructMtl(bf, format) }) |
88 | .assert_valid() |
89 | } |
90 | |
91 | #[cfg (feature = "d3d" )] |
92 | pub fn new_dxgi(format: d3d::DXGI_FORMAT) -> Self { |
93 | Self::construct(|bf| unsafe { |
94 | sb::C_GrBackendFormat_ConstructDxgi(bf, format.into_native()) |
95 | }) |
96 | .assert_valid() |
97 | } |
98 | |
99 | pub fn backend(&self) -> BackendAPI { |
100 | self.native().fBackend |
101 | } |
102 | |
103 | pub fn channel_mask(&self) -> u32 { |
104 | unsafe { self.native().channelMask() } |
105 | } |
106 | |
107 | // m117: Even though Skia did, we won't deprecate these functions here for convenience. |
108 | |
109 | #[cfg (feature = "gl" )] |
110 | pub fn as_gl_format(&self) -> gl::Format { |
111 | super::backend_formats::as_gl_format(self) |
112 | } |
113 | |
114 | #[cfg (feature = "gl" )] |
115 | pub fn as_gl_format_enum(&self) -> gl::Enum { |
116 | super::backend_formats::as_gl_format_enum(self) |
117 | } |
118 | |
119 | // Deprecated in Skia |
120 | #[cfg (feature = "vulkan" )] |
121 | pub fn as_vk_format(&self) -> Option<vk::Format> { |
122 | super::backend_formats::as_vk_format(self) |
123 | } |
124 | |
125 | #[cfg (feature = "metal" )] |
126 | pub fn as_mtl_format(&self) -> Option<mtl::PixelFormat> { |
127 | let pixel_format = unsafe { self.native().asMtlFormat() }; |
128 | // Mtl's PixelFormat == 0 is invalid. |
129 | (pixel_format != 0).if_true_some(pixel_format) |
130 | } |
131 | |
132 | #[cfg (feature = "d3d" )] |
133 | pub fn as_dxgi_format(&self) -> Option<d3d::DXGI_FORMAT> { |
134 | let mut f = sb::DXGI_FORMAT::DXGI_FORMAT_UNKNOWN; |
135 | unsafe { self.native().asDxgiFormat(&mut f) } |
136 | .if_true_some(d3d::DXGI_FORMAT::from_native_c(f)) |
137 | } |
138 | |
139 | #[must_use ] |
140 | pub fn to_texture_2d(&self) -> Self { |
141 | let mut new = Self::new_invalid(); |
142 | unsafe { sb::C_GrBackendFormat_makeTexture2D(self.native(), new.native_mut()) }; |
143 | assert!(Self::native_is_valid(new.native())); |
144 | new |
145 | } |
146 | |
147 | #[deprecated ( |
148 | note = "Invalid BackendFormats are not supported anymore" , |
149 | since = "0.37.0" |
150 | )] |
151 | pub fn is_valid(&self) -> bool { |
152 | self.native().fValid |
153 | } |
154 | |
155 | pub(crate) fn native_is_valid(format: &GrBackendFormat) -> bool { |
156 | format.fValid |
157 | } |
158 | |
159 | pub(crate) fn assert_valid(self) -> Self { |
160 | assert!(Self::native_is_valid(self.native())); |
161 | self |
162 | } |
163 | } |
164 | |
165 | // GrBackendTexture contains a string `fLabel`, and with SSO on some platforms, it can't be moved. |
166 | // See <https://github.com/rust-skia/rust-skia/issues/750>. |
167 | pub type BackendTexture = RefHandle<GrBackendTexture>; |
168 | unsafe_send_sync!(BackendTexture); |
169 | |
170 | impl NativeDrop for GrBackendTexture { |
171 | fn drop(&mut self) { |
172 | unsafe { sb::C_GrBackendTexture_delete(self) } |
173 | } |
174 | } |
175 | |
176 | impl Clone for BackendTexture { |
177 | fn clone(&self) -> Self { |
178 | unsafe { Self::from_ptr(sb::C_GrBackendTexture_Clone(self.native())) }.unwrap() |
179 | } |
180 | } |
181 | |
182 | impl fmt::Debug for BackendTexture { |
183 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
184 | let mut d: DebugStruct<'_, '_> = f.debug_struct(name:"BackendTexture" ); |
185 | d.field(name:"dimensions" , &self.dimensions()); |
186 | d.field(name:"label" , &self.label()); |
187 | d.field(name:"mipmapped" , &self.mipmapped()); |
188 | d.field(name:"backend" , &self.backend()); |
189 | #[cfg (feature = "gl" )] |
190 | d.field(name:"gl_texture_info" , &self.gl_texture_info()); |
191 | #[cfg (feature = "vulkan" )] |
192 | d.field("vulkan_image_info" , &self.vulkan_image_info()); |
193 | #[cfg (feature = "metal" )] |
194 | d.field(name:"metal_texture_info" , &self.metal_texture_info()); |
195 | #[cfg (feature = "d3d" )] |
196 | d.field( |
197 | name:"d3d_texture_resource_info" , |
198 | &self.d3d_texture_resource_info(), |
199 | ); |
200 | d.field(name:"backend_format" , &self.backend_format()); |
201 | d.field(name:"is_protected" , &self.is_protected()); |
202 | d.finish() |
203 | } |
204 | } |
205 | |
206 | impl BackendTexture { |
207 | pub(crate) fn new_invalid() -> Self { |
208 | Self::from_ptr(unsafe { sb::C_GrBackendTexture_new() }).unwrap() |
209 | } |
210 | |
211 | #[cfg (feature = "gl" )] |
212 | #[allow (clippy::missing_safety_doc)] |
213 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_textures::make_gl()" )] |
214 | pub unsafe fn new_gl( |
215 | (width, height): (i32, i32), |
216 | mipmapped: super::Mipmapped, |
217 | gl_info: gl::TextureInfo, |
218 | ) -> Self { |
219 | super::backend_textures::make_gl((width, height), mipmapped, gl_info, "" ) |
220 | } |
221 | |
222 | #[cfg (feature = "gl" )] |
223 | #[allow (clippy::missing_safety_doc)] |
224 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_textures::make_gl()" )] |
225 | pub unsafe fn new_gl_with_label( |
226 | (width, height): (i32, i32), |
227 | mipmapped: super::Mipmapped, |
228 | gl_info: gl::TextureInfo, |
229 | label: impl AsRef<str>, |
230 | ) -> Self { |
231 | super::backend_textures::make_gl((width, height), mipmapped, gl_info, label) |
232 | } |
233 | |
234 | #[cfg (feature = "vulkan" )] |
235 | #[allow (clippy::missing_safety_doc)] |
236 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_textures::make_vk()" )] |
237 | pub unsafe fn new_vulkan((width, height): (i32, i32), vk_info: &vk::ImageInfo) -> Self { |
238 | super::backend_textures::make_vk((width, height), vk_info, "" ) |
239 | } |
240 | |
241 | #[cfg (feature = "vulkan" )] |
242 | #[allow (clippy::missing_safety_doc)] |
243 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_textures::make_vk()" )] |
244 | pub unsafe fn new_vulkan_with_label( |
245 | (width, height): (i32, i32), |
246 | vk_info: &vk::ImageInfo, |
247 | label: impl AsRef<str>, |
248 | ) -> Self { |
249 | super::backend_textures::make_vk((width, height), vk_info, label) |
250 | } |
251 | |
252 | #[cfg (feature = "metal" )] |
253 | #[allow (clippy::missing_safety_doc)] |
254 | pub unsafe fn new_metal( |
255 | (width, height): (i32, i32), |
256 | mipmapped: super::Mipmapped, |
257 | mtl_info: &mtl::TextureInfo, |
258 | ) -> Self { |
259 | Self::new_metal_with_label((width, height), mipmapped, mtl_info, "" ) |
260 | } |
261 | |
262 | #[cfg (feature = "metal" )] |
263 | #[allow (clippy::missing_safety_doc)] |
264 | pub unsafe fn new_metal_with_label( |
265 | (width, height): (i32, i32), |
266 | mipmapped: super::Mipmapped, |
267 | mtl_info: &mtl::TextureInfo, |
268 | label: impl AsRef<str>, |
269 | ) -> Self { |
270 | let label = label.as_ref().as_bytes(); |
271 | Self::from_native_if_valid(sb::C_GrBackendTexture_newMtl( |
272 | width, |
273 | height, |
274 | mipmapped, |
275 | mtl_info.native(), |
276 | label.as_ptr() as _, |
277 | label.len(), |
278 | )) |
279 | .unwrap() |
280 | } |
281 | |
282 | #[cfg (feature = "d3d" )] |
283 | pub fn new_d3d((width, height): (i32, i32), d3d_info: &d3d::TextureResourceInfo) -> Self { |
284 | Self::new_d3d_with_label((width, height), d3d_info, "" ) |
285 | } |
286 | |
287 | #[cfg (feature = "d3d" )] |
288 | pub fn new_d3d_with_label( |
289 | (width, height): (i32, i32), |
290 | d3d_info: &d3d::TextureResourceInfo, |
291 | label: impl AsRef<str>, |
292 | ) -> Self { |
293 | let label = label.as_ref().as_bytes(); |
294 | unsafe { |
295 | Self::from_native_if_valid(sb::C_GrBackendTexture_newD3D( |
296 | width, |
297 | height, |
298 | d3d_info.native(), |
299 | label.as_ptr() as _, |
300 | label.len(), |
301 | )) |
302 | } |
303 | .unwrap() |
304 | } |
305 | |
306 | pub(crate) unsafe fn from_native_if_valid( |
307 | backend_texture: *mut GrBackendTexture, |
308 | ) -> Option<BackendTexture> { |
309 | Self::native_is_valid(backend_texture) |
310 | .if_true_then_some(|| BackendTexture::from_ptr(backend_texture).unwrap()) |
311 | } |
312 | |
313 | pub fn dimensions(&self) -> ISize { |
314 | ISize::new(self.width(), self.height()) |
315 | } |
316 | |
317 | pub fn width(&self) -> i32 { |
318 | self.native().fWidth |
319 | } |
320 | |
321 | pub fn height(&self) -> i32 { |
322 | self.native().fHeight |
323 | } |
324 | |
325 | pub fn label(&self) -> &str { |
326 | self.native().fLabel.as_str() |
327 | } |
328 | |
329 | pub fn mipmapped(&self) -> Mipmapped { |
330 | self.native().fMipmapped |
331 | } |
332 | |
333 | #[deprecated (since = "0.35.0" , note = "Use has_mipmaps()" )] |
334 | pub fn has_mip_maps(&self) -> bool { |
335 | self.has_mipmaps() |
336 | } |
337 | |
338 | pub fn has_mipmaps(&self) -> bool { |
339 | self.native().fMipmapped == Mipmapped::Yes |
340 | } |
341 | |
342 | pub fn backend(&self) -> BackendAPI { |
343 | self.native().fBackend |
344 | } |
345 | |
346 | // Deprecated in Skia |
347 | #[cfg (feature = "gl" )] |
348 | pub fn gl_texture_info(&self) -> Option<gl::TextureInfo> { |
349 | super::backend_textures::get_gl_texture_info(self) |
350 | } |
351 | |
352 | // Deprecated in Skia |
353 | #[cfg (feature = "gl" )] |
354 | pub fn gl_texture_parameters_modified(&mut self) { |
355 | super::backend_textures::gl_texture_parameters_modified(self) |
356 | } |
357 | |
358 | // Deprecated in Skia |
359 | #[cfg (feature = "vulkan" )] |
360 | pub fn vulkan_image_info(&self) -> Option<vk::ImageInfo> { |
361 | super::backend_textures::get_vk_image_info(self) |
362 | } |
363 | |
364 | // Deprecated in Skia |
365 | #[cfg (feature = "vulkan" )] |
366 | pub fn set_vulkan_image_layout(&mut self, layout: vk::ImageLayout) -> &mut Self { |
367 | super::backend_textures::set_vk_image_layout(self, layout) |
368 | } |
369 | |
370 | #[cfg (feature = "metal" )] |
371 | pub fn metal_texture_info(&self) -> Option<mtl::TextureInfo> { |
372 | unsafe { |
373 | let mut texture_info = mtl::TextureInfo::default(); |
374 | self.native() |
375 | .getMtlTextureInfo(texture_info.native_mut()) |
376 | .if_true_some(texture_info) |
377 | } |
378 | } |
379 | |
380 | #[cfg (feature = "d3d" )] |
381 | pub fn d3d_texture_resource_info(&self) -> Option<d3d::TextureResourceInfo> { |
382 | unsafe { |
383 | let mut info = sb::GrD3DTextureResourceInfo::default(); |
384 | self.native() |
385 | .getD3DTextureResourceInfo(&mut info) |
386 | .if_true_then_some(|| { |
387 | assert!(!info.fResource.fObject.is_null()); |
388 | d3d::TextureResourceInfo::from_native_c(info) |
389 | }) |
390 | } |
391 | } |
392 | |
393 | #[cfg (feature = "d3d" )] |
394 | pub fn set_d3d_resource_state(&mut self, resource_state: d3d::ResourceStateEnum) -> &mut Self { |
395 | unsafe { self.native_mut().setD3DResourceState(resource_state) } |
396 | self |
397 | } |
398 | |
399 | pub fn backend_format(&self) -> BackendFormat { |
400 | let mut format = BackendFormat::new_invalid(); |
401 | unsafe { sb::C_GrBackendTexture_getBackendFormat(self.native(), format.native_mut()) }; |
402 | assert!(BackendFormat::native_is_valid(format.native())); |
403 | format |
404 | } |
405 | |
406 | pub fn set_mutable_state(&mut self, state: &MutableTextureState) { |
407 | unsafe { self.native_mut().setMutableState(state.native()) } |
408 | } |
409 | |
410 | pub fn is_protected(&self) -> bool { |
411 | unsafe { self.native().isProtected() } |
412 | } |
413 | |
414 | #[deprecated (note = "Invalid BackendTextures aren't supported" , since = "0.37.0" )] |
415 | pub fn is_valid(&self) -> bool { |
416 | self.native().fIsValid |
417 | } |
418 | |
419 | pub(crate) unsafe fn native_is_valid(texture: *const GrBackendTexture) -> bool { |
420 | (*texture).fIsValid |
421 | } |
422 | |
423 | #[allow (clippy::wrong_self_convention)] |
424 | pub fn is_same_texture(&mut self, texture: &BackendTexture) -> bool { |
425 | unsafe { self.native_mut().isSameTexture(texture.native()) } |
426 | } |
427 | } |
428 | |
429 | pub type BackendRenderTarget = Handle<GrBackendRenderTarget>; |
430 | unsafe_send_sync!(BackendRenderTarget); |
431 | |
432 | impl NativeDrop for GrBackendRenderTarget { |
433 | fn drop(&mut self) { |
434 | unsafe { sb::C_GrBackendRenderTarget_destruct(self) } |
435 | } |
436 | } |
437 | |
438 | impl NativeClone for GrBackendRenderTarget { |
439 | fn clone(&self) -> Self { |
440 | construct(|render_target: *mut GrBackendRenderTarget| unsafe { |
441 | sb::C_GrBackendRenderTarget_CopyConstruct(uninitialized:render_target, self) |
442 | }) |
443 | } |
444 | } |
445 | |
446 | impl fmt::Debug for BackendRenderTarget { |
447 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
448 | let mut d: DebugStruct<'_, '_> = f.debug_struct(name:"BackendRenderTarget" ); |
449 | d.field(name:"dimensions" , &self.dimensions()); |
450 | d.field(name:"sample_count" , &self.sample_count()); |
451 | d.field(name:"stencil_bits" , &self.stencil_bits()); |
452 | d.field(name:"backend" , &self.backend()); |
453 | d.field(name:"is_framebuffer_only" , &self.is_framebuffer_only()); |
454 | #[cfg (feature = "gl" )] |
455 | d.field(name:"gl_framebuffer_info" , &self.gl_framebuffer_info()); |
456 | #[cfg (feature = "vulkan" )] |
457 | d.field("vulkan_image_info" , &self.vulkan_image_info()); |
458 | #[cfg (feature = "metal" )] |
459 | d.field(name:"metal_texture_info" , &self.metal_texture_info()); |
460 | #[cfg (feature = "d3d" )] |
461 | d.field( |
462 | name:"d3d_texture_resource_info" , |
463 | &self.d3d_texture_resource_info(), |
464 | ); |
465 | d.field(name:"backend_format" , &self.backend_format()); |
466 | d.field(name:"is_protected" , &self.is_protected()); |
467 | d.finish() |
468 | } |
469 | } |
470 | |
471 | impl BackendRenderTarget { |
472 | #[cfg (feature = "gl" )] |
473 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_render_targets::make_gl()" )] |
474 | pub fn new_gl( |
475 | (width, height): (i32, i32), |
476 | sample_count: impl Into<Option<usize>>, |
477 | stencil_bits: usize, |
478 | info: gl::FramebufferInfo, |
479 | ) -> Self { |
480 | super::backend_render_targets::make_gl((width, height), sample_count, stencil_bits, info) |
481 | } |
482 | |
483 | #[cfg (feature = "vulkan" )] |
484 | #[deprecated (since = "0.67.0" , note = "use gpu::backend_render_targets::make_vk()" )] |
485 | pub fn new_vulkan((width, height): (i32, i32), info: &vk::ImageInfo) -> Self { |
486 | super::backend_render_targets::make_vk((width, height), info) |
487 | } |
488 | |
489 | #[cfg (feature = "metal" )] |
490 | pub fn new_metal((width, height): (i32, i32), mtl_info: &mtl::TextureInfo) -> Self { |
491 | Self::construct(|target| unsafe { |
492 | sb::C_GrBackendRenderTargets_ConstructMtl(target, width, height, mtl_info.native()) |
493 | }) |
494 | } |
495 | |
496 | #[cfg (feature = "d3d" )] |
497 | pub fn new_d3d((width, height): (i32, i32), d3d_info: &d3d::TextureResourceInfo) -> Self { |
498 | Self::construct(|brt| unsafe { |
499 | sb::C_GrBackendRenderTarget_ConstructD3D(brt, width, height, d3d_info.native()) |
500 | }) |
501 | } |
502 | |
503 | pub(crate) fn from_native_c_if_valid( |
504 | native: GrBackendRenderTarget, |
505 | ) -> Option<BackendRenderTarget> { |
506 | let backend_render_target = BackendRenderTarget::from_native_c(native); |
507 | Self::native_is_valid(backend_render_target.native()).if_true_some(backend_render_target) |
508 | } |
509 | |
510 | pub fn dimensions(&self) -> ISize { |
511 | ISize::new(self.width(), self.height()) |
512 | } |
513 | |
514 | pub fn width(&self) -> i32 { |
515 | self.native().fWidth |
516 | } |
517 | |
518 | pub fn height(&self) -> i32 { |
519 | self.native().fHeight |
520 | } |
521 | |
522 | pub fn sample_count(&self) -> usize { |
523 | self.native().fSampleCnt.try_into().unwrap() |
524 | } |
525 | |
526 | pub fn stencil_bits(&self) -> usize { |
527 | self.native().fStencilBits.try_into().unwrap() |
528 | } |
529 | |
530 | pub fn backend(&self) -> BackendAPI { |
531 | self.native().fBackend |
532 | } |
533 | |
534 | pub fn is_framebuffer_only(&self) -> bool { |
535 | self.native().fFramebufferOnly |
536 | } |
537 | |
538 | // Deprecated in Skia |
539 | #[cfg (feature = "gl" )] |
540 | pub fn gl_framebuffer_info(&self) -> Option<gl::FramebufferInfo> { |
541 | super::backend_render_targets::get_gl_framebuffer_info(self) |
542 | } |
543 | |
544 | // Deprecated in Skia |
545 | #[cfg (feature = "vulkan" )] |
546 | pub fn vulkan_image_info(&self) -> Option<vk::ImageInfo> { |
547 | super::backend_render_targets::get_vk_image_info(self) |
548 | } |
549 | |
550 | // Deprecated in Skia |
551 | #[cfg (feature = "vulkan" )] |
552 | pub fn set_vulkan_image_layout(&mut self, layout: vk::ImageLayout) -> &mut Self { |
553 | super::backend_render_targets::set_vk_image_layout(self, layout) |
554 | } |
555 | |
556 | #[cfg (feature = "metal" )] |
557 | pub fn metal_texture_info(&self) -> Option<mtl::TextureInfo> { |
558 | let mut info = mtl::TextureInfo::default(); |
559 | unsafe { self.native().getMtlTextureInfo(info.native_mut()) }.if_true_some(info) |
560 | } |
561 | |
562 | #[cfg (feature = "d3d" )] |
563 | pub fn d3d_texture_resource_info(&self) -> Option<d3d::TextureResourceInfo> { |
564 | let mut info = sb::GrD3DTextureResourceInfo::default(); |
565 | unsafe { self.native().getD3DTextureResourceInfo(&mut info) }.if_true_then_some(|| { |
566 | assert!(!info.fResource.fObject.is_null()); |
567 | d3d::TextureResourceInfo::from_native_c(info) |
568 | }) |
569 | } |
570 | |
571 | #[cfg (feature = "d3d" )] |
572 | pub fn set_d3d_resource_state(&mut self, resource_state: d3d::ResourceStateEnum) -> &mut Self { |
573 | unsafe { self.native_mut().setD3DResourceState(resource_state) } |
574 | self |
575 | } |
576 | |
577 | pub fn backend_format(&self) -> BackendFormat { |
578 | BackendFormat::construct(|format| unsafe { |
579 | sb::C_GrBackendRenderTarget_getBackendFormat(self.native(), format) |
580 | }) |
581 | } |
582 | |
583 | pub fn set_mutable_state(&mut self, state: &MutableTextureState) { |
584 | unsafe { self.native_mut().setMutableState(state.native()) } |
585 | } |
586 | |
587 | pub fn is_protected(&self) -> bool { |
588 | unsafe { self.native().isProtected() } |
589 | } |
590 | |
591 | #[deprecated ( |
592 | since = "0.37.0" , |
593 | note = "Exposed BackendRenderTargets are always valid." |
594 | )] |
595 | pub fn is_valid(&self) -> bool { |
596 | self.native().fIsValid |
597 | } |
598 | |
599 | pub(crate) fn native_is_valid(rt: &GrBackendRenderTarget) -> bool { |
600 | rt.fIsValid |
601 | } |
602 | } |
603 | |
604 | #[cfg (test)] |
605 | mod tests { |
606 | use super::BackendTexture; |
607 | use std::hint::black_box; |
608 | |
609 | // Regression test for <https://github.com/rust-skia/rust-skia/issues/750> |
610 | #[test ] |
611 | fn create_move_and_drop_backend_texture() { |
612 | let texture = force_move(BackendTexture::new_invalid()); |
613 | drop(texture); |
614 | } |
615 | |
616 | fn force_move<V>(src: V) -> V { |
617 | let src = black_box(src); |
618 | *black_box(Box::new(src)) |
619 | } |
620 | } |
621 | |