fix(smoke): drop renderer before window teardown
This commit is contained in:
@@ -185,6 +185,14 @@ struct SmokeApp {
|
|||||||
started_at: Instant,
|
started_at: Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn drop_renderer_before_window<Renderer, WindowLike>(
|
||||||
|
renderer: &mut Option<Renderer>,
|
||||||
|
window: &mut Option<WindowLike>,
|
||||||
|
) {
|
||||||
|
drop(renderer.take());
|
||||||
|
drop(window.take());
|
||||||
|
}
|
||||||
|
|
||||||
impl SmokeApp {
|
impl SmokeApp {
|
||||||
fn new(
|
fn new(
|
||||||
options: SmokeOptions,
|
options: SmokeOptions,
|
||||||
@@ -408,6 +416,14 @@ impl SmokeApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for SmokeApp {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Keep the native window alive until the Vulkan renderer finishes
|
||||||
|
// destroying swapchain and surface state that still references it.
|
||||||
|
drop_renderer_before_window(&mut self.renderer, &mut self.window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn render_timeout_failure_report(
|
fn render_timeout_failure_report(
|
||||||
options: &SmokeOptions,
|
options: &SmokeOptions,
|
||||||
failure_reason: &str,
|
failure_reason: &str,
|
||||||
@@ -859,6 +875,32 @@ fn parse_bool_env(value: &str) -> Option<bool> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
enum DropStep {
|
||||||
|
Renderer,
|
||||||
|
Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DropTracker {
|
||||||
|
step: DropStep,
|
||||||
|
log: Rc<RefCell<Vec<DropStep>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for DropTracker {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.log.borrow_mut().push(self.step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tracker(step: DropStep, log: &Rc<RefCell<Vec<DropStep>>>) -> DropTracker {
|
||||||
|
DropTracker {
|
||||||
|
step,
|
||||||
|
log: Rc::clone(log),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parses_required_args() {
|
fn parses_required_args() {
|
||||||
@@ -1058,4 +1100,20 @@ mod tests {
|
|||||||
std::fs::remove_file(out).expect("cleanup report");
|
std::fs::remove_file(out).expect("cleanup report");
|
||||||
std::fs::remove_dir(root).expect("cleanup dir");
|
std::fs::remove_dir(root).expect("cleanup dir");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn renderer_is_dropped_before_window() {
|
||||||
|
let log = Rc::new(RefCell::new(Vec::new()));
|
||||||
|
let mut renderer = Some(tracker(DropStep::Renderer, &log));
|
||||||
|
let mut window = Some(tracker(DropStep::Window, &log));
|
||||||
|
|
||||||
|
drop_renderer_before_window(&mut renderer, &mut window);
|
||||||
|
|
||||||
|
assert!(renderer.is_none());
|
||||||
|
assert!(window.is_none());
|
||||||
|
assert_eq!(
|
||||||
|
Rc::into_inner(log).expect("trackers released").into_inner(),
|
||||||
|
vec![DropStep::Renderer, DropStep::Window]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user