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> {
685 let map = self.inner.native()?;
686 let mut raw_coordinate = empty_lat_lng();
687 maplibre_core::check(unsafe {
690 sys::mln_map_lat_lng_for_pixel(map, point.to_native(), &mut raw_coordinate)
691 })?;
692 Ok(LatLng::from_native(raw_coordinate))
693 }
694
695 pub fn lat_lng_for_pixel_unwrapped(&self, point: ScreenPoint) -> Result<LatLng> {
700 let map = self.inner.native()?;
701 let mut raw_coordinate = empty_lat_lng();
702 maplibre_core::check(unsafe {
705 sys::mln_map_lat_lng_for_pixel_unwrapped(map, point.to_native(), &mut raw_coordinate)
706 })?;
707 Ok(LatLng::from_native(raw_coordinate))
708 }
709
710 pub fn pixels_for_lat_lngs(&self, coordinates: &[LatLng]) -> Result<Vec<ScreenPoint>> {
712 let map = self.inner.native()?;
713 let raw_coordinates = lat_lngs_to_native(coordinates);
714 let mut raw_points = vec![empty_screen_point(); coordinates.len()];
715 maplibre_core::check(unsafe {
718 sys::mln_map_pixels_for_lat_lngs(
719 map,
720 const_ptr_or_null(&raw_coordinates),
721 raw_coordinates.len(),
722 mut_ptr_or_null(&mut raw_points),
723 )
724 })?;
725 Ok(raw_points
726 .into_iter()
727 .map(ScreenPoint::from_native)
728 .collect())
729 }
730
731 pub fn lat_lngs_for_pixels(&self, points: &[ScreenPoint]) -> Result<Vec<LatLng>> {
735 let map = self.inner.native()?;
736 let raw_points = screen_points_to_native(points);
737 let mut raw_coordinates = vec![empty_lat_lng(); points.len()];
738 maplibre_core::check(unsafe {
741 sys::mln_map_lat_lngs_for_pixels(
742 map,
743 const_ptr_or_null(&raw_points),
744 raw_points.len(),
745 mut_ptr_or_null(&mut raw_coordinates),
746 )
747 })?;
748 Ok(raw_coordinates
749 .into_iter()
750 .map(LatLng::from_native)
751 .collect())
752 }
753
754 pub fn lat_lngs_for_pixels_unwrapped(&self, points: &[ScreenPoint]) -> Result<Vec<LatLng>> {
759 let map = self.inner.native()?;
760 let raw_points = screen_points_to_native(points);
761 let mut raw_coordinates = vec![empty_lat_lng(); points.len()];
762 maplibre_core::check(unsafe {
765 sys::mln_map_lat_lngs_for_pixels_unwrapped(
766 map,
767 const_ptr_or_null(&raw_points),
768 raw_points.len(),
769 mut_ptr_or_null(&mut raw_coordinates),
770 )
771 })?;
772 Ok(raw_coordinates
773 .into_iter()
774 .map(LatLng::from_native)
775 .collect())
776 }
777
778 pub fn create_projection(&self) -> Result<MapProjectionHandle> {
780 MapProjectionHandle::new(self)
781 }
782
783 pub fn attach_ref(&self) -> Result<MapAttachRef> {
787 Ok(MapAttachRef {
788 map: self.inner.native()?,
789 })
790 }
791}
792
793#[derive(Clone, Copy)]
806pub struct MapAttachRef {
807 map: sys::mln_map,
808}
809
810impl fmt::Debug for MapAttachRef {
811 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
812 f.debug_struct("MapAttachRef").finish()
813 }
814}
815
816impl MapAttachRef {
817 pub(crate) fn map(&self) -> sys::mln_map {
819 self.map
820 }
821
822 pub fn attach_metal_surface(
828 &self,
829 descriptor: &MetalSurfaceDescriptor,
830 ) -> Result<RenderSessionHandle> {
831 let raw = descriptor.to_native();
832 RenderSessionHandle::attach(self, |map, out| {
833 unsafe { sys::mln_metal_surface_attach(map, &raw, out) }
836 })
837 }
838
839 pub fn attach_vulkan_surface(
844 &self,
845 descriptor: &VulkanSurfaceDescriptor,
846 ) -> Result<RenderSessionHandle> {
847 let raw = descriptor.to_native();
848 RenderSessionHandle::attach(self, |map, out| {
849 unsafe { sys::mln_vulkan_surface_attach(map, &raw, out) }
852 })
853 }
854
855 pub fn attach_webgpu_surface(
860 &self,
861 descriptor: &WebGpuSurfaceDescriptor,
862 ) -> Result<RenderSessionHandle> {
863 let raw = descriptor.to_native();
864 RenderSessionHandle::attach(self, |map, out| {
865 unsafe { sys::mln_webgpu_surface_attach(map, &raw, out) }
868 })
869 }
870
871 pub fn attach_opengl_surface(
877 &self,
878 descriptor: &OpenGLSurfaceDescriptor,
879 ) -> Result<RenderSessionHandle> {
880 let raw = descriptor.to_native();
881 RenderSessionHandle::attach(self, |map, out| {
882 unsafe { sys::mln_opengl_surface_attach(map, &raw, out) }
885 })
886 }
887
888 pub fn attach_metal_owned_texture(
893 &self,
894 descriptor: &MetalOwnedTextureDescriptor,
895 ) -> Result<RenderSessionHandle> {
896 let raw = descriptor.to_native();
897 RenderSessionHandle::attach(self, |map, out| {
898 unsafe { sys::mln_metal_owned_texture_attach(map, &raw, out) }
901 })
902 }
903
904 pub fn attach_metal_borrowed_texture(
909 &self,
910 descriptor: &MetalBorrowedTextureDescriptor,
911 ) -> Result<RenderSessionHandle> {
912 let raw = descriptor.to_native();
913 RenderSessionHandle::attach(self, |map, out| {
914 unsafe { sys::mln_metal_borrowed_texture_attach(map, &raw, out) }
917 })
918 }
919
920 pub fn attach_vulkan_owned_texture(
925 &self,
926 descriptor: &VulkanOwnedTextureDescriptor,
927 ) -> Result<RenderSessionHandle> {
928 let raw = descriptor.to_native();
929 RenderSessionHandle::attach(self, |map, out| {
930 unsafe { sys::mln_vulkan_owned_texture_attach(map, &raw, out) }
933 })
934 }
935
936 pub fn attach_vulkan_borrowed_texture(
942 &self,
943 descriptor: &VulkanBorrowedTextureDescriptor,
944 ) -> Result<RenderSessionHandle> {
945 let raw = descriptor.to_native();
946 RenderSessionHandle::attach(self, |map, out| {
947 unsafe { sys::mln_vulkan_borrowed_texture_attach(map, &raw, out) }
950 })
951 }
952
953 pub fn attach_webgpu_owned_texture(
959 &self,
960 descriptor: &WebGpuOwnedTextureDescriptor,
961 ) -> Result<RenderSessionHandle> {
962 let raw = descriptor.to_native();
963 RenderSessionHandle::attach(self, |map, out| {
964 unsafe { sys::mln_webgpu_owned_texture_attach(map, &raw, out) }
967 })
968 }
969
970 pub fn attach_webgpu_borrowed_texture(
976 &self,
977 descriptor: &WebGpuBorrowedTextureDescriptor,
978 ) -> Result<RenderSessionHandle> {
979 let raw = descriptor.to_native();
980 RenderSessionHandle::attach(self, |map, out| {
981 unsafe { sys::mln_webgpu_borrowed_texture_attach(map, &raw, out) }
984 })
985 }
986
987 pub fn attach_opengl_owned_texture(
993 &self,
994 descriptor: &OpenGLOwnedTextureDescriptor,
995 ) -> Result<RenderSessionHandle> {
996 let raw = descriptor.to_native();
997 RenderSessionHandle::attach(self, |map, out| {
998 unsafe { sys::mln_opengl_owned_texture_attach(map, &raw, out) }
1001 })
1002 }
1003
1004 pub fn attach_opengl_borrowed_texture(
1010 &self,
1011 descriptor: &OpenGLBorrowedTextureDescriptor,
1012 ) -> Result<RenderSessionHandle> {
1013 let raw = descriptor.to_native();
1014 RenderSessionHandle::attach(self, |map, out| {
1015 unsafe { sys::mln_opengl_borrowed_texture_attach(map, &raw, out) }
1018 })
1019 }
1020}
1021
1022#[cfg(test)]
1023mod tests;