mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 1452603 - Update webrender to commit 6f997974cec5772b1797725f4a7942d742e7d7ff. r=jrmuizel
MozReview-Commit-ID: 1Gq3I7Z2Dd2 --HG-- extra : rebase_source : 00049966e37dab234cae5b13e7683a608609f2e5
This commit is contained in:
parent
aaf89f2684
commit
651d96be0a
@ -22,7 +22,7 @@ byteorder = "1.0"
|
||||
bincode = "1.0"
|
||||
euclid = "0.17"
|
||||
fxhash = "0.2.1"
|
||||
gleam = "0.4.20"
|
||||
gleam = "0.4.32"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
num-traits = "0.1.43"
|
||||
|
@ -142,6 +142,7 @@ pub fn main_wrapper<E: Example>(
|
||||
device_pixel_ratio,
|
||||
clear_color: Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
|
||||
//scatter_gpu_cache_updates: false,
|
||||
debug_flags: webrender::DebugFlags::ECHO_DRIVER_MESSAGES,
|
||||
..options.unwrap_or(webrender::RendererOptions::default())
|
||||
};
|
||||
|
||||
|
@ -975,23 +975,17 @@ impl AlphaBatchBuilder {
|
||||
let border_cpu =
|
||||
&ctx.prim_store.cpu_borders[prim_metadata.cpu_prim_index.0];
|
||||
// TODO(gw): Select correct blend mode for edges and corners!!
|
||||
let corner_kind = BatchKind::Transformable(
|
||||
transform_kind,
|
||||
TransformBatchKind::BorderCorner,
|
||||
);
|
||||
let corner_key = BatchKey::new(corner_kind, non_segmented_blend_mode, no_textures);
|
||||
let edge_kind = BatchKind::Transformable(
|
||||
transform_kind,
|
||||
TransformBatchKind::BorderEdge,
|
||||
);
|
||||
let edge_key = BatchKey::new(edge_kind, non_segmented_blend_mode, no_textures);
|
||||
|
||||
// Work around borrow ck on borrowing batch_list twice.
|
||||
{
|
||||
let batch =
|
||||
self.batch_list.get_suitable_batch(corner_key, &task_relative_bounding_rect);
|
||||
for (i, instance_kind) in border_cpu.corner_instances.iter().enumerate()
|
||||
{
|
||||
if border_cpu.corner_instances.iter().any(|&kind| kind != BorderCornerInstance::None) {
|
||||
let corner_kind = BatchKind::Transformable(
|
||||
transform_kind,
|
||||
TransformBatchKind::BorderCorner,
|
||||
);
|
||||
let corner_key = BatchKey::new(corner_kind, non_segmented_blend_mode, no_textures);
|
||||
let batch = self.batch_list
|
||||
.get_suitable_batch(corner_key, &task_relative_bounding_rect);
|
||||
|
||||
for (i, instance_kind) in border_cpu.corner_instances.iter().enumerate() {
|
||||
let sub_index = i as i32;
|
||||
match *instance_kind {
|
||||
BorderCornerInstance::None => {}
|
||||
@ -1018,12 +1012,22 @@ impl AlphaBatchBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
let batch = self.batch_list.get_suitable_batch(edge_key, &task_relative_bounding_rect);
|
||||
for (border_segment, instance_kind) in border_cpu.edges.iter().enumerate() {
|
||||
match *instance_kind {
|
||||
BorderEdgeKind::None => {},
|
||||
_ => {
|
||||
batch.push(base_instance.build(border_segment as i32, 0, 0));
|
||||
if border_cpu.edges.iter().any(|&kind| kind != BorderEdgeKind::None) {
|
||||
let edge_kind = BatchKind::Transformable(
|
||||
transform_kind,
|
||||
TransformBatchKind::BorderEdge,
|
||||
);
|
||||
let edge_key = BatchKey::new(edge_kind, non_segmented_blend_mode, no_textures);
|
||||
let batch = self.batch_list
|
||||
.get_suitable_batch(edge_key, &task_relative_bounding_rect);
|
||||
|
||||
for (border_segment, instance_kind) in border_cpu.edges.iter().enumerate() {
|
||||
match *instance_kind {
|
||||
BorderEdgeKind::None => {},
|
||||
BorderEdgeKind::Solid |
|
||||
BorderEdgeKind::Clip => {
|
||||
batch.push(base_instance.build(border_segment as i32, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,134 +103,116 @@ pub enum BorderEdgeKind {
|
||||
Clip,
|
||||
}
|
||||
|
||||
trait NormalBorderHelpers {
|
||||
fn get_corner(
|
||||
&self,
|
||||
edge0: &BorderSide,
|
||||
width0: f32,
|
||||
edge1: &BorderSide,
|
||||
width1: f32,
|
||||
radius: &LayerSize,
|
||||
corner: BorderCorner,
|
||||
border_rect: &LayerRect,
|
||||
) -> BorderCornerKind;
|
||||
|
||||
fn get_edge(&self, edge: &BorderSide, width: f32) -> (BorderEdgeKind, f32);
|
||||
}
|
||||
|
||||
impl NormalBorderHelpers for NormalBorder {
|
||||
fn get_corner(
|
||||
&self,
|
||||
edge0: &BorderSide,
|
||||
width0: f32,
|
||||
edge1: &BorderSide,
|
||||
width1: f32,
|
||||
radius: &LayerSize,
|
||||
corner: BorderCorner,
|
||||
border_rect: &LayerRect,
|
||||
) -> BorderCornerKind {
|
||||
// If both widths are zero, a corner isn't formed.
|
||||
if width0 == 0.0 && width1 == 0.0 {
|
||||
return BorderCornerKind::None;
|
||||
}
|
||||
|
||||
// If both edges are transparent, no corner is formed.
|
||||
if edge0.color.a == 0.0 && edge1.color.a == 0.0 {
|
||||
return BorderCornerKind::None;
|
||||
}
|
||||
|
||||
match (edge0.style, edge1.style) {
|
||||
// If both edges are none or hidden, no corner is needed.
|
||||
(BorderStyle::None, BorderStyle::None) |
|
||||
(BorderStyle::None, BorderStyle::Hidden) |
|
||||
(BorderStyle::Hidden, BorderStyle::None) |
|
||||
(BorderStyle::Hidden, BorderStyle::Hidden) => {
|
||||
BorderCornerKind::None
|
||||
}
|
||||
|
||||
// If one of the edges is none or hidden, we just draw one style.
|
||||
(BorderStyle::None, _) |
|
||||
(_, BorderStyle::None) |
|
||||
(BorderStyle::Hidden, _) |
|
||||
(_, BorderStyle::Hidden) => {
|
||||
BorderCornerKind::Clip(BorderCornerInstance::Single)
|
||||
}
|
||||
|
||||
// If both borders are solid, we can draw them with a simple rectangle if
|
||||
// both the colors match and there is no radius.
|
||||
(BorderStyle::Solid, BorderStyle::Solid) => {
|
||||
if edge0.color == edge1.color && radius.width == 0.0 && radius.height == 0.0 {
|
||||
BorderCornerKind::Solid
|
||||
} else {
|
||||
BorderCornerKind::Clip(BorderCornerInstance::Single)
|
||||
}
|
||||
}
|
||||
|
||||
// Inset / outset borders just modify the color of edges, so can be
|
||||
// drawn with the normal border corner shader.
|
||||
(BorderStyle::Outset, BorderStyle::Outset) |
|
||||
(BorderStyle::Inset, BorderStyle::Inset) |
|
||||
(BorderStyle::Double, BorderStyle::Double) |
|
||||
(BorderStyle::Groove, BorderStyle::Groove) |
|
||||
(BorderStyle::Ridge, BorderStyle::Ridge) => {
|
||||
BorderCornerKind::Clip(BorderCornerInstance::Single)
|
||||
}
|
||||
|
||||
// Dashed and dotted border corners get drawn into a clip mask.
|
||||
(BorderStyle::Dashed, BorderStyle::Dashed) => BorderCornerKind::new_mask(
|
||||
BorderCornerClipKind::Dash,
|
||||
width0,
|
||||
width1,
|
||||
corner,
|
||||
*radius,
|
||||
*border_rect,
|
||||
),
|
||||
(BorderStyle::Dotted, BorderStyle::Dotted) => BorderCornerKind::new_mask(
|
||||
BorderCornerClipKind::Dot,
|
||||
width0,
|
||||
width1,
|
||||
corner,
|
||||
*radius,
|
||||
*border_rect,
|
||||
),
|
||||
|
||||
// Draw border transitions with dots and/or dashes as
|
||||
// solid segments. The old border path didn't support
|
||||
// this anyway, so we might as well start using the new
|
||||
// border path here, since the dashing in the edges is
|
||||
// much higher quality anyway.
|
||||
(BorderStyle::Dotted, _) |
|
||||
(_, BorderStyle::Dotted) |
|
||||
(BorderStyle::Dashed, _) |
|
||||
(_, BorderStyle::Dashed) => BorderCornerKind::Clip(BorderCornerInstance::Single),
|
||||
|
||||
// Everything else can be handled by drawing the corner twice,
|
||||
// where the shader outputs zero alpha for the side it's not
|
||||
// drawing. This is somewhat inefficient in terms of pixels
|
||||
// written, but it's a fairly rare case, and we can optimize
|
||||
// this case later.
|
||||
_ => BorderCornerKind::Clip(BorderCornerInstance::Double),
|
||||
}
|
||||
fn get_corner(
|
||||
edge0: &BorderSide,
|
||||
width0: f32,
|
||||
edge1: &BorderSide,
|
||||
width1: f32,
|
||||
radius: &LayerSize,
|
||||
corner: BorderCorner,
|
||||
border_rect: &LayerRect,
|
||||
) -> BorderCornerKind {
|
||||
// If both widths are zero, a corner isn't formed.
|
||||
if width0 == 0.0 && width1 == 0.0 {
|
||||
return BorderCornerKind::None;
|
||||
}
|
||||
|
||||
fn get_edge(&self, edge: &BorderSide, width: f32) -> (BorderEdgeKind, f32) {
|
||||
if width == 0.0 {
|
||||
return (BorderEdgeKind::None, 0.0);
|
||||
// If both edges are transparent, no corner is formed.
|
||||
if edge0.color.a == 0.0 && edge1.color.a == 0.0 {
|
||||
return BorderCornerKind::None;
|
||||
}
|
||||
|
||||
match (edge0.style, edge1.style) {
|
||||
// If both edges are none or hidden, no corner is needed.
|
||||
(BorderStyle::None, BorderStyle::None) |
|
||||
(BorderStyle::None, BorderStyle::Hidden) |
|
||||
(BorderStyle::Hidden, BorderStyle::None) |
|
||||
(BorderStyle::Hidden, BorderStyle::Hidden) => {
|
||||
BorderCornerKind::None
|
||||
}
|
||||
|
||||
match edge.style {
|
||||
BorderStyle::None | BorderStyle::Hidden => (BorderEdgeKind::None, 0.0),
|
||||
// If one of the edges is none or hidden, we just draw one style.
|
||||
(BorderStyle::None, _) |
|
||||
(_, BorderStyle::None) |
|
||||
(BorderStyle::Hidden, _) |
|
||||
(_, BorderStyle::Hidden) => {
|
||||
BorderCornerKind::Clip(BorderCornerInstance::Single)
|
||||
}
|
||||
|
||||
BorderStyle::Solid | BorderStyle::Inset | BorderStyle::Outset => {
|
||||
(BorderEdgeKind::Solid, width)
|
||||
// If both borders are solid, we can draw them with a simple rectangle if
|
||||
// both the colors match and there is no radius.
|
||||
(BorderStyle::Solid, BorderStyle::Solid) => {
|
||||
if edge0.color == edge1.color && radius.width == 0.0 && radius.height == 0.0 {
|
||||
BorderCornerKind::Solid
|
||||
} else {
|
||||
BorderCornerKind::Clip(BorderCornerInstance::Single)
|
||||
}
|
||||
|
||||
BorderStyle::Double |
|
||||
BorderStyle::Groove |
|
||||
BorderStyle::Ridge |
|
||||
BorderStyle::Dashed |
|
||||
BorderStyle::Dotted => (BorderEdgeKind::Clip, width),
|
||||
}
|
||||
|
||||
// Inset / outset borders just modify the color of edges, so can be
|
||||
// drawn with the normal border corner shader.
|
||||
(BorderStyle::Outset, BorderStyle::Outset) |
|
||||
(BorderStyle::Inset, BorderStyle::Inset) |
|
||||
(BorderStyle::Double, BorderStyle::Double) |
|
||||
(BorderStyle::Groove, BorderStyle::Groove) |
|
||||
(BorderStyle::Ridge, BorderStyle::Ridge) => {
|
||||
BorderCornerKind::Clip(BorderCornerInstance::Single)
|
||||
}
|
||||
|
||||
// Dashed and dotted border corners get drawn into a clip mask.
|
||||
(BorderStyle::Dashed, BorderStyle::Dashed) => BorderCornerKind::new_mask(
|
||||
BorderCornerClipKind::Dash,
|
||||
width0,
|
||||
width1,
|
||||
corner,
|
||||
*radius,
|
||||
*border_rect,
|
||||
),
|
||||
(BorderStyle::Dotted, BorderStyle::Dotted) => BorderCornerKind::new_mask(
|
||||
BorderCornerClipKind::Dot,
|
||||
width0,
|
||||
width1,
|
||||
corner,
|
||||
*radius,
|
||||
*border_rect,
|
||||
),
|
||||
|
||||
// Draw border transitions with dots and/or dashes as
|
||||
// solid segments. The old border path didn't support
|
||||
// this anyway, so we might as well start using the new
|
||||
// border path here, since the dashing in the edges is
|
||||
// much higher quality anyway.
|
||||
(BorderStyle::Dotted, _) |
|
||||
(_, BorderStyle::Dotted) |
|
||||
(BorderStyle::Dashed, _) |
|
||||
(_, BorderStyle::Dashed) => BorderCornerKind::Clip(BorderCornerInstance::Single),
|
||||
|
||||
// Everything else can be handled by drawing the corner twice,
|
||||
// where the shader outputs zero alpha for the side it's not
|
||||
// drawing. This is somewhat inefficient in terms of pixels
|
||||
// written, but it's a fairly rare case, and we can optimize
|
||||
// this case later.
|
||||
_ => BorderCornerKind::Clip(BorderCornerInstance::Double),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_edge(edge: &BorderSide, width: f32, height: f32) -> (BorderEdgeKind, f32) {
|
||||
if width == 0.0 || height <= 0.0 {
|
||||
return (BorderEdgeKind::None, 0.0);
|
||||
}
|
||||
|
||||
match edge.style {
|
||||
BorderStyle::None | BorderStyle::Hidden => (BorderEdgeKind::None, 0.0),
|
||||
|
||||
BorderStyle::Solid | BorderStyle::Inset | BorderStyle::Outset => {
|
||||
(BorderEdgeKind::Solid, width)
|
||||
}
|
||||
|
||||
BorderStyle::Double |
|
||||
BorderStyle::Groove |
|
||||
BorderStyle::Ridge |
|
||||
BorderStyle::Dashed |
|
||||
BorderStyle::Dotted => (BorderEdgeKind::Clip, width),
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,7 +413,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
}
|
||||
|
||||
let corners = [
|
||||
border.get_corner(
|
||||
get_corner(
|
||||
left,
|
||||
widths.left,
|
||||
top,
|
||||
@ -440,7 +422,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
BorderCorner::TopLeft,
|
||||
&info.rect,
|
||||
),
|
||||
border.get_corner(
|
||||
get_corner(
|
||||
right,
|
||||
widths.right,
|
||||
top,
|
||||
@ -449,7 +431,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
BorderCorner::TopRight,
|
||||
&info.rect,
|
||||
),
|
||||
border.get_corner(
|
||||
get_corner(
|
||||
right,
|
||||
widths.right,
|
||||
bottom,
|
||||
@ -458,7 +440,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
BorderCorner::BottomRight,
|
||||
&info.rect,
|
||||
),
|
||||
border.get_corner(
|
||||
get_corner(
|
||||
left,
|
||||
widths.left,
|
||||
bottom,
|
||||
@ -469,10 +451,14 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
),
|
||||
];
|
||||
|
||||
let (left_edge, left_len) = border.get_edge(left, widths.left);
|
||||
let (top_edge, top_len) = border.get_edge(top, widths.top);
|
||||
let (right_edge, right_len) = border.get_edge(right, widths.right);
|
||||
let (bottom_edge, bottom_len) = border.get_edge(bottom, widths.bottom);
|
||||
let (left_edge, left_len) = get_edge(left, widths.left,
|
||||
info.rect.size.height - radius.top_left.height - radius.bottom_left.height);
|
||||
let (top_edge, top_len) = get_edge(top, widths.top,
|
||||
info.rect.size.width - radius.top_left.width - radius.top_right.width);
|
||||
let (right_edge, right_len) = get_edge(right, widths.right,
|
||||
info.rect.size.height - radius.top_right.height - radius.bottom_right.height);
|
||||
let (bottom_edge, bottom_len) = get_edge(bottom, widths.bottom,
|
||||
info.rect.size.width - radius.bottom_right.width - radius.bottom_left.width);
|
||||
|
||||
let edges = [left_edge, top_edge, right_edge, bottom_edge];
|
||||
|
||||
|
@ -63,7 +63,7 @@ impl ws::Handler for Server {
|
||||
"fetch_clip_scroll_tree" => DebugCommand::FetchClipScrollTree,
|
||||
"fetch_render_tasks" => DebugCommand::FetchRenderTasks,
|
||||
msg => {
|
||||
println!("unknown msg {}", msg);
|
||||
error!("unknown msg {}", msg);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
@ -105,9 +105,9 @@ impl DebugServer {
|
||||
|
||||
let join_handle = Some(thread::spawn(move || {
|
||||
let address = "127.0.0.1:3583";
|
||||
println!("WebRender debug server started: {}", address);
|
||||
debug!("WebRender debug server started: {}", address);
|
||||
if let Err(..) = socket.listen(address) {
|
||||
println!("ERROR: Unable to bind debugger websocket (port may be in use).");
|
||||
error!("ERROR: Unable to bind debugger websocket (port may be in use).");
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -11,6 +11,7 @@ use api::ImageDescriptor;
|
||||
use euclid::Transform3D;
|
||||
use gleam::gl;
|
||||
use internal_types::{FastHashMap, RenderTargetInfo};
|
||||
use log::Level;
|
||||
use smallvec::SmallVec;
|
||||
use std::cell::RefCell;
|
||||
use std::fs::File;
|
||||
@ -787,7 +788,7 @@ impl Device {
|
||||
_ => return,
|
||||
};
|
||||
for (line, prefix) in source.lines().skip(base_line_number).zip(&["|",">","|"]) {
|
||||
println!("{}\t{}", prefix, line);
|
||||
error!("{}\t{}", prefix, line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,13 +804,13 @@ impl Device {
|
||||
gl.compile_shader(id);
|
||||
let log = gl.get_shader_info_log(id);
|
||||
if gl.get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
|
||||
println!("Failed to compile shader: {}\n{}", name, log);
|
||||
error!("Failed to compile shader: {}\n{}", name, log);
|
||||
#[cfg(debug_assertions)]
|
||||
Self::print_shader_errors(source, &log);
|
||||
Err(ShaderError::Compilation(name.to_string(), log))
|
||||
} else {
|
||||
if !log.is_empty() {
|
||||
println!("Warnings detected on shader: {}\n{}", name, log);
|
||||
warn!("Warnings detected on shader: {}\n{}", name, log);
|
||||
}
|
||||
Ok(id)
|
||||
}
|
||||
@ -1380,7 +1381,7 @@ impl Device {
|
||||
|
||||
if self.gl.get_program_iv(pid, gl::LINK_STATUS) == (0 as gl::GLint) {
|
||||
let error_log = self.gl.get_program_info_log(pid);
|
||||
println!(
|
||||
error!(
|
||||
"Failed to load a program object with a program binary: {} renderer {}\n{}",
|
||||
base_filename,
|
||||
self.renderer_name,
|
||||
@ -1442,7 +1443,7 @@ impl Device {
|
||||
|
||||
if self.gl.get_program_iv(pid, gl::LINK_STATUS) == (0 as gl::GLint) {
|
||||
let error_log = self.gl.get_program_info_log(pid);
|
||||
println!(
|
||||
error!(
|
||||
"Failed to link shader program: {}\n{}",
|
||||
base_filename,
|
||||
error_log
|
||||
@ -2103,6 +2104,31 @@ impl Device {
|
||||
pub fn supports_extension(&self, extension: &str) -> bool {
|
||||
self.extensions.iter().any(|s| s == extension)
|
||||
}
|
||||
|
||||
pub fn echo_driver_messages(&self) {
|
||||
for msg in self.gl.get_debug_messages() {
|
||||
let level = match msg.severity {
|
||||
gl::DEBUG_SEVERITY_HIGH => Level::Error,
|
||||
gl::DEBUG_SEVERITY_MEDIUM => Level::Warn,
|
||||
gl::DEBUG_SEVERITY_LOW => Level::Info,
|
||||
gl::DEBUG_SEVERITY_NOTIFICATION => Level::Debug,
|
||||
_ => Level::Trace,
|
||||
};
|
||||
let ty = match msg.ty {
|
||||
gl::DEBUG_TYPE_ERROR => "error",
|
||||
gl::DEBUG_TYPE_DEPRECATED_BEHAVIOR => "deprecated",
|
||||
gl::DEBUG_TYPE_UNDEFINED_BEHAVIOR => "undefined",
|
||||
gl::DEBUG_TYPE_PORTABILITY => "portability",
|
||||
gl::DEBUG_TYPE_PERFORMANCE => "perf",
|
||||
gl::DEBUG_TYPE_MARKER => "marker",
|
||||
gl::DEBUG_TYPE_PUSH_GROUP => "group push",
|
||||
gl::DEBUG_TYPE_POP_GROUP => "group pop",
|
||||
gl::DEBUG_TYPE_OTHER => "other",
|
||||
_ => "?",
|
||||
};
|
||||
log!(level, "({}) {}", ty, msg.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FormatDesc {
|
||||
|
@ -570,7 +570,11 @@ impl<'a> DisplayListFlattener<'a> {
|
||||
let iframe_pipeline_id = info.pipeline_id;
|
||||
let pipeline = match self.scene.pipelines.get(&iframe_pipeline_id) {
|
||||
Some(pipeline) => pipeline,
|
||||
None => return,
|
||||
None => {
|
||||
//TODO: assert/debug_assert?
|
||||
error!("Unknown pipeline used for iframe {:?}", info);
|
||||
return
|
||||
},
|
||||
};
|
||||
|
||||
self.id_to_index_mapper.initialize_for_pipeline(pipeline);
|
||||
|
@ -90,6 +90,12 @@ impl<T> FreeList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.slots.clear();
|
||||
self.free_list_head = None;
|
||||
self.active_count = 0;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get(&self, id: &FreeListHandle<T>) -> &T {
|
||||
self.slots[id.index as usize].value.as_ref().unwrap()
|
||||
|
@ -8,6 +8,8 @@ use api::{ColorF, ColorU};
|
||||
use api::{FontInstanceFlags, FontInstancePlatformOptions};
|
||||
use api::{FontKey, FontRenderMode, FontTemplate, FontVariation};
|
||||
use api::{GlyphDimensions, GlyphKey, LayerToWorldTransform, SubpixelDirection};
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use api::NativeFontHandle;
|
||||
#[cfg(any(test, feature = "pathfinder"))]
|
||||
use api::DeviceIntSize;
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
@ -128,12 +130,12 @@ impl FontTransform {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn determinant(&self) -> f64 {
|
||||
self.scale_x as f64 * self.scale_y as f64 - self.skew_y as f64 * self.skew_x as f64
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn compute_scale(&self) -> Option<(f64, f64)> {
|
||||
let det = self.determinant();
|
||||
if det != 0.0 {
|
||||
@ -145,7 +147,7 @@ impl FontTransform {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn pre_scale(&self, scale_x: f32, scale_y: f32) -> Self {
|
||||
FontTransform::new(
|
||||
self.scale_x * scale_x,
|
||||
@ -155,7 +157,7 @@ impl FontTransform {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
#[allow(dead_code)]
|
||||
pub fn invert_scale(&self, x_scale: f64, y_scale: f64) -> Self {
|
||||
self.pre_scale(x_scale.recip() as f32, y_scale.recip() as f32)
|
||||
}
|
||||
@ -453,6 +455,7 @@ impl GlyphRasterizer {
|
||||
#[cfg(feature = "pathfinder")]
|
||||
fn add_font_to_pathfinder(&mut self, font_key: &FontKey, template: &FontTemplate) {
|
||||
let font_contexts = Arc::clone(&self.font_contexts);
|
||||
debug!("add_font_to_pathfinder({:?})", font_key);
|
||||
font_contexts.lock_pathfinder_context().add_font(&font_key, &template);
|
||||
}
|
||||
|
||||
@ -861,10 +864,10 @@ impl AddFont for PathfinderFontContext {
|
||||
fn add_font(&mut self, font_key: &FontKey, template: &FontTemplate) {
|
||||
match *template {
|
||||
FontTemplate::Raw(ref bytes, index) => {
|
||||
drop(self.add_font_from_memory(font_key, bytes.clone(), index));
|
||||
drop(self.add_font_from_memory(&font_key, bytes.clone(), index))
|
||||
}
|
||||
FontTemplate::Native(ref native_font_handle) => {
|
||||
drop(self.add_native_font(font_key, (*native_font_handle).clone().0));
|
||||
drop(self.add_native_font(&font_key, NativeFontHandleWrapper(native_font_handle)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1067,3 +1070,6 @@ fn request_render_task_from_pathfinder(glyph_key: &GlyphKey,
|
||||
|
||||
Ok((root_task_id, false))
|
||||
}
|
||||
|
||||
#[cfg(feature = "pathfinder")]
|
||||
pub struct NativeFontHandleWrapper<'a>(pub &'a NativeFontHandle);
|
||||
|
@ -28,6 +28,8 @@ use core_text::font::{CTFont, CTFontRef};
|
||||
use core_text::font_descriptor::{kCTFontDefaultOrientation, kCTFontColorGlyphsTrait};
|
||||
use gamma_lut::{ColorLut, GammaLut};
|
||||
use glyph_rasterizer::{FontInstance, FontTransform};
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use glyph_rasterizer::NativeFontHandleWrapper;
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
use glyph_rasterizer::{GlyphFormat, GlyphRasterResult, RasterizedGlyph};
|
||||
use internal_types::{FastHashMap, ResourceCacheError};
|
||||
@ -729,3 +731,10 @@ impl FontContext {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pathfinder")]
|
||||
impl<'a> Into<CGFont> for NativeFontHandleWrapper<'a> {
|
||||
fn into(self) -> CGFont {
|
||||
(self.0).0.clone()
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,11 @@ use freetype::freetype::{FT_LOAD_NO_BITMAP, FT_LOAD_NO_HINTING, FT_LOAD_VERTICAL
|
||||
use freetype::freetype::{FT_FACE_FLAG_SCALABLE, FT_FACE_FLAG_FIXED_SIZES};
|
||||
use freetype::succeeded;
|
||||
use glyph_rasterizer::{FontInstance, GlyphFormat, GlyphRasterResult, RasterizedGlyph};
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use glyph_rasterizer::NativeFontHandleWrapper;
|
||||
use internal_types::{FastHashMap, ResourceCacheError};
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use pathfinder_font_renderer::freetype as pf_freetype;
|
||||
use std::{cmp, mem, ptr, slice};
|
||||
use std::cmp::max;
|
||||
use std::ffi::CString;
|
||||
@ -192,7 +196,7 @@ impl FontContext {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
println!("WARN: webrender failed to load font");
|
||||
warn!("WARN: webrender failed to load font");
|
||||
debug!("font={:?}", font_key);
|
||||
}
|
||||
}
|
||||
@ -219,7 +223,7 @@ impl FontContext {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
println!("WARN: webrender failed to load font");
|
||||
warn!("WARN: webrender failed to load font");
|
||||
debug!("font={:?}, path={:?}", font_key, pathname);
|
||||
}
|
||||
}
|
||||
@ -788,3 +792,11 @@ impl Drop for FontContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pathfinder")]
|
||||
impl<'a> Into<pf_freetype::FontDescriptor> for NativeFontHandleWrapper<'a> {
|
||||
fn into(self) -> pf_freetype::FontDescriptor {
|
||||
let NativeFontHandleWrapper(font_handle) = self;
|
||||
pf_freetype::FontDescriptor::new(font_handle.pathname.clone().into(), font_handle.index)
|
||||
}
|
||||
}
|
||||
|
@ -666,6 +666,10 @@ impl RenderBackend {
|
||||
doc.dynamic_properties.set_properties(property_bindings);
|
||||
DocumentOps::render()
|
||||
}
|
||||
FrameMsg::AppendDynamicProperties(property_bindings) => {
|
||||
doc.dynamic_properties.add_properties(property_bindings);
|
||||
DocumentOps::render()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ use clip_scroll_tree::CoordinateSystemId;
|
||||
use device::TextureFilter;
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use euclid::{TypedPoint2D, TypedVector2D};
|
||||
use freelist::{FreeList, FreeListHandle};
|
||||
use glyph_rasterizer::GpuGlyphCacheKey;
|
||||
use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
|
||||
use gpu_types::{ImageSource, RasterizationSpace};
|
||||
@ -866,8 +867,8 @@ pub struct RenderTaskCacheKey {
|
||||
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
struct RenderTaskCacheEntry {
|
||||
handle: TextureCacheHandle,
|
||||
pub struct RenderTaskCacheEntry {
|
||||
pub handle: TextureCacheHandle,
|
||||
}
|
||||
|
||||
// A cache of render tasks that are stored in the texture
|
||||
@ -875,18 +876,21 @@ struct RenderTaskCacheEntry {
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct RenderTaskCache {
|
||||
entries: FastHashMap<RenderTaskCacheKey, RenderTaskCacheEntry>,
|
||||
map: FastHashMap<RenderTaskCacheKey, FreeListHandle<RenderTaskCacheEntry>>,
|
||||
cache_entries: FreeList<RenderTaskCacheEntry>,
|
||||
}
|
||||
|
||||
impl RenderTaskCache {
|
||||
pub fn new() -> Self {
|
||||
RenderTaskCache {
|
||||
entries: FastHashMap::default(),
|
||||
map: FastHashMap::default(),
|
||||
cache_entries: FreeList::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.entries.clear();
|
||||
self.map.clear();
|
||||
self.cache_entries.clear();
|
||||
}
|
||||
|
||||
pub fn begin_frame(
|
||||
@ -906,9 +910,19 @@ impl RenderTaskCache {
|
||||
// Nonetheless, we should remove stale entries
|
||||
// from here so that this hash map doesn't
|
||||
// grow indefinitely!
|
||||
self.entries.retain(|_, value| {
|
||||
texture_cache.is_allocated(&value.handle)
|
||||
});
|
||||
let mut keys_to_remove = Vec::new();
|
||||
|
||||
for (key, handle) in &self.map {
|
||||
let entry = self.cache_entries.get(handle);
|
||||
if !texture_cache.is_allocated(&entry.handle) {
|
||||
keys_to_remove.push(key.clone())
|
||||
}
|
||||
}
|
||||
|
||||
for key in &keys_to_remove {
|
||||
let handle = self.map.remove(key).unwrap();
|
||||
self.cache_entries.free(handle);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn request_render_task<F>(
|
||||
@ -923,11 +937,16 @@ impl RenderTaskCache {
|
||||
where F: FnMut(&mut RenderTaskTree) -> Result<(RenderTaskId, bool), ()> {
|
||||
// Get the texture cache handle for this cache key,
|
||||
// or create one.
|
||||
let cache_entry = self.entries
|
||||
.entry(key)
|
||||
.or_insert(RenderTaskCacheEntry {
|
||||
handle: TextureCacheHandle::new(),
|
||||
});
|
||||
let cache_entries = &mut self.cache_entries;
|
||||
let entry_handle = self.map
|
||||
.entry(key)
|
||||
.or_insert_with(|| {
|
||||
let entry = RenderTaskCacheEntry {
|
||||
handle: TextureCacheHandle::new(),
|
||||
};
|
||||
cache_entries.insert(entry)
|
||||
});
|
||||
let cache_entry = cache_entries.get_mut(entry_handle);
|
||||
|
||||
// Check if this texture cache handle is valid.
|
||||
if texture_cache.request(&cache_entry.handle, gpu_cache) {
|
||||
@ -1000,7 +1019,8 @@ impl RenderTaskCache {
|
||||
key: &RenderTaskCacheKey)
|
||||
-> CacheItem {
|
||||
// Get the texture cache handle for this cache key.
|
||||
let cache_entry = self.entries.get(key).unwrap();
|
||||
let handle = self.map.get(key).unwrap();
|
||||
let cache_entry = self.cache_entries.get(handle);
|
||||
texture_cache.get(&cache_entry.handle)
|
||||
}
|
||||
|
||||
@ -1009,7 +1029,8 @@ impl RenderTaskCache {
|
||||
texture_cache: &TextureCache,
|
||||
key: &RenderTaskCacheKey)
|
||||
-> bool {
|
||||
let cache_entry = self.entries.get(key).unwrap();
|
||||
let handle = self.map.get(key).unwrap();
|
||||
let cache_entry = self.cache_entries.get(handle);
|
||||
texture_cache.is_allocated(&cache_entry.handle)
|
||||
}
|
||||
}
|
||||
|
@ -255,6 +255,7 @@ bitflags! {
|
||||
const DISABLE_BATCHING = 1 << 5;
|
||||
const EPOCHS = 1 << 6;
|
||||
const COMPACT_PROFILER = 1 << 7;
|
||||
const ECHO_DRIVER_MESSAGES = 1 << 8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,6 +1258,12 @@ impl LazyInitializedDebugRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RendererVAOs {
|
||||
prim_vao: VAO,
|
||||
blur_vao: VAO,
|
||||
clip_vao: VAO,
|
||||
}
|
||||
|
||||
/// The renderer is responsible for submitting to the GPU the work prepared by the
|
||||
/// RenderBackend.
|
||||
pub struct Renderer {
|
||||
@ -1287,9 +1294,7 @@ pub struct Renderer {
|
||||
last_time: u64,
|
||||
|
||||
pub gpu_profile: GpuProfiler<GpuProfileTag>,
|
||||
prim_vao: VAO,
|
||||
blur_vao: VAO,
|
||||
clip_vao: VAO,
|
||||
vaos: RendererVAOs,
|
||||
|
||||
node_data_texture: VertexDataTexture,
|
||||
local_clip_rects_texture: VertexDataTexture,
|
||||
@ -1412,7 +1417,7 @@ impl Renderer {
|
||||
// gracefully fail now than panic as soon as a texture is allocated.
|
||||
let min_texture_size = 512;
|
||||
if device_max_size < min_texture_size {
|
||||
println!(
|
||||
error!(
|
||||
"Device reporting insufficient max texture size ({})",
|
||||
device_max_size
|
||||
);
|
||||
@ -1689,9 +1694,11 @@ impl Renderer {
|
||||
last_time: 0,
|
||||
gpu_profile,
|
||||
gpu_glyph_renderer,
|
||||
prim_vao,
|
||||
blur_vao,
|
||||
clip_vao,
|
||||
vaos: RendererVAOs {
|
||||
prim_vao,
|
||||
blur_vao,
|
||||
clip_vao,
|
||||
},
|
||||
node_data_texture,
|
||||
local_clip_rects_texture,
|
||||
render_task_texture,
|
||||
@ -2298,6 +2305,10 @@ impl Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
if self.debug_flags.contains(DebugFlags::ECHO_DRIVER_MESSAGES) {
|
||||
self.device.echo_driver_messages();
|
||||
}
|
||||
|
||||
self.backend_profile_counters.reset();
|
||||
self.profile_counters.reset();
|
||||
self.profile_counters.frame_counter.inc();
|
||||
@ -2512,11 +2523,7 @@ impl Renderer {
|
||||
vertex_array_kind: VertexArrayKind,
|
||||
stats: &mut RendererStats,
|
||||
) {
|
||||
let vao = get_vao(vertex_array_kind,
|
||||
&self.prim_vao,
|
||||
&self.clip_vao,
|
||||
&self.blur_vao,
|
||||
&self.gpu_glyph_renderer);
|
||||
let vao = get_vao(vertex_array_kind, &self.vaos, &self.gpu_glyph_renderer);
|
||||
|
||||
self.device.bind_vao(vao);
|
||||
|
||||
@ -3920,9 +3927,9 @@ impl Renderer {
|
||||
self.render_task_texture.deinit(&mut self.device);
|
||||
self.device.delete_pbo(self.texture_cache_upload_pbo);
|
||||
self.texture_resolver.deinit(&mut self.device);
|
||||
self.device.delete_vao(self.prim_vao);
|
||||
self.device.delete_vao(self.clip_vao);
|
||||
self.device.delete_vao(self.blur_vao);
|
||||
self.device.delete_vao(self.vaos.prim_vao);
|
||||
self.device.delete_vao(self.vaos.clip_vao);
|
||||
self.device.delete_vao(self.vaos.blur_vao);
|
||||
|
||||
#[cfg(feature = "debug_renderer")]
|
||||
{
|
||||
@ -4488,19 +4495,15 @@ impl Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): We should really gather up all the VAOs into a separate structure so that they
|
||||
// don't have to be passed in as parameters here.
|
||||
#[cfg(feature = "pathfinder")]
|
||||
fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
|
||||
prim_vao: &'a VAO,
|
||||
clip_vao: &'a VAO,
|
||||
blur_vao: &'a VAO,
|
||||
vaos: &'a RendererVAOs,
|
||||
gpu_glyph_renderer: &'a GpuGlyphRenderer)
|
||||
-> &'a VAO {
|
||||
match vertex_array_kind {
|
||||
VertexArrayKind::Primitive => prim_vao,
|
||||
VertexArrayKind::Clip => clip_vao,
|
||||
VertexArrayKind::Blur => blur_vao,
|
||||
VertexArrayKind::Primitive => &vaos.prim_vao,
|
||||
VertexArrayKind::Clip => &vaos.clip_vao,
|
||||
VertexArrayKind::Blur => &vaos.blur_vao,
|
||||
VertexArrayKind::VectorStencil => &gpu_glyph_renderer.vector_stencil_vao,
|
||||
VertexArrayKind::VectorCover => &gpu_glyph_renderer.vector_cover_vao,
|
||||
}
|
||||
@ -4508,15 +4511,13 @@ fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
|
||||
|
||||
#[cfg(not(feature = "pathfinder"))]
|
||||
fn get_vao<'a>(vertex_array_kind: VertexArrayKind,
|
||||
prim_vao: &'a VAO,
|
||||
clip_vao: &'a VAO,
|
||||
blur_vao: &'a VAO,
|
||||
vaos: &'a RendererVAOs,
|
||||
_: &'a GpuGlyphRenderer)
|
||||
-> &'a VAO {
|
||||
match vertex_array_kind {
|
||||
VertexArrayKind::Primitive => prim_vao,
|
||||
VertexArrayKind::Clip => clip_vao,
|
||||
VertexArrayKind::Blur => blur_vao,
|
||||
VertexArrayKind::Primitive => &vaos.prim_vao,
|
||||
VertexArrayKind::Clip => &vaos.clip_vao,
|
||||
VertexArrayKind::Blur => &vaos.blur_vao,
|
||||
VertexArrayKind::VectorStencil | VertexArrayKind::VectorCover => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use api::{AddFont, BlobImageData, BlobImageResources, ResourceUpdate, ResourceUpdates};
|
||||
use api::{BlobImageDescriptor, BlobImageError, BlobImageRenderer, BlobImageRequest};
|
||||
use api::{ClearCache, ColorF, DevicePoint, DeviceUintRect, DeviceUintSize};
|
||||
use api::{ClearCache, ColorF, DevicePoint, DeviceUintPoint, DeviceUintRect, DeviceUintSize};
|
||||
use api::{Epoch, FontInstanceKey, FontKey, FontTemplate};
|
||||
use api::{ExternalImageData, ExternalImageType};
|
||||
use api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation};
|
||||
@ -482,7 +482,8 @@ impl ResourceCache {
|
||||
data,
|
||||
epoch: Epoch(0),
|
||||
tiling,
|
||||
dirty_rect: None,
|
||||
dirty_rect: Some(DeviceUintRect::new(DeviceUintPoint::zero(),
|
||||
DeviceUintSize::new(descriptor.width, descriptor.height))),
|
||||
};
|
||||
|
||||
self.resources.image_templates.insert(image_key, resource);
|
||||
|
@ -31,7 +31,11 @@ impl SceneProperties {
|
||||
pub fn set_properties(&mut self, properties: DynamicProperties) {
|
||||
self.transform_properties.clear();
|
||||
self.float_properties.clear();
|
||||
self.add_properties(properties);
|
||||
}
|
||||
|
||||
/// Add to the current property list for this display list.
|
||||
pub fn add_properties(&mut self, properties: DynamicProperties) {
|
||||
for property in properties.transforms {
|
||||
self.transform_properties
|
||||
.insert(property.key.id, property.value);
|
||||
|
@ -474,6 +474,15 @@ impl Shaders {
|
||||
gl_type: GlType,
|
||||
options: &RendererOptions,
|
||||
) -> Result<Self, ShaderError> {
|
||||
// needed for the precache fake draws
|
||||
let dummy_vao = if options.precache_shaders {
|
||||
let vao = device.create_custom_vao(&[]);
|
||||
device.bind_custom_vao(&vao);
|
||||
Some(vao)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let brush_solid = BrushShader::new(
|
||||
"brush_solid",
|
||||
device,
|
||||
@ -681,6 +690,10 @@ impl Shaders {
|
||||
options.precache_shaders,
|
||||
)?;
|
||||
|
||||
if let Some(vao) = dummy_vao {
|
||||
device.delete_custom_vao(vao);
|
||||
}
|
||||
|
||||
Ok(Shaders {
|
||||
cs_blur_a8,
|
||||
cs_blur_rgba8,
|
||||
|
@ -18,8 +18,8 @@ bitflags = "1.0"
|
||||
byteorder = "1.2.1"
|
||||
ipc-channel = {version = "0.10.0", optional = true}
|
||||
euclid = { version = "0.17", features = ["serde"] }
|
||||
serde = { version = "=1.0.35", features = ["rc"] }
|
||||
serde_derive = { version = "=1.0.35", features = ["deserialize_in_place"] }
|
||||
serde = { version = "=1.0.37", features = ["rc"] }
|
||||
serde_derive = { version = "=1.0.37", features = ["deserialize_in_place"] }
|
||||
serde_bytes = "0.10"
|
||||
time = "0.1"
|
||||
|
||||
|
@ -324,6 +324,14 @@ impl Transaction {
|
||||
self.frame_ops.push(FrameMsg::UpdateDynamicProperties(properties));
|
||||
}
|
||||
|
||||
/// Add to the list of animated property bindings that should be used to
|
||||
/// resolve bindings in the current display list. This is a convenience method
|
||||
/// so the caller doesn't have to figure out all the dynamic properties before
|
||||
/// setting them on the transaction but can do them incrementally.
|
||||
pub fn append_dynamic_properties(&mut self, properties: DynamicProperties) {
|
||||
self.frame_ops.push(FrameMsg::AppendDynamicProperties(properties));
|
||||
}
|
||||
|
||||
/// Enable copying of the output of this pipeline id to
|
||||
/// an external texture for callers to consume.
|
||||
pub fn enable_frame_output(&mut self, pipeline_id: PipelineId, enable: bool) {
|
||||
@ -486,6 +494,7 @@ pub enum FrameMsg {
|
||||
ScrollNodeWithId(LayoutPoint, ExternalScrollId, ScrollClamping),
|
||||
GetScrollNodeState(MsgSender<Vec<ScrollNodeState>>),
|
||||
UpdateDynamicProperties(DynamicProperties),
|
||||
AppendDynamicProperties(DynamicProperties),
|
||||
}
|
||||
|
||||
impl fmt::Debug for SceneMsg {
|
||||
@ -513,6 +522,7 @@ impl fmt::Debug for FrameMsg {
|
||||
FrameMsg::GetScrollNodeState(..) => "FrameMsg::GetScrollNodeState",
|
||||
FrameMsg::EnableFrameOutput(..) => "FrameMsg::EnableFrameOutput",
|
||||
FrameMsg::UpdateDynamicProperties(..) => "FrameMsg::UpdateDynamicProperties",
|
||||
FrameMsg::AppendDynamicProperties(..) => "FrameMsg::AppendDynamicProperties",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ rayon = "1"
|
||||
thread_profiler = "0.1.1"
|
||||
euclid = { version = "0.17", features = ["serde"] }
|
||||
app_units = "0.6"
|
||||
gleam = "0.4.20"
|
||||
gleam = "0.4.32"
|
||||
log = "0.4"
|
||||
|
||||
[dependencies.webrender]
|
||||
|
@ -1 +1 @@
|
||||
092ada1154b72fe71d2f227a5df0239586d2323a
|
||||
6f997974cec5772b1797725f4a7942d742e7d7ff
|
||||
|
@ -24,7 +24,7 @@ ron = "0.1.5"
|
||||
time = "0.1"
|
||||
crossbeam = "0.2"
|
||||
osmesa-sys = { version = "0.1.2", optional = true }
|
||||
osmesa-src = { git = "https://github.com/servo/osmesa-src", optional = true }
|
||||
osmesa-src = { git = "https://github.com/jrmuizel/osmesa-src", optional = true, branch = "serialize" }
|
||||
webrender = {path = "../webrender", features=["capture","replay","debugger","png","profiler"]}
|
||||
webrender_api = {path = "../webrender_api", features=["serialize","deserialize"]}
|
||||
serde = {version = "1.0", features = ["derive"] }
|
||||
|
@ -197,7 +197,7 @@ impl Wrench {
|
||||
)) as Box<webrender::ApiRecordingReceiver>,
|
||||
});
|
||||
|
||||
let mut debug_flags = DebugFlags::default();
|
||||
let mut debug_flags = DebugFlags::ECHO_DRIVER_MESSAGES;
|
||||
debug_flags.set(DebugFlags::DISABLE_BATCHING, no_batch);
|
||||
let callbacks = Arc::new(Mutex::new(blob::BlobCallbacks::new()));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user