mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #16073 - glennw:update-wr-glfns, r=mrobinson
Update WR (gl trait, scroll roots) <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16073) <!-- Reviewable:end -->
This commit is contained in:
commit
c99289a928
23 changed files with 385 additions and 337 deletions
|
@ -14,10 +14,10 @@ azure = {git = "https://github.com/servo/rust-azure"}
|
|||
canvas_traits = {path = "../canvas_traits"}
|
||||
cssparser = "0.12"
|
||||
euclid = "0.11"
|
||||
gleam = "0.2.8"
|
||||
gleam = "0.4"
|
||||
ipc-channel = "0.7"
|
||||
log = "0.3.5"
|
||||
num-traits = "0.1.32"
|
||||
offscreen_gl_context = "0.6"
|
||||
offscreen_gl_context = "0.8"
|
||||
servo_config = {path = "../config"}
|
||||
webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]}
|
||||
|
|
|
@ -22,17 +22,20 @@ enum GLContextWrapper {
|
|||
|
||||
impl GLContextWrapper {
|
||||
fn new(size: Size2D<i32>,
|
||||
attributes: GLContextAttributes) -> Result<GLContextWrapper, &'static str> {
|
||||
attributes: GLContextAttributes,
|
||||
gl_type: gl::GlType) -> Result<GLContextWrapper, &'static str> {
|
||||
if opts::get().should_use_osmesa() {
|
||||
let ctx = GLContext::<OSMesaContext>::new(size,
|
||||
attributes,
|
||||
ColorAttachmentType::Texture,
|
||||
gl_type,
|
||||
None);
|
||||
ctx.map(GLContextWrapper::OSMesa)
|
||||
} else {
|
||||
let ctx = GLContext::<NativeGLContext>::new(size,
|
||||
attributes,
|
||||
ColorAttachmentType::Texture,
|
||||
gl_type,
|
||||
None);
|
||||
ctx.map(GLContextWrapper::Native)
|
||||
}
|
||||
|
@ -62,6 +65,17 @@ impl GLContextWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
fn gl(&self) -> &gl::Gl {
|
||||
match *self {
|
||||
GLContextWrapper::Native(ref ctx) => {
|
||||
ctx.gl()
|
||||
}
|
||||
GLContextWrapper::OSMesa(ref ctx) => {
|
||||
ctx.gl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_current(&self) {
|
||||
match *self {
|
||||
GLContextWrapper::Native(ref ctx) => {
|
||||
|
@ -97,9 +111,10 @@ pub struct WebGLPaintThread {
|
|||
|
||||
fn create_readback_painter(size: Size2D<i32>,
|
||||
attrs: GLContextAttributes,
|
||||
webrender_api: webrender_traits::RenderApi)
|
||||
webrender_api: webrender_traits::RenderApi,
|
||||
gl_type: gl::GlType)
|
||||
-> Result<(WebGLPaintThread, GLLimits), String> {
|
||||
let context = try!(GLContextWrapper::new(size, attrs));
|
||||
let context = try!(GLContextWrapper::new(size, attrs, gl_type));
|
||||
let limits = context.get_limits();
|
||||
let image_key = webrender_api.generate_image_key();
|
||||
let painter = WebGLPaintThread {
|
||||
|
@ -113,7 +128,8 @@ fn create_readback_painter(size: Size2D<i32>,
|
|||
impl WebGLPaintThread {
|
||||
fn new(size: Size2D<i32>,
|
||||
attrs: GLContextAttributes,
|
||||
webrender_api_sender: webrender_traits::RenderApiSender)
|
||||
webrender_api_sender: webrender_traits::RenderApiSender,
|
||||
gl_type: gl::GlType)
|
||||
-> Result<(WebGLPaintThread, GLLimits), String> {
|
||||
let wr_api = webrender_api_sender.create_api();
|
||||
let device_size = webrender_traits::DeviceIntSize::from_untyped(&size);
|
||||
|
@ -127,7 +143,7 @@ impl WebGLPaintThread {
|
|||
},
|
||||
Err(msg) => {
|
||||
warn!("Initial context creation failed, falling back to readback: {}", msg);
|
||||
create_readback_painter(size, attrs, wr_api)
|
||||
create_readback_painter(size, attrs, wr_api, gl_type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +181,8 @@ impl WebGLPaintThread {
|
|||
let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
|
||||
let (result_chan, result_port) = channel();
|
||||
thread::Builder::new().name("WebGLThread".to_owned()).spawn(move || {
|
||||
let mut painter = match WebGLPaintThread::new(size, attrs, webrender_api_sender) {
|
||||
let gl_type = gl::GlType::default();
|
||||
let mut painter = match WebGLPaintThread::new(size, attrs, webrender_api_sender, gl_type) {
|
||||
Ok((thread, limits)) => {
|
||||
result_chan.send(Ok(limits)).unwrap();
|
||||
thread
|
||||
|
@ -212,14 +229,14 @@ impl WebGLPaintThread {
|
|||
|
||||
fn send_data(&mut self, chan: IpcSender<CanvasData>) {
|
||||
match self.data {
|
||||
WebGLPaintTaskData::Readback(_, ref webrender_api, image_key) => {
|
||||
WebGLPaintTaskData::Readback(ref ctx, ref webrender_api, image_key) => {
|
||||
let width = self.size.width as usize;
|
||||
let height = self.size.height as usize;
|
||||
|
||||
let mut pixels = gl::read_pixels(0, 0,
|
||||
self.size.width as gl::GLsizei,
|
||||
self.size.height as gl::GLsizei,
|
||||
gl::RGBA, gl::UNSIGNED_BYTE);
|
||||
let mut pixels = ctx.gl().read_pixels(0, 0,
|
||||
self.size.width as gl::GLsizei,
|
||||
self.size.height as gl::GLsizei,
|
||||
gl::RGBA, gl::UNSIGNED_BYTE);
|
||||
// flip image vertically (texture is upside down)
|
||||
let orig_pixels = pixels.clone();
|
||||
let stride = width * 4;
|
||||
|
@ -267,7 +284,7 @@ impl WebGLPaintThread {
|
|||
self.size = try!(context.resize(size));
|
||||
} else {
|
||||
self.size = size;
|
||||
unsafe { gl::Scissor(0, 0, size.width, size.height); }
|
||||
context.gl().scissor(0, 0, size.width, size.height);
|
||||
}
|
||||
}
|
||||
WebGLPaintTaskData::WebRender(ref api, id) => {
|
||||
|
|
|
@ -12,7 +12,7 @@ path = "lib.rs"
|
|||
[dependencies]
|
||||
euclid = "0.11"
|
||||
gfx_traits = {path = "../gfx_traits"}
|
||||
gleam = "0.2.8"
|
||||
gleam = "0.4"
|
||||
image = "0.12"
|
||||
ipc-channel = "0.7"
|
||||
log = "0.3.5"
|
||||
|
|
|
@ -14,7 +14,6 @@ use euclid::scale_factor::ScaleFactor;
|
|||
use euclid::size::TypedSize2D;
|
||||
use gfx_traits::{Epoch, ScrollRootId};
|
||||
use gleam::gl;
|
||||
use gleam::gl::types::{GLint, GLsizei};
|
||||
use image::{DynamicImage, ImageFormat, RgbImage};
|
||||
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
||||
use msg::constellation_msg::{Key, KeyModifiers, KeyState, CONTROL};
|
||||
|
@ -40,7 +39,7 @@ use style_traits::viewport::ViewportConstraints;
|
|||
use time::{precise_time_ns, precise_time_s};
|
||||
use touch::{TouchHandler, TouchAction};
|
||||
use webrender;
|
||||
use webrender_traits::{self, ScrollEventPhase, ServoScrollRootId, LayoutPoint, ScrollLocation};
|
||||
use webrender_traits::{self, LayoutPoint, ScrollEventPhase, ScrollLayerId, ScrollLocation};
|
||||
use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -77,9 +76,9 @@ trait ConvertScrollRootIdFromWebRender {
|
|||
fn from_webrender(&self) -> ScrollRootId;
|
||||
}
|
||||
|
||||
impl ConvertScrollRootIdFromWebRender for webrender_traits::ServoScrollRootId {
|
||||
impl ConvertScrollRootIdFromWebRender for usize {
|
||||
fn from_webrender(&self) -> ScrollRootId {
|
||||
ScrollRootId(self.0)
|
||||
ScrollRootId(*self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,6 +207,9 @@ pub struct IOCompositor<Window: WindowMethods> {
|
|||
|
||||
/// The webrender interface, if enabled.
|
||||
webrender_api: webrender_traits::RenderApi,
|
||||
|
||||
/// GL functions interface (may be GL or GLES)
|
||||
gl: Rc<gl::Gl>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -291,34 +293,34 @@ impl RenderTargetInfo {
|
|||
}
|
||||
}
|
||||
|
||||
fn initialize_png(width: usize, height: usize) -> RenderTargetInfo {
|
||||
let framebuffer_ids = gl::gen_framebuffers(1);
|
||||
gl::bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]);
|
||||
fn initialize_png(gl: &gl::Gl, width: usize, height: usize) -> RenderTargetInfo {
|
||||
let framebuffer_ids = gl.gen_framebuffers(1);
|
||||
gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]);
|
||||
|
||||
let texture_ids = gl::gen_textures(1);
|
||||
gl::bind_texture(gl::TEXTURE_2D, texture_ids[0]);
|
||||
let texture_ids = gl.gen_textures(1);
|
||||
gl.bind_texture(gl::TEXTURE_2D, texture_ids[0]);
|
||||
|
||||
gl::tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as GLint, width as GLsizei,
|
||||
height as GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None);
|
||||
gl::tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
|
||||
gl::tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
|
||||
gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width as gl::GLsizei,
|
||||
height as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None);
|
||||
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as gl::GLint);
|
||||
gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as gl::GLint);
|
||||
|
||||
gl::framebuffer_texture_2d(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D,
|
||||
texture_ids[0], 0);
|
||||
gl.framebuffer_texture_2d(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D,
|
||||
texture_ids[0], 0);
|
||||
|
||||
gl::bind_texture(gl::TEXTURE_2D, 0);
|
||||
gl.bind_texture(gl::TEXTURE_2D, 0);
|
||||
|
||||
let renderbuffer_ids = gl::gen_renderbuffers(1);
|
||||
let renderbuffer_ids = gl.gen_renderbuffers(1);
|
||||
let depth_rb = renderbuffer_ids[0];
|
||||
gl::bind_renderbuffer(gl::RENDERBUFFER, depth_rb);
|
||||
gl::renderbuffer_storage(gl::RENDERBUFFER,
|
||||
gl::DEPTH_COMPONENT24,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei);
|
||||
gl::framebuffer_renderbuffer(gl::FRAMEBUFFER,
|
||||
gl::DEPTH_ATTACHMENT,
|
||||
gl::RENDERBUFFER,
|
||||
depth_rb);
|
||||
gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb);
|
||||
gl.renderbuffer_storage(gl::RENDERBUFFER,
|
||||
gl::DEPTH_COMPONENT24,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei);
|
||||
gl.framebuffer_renderbuffer(gl::FRAMEBUFFER,
|
||||
gl::DEPTH_ATTACHMENT,
|
||||
gl::RENDERBUFFER,
|
||||
depth_rb);
|
||||
|
||||
RenderTargetInfo {
|
||||
framebuffer_ids: framebuffer_ids,
|
||||
|
@ -373,6 +375,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
};
|
||||
|
||||
IOCompositor {
|
||||
gl: window.gl(),
|
||||
window: window,
|
||||
port: state.receiver,
|
||||
root_pipeline: None,
|
||||
|
@ -791,10 +794,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
pipeline_id: PipelineId,
|
||||
scroll_root_id: ScrollRootId,
|
||||
point: Point2D<f32>) {
|
||||
self.webrender_api.scroll_layers_with_scroll_root_id(
|
||||
LayoutPoint::from_untyped(&point),
|
||||
pipeline_id.to_webrender(),
|
||||
ServoScrollRootId(scroll_root_id.0));
|
||||
let id = ScrollLayerId::new(scroll_root_id.0, pipeline_id.to_webrender());
|
||||
self.webrender_api.scroll_layer_with_id(LayoutPoint::from_untyped(&point), id);
|
||||
}
|
||||
|
||||
fn handle_window_message(&mut self, event: WindowEvent) {
|
||||
|
@ -1386,13 +1387,18 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
fn send_viewport_rects(&self) {
|
||||
let mut stacking_context_scroll_states_per_pipeline = HashMap::new();
|
||||
for scroll_layer_state in self.webrender_api.get_scroll_layer_state() {
|
||||
let external_id = match scroll_layer_state.id.external_id() {
|
||||
Some(id) => id,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
let stacking_context_scroll_state = StackingContextScrollState {
|
||||
scroll_root_id: scroll_layer_state.scroll_root_id.from_webrender(),
|
||||
scroll_root_id: external_id.from_webrender(),
|
||||
scroll_offset: scroll_layer_state.scroll_offset.to_untyped(),
|
||||
};
|
||||
let pipeline_id = scroll_layer_state.pipeline_id;
|
||||
|
||||
stacking_context_scroll_states_per_pipeline
|
||||
.entry(pipeline_id)
|
||||
.entry(scroll_layer_state.id.pipeline_id())
|
||||
.or_insert(vec![])
|
||||
.push(stacking_context_scroll_state);
|
||||
}
|
||||
|
@ -1529,7 +1535,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
|
||||
let render_target_info = match target {
|
||||
CompositeTarget::Window => RenderTargetInfo::empty(),
|
||||
_ => initialize_png(width, height)
|
||||
_ => initialize_png(&*self.gl, width, height)
|
||||
};
|
||||
|
||||
profile(ProfilerCategory::Compositing, None, self.time_profiler_chan.clone(), || {
|
||||
|
@ -1593,16 +1599,16 @@ impl<Window: WindowMethods> IOCompositor<Window> {
|
|||
width: usize,
|
||||
height: usize)
|
||||
-> RgbImage {
|
||||
let mut pixels = gl::read_pixels(0, 0,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei,
|
||||
gl::RGB, gl::UNSIGNED_BYTE);
|
||||
let mut pixels = self.gl.read_pixels(0, 0,
|
||||
width as gl::GLsizei,
|
||||
height as gl::GLsizei,
|
||||
gl::RGB, gl::UNSIGNED_BYTE);
|
||||
|
||||
gl::bind_framebuffer(gl::FRAMEBUFFER, 0);
|
||||
self.gl.bind_framebuffer(gl::FRAMEBUFFER, 0);
|
||||
|
||||
gl::delete_buffers(&render_target_info.texture_ids);
|
||||
gl::delete_renderbuffers(&render_target_info.renderbuffer_ids);
|
||||
gl::delete_frame_buffers(&render_target_info.framebuffer_ids);
|
||||
self.gl.delete_buffers(&render_target_info.texture_ids);
|
||||
self.gl.delete_renderbuffers(&render_target_info.renderbuffer_ids);
|
||||
self.gl.delete_framebuffers(&render_target_info.framebuffer_ids);
|
||||
|
||||
// flip image vertically (texture is upside down)
|
||||
let orig_pixels = pixels.clone();
|
||||
|
|
|
@ -10,12 +10,14 @@ use euclid::point::TypedPoint2D;
|
|||
use euclid::rect::TypedRect;
|
||||
use euclid::scale_factor::ScaleFactor;
|
||||
use euclid::size::TypedSize2D;
|
||||
use gleam::gl;
|
||||
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
|
||||
use net_traits::net_error_list::NetError;
|
||||
use script_traits::{DevicePixel, MouseButton, TouchEventType, TouchId, TouchpadPressurePhase};
|
||||
use servo_geometry::DeviceIndependentPixel;
|
||||
use servo_url::ServoUrl;
|
||||
use std::fmt::{Debug, Error, Formatter};
|
||||
use std::rc::Rc;
|
||||
use style_traits::cursor::Cursor;
|
||||
use webrender_traits::ScrollLocation;
|
||||
|
||||
|
@ -168,4 +170,7 @@ pub trait WindowMethods {
|
|||
|
||||
/// Add a favicon
|
||||
fn set_favicon(&self, url: ServoUrl);
|
||||
|
||||
/// Return the GL function pointer trait.
|
||||
fn gl(&self) -> Rc<gl::Gl>;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ layout_traits = {path = "../layout_traits"}
|
|||
log = "0.3.5"
|
||||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
offscreen_gl_context = "0.6"
|
||||
offscreen_gl_context = "0.8"
|
||||
profile_traits = {path = "../profile_traits"}
|
||||
script_traits = {path = "../script_traits"}
|
||||
serde = "0.9"
|
||||
|
|
|
@ -434,6 +434,7 @@ impl StackingContext {
|
|||
pub fn to_display_list_items(self) -> (DisplayItem, DisplayItem) {
|
||||
let mut base_item = BaseDisplayItem::empty();
|
||||
base_item.stacking_context_id = self.id;
|
||||
base_item.scroll_root_id = self.parent_scroll_id;
|
||||
|
||||
let pop_item = DisplayItem::PopStackingContext(Box::new(
|
||||
PopStackingContextItem {
|
||||
|
|
|
@ -2233,10 +2233,11 @@ impl Flow for BlockFlow {
|
|||
|
||||
fn compute_overflow(&self) -> Overflow {
|
||||
let flow_size = self.base.position.size.to_physical(self.base.writing_mode);
|
||||
self.fragment.compute_overflow(&flow_size,
|
||||
let overflow = self.fragment.compute_overflow(&flow_size,
|
||||
&self.base
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_size)
|
||||
.relative_containing_block_size);
|
||||
overflow
|
||||
}
|
||||
|
||||
fn iterate_through_fragment_border_boxes(&self,
|
||||
|
|
|
@ -120,12 +120,31 @@ fn get_cyclic<T>(arr: &[T], index: usize) -> &T {
|
|||
&arr[index % arr.len()]
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct StackingContextInfo {
|
||||
children: Vec<StackingContext>,
|
||||
scroll_roots: Vec<ScrollRoot>,
|
||||
}
|
||||
|
||||
impl StackingContextInfo {
|
||||
fn new() -> StackingContextInfo {
|
||||
StackingContextInfo {
|
||||
children: Vec::new(),
|
||||
scroll_roots: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn take_children(&mut self) -> Vec<StackingContext> {
|
||||
mem::replace(&mut self.children, Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DisplayListBuildState<'a> {
|
||||
pub layout_context: &'a LayoutContext<'a>,
|
||||
pub root_stacking_context: StackingContext,
|
||||
pub items: HashMap<StackingContextId, Vec<DisplayItem>>,
|
||||
pub stacking_context_children: HashMap<StackingContextId, Vec<StackingContext>>,
|
||||
pub scroll_roots: HashMap<ScrollRootId, ScrollRoot>,
|
||||
stacking_context_info: HashMap<StackingContextId, StackingContextInfo>,
|
||||
pub scroll_root_parents: HashMap<ScrollRootId, ScrollRootId>,
|
||||
pub processing_scroll_root_element: bool,
|
||||
|
||||
/// The current stacking context id, used to keep track of state when building.
|
||||
|
@ -147,8 +166,8 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
layout_context: layout_context,
|
||||
root_stacking_context: StackingContext::root(),
|
||||
items: HashMap::new(),
|
||||
stacking_context_children: HashMap::new(),
|
||||
scroll_roots: HashMap::new(),
|
||||
stacking_context_info: HashMap::new(),
|
||||
scroll_root_parents: HashMap::new(),
|
||||
processing_scroll_root_element: false,
|
||||
current_stacking_context_id: StackingContextId::root(),
|
||||
current_scroll_root_id: ScrollRootId::root(),
|
||||
|
@ -164,13 +183,18 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
fn add_stacking_context(&mut self,
|
||||
parent_id: StackingContextId,
|
||||
stacking_context: StackingContext) {
|
||||
let contexts = self.stacking_context_children.entry(parent_id).or_insert(Vec::new());
|
||||
contexts.push(stacking_context);
|
||||
let info = self.stacking_context_info
|
||||
.entry(parent_id)
|
||||
.or_insert(StackingContextInfo::new());
|
||||
info.children.push(stacking_context);
|
||||
}
|
||||
|
||||
fn add_scroll_root(&mut self, scroll_root: ScrollRoot) {
|
||||
debug_assert!(!self.scroll_roots.contains_key(&scroll_root.id));
|
||||
self.scroll_roots.insert(scroll_root.id, scroll_root);
|
||||
fn add_scroll_root(&mut self, scroll_root: ScrollRoot, stacking_context_id: StackingContextId) {
|
||||
self.scroll_root_parents.insert(scroll_root.id, scroll_root.parent_id);
|
||||
let info = self.stacking_context_info
|
||||
.entry(stacking_context_id)
|
||||
.or_insert(StackingContextInfo::new());
|
||||
info.scroll_roots.push(scroll_root);
|
||||
}
|
||||
|
||||
fn parent_scroll_root_id(&self, scroll_root_id: ScrollRootId) -> ScrollRootId {
|
||||
|
@ -178,8 +202,8 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
return ScrollRootId::root()
|
||||
}
|
||||
|
||||
debug_assert!(self.scroll_roots.contains_key(&scroll_root_id));
|
||||
self.scroll_roots.get(&scroll_root_id).unwrap().parent_id
|
||||
debug_assert!(self.scroll_root_parents.contains_key(&scroll_root_id));
|
||||
*self.scroll_root_parents.get(&scroll_root_id).unwrap()
|
||||
}
|
||||
|
||||
fn create_base_display_item(&self,
|
||||
|
@ -209,13 +233,10 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
}
|
||||
|
||||
pub fn to_display_list(mut self) -> DisplayList {
|
||||
let mut scroll_root_stack = Vec::new();
|
||||
scroll_root_stack.push(ScrollRootId::root());
|
||||
|
||||
let mut list = Vec::new();
|
||||
let root_context = mem::replace(&mut self.root_stacking_context, StackingContext::root());
|
||||
|
||||
self.to_display_list_for_stacking_context(&mut list, root_context, &mut scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(&mut list, root_context);
|
||||
|
||||
DisplayList {
|
||||
list: list,
|
||||
|
@ -224,128 +245,75 @@ impl<'a> DisplayListBuildState<'a> {
|
|||
|
||||
fn to_display_list_for_stacking_context(&mut self,
|
||||
list: &mut Vec<DisplayItem>,
|
||||
stacking_context: StackingContext,
|
||||
scroll_root_stack: &mut Vec<ScrollRootId>) {
|
||||
stacking_context: StackingContext) {
|
||||
let mut child_items = self.items.remove(&stacking_context.id).unwrap_or(Vec::new());
|
||||
child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section));
|
||||
child_items.reverse();
|
||||
|
||||
let mut child_stacking_contexts =
|
||||
self.stacking_context_children.remove(&stacking_context.id).unwrap_or_else(Vec::new);
|
||||
child_stacking_contexts.sort();
|
||||
let mut info = self.stacking_context_info.remove(&stacking_context.id)
|
||||
.unwrap_or_else(StackingContextInfo::new);
|
||||
|
||||
let real_stacking_context = stacking_context.context_type == StackingContextType::Real;
|
||||
if !real_stacking_context {
|
||||
self.to_display_list_for_items(list,
|
||||
child_items,
|
||||
child_stacking_contexts,
|
||||
scroll_root_stack);
|
||||
return;
|
||||
info.children.sort();
|
||||
|
||||
if stacking_context.context_type != StackingContextType::Real {
|
||||
list.extend(info.scroll_roots.into_iter().map(|root| root.to_push()));
|
||||
self.to_display_list_for_items(list, child_items, info.children);
|
||||
} else {
|
||||
let (push_item, pop_item) = stacking_context.to_display_list_items();
|
||||
list.push(push_item);
|
||||
list.extend(info.scroll_roots.into_iter().map(|root| root.to_push()));
|
||||
self.to_display_list_for_items(list, child_items, info.children);
|
||||
list.push(pop_item);
|
||||
}
|
||||
|
||||
let mut scroll_root_stack = Vec::new();
|
||||
scroll_root_stack.push(stacking_context.parent_scroll_id);
|
||||
|
||||
let (push_item, pop_item) = stacking_context.to_display_list_items();
|
||||
list.push(push_item);
|
||||
self.to_display_list_for_items(list,
|
||||
child_items,
|
||||
child_stacking_contexts,
|
||||
&mut scroll_root_stack);
|
||||
list.push(pop_item);
|
||||
}
|
||||
|
||||
fn to_display_list_for_items(&mut self,
|
||||
list: &mut Vec<DisplayItem>,
|
||||
mut child_items: Vec<DisplayItem>,
|
||||
child_stacking_contexts: Vec<StackingContext>,
|
||||
scroll_root_stack: &mut Vec<ScrollRootId>) {
|
||||
child_stacking_contexts: Vec<StackingContext>) {
|
||||
// Properly order display items that make up a stacking context. "Steps" here
|
||||
// refer to the steps in CSS 2.1 Appendix E.
|
||||
// Steps 1 and 2: Borders and background for the root.
|
||||
while child_items.last().map_or(false,
|
||||
|child| child.section() == DisplayListSection::BackgroundAndBorders) {
|
||||
let item = child_items.pop().unwrap();
|
||||
self.switch_scroll_roots(list, item.scroll_root_id(), scroll_root_stack);
|
||||
list.push(item);
|
||||
list.push(child_items.pop().unwrap());
|
||||
}
|
||||
|
||||
// Step 3: Positioned descendants with negative z-indices.
|
||||
let mut child_stacking_contexts = child_stacking_contexts.into_iter().peekable();
|
||||
while child_stacking_contexts.peek().map_or(false, |child| child.z_index < 0) {
|
||||
let context = child_stacking_contexts.next().unwrap();
|
||||
self.switch_scroll_roots(list, context.parent_scroll_id, scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(list, context, scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(list, context);
|
||||
}
|
||||
|
||||
// Step 4: Block backgrounds and borders.
|
||||
while child_items.last().map_or(false,
|
||||
|child| child.section() == DisplayListSection::BlockBackgroundsAndBorders) {
|
||||
let item = child_items.pop().unwrap();
|
||||
self.switch_scroll_roots(list, item.scroll_root_id(), scroll_root_stack);
|
||||
list.push(item);
|
||||
list.push(child_items.pop().unwrap());
|
||||
}
|
||||
|
||||
// Step 5: Floats.
|
||||
while child_stacking_contexts.peek().map_or(false,
|
||||
|child| child.context_type == StackingContextType::PseudoFloat) {
|
||||
let context = child_stacking_contexts.next().unwrap();
|
||||
self.switch_scroll_roots(list, context.parent_scroll_id, scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(list, context, scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(list, context);
|
||||
}
|
||||
|
||||
// Step 6 & 7: Content and inlines that generate stacking contexts.
|
||||
while child_items.last().map_or(false,
|
||||
|child| child.section() == DisplayListSection::Content) {
|
||||
let item = child_items.pop().unwrap();
|
||||
self.switch_scroll_roots(list, item.scroll_root_id(), scroll_root_stack);
|
||||
list.push(item);
|
||||
list.push(child_items.pop().unwrap());
|
||||
}
|
||||
|
||||
// Step 8 & 9: Positioned descendants with nonnegative, numeric z-indices.
|
||||
for child in child_stacking_contexts {
|
||||
self.switch_scroll_roots(list, child.parent_scroll_id, scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(list, child, scroll_root_stack);
|
||||
self.to_display_list_for_stacking_context(list, child);
|
||||
}
|
||||
|
||||
// Step 10: Outlines.
|
||||
for item in child_items.drain(..) {
|
||||
self.switch_scroll_roots(list, item.scroll_root_id(), scroll_root_stack);
|
||||
list.push(item);
|
||||
}
|
||||
|
||||
for _ in scroll_root_stack.drain(1..) {
|
||||
list.push(DisplayItem::PopScrollRoot(Box::new(BaseDisplayItem::empty())));
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_scroll_roots(&self,
|
||||
list: &mut Vec<DisplayItem>,
|
||||
new_id: ScrollRootId,
|
||||
scroll_root_stack: &mut Vec<ScrollRootId>) {
|
||||
if new_id == *scroll_root_stack.last().unwrap() {
|
||||
return;
|
||||
}
|
||||
|
||||
if new_id == *scroll_root_stack.first().unwrap() {
|
||||
for _ in scroll_root_stack.drain(1..) {
|
||||
list.push(DisplayItem::PopScrollRoot(Box::new(BaseDisplayItem::empty())));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// We never want to reach the root of the ScrollRoot tree without encountering the
|
||||
// containing scroll root of this StackingContext. If this does happen we've tried to
|
||||
// switch to a ScrollRoot that does not contain our current stacking context or isn't
|
||||
// itself a direct child of our current stacking context. This should never happen
|
||||
// due to CSS stacking rules.
|
||||
debug_assert!(new_id != ScrollRootId::root());
|
||||
|
||||
let scroll_root = self.scroll_roots.get(&new_id).unwrap();
|
||||
self.switch_scroll_roots(list, scroll_root.parent_id, scroll_root_stack);
|
||||
|
||||
scroll_root_stack.push(new_id);
|
||||
list.push(scroll_root.to_push());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,6 +475,10 @@ pub trait FragmentDisplayListBuilding {
|
|||
mode: StackingContextCreationMode,
|
||||
parent_scroll_id: ScrollRootId)
|
||||
-> StackingContext;
|
||||
|
||||
|
||||
/// The id of stacking context this fragment would create.
|
||||
fn stacking_context_id(&self) -> StackingContextId;
|
||||
}
|
||||
|
||||
fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> BorderRadii<Au> {
|
||||
|
@ -1612,6 +1584,10 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
fn stacking_context_id(&self) -> StackingContextId {
|
||||
StackingContextId::new_of_type(self.node.id() as usize, self.fragment_type())
|
||||
}
|
||||
|
||||
fn create_stacking_context(&self,
|
||||
id: StackingContextId,
|
||||
base_flow: &BaseFlow,
|
||||
|
@ -1858,14 +1834,12 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
|
||||
pub trait BlockFlowDisplayListBuilding {
|
||||
fn collect_stacking_contexts_for_block(&mut self, state: &mut DisplayListBuildState);
|
||||
fn collect_scroll_root_for_block(&mut self, state: &mut DisplayListBuildState) -> ScrollRootId;
|
||||
fn setup_scroll_root_for_block(&mut self, state: &mut DisplayListBuildState) -> ScrollRootId;
|
||||
fn create_pseudo_stacking_context_for_block(&mut self,
|
||||
stacking_context_id: StackingContextId,
|
||||
parent_stacking_context_id: StackingContextId,
|
||||
parent_scroll_root_id: ScrollRootId,
|
||||
state: &mut DisplayListBuildState);
|
||||
fn create_real_stacking_context_for_block(&mut self,
|
||||
stacking_context_id: StackingContextId,
|
||||
parent_stacking_context_id: StackingContextId,
|
||||
parent_scroll_root_id: ScrollRootId,
|
||||
state: &mut DisplayListBuildState);
|
||||
|
@ -1876,43 +1850,49 @@ pub trait BlockFlowDisplayListBuilding {
|
|||
|
||||
impl BlockFlowDisplayListBuilding for BlockFlow {
|
||||
fn collect_stacking_contexts_for_block(&mut self, state: &mut DisplayListBuildState) {
|
||||
let parent_scroll_root_id = state.current_scroll_root_id;
|
||||
self.base.scroll_root_id = self.collect_scroll_root_for_block(state);
|
||||
state.current_scroll_root_id = self.base.scroll_root_id;
|
||||
|
||||
let parent_stacking_context_id = state.current_stacking_context_id;
|
||||
let block_stacking_context_type = self.block_stacking_context_type();
|
||||
if block_stacking_context_type == BlockStackingContextType::NonstackingContext {
|
||||
self.base.stacking_context_id = state.current_stacking_context_id;
|
||||
self.base.collect_stacking_contexts_for_children(state);
|
||||
} else {
|
||||
let parent_stacking_context_id = state.current_stacking_context_id;
|
||||
let stacking_context_id =
|
||||
StackingContextId::new_of_type(self.fragment.node.id() as usize,
|
||||
self.fragment.fragment_type());
|
||||
state.current_stacking_context_id = stacking_context_id;
|
||||
self.base.stacking_context_id = stacking_context_id;
|
||||
self.base.stacking_context_id = match block_stacking_context_type {
|
||||
BlockStackingContextType::NonstackingContext => state.current_stacking_context_id,
|
||||
BlockStackingContextType::PseudoStackingContext |
|
||||
BlockStackingContextType::StackingContext => self.fragment.stacking_context_id(),
|
||||
};
|
||||
state.current_stacking_context_id = self.base.stacking_context_id;
|
||||
|
||||
if block_stacking_context_type == BlockStackingContextType::PseudoStackingContext {
|
||||
self.create_pseudo_stacking_context_for_block(stacking_context_id,
|
||||
parent_stacking_context_id,
|
||||
parent_scroll_root_id,
|
||||
let original_scroll_root_id = state.current_scroll_root_id;
|
||||
|
||||
// We are getting the id of the scroll root that contains us here, not the id of
|
||||
// any scroll root that we create. If we create a scroll root, its id will be
|
||||
// stored in state.current_scroll_root_id. If we should create a stacking context,
|
||||
// we don't want it to be clipped by its own scroll root.
|
||||
let containing_scroll_root_id = self.setup_scroll_root_for_block(state);
|
||||
|
||||
match block_stacking_context_type {
|
||||
BlockStackingContextType::NonstackingContext => {
|
||||
self.base.collect_stacking_contexts_for_children(state);
|
||||
}
|
||||
BlockStackingContextType::PseudoStackingContext => {
|
||||
self.create_pseudo_stacking_context_for_block(parent_stacking_context_id,
|
||||
containing_scroll_root_id,
|
||||
state);
|
||||
} else {
|
||||
self.create_real_stacking_context_for_block(stacking_context_id,
|
||||
parent_stacking_context_id,
|
||||
parent_scroll_root_id,
|
||||
}
|
||||
BlockStackingContextType::StackingContext => {
|
||||
self.create_real_stacking_context_for_block(parent_stacking_context_id,
|
||||
containing_scroll_root_id,
|
||||
state);
|
||||
}
|
||||
|
||||
state.current_stacking_context_id = parent_stacking_context_id;
|
||||
}
|
||||
|
||||
state.current_scroll_root_id = parent_scroll_root_id;
|
||||
state.current_scroll_root_id = original_scroll_root_id;
|
||||
state.current_stacking_context_id = parent_stacking_context_id;
|
||||
}
|
||||
|
||||
fn collect_scroll_root_for_block(&mut self, state: &mut DisplayListBuildState) -> ScrollRootId {
|
||||
fn setup_scroll_root_for_block(&mut self, state: &mut DisplayListBuildState) -> ScrollRootId {
|
||||
let containing_scroll_root_id = state.current_scroll_root_id;
|
||||
self.base.scroll_root_id = containing_scroll_root_id;
|
||||
|
||||
if !self.style_permits_scrolling_overflow() {
|
||||
return state.current_scroll_root_id;
|
||||
return containing_scroll_root_id;
|
||||
}
|
||||
|
||||
let coordinate_system = if self.fragment.establishes_stacking_context() {
|
||||
|
@ -1933,25 +1913,27 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
self.base.overflow.scroll.size.height > clip.size.height;
|
||||
self.mark_scrolling_overflow(has_scrolling_overflow);
|
||||
if !has_scrolling_overflow {
|
||||
return state.current_scroll_root_id;
|
||||
return containing_scroll_root_id;
|
||||
}
|
||||
|
||||
let scroll_root_id = ScrollRootId::new_of_type(self.fragment.node.id() as usize,
|
||||
self.fragment.fragment_type());
|
||||
let parent_scroll_root_id = state.current_scroll_root_id;
|
||||
let new_scroll_root_id = ScrollRootId::new_of_type(self.fragment.node.id() as usize,
|
||||
self.fragment.fragment_type());
|
||||
state.add_scroll_root(
|
||||
ScrollRoot {
|
||||
id: scroll_root_id,
|
||||
parent_id: parent_scroll_root_id,
|
||||
id: new_scroll_root_id,
|
||||
parent_id: containing_scroll_root_id,
|
||||
clip: clip,
|
||||
size: self.base.overflow.scroll.size,
|
||||
}
|
||||
},
|
||||
self.base.stacking_context_id
|
||||
);
|
||||
scroll_root_id
|
||||
|
||||
self.base.scroll_root_id = new_scroll_root_id;
|
||||
state.current_scroll_root_id = new_scroll_root_id;
|
||||
containing_scroll_root_id
|
||||
}
|
||||
|
||||
fn create_pseudo_stacking_context_for_block(&mut self,
|
||||
stacking_context_id: StackingContextId,
|
||||
parent_stacking_context_id: StackingContextId,
|
||||
parent_scroll_root_id: ScrollRootId,
|
||||
state: &mut DisplayListBuildState) {
|
||||
|
@ -1963,7 +1945,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
StackingContextCreationMode::PseudoFloat
|
||||
};
|
||||
|
||||
let new_context = self.fragment.create_stacking_context(stacking_context_id,
|
||||
let new_context = self.fragment.create_stacking_context(self.base.stacking_context_id,
|
||||
&self.base,
|
||||
ScrollPolicy::Scrollable,
|
||||
creation_mode,
|
||||
|
@ -1972,19 +1954,20 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
|
||||
self.base.collect_stacking_contexts_for_children(state);
|
||||
|
||||
let new_children =
|
||||
state.stacking_context_children.remove(&stacking_context_id).unwrap_or_else(Vec::new);
|
||||
for child in new_children {
|
||||
if child.context_type == StackingContextType::PseudoFloat {
|
||||
state.add_stacking_context(stacking_context_id, child);
|
||||
} else {
|
||||
state.add_stacking_context(parent_stacking_context_id, child);
|
||||
let children = state.stacking_context_info.get_mut(&self.base.stacking_context_id)
|
||||
.map(|info| info.take_children());
|
||||
if let Some(children) = children {
|
||||
for child in children {
|
||||
if child.context_type == StackingContextType::PseudoFloat {
|
||||
state.add_stacking_context(self.base.stacking_context_id, child);
|
||||
} else {
|
||||
state.add_stacking_context(parent_stacking_context_id, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_real_stacking_context_for_block(&mut self,
|
||||
stacking_context_id: StackingContextId,
|
||||
parent_stacking_context_id: StackingContextId,
|
||||
parent_scroll_root_id: ScrollRootId,
|
||||
state: &mut DisplayListBuildState) {
|
||||
|
@ -1995,7 +1978,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
};
|
||||
|
||||
let stacking_context = self.fragment.create_stacking_context(
|
||||
stacking_context_id,
|
||||
self.base.stacking_context_id,
|
||||
&self.base,
|
||||
scroll_policy,
|
||||
StackingContextCreationMode::Normal,
|
||||
|
|
|
@ -16,14 +16,16 @@ use msg::constellation_msg::PipelineId;
|
|||
use style::computed_values::{image_rendering, mix_blend_mode};
|
||||
use style::computed_values::filter::{self, Filter};
|
||||
use style::values::computed::BorderStyle;
|
||||
use webrender_traits::{self, DisplayListBuilder, ExtendMode, LayoutTransform};
|
||||
use webrender_traits::{self, DisplayListBuilder, ExtendMode, LayoutTransform, ScrollLayerId};
|
||||
|
||||
pub trait WebRenderDisplayListConverter {
|
||||
fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
|
||||
}
|
||||
|
||||
trait WebRenderDisplayItemConverter {
|
||||
fn convert_to_webrender(&self, builder: &mut DisplayListBuilder);
|
||||
fn convert_to_webrender(&self,
|
||||
builder: &mut DisplayListBuilder,
|
||||
current_scroll_root_id: &mut ScrollRootId);
|
||||
}
|
||||
|
||||
trait ToBorderStyle {
|
||||
|
@ -212,16 +214,31 @@ impl ToFilterOps for filter::T {
|
|||
impl WebRenderDisplayListConverter for DisplayList {
|
||||
fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder {
|
||||
let traversal = DisplayListTraversal::new(self);
|
||||
let mut builder = DisplayListBuilder::new(pipeline_id.to_webrender());
|
||||
let webrender_pipeline_id = pipeline_id.to_webrender();
|
||||
let mut builder = DisplayListBuilder::new(webrender_pipeline_id);
|
||||
|
||||
let mut current_scroll_root_id = ScrollRootId::root();
|
||||
builder.push_clip_id(current_scroll_root_id.convert_to_webrender(webrender_pipeline_id));
|
||||
|
||||
for item in traversal {
|
||||
item.convert_to_webrender(&mut builder);
|
||||
item.convert_to_webrender(&mut builder, &mut current_scroll_root_id);
|
||||
}
|
||||
builder
|
||||
}
|
||||
}
|
||||
|
||||
impl WebRenderDisplayItemConverter for DisplayItem {
|
||||
fn convert_to_webrender(&self, builder: &mut DisplayListBuilder) {
|
||||
fn convert_to_webrender(&self,
|
||||
builder: &mut DisplayListBuilder,
|
||||
current_scroll_root_id: &mut ScrollRootId) {
|
||||
let scroll_root_id = self.base().scroll_root_id;
|
||||
if scroll_root_id != *current_scroll_root_id {
|
||||
let pipeline_id = builder.pipeline_id;
|
||||
builder.pop_clip_id();
|
||||
builder.push_clip_id(scroll_root_id.convert_to_webrender(pipeline_id));
|
||||
*current_scroll_root_id = scroll_root_id;
|
||||
}
|
||||
|
||||
match *self {
|
||||
DisplayItem::SolidColor(ref item) => {
|
||||
let color = item.color;
|
||||
|
@ -403,21 +420,26 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||
vec![],
|
||||
None);
|
||||
|
||||
builder.push_scroll_layer(clip,
|
||||
item.scroll_root.size.to_sizef(),
|
||||
Some(item.scroll_root.id.convert_to_webrender()));
|
||||
let provided_id = ScrollLayerId::new(item.scroll_root.id.0, builder.pipeline_id);
|
||||
let id = builder.define_clip(clip,
|
||||
item.scroll_root.size.to_sizef(),
|
||||
Some(provided_id));
|
||||
debug_assert!(provided_id == id);
|
||||
}
|
||||
DisplayItem::PopScrollRoot(_) => builder.pop_scroll_layer(),
|
||||
DisplayItem::PopScrollRoot(_) => {} //builder.pop_scroll_layer(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait WebRenderScrollRootIdConverter {
|
||||
fn convert_to_webrender(&self) -> webrender_traits::ServoScrollRootId;
|
||||
fn convert_to_webrender(&self, pipeline_id: webrender_traits::PipelineId) -> ScrollLayerId;
|
||||
}
|
||||
|
||||
impl WebRenderScrollRootIdConverter for ScrollRootId {
|
||||
fn convert_to_webrender(&self) -> webrender_traits::ServoScrollRootId {
|
||||
webrender_traits::ServoScrollRootId(self.0)
|
||||
fn convert_to_webrender(&self, pipeline_id: webrender_traits::PipelineId) -> ScrollLayerId {
|
||||
if *self == ScrollRootId::root() {
|
||||
ScrollLayerId::root_scroll_layer(pipeline_id)
|
||||
} else {
|
||||
ScrollLayerId::new(self.0, pipeline_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ mime_guess = "1.8.0"
|
|||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
num-traits = "0.1.32"
|
||||
offscreen_gl_context = "0.6"
|
||||
offscreen_gl_context = "0.8"
|
||||
open = "1.1.1"
|
||||
parking_lot = "0.3"
|
||||
phf = "0.7.18"
|
||||
|
|
|
@ -25,7 +25,7 @@ ipc-channel = "0.7"
|
|||
libc = "0.2"
|
||||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
offscreen_gl_context = "0.6"
|
||||
offscreen_gl_context = "0.8"
|
||||
profile_traits = {path = "../profile_traits"}
|
||||
rustc-serialize = "0.3.4"
|
||||
serde = "0.9"
|
||||
|
|
|
@ -32,7 +32,7 @@ devtools_traits = {path = "../devtools_traits"}
|
|||
env_logger = "0.4"
|
||||
euclid = "0.11"
|
||||
gfx = {path = "../gfx"}
|
||||
gleam = "0.2"
|
||||
gleam = "0.4"
|
||||
ipc-channel = "0.7"
|
||||
layout_thread = {path = "../layout_thread"}
|
||||
log = "0.3"
|
||||
|
|
|
@ -177,7 +177,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
|
|||
let framebuffer_size = webrender_traits::DeviceUintSize::new(framebuffer_size.width,
|
||||
framebuffer_size.height);
|
||||
|
||||
webrender::Renderer::new(webrender::RendererOptions {
|
||||
webrender::Renderer::new(window.gl(), webrender::RendererOptions {
|
||||
device_pixel_ratio: device_pixel_ratio,
|
||||
resource_override_path: Some(resource_path),
|
||||
enable_aa: opts.enable_text_antialiasing,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue