Wait for rendering after Update

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau
2021-02-20 15:51:58 +04:00
parent 2a26d33561
commit 35758dacb0
4 changed files with 61 additions and 29 deletions
+22 -6
View File
@@ -4,6 +4,7 @@ use gtk::prelude::*;
use gtk::subclass::widget::WidgetImplExt;
use gtk::{glib, CompositeTemplate};
use once_cell::sync::OnceCell;
use std::cell::Cell;
use keycodemap::*;
use qemu_display_listener::{Console, Event, MouseButton};
@@ -21,6 +22,7 @@ mod imp {
#[template_child]
pub label: TemplateChild<gtk::Label>,
pub console: OnceCell<Console>,
pub wait_rendering: Cell<usize>,
}
impl ObjectSubclass for QemuConsole {
@@ -137,23 +139,37 @@ glib::wrapper! {
impl QemuConsole {
pub fn set_qemu_console(&self, console: Console) {
let priv_ = imp::QemuConsole::from_instance(self);
let rx = console
let (rx, wait_tx) = console
.glib_listen()
.expect("Failed to listen to the console");
priv_
.area
.connect_render(clone!(@weak self as obj => move |_, _| {
let priv_ = imp::QemuConsole::from_instance(&obj);
let wait_rendering = priv_.wait_rendering.get();
if wait_rendering > 0 {
if let Err(e) = wait_tx.send(()) {
eprintln!("Failed to ack rendering: {}", e);
}
priv_.wait_rendering.set(wait_rendering - 1);
}
glib::signal::Inhibit(false)
}));
rx.attach(
None,
clone!(@weak self as con => move |t| {
let con = imp::QemuConsole::from_instance(&con);
let priv_ = imp::QemuConsole::from_instance(&con);
match t {
Event::Update { .. } => {
con.area.queue_render();
priv_.wait_rendering.set(priv_.wait_rendering.get() + 1);
priv_.area.queue_render();
}
Event::Scanout(s) => {
con.label.set_label(&format!("{:?}", s));
con.area.set_scanout(s);
priv_.label.set_label(&format!("{:?}", s));
priv_.area.set_scanout(s);
}
Event::Disconnected => {
con.label.set_label("Console disconnected!");
priv_.label.set_label("Console disconnected!");
}
_ => ()
}
+7 -6
View File
@@ -75,7 +75,7 @@ mod imp {
widget.make_current();
if let Err(e) = unsafe { self.realize_gl() } {
let e = glib::Error::new(AppError::GL, &format!("{}", e));
let e = glib::Error::new(AppError::GL, &e.to_string());
widget.set_error(Some(&e));
}
}
@@ -92,7 +92,8 @@ mod imp {
gl::Viewport(vp.x, vp.y, vp.width, vp.height);
self.texture_blit(false);
}
return true; /* FIXME: Inibit */
// parent will return to update call
false
}
}
@@ -308,11 +309,11 @@ impl QemuConsoleArea {
}
}
unsafe fn compile_shader(type_: GLenum, src: &CStr) -> Result<GLuint, String> {
unsafe fn compile_shader(type_: GLenum, src: &CStr) -> GLuint {
let shader = gl::CreateShader(type_);
gl::ShaderSource(shader, 1, &src.as_ptr(), std::ptr::null());
gl::CompileShader(shader);
Ok(shader)
shader
}
fn cstring_new_len(len: usize) -> CString {
@@ -321,8 +322,8 @@ fn cstring_new_len(len: usize) -> CString {
}
unsafe fn compile_prog(vs: &CStr, fs: &CStr) -> Result<GLuint, String> {
let vs = compile_shader(gl::VERTEX_SHADER, vs)?;
let fs = compile_shader(gl::FRAGMENT_SHADER, fs)?;
let vs = compile_shader(gl::VERTEX_SHADER, vs);
let fs = compile_shader(gl::FRAGMENT_SHADER, fs);
let prog = gl::CreateProgram();
gl::AttachShader(prog, vs);