use crate::it::test_client::TestClientExt;
use crate::it::test_error::TestResult;
use crate::it::testrun::TestRun;
use crate::syncobj::SyncobjError;
use crate::syncobj::wait_for_syncobj::SyncobjWaiter;
use crate::theme::Color;
use crate::utils::errorfmt::ErrorFmt;
use crate::video::drm::syncobj::SyncobjPoint;
use std::cell::Cell;
use std::rc::Rc;
testcase!();
async fn test(run: Rc<TestRun>) -> TestResult {
let _ds = run.create_default_setup2(true).await?;
struct Waiter(Cell<bool>);
impl SyncobjWaiter for Waiter {
fn done(self: Rc<Self>, result: Result<(), SyncobjError>) {
result.unwrap();
self.0.set(true);
}
}
let waiter = Rc::new(Waiter(Cell::new(false)));
let eng = run.state.render_ctx.get().unwrap();
let Some(ctx) = eng.syncobj_ctx() else {
log::warn!(
"Cannot test explicit sync on this system: render context does not support sync objects"
);
return Ok(());
};
let syncobj = match ctx.create_syncobj() {
Ok(s) => Rc::new(s),
Err(e) => {
log::warn!("Cannot test explicit sync on this system: {}", ErrorFmt(e));
return Ok(());
}
};
let _wait_handle =
run.state
.wait_for_syncobj
.wait(&syncobj, SyncobjPoint(2), true, waiter.clone())?;
let client = run.create_client()?;
let buf1 = client.create_single_pixel_buffer(Color::SOLID_BLACK);
let buf2 = client.create_single_pixel_buffer(Color::SOLID_BLACK);
let timeline = client.import_syncobj_timeline(&syncobj);
let win = client.create_window().await?;
let sync = client.get_syncobj_surface(&win.surface);
win.surface.attach(buf1.id);
sync.set_acquire_point(&timeline, 1);
sync.set_release_point(&timeline, 2);
win.surface.commit();
sync.destroy();
win.surface.attach(buf2.id);
win.surface.commit();
client.sync().await;
tassert_eq!(waiter.0.get(), false);
ctx.signal(&syncobj, SyncobjPoint(1))?;
client.sync().await;
tassert_eq!(waiter.0.get(), true);
Ok(())
}