1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 extern crate webrender;
12 use glutin::NotCurrent;
15 use webrender::api::*;
16 use webrender::api::units::*;
17 use webrender::render_api::*;
18 use webrender::DebugFlags;
19 use winit::dpi::LogicalSize;
20 use winit::platform::run_return::EventLoopExtRunReturn;
23 events_proxy: winit::event_loop::EventLoopProxy<()>,
27 fn new(events_proxy: winit::event_loop::EventLoopProxy<()>) -> Notifier {
28 Notifier { events_proxy }
32 impl RenderNotifier for Notifier {
33 fn clone(&self) -> Box<dyn RenderNotifier> {
35 events_proxy: self.events_proxy.clone(),
39 fn wake_up(&self, _composite_needed: bool) {
40 #[cfg(not(target_os = "android"))]
41 let _ = self.events_proxy.send_event(());
44 fn new_frame_ready(&self,
47 composite_needed: bool,
49 self.wake_up(composite_needed);
54 events_loop: winit::event_loop::EventLoop<()>, //TODO: share events loop?
55 context: Option<glutin::WindowedContext<NotCurrent>>,
56 renderer: webrender::Renderer,
58 pipeline_id: PipelineId,
59 document_id: DocumentId,
62 font_instance_key: FontInstanceKey,
66 fn new(name: &'static str, clear_color: ColorF) -> Self {
67 let events_loop = winit::event_loop::EventLoop::new();
68 let window_builder = winit::window::WindowBuilder::new()
70 .with_inner_size(LogicalSize::new(800. as f64, 600. as f64));
71 let context = glutin::ContextBuilder::new()
72 .with_gl(glutin::GlRequest::GlThenGles {
73 opengl_version: (3, 2),
74 opengles_version: (3, 0),
76 .build_windowed(window_builder, &events_loop)
79 let context = unsafe { context.make_current().unwrap() };
81 let gl = match context.get_api() {
82 glutin::Api::OpenGl => unsafe {
83 gl::GlFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
85 glutin::Api::OpenGlEs => unsafe {
86 gl::GlesFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
88 glutin::Api::WebGl => unimplemented!(),
91 let opts = webrender::WebRenderOptions {
93 ..webrender::WebRenderOptions::default()
100 DeviceIntSize::new(size.width as i32, size.height as i32)
102 let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
103 let (renderer, sender) = webrender::create_webrender_instance(gl.clone(), notifier, opts, None).unwrap();
104 let mut api = sender.create_api();
105 let document_id = api.add_document(device_size);
107 let epoch = Epoch(0);
108 let pipeline_id = PipelineId(0, 0);
109 let mut txn = Transaction::new();
111 let font_key = api.generate_font_key();
112 let font_bytes = load_file("../wrench/reftests/text/FreeSans.ttf");
113 txn.add_raw_font(font_key, font_bytes, 0);
115 let font_instance_key = api.generate_font_instance_key();
116 txn.add_font_instance(font_instance_key, font_key, 32.0, None, None, Vec::new());
118 api.send_transaction(document_id, txn);
122 context: Some(unsafe { context.make_not_current().unwrap() }),
133 fn tick(&mut self) -> bool {
134 let mut do_exit = false;
135 let my_name = &self.name;
136 let renderer = &mut self.renderer;
137 let api = &mut self.api;
139 self.events_loop.run_return(|global_event, _elwt, control_flow| {
140 *control_flow = winit::event_loop::ControlFlow::Exit;
142 winit::event::Event::WindowEvent { event, .. } => match event {
143 winit::event::WindowEvent::CloseRequested |
144 winit::event::WindowEvent::KeyboardInput {
145 input: winit::event::KeyboardInput {
146 virtual_keycode: Some(winit::event::VirtualKeyCode::Escape),
153 winit::event::WindowEvent::KeyboardInput {
154 input: winit::event::KeyboardInput {
155 state: winit::event::ElementState::Pressed,
156 virtual_keycode: Some(winit::event::VirtualKeyCode::P),
161 println!("set flags {}", my_name);
162 api.send_debug_cmd(DebugCommand::SetFlags(DebugFlags::PROFILER_DBG))
173 let context = unsafe { self.context.take().unwrap().make_current().unwrap() };
174 let device_pixel_ratio = context.window().scale_factor() as f32;
179 DeviceIntSize::new(size.width as i32, size.height as i32)
181 let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
182 let mut txn = Transaction::new();
183 let mut builder = DisplayListBuilder::new(self.pipeline_id);
184 let space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);
187 let bounds = LayoutRect::from_size(layout_size);
188 builder.push_simple_stacking_context(
190 space_and_clip.spatial_id,
191 PrimitiveFlags::IS_BACKFACE_VISIBLE,
195 &CommonItemProperties::new(
196 LayoutRect::from_origin_and_size(
197 LayoutPoint::new(100.0, 200.0),
198 LayoutSize::new(100.0, 200.0),
202 LayoutRect::from_origin_and_size(
203 LayoutPoint::new(100.0, 200.0),
204 LayoutSize::new(100.0, 200.0),
206 ColorF::new(0.0, 1.0, 0.0, 1.0));
208 let text_bounds = LayoutRect::from_origin_and_size(
209 LayoutPoint::new(100.0, 50.0),
210 LayoutSize::new(700.0, 200.0)
215 point: LayoutPoint::new(100.0, 100.0),
219 point: LayoutPoint::new(150.0, 100.0),
223 point: LayoutPoint::new(200.0, 100.0),
227 point: LayoutPoint::new(250.0, 100.0),
231 point: LayoutPoint::new(300.0, 100.0),
235 point: LayoutPoint::new(350.0, 100.0),
239 point: LayoutPoint::new(400.0, 100.0),
243 point: LayoutPoint::new(450.0, 100.0),
247 point: LayoutPoint::new(500.0, 100.0),
251 point: LayoutPoint::new(550.0, 100.0),
255 point: LayoutPoint::new(600.0, 100.0),
259 point: LayoutPoint::new(650.0, 100.0),
264 &CommonItemProperties::new(
270 self.font_instance_key,
271 ColorF::new(1.0, 1.0, 0.0, 1.0),
275 builder.pop_stacking_context();
277 txn.set_display_list(
281 txn.set_root_pipeline(self.pipeline_id);
282 txn.generate_frame(0, RenderReasons::empty());
283 api.send_transaction(self.document_id, txn);
286 renderer.render(device_size, 0).unwrap();
287 context.swap_buffers().ok();
289 self.context = Some(unsafe { context.make_not_current().unwrap() });
295 self.renderer.deinit();
300 let mut win1 = Window::new("window1", ColorF::new(0.3, 0.0, 0.0, 1.0));
301 let mut win2 = Window::new("window2", ColorF::new(0.0, 0.3, 0.0, 1.0));
316 fn load_file(name: &str) -> Vec<u8> {
317 let mut file = File::open(name).unwrap();
318 let mut buffer = vec![];
319 file.read_to_end(&mut buffer).unwrap();