1use std::cell::Cell;
2use std::fmt;
3use std::marker::PhantomData;
4use std::mem;
5use std::rc::Rc;
6
7pub use maplibre_core::{PremultipliedRgba8Image, TextureImageInfo};
8use maplibre_native_ffi_core as maplibre_core;
9use maplibre_native_ffi_core::{OpenGLClientApi, OpenGLContextOwnership, RenderResult};
10use maplibre_native_ffi_sys as sys;
11
12use crate::handle::{ThreadAffineNativeHandle, closed_handle_error, out_handle};
13use crate::map::MapAttachRef;
14use crate::{HandleOperationError, Result};
15
16#[derive(Clone, Copy, PartialEq, Eq, Hash)]
20pub struct NativePointer {
21 address: usize,
22 _thread_affine: PhantomData<Rc<()>>,
23}
24
25impl NativePointer {
26 pub const NULL: Self = Self {
28 address: 0,
29 _thread_affine: PhantomData,
30 };
31
32 pub unsafe fn from_address(address: usize) -> Self {
40 if address == 0 {
41 Self::NULL
42 } else {
43 Self {
44 address,
45 _thread_affine: PhantomData,
46 }
47 }
48 }
49
50 pub unsafe fn from_ptr<T>(ptr: *mut T) -> Self {
57 unsafe { Self::from_address(ptr as usize) }
60 }
61
62 pub fn address(self) -> usize {
64 self.address
65 }
66
67 pub fn is_null(self) -> bool {
69 self.address == 0
70 }
71
72 pub unsafe fn as_ptr<T>(self) -> *mut T {
80 self.address as *mut T
81 }
82
83 fn as_void_ptr(self) -> *mut std::ffi::c_void {
84 self.address as *mut std::ffi::c_void
85 }
86}
87
88impl fmt::Debug for NativePointer {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(f, "NativePointer(0x{:x})", self.address)
91 }
92}
93
94#[derive(Clone, Copy, PartialEq, Eq, Hash)]
97pub struct VulkanHandle {
98 bits: u64,
99 _thread_affine: PhantomData<Rc<()>>,
100}
101
102impl VulkanHandle {
103 pub const NULL: Self = Self {
105 bits: 0,
106 _thread_affine: PhantomData,
107 };
108
109 pub unsafe fn from_bits(bits: u64) -> Self {
117 Self {
118 bits,
119 _thread_affine: PhantomData,
120 }
121 }
122
123 pub fn bits(self) -> u64 {
125 self.bits
126 }
127
128 pub fn is_null(self) -> bool {
130 self.bits == 0
131 }
132}
133
134impl fmt::Debug for VulkanHandle {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 write!(f, "VulkanHandle(0x{:x})", self.bits)
137 }
138}
139
140#[derive(Clone, Copy, PartialEq, Eq, Hash)]
142pub struct FrameVulkanHandle<'frame> {
143 bits: u64,
144 _frame: PhantomData<&'frame ()>,
145 _thread_affine: PhantomData<Rc<()>>,
146}
147
148impl<'frame> FrameVulkanHandle<'frame> {
149 fn new(bits: u64) -> Self {
150 Self {
151 bits,
152 _frame: PhantomData,
153 _thread_affine: PhantomData,
154 }
155 }
156
157 pub unsafe fn bits(self) -> u64 {
165 self.bits
166 }
167
168 pub fn is_null(self) -> bool {
170 self.bits == 0
171 }
172}
173
174impl fmt::Debug for FrameVulkanHandle<'_> {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 write!(f, "FrameVulkanHandle(0x{:x})", self.bits)
177 }
178}
179
180#[derive(Clone, Copy, PartialEq, Eq, Hash)]
184pub struct FrameNativePointer<'frame> {
185 address: usize,
186 _frame: PhantomData<&'frame ()>,
187 _thread_affine: PhantomData<Rc<()>>,
188}
189
190impl<'frame> FrameNativePointer<'frame> {
191 unsafe fn from_ptr<T>(ptr: *mut T) -> Self {
192 Self {
193 address: ptr as usize,
194 _frame: PhantomData,
195 _thread_affine: PhantomData,
196 }
197 }
198
199 pub unsafe fn address(self) -> usize {
208 self.address
209 }
210
211 pub fn is_null(self) -> bool {
213 self.address == 0
214 }
215
216 pub unsafe fn as_ptr<T>(self) -> *mut T {
224 self.address as *mut T
225 }
226}
227
228impl fmt::Debug for FrameNativePointer<'_> {
229 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230 write!(f, "FrameNativePointer(0x{:x})", self.address)
231 }
232}
233
234#[derive(Clone, Copy, PartialEq, Eq, Hash)]
236pub struct FrameOpenGLTextureName<'frame> {
237 name: u32,
238 _frame: PhantomData<&'frame ()>,
239 _thread_affine: PhantomData<Rc<()>>,
240}
241
242impl<'frame> FrameOpenGLTextureName<'frame> {
243 fn new(name: u32) -> Self {
244 Self {
245 name,
246 _frame: PhantomData,
247 _thread_affine: PhantomData,
248 }
249 }
250
251 pub fn is_zero(self) -> bool {
253 self.name == 0
254 }
255
256 pub unsafe fn value(self) -> u32 {
264 self.name
265 }
266}
267
268impl fmt::Debug for FrameOpenGLTextureName<'_> {
269 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270 write!(f, "FrameOpenGLTextureName({})", self.name)
271 }
272}
273
274mod query;
275pub use query::{
276 FeatureStateSelector, QueriedFeature, RenderedFeatureQueryOptions, RenderedQueryGeometry,
277 SourceFeatureQueryOptions,
278};
279#[derive(Debug, Clone, PartialEq)]
280#[non_exhaustive]
281pub struct RenderTargetExtent {
282 pub width: u32,
283 pub height: u32,
284 pub scale_factor: f64,
285}
286
287impl RenderTargetExtent {
288 pub fn new(width: u32, height: u32, scale_factor: f64) -> Self {
289 Self {
290 width,
291 height,
292 scale_factor,
293 }
294 }
295
296 pub(crate) fn to_core(&self) -> maplibre_core::render::RenderTargetExtentFields {
297 maplibre_core::render::RenderTargetExtentFields {
298 width: self.width,
299 height: self.height,
300 scale_factor: self.scale_factor,
301 }
302 }
303
304 pub fn physical_size(&self) -> Result<(u32, u32)> {
309 let native = maplibre_core::render::render_target_extent_to_native(self.to_core());
310 let mut width = 0u32;
311 let mut height = 0u32;
312 maplibre_core::check(unsafe {
315 sys::mln_render_target_extent_physical_size(&native, &mut width, &mut height)
316 })?;
317 Ok((width, height))
318 }
319}
320
321impl Default for RenderTargetExtent {
322 fn default() -> Self {
323 Self::new(256, 256, 1.0)
324 }
325}
326
327#[derive(Debug, Clone, PartialEq)]
328#[non_exhaustive]
329pub struct MetalContextDescriptor {
330 pub device: NativePointer,
331}
332
333impl MetalContextDescriptor {
334 pub fn new(device: NativePointer) -> Self {
335 Self { device }
336 }
337
338 pub(crate) fn to_core(&self) -> maplibre_core::render::MetalContextDescriptorFields {
339 maplibre_core::render::MetalContextDescriptorFields {
340 device: self.device.as_void_ptr(),
341 }
342 }
343}
344
345impl Default for MetalContextDescriptor {
346 fn default() -> Self {
347 Self::new(NativePointer::NULL)
348 }
349}
350
351#[derive(Debug, Clone, PartialEq)]
352#[non_exhaustive]
353pub struct VulkanContextDescriptor {
354 pub instance: NativePointer,
355 pub physical_device: NativePointer,
356 pub device: NativePointer,
357 pub graphics_queue: NativePointer,
358 pub graphics_queue_family_index: u32,
359 pub get_instance_proc_addr: NativePointer,
360 pub get_device_proc_addr: NativePointer,
361}
362
363impl VulkanContextDescriptor {
364 #[allow(clippy::too_many_arguments)]
365 pub fn new(
366 instance: NativePointer,
367 physical_device: NativePointer,
368 device: NativePointer,
369 graphics_queue: NativePointer,
370 graphics_queue_family_index: u32,
371 ) -> Self {
372 Self {
373 instance,
374 physical_device,
375 device,
376 graphics_queue,
377 graphics_queue_family_index,
378 get_instance_proc_addr: NativePointer::NULL,
379 get_device_proc_addr: NativePointer::NULL,
380 }
381 }
382
383 pub(crate) fn to_core(&self) -> maplibre_core::render::VulkanContextDescriptorFields {
384 maplibre_core::render::VulkanContextDescriptorFields {
385 instance: self.instance.as_void_ptr(),
386 physical_device: self.physical_device.as_void_ptr(),
387 device: self.device.as_void_ptr(),
388 graphics_queue: self.graphics_queue.as_void_ptr(),
389 graphics_queue_family_index: self.graphics_queue_family_index,
390 get_instance_proc_addr: self.get_instance_proc_addr.as_void_ptr(),
391 get_device_proc_addr: self.get_device_proc_addr.as_void_ptr(),
392 }
393 }
394}
395
396impl Default for VulkanContextDescriptor {
397 fn default() -> Self {
398 Self::new(
399 NativePointer::NULL,
400 NativePointer::NULL,
401 NativePointer::NULL,
402 NativePointer::NULL,
403 0,
404 )
405 }
406}
407
408#[derive(Debug, Clone, PartialEq)]
414#[non_exhaustive]
415pub struct WebGpuContextDescriptor {
416 pub instance: NativePointer,
418 pub device: NativePointer,
419 pub queue: NativePointer,
422}
423
424impl WebGpuContextDescriptor {
425 pub fn new(device: NativePointer) -> Self {
426 Self {
427 instance: NativePointer::NULL,
428 device,
429 queue: NativePointer::NULL,
430 }
431 }
432
433 pub(crate) fn to_core(&self) -> maplibre_core::render::WebGpuContextDescriptorFields {
434 maplibre_core::render::WebGpuContextDescriptorFields {
435 instance: self.instance.as_void_ptr(),
436 device: self.device.as_void_ptr(),
437 queue: self.queue.as_void_ptr(),
438 }
439 }
440}
441
442impl Default for WebGpuContextDescriptor {
443 fn default() -> Self {
444 Self::new(NativePointer::NULL)
445 }
446}
447
448#[derive(Debug, Clone, PartialEq)]
449#[non_exhaustive]
450pub struct WglContextDescriptor {
451 pub device_context: NativePointer,
452 pub share_context: NativePointer,
456 pub get_proc_address: NativePointer,
457 pub ownership: OpenGLContextOwnership,
459}
460
461impl WglContextDescriptor {
462 pub fn new(device_context: NativePointer, share_context: NativePointer) -> Self {
463 Self {
464 device_context,
465 share_context,
466 get_proc_address: NativePointer::NULL,
467 ownership: OpenGLContextOwnership::Shared,
468 }
469 }
470
471 pub(crate) fn to_core(&self) -> maplibre_core::render::WglContextDescriptorFields {
472 maplibre_core::render::WglContextDescriptorFields {
473 device_context: self.device_context.as_void_ptr(),
474 share_context: self.share_context.as_void_ptr(),
475 get_proc_address: self.get_proc_address.as_void_ptr(),
476 ownership: self.ownership.as_raw(),
477 }
478 }
479}
480
481impl Default for WglContextDescriptor {
482 fn default() -> Self {
483 Self::new(NativePointer::NULL, NativePointer::NULL)
484 }
485}
486
487#[derive(Debug, Clone, PartialEq)]
488#[non_exhaustive]
489pub struct EglContextDescriptor {
490 pub display: NativePointer,
491 pub config: NativePointer,
492 pub share_context: NativePointer,
497 pub client_api: OpenGLClientApi,
501 pub get_proc_address: NativePointer,
502 pub ownership: OpenGLContextOwnership,
504}
505
506impl EglContextDescriptor {
507 pub fn new(
508 display: NativePointer,
509 config: NativePointer,
510 share_context: NativePointer,
511 ) -> Self {
512 Self {
513 display,
514 config,
515 share_context,
516 client_api: OpenGLClientApi::Unspecified,
517 get_proc_address: NativePointer::NULL,
518 ownership: OpenGLContextOwnership::Shared,
519 }
520 }
521
522 pub(crate) fn to_core(&self) -> maplibre_core::render::EglContextDescriptorFields {
523 maplibre_core::render::EglContextDescriptorFields {
524 display: self.display.as_void_ptr(),
525 config: self.config.as_void_ptr(),
526 share_context: self.share_context.as_void_ptr(),
527 client_api: self.client_api.as_raw(),
528 get_proc_address: self.get_proc_address.as_void_ptr(),
529 ownership: self.ownership.as_raw(),
530 }
531 }
532}
533
534impl Default for EglContextDescriptor {
535 fn default() -> Self {
536 Self::new(
537 NativePointer::NULL,
538 NativePointer::NULL,
539 NativePointer::NULL,
540 )
541 }
542}
543
544#[derive(Debug, Clone, PartialEq)]
551#[non_exhaustive]
552pub struct WebGlContextDescriptor {
553 pub context: i32,
554}
555
556impl WebGlContextDescriptor {
557 pub fn new(context: i32) -> Self {
558 Self { context }
559 }
560
561 pub(crate) fn to_core(&self) -> maplibre_core::render::WebGlContextDescriptorFields {
562 maplibre_core::render::WebGlContextDescriptorFields {
563 context: self.context,
564 }
565 }
566}
567
568#[derive(Debug, Clone, PartialEq)]
573#[non_exhaustive]
574pub enum OpenGLContextDescriptor {
575 Wgl(WglContextDescriptor),
576 Egl(EglContextDescriptor),
577 WebGl(WebGlContextDescriptor),
578}
579
580impl OpenGLContextDescriptor {
581 pub(crate) fn to_core(&self) -> maplibre_core::render::OpenGLContextDescriptorFields {
582 match self {
583 Self::Wgl(descriptor) => {
584 maplibre_core::render::OpenGLContextDescriptorFields::Wgl(descriptor.to_core())
585 }
586 Self::Egl(descriptor) => {
587 maplibre_core::render::OpenGLContextDescriptorFields::Egl(descriptor.to_core())
588 }
589 Self::WebGl(descriptor) => {
590 maplibre_core::render::OpenGLContextDescriptorFields::WebGl(descriptor.to_core())
591 }
592 }
593 }
594}
595
596#[derive(Debug, Clone, PartialEq)]
597#[non_exhaustive]
598pub struct MetalSurfaceDescriptor {
599 pub extent: RenderTargetExtent,
600 pub context: MetalContextDescriptor,
601 pub layer: NativePointer,
602}
603
604impl MetalSurfaceDescriptor {
605 pub fn new(
606 extent: RenderTargetExtent,
607 context: MetalContextDescriptor,
608 layer: NativePointer,
609 ) -> Self {
610 Self {
611 extent,
612 context,
613 layer,
614 }
615 }
616
617 pub(crate) fn to_native(&self) -> sys::mln_metal_surface_descriptor {
618 maplibre_core::render::metal_surface_descriptor_to_native(
619 maplibre_core::render::MetalSurfaceDescriptorFields {
620 extent: self.extent.to_core(),
621 context: self.context.to_core(),
622 layer: self.layer.as_void_ptr(),
623 },
624 )
625 }
626}
627
628#[derive(Debug, Clone, PartialEq)]
629#[non_exhaustive]
630pub struct VulkanSurfaceDescriptor {
631 pub extent: RenderTargetExtent,
632 pub context: VulkanContextDescriptor,
633 pub surface: VulkanHandle,
634}
635
636impl VulkanSurfaceDescriptor {
637 pub fn new(
638 extent: RenderTargetExtent,
639 context: VulkanContextDescriptor,
640 surface: VulkanHandle,
641 ) -> Self {
642 Self {
643 extent,
644 context,
645 surface,
646 }
647 }
648
649 pub(crate) fn to_native(&self) -> sys::mln_vulkan_surface_descriptor {
650 maplibre_core::render::vulkan_surface_descriptor_to_native(
651 maplibre_core::render::VulkanSurfaceDescriptorFields {
652 extent: self.extent.to_core(),
653 context: self.context.to_core(),
654 surface: self.surface.bits(),
655 },
656 )
657 }
658}
659
660#[derive(Debug, Clone, PartialEq)]
667#[non_exhaustive]
668pub struct WebGpuSurfaceDescriptor {
669 pub extent: RenderTargetExtent,
670 pub context: WebGpuContextDescriptor,
671 pub surface: NativePointer,
672 pub format: u32,
673}
674
675impl WebGpuSurfaceDescriptor {
676 pub fn new(
677 extent: RenderTargetExtent,
678 context: WebGpuContextDescriptor,
679 surface: NativePointer,
680 format: u32,
681 ) -> Self {
682 Self {
683 extent,
684 context,
685 surface,
686 format,
687 }
688 }
689
690 pub(crate) fn to_native(&self) -> sys::mln_webgpu_surface_descriptor {
691 maplibre_core::render::webgpu_surface_descriptor_to_native(
692 maplibre_core::render::WebGpuSurfaceDescriptorFields {
693 extent: self.extent.to_core(),
694 context: self.context.to_core(),
695 surface: self.surface.as_void_ptr(),
696 format: self.format,
697 },
698 )
699 }
700}
701
702#[derive(Debug, Clone, PartialEq)]
703#[non_exhaustive]
704pub struct OpenGLSurfaceDescriptor {
705 pub extent: RenderTargetExtent,
706 pub context: OpenGLContextDescriptor,
707 pub surface: NativePointer,
708}
709
710impl OpenGLSurfaceDescriptor {
711 pub fn new(
712 extent: RenderTargetExtent,
713 context: OpenGLContextDescriptor,
714 surface: NativePointer,
715 ) -> Self {
716 Self {
717 extent,
718 context,
719 surface,
720 }
721 }
722
723 pub(crate) fn to_native(&self) -> sys::mln_opengl_surface_descriptor {
724 maplibre_core::render::opengl_surface_descriptor_to_native(
725 maplibre_core::render::OpenGLSurfaceDescriptorFields {
726 extent: self.extent.to_core(),
727 context: self.context.to_core(),
728 surface: self.surface.as_void_ptr(),
729 },
730 )
731 }
732}
733
734#[derive(Debug, Clone, PartialEq)]
735#[non_exhaustive]
736pub struct MetalOwnedTextureDescriptor {
737 pub extent: RenderTargetExtent,
738 pub context: MetalContextDescriptor,
739}
740
741impl MetalOwnedTextureDescriptor {
742 pub fn new(extent: RenderTargetExtent, context: MetalContextDescriptor) -> Self {
743 Self { extent, context }
744 }
745
746 pub(crate) fn to_native(&self) -> sys::mln_metal_owned_texture_descriptor {
747 maplibre_core::render::metal_owned_texture_descriptor_to_native(
748 maplibre_core::render::MetalOwnedTextureDescriptorFields {
749 extent: self.extent.to_core(),
750 context: self.context.to_core(),
751 },
752 )
753 }
754}
755
756#[derive(Debug, Clone, PartialEq)]
757#[non_exhaustive]
758pub struct MetalBorrowedTextureDescriptor {
759 pub extent: RenderTargetExtent,
760 pub physical_width: u32,
763 pub physical_height: u32,
764 pub texture: NativePointer,
765}
766
767impl MetalBorrowedTextureDescriptor {
768 pub fn new(
769 extent: RenderTargetExtent,
770 physical_width: u32,
771 physical_height: u32,
772 texture: NativePointer,
773 ) -> Self {
774 Self {
775 extent,
776 physical_width,
777 physical_height,
778 texture,
779 }
780 }
781
782 pub(crate) fn to_native(&self) -> sys::mln_metal_borrowed_texture_descriptor {
783 maplibre_core::render::metal_borrowed_texture_descriptor_to_native(
784 maplibre_core::render::MetalBorrowedTextureDescriptorFields {
785 extent: self.extent.to_core(),
786 physical_width: self.physical_width,
787 physical_height: self.physical_height,
788 texture: self.texture.as_void_ptr(),
789 },
790 )
791 }
792}
793
794#[derive(Debug, Clone, PartialEq)]
795#[non_exhaustive]
796pub struct VulkanOwnedTextureDescriptor {
797 pub extent: RenderTargetExtent,
798 pub context: VulkanContextDescriptor,
799}
800
801impl VulkanOwnedTextureDescriptor {
802 pub fn new(extent: RenderTargetExtent, context: VulkanContextDescriptor) -> Self {
803 Self { extent, context }
804 }
805
806 pub(crate) fn to_native(&self) -> sys::mln_vulkan_owned_texture_descriptor {
807 maplibre_core::render::vulkan_owned_texture_descriptor_to_native(
808 maplibre_core::render::VulkanOwnedTextureDescriptorFields {
809 extent: self.extent.to_core(),
810 context: self.context.to_core(),
811 },
812 )
813 }
814}
815
816#[derive(Debug, Clone, PartialEq)]
817#[non_exhaustive]
818pub struct VulkanBorrowedTextureDescriptor {
819 pub extent: RenderTargetExtent,
820 pub physical_width: u32,
823 pub physical_height: u32,
824 pub context: VulkanContextDescriptor,
825 pub image: VulkanHandle,
826 pub image_view: VulkanHandle,
827 pub format: u32,
828 pub initial_layout: u32,
829 pub final_layout: u32,
830}
831
832impl VulkanBorrowedTextureDescriptor {
833 #[allow(clippy::too_many_arguments)]
834 pub fn new(
835 extent: RenderTargetExtent,
836 physical_width: u32,
837 physical_height: u32,
838 context: VulkanContextDescriptor,
839 image: VulkanHandle,
840 image_view: VulkanHandle,
841 format: u32,
842 initial_layout: u32,
843 final_layout: u32,
844 ) -> Self {
845 Self {
846 extent,
847 physical_width,
848 physical_height,
849 context,
850 image,
851 image_view,
852 format,
853 initial_layout,
854 final_layout,
855 }
856 }
857
858 pub(crate) fn to_native(&self) -> sys::mln_vulkan_borrowed_texture_descriptor {
859 maplibre_core::render::vulkan_borrowed_texture_descriptor_to_native(
860 maplibre_core::render::VulkanBorrowedTextureDescriptorFields {
861 extent: self.extent.to_core(),
862 physical_width: self.physical_width,
863 physical_height: self.physical_height,
864 context: self.context.to_core(),
865 image: self.image.bits(),
866 image_view: self.image_view.bits(),
867 format: self.format,
868 initial_layout: self.initial_layout,
869 final_layout: self.final_layout,
870 },
871 )
872 }
873}
874
875#[derive(Debug, Clone, PartialEq)]
876#[non_exhaustive]
877pub struct WebGpuOwnedTextureDescriptor {
878 pub extent: RenderTargetExtent,
879 pub context: WebGpuContextDescriptor,
880}
881
882impl WebGpuOwnedTextureDescriptor {
883 pub fn new(extent: RenderTargetExtent, context: WebGpuContextDescriptor) -> Self {
884 Self { extent, context }
885 }
886
887 pub(crate) fn to_native(&self) -> sys::mln_webgpu_owned_texture_descriptor {
888 maplibre_core::render::webgpu_owned_texture_descriptor_to_native(
889 maplibre_core::render::WebGpuOwnedTextureDescriptorFields {
890 extent: self.extent.to_core(),
891 context: self.context.to_core(),
892 },
893 )
894 }
895}
896
897#[derive(Debug, Clone, PartialEq)]
898#[non_exhaustive]
899pub struct WebGpuBorrowedTextureDescriptor {
900 pub extent: RenderTargetExtent,
901 pub physical_width: u32,
904 pub physical_height: u32,
905 pub context: WebGpuContextDescriptor,
906 pub texture: NativePointer,
907 pub texture_view: NativePointer,
908 pub format: u32,
910}
911
912impl WebGpuBorrowedTextureDescriptor {
913 #[allow(clippy::too_many_arguments)]
914 pub fn new(
915 extent: RenderTargetExtent,
916 physical_width: u32,
917 physical_height: u32,
918 context: WebGpuContextDescriptor,
919 texture: NativePointer,
920 texture_view: NativePointer,
921 format: u32,
922 ) -> Self {
923 Self {
924 extent,
925 physical_width,
926 physical_height,
927 context,
928 texture,
929 texture_view,
930 format,
931 }
932 }
933
934 pub(crate) fn to_native(&self) -> sys::mln_webgpu_borrowed_texture_descriptor {
935 maplibre_core::render::webgpu_borrowed_texture_descriptor_to_native(
936 maplibre_core::render::WebGpuBorrowedTextureDescriptorFields {
937 extent: self.extent.to_core(),
938 physical_width: self.physical_width,
939 physical_height: self.physical_height,
940 context: self.context.to_core(),
941 texture: self.texture.as_void_ptr(),
942 texture_view: self.texture_view.as_void_ptr(),
943 format: self.format,
944 },
945 )
946 }
947}
948
949#[derive(Debug, Clone, PartialEq)]
950#[non_exhaustive]
951pub struct OpenGLOwnedTextureDescriptor {
952 pub extent: RenderTargetExtent,
953 pub context: OpenGLContextDescriptor,
954}
955
956impl OpenGLOwnedTextureDescriptor {
957 pub fn new(extent: RenderTargetExtent, context: OpenGLContextDescriptor) -> Self {
958 Self { extent, context }
959 }
960
961 pub(crate) fn to_native(&self) -> sys::mln_opengl_owned_texture_descriptor {
962 maplibre_core::render::opengl_owned_texture_descriptor_to_native(
963 maplibre_core::render::OpenGLOwnedTextureDescriptorFields {
964 extent: self.extent.to_core(),
965 context: self.context.to_core(),
966 },
967 )
968 }
969}
970
971#[derive(Debug, Clone, PartialEq)]
972#[non_exhaustive]
973pub struct OpenGLBorrowedTextureDescriptor {
974 pub extent: RenderTargetExtent,
975 pub physical_width: u32,
978 pub physical_height: u32,
979 pub context: OpenGLContextDescriptor,
980 pub texture: u32,
981 pub target: u32,
982}
983
984impl OpenGLBorrowedTextureDescriptor {
985 pub fn new(
986 extent: RenderTargetExtent,
987 physical_width: u32,
988 physical_height: u32,
989 context: OpenGLContextDescriptor,
990 texture: u32,
991 target: u32,
992 ) -> Self {
993 Self {
994 extent,
995 physical_width,
996 physical_height,
997 context,
998 texture,
999 target,
1000 }
1001 }
1002
1003 pub(crate) fn to_native(&self) -> sys::mln_opengl_borrowed_texture_descriptor {
1004 maplibre_core::render::opengl_borrowed_texture_descriptor_to_native(
1005 maplibre_core::render::OpenGLBorrowedTextureDescriptorFields {
1006 extent: self.extent.to_core(),
1007 physical_width: self.physical_width,
1008 physical_height: self.physical_height,
1009 context: self.context.to_core(),
1010 texture: self.texture,
1011 target: self.target,
1012 },
1013 )
1014 }
1015}
1016
1017#[derive(Debug)]
1018struct RenderSessionState {
1019 handle: ThreadAffineNativeHandle<sys::mln_render_session>,
1020 detached: Cell<bool>,
1021 frame_acquired: Cell<bool>,
1022}
1023
1024impl RenderSessionState {
1025 fn new(native: sys::mln_render_session) -> Result<Self> {
1026 let handle = unsafe {
1029 ThreadAffineNativeHandle::from_handle(
1030 native,
1031 sys::mln_render_session_destroy,
1032 "mln_render_session",
1033 )
1034 }?;
1035 Ok(Self {
1036 handle,
1037 detached: Cell::new(false),
1038 frame_acquired: Cell::new(false),
1039 })
1040 }
1041
1042 fn ensure_no_frame_acquired(&self) -> Result<()> {
1043 if self.frame_acquired.get() {
1044 Err(frame_acquired_error())
1045 } else {
1046 Ok(())
1047 }
1048 }
1049
1050 fn native(&self) -> Result<sys::mln_render_session> {
1051 self.handle
1052 .live_handle()
1053 .ok_or_else(|| closed_handle_error("RenderSessionHandle"))
1054 }
1055
1056 fn close(&self) -> Result<()> {
1057 self.handle.close()
1058 }
1059}
1060
1061#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1063#[non_exhaustive]
1064pub struct RenderUpdate {
1065 pub result: RenderResult,
1068 pub needs_repaint: bool,
1075}
1076
1077pub struct RenderSessionHandle {
1082 inner: Rc<RenderSessionState>,
1083}
1084
1085impl fmt::Debug for RenderSessionHandle {
1086 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1087 f.debug_struct("RenderSessionHandle")
1088 .field("closed", &self.inner.handle.is_closed())
1089 .field("detached", &self.inner.detached.get())
1090 .finish()
1091 }
1092}
1093
1094pub struct DetachedRenderSessionHandle {
1099 inner: Rc<RenderSessionState>,
1100}
1101
1102impl fmt::Debug for DetachedRenderSessionHandle {
1103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1104 f.debug_struct("DetachedRenderSessionHandle")
1105 .field("closed", &self.inner.handle.is_closed())
1106 .finish()
1107 }
1108}
1109
1110impl DetachedRenderSessionHandle {
1111 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
1113 if let Err(error) = self.inner.close() {
1114 return Err(HandleOperationError::new(error, self));
1115 }
1116 Ok(())
1117 }
1118}
1119
1120fn frame_acquired_error() -> crate::Error {
1121 crate::Error::new(
1122 crate::ErrorKind::InvalidState,
1123 None,
1124 "render session has an acquired texture frame",
1125 )
1126}
1127
1128#[derive(Debug, Clone, Copy, PartialEq)]
1133#[non_exhaustive]
1134pub struct MetalOwnedTextureFrame {
1135 pub generation: u64,
1136 pub width: u32,
1137 pub height: u32,
1138 pub scale_factor: f64,
1139 pub frame_id: u64,
1140 pub pixel_format: u64,
1141}
1142
1143impl MetalOwnedTextureFrame {
1144 fn from_native(raw: &sys::mln_metal_owned_texture_frame) -> Self {
1145 Self {
1146 generation: raw.generation,
1147 width: raw.width,
1148 height: raw.height,
1149 scale_factor: raw.scale_factor,
1150 frame_id: raw.frame_id,
1151 pixel_format: raw.pixel_format,
1152 }
1153 }
1154}
1155
1156#[derive(Debug, Clone, Copy, PartialEq)]
1161#[non_exhaustive]
1162pub struct VulkanOwnedTextureFrame {
1163 pub generation: u64,
1164 pub width: u32,
1165 pub height: u32,
1166 pub scale_factor: f64,
1167 pub frame_id: u64,
1168 pub format: u32,
1169 pub layout: u32,
1170}
1171
1172impl VulkanOwnedTextureFrame {
1173 fn from_native(raw: &sys::mln_vulkan_owned_texture_frame) -> Self {
1174 Self {
1175 generation: raw.generation,
1176 width: raw.width,
1177 height: raw.height,
1178 scale_factor: raw.scale_factor,
1179 frame_id: raw.frame_id,
1180 format: raw.format,
1181 layout: raw.layout,
1182 }
1183 }
1184}
1185
1186#[derive(Debug, Clone, Copy, PartialEq)]
1191#[non_exhaustive]
1192pub struct WebGpuOwnedTextureFrame {
1193 pub generation: u64,
1194 pub width: u32,
1195 pub height: u32,
1196 pub scale_factor: f64,
1197 pub frame_id: u64,
1198 pub format: u32,
1199}
1200
1201impl WebGpuOwnedTextureFrame {
1202 fn from_native(raw: &sys::mln_webgpu_owned_texture_frame) -> Self {
1203 Self {
1204 generation: raw.generation,
1205 width: raw.width,
1206 height: raw.height,
1207 scale_factor: raw.scale_factor,
1208 frame_id: raw.frame_id,
1209 format: raw.format,
1210 }
1211 }
1212}
1213
1214#[derive(Debug, Clone, Copy, PartialEq)]
1219#[non_exhaustive]
1220pub struct OpenGLOwnedTextureFrame {
1221 pub generation: u64,
1222 pub width: u32,
1223 pub height: u32,
1224 pub scale_factor: f64,
1225 pub frame_id: u64,
1226 pub target: u32,
1227 pub internal_format: u32,
1228 pub format: u32,
1229 pub type_: u32,
1230}
1231
1232impl OpenGLOwnedTextureFrame {
1233 fn from_native(raw: &sys::mln_opengl_owned_texture_frame) -> Self {
1234 Self {
1235 generation: raw.generation,
1236 width: raw.width,
1237 height: raw.height,
1238 scale_factor: raw.scale_factor,
1239 frame_id: raw.frame_id,
1240 target: raw.target,
1241 internal_format: raw.internal_format,
1242 format: raw.format,
1243 type_: raw.type_,
1244 }
1245 }
1246}
1247
1248pub struct MetalOwnedTextureFrameHandle {
1252 session: Rc<RenderSessionState>,
1253 raw: sys::mln_metal_owned_texture_frame,
1254 frame: MetalOwnedTextureFrame,
1255 closed: Cell<bool>,
1256 _thread_affine: PhantomData<Rc<()>>,
1257}
1258
1259impl fmt::Debug for MetalOwnedTextureFrameHandle {
1260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1261 f.debug_struct("MetalOwnedTextureFrameHandle")
1262 .field("closed", &self.closed.get())
1263 .field("frame", &self.frame)
1264 .finish()
1265 }
1266}
1267
1268impl MetalOwnedTextureFrameHandle {
1269 pub fn frame(&self) -> Result<&MetalOwnedTextureFrame> {
1271 if self.closed.get() {
1272 Err(closed_handle_error("MetalOwnedTextureFrameHandle"))
1273 } else {
1274 Ok(&self.frame)
1275 }
1276 }
1277 pub unsafe fn texture(&self) -> Result<FrameNativePointer<'_>> {
1285 if self.closed.get() {
1286 Err(closed_handle_error("MetalOwnedTextureFrameHandle"))
1287 } else {
1288 Ok(unsafe { FrameNativePointer::from_ptr(self.raw.texture) })
1291 }
1292 }
1293
1294 pub unsafe fn device(&self) -> Result<FrameNativePointer<'_>> {
1301 if self.closed.get() {
1302 Err(closed_handle_error("MetalOwnedTextureFrameHandle"))
1303 } else {
1304 Ok(unsafe { FrameNativePointer::from_ptr(self.raw.device) })
1306 }
1307 }
1308
1309 #[allow(clippy::result_large_err)]
1311 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
1312 self.close_with_release(sys::mln_metal_owned_texture_release_frame)
1313 }
1314
1315 #[allow(clippy::result_large_err)]
1316 fn close_with_release(
1317 self,
1318 release: unsafe extern "C" fn(
1319 sys::mln_render_session,
1320 *const sys::mln_metal_owned_texture_frame,
1321 ) -> sys::mln_status,
1322 ) -> std::result::Result<(), HandleOperationError<Self>> {
1323 if self.closed.get() {
1324 return Ok(());
1325 }
1326 let session = match self.session.native() {
1327 Ok(session) => session,
1328 Err(error) => return Err(HandleOperationError::new(error, self)),
1329 };
1330 if let Err(error) = maplibre_core::check(unsafe { release(session, &self.raw) }) {
1333 return Err(HandleOperationError::new(error, self));
1334 }
1335 self.closed.set(true);
1336 self.session.frame_acquired.set(false);
1337 Ok(())
1338 }
1339}
1340
1341impl Drop for MetalOwnedTextureFrameHandle {
1342 fn drop(&mut self) {
1343 if self.closed.get() {
1344 return;
1345 }
1346 if let Ok(session) = self.session.native() {
1347 let status = unsafe { sys::mln_metal_owned_texture_release_frame(session, &self.raw) };
1350 if status == sys::MLN_STATUS_OK {
1351 self.closed.set(true);
1352 self.session.frame_acquired.set(false);
1353 }
1354 }
1355 }
1356}
1357
1358pub struct VulkanOwnedTextureFrameHandle {
1363 session: Rc<RenderSessionState>,
1364 raw: sys::mln_vulkan_owned_texture_frame,
1365 frame: VulkanOwnedTextureFrame,
1366 closed: Cell<bool>,
1367 _thread_affine: PhantomData<Rc<()>>,
1368}
1369
1370impl fmt::Debug for VulkanOwnedTextureFrameHandle {
1371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1372 f.debug_struct("VulkanOwnedTextureFrameHandle")
1373 .field("closed", &self.closed.get())
1374 .field("frame", &self.frame)
1375 .finish()
1376 }
1377}
1378
1379impl VulkanOwnedTextureFrameHandle {
1380 pub fn frame(&self) -> Result<&VulkanOwnedTextureFrame> {
1382 if self.closed.get() {
1383 Err(closed_handle_error("VulkanOwnedTextureFrameHandle"))
1384 } else {
1385 Ok(&self.frame)
1386 }
1387 }
1388 pub unsafe fn image(&self) -> Result<FrameVulkanHandle<'_>> {
1396 if self.closed.get() {
1397 Err(closed_handle_error("VulkanOwnedTextureFrameHandle"))
1398 } else {
1399 Ok(FrameVulkanHandle::new(self.raw.image))
1400 }
1401 }
1402
1403 pub unsafe fn image_view(&self) -> Result<FrameVulkanHandle<'_>> {
1410 if self.closed.get() {
1411 Err(closed_handle_error("VulkanOwnedTextureFrameHandle"))
1412 } else {
1413 Ok(FrameVulkanHandle::new(self.raw.image_view))
1414 }
1415 }
1416
1417 pub unsafe fn device(&self) -> Result<FrameNativePointer<'_>> {
1424 if self.closed.get() {
1425 Err(closed_handle_error("VulkanOwnedTextureFrameHandle"))
1426 } else {
1427 Ok(unsafe { FrameNativePointer::from_ptr(self.raw.device) })
1429 }
1430 }
1431
1432 #[allow(clippy::result_large_err)]
1434 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
1435 if self.closed.get() {
1436 return Ok(());
1437 }
1438 let session = match self.session.native() {
1439 Ok(session) => session,
1440 Err(error) => return Err(HandleOperationError::new(error, self)),
1441 };
1442 if let Err(error) = maplibre_core::check(unsafe {
1445 sys::mln_vulkan_owned_texture_release_frame(session, &self.raw)
1446 }) {
1447 return Err(HandleOperationError::new(error, self));
1448 }
1449 self.closed.set(true);
1450 self.session.frame_acquired.set(false);
1451 Ok(())
1452 }
1453}
1454
1455impl Drop for VulkanOwnedTextureFrameHandle {
1456 fn drop(&mut self) {
1457 if self.closed.get() {
1458 return;
1459 }
1460 if let Ok(session) = self.session.native() {
1461 let status = unsafe { sys::mln_vulkan_owned_texture_release_frame(session, &self.raw) };
1464 if status == sys::MLN_STATUS_OK {
1465 self.closed.set(true);
1466 self.session.frame_acquired.set(false);
1467 }
1468 }
1469 }
1470}
1471
1472pub struct WebGpuOwnedTextureFrameHandle {
1477 session: Rc<RenderSessionState>,
1478 raw: sys::mln_webgpu_owned_texture_frame,
1479 frame: WebGpuOwnedTextureFrame,
1480 closed: Cell<bool>,
1481 _thread_affine: PhantomData<Rc<()>>,
1482}
1483
1484impl fmt::Debug for WebGpuOwnedTextureFrameHandle {
1485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1486 f.debug_struct("WebGpuOwnedTextureFrameHandle")
1487 .field("closed", &self.closed.get())
1488 .field("frame", &self.frame)
1489 .finish()
1490 }
1491}
1492
1493impl WebGpuOwnedTextureFrameHandle {
1494 pub fn frame(&self) -> Result<&WebGpuOwnedTextureFrame> {
1496 if self.closed.get() {
1497 Err(closed_handle_error("WebGpuOwnedTextureFrameHandle"))
1498 } else {
1499 Ok(&self.frame)
1500 }
1501 }
1502
1503 pub unsafe fn texture(&self) -> Result<FrameNativePointer<'_>> {
1511 if self.closed.get() {
1512 Err(closed_handle_error("WebGpuOwnedTextureFrameHandle"))
1513 } else {
1514 Ok(unsafe { FrameNativePointer::from_ptr(self.raw.texture) })
1517 }
1518 }
1519
1520 pub unsafe fn texture_view(&self) -> Result<FrameNativePointer<'_>> {
1527 if self.closed.get() {
1528 Err(closed_handle_error("WebGpuOwnedTextureFrameHandle"))
1529 } else {
1530 Ok(unsafe { FrameNativePointer::from_ptr(self.raw.texture_view) })
1532 }
1533 }
1534
1535 pub unsafe fn device(&self) -> Result<FrameNativePointer<'_>> {
1542 if self.closed.get() {
1543 Err(closed_handle_error("WebGpuOwnedTextureFrameHandle"))
1544 } else {
1545 Ok(unsafe { FrameNativePointer::from_ptr(self.raw.device) })
1547 }
1548 }
1549
1550 #[allow(clippy::result_large_err)]
1552 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
1553 if self.closed.get() {
1554 return Ok(());
1555 }
1556 let session = match self.session.native() {
1557 Ok(session) => session,
1558 Err(error) => return Err(HandleOperationError::new(error, self)),
1559 };
1560 if let Err(error) = maplibre_core::check(unsafe {
1563 sys::mln_webgpu_owned_texture_release_frame(session, &self.raw)
1564 }) {
1565 return Err(HandleOperationError::new(error, self));
1566 }
1567 self.closed.set(true);
1568 self.session.frame_acquired.set(false);
1569 Ok(())
1570 }
1571}
1572
1573impl Drop for WebGpuOwnedTextureFrameHandle {
1574 fn drop(&mut self) {
1575 if self.closed.get() {
1576 return;
1577 }
1578 if let Ok(session) = self.session.native() {
1579 let status = unsafe { sys::mln_webgpu_owned_texture_release_frame(session, &self.raw) };
1582 if status == sys::MLN_STATUS_OK {
1583 self.closed.set(true);
1584 self.session.frame_acquired.set(false);
1585 }
1586 }
1587 }
1588}
1589
1590pub struct OpenGLOwnedTextureFrameHandle {
1594 session: Rc<RenderSessionState>,
1595 raw: sys::mln_opengl_owned_texture_frame,
1596 frame: OpenGLOwnedTextureFrame,
1597 closed: Cell<bool>,
1598 _thread_affine: PhantomData<Rc<()>>,
1599}
1600
1601impl fmt::Debug for OpenGLOwnedTextureFrameHandle {
1602 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1603 f.debug_struct("OpenGLOwnedTextureFrameHandle")
1604 .field("closed", &self.closed.get())
1605 .field("frame", &self.frame)
1606 .finish()
1607 }
1608}
1609
1610impl OpenGLOwnedTextureFrameHandle {
1611 pub fn frame(&self) -> Result<&OpenGLOwnedTextureFrame> {
1613 if self.closed.get() {
1614 Err(closed_handle_error("OpenGLOwnedTextureFrameHandle"))
1615 } else {
1616 Ok(&self.frame)
1617 }
1618 }
1619 pub fn texture(&self) -> Result<FrameOpenGLTextureName<'_>> {
1621 if self.closed.get() {
1622 Err(closed_handle_error("OpenGLOwnedTextureFrameHandle"))
1623 } else {
1624 Ok(FrameOpenGLTextureName::new(self.raw.texture))
1625 }
1626 }
1627
1628 #[allow(clippy::result_large_err)]
1630 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
1631 if self.closed.get() {
1632 return Ok(());
1633 }
1634 let session = match self.session.native() {
1635 Ok(session) => session,
1636 Err(error) => return Err(HandleOperationError::new(error, self)),
1637 };
1638 if let Err(error) = maplibre_core::check(unsafe {
1641 sys::mln_opengl_owned_texture_release_frame(session, &self.raw)
1642 }) {
1643 return Err(HandleOperationError::new(error, self));
1644 }
1645 self.closed.set(true);
1646 self.session.frame_acquired.set(false);
1647 Ok(())
1648 }
1649}
1650
1651impl Drop for OpenGLOwnedTextureFrameHandle {
1652 fn drop(&mut self) {
1653 if self.closed.get() {
1654 return;
1655 }
1656 if let Ok(session) = self.session.native() {
1657 let status = unsafe { sys::mln_opengl_owned_texture_release_frame(session, &self.raw) };
1660 if status == sys::MLN_STATUS_OK {
1661 self.closed.set(true);
1662 self.session.frame_acquired.set(false);
1663 }
1664 }
1665 }
1666}
1667
1668impl RenderSessionHandle {
1669 pub(crate) fn attach<F>(map: &MapAttachRef, attach: F) -> Result<Self>
1670 where
1671 F: FnOnce(sys::mln_map, *mut sys::mln_render_session) -> sys::mln_status,
1672 {
1673 let mut out = maplibre_core::ptr::OutHandle::<sys::mln_render_session>::new();
1674 let status = attach(map.map(), out.as_mut_ptr());
1677 maplibre_core::check(status)?;
1678 let ptr = out_handle(out, "mln_render_session")?;
1679 Ok(Self {
1680 inner: Rc::new(RenderSessionState::new(ptr)?),
1681 })
1682 }
1683
1684 pub fn close(self) -> std::result::Result<(), HandleOperationError<Self>> {
1689 if let Err(error) = self.inner.ensure_no_frame_acquired() {
1690 return Err(HandleOperationError::new(error, self));
1691 }
1692 if let Err(error) = self.inner.close() {
1693 return Err(HandleOperationError::new(error, self));
1694 }
1695 Ok(())
1696 }
1697 pub fn resize(&self, width: u32, height: u32, scale_factor: f64) -> Result<()> {
1707 self.inner.ensure_no_frame_acquired()?;
1708 let session = self.inner.native()?;
1709 maplibre_core::check(unsafe {
1711 sys::mln_render_session_resize(session, width, height, scale_factor)
1712 })
1713 }
1714
1715 pub fn set_metal_surface_target(&self, descriptor: &MetalSurfaceDescriptor) -> Result<()> {
1722 self.set_target(descriptor.to_native(), |session, raw| {
1723 unsafe { sys::mln_metal_surface_set_target(session, raw) }
1726 })
1727 }
1728
1729 pub fn set_vulkan_surface_target(&self, descriptor: &VulkanSurfaceDescriptor) -> Result<()> {
1736 self.set_target(descriptor.to_native(), |session, raw| {
1737 unsafe { sys::mln_vulkan_surface_set_target(session, raw) }
1740 })
1741 }
1742
1743 pub fn set_webgpu_surface_target(&self, descriptor: &WebGpuSurfaceDescriptor) -> Result<()> {
1749 self.set_target(descriptor.to_native(), |session, raw| {
1750 unsafe { sys::mln_webgpu_surface_set_target(session, raw) }
1753 })
1754 }
1755
1756 pub fn set_opengl_surface_target(&self, descriptor: &OpenGLSurfaceDescriptor) -> Result<()> {
1764 self.set_target(descriptor.to_native(), |session, raw| {
1765 unsafe { sys::mln_opengl_surface_set_target(session, raw) }
1768 })
1769 }
1770
1771 pub fn set_metal_borrowed_texture_target(
1781 &self,
1782 descriptor: &MetalBorrowedTextureDescriptor,
1783 ) -> Result<()> {
1784 self.set_target(descriptor.to_native(), |session, raw| {
1785 unsafe { sys::mln_metal_borrowed_texture_set_target(session, raw) }
1788 })
1789 }
1790
1791 pub fn set_vulkan_borrowed_texture_target(
1798 &self,
1799 descriptor: &VulkanBorrowedTextureDescriptor,
1800 ) -> Result<()> {
1801 self.set_target(descriptor.to_native(), |session, raw| {
1802 unsafe { sys::mln_vulkan_borrowed_texture_set_target(session, raw) }
1805 })
1806 }
1807
1808 pub fn set_webgpu_borrowed_texture_target(
1814 &self,
1815 descriptor: &WebGpuBorrowedTextureDescriptor,
1816 ) -> Result<()> {
1817 self.set_target(descriptor.to_native(), |session, raw| {
1818 unsafe { sys::mln_webgpu_borrowed_texture_set_target(session, raw) }
1821 })
1822 }
1823
1824 pub fn set_opengl_borrowed_texture_target(
1831 &self,
1832 descriptor: &OpenGLBorrowedTextureDescriptor,
1833 ) -> Result<()> {
1834 self.set_target(descriptor.to_native(), |session, raw| {
1835 unsafe { sys::mln_opengl_borrowed_texture_set_target(session, raw) }
1838 })
1839 }
1840
1841 fn set_target<D>(
1845 &self,
1846 raw: D,
1847 set_target: impl FnOnce(sys::mln_render_session, &D) -> sys::mln_status,
1848 ) -> Result<()> {
1849 self.inner.ensure_no_frame_acquired()?;
1850 let session = self.inner.native()?;
1851 maplibre_core::check(set_target(session, &raw))
1852 }
1853
1854 pub fn render_update(&self) -> Result<RenderUpdate> {
1867 self.inner.ensure_no_frame_acquired()?;
1868 let session = self.inner.native()?;
1869 let mut result = sys::MLN_RENDER_RESULT_NO_UPDATE;
1870 let mut needs_repaint = false;
1871 maplibre_core::check(unsafe {
1874 sys::mln_render_session_render_update(session, &raw mut result, &raw mut needs_repaint)
1875 })?;
1876 Ok(RenderUpdate {
1877 result: RenderResult::from_raw(result),
1878 needs_repaint,
1879 })
1880 }
1881
1882 pub fn detach(
1888 self,
1889 ) -> std::result::Result<DetachedRenderSessionHandle, HandleOperationError<Self>> {
1890 if let Err(error) = self.inner.ensure_no_frame_acquired() {
1891 return Err(HandleOperationError::new(error, self));
1892 }
1893 let session = match self.inner.native() {
1894 Ok(session) => session,
1895 Err(error) => return Err(HandleOperationError::new(error, self)),
1896 };
1897 if let Err(error) = maplibre_core::check(unsafe { sys::mln_render_session_detach(session) })
1899 {
1900 return Err(HandleOperationError::new(error, self));
1901 }
1902 self.inner.detached.set(true);
1903 Ok(DetachedRenderSessionHandle {
1904 inner: Rc::clone(&self.inner),
1905 })
1906 }
1907
1908 pub fn reduce_memory_use(&self) -> Result<()> {
1910 self.inner.ensure_no_frame_acquired()?;
1911 let session = self.inner.native()?;
1912 maplibre_core::check(unsafe { sys::mln_render_session_reduce_memory_use(session) })
1914 }
1915
1916 pub fn clear_data(&self) -> Result<()> {
1918 self.inner.ensure_no_frame_acquired()?;
1919 let session = self.inner.native()?;
1920 maplibre_core::check(unsafe { sys::mln_render_session_clear_data(session) })
1922 }
1923
1924 pub fn dump_debug_logs(&self) -> Result<()> {
1926 self.inner.ensure_no_frame_acquired()?;
1927 let session = self.inner.native()?;
1928 maplibre_core::check(unsafe { sys::mln_render_session_dump_debug_logs(session) })
1930 }
1931
1932 pub fn texture_image_info(&self) -> Result<TextureImageInfo> {
1934 self.inner.ensure_no_frame_acquired()?;
1935 let session = self.inner.native()?;
1936 let mut info = unsafe { sys::mln_texture_image_info_default() };
1938 maplibre_core::check(unsafe {
1941 sys::mln_texture_read_premultiplied_rgba8(session, std::ptr::null_mut(), 0, &mut info)
1942 })?;
1943 Ok(maplibre_core::values::texture_image_info_from_native(&info))
1944 }
1945
1946 pub fn read_premultiplied_rgba8_into(&self, data: &mut [u8]) -> Result<TextureImageInfo> {
1948 self.inner.ensure_no_frame_acquired()?;
1949 let session = self.inner.native()?;
1950 let mut info = unsafe { sys::mln_texture_image_info_default() };
1952 let data_ptr = if data.is_empty() {
1953 std::ptr::null_mut()
1954 } else {
1955 data.as_mut_ptr()
1956 };
1957 maplibre_core::check(unsafe {
1961 sys::mln_texture_read_premultiplied_rgba8(session, data_ptr, data.len(), &mut info)
1962 })?;
1963 if data.is_empty() && info.byte_length > 0 {
1966 return Err(crate::Error::invalid_argument(format!(
1967 "buffer length 0 is smaller than the required {} bytes",
1968 info.byte_length
1969 )));
1970 }
1971 Ok(maplibre_core::values::texture_image_info_from_native(&info))
1972 }
1973
1974 pub fn acquire_metal_owned_texture_frame(&self) -> Result<MetalOwnedTextureFrameHandle> {
1976 self.inner.ensure_no_frame_acquired()?;
1977 let session = self.inner.native()?;
1978 let mut raw = empty_metal_owned_texture_frame();
1979 maplibre_core::check(unsafe {
1981 sys::mln_metal_owned_texture_acquire_frame(session, &mut raw)
1982 })?;
1983 self.inner.frame_acquired.set(true);
1984 Ok(MetalOwnedTextureFrameHandle {
1985 session: Rc::clone(&self.inner),
1986 frame: MetalOwnedTextureFrame::from_native(&raw),
1987 raw,
1988 closed: Cell::new(false),
1989 _thread_affine: PhantomData,
1990 })
1991 }
1992
1993 pub fn acquire_vulkan_owned_texture_frame(&self) -> Result<VulkanOwnedTextureFrameHandle> {
1995 self.inner.ensure_no_frame_acquired()?;
1996 let session = self.inner.native()?;
1997 let mut raw = empty_vulkan_owned_texture_frame();
1998 maplibre_core::check(unsafe {
2000 sys::mln_vulkan_owned_texture_acquire_frame(session, &mut raw)
2001 })?;
2002 self.inner.frame_acquired.set(true);
2003 Ok(VulkanOwnedTextureFrameHandle {
2004 session: Rc::clone(&self.inner),
2005 frame: VulkanOwnedTextureFrame::from_native(&raw),
2006 raw,
2007 closed: Cell::new(false),
2008 _thread_affine: PhantomData,
2009 })
2010 }
2011
2012 pub fn acquire_webgpu_owned_texture_frame(&self) -> Result<WebGpuOwnedTextureFrameHandle> {
2014 self.inner.ensure_no_frame_acquired()?;
2015 let session = self.inner.native()?;
2016 let mut raw = empty_webgpu_owned_texture_frame();
2017 maplibre_core::check(unsafe {
2019 sys::mln_webgpu_owned_texture_acquire_frame(session, &mut raw)
2020 })?;
2021 self.inner.frame_acquired.set(true);
2022 Ok(WebGpuOwnedTextureFrameHandle {
2023 session: Rc::clone(&self.inner),
2024 frame: WebGpuOwnedTextureFrame::from_native(&raw),
2025 raw,
2026 closed: Cell::new(false),
2027 _thread_affine: PhantomData,
2028 })
2029 }
2030
2031 pub fn acquire_opengl_owned_texture_frame(&self) -> Result<OpenGLOwnedTextureFrameHandle> {
2033 self.inner.ensure_no_frame_acquired()?;
2034 let session = self.inner.native()?;
2035 let mut raw = empty_opengl_owned_texture_frame();
2036 maplibre_core::check(unsafe {
2038 sys::mln_opengl_owned_texture_acquire_frame(session, &mut raw)
2039 })?;
2040 self.inner.frame_acquired.set(true);
2041 Ok(OpenGLOwnedTextureFrameHandle {
2042 session: Rc::clone(&self.inner),
2043 frame: OpenGLOwnedTextureFrame::from_native(&raw),
2044 raw,
2045 closed: Cell::new(false),
2046 _thread_affine: PhantomData,
2047 })
2048 }
2049}
2050
2051fn empty_metal_owned_texture_frame() -> sys::mln_metal_owned_texture_frame {
2052 sys::mln_metal_owned_texture_frame {
2053 size: mem::size_of::<sys::mln_metal_owned_texture_frame>() as u32,
2054 generation: 0,
2055 width: 0,
2056 height: 0,
2057 scale_factor: 0.0,
2058 frame_id: 0,
2059 texture: std::ptr::null_mut(),
2060 device: std::ptr::null_mut(),
2061 pixel_format: 0,
2062 }
2063}
2064
2065fn empty_webgpu_owned_texture_frame() -> sys::mln_webgpu_owned_texture_frame {
2066 sys::mln_webgpu_owned_texture_frame {
2067 size: mem::size_of::<sys::mln_webgpu_owned_texture_frame>() as u32,
2068 generation: 0,
2069 width: 0,
2070 height: 0,
2071 scale_factor: 0.0,
2072 frame_id: 0,
2073 texture: std::ptr::null_mut(),
2074 texture_view: std::ptr::null_mut(),
2075 device: std::ptr::null_mut(),
2076 format: 0,
2077 }
2078}
2079
2080fn empty_vulkan_owned_texture_frame() -> sys::mln_vulkan_owned_texture_frame {
2081 sys::mln_vulkan_owned_texture_frame {
2082 size: mem::size_of::<sys::mln_vulkan_owned_texture_frame>() as u32,
2083 generation: 0,
2084 width: 0,
2085 height: 0,
2086 scale_factor: 0.0,
2087 frame_id: 0,
2088 image: 0,
2089 image_view: 0,
2090 device: std::ptr::null_mut(),
2091 format: 0,
2092 layout: 0,
2093 }
2094}
2095
2096fn empty_opengl_owned_texture_frame() -> sys::mln_opengl_owned_texture_frame {
2097 sys::mln_opengl_owned_texture_frame {
2098 size: mem::size_of::<sys::mln_opengl_owned_texture_frame>() as u32,
2099 generation: 0,
2100 width: 0,
2101 height: 0,
2102 scale_factor: 0.0,
2103 frame_id: 0,
2104 texture: 0,
2105 target: 0,
2106 internal_format: 0,
2107 format: 0,
2108 type_: 0,
2109 }
2110}
2111
2112#[cfg(test)]
2113mod tests;