Rust-SDL2 / rust-sdl2

SDL2 bindings for Rust
MIT License
2.74k stars 468 forks source link

SDL_LogCritical showing up in profiling #631

Open bgourlie opened 7 years ago

bgourlie commented 7 years ago

I did some cursory profiling of an emulator I'm writing, and SDL_LogCritical is one of the top hits.

capture

I'm unable to see what exactly is getting logged. Is there a way to control SDL's log output so I can get an idea of what's going on? You can see how I'm doing my rendering here: https://github.com/bgourlie/rs-nes/blob/sdl-refactor/examples/real_time.rs

Cobrand commented 7 years ago

It's true that there is no "native" rust-sdl2 port for this, but it can be useful. SDL_LogSetOutputFunction would definitely be the solution here, but unfortunately it hasn't been added to sdl2-sys yet.

If you want, you can try forking sdl2-sys and adding this function with bindgen (or manually even though I don't recommend it), so at least you can use this function in an unsafe manner via sdl2-sys. Once that will be done, rust-sdl2 bindings will be feasible.

If you don't want to do it, it doesn't look like it will take much time so I might be able to pull off something to add this this week, but no guarantees.

Cobrand commented 7 years ago

by the way your example doesn't compile:

error[E0061]: this function takes 2 parameters but 1 parameter was supplied
  --> src/main.rs:29:28
   |
29 |     let ppu = PpuImpl::new(rom.clone());
   |                            ^^^^^^^^^^^ expected 2 parameters

error[E0308]: mismatched types
  --> src/main.rs:30:34
   |
30 |     let mem = NesMemoryImpl::new(rom, ppu);
   |                                  ^^^ expected struct `rs_nes::rom::NesRom`, found struct `std::rc::Rc`
   |
   = note: expected type `rs_nes::rom::NesRom`
              found type `std::rc::Rc<std::boxed::Box<rs_nes::rom::NesRom>>`

error: field `memory` of struct `rs_nes::cpu::Cpu` is private
  --> src/main.rs:78:39
   |
78 |                         .update(None, cpu.memory.screen_buffer(), SCREEN_WIDTH as usize * 3)
   |                                       ^^^^^^^^^^

error: no method named `screen_buffer` found for type `rs_nes::memory::nes_memory::NesMemoryBase<rs_nes::ppu::PpuBase<rs_nes::ppu::vram::VramBase, rs_nes::ppu::sprite_renderer::SpriteRendererBase>, rs_nes::apu::ApuBase, rs_nes::input::InputBase>` in the current scope
  --> src/main.rs:78:50
   |
78 |                         .update(None, cpu.memory.screen_buffer(), SCREEN_WIDTH as usize * 3)
   |                                                  ^^^^^^^^^^^^^
bgourlie commented 7 years ago

Ah, I must have forgotten to push my latest changes. Will get that fixed up tonight.

bgourlie commented 7 years ago

After further investigation, it looks like you're trying to run the the linked example against the master branch. You'll want to check out the sdl-refactor branch. You can then run the emulator using the following command:

cargo run --example real_time --release -- /path/to/rom.nes

You'll need a ROM to run it against. Only a small set of ROMs are supported at the moment. Super mario brothers is known to run on it.

Cobrand commented 7 years ago

I don't really have the time to test that for you, sorry ... However I added a functionality on the master branch, please tell me if you see something when you add this to your code :

fn sdl2_print(priority: ::sdl2::log::Priority, category: ::sdl2::log::Category, message: &str) {
    println!("[{:?}][{:?}] {}", category, priority, message);
}

pub fn main() {
    ::sdl2::log::set_output_function(sdl2_print);
    // rest of your code here
}

It compiles but I haven't had the time to test if it actually odes something (it should).

bgourlie commented 7 years ago

I don't really have the time to test that for you, sorry

Oh, no problem at all! It seemed like you were trying to run it, so I wanted to make sure I gave you proper instructions if that were the case.

Thanks for addressing this so quickly, I'll try this out tonight!

bgourlie commented 7 years ago

please tell me if you see something when you add this to your code

Nothing was printed, unfortunately. I also re-profiled to verify that SDL_LogCritical was showing up.

Cobrand commented 7 years ago

Latest commit added sdl2::log::log(message: &str), and it works properly (whenever log() is called the message is displayed in the console). So I don't really know what the problem is ... maybe Log_Critical is actually never called ? I don't know wy there is such a high CPU usage though.

bgourlie commented 7 years ago

Yeah, it's odd. I really appreciate you taking the time to address this. I'll keep digging in to see if I can find what's going on. Feel free to close this ticket.

enerqi commented 7 years ago

Months ago I was profiling on Windows and I also saw SDL_LogCritical show up. I tried:

extern "C" {   
    pub fn SDL_LogSetOutputFunction(callback: Option<extern fn()>,
                                    userdata: Option<extern fn()>);
    }
    unsafe { SDL_LogSetOutputFunction(None, None); 
}

but that didn't help. Then I recompiled the SDL2 libraries with visual studio. When using the newly built DLLs SDL_LogCritical stopped showing up in the profile.