1use std::cell::RefCell;
2use std::fmt;
3use std::rc::Rc;
4
5use maplibre_native_ffi_core as maplibre_core;
6use maplibre_native_ffi_core::ptr::{const_ptr_or_null, mut_ptr_or_null, option_ptr};
7use maplibre_native_ffi_core::values::{
8 empty_lat_lng, empty_lat_lng_bounds as empty_bounds, empty_screen_point, lat_lngs_to_native,
9 screen_points_to_native,
10};
11use maplibre_native_ffi_sys as sys;
12
13#[cfg(test)]
14use crate::PremultipliedRgba8Image;
15use crate::camera::{
16 AnimationOptionsNativeExt, BoundOptionsNativeExt, CameraFitOptionsNativeExt,
17 CameraOptionsNativeExt, FreeCameraOptionsNativeExt, ProjectionModeNativeExt,
18};
19#[cfg(test)]
20use crate::custom_geometry::CanonicalTileId;
21use crate::events::MapId;
22use crate::handle::{ThreadAffineNativeHandle, closed_handle_error};
23use crate::options::{MapOptionsNativeExt, MapTileOptionsNativeExt, MapViewportOptionsNativeExt};
24use crate::render::{
25 MetalBorrowedTextureDescriptor, MetalOwnedTextureDescriptor, MetalSurfaceDescriptor,
26 OpenGLBorrowedTextureDescriptor, OpenGLOwnedTextureDescriptor, OpenGLSurfaceDescriptor,
27 RenderSessionHandle, VulkanBorrowedTextureDescriptor, VulkanOwnedTextureDescriptor,
28 VulkanSurfaceDescriptor, WebGpuBorrowedTextureDescriptor, WebGpuOwnedTextureDescriptor,
29 WebGpuSurfaceDescriptor,
30};
31use crate::runtime::{RuntimeHandle, RuntimeState};
32use crate::values::NativeValue;
33use crate::{
34 AnimationOptions, BoundOptions, CameraFitOptions, CameraOptions, Error, ErrorKind,
35 FreeCameraOptions, HandleOperationError, LatLng, LatLngBounds, MapDebugOptions, MapOptions,
36 MapProjectionHandle, MapTileOptions, MapViewportOptions, ProjectionMode, Result,
37 RuntimeEventMask, ScreenPoint,
38};
39
40mod style;
41pub use style::{
42 GeoJsonSourceOptions, ImageContent, ImageStretch, LocationIndicatorImageKind,
43 RasterDemEncoding, SourceInfo, SourceType, StyleImage, StyleImageInfo, StyleImageOptions,
44 StyleImageTextFit, StyleLayerVisibility, StyleTransitionOptions, TileJsonInfo, TileScheme,
45 TileSourceOptions, VectorTileEncoding,
46};
47
48#[derive(Debug)]
49pub(crate) struct MapState {
50 handle: ThreadAffineNativeHandle<sys::mln_map>,
51 runtime: RefCell<Option<Rc<RuntimeState>>>,
52 id: MapId,
53}
54
55impl MapState {
56 fn new(native: sys::mln_map, runtime: Rc<RuntimeState>, id: MapId) -> Result<Self> {
57 let handle = unsafe {
60 ThreadAffineNativeHandle::from_handle(native, sys::mln_map_destroy, "mln_map")
61 }?;
62 Ok(Self {
63 handle,
64 runtime: RefCell::new(Some(runtime)),
65 id,
66 })
67 }
68
69 pub(crate) fn native(&self) -> Result<sys::mln_map> {
70 self.handle
71 .live_handle()
72 .ok_or_else(|| closed_handle_error("MapHandle"))
73 }
74
75 fn is_closed(&self) -> bool {
76 self.handle.is_closed()
77 }
78
79 fn close(&self) -> Result<()> {
80 self.handle.close()?;
83 self.runtime.borrow_mut().take();
84 Ok(())
85 }
86}
87
88impl Drop for MapState {
89 fn drop(&mut self) {
90 self.runtime.borrow_mut().take();
91 let _ = self.handle.close();
94 }
95}
96
97pub struct MapHandle {
99 pub(crate) inner: Rc<MapState>,
100}
101
102impl fmt::Debug for MapHandle {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 f.debug_struct("MapHandle")
105 .field("closed", &self.inner.is_closed())
106 .finish()
107 }
108}
109
110impl MapHandle {
111 pub fn with_options(runtime: &RuntimeHandle, options: &MapOptions) -> Result<Self> {
113 let runtime_ptr = runtime.inner.native()?;
114 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_map>::new();
115 let raw_options = options.to_native()?;
116
117 maplibre_core::check(unsafe {
121 sys::mln_map_create(runtime_ptr, &raw_options, out.as_mut_ptr())
122 })?;
123 let native = out.get();
124 let id = MapId::new(native.0);
125 let state = Rc::new(MapState::new(native, Rc::clone(&runtime.inner), id)?);
126
127 Ok(Self { inner: state })
128 }
129
130 pub fn id(&self) -> MapId {
132 self.inner.id
133 }
134
135 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
142 if self.inner.is_closed() {
143 return Ok(());
144 }
145 if Rc::strong_count(&self.inner) > 1 {
146 return Err(HandleOperationError::new(
147 Error::new(
148 ErrorKind::InvalidState,
149 None,
150 "MapHandle cannot close while child handles are live",
151 ),
152 self,
153 ));
154 }
155 self.inner
156 .close()
157 .map_err(|error| HandleOperationError::new(error, self))
158 }
159
160 pub fn request_repaint(&self) -> Result<()> {
162 let map = self.inner.native()?;
163 maplibre_core::check(unsafe { sys::mln_map_request_repaint(map) })
165 }
166
167 pub fn request_still_image(&self) -> Result<()> {
169 let map = self.inner.native()?;
170 maplibre_core::check(unsafe { sys::mln_map_request_still_image(map) })
172 }
173
174 pub fn set_event_mask(&self, mask: RuntimeEventMask) -> Result<()> {
182 let map = self.inner.native()?;
183 maplibre_core::check(unsafe { sys::mln_map_set_event_mask(map, mask.bits()) })
185 }
186
187 pub fn event_mask(&self) -> Result<RuntimeEventMask> {
190 let map = self.inner.native()?;
191 let mut raw = 0;
192 maplibre_core::check(unsafe { sys::mln_map_get_event_mask(map, &mut raw) })?;
194 Ok(RuntimeEventMask::from_bits_retain(raw))
195 }
196
197 pub fn set_debug_options(&self, options: MapDebugOptions) -> Result<()> {
199 let map = self.inner.native()?;
200 maplibre_core::check(unsafe { sys::mln_map_set_debug_options(map, options.bits()) })
202 }
203
204 pub fn debug_options(&self) -> Result<MapDebugOptions> {
206 let map = self.inner.native()?;
207 let mut raw = 0;
208 maplibre_core::check(unsafe { sys::mln_map_get_debug_options(map, &mut raw) })?;
210 Ok(MapDebugOptions::from_bits_retain(raw))
211 }
212
213 pub fn set_rendering_stats_view_enabled(&self, enabled: bool) -> Result<()> {
215 let map = self.inner.native()?;
216 maplibre_core::check(unsafe { sys::mln_map_set_rendering_stats_view_enabled(map, enabled) })
218 }
219
220 pub fn rendering_stats_view_enabled(&self) -> Result<bool> {
222 let map = self.inner.native()?;
223 let mut enabled = false;
224 maplibre_core::check(unsafe {
226 sys::mln_map_get_rendering_stats_view_enabled(map, &mut enabled)
227 })?;
228 Ok(enabled)
229 }
230
231 pub fn is_fully_loaded(&self) -> Result<bool> {
233 let map = self.inner.native()?;
234 let mut loaded = false;
235 maplibre_core::check(unsafe { sys::mln_map_is_fully_loaded(map, &mut loaded) })?;
237 Ok(loaded)
238 }
239
240 pub fn dump_debug_logs(&self) -> Result<()> {
242 let map = self.inner.native()?;
243 maplibre_core::check(unsafe { sys::mln_map_dump_debug_logs(map) })
245 }
246
247 pub fn size(&self) -> Result<(u32, u32, f64)> {
251 let map = self.inner.native()?;
252 let mut width = 0u32;
253 let mut height = 0u32;
254 let mut scale_factor = 0f64;
255 maplibre_core::check(unsafe {
258 sys::mln_map_get_size(map, &mut width, &mut height, &mut scale_factor)
259 })?;
260 Ok((width, height, scale_factor))
261 }
262
263 pub fn viewport_options(&self) -> Result<MapViewportOptions> {
265 let map = self.inner.native()?;
266 let mut raw = unsafe { sys::mln_map_viewport_options_default() };
268 maplibre_core::check(unsafe { sys::mln_map_get_viewport_options(map, &mut raw) })?;
270 Ok(MapViewportOptions::from_native(raw))
271 }
272
273 pub fn set_viewport_options(&self, options: &MapViewportOptions) -> Result<()> {
275 let map = self.inner.native()?;
276 let raw = options.to_native();
277 maplibre_core::check(unsafe { sys::mln_map_set_viewport_options(map, &raw) })
280 }
281
282 pub fn tile_options(&self) -> Result<MapTileOptions> {
284 let map = self.inner.native()?;
285 let mut raw = unsafe { sys::mln_map_tile_options_default() };
287 maplibre_core::check(unsafe { sys::mln_map_get_tile_options(map, &mut raw) })?;
289 Ok(MapTileOptions::from_native(raw))
290 }
291
292 pub fn set_tile_options(&self, options: &MapTileOptions) -> Result<()> {
294 let map = self.inner.native()?;
295 let raw = options.to_native();
296 maplibre_core::check(unsafe { sys::mln_map_set_tile_options(map, &raw) })
299 }
300
301 pub fn camera(&self) -> Result<CameraOptions> {
303 let map = self.inner.native()?;
304 let mut raw = unsafe { sys::mln_camera_options_default() };
306 maplibre_core::check(unsafe { sys::mln_map_get_camera(map, &mut raw) })?;
308 Ok(CameraOptions::from_native(raw))
309 }
310
311 pub fn jump_to(&self, camera: &CameraOptions) -> Result<()> {
313 let map = self.inner.native()?;
314 let raw = camera.to_native();
315 maplibre_core::check(unsafe { sys::mln_map_jump_to(map, &raw) })
318 }
319
320 pub fn ease_to(
323 &self,
324 camera: &CameraOptions,
325 animation: Option<&AnimationOptions>,
326 ) -> Result<()> {
327 let map = self.inner.native()?;
328 let raw_camera = camera.to_native();
329 let raw_animation = animation.map(AnimationOptions::to_native);
330 maplibre_core::check(unsafe {
333 sys::mln_map_ease_to(map, &raw_camera, option_ptr(raw_animation.as_ref()))
334 })
335 }
336
337 pub fn fly_to(
341 &self,
342 camera: &CameraOptions,
343 animation: Option<&AnimationOptions>,
344 ) -> Result<()> {
345 let map = self.inner.native()?;
346 let raw_camera = camera.to_native();
347 let raw_animation = animation.map(AnimationOptions::to_native);
348 maplibre_core::check(unsafe {
351 sys::mln_map_fly_to(map, &raw_camera, option_ptr(raw_animation.as_ref()))
352 })
353 }
354
355 pub fn move_by(&self, delta_x: f64, delta_y: f64) -> Result<()> {
357 let map = self.inner.native()?;
358 maplibre_core::check(unsafe { sys::mln_map_move_by(map, delta_x, delta_y) })
360 }
361
362 pub fn move_by_animated(
366 &self,
367 delta_x: f64,
368 delta_y: f64,
369 animation: Option<&AnimationOptions>,
370 ) -> Result<()> {
371 let map = self.inner.native()?;
372 let raw_animation = animation.map(AnimationOptions::to_native);
373 maplibre_core::check(unsafe {
376 sys::mln_map_move_by_animated(map, delta_x, delta_y, option_ptr(raw_animation.as_ref()))
377 })
378 }
379
380 pub fn scale_by(&self, scale: f64, anchor: Option<ScreenPoint>) -> Result<()> {
382 let map = self.inner.native()?;
383 let raw_anchor = anchor.map(ScreenPoint::to_native);
384 maplibre_core::check(unsafe {
387 sys::mln_map_scale_by(map, scale, option_ptr(raw_anchor.as_ref()))
388 })
389 }
390
391 pub fn scale_by_animated(
395 &self,
396 scale: f64,
397 anchor: Option<ScreenPoint>,
398 animation: Option<&AnimationOptions>,
399 ) -> Result<()> {
400 let map = self.inner.native()?;
401 let raw_anchor = anchor.map(ScreenPoint::to_native);
402 let raw_animation = animation.map(AnimationOptions::to_native);
403 maplibre_core::check(unsafe {
406 sys::mln_map_scale_by_animated(
407 map,
408 scale,
409 option_ptr(raw_anchor.as_ref()),
410 option_ptr(raw_animation.as_ref()),
411 )
412 })
413 }
414
415 pub fn rotate_by(&self, first: ScreenPoint, second: ScreenPoint) -> Result<()> {
417 let map = self.inner.native()?;
418 maplibre_core::check(unsafe {
420 sys::mln_map_rotate_by(map, first.to_native(), second.to_native())
421 })
422 }
423
424 pub fn rotate_by_animated(
428 &self,
429 first: ScreenPoint,
430 second: ScreenPoint,
431 animation: Option<&AnimationOptions>,
432 ) -> Result<()> {
433 let map = self.inner.native()?;
434 let raw_animation = animation.map(AnimationOptions::to_native);
435 maplibre_core::check(unsafe {
438 sys::mln_map_rotate_by_animated(
439 map,
440 first.to_native(),
441 second.to_native(),
442 option_ptr(raw_animation.as_ref()),
443 )
444 })
445 }
446
447 pub fn pitch_by(&self, pitch: f64) -> Result<()> {
449 let map = self.inner.native()?;
450 maplibre_core::check(unsafe { sys::mln_map_pitch_by(map, pitch) })
452 }
453
454 pub fn pitch_by_animated(
458 &self,
459 pitch: f64,
460 animation: Option<&AnimationOptions>,
461 ) -> Result<()> {
462 let map = self.inner.native()?;
463 let raw_animation = animation.map(AnimationOptions::to_native);
464 maplibre_core::check(unsafe {
467 sys::mln_map_pitch_by_animated(map, pitch, option_ptr(raw_animation.as_ref()))
468 })
469 }
470
471 pub fn cancel_transitions(&self) -> Result<()> {
473 let map = self.inner.native()?;
474 maplibre_core::check(unsafe { sys::mln_map_cancel_transitions(map) })
476 }
477
478 pub fn set_gesture_in_progress(&self, in_progress: bool) -> Result<()> {
481 let map = self.inner.native()?;
482 maplibre_core::check(unsafe { sys::mln_map_set_gesture_in_progress(map, in_progress) })
484 }
485
486 pub fn is_gesture_in_progress(&self) -> Result<bool> {
488 let map = self.inner.native()?;
489 let mut in_progress = false;
490 maplibre_core::check(unsafe {
493 sys::mln_map_is_gesture_in_progress(map, &mut in_progress)
494 })?;
495 Ok(in_progress)
496 }
497
498 pub fn camera_for_lat_lng_bounds(
500 &self,
501 bounds: LatLngBounds,
502 fit_options: Option<&CameraFitOptions>,
503 ) -> Result<CameraOptions> {
504 let map = self.inner.native()?;
505 let raw_fit = fit_options.map(CameraFitOptions::to_native);
506 let mut raw_camera = unsafe { sys::mln_camera_options_default() };
508 maplibre_core::check(unsafe {
511 sys::mln_map_camera_for_lat_lng_bounds(
512 map,
513 bounds.to_native(),
514 option_ptr(raw_fit.as_ref()),
515 &mut raw_camera,
516 )
517 })?;
518 Ok(CameraOptions::from_native(raw_camera))
519 }
520
521 pub fn camera_for_lat_lngs(
523 &self,
524 coordinates: &[LatLng],
525 fit_options: Option<&CameraFitOptions>,
526 ) -> Result<CameraOptions> {
527 let map = self.inner.native()?;
528 if coordinates.is_empty() {
529 return Err(Error::invalid_argument(
530 "camera_for_lat_lngs requires at least one coordinate",
531 ));
532 }
533 let raw_coordinates = lat_lngs_to_native(coordinates);
534 let raw_fit = fit_options.map(CameraFitOptions::to_native);
535 let mut raw_camera = unsafe { sys::mln_camera_options_default() };
537 maplibre_core::check(unsafe {
540 sys::mln_map_camera_for_lat_lngs(
541 map,
542 const_ptr_or_null(&raw_coordinates),
543 raw_coordinates.len(),
544 option_ptr(raw_fit.as_ref()),
545 &mut raw_camera,
546 )
547 })?;
548 Ok(CameraOptions::from_native(raw_camera))
549 }
550
551 pub fn camera_for_geometry(
553 &self,
554 geometry: &[u8],
555 fit_options: Option<&CameraFitOptions>,
556 ) -> Result<CameraOptions> {
557 let map = self.inner.native()?;
558 let native_geometry = maplibre_core::string::buffer_view(geometry);
559 let raw_fit = fit_options.map(CameraFitOptions::to_native);
560 let mut raw_camera = unsafe { sys::mln_camera_options_default() };
562 maplibre_core::check(unsafe {
566 sys::mln_map_camera_for_geometry(
567 map,
568 native_geometry,
569 option_ptr(raw_fit.as_ref()),
570 &mut raw_camera,
571 )
572 })?;
573 Ok(CameraOptions::from_native(raw_camera))
574 }
575
576 pub fn lat_lng_bounds_for_camera(&self, camera: &CameraOptions) -> Result<LatLngBounds> {
583 let map = self.inner.native()?;
584 let raw_camera = camera.to_native();
585 let mut raw_bounds = empty_bounds();
586 maplibre_core::check(unsafe {
589 sys::mln_map_lat_lng_bounds_for_camera(map, &raw_camera, &mut raw_bounds)
590 })?;
591 Ok(LatLngBounds::from_native(raw_bounds))
592 }
593
594 pub fn lat_lng_bounds_for_camera_unwrapped(
601 &self,
602 camera: &CameraOptions,
603 ) -> Result<LatLngBounds> {
604 let map = self.inner.native()?;
605 let raw_camera = camera.to_native();
606 let mut raw_bounds = empty_bounds();
607 maplibre_core::check(unsafe {
610 sys::mln_map_lat_lng_bounds_for_camera_unwrapped(map, &raw_camera, &mut raw_bounds)
611 })?;
612 Ok(LatLngBounds::from_native(raw_bounds))
613 }
614
615 pub fn bounds(&self) -> Result<BoundOptions> {
617 let map = self.inner.native()?;
618 let mut raw = unsafe { sys::mln_bound_options_default() };
620 maplibre_core::check(unsafe { sys::mln_map_get_bounds(map, &mut raw) })?;
622 Ok(BoundOptions::from_native(raw))
623 }
624
625 pub fn set_bounds(&self, options: &BoundOptions) -> Result<()> {
627 let map = self.inner.native()?;
628 let raw = options.to_native();
629 maplibre_core::check(unsafe { sys::mln_map_set_bounds(map, &raw) })
631 }
632
633 pub fn free_camera_options(&self) -> Result<FreeCameraOptions> {
635 let map = self.inner.native()?;
636 let mut raw = unsafe { sys::mln_free_camera_options_default() };
638 maplibre_core::check(unsafe { sys::mln_map_get_free_camera_options(map, &mut raw) })?;
640 Ok(FreeCameraOptions::from_native(raw))
641 }
642
643 pub fn set_free_camera_options(&self, options: &FreeCameraOptions) -> Result<()> {
645 let map = self.inner.native()?;
646 let raw = options.to_native();
647 maplibre_core::check(unsafe { sys::mln_map_set_free_camera_options(map, &raw) })
649 }
650
651 pub fn projection_mode(&self) -> Result<ProjectionMode> {
653 let map = self.inner.native()?;
654 let mut raw = unsafe { sys::mln_projection_mode_default() };
656 maplibre_core::check(unsafe { sys::mln_map_get_projection_mode(map, &mut raw) })?;
658 Ok(ProjectionMode::from_native(raw))
659 }
660
661 pub fn set_projection_mode(&self, mode: &ProjectionMode) -> Result<()> {
663 let map = self.inner.native()?;
664 let raw = mode.to_native();
665 maplibre_core::check(unsafe { sys::mln_map_set_projection_mode(map, &raw) })
667 }
668
669 pub fn pixel_for_lat_lng(&self, coordinate: LatLng) -> Result<ScreenPoint> {
671 let map = self.inner.native()?;
672 let mut raw_point = empty_screen_point();
673 maplibre_core::check(unsafe {
676 sys::mln_map_pixel_for_lat_lng(map, coordinate.to_native(), &mut raw_point)
677 })?;
678 Ok(ScreenPoint::from_native(raw_point))
679 }
680
681 pub fn lat_lng_for_pixel(&self, point: ScreenPoint) -> Result<LatLng> {
683 let map = self.inner.native()?;
684 let mut raw_coordinate = empty_lat_lng();
685 maplibre_core::check(unsafe {
688 sys::mln_map_lat_lng_for_pixel(map, point.to_native(), &mut raw_coordinate)
689 })?;
690 Ok(LatLng::from_native(raw_coordinate))
691 }
692
693 pub fn pixels_for_lat_lngs(&self, coordinates: &[LatLng]) -> Result<Vec<ScreenPoint>> {
695 let map = self.inner.native()?;
696 let raw_coordinates = lat_lngs_to_native(coordinates);
697 let mut raw_points = vec![empty_screen_point(); coordinates.len()];
698 maplibre_core::check(unsafe {
701 sys::mln_map_pixels_for_lat_lngs(
702 map,
703 const_ptr_or_null(&raw_coordinates),
704 raw_coordinates.len(),
705 mut_ptr_or_null(&mut raw_points),
706 )
707 })?;
708 Ok(raw_points
709 .into_iter()
710 .map(ScreenPoint::from_native)
711 .collect())
712 }
713
714 pub fn lat_lngs_for_pixels(&self, points: &[ScreenPoint]) -> Result<Vec<LatLng>> {
716 let map = self.inner.native()?;
717 let raw_points = screen_points_to_native(points);
718 let mut raw_coordinates = vec![empty_lat_lng(); points.len()];
719 maplibre_core::check(unsafe {
722 sys::mln_map_lat_lngs_for_pixels(
723 map,
724 const_ptr_or_null(&raw_points),
725 raw_points.len(),
726 mut_ptr_or_null(&mut raw_coordinates),
727 )
728 })?;
729 Ok(raw_coordinates
730 .into_iter()
731 .map(LatLng::from_native)
732 .collect())
733 }
734
735 pub fn create_projection(&self) -> Result<MapProjectionHandle> {
737 MapProjectionHandle::new(self)
738 }
739
740 pub fn attach_ref(&self) -> Result<MapAttachRef> {
744 Ok(MapAttachRef {
745 map: self.inner.native()?,
746 })
747 }
748}
749
750#[derive(Clone, Copy)]
763pub struct MapAttachRef {
764 map: sys::mln_map,
765}
766
767impl fmt::Debug for MapAttachRef {
768 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
769 f.debug_struct("MapAttachRef").finish()
770 }
771}
772
773impl MapAttachRef {
774 pub(crate) fn map(&self) -> sys::mln_map {
776 self.map
777 }
778
779 pub fn attach_metal_surface(
785 &self,
786 descriptor: &MetalSurfaceDescriptor,
787 ) -> Result<RenderSessionHandle> {
788 let raw = descriptor.to_native();
789 RenderSessionHandle::attach(self, |map, out| {
790 unsafe { sys::mln_metal_surface_attach(map, &raw, out) }
793 })
794 }
795
796 pub fn attach_vulkan_surface(
801 &self,
802 descriptor: &VulkanSurfaceDescriptor,
803 ) -> Result<RenderSessionHandle> {
804 let raw = descriptor.to_native();
805 RenderSessionHandle::attach(self, |map, out| {
806 unsafe { sys::mln_vulkan_surface_attach(map, &raw, out) }
809 })
810 }
811
812 pub fn attach_webgpu_surface(
817 &self,
818 descriptor: &WebGpuSurfaceDescriptor,
819 ) -> Result<RenderSessionHandle> {
820 let raw = descriptor.to_native();
821 RenderSessionHandle::attach(self, |map, out| {
822 unsafe { sys::mln_webgpu_surface_attach(map, &raw, out) }
825 })
826 }
827
828 pub fn attach_opengl_surface(
834 &self,
835 descriptor: &OpenGLSurfaceDescriptor,
836 ) -> Result<RenderSessionHandle> {
837 let raw = descriptor.to_native();
838 RenderSessionHandle::attach(self, |map, out| {
839 unsafe { sys::mln_opengl_surface_attach(map, &raw, out) }
842 })
843 }
844
845 pub fn attach_metal_owned_texture(
850 &self,
851 descriptor: &MetalOwnedTextureDescriptor,
852 ) -> Result<RenderSessionHandle> {
853 let raw = descriptor.to_native();
854 RenderSessionHandle::attach(self, |map, out| {
855 unsafe { sys::mln_metal_owned_texture_attach(map, &raw, out) }
858 })
859 }
860
861 pub fn attach_metal_borrowed_texture(
866 &self,
867 descriptor: &MetalBorrowedTextureDescriptor,
868 ) -> Result<RenderSessionHandle> {
869 let raw = descriptor.to_native();
870 RenderSessionHandle::attach(self, |map, out| {
871 unsafe { sys::mln_metal_borrowed_texture_attach(map, &raw, out) }
874 })
875 }
876
877 pub fn attach_vulkan_owned_texture(
882 &self,
883 descriptor: &VulkanOwnedTextureDescriptor,
884 ) -> Result<RenderSessionHandle> {
885 let raw = descriptor.to_native();
886 RenderSessionHandle::attach(self, |map, out| {
887 unsafe { sys::mln_vulkan_owned_texture_attach(map, &raw, out) }
890 })
891 }
892
893 pub fn attach_vulkan_borrowed_texture(
899 &self,
900 descriptor: &VulkanBorrowedTextureDescriptor,
901 ) -> Result<RenderSessionHandle> {
902 let raw = descriptor.to_native();
903 RenderSessionHandle::attach(self, |map, out| {
904 unsafe { sys::mln_vulkan_borrowed_texture_attach(map, &raw, out) }
907 })
908 }
909
910 pub fn attach_webgpu_owned_texture(
916 &self,
917 descriptor: &WebGpuOwnedTextureDescriptor,
918 ) -> Result<RenderSessionHandle> {
919 let raw = descriptor.to_native();
920 RenderSessionHandle::attach(self, |map, out| {
921 unsafe { sys::mln_webgpu_owned_texture_attach(map, &raw, out) }
924 })
925 }
926
927 pub fn attach_webgpu_borrowed_texture(
933 &self,
934 descriptor: &WebGpuBorrowedTextureDescriptor,
935 ) -> Result<RenderSessionHandle> {
936 let raw = descriptor.to_native();
937 RenderSessionHandle::attach(self, |map, out| {
938 unsafe { sys::mln_webgpu_borrowed_texture_attach(map, &raw, out) }
941 })
942 }
943
944 pub fn attach_opengl_owned_texture(
950 &self,
951 descriptor: &OpenGLOwnedTextureDescriptor,
952 ) -> Result<RenderSessionHandle> {
953 let raw = descriptor.to_native();
954 RenderSessionHandle::attach(self, |map, out| {
955 unsafe { sys::mln_opengl_owned_texture_attach(map, &raw, out) }
958 })
959 }
960
961 pub fn attach_opengl_borrowed_texture(
967 &self,
968 descriptor: &OpenGLBorrowedTextureDescriptor,
969 ) -> Result<RenderSessionHandle> {
970 let raw = descriptor.to_native();
971 RenderSessionHandle::attach(self, |map, out| {
972 unsafe { sys::mln_opengl_borrowed_texture_attach(map, &raw, out) }
975 })
976 }
977}
978
979#[cfg(test)]
980mod tests;