Last active
October 16, 2018 15:06
-
-
Save squarewave/53e8c5e563b2a47b43ed4853af7a9983 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This Source Code Form is subject to the terms of the Mozilla Public | |
* License, v. 2.0. If a copy of the MPL was not distributed with this | |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
extern crate euclid; | |
extern crate gleam; | |
extern crate glutin; | |
extern crate webrender; | |
extern crate winit; | |
#[path = "common/boilerplate.rs"] | |
mod boilerplate; | |
use boilerplate::Example; | |
use euclid::TypedScale; | |
use webrender::api::*; | |
// This example creates multiple documents overlapping each other with | |
// specified layer indices. | |
struct Document { | |
id: DocumentId, | |
pipeline_id: PipelineId, | |
sub_pipeline_id: PipelineId, | |
content_rect: LayoutRect, | |
color: ColorF, | |
skip: bool, | |
} | |
struct App { | |
documents: Vec<Document>, | |
} | |
impl App { | |
fn init( | |
&mut self, | |
api: &RenderApi, | |
framebuffer_size: DeviceUintSize, | |
device_pixel_ratio: f32, | |
) { | |
let init_data = vec![ | |
( | |
PipelineId(1, 0), | |
PipelineId(1, 1), | |
-1, | |
ColorF::new(0.0, 1.0, 0.0, 1.0), | |
DeviceUintPoint::new(0, 0), | |
), | |
( | |
PipelineId(2, 0), | |
PipelineId(2, 1), | |
-2, | |
ColorF::new(1.0, 1.0, 0.0, 1.0), | |
DeviceUintPoint::new(150, 0), | |
), | |
( | |
PipelineId(3, 0), | |
PipelineId(3, 1), | |
-3, | |
ColorF::new(1.0, 0.0, 0.0, 1.0), | |
DeviceUintPoint::new(150, 150), | |
), | |
( | |
PipelineId(4, 0), | |
PipelineId(4, 1), | |
-4, | |
ColorF::new(1.0, 0.0, 1.0, 1.0), | |
DeviceUintPoint::new(0, 150), | |
), | |
]; | |
for (pipeline_id, sub_pipeline_id, layer, color, offset) in init_data { | |
let size = DeviceUintSize::new(250, 250); | |
let bounds = DeviceUintRect::new(offset, size); | |
let document_id = api.add_document(size, layer); | |
let mut txn = Transaction::new(); | |
txn.set_window_parameters(framebuffer_size, bounds, device_pixel_ratio); | |
txn.set_root_pipeline(pipeline_id); | |
api.send_transaction(document_id, txn); | |
self.documents.push(Document { | |
id: document_id, | |
pipeline_id, | |
sub_pipeline_id, | |
content_rect: bounds.to_f32() / TypedScale::new(device_pixel_ratio), | |
color, | |
skip: false, | |
}); | |
} | |
} | |
} | |
impl Example for App { | |
fn on_event( | |
&mut self, | |
event: winit::WindowEvent, | |
_api: &RenderApi, | |
_document_id: DocumentId | |
) -> bool { | |
match event { | |
winit::WindowEvent::KeyboardInput { | |
input: winit::KeyboardInput { | |
state: winit::ElementState::Pressed, | |
virtual_keycode: Some(key), | |
.. | |
}, | |
.. | |
} => { | |
match key { | |
winit::VirtualKeyCode::Key3 => { | |
self.documents[0].skip = !self.documents[0].skip; | |
} | |
winit::VirtualKeyCode::Key4 => { | |
self.documents[1].skip = !self.documents[1].skip; | |
} | |
winit::VirtualKeyCode::Key5 => { | |
self.documents[2].skip = !self.documents[2].skip; | |
} | |
winit::VirtualKeyCode::Key6 => { | |
self.documents[3].skip = !self.documents[3].skip; | |
} | |
_ => {} | |
}; | |
} | |
_ => (), | |
} | |
true | |
} | |
fn render( | |
&mut self, | |
api: &RenderApi, | |
base_builder: &mut DisplayListBuilder, | |
_txn: &mut Transaction, | |
framebuffer_size: DeviceUintSize, | |
_: PipelineId, | |
_: DocumentId, | |
) { | |
if self.documents.is_empty() { | |
let device_pixel_ratio = framebuffer_size.width as f32 / | |
base_builder.content_size().width; | |
// this is the first run, hack around the boilerplate, | |
// which assumes an example only needs one document | |
self.init(api, framebuffer_size, device_pixel_ratio); | |
} | |
for doc in &self.documents { | |
if doc.skip { | |
continue; | |
} | |
let mut builder = DisplayListBuilder::new( | |
doc.pipeline_id, | |
doc.content_rect.size, | |
); | |
let local_rect = LayoutRect::new( | |
LayoutPoint::zero(), | |
doc.content_rect.size, | |
); | |
let mut sub_builder = DisplayListBuilder::new( | |
doc.sub_pipeline_id, | |
doc.content_rect.size, | |
); | |
sub_builder.push_stacking_context( | |
&LayoutPrimitiveInfo::new(local_rect), | |
None, | |
TransformStyle::Flat, | |
MixBlendMode::Normal, | |
Vec::new(), | |
RasterSpace::Screen, | |
); | |
sub_builder.push_rect( | |
&LayoutPrimitiveInfo::new(local_rect), | |
doc.color, | |
); | |
sub_builder.pop_stacking_context(); | |
let mut txn = Transaction::new(); | |
txn.set_display_list( | |
Epoch(0), | |
None, | |
doc.content_rect.size, | |
sub_builder.finalize(), | |
true, | |
); | |
api.send_transaction(doc.id, txn); | |
builder.push_stacking_context( | |
&LayoutPrimitiveInfo::new(doc.content_rect), | |
None, | |
TransformStyle::Flat, | |
MixBlendMode::Normal, | |
Vec::new(), | |
RasterSpace::Screen, | |
); | |
// white rect under the iframe: if this is visible, things have gone wrong | |
builder.push_rect(&LayoutPrimitiveInfo::new(local_rect), ColorF::new(1.0, 1.0, 1.0, 1.0)); | |
builder.push_iframe(&LayoutPrimitiveInfo::new(local_rect), doc.sub_pipeline_id, true); | |
builder.pop_stacking_context(); | |
let mut txn = Transaction::new(); | |
txn.set_display_list( | |
Epoch(0), | |
None, | |
doc.content_rect.size, | |
builder.finalize(), | |
true, | |
); | |
txn.generate_frame(); | |
api.send_transaction(doc.id, txn); | |
} | |
} | |
} | |
fn main() { | |
let mut app = App { | |
documents: Vec::new(), | |
}; | |
boilerplate::main_wrapper(&mut app, None); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment