@@ -146,6 +146,7 @@ pub struct EguiMapState {
146146 texture_view : TextureView ,
147147 event_processor : EventProcessor ,
148148 messenger : MapStateMessenger ,
149+ map_ready : bool ,
149150}
150151
151152impl < ' a > EguiMapState {
@@ -177,6 +178,7 @@ impl<'a> EguiMapState {
177178 // This size will be replaced by the UI on the first frame.
178179 let size = Size :: new ( 1 , 1 ) ;
179180 map. set_size ( size. cast ( ) ) ;
181+ map. set_view ( map. view ( ) . with_dpi_scale_factor ( ctx. pixels_per_point ( ) ) ) ;
180182
181183 let mut renderer = WgpuRenderer :: new_with_device_and_texture (
182184 render_state. device . clone ( ) ,
@@ -209,6 +211,7 @@ impl<'a> EguiMapState {
209211 texture_view : texture,
210212 event_processor,
211213 messenger,
214+ map_ready : false ,
212215 }
213216 }
214217
@@ -219,10 +222,13 @@ impl<'a> EguiMapState {
219222
220223 /// Renders the map into UI.
221224 pub fn render ( & mut self , ui : & mut egui:: Ui ) {
222- let available_size = ui. available_size ( ) . floor ( ) ;
223- let map_size = self . renderer . size ( ) . cast :: < f32 > ( ) ;
225+ let logical_size = ui. available_size ( ) . floor ( ) ;
226+ let pixels_per_point = ui. ctx ( ) . pixels_per_point ( ) ;
227+ let physical_size = logical_size * pixels_per_point;
224228
225- let ( rect, response) = ui. allocate_exact_size ( available_size, Sense :: click_and_drag ( ) ) ;
229+ let ( rect, response) = ui. allocate_exact_size ( logical_size, Sense :: click_and_drag ( ) ) ;
230+
231+ let renderer_size = self . renderer . size ( ) . cast :: < f32 > ( ) ;
226232
227233 let attributions = self . collect_attributions ( ) ;
228234 if attributions. is_some ( ) {
@@ -243,8 +249,15 @@ impl<'a> EguiMapState {
243249
244250 self . map . animate ( ) ;
245251
246- if available_size[ 0 ] != map_size. width ( ) || available_size[ 1 ] != map_size. height ( ) {
247- self . resize_map ( available_size) ;
252+ if physical_size[ 0 ] != renderer_size. width ( ) || physical_size[ 1 ] != renderer_size. height ( ) {
253+ self . map_ready = true ;
254+ self . resize_map ( logical_size, pixels_per_point) ;
255+ self . map
256+ . set_view ( self . map . view ( ) . with_dpi_scale_factor ( pixels_per_point) ) ;
257+ }
258+
259+ if self . map_ready {
260+ self . map . load_layers ( ) ;
248261 }
249262
250263 if self . requires_redraw . swap ( false , Ordering :: Relaxed ) {
@@ -253,7 +266,7 @@ impl<'a> EguiMapState {
253266
254267 Image :: new ( ImageSource :: Texture ( SizedTexture :: new (
255268 self . texture_id ,
256- Vec2 :: new ( map_size . width ( ) , map_size . height ( ) ) ,
269+ Vec2 :: new ( renderer_size . width ( ) , renderer_size . height ( ) ) ,
257270 ) ) )
258271 . paint_at ( ui, rect) ;
259272 }
@@ -309,30 +322,42 @@ impl<'a> EguiMapState {
309322 self . messenger . clone ( )
310323 }
311324
312- fn resize_map ( & mut self , size : Vec2 ) {
313- log:: trace!( "Resizing map to size: {size:?}" ) ;
325+ fn resize_map ( & mut self , logical_size : Vec2 , pixels_per_point : f32 ) {
326+ log:: trace!(
327+ "Resizing map to logical size: {logical_size:?}, pixels_per_point: {pixels_per_point}"
328+ ) ;
314329
315- let size = Size :: new ( size. x as f64 , size. y as f64 ) ;
316- self . map . set_size ( size) ;
330+ // Set the logical size for the map
331+ let logical_size_f64 = Size :: new ( logical_size. x as f64 , logical_size. y as f64 ) ;
332+ self . map . set_size ( logical_size_f64) ;
317333
318- let size = Size :: new ( size. width ( ) as u32 , size. height ( ) as u32 ) ;
319- self . renderer . resize ( size) ;
334+ // Resize the renderer to physical size (accounting for pixel density)
335+ let physical_size = Size :: new (
336+ ( logical_size. x * pixels_per_point) as u32 ,
337+ ( logical_size. y * pixels_per_point) as u32 ,
338+ ) ;
339+ self . renderer . resize ( physical_size) ;
320340
321341 // After renderer is resized, a new texture is created, so we need to update its id that we
322342 // use in UI.
323343 let texture = self
324344 . renderer
325345 . get_target_texture_view ( )
326346 . expect ( "failed to get map texture" ) ;
347+
348+ // Use Linear filtering for better quality on HiDPI displays
349+ let filter_mode = if pixels_per_point > 1.0 {
350+ FilterMode :: Linear
351+ } else {
352+ FilterMode :: Nearest
353+ } ;
354+ log:: info!( "Using filter mode: {filter_mode:?}" ) ;
355+
327356 let texture_id = self
328357 . egui_render_state
329358 . renderer
330359 . write ( )
331- . register_native_texture (
332- & self . egui_render_state . device ,
333- & texture,
334- FilterMode :: Nearest ,
335- ) ;
360+ . register_native_texture ( & self . egui_render_state . device , & texture, filter_mode) ;
336361
337362 self . texture_id = texture_id;
338363 self . texture_view = texture;
0 commit comments