Skip to content

Commit 87812ae

Browse files
committed
Make the direct-composition demo compile to an empty program on non-windows.
1 parent 83edf97 commit 87812ae

File tree

3 files changed

+189
-187
lines changed

3 files changed

+189
-187
lines changed

direct-composition/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ version = "0.1.0"
44
authors = ["Simon Sapin <[email protected]>"]
55

66
[target.'cfg(windows)'.dependencies]
7-
winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
8-
9-
[dependencies]
107
euclid = "0.17"
118
gleam = "0.4"
129
mozangle = {version = "0.1", features = ["egl"]}
1310
webrender = {path = "../webrender"}
11+
winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
1412
winit = "0.10"

direct-composition/src/main.rs

Lines changed: 3 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -1,188 +1,7 @@
11
#[cfg(not(windows))]
2-
compile_error!("This demo only runs on Windows.");
3-
4-
extern crate direct_composition;
5-
extern crate euclid;
6-
extern crate gleam;
7-
extern crate webrender;
8-
extern crate winit;
9-
10-
use direct_composition::DirectComposition;
11-
use std::sync::mpsc;
12-
use webrender::api;
13-
use winit::os::windows::WindowExt;
14-
152
fn main() {
16-
let mut events_loop = winit::EventsLoop::new();
17-
18-
let (tx, rx) = mpsc::channel();
19-
let notifier = Box::new(Notifier { events_proxy: events_loop.create_proxy(), tx });
20-
21-
let window = winit::WindowBuilder::new()
22-
.with_title("WebRender + ANGLE + DirectComposition")
23-
.with_dimensions(1024, 768)
24-
.build(&events_loop)
25-
.unwrap();
26-
27-
let composition = direct_composition_from_window(&window);
28-
let factor = window.hidpi_factor();
29-
30-
let mut clicks: usize = 0;
31-
let mut offset_y = 100.;
32-
let size = api::DeviceUintSize::new;
33-
let mut rects = [
34-
Rectangle::new(&composition, &notifier, factor, size(300, 200), 0., 0.2, 0.4, 1.),
35-
Rectangle::new(&composition, &notifier, factor, size(400, 300), 0., 0.5, 0., 0.5),
36-
];
37-
rects[0].render(factor, &rx);
38-
rects[1].render(factor, &rx);
39-
40-
rects[0].visual.set_offset_x(100.);
41-
rects[0].visual.set_offset_y(50.);
42-
43-
rects[1].visual.set_offset_x(200.);
44-
rects[1].visual.set_offset_y(offset_y);
45-
46-
composition.commit();
47-
48-
events_loop.run_forever(|event| {
49-
if let winit::Event::WindowEvent { event, .. } = event {
50-
match event {
51-
winit::WindowEvent::Closed => {
52-
return winit::ControlFlow::Break
53-
}
54-
winit::WindowEvent::MouseWheel { delta, .. } => {
55-
let dy = match delta {
56-
winit::MouseScrollDelta::LineDelta(_, dy) => dy,
57-
winit::MouseScrollDelta::PixelDelta(_, dy) => dy,
58-
};
59-
offset_y = (offset_y - 10. * dy).max(0.).min(468.);
60-
61-
rects[1].visual.set_offset_y(offset_y);
62-
composition.commit();
63-
}
64-
winit::WindowEvent::MouseInput {
65-
button: winit::MouseButton::Left,
66-
state: winit::ElementState::Pressed,
67-
..
68-
} => {
69-
clicks += 1;
70-
let rect = &mut rects[clicks % 2];
71-
rect.color.g += 0.1;
72-
rect.color.g %= 1.;
73-
rect.render(factor, &rx)
74-
}
75-
_ => {}
76-
}
77-
}
78-
winit::ControlFlow::Continue
79-
});
80-
}
81-
82-
fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
83-
unsafe {
84-
DirectComposition::new(window.get_hwnd() as _)
85-
}
86-
}
87-
88-
struct Rectangle {
89-
visual: direct_composition::AngleVisual,
90-
renderer: Option<webrender::Renderer>,
91-
api: api::RenderApi,
92-
document_id: api::DocumentId,
93-
size: api::DeviceUintSize,
94-
color: api::ColorF,
3+
println!("This demo only runs on Windows.");
954
}
965

97-
impl Rectangle {
98-
fn new(composition: &DirectComposition, notifier: &Box<Notifier>,
99-
device_pixel_ratio: f32, size: api::DeviceUintSize, r: f32, g: f32, b: f32, a: f32)
100-
-> Self {
101-
let visual = composition.create_angle_visual(size.width, size.height);
102-
visual.make_current();
103-
104-
let (renderer, sender) = webrender::Renderer::new(
105-
composition.gleam.clone(),
106-
notifier.clone(),
107-
webrender::RendererOptions {
108-
clear_color: Some(api::ColorF::new(0., 0., 0., 0.)),
109-
device_pixel_ratio,
110-
..webrender::RendererOptions::default()
111-
},
112-
).unwrap();
113-
let api = sender.create_api();
114-
115-
Rectangle {
116-
visual,
117-
renderer: Some(renderer),
118-
document_id: api.add_document(size, 0),
119-
api,
120-
size,
121-
color: api::ColorF { r, g, b, a },
122-
}
123-
}
124-
125-
fn render(&mut self, device_pixel_ratio: f32, rx: &mpsc::Receiver<()>) {
126-
self.visual.make_current();
127-
128-
let pipeline_id = api::PipelineId(0, 0);
129-
let layout_size = self.size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
130-
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);
131-
132-
let rect = euclid::TypedRect::new(euclid::TypedPoint2D::zero(), layout_size);
133-
builder.push_rect(
134-
&api::PrimitiveInfo::with_clip(
135-
rect,
136-
api::LocalClip::RoundedRect(rect, api::ComplexClipRegion::new(
137-
rect, api::BorderRadius::uniform(20.), api::ClipMode::Clip,
138-
))
139-
),
140-
self.color,
141-
);
142-
143-
let mut transaction = api::Transaction::new();
144-
transaction.set_display_list(
145-
api::Epoch(0),
146-
None,
147-
layout_size,
148-
builder.finalize(),
149-
true,
150-
);
151-
transaction.set_root_pipeline(pipeline_id);
152-
transaction.generate_frame();
153-
self.api.send_transaction(self.document_id, transaction);
154-
rx.recv().unwrap();
155-
let renderer = self.renderer.as_mut().unwrap();
156-
renderer.update();
157-
renderer.render(self.size).unwrap();
158-
let _ = renderer.flush_pipeline_info();
159-
self.visual.present();
160-
}
161-
}
162-
163-
impl Drop for Rectangle {
164-
fn drop(&mut self) {
165-
self.renderer.take().unwrap().deinit()
166-
}
167-
}
168-
169-
#[derive(Clone)]
170-
struct Notifier {
171-
events_proxy: winit::EventsLoopProxy,
172-
tx: mpsc::Sender<()>,
173-
}
174-
175-
impl api::RenderNotifier for Notifier {
176-
fn clone(&self) -> Box<api::RenderNotifier> {
177-
Box::new(Clone::clone(self))
178-
}
179-
180-
fn wake_up(&self) {
181-
self.tx.send(()).unwrap();
182-
let _ = self.events_proxy.wakeup();
183-
}
184-
185-
fn new_document_ready(&self, _: api::DocumentId, _: bool, _: bool) {
186-
self.wake_up();
187-
}
188-
}
6+
#[cfg(windows)]
7+
include!("main_windows.rs");
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
extern crate direct_composition;
2+
extern crate euclid;
3+
extern crate gleam;
4+
extern crate webrender;
5+
extern crate winit;
6+
7+
use direct_composition::DirectComposition;
8+
use std::sync::mpsc;
9+
use webrender::api;
10+
use winit::os::windows::WindowExt;
11+
12+
fn main() {
13+
let mut events_loop = winit::EventsLoop::new();
14+
15+
let (tx, rx) = mpsc::channel();
16+
let notifier = Box::new(Notifier { events_proxy: events_loop.create_proxy(), tx });
17+
18+
let window = winit::WindowBuilder::new()
19+
.with_title("WebRender + ANGLE + DirectComposition")
20+
.with_dimensions(1024, 768)
21+
.build(&events_loop)
22+
.unwrap();
23+
24+
let composition = direct_composition_from_window(&window);
25+
let factor = window.hidpi_factor();
26+
27+
let mut clicks: usize = 0;
28+
let mut offset_y = 100.;
29+
let size = api::DeviceUintSize::new;
30+
let mut rects = [
31+
Rectangle::new(&composition, &notifier, factor, size(300, 200), 0., 0.2, 0.4, 1.),
32+
Rectangle::new(&composition, &notifier, factor, size(400, 300), 0., 0.5, 0., 0.5),
33+
];
34+
rects[0].render(factor, &rx);
35+
rects[1].render(factor, &rx);
36+
37+
rects[0].visual.set_offset_x(100.);
38+
rects[0].visual.set_offset_y(50.);
39+
40+
rects[1].visual.set_offset_x(200.);
41+
rects[1].visual.set_offset_y(offset_y);
42+
43+
composition.commit();
44+
45+
events_loop.run_forever(|event| {
46+
if let winit::Event::WindowEvent { event, .. } = event {
47+
match event {
48+
winit::WindowEvent::Closed => {
49+
return winit::ControlFlow::Break
50+
}
51+
winit::WindowEvent::MouseWheel { delta, .. } => {
52+
let dy = match delta {
53+
winit::MouseScrollDelta::LineDelta(_, dy) => dy,
54+
winit::MouseScrollDelta::PixelDelta(_, dy) => dy,
55+
};
56+
offset_y = (offset_y - 10. * dy).max(0.).min(468.);
57+
58+
rects[1].visual.set_offset_y(offset_y);
59+
composition.commit();
60+
}
61+
winit::WindowEvent::MouseInput {
62+
button: winit::MouseButton::Left,
63+
state: winit::ElementState::Pressed,
64+
..
65+
} => {
66+
clicks += 1;
67+
let rect = &mut rects[clicks % 2];
68+
rect.color.g += 0.1;
69+
rect.color.g %= 1.;
70+
rect.render(factor, &rx)
71+
}
72+
_ => {}
73+
}
74+
}
75+
winit::ControlFlow::Continue
76+
});
77+
}
78+
79+
fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
80+
unsafe {
81+
DirectComposition::new(window.get_hwnd() as _)
82+
}
83+
}
84+
85+
struct Rectangle {
86+
visual: direct_composition::AngleVisual,
87+
renderer: Option<webrender::Renderer>,
88+
api: api::RenderApi,
89+
document_id: api::DocumentId,
90+
size: api::DeviceUintSize,
91+
color: api::ColorF,
92+
}
93+
94+
impl Rectangle {
95+
fn new(composition: &DirectComposition, notifier: &Box<Notifier>,
96+
device_pixel_ratio: f32, size: api::DeviceUintSize, r: f32, g: f32, b: f32, a: f32)
97+
-> Self {
98+
let visual = composition.create_angle_visual(size.width, size.height);
99+
visual.make_current();
100+
101+
let (renderer, sender) = webrender::Renderer::new(
102+
composition.gleam.clone(),
103+
notifier.clone(),
104+
webrender::RendererOptions {
105+
clear_color: Some(api::ColorF::new(0., 0., 0., 0.)),
106+
device_pixel_ratio,
107+
..webrender::RendererOptions::default()
108+
},
109+
).unwrap();
110+
let api = sender.create_api();
111+
112+
Rectangle {
113+
visual,
114+
renderer: Some(renderer),
115+
document_id: api.add_document(size, 0),
116+
api,
117+
size,
118+
color: api::ColorF { r, g, b, a },
119+
}
120+
}
121+
122+
fn render(&mut self, device_pixel_ratio: f32, rx: &mpsc::Receiver<()>) {
123+
self.visual.make_current();
124+
125+
let pipeline_id = api::PipelineId(0, 0);
126+
let layout_size = self.size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
127+
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);
128+
129+
let rect = euclid::TypedRect::new(euclid::TypedPoint2D::zero(), layout_size);
130+
builder.push_rect(
131+
&api::PrimitiveInfo::with_clip(
132+
rect,
133+
api::LocalClip::RoundedRect(rect, api::ComplexClipRegion::new(
134+
rect, api::BorderRadius::uniform(20.), api::ClipMode::Clip,
135+
))
136+
),
137+
self.color,
138+
);
139+
140+
let mut transaction = api::Transaction::new();
141+
transaction.set_display_list(
142+
api::Epoch(0),
143+
None,
144+
layout_size,
145+
builder.finalize(),
146+
true,
147+
);
148+
transaction.set_root_pipeline(pipeline_id);
149+
transaction.generate_frame();
150+
self.api.send_transaction(self.document_id, transaction);
151+
rx.recv().unwrap();
152+
let renderer = self.renderer.as_mut().unwrap();
153+
renderer.update();
154+
renderer.render(self.size).unwrap();
155+
let _ = renderer.flush_pipeline_info();
156+
self.visual.present();
157+
}
158+
}
159+
160+
impl Drop for Rectangle {
161+
fn drop(&mut self) {
162+
self.renderer.take().unwrap().deinit()
163+
}
164+
}
165+
166+
#[derive(Clone)]
167+
struct Notifier {
168+
events_proxy: winit::EventsLoopProxy,
169+
tx: mpsc::Sender<()>,
170+
}
171+
172+
impl api::RenderNotifier for Notifier {
173+
fn clone(&self) -> Box<api::RenderNotifier> {
174+
Box::new(Clone::clone(self))
175+
}
176+
177+
fn wake_up(&self) {
178+
self.tx.send(()).unwrap();
179+
let _ = self.events_proxy.wakeup();
180+
}
181+
182+
fn new_document_ready(&self, _: api::DocumentId, _: bool, _: bool) {
183+
self.wake_up();
184+
}
185+
}

0 commit comments

Comments
 (0)