emoon / rust_minifb

Cross platfrom window and framebuffer crate for Rust
MIT License
1.01k stars 97 forks source link

MacOS displays blurry lines #226

Closed curlywurlycraig closed 3 years ago

curlywurlycraig commented 3 years ago

Description

With a retina display Macbook (Mojave, mid-2014, 13"), it is as if retina is not being used.

With the following code:

use minifb::{Key, Window, WindowOptions};

const WINDOW_WIDTH: usize = 200;
const WINDOW_HEIGHT: usize = 100;

fn main() {
    let mut window = Window::new(
        "Example window",
        WINDOW_WIDTH,
        WINDOW_HEIGHT,
        WindowOptions::default()
    ).unwrap_or_else(|e| {
        panic!("{}", e);
    });

    // Limit to max ~60 fps update rate
    window.limit_update_rate(Some(std::time::Duration::from_micros(16600)));

    let mut buffer: Vec<u32> = vec![0; WINDOW_WIDTH * WINDOW_HEIGHT];

    while window.is_open() && !window.is_key_down(Key::Escape) {
        // Alternate between white and black
        for i in buffer.iter_mut().enumerate() {
            *i.1 = if i.0 % 2 == 0 { 0xFFFFFF } else { 0x00 }
        }

        window
            .update_with_buffer(&buffer, WINDOW_WIDTH, WINDOW_HEIGHT)
            .unwrap();
    }
}

I see the following result:

Screenshot 2020-12-02 at 11 14 42

when I would expect the lines to be 1 pixel wide every time.

I wonder if this is related to changing to use Metal.

curlywurlycraig commented 3 years ago

Hang on, I just noticed that if I zoom into that window, the screenshot is showing 1 pixel for each line 🤔

curlywurlycraig commented 3 years ago

Ah yes. It appears to be two pixels wide, not one. As if what we actually need is a 0.5X scaling factor. I still suspect this is related to the change to using Metal.

emoon commented 3 years ago

If you set WindowOpts to something like

  WindowOptions {
            scale: Scale::X2,
            ..WindowOptions::default()
        },

Does it seem to look better?

curlywurlycraig commented 3 years ago

That makes it worse (4 pixels for every real pixel):

Screenshot 2020-12-02 at 13 22 48
emoon commented 3 years ago

Ok, doubling of pixels is expected (that is the point of the scale factor) but not sure about the need for 0.5X scale and I doubt it's related to Metal. I just thing it's because minifb doesn't do anything special for HiDPI. It would be interesting to know if it looks correct if you set macOS to non-scaled mode.

curlywurlycraig commented 3 years ago

The problem remains when I use default for display. If this isn't related to Metal, is it possibly something in the Cocoa window management code? I don't know much about Cocoa unfortunately, so I can only get so far trying to debug this myself.

emoon commented 3 years ago

I see. I will have to look into it at some point, but currently I don't have easy access to my mac so I can't do it for a while.

curlywurlycraig commented 3 years ago

Sure. Thanks for your help

LoganDark commented 3 years ago

All you have to do is multiply the width and height of the buffer (but not the window) by two. This is intended behavior and minifb is working correctly.

Watch out for #221. minifb currently offers no facilities for actually determining what the scale factor is.

curlywurlycraig commented 3 years ago

Makes sense, thanks.

emoon commented 3 years ago

Being tracked in #236