2018-11-23 00:47:48 +03:00
|
|
|
/* 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;
|
|
|
|
|
|
|
|
use gleam::gl;
|
2019-07-10 14:12:08 +03:00
|
|
|
use glutin::NotCurrent;
|
2018-11-23 00:47:48 +03:00
|
|
|
use std::fs::File;
|
|
|
|
use std::io::Read;
|
|
|
|
use webrender::api::*;
|
2019-03-14 04:44:05 +03:00
|
|
|
use webrender::api::units::*;
|
2018-12-22 00:12:36 +03:00
|
|
|
use webrender::DebugFlags;
|
2018-11-23 00:47:48 +03:00
|
|
|
use winit::dpi::LogicalSize;
|
|
|
|
|
|
|
|
struct Notifier {
|
|
|
|
events_proxy: winit::EventsLoopProxy,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Notifier {
|
|
|
|
fn new(events_proxy: winit::EventsLoopProxy) -> Notifier {
|
|
|
|
Notifier { events_proxy }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RenderNotifier for Notifier {
|
2019-06-05 17:07:48 +03:00
|
|
|
fn clone(&self) -> Box<dyn RenderNotifier> {
|
2018-11-23 00:47:48 +03:00
|
|
|
Box::new(Notifier {
|
|
|
|
events_proxy: self.events_proxy.clone(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
fn wake_up(&self) {
|
|
|
|
#[cfg(not(target_os = "android"))]
|
|
|
|
let _ = self.events_proxy.wakeup();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn new_frame_ready(&self,
|
|
|
|
_: DocumentId,
|
|
|
|
_scrolled: bool,
|
|
|
|
_composite_needed: bool,
|
|
|
|
_render_time: Option<u64>) {
|
|
|
|
self.wake_up();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Window {
|
|
|
|
events_loop: winit::EventsLoop, //TODO: share events loop?
|
2019-07-10 14:12:08 +03:00
|
|
|
context: Option<glutin::WindowedContext<NotCurrent>>,
|
2018-11-23 00:47:48 +03:00
|
|
|
renderer: webrender::Renderer,
|
|
|
|
name: &'static str,
|
|
|
|
pipeline_id: PipelineId,
|
|
|
|
document_id: DocumentId,
|
|
|
|
epoch: Epoch,
|
|
|
|
api: RenderApi,
|
|
|
|
font_instance_key: FontInstanceKey,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Window {
|
|
|
|
fn new(name: &'static str, clear_color: ColorF) -> Self {
|
|
|
|
let events_loop = winit::EventsLoop::new();
|
|
|
|
let window_builder = winit::WindowBuilder::new()
|
|
|
|
.with_title(name)
|
|
|
|
.with_multitouch()
|
|
|
|
.with_dimensions(LogicalSize::new(800., 600.));
|
2019-07-10 14:12:08 +03:00
|
|
|
let context = glutin::ContextBuilder::new()
|
|
|
|
.with_gl(glutin::GlRequest::GlThenGles {
|
|
|
|
opengl_version: (3, 2),
|
|
|
|
opengles_version: (3, 0),
|
|
|
|
})
|
|
|
|
.build_windowed(window_builder, &events_loop)
|
2018-11-23 00:47:48 +03:00
|
|
|
.unwrap();
|
|
|
|
|
2019-07-10 14:12:08 +03:00
|
|
|
let context = unsafe { context.make_current().unwrap() };
|
2018-11-23 00:47:48 +03:00
|
|
|
|
2019-07-10 14:12:08 +03:00
|
|
|
let gl = match context.get_api() {
|
2018-11-23 00:47:48 +03:00
|
|
|
glutin::Api::OpenGl => unsafe {
|
2019-07-10 14:12:08 +03:00
|
|
|
gl::GlFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
|
2018-11-23 00:47:48 +03:00
|
|
|
},
|
|
|
|
glutin::Api::OpenGlEs => unsafe {
|
2019-07-10 14:12:08 +03:00
|
|
|
gl::GlesFns::load_with(|symbol| context.get_proc_address(symbol) as *const _)
|
2018-11-23 00:47:48 +03:00
|
|
|
},
|
|
|
|
glutin::Api::WebGl => unimplemented!(),
|
|
|
|
};
|
|
|
|
|
2019-07-10 14:12:08 +03:00
|
|
|
let device_pixel_ratio = context.window().get_hidpi_factor() as f32;
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
let opts = webrender::RendererOptions {
|
|
|
|
device_pixel_ratio,
|
|
|
|
clear_color: Some(clear_color),
|
|
|
|
..webrender::RendererOptions::default()
|
|
|
|
};
|
|
|
|
|
2019-04-25 16:02:47 +03:00
|
|
|
let device_size = {
|
2019-07-10 14:12:08 +03:00
|
|
|
let size = context
|
|
|
|
.window()
|
2018-11-23 00:47:48 +03:00
|
|
|
.get_inner_size()
|
|
|
|
.unwrap()
|
|
|
|
.to_physical(device_pixel_ratio as f64);
|
2019-04-25 16:02:47 +03:00
|
|
|
DeviceIntSize::new(size.width as i32, size.height as i32)
|
2018-11-23 00:47:48 +03:00
|
|
|
};
|
|
|
|
let notifier = Box::new(Notifier::new(events_loop.create_proxy()));
|
2019-04-25 16:02:47 +03:00
|
|
|
let (renderer, sender) = webrender::Renderer::new(gl.clone(), notifier, opts, None, device_size).unwrap();
|
2018-11-23 00:47:48 +03:00
|
|
|
let api = sender.create_api();
|
2019-04-25 16:02:47 +03:00
|
|
|
let document_id = api.add_document(device_size, 0);
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
let epoch = Epoch(0);
|
|
|
|
let pipeline_id = PipelineId(0, 0);
|
|
|
|
let mut txn = Transaction::new();
|
|
|
|
|
|
|
|
let font_key = api.generate_font_key();
|
|
|
|
let font_bytes = load_file("../wrench/reftests/text/FreeSans.ttf");
|
|
|
|
txn.add_raw_font(font_key, font_bytes, 0);
|
|
|
|
|
|
|
|
let font_instance_key = api.generate_font_instance_key();
|
|
|
|
txn.add_font_instance(font_instance_key, font_key, Au::from_px(32), None, None, Vec::new());
|
|
|
|
|
|
|
|
api.send_transaction(document_id, txn);
|
|
|
|
|
|
|
|
Window {
|
|
|
|
events_loop,
|
2019-07-10 14:12:08 +03:00
|
|
|
context: Some(unsafe { context.make_not_current().unwrap() }),
|
2018-11-23 00:47:48 +03:00
|
|
|
renderer,
|
|
|
|
name,
|
|
|
|
epoch,
|
|
|
|
pipeline_id,
|
|
|
|
document_id,
|
|
|
|
api,
|
|
|
|
font_instance_key,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tick(&mut self) -> bool {
|
|
|
|
let mut do_exit = false;
|
|
|
|
let my_name = &self.name;
|
|
|
|
let renderer = &mut self.renderer;
|
2018-12-22 00:12:36 +03:00
|
|
|
let api = &mut self.api;
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
self.events_loop.poll_events(|global_event| match global_event {
|
|
|
|
winit::Event::WindowEvent { event, .. } => match event {
|
|
|
|
winit::WindowEvent::CloseRequested |
|
|
|
|
winit::WindowEvent::KeyboardInput {
|
|
|
|
input: winit::KeyboardInput {
|
|
|
|
virtual_keycode: Some(winit::VirtualKeyCode::Escape),
|
|
|
|
..
|
|
|
|
},
|
|
|
|
..
|
|
|
|
} => {
|
|
|
|
do_exit = true
|
|
|
|
}
|
|
|
|
winit::WindowEvent::KeyboardInput {
|
|
|
|
input: winit::KeyboardInput {
|
|
|
|
state: winit::ElementState::Pressed,
|
|
|
|
virtual_keycode: Some(winit::VirtualKeyCode::P),
|
|
|
|
..
|
|
|
|
},
|
|
|
|
..
|
|
|
|
} => {
|
2018-12-22 00:12:36 +03:00
|
|
|
println!("set flags {}", my_name);
|
|
|
|
api.send_debug_cmd(DebugCommand::SetFlags(DebugFlags::PROFILER_DBG))
|
2018-11-23 00:47:48 +03:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
});
|
|
|
|
if do_exit {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-07-10 14:12:08 +03:00
|
|
|
let context = unsafe { self.context.take().unwrap().make_current().unwrap() };
|
|
|
|
let device_pixel_ratio = context.window().get_hidpi_factor() as f32;
|
2019-04-25 16:02:47 +03:00
|
|
|
let device_size = {
|
2019-07-10 14:12:08 +03:00
|
|
|
let size = context
|
|
|
|
.window()
|
2018-11-23 00:47:48 +03:00
|
|
|
.get_inner_size()
|
|
|
|
.unwrap()
|
|
|
|
.to_physical(device_pixel_ratio as f64);
|
2019-04-25 16:02:47 +03:00
|
|
|
DeviceIntSize::new(size.width as i32, size.height as i32)
|
2018-11-23 00:47:48 +03:00
|
|
|
};
|
2019-07-18 23:54:16 +03:00
|
|
|
let layout_size = device_size.to_f32() / euclid::Scale::new(device_pixel_ratio);
|
2018-11-23 00:47:48 +03:00
|
|
|
let mut txn = Transaction::new();
|
|
|
|
let mut builder = DisplayListBuilder::new(self.pipeline_id, layout_size);
|
2019-01-09 06:27:04 +03:00
|
|
|
let space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
|
2019-01-23 21:32:40 +03:00
|
|
|
builder.push_simple_stacking_context(
|
Bug 1536121 - rearchitect the webrender display-list. r=gw
disclaimer: this isn't an *amazing* cleanup, but more of a major step that
unlocks the ability to do more minor cleanups and refinements. There's some
messy things and inconsistencies here and there, but we can hopefully iron
them out over time.
1. The primary change here is to move from
struct { common_fields, enum(specific_fields) }
to
enum (maybe_common_fields, specific_fields)
most notably this drops the common fields from a ton of things
that don't need them PopXXX, SetXXX, ClipChain, etc.
2. Additionally some types have had some redundant states shaved off,
for instance, rect no longer has *both* bounds and a clip_rect, as
the intersection of the two can be used. This was done a bit conservatively
as some adjustments will need to be done to the backend to fully eliminate
some states, and this can be done more incrementally.
2.5. As a minor side-effect of 2, we now early-reject some primitives whose
bounds and clip_rect are disjoint.
3. A HitTest display item has been added, which is just a Rect without
color. In addition to the minor space wins from this, this makes it much
easier to debug display lists
4. Adds a bunch of comments to the display list, making it easier to understand
things.
The end result of all these changes is a significantly smaller and easier to
understand display list. Especially on pages like gmail which have so many
clip chains. However this ultimately just makes text an even greater percentage
of pages (often 70-80%).
Differential Revision: https://phabricator.services.mozilla.com/D27439
--HG--
extra : moz-landing-system : lando
2019-04-23 20:29:58 +03:00
|
|
|
bounds.origin,
|
2019-01-09 06:27:04 +03:00
|
|
|
space_and_clip.spatial_id,
|
2019-09-24 05:40:27 +03:00
|
|
|
PrimitiveFlags::IS_BACKFACE_VISIBLE,
|
2018-11-23 00:47:48 +03:00
|
|
|
);
|
|
|
|
|
Bug 1536121 - rearchitect the webrender display-list. r=gw
disclaimer: this isn't an *amazing* cleanup, but more of a major step that
unlocks the ability to do more minor cleanups and refinements. There's some
messy things and inconsistencies here and there, but we can hopefully iron
them out over time.
1. The primary change here is to move from
struct { common_fields, enum(specific_fields) }
to
enum (maybe_common_fields, specific_fields)
most notably this drops the common fields from a ton of things
that don't need them PopXXX, SetXXX, ClipChain, etc.
2. Additionally some types have had some redundant states shaved off,
for instance, rect no longer has *both* bounds and a clip_rect, as
the intersection of the two can be used. This was done a bit conservatively
as some adjustments will need to be done to the backend to fully eliminate
some states, and this can be done more incrementally.
2.5. As a minor side-effect of 2, we now early-reject some primitives whose
bounds and clip_rect are disjoint.
3. A HitTest display item has been added, which is just a Rect without
color. In addition to the minor space wins from this, this makes it much
easier to debug display lists
4. Adds a bunch of comments to the display list, making it easier to understand
things.
The end result of all these changes is a significantly smaller and easier to
understand display list. Especially on pages like gmail which have so many
clip chains. However this ultimately just makes text an even greater percentage
of pages (often 70-80%).
Differential Revision: https://phabricator.services.mozilla.com/D27439
--HG--
extra : moz-landing-system : lando
2019-04-23 20:29:58 +03:00
|
|
|
builder.push_rect(
|
|
|
|
&CommonItemProperties::new(
|
|
|
|
LayoutRect::new(
|
|
|
|
LayoutPoint::new(100.0, 200.0),
|
|
|
|
LayoutSize::new(100.0, 200.0),
|
|
|
|
),
|
|
|
|
space_and_clip,
|
|
|
|
),
|
2020-04-01 13:01:26 +03:00
|
|
|
LayoutRect::new(
|
|
|
|
LayoutPoint::new(100.0, 200.0),
|
|
|
|
LayoutSize::new(100.0, 200.0),
|
|
|
|
),
|
Bug 1536121 - rearchitect the webrender display-list. r=gw
disclaimer: this isn't an *amazing* cleanup, but more of a major step that
unlocks the ability to do more minor cleanups and refinements. There's some
messy things and inconsistencies here and there, but we can hopefully iron
them out over time.
1. The primary change here is to move from
struct { common_fields, enum(specific_fields) }
to
enum (maybe_common_fields, specific_fields)
most notably this drops the common fields from a ton of things
that don't need them PopXXX, SetXXX, ClipChain, etc.
2. Additionally some types have had some redundant states shaved off,
for instance, rect no longer has *both* bounds and a clip_rect, as
the intersection of the two can be used. This was done a bit conservatively
as some adjustments will need to be done to the backend to fully eliminate
some states, and this can be done more incrementally.
2.5. As a minor side-effect of 2, we now early-reject some primitives whose
bounds and clip_rect are disjoint.
3. A HitTest display item has been added, which is just a Rect without
color. In addition to the minor space wins from this, this makes it much
easier to debug display lists
4. Adds a bunch of comments to the display list, making it easier to understand
things.
The end result of all these changes is a significantly smaller and easier to
understand display list. Especially on pages like gmail which have so many
clip chains. However this ultimately just makes text an even greater percentage
of pages (often 70-80%).
Differential Revision: https://phabricator.services.mozilla.com/D27439
--HG--
extra : moz-landing-system : lando
2019-04-23 20:29:58 +03:00
|
|
|
ColorF::new(0.0, 1.0, 0.0, 1.0));
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
let text_bounds = LayoutRect::new(
|
|
|
|
LayoutPoint::new(100.0, 50.0),
|
|
|
|
LayoutSize::new(700.0, 200.0)
|
|
|
|
);
|
|
|
|
let glyphs = vec![
|
|
|
|
GlyphInstance {
|
|
|
|
index: 48,
|
|
|
|
point: LayoutPoint::new(100.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 68,
|
|
|
|
point: LayoutPoint::new(150.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 80,
|
|
|
|
point: LayoutPoint::new(200.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 82,
|
|
|
|
point: LayoutPoint::new(250.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 81,
|
|
|
|
point: LayoutPoint::new(300.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 3,
|
|
|
|
point: LayoutPoint::new(350.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 86,
|
|
|
|
point: LayoutPoint::new(400.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 79,
|
|
|
|
point: LayoutPoint::new(450.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 72,
|
|
|
|
point: LayoutPoint::new(500.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 83,
|
|
|
|
point: LayoutPoint::new(550.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 87,
|
|
|
|
point: LayoutPoint::new(600.0, 100.0),
|
|
|
|
},
|
|
|
|
GlyphInstance {
|
|
|
|
index: 17,
|
|
|
|
point: LayoutPoint::new(650.0, 100.0),
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
builder.push_text(
|
Bug 1536121 - rearchitect the webrender display-list. r=gw
disclaimer: this isn't an *amazing* cleanup, but more of a major step that
unlocks the ability to do more minor cleanups and refinements. There's some
messy things and inconsistencies here and there, but we can hopefully iron
them out over time.
1. The primary change here is to move from
struct { common_fields, enum(specific_fields) }
to
enum (maybe_common_fields, specific_fields)
most notably this drops the common fields from a ton of things
that don't need them PopXXX, SetXXX, ClipChain, etc.
2. Additionally some types have had some redundant states shaved off,
for instance, rect no longer has *both* bounds and a clip_rect, as
the intersection of the two can be used. This was done a bit conservatively
as some adjustments will need to be done to the backend to fully eliminate
some states, and this can be done more incrementally.
2.5. As a minor side-effect of 2, we now early-reject some primitives whose
bounds and clip_rect are disjoint.
3. A HitTest display item has been added, which is just a Rect without
color. In addition to the minor space wins from this, this makes it much
easier to debug display lists
4. Adds a bunch of comments to the display list, making it easier to understand
things.
The end result of all these changes is a significantly smaller and easier to
understand display list. Especially on pages like gmail which have so many
clip chains. However this ultimately just makes text an even greater percentage
of pages (often 70-80%).
Differential Revision: https://phabricator.services.mozilla.com/D27439
--HG--
extra : moz-landing-system : lando
2019-04-23 20:29:58 +03:00
|
|
|
&CommonItemProperties::new(
|
|
|
|
text_bounds,
|
|
|
|
space_and_clip,
|
|
|
|
),
|
|
|
|
text_bounds,
|
2018-11-23 00:47:48 +03:00
|
|
|
&glyphs,
|
|
|
|
self.font_instance_key,
|
|
|
|
ColorF::new(1.0, 1.0, 0.0, 1.0),
|
|
|
|
None,
|
|
|
|
);
|
|
|
|
|
|
|
|
builder.pop_stacking_context();
|
|
|
|
|
|
|
|
txn.set_display_list(
|
|
|
|
self.epoch,
|
|
|
|
None,
|
|
|
|
layout_size,
|
|
|
|
builder.finalize(),
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
txn.set_root_pipeline(self.pipeline_id);
|
|
|
|
txn.generate_frame();
|
2018-12-22 00:12:36 +03:00
|
|
|
api.send_transaction(self.document_id, txn);
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
renderer.update();
|
2019-04-25 16:02:47 +03:00
|
|
|
renderer.render(device_size).unwrap();
|
2019-07-10 14:12:08 +03:00
|
|
|
context.swap_buffers().ok();
|
|
|
|
|
|
|
|
self.context = Some(unsafe { context.make_not_current().unwrap() });
|
2018-11-23 00:47:48 +03:00
|
|
|
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
|
|
|
fn deinit(self) {
|
|
|
|
self.renderer.deinit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let mut win1 = Window::new("window1", ColorF::new(0.3, 0.0, 0.0, 1.0));
|
|
|
|
let mut win2 = Window::new("window2", ColorF::new(0.0, 0.3, 0.0, 1.0));
|
|
|
|
|
|
|
|
loop {
|
|
|
|
if win1.tick() {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if win2.tick() {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
win1.deinit();
|
|
|
|
win2.deinit();
|
|
|
|
}
|
|
|
|
|
|
|
|
fn load_file(name: &str) -> Vec<u8> {
|
|
|
|
let mut file = File::open(name).unwrap();
|
|
|
|
let mut buffer = vec![];
|
|
|
|
file.read_to_end(&mut buffer).unwrap();
|
|
|
|
buffer
|
|
|
|
}
|