Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render into bitmap callback is too slow. #147

Open
LaineZ opened this issue May 12, 2024 · 0 comments
Open

Render into bitmap callback is too slow. #147

LaineZ opened this issue May 12, 2024 · 0 comments

Comments

@LaineZ
Copy link

LaineZ commented May 12, 2024

I'm using a sciter.lite in ggez game framework. And I need draw a UI into the bitmap. There was a problem is low performance when render is goes into reasonable resolution like 2560×1440. The bitmap render callback renders one frame around 169-180 ms on my PC (Ryzen 9 5900X, RTX 3060, Windows 10).

Here is minimal-example, without any render output, just a generating bitmap

//! Windowless mode example (for Sciter.Lite build).
extern crate sciter;
extern crate winit;
extern crate winapi;
extern crate raw_window_handle;

use std::time::Instant;

use winit::event::{Event, WindowEvent};
use winit::event_loop::EventLoop;
use winit::window::WindowBuilder;

fn main() {
	if let Some(arg) = std::env::args().nth(1) {
		println!("loading sciter from {:?}", arg);
		if let Err(_) = sciter::set_options(sciter::RuntimeOptions::LibraryPath(&arg)) {
			panic!("Invalid sciter-lite dll specified.");
		}
	} else {
		panic!("usage: cargo run -p windowless -- sciter-sdk/bin.win/x64lite/sciter.dll")
	}

	// prepare and create a new window
	println!("create window");
	let events = EventLoop::new();

	use raw_window_handle::HasRawWindowHandle;
	let wnd = WindowBuilder::new();
	let wnd = wnd.build(&events).expect("Failed to create window");
	let window_handle = wnd.raw_window_handle();

	// configure Sciter
	println!("create sciter instance");
	sciter::set_options(sciter::RuntimeOptions::UxTheming(true)).unwrap();
	sciter::set_options(sciter::RuntimeOptions::DebugMode(true)).unwrap();
	sciter::set_options(sciter::RuntimeOptions::ScriptFeatures(0xFF)).unwrap();

	// create an engine instance with an opaque pointer as an identifier
	use sciter::windowless::{Message, handle_message};
	let scwnd = { &wnd as *const _ as sciter::types::HWINDOW };
	handle_message(scwnd, Message::Create { backend: sciter::types::GFX_LAYER::SKIA_OPENGL, transparent: false, });

	#[cfg(windows)]
	{
		// Windows-specific: we need to redraw window in response to a corresponding notification.
		// winit 0.20 has an explicit `Window::request_redraw` method,
		// here we use `winapi::InvalidateRect` for this.
		struct WindowlessHandler {
			hwnd: winapi::shared::windef::HWND,
		}

		impl sciter::HostHandler for WindowlessHandler {
			fn on_invalidate(&mut self, pnm: &sciter::host::SCN_INVALIDATE_RECT) {
				unsafe {
					let rc = &pnm.invalid_rect;
					let dst = winapi::shared::windef::RECT {
						left: rc.left,
						top: rc.top,
						right: rc.right,
						bottom: rc.bottom,
					};
					winapi::um::winuser::InvalidateRect(self.hwnd, &dst as *const _, 0);
					// println!("- {} {}", rc.width(), rc.height());
				}
			}
		}

		let handler = WindowlessHandler {
			hwnd: match window_handle {
				raw_window_handle::RawWindowHandle::Windows(data) => data.hwnd as winapi::shared::windef::HWND,
				_ => unreachable!(),
			},
		};

		let instance = sciter::Host::attach_with(scwnd, handler);

		let html = include_bytes!("../../minimal.htm");
		instance.load_html(html, Some("example://minimal.htm"));
	}

	// events processing
	use sciter::windowless::RenderEvent;

	println!("running...");

	let startup = std::time::Instant::now();

	// release CPU a bit, hackish
	std::thread::sleep(std::time::Duration::from_millis(0));

	handle_message(scwnd, Message::Heartbit {
		milliseconds: std::time::Instant::now().duration_since(startup).as_millis() as u32,
	});
	handle_message(scwnd, Message::Size { width: 2560, height: 1440 });

	// the actual event loop polling

	events.run(move |event, _, control_flow| {
		match event {
			Event::RedrawRequested(_) => {
				let on_render = move |bitmap_area: &sciter::types::RECT, bitmap_data: &[u8]|
				{
				};

				let render_time = Instant::now();
				let cb = RenderEvent {
					layer: None,
					callback: Box::new(on_render),
				};

				handle_message(scwnd, Message::RenderTo(cb));

				println!("Render took {} ms", render_time.elapsed().as_millis());
			},
			_ => (),
		}
	});
}

output:

loading sciter from "F:\\rust-sciter\\sciter-js-sdk-main\\sciter-js-sdk-main\\bin.lite\\windows\\x64\\sciter.dll"
create window
create sciter instance
running...
Render took 169 ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant