Skip to content

Commit 42a25b4

Browse files
committed
Render with WebRender
1 parent cc4980f commit 42a25b4

File tree

3 files changed

+85
-27
lines changed

3 files changed

+85
-27
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

direct-composition/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ winapi = {version = "0.3", features = ["winerror", "d3d11", "dcomp"]}
88

99
# For the `main.rs` demo
1010
[dependencies]
11+
euclid = "0.16"
1112
gleam = "0.4"
1213
webrender = {path = "../webrender"}
1314
winit = "0.10"

direct-composition/src/main.rs

Lines changed: 83 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,41 @@
22
compile_error!("This demo only runs on Windows.");
33

44
extern crate direct_composition;
5+
extern crate euclid;
56
extern crate gleam;
67
extern crate webrender;
78
extern crate winit;
89

910
use direct_composition::DirectComposition;
10-
use webrender::api::{ColorF, DeviceUintSize};
11+
use webrender::api;
1112
use winit::os::windows::WindowExt;
1213

1314
fn main() {
1415
let mut events_loop = winit::EventsLoop::new();
16+
let notifier = Box::new(Notifier { events_proxy: events_loop.create_proxy() });
17+
1518
let window = winit::WindowBuilder::new()
1619
.with_title("Hello, world!")
1720
.with_dimensions(1024, 768)
1821
.build(&events_loop)
1922
.unwrap();
2023

2124
let composition = direct_composition_from_window(&window);
22-
23-
let (renderer, _api_sender) = webrender::Renderer::new(
24-
composition.gleam.clone(),
25-
Box::new(Notifier { events_proxy: events_loop.create_proxy() }),
26-
webrender::RendererOptions::default(),
27-
).unwrap();
25+
let factor = window.hidpi_factor();
2826

2927
let mut clicks: usize = 0;
3028
let mut offset_y = 100.;
29+
let size = api::DeviceUintSize::new;
3130
let mut rects = [
32-
Rectangle::new(&composition, DeviceUintSize::new(300, 200), 0., 0.2, 0.4, 1.),
33-
Rectangle::new(&composition, DeviceUintSize::new(400, 300), 0., 0.5, 0., 0.5),
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),
3433
];
35-
rects[0].render();
36-
rects[1].render();
34+
rects[0].render(factor);
35+
rects[1].render(factor);
36+
37+
// FIXME: what shows up on screen for each visual seems to be one frame late?
38+
rects[0].render(factor);
39+
rects[1].render(factor);
3740

3841
rects[0].visual.set_offset_x(100.);
3942
rects[0].visual.set_offset_y(50.);
@@ -68,15 +71,13 @@ fn main() {
6871
let rect = &mut rects[clicks % 2];
6972
rect.color.g += 0.1;
7073
rect.color.g %= 1.;
71-
rect.render()
74+
rect.render(factor)
7275
}
7376
_ => {}
7477
}
7578
}
7679
winit::ControlFlow::Continue
7780
});
78-
79-
renderer.deinit()
8081
}
8182

8283
fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
@@ -87,44 +88,99 @@ fn direct_composition_from_window(window: &winit::Window) -> DirectComposition {
8788

8889
struct Rectangle {
8990
visual: direct_composition::AngleVisual,
90-
color: ColorF,
91+
renderer: Option<webrender::Renderer>,
92+
api: api::RenderApi,
93+
document_id: api::DocumentId,
94+
size: api::DeviceUintSize,
95+
color: api::ColorF,
9196
}
9297

9398
impl Rectangle {
94-
fn new(composition: &DirectComposition, size: DeviceUintSize,
95-
r: f32, g: f32, b: f32, a: f32)
99+
fn new(composition: &DirectComposition, notifier: &Box<Notifier>,
100+
device_pixel_ratio: f32, size: api::DeviceUintSize, r: f32, g: f32, b: f32, a: f32)
96101
-> Self {
97-
Rectangle {
98-
visual: composition.create_angle_visual(size.width, size.height),
99-
color: ColorF { r, g, b, a },
102+
let visual = composition.create_angle_visual(size.width, size.height);
103+
visual.make_current();
104+
105+
let (renderer, sender) = webrender::Renderer::new(
106+
composition.gleam.clone(),
107+
notifier.clone(),
108+
webrender::RendererOptions {
109+
clear_color: Some(api::ColorF::new(0., 0., 0., 0.)),
110+
device_pixel_ratio,
111+
..webrender::RendererOptions::default()
112+
},
113+
).unwrap();
114+
let api = sender.create_api();
115+
116+
Rectangle {
117+
visual,
118+
renderer: Some(renderer),
119+
document_id: api.add_document(size, 0),
120+
api,
121+
size,
122+
color: api::ColorF { r, g, b, a },
100123
}
101124
}
102125

103-
fn render(&self) {
126+
fn render(&mut self, device_pixel_ratio: f32) {
104127
self.visual.make_current();
105-
self.visual.gleam.clear_color(self.color.r, self.color.g, self.color.b, self.color.a);
106-
self.visual.gleam.clear(gleam::gl::COLOR_BUFFER_BIT);
107-
assert_eq!(self.visual.gleam.get_error(), 0);
128+
129+
let pipeline_id = api::PipelineId(0, 0);
130+
let layout_size = self.size.to_f32() / euclid::TypedScale::new(device_pixel_ratio);
131+
let mut builder = api::DisplayListBuilder::new(pipeline_id, layout_size);
132+
133+
let rect = euclid::TypedRect::new(euclid::TypedPoint2D::zero(), layout_size);
134+
builder.push_rect(
135+
&api::PrimitiveInfo::with_clip(
136+
rect,
137+
api::LocalClip::RoundedRect(rect, api::ComplexClipRegion::new(
138+
rect, api::BorderRadius::uniform(20.), api::ClipMode::Clip,
139+
))
140+
),
141+
self.color,
142+
);
143+
144+
let mut transaction = api::Transaction::new();
145+
transaction.set_display_list(
146+
api::Epoch(0),
147+
None,
148+
layout_size,
149+
builder.finalize(),
150+
true,
151+
);
152+
transaction.set_root_pipeline(pipeline_id);
153+
transaction.generate_frame();
154+
self.api.send_transaction(self.document_id, transaction);
155+
let renderer = self.renderer.as_mut().unwrap();
156+
renderer.update();
157+
renderer.render(self.size).unwrap();
158+
let _ = renderer.flush_pipeline_info();
108159
self.visual.present();
109160
}
110161
}
111162

163+
impl Drop for Rectangle {
164+
fn drop(&mut self) {
165+
self.renderer.take().unwrap().deinit()
166+
}
167+
}
112168

113169
#[derive(Clone)]
114170
struct Notifier {
115171
events_proxy: winit::EventsLoopProxy,
116172
}
117173

118-
impl webrender::api::RenderNotifier for Notifier {
119-
fn clone(&self) -> Box<webrender::api::RenderNotifier> {
174+
impl api::RenderNotifier for Notifier {
175+
fn clone(&self) -> Box<api::RenderNotifier> {
120176
Box::new(Clone::clone(self))
121177
}
122178

123179
fn wake_up(&self) {
124180
let _ = self.events_proxy.wakeup();
125181
}
126182

127-
fn new_document_ready(&self, _: webrender::api::DocumentId, _: bool, _: bool) {
183+
fn new_document_ready(&self, _: api::DocumentId, _: bool, _: bool) {
128184
self.wake_up();
129185
}
130186
}

0 commit comments

Comments
 (0)