Skip to content

Instantly share code, notes, and snippets.

@TomMarius
Created March 8, 2020 14:27
Show Gist options
  • Select an option

  • Save TomMarius/6a7c7afa1aeb49428bd8615abc246938 to your computer and use it in GitHub Desktop.

Select an option

Save TomMarius/6a7c7afa1aeb49428bd8615abc246938 to your computer and use it in GitHub Desktop.
use gleam::gl;
use glutin;
use glutin::event::{Event, WindowEvent};
use glutin::event_loop::{ControlFlow, EventLoop};
use glutin::window::WindowBuilder;
use glutin::ContextBuilder;
use webrender;
use webrender::api::units::*;
use webrender::api::*;
use webrender::{DebugFlags, ShaderPrecacheFlags};
pub trait HandyDandyRectBuilder {
fn to(&self, x2: i32, y2: i32) -> LayoutRect;
fn by(&self, w: i32, h: i32) -> LayoutRect;
}
// Allows doing `(x, y).to(x2, y2)` or `(x, y).by(width, height)` with i32
// values to build a f32 LayoutRect
impl HandyDandyRectBuilder for (i32, i32) {
fn to(&self, x2: i32, y2: i32) -> LayoutRect {
LayoutRect::new(
LayoutPoint::new(self.0 as f32, self.1 as f32),
LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32),
)
}
fn by(&self, w: i32, h: i32) -> LayoutRect {
LayoutRect::new(
LayoutPoint::new(self.0 as f32, self.1 as f32),
LayoutSize::new(w as f32, h as f32),
)
}
}
struct Notifier {}
impl Notifier {
fn new() -> Notifier {
Notifier {}
}
}
impl RenderNotifier for Notifier {
fn clone(&self) -> Box<dyn RenderNotifier> {
Box::new(Notifier {})
}
fn wake_up(&self) {}
fn new_frame_ready(
&self,
_: DocumentId,
_scrolled: bool,
_composite_needed: bool,
_render_time_ns: Option<u64>,
) {
self.wake_up();
}
}
fn main() {
println!("Hello, world!");
let event_loop = EventLoop::new();
let window_builder = glutin::window::WindowBuilder::new();
let windowed_context = ContextBuilder::new()
.build_windowed(window_builder, &event_loop)
.unwrap();
let windowed_context = unsafe { windowed_context.make_current().unwrap() };
let window_size = windowed_context.window().inner_size();
let gl = match windowed_context.get_api() {
glutin::Api::OpenGl => unsafe {
gl::GlFns::load_with(|symbol| windowed_context.get_proc_address(symbol) as *const _)
},
glutin::Api::OpenGlEs => unsafe {
gl::GlesFns::load_with(|symbol| windowed_context.get_proc_address(symbol) as *const _)
},
glutin::Api::WebGl => unimplemented!(),
};
let notifier = Box::new(Notifier::new());
let debug_flags = DebugFlags::ECHO_DRIVER_MESSAGES | DebugFlags::TEXTURE_CACHE_DBG;
let opts = webrender::RendererOptions {
resource_override_path: None,
device_pixel_ratio: 1.0,
clear_color: Some(ColorF::new(1.0, 0.0, 0.0, 1.0)),
//scatter_gpu_cache_updates: false,
debug_flags,
//allow_texture_swizzling: false,
..webrender::RendererOptions::default()
};
let device_size = DeviceIntSize::new(window_size.width as i32, window_size.height as i32);
let (mut renderer, sender) =
webrender::Renderer::new(gl.clone(), notifier, opts, None, device_size).unwrap();
let api = sender.create_api();
let document_id = api.add_document(device_size, 0);
let epoch = Epoch(0);
let pipeline_id = PipelineId(0, 0);
let layout_size = device_size.to_f32() / euclid::Scale::new(1.0);
event_loop.run(move |event, _, control_flow| {
println!("{:?}", event);
*control_flow = ControlFlow::Wait;
match event {
Event::LoopDestroyed => return,
Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(physical_size) => windowed_context.resize(physical_size),
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
_ => (),
},
Event::RedrawRequested(_) => {
let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
let mut txn = Transaction::new();
// render code:
let content_bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
let spatial_id = root_space_and_clip.spatial_id;
builder.push_simple_stacking_context(
content_bounds.origin,
spatial_id,
PrimitiveFlags::IS_BACKFACE_VISIBLE,
);
let complex = ComplexClipRegion::new(
(50, 50).to(150, 150),
BorderRadius::uniform(20.0),
ClipMode::Clip,
);
let clip_id =
builder.define_clip(&root_space_and_clip, content_bounds, vec![complex], None);
builder.push_rect(
&CommonItemProperties::new(
(50, 50).to(150, 150),
SpaceAndClipInfo {
spatial_id,
clip_id,
},
),
ColorF::new(1.0, 1.0, 0.0, 1.0),
);
builder.pop_stacking_context();
// end render code
txn.set_display_list(
epoch,
Some(ColorF::new(1.0, 1.0, 0.0, 1.0)),
layout_size,
builder.finalize(),
true,
);
txn.set_root_pipeline(pipeline_id);
txn.generate_frame();
api.send_transaction(document_id, txn);
renderer.update();
renderer.render(device_size).unwrap();
renderer.flush_pipeline_info();
windowed_context.swap_buffers().unwrap();
}
_ => (),
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment