Skip to content

Commit 4c85831

Browse files
committed
Add reftesting framework
1 parent 61d89dc commit 4c85831

File tree

9 files changed

+153
-0
lines changed

9 files changed

+153
-0
lines changed

wrench/reftests/green.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
root:
3+
items:
4+
-
5+
bounds: [0, 0, 95, 88]
6+
type: rect
7+
color: green

wrench/reftests/mask-ref.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
root:
3+
items:
4+
-
5+
bounds: [0, 0, 95, 88]
6+
items:
7+
-
8+
bounds: [9, 9, 10, 10]
9+
type: rect
10+
color: blue
11+
type: stacking_context

wrench/reftests/mask.png

187 Bytes
Loading

wrench/reftests/mask.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
root:
3+
items:
4+
-
5+
bounds: [0, 0, 95, 88]
6+
clip:
7+
image_mask:
8+
image: "mask.png"
9+
rect: [0, 0, 35, 35]
10+
repeat: false
11+
rect: [0, 0, 95, 88]
12+
items:
13+
-
14+
bounds: [0, 0, 95, 88]
15+
type: rect
16+
color: blue
17+
type: stacking_context

wrench/reftests/reftest.list

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
== mask.yaml mask-ref.yaml
2+
!= mask.yaml green.yaml

wrench/run_tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,5 @@ def set_osmesa_env(bin_path):
6262

6363
set_osmesa_env('../target/release/')
6464
subprocess.check_call(['../target/release/wrench', '-t', '1', '-h', 'show', sys.argv[1]])
65+
subprocess.check_call(['../target/release/wrench', '-h', 'reftest'])
6566
print('md5 = ' + hashlib.md5(open('screenshot.png', 'rb').read()).hexdigest())

wrench/src/args.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,5 @@ subcommands:
8989
help: The input binary file or directory
9090
required: true
9191
index: 1
92+
- reftest:
93+
about: run reftests

wrench/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ use yaml_frame_reader::YamlFrameReader;
5555
mod yaml_frame_writer;
5656
mod json_frame_writer;
5757
mod scene;
58+
mod reftest;
59+
use reftest::run_reftests;
5860

5961
mod binary_frame_reader;
6062
use binary_frame_reader::BinaryFrameReader;
@@ -301,6 +303,9 @@ fn main() {
301303
Box::new(YamlFrameReader::new_from_args(subargs)) as Box<WrenchThing>
302304
} else if let Some(subargs) = args.subcommand_matches("replay") {
303305
Box::new(BinaryFrameReader::new_from_args(subargs)) as Box<WrenchThing>
306+
} else if let Some(_) = args.subcommand_matches("reftest") {
307+
run_reftests(&mut wrench, &mut window, "reftests/reftest.list");
308+
return;
304309
} else {
305310
panic!("Should never have gotten here");
306311
};

wrench/src/reftest.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
use std::io::BufReader;
2+
use std::io::BufRead;
3+
use std::fs::File;
4+
use wrench::{Wrench, WrenchThing};
5+
use std::path::Path;
6+
use gleam::gl;
7+
use std::sync::mpsc::{channel, Sender, Receiver};
8+
9+
use yaml_frame_reader::YamlFrameReader;
10+
use webrender_traits::*;
11+
12+
use WindowWrapper;
13+
14+
pub enum ReftestOp {
15+
Equal,
16+
NotEqual,
17+
}
18+
19+
pub struct Reftest<'a> {
20+
op: ReftestOp,
21+
test: &'a Path,
22+
reference: &'a Path,
23+
}
24+
25+
pub fn parse_reftests<F>(filename: &str, mut runner: F)
26+
where F: FnMut(Reftest)
27+
{
28+
let manifest = Path::new(filename);
29+
let dir = manifest.parent().unwrap();
30+
let f = File::open(manifest).unwrap();
31+
let file = BufReader::new(&f);
32+
for line in file.lines() {
33+
let l = line.unwrap();
34+
if l.starts_with("#") {
35+
continue;
36+
}
37+
38+
// strip the comments
39+
let s = &l[0..l.find("#").unwrap_or(l.len())];
40+
let s = s.trim();
41+
if l.len() == 0 {
42+
continue;
43+
}
44+
let mut items = s.split_whitespace();
45+
let kind = match items.next() {
46+
Some("==") => ReftestOp::Equal,
47+
Some("!=") => ReftestOp::NotEqual,
48+
_ => panic!(),
49+
};
50+
let test = dir.join(items.next().unwrap());
51+
let reference = dir.join(items.next().unwrap());
52+
runner(Reftest {
53+
op: kind,
54+
test: test.as_path(),
55+
reference: reference.as_path(),
56+
});
57+
}
58+
59+
}
60+
61+
62+
fn render_yaml(wrench: &mut Wrench,
63+
window: &mut WindowWrapper,
64+
filename: &Path,
65+
rx: &Receiver<()>)
66+
-> Vec<u8> {
67+
let mut reader = YamlFrameReader::new(filename);
68+
reader.do_frame(wrench);
69+
// wait for the frame
70+
rx.recv().unwrap();
71+
wrench.render();
72+
73+
let size = window.get_inner_size();
74+
let pixels = gl::read_pixels(0,
75+
0,
76+
size.0 as gl::GLsizei,
77+
size.1 as gl::GLsizei,
78+
gl::RGBA,
79+
gl::UNSIGNED_BYTE);
80+
window.swap_buffers();
81+
pixels
82+
}
83+
84+
pub fn run_reftests(wrench: &mut Wrench, window: &mut WindowWrapper, filename: &str) {
85+
// setup a notifier so we can wait for frames to be finished
86+
struct Notifier {
87+
tx: Sender<()>,
88+
};
89+
impl RenderNotifier for Notifier {
90+
fn new_frame_ready(&mut self) {
91+
self.tx.send(()).unwrap();
92+
}
93+
fn new_scroll_frame_ready(&mut self, _composite_needed: bool) {}
94+
fn pipeline_size_changed(&mut self, _: PipelineId, _: Option<LayoutSize>) {}
95+
}
96+
let (tx, rx) = channel();
97+
wrench.renderer.set_render_notifier(Box::new(Notifier { tx: tx }));
98+
99+
parse_reftests(filename, |t: Reftest| {
100+
println!("{} {}", t.test.display(), t.reference.display());
101+
let test = render_yaml(wrench, window, t.test, &rx);
102+
let reference = render_yaml(wrench, window, t.reference, &rx);
103+
match t.op {
104+
ReftestOp::Equal => assert!(test == reference),
105+
ReftestOp::NotEqual => assert!(test != reference),
106+
}
107+
});
108+
}

0 commit comments

Comments
 (0)