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