зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1442422 - Update webrender to commit 0da6c839b3a0e165f1115fb9fe286be7540c24ed. r=jrmuizel
MozReview-Commit-ID: DmcL7siJnZ2 --HG-- extra : rebase_source : 62cf0b5cacd771b0c97a4282761fcf0edc3cf3ef
This commit is contained in:
Родитель
6043805daf
Коммит
ff7771db98
|
@ -40,7 +40,7 @@ base64 = { optional = true, version = "0.3.0" }
|
||||||
ron = { optional = true, version = "0.1.7" }
|
ron = { optional = true, version = "0.1.7" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
angle = {git = "https://github.com/servo/angle", branch = "servo"}
|
mozangle = "0.1"
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
rand = "0.3" # for the benchmarks
|
rand = "0.3" # for the benchmarks
|
||||||
glutin = "0.12" # for the example apps
|
glutin = "0.12" # for the example apps
|
||||||
|
|
|
@ -71,7 +71,7 @@ vec4[2] fetch_from_resource_cache_2(int address) {
|
||||||
|
|
||||||
#ifdef WR_VERTEX_SHADER
|
#ifdef WR_VERTEX_SHADER
|
||||||
|
|
||||||
#define VECS_PER_CLIP_SCROLL_NODE 5
|
#define VECS_PER_CLIP_SCROLL_NODE 9
|
||||||
#define VECS_PER_LOCAL_CLIP_RECT 1
|
#define VECS_PER_LOCAL_CLIP_RECT 1
|
||||||
#define VECS_PER_RENDER_TASK 3
|
#define VECS_PER_RENDER_TASK 3
|
||||||
#define VECS_PER_PRIM_HEADER 2
|
#define VECS_PER_PRIM_HEADER 2
|
||||||
|
@ -86,6 +86,16 @@ uniform HIGHP_SAMPLER_FLOAT sampler2D sRenderTasks;
|
||||||
in ivec4 aData0;
|
in ivec4 aData0;
|
||||||
in ivec4 aData1;
|
in ivec4 aData1;
|
||||||
|
|
||||||
|
// Work around Angle bug that forgets to update sampler metadata,
|
||||||
|
// by making the use of those samplers uniform across programs.
|
||||||
|
// https://github.com/servo/webrender/wiki/Driver-issues#texturesize-in-vertex-shaders
|
||||||
|
void markCacheTexturesUsed() {
|
||||||
|
vec2 size = vec2(textureSize(sCacheA8, 0)) + vec2(textureSize(sCacheRGBA8, 0));
|
||||||
|
if (size.x > 1000000.0) {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get_fetch_uv is a macro to work around a macOS Intel driver parsing bug.
|
// get_fetch_uv is a macro to work around a macOS Intel driver parsing bug.
|
||||||
// TODO: convert back to a function once the driver issues are resolved, if ever.
|
// TODO: convert back to a function once the driver issues are resolved, if ever.
|
||||||
// https://github.com/servo/webrender/pull/623
|
// https://github.com/servo/webrender/pull/623
|
||||||
|
@ -154,6 +164,7 @@ vec4 fetch_from_resource_cache_1(int address) {
|
||||||
|
|
||||||
struct ClipScrollNode {
|
struct ClipScrollNode {
|
||||||
mat4 transform;
|
mat4 transform;
|
||||||
|
mat4 inv_transform;
|
||||||
bool is_axis_aligned;
|
bool is_axis_aligned;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,13 +177,19 @@ ClipScrollNode fetch_clip_scroll_node(int index) {
|
||||||
// of OSX.
|
// of OSX.
|
||||||
ivec2 uv = get_fetch_uv(index, VECS_PER_CLIP_SCROLL_NODE);
|
ivec2 uv = get_fetch_uv(index, VECS_PER_CLIP_SCROLL_NODE);
|
||||||
ivec2 uv0 = ivec2(uv.x + 0, uv.y);
|
ivec2 uv0 = ivec2(uv.x + 0, uv.y);
|
||||||
|
ivec2 uv1 = ivec2(uv.x + 8, uv.y);
|
||||||
|
|
||||||
node.transform[0] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(0, 0));
|
node.transform[0] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(0, 0));
|
||||||
node.transform[1] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(1, 0));
|
node.transform[1] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(1, 0));
|
||||||
node.transform[2] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(2, 0));
|
node.transform[2] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(2, 0));
|
||||||
node.transform[3] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(3, 0));
|
node.transform[3] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(3, 0));
|
||||||
|
|
||||||
vec4 misc = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(4, 0));
|
node.inv_transform[0] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(4, 0));
|
||||||
|
node.inv_transform[1] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(5, 0));
|
||||||
|
node.inv_transform[2] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(6, 0));
|
||||||
|
node.inv_transform[3] = TEXEL_FETCH(sClipScrollNodes, uv0, 0, ivec2(7, 0));
|
||||||
|
|
||||||
|
vec4 misc = TEXEL_FETCH(sClipScrollNodes, uv1, 0, ivec2(0, 0));
|
||||||
node.is_axis_aligned = misc.x == 0.0;
|
node.is_axis_aligned = misc.x == 0.0;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
@ -358,6 +375,8 @@ PrimitiveInstance fetch_prim_instance() {
|
||||||
pi.user_data1 = aData1.z;
|
pi.user_data1 = aData1.z;
|
||||||
pi.user_data2 = aData1.w;
|
pi.user_data2 = aData1.w;
|
||||||
|
|
||||||
|
markCacheTexturesUsed();
|
||||||
|
|
||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +404,8 @@ CompositeInstance fetch_composite_instance() {
|
||||||
ci.user_data2 = aData1.z;
|
ci.user_data2 = aData1.z;
|
||||||
ci.user_data3 = aData1.w;
|
ci.user_data3 = aData1.w;
|
||||||
|
|
||||||
|
markCacheTexturesUsed();
|
||||||
|
|
||||||
return ci;
|
return ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,9 +497,8 @@ vec4 get_node_pos(vec2 pos, ClipScrollNode node) {
|
||||||
vec3 a = ah.xyz / ah.w;
|
vec3 a = ah.xyz / ah.w;
|
||||||
|
|
||||||
// get the normal to the scroll node plane
|
// get the normal to the scroll node plane
|
||||||
mat4 inv_transform = inverse(node.transform);
|
vec3 n = transpose(mat3(node.inv_transform)) * vec3(0.0, 0.0, 1.0);
|
||||||
vec3 n = transpose(mat3(inv_transform)) * vec3(0.0, 0.0, 1.0);
|
return untransform(pos, n, a, node.inv_transform);
|
||||||
return untransform(pos, n, a, inv_transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute a snapping offset in world space (adjusted to pixel ratio),
|
// Compute a snapping offset in world space (adjusted to pixel ratio),
|
||||||
|
|
|
@ -245,11 +245,6 @@ impl ClipSources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether or not this ClipSources has any clips (does any clipping).
|
|
||||||
pub fn has_clips(&self) -> bool {
|
|
||||||
!self.clips.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_screen_bounds(
|
pub fn get_screen_bounds(
|
||||||
&self,
|
&self,
|
||||||
transform: &LayerToWorldFastTransform,
|
transform: &LayerToWorldFastTransform,
|
||||||
|
|
|
@ -286,6 +286,14 @@ impl ClipScrollNode {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inv_transform = match self.world_content_transform.inverse() {
|
||||||
|
Some(inverted) => inverted.to_transform(),
|
||||||
|
None => {
|
||||||
|
node_data.push(ClipScrollNodeData::invalid());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let transform_kind = if self.world_content_transform.preserves_2d_axis_alignment() {
|
let transform_kind = if self.world_content_transform.preserves_2d_axis_alignment() {
|
||||||
TransformedRectKind::AxisAligned
|
TransformedRectKind::AxisAligned
|
||||||
} else {
|
} else {
|
||||||
|
@ -293,6 +301,7 @@ impl ClipScrollNode {
|
||||||
};
|
};
|
||||||
let data = ClipScrollNodeData {
|
let data = ClipScrollNodeData {
|
||||||
transform: self.world_content_transform.into(),
|
transform: self.world_content_transform.into(),
|
||||||
|
inv_transform,
|
||||||
transform_kind: transform_kind as u32 as f32,
|
transform_kind: transform_kind as u32 as f32,
|
||||||
padding: [0.0; 3],
|
padding: [0.0; 3],
|
||||||
};
|
};
|
||||||
|
|
|
@ -216,14 +216,13 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
view: &DocumentView,
|
view: &DocumentView,
|
||||||
output_pipelines: &FastHashSet<PipelineId>,
|
output_pipelines: &FastHashSet<PipelineId>,
|
||||||
frame_builder_config: &FrameBuilderConfig,
|
frame_builder_config: &FrameBuilderConfig,
|
||||||
pipeline_epochs: &mut FastHashMap<PipelineId, Epoch>,
|
new_scene: &mut Scene,
|
||||||
) -> FrameBuilder {
|
) -> FrameBuilder {
|
||||||
// We checked that the root pipeline is available on the render backend.
|
// We checked that the root pipeline is available on the render backend.
|
||||||
let root_pipeline_id = scene.root_pipeline_id.unwrap();
|
let root_pipeline_id = scene.root_pipeline_id.unwrap();
|
||||||
let root_pipeline = scene.pipelines.get(&root_pipeline_id).unwrap();
|
let root_pipeline = scene.pipelines.get(&root_pipeline_id).unwrap();
|
||||||
|
|
||||||
let root_epoch = scene.pipeline_epochs[&root_pipeline_id];
|
let root_epoch = scene.pipeline_epochs[&root_pipeline_id];
|
||||||
pipeline_epochs.insert(root_pipeline_id, root_epoch);
|
|
||||||
|
|
||||||
let background_color = root_pipeline
|
let background_color = root_pipeline
|
||||||
.background_color
|
.background_color
|
||||||
|
@ -261,7 +260,11 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
flattener.flatten_root(root_pipeline, &root_pipeline.viewport_size);
|
flattener.flatten_root(root_pipeline, &root_pipeline.viewport_size);
|
||||||
|
|
||||||
debug_assert!(flattener.picture_stack.is_empty());
|
debug_assert!(flattener.picture_stack.is_empty());
|
||||||
pipeline_epochs.extend(flattener.pipeline_epochs.drain(..));
|
|
||||||
|
new_scene.root_pipeline_id = Some(root_pipeline_id);
|
||||||
|
new_scene.pipeline_epochs.insert(root_pipeline_id, root_epoch);
|
||||||
|
new_scene.pipeline_epochs.extend(flattener.pipeline_epochs.drain(..));
|
||||||
|
new_scene.pipelines = scene.pipelines.clone();
|
||||||
|
|
||||||
FrameBuilder::with_display_list_flattener(
|
FrameBuilder::with_display_list_flattener(
|
||||||
view.inner_rect,
|
view.inner_rect,
|
||||||
|
@ -1164,7 +1167,12 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
|
|
||||||
let stacking_context = self.sc_stack.last().expect("bug: no stacking context!");
|
let stacking_context = self.sc_stack.last().expect("bug: no stacking context!");
|
||||||
|
|
||||||
let clip_sources = self.clip_store.insert(ClipSources::new(clip_sources));
|
let clip_sources = if clip_sources.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.clip_store.insert(ClipSources::new(clip_sources)))
|
||||||
|
};
|
||||||
|
|
||||||
let prim_index = self.prim_store.add_primitive(
|
let prim_index = self.prim_store.add_primitive(
|
||||||
&info.rect,
|
&info.rect,
|
||||||
&info.local_clip.clip_rect(),
|
&info.local_clip.clip_rect(),
|
||||||
|
@ -1271,9 +1279,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
// No clip sources needed for the main framebuffer.
|
|
||||||
let clip_sources = self.clip_store.insert(ClipSources::new(Vec::new()));
|
|
||||||
|
|
||||||
// Add root picture primitive. The provided layer rect
|
// Add root picture primitive. The provided layer rect
|
||||||
// is zero, because we don't yet know the size of the
|
// is zero, because we don't yet know the size of the
|
||||||
// picture. Instead, this is calculated recursively
|
// picture. Instead, this is calculated recursively
|
||||||
|
@ -1282,7 +1287,7 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
&LayerRect::zero(),
|
&LayerRect::zero(),
|
||||||
&max_clip,
|
&max_clip,
|
||||||
true,
|
true,
|
||||||
clip_sources,
|
None,
|
||||||
None,
|
None,
|
||||||
PrimitiveContainer::Picture(pic),
|
PrimitiveContainer::Picture(pic),
|
||||||
);
|
);
|
||||||
|
@ -1351,13 +1356,11 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let clip_sources = self.clip_store.insert(ClipSources::new(Vec::new()));
|
|
||||||
|
|
||||||
let prim_index = self.prim_store.add_primitive(
|
let prim_index = self.prim_store.add_primitive(
|
||||||
&LayerRect::zero(),
|
&LayerRect::zero(),
|
||||||
&max_clip,
|
&max_clip,
|
||||||
is_backface_visible,
|
is_backface_visible,
|
||||||
clip_sources,
|
None,
|
||||||
None,
|
None,
|
||||||
PrimitiveContainer::Picture(container),
|
PrimitiveContainer::Picture(container),
|
||||||
);
|
);
|
||||||
|
@ -1402,13 +1405,12 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
current_reference_frame_index,
|
current_reference_frame_index,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let src_clip_sources = self.clip_store.insert(ClipSources::new(Vec::new()));
|
|
||||||
|
|
||||||
let src_prim_index = self.prim_store.add_primitive(
|
let src_prim_index = self.prim_store.add_primitive(
|
||||||
&LayerRect::zero(),
|
&LayerRect::zero(),
|
||||||
&max_clip,
|
&max_clip,
|
||||||
is_backface_visible,
|
is_backface_visible,
|
||||||
src_clip_sources,
|
None,
|
||||||
None,
|
None,
|
||||||
PrimitiveContainer::Picture(src_prim),
|
PrimitiveContainer::Picture(src_prim),
|
||||||
);
|
);
|
||||||
|
@ -1433,13 +1435,12 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
current_reference_frame_index,
|
current_reference_frame_index,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
let src_clip_sources = self.clip_store.insert(ClipSources::new(Vec::new()));
|
|
||||||
|
|
||||||
let src_prim_index = self.prim_store.add_primitive(
|
let src_prim_index = self.prim_store.add_primitive(
|
||||||
&LayerRect::zero(),
|
&LayerRect::zero(),
|
||||||
&max_clip,
|
&max_clip,
|
||||||
is_backface_visible,
|
is_backface_visible,
|
||||||
src_clip_sources,
|
None,
|
||||||
None,
|
None,
|
||||||
PrimitiveContainer::Picture(src_prim),
|
PrimitiveContainer::Picture(src_prim),
|
||||||
);
|
);
|
||||||
|
@ -1487,12 +1488,11 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
frame_output_pipeline_id,
|
frame_output_pipeline_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let sc_clip_sources = self.clip_store.insert(ClipSources::new(Vec::new()));
|
|
||||||
let sc_prim_index = self.prim_store.add_primitive(
|
let sc_prim_index = self.prim_store.add_primitive(
|
||||||
&LayerRect::zero(),
|
&LayerRect::zero(),
|
||||||
&max_clip,
|
&max_clip,
|
||||||
is_backface_visible,
|
is_backface_visible,
|
||||||
sc_clip_sources,
|
None,
|
||||||
None,
|
None,
|
||||||
PrimitiveContainer::Picture(sc_prim),
|
PrimitiveContainer::Picture(sc_prim),
|
||||||
);
|
);
|
||||||
|
@ -1646,8 +1646,6 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
) -> ClipScrollNodeIndex {
|
) -> ClipScrollNodeIndex {
|
||||||
let clip_rect = clip_region.main;
|
let clip_rect = clip_region.main;
|
||||||
let clip_sources = ClipSources::from(clip_region);
|
let clip_sources = ClipSources::from(clip_region);
|
||||||
|
|
||||||
debug_assert!(clip_sources.has_clips());
|
|
||||||
let handle = self.clip_store.insert(clip_sources);
|
let handle = self.clip_store.insert(clip_sources);
|
||||||
|
|
||||||
let node_index = self.id_to_index_mapper.get_node_index(new_node_id);
|
let node_index = self.id_to_index_mapper.get_node_index(new_node_id);
|
||||||
|
@ -2621,10 +2619,9 @@ impl<'a> DisplayListFlattener<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_scene(config: &FrameBuilderConfig, request: SceneRequest) -> BuiltScene {
|
pub fn build_scene(config: &FrameBuilderConfig, request: SceneRequest) -> BuiltScene {
|
||||||
// TODO: mutably pass the scene and update its own pipeline epoch map instead of
|
|
||||||
// creating a new one here.
|
|
||||||
let mut pipeline_epoch_map = FastHashMap::default();
|
|
||||||
let mut clip_scroll_tree = ClipScrollTree::new();
|
let mut clip_scroll_tree = ClipScrollTree::new();
|
||||||
|
let mut new_scene = Scene::new();
|
||||||
|
|
||||||
let frame_builder = DisplayListFlattener::create_frame_builder(
|
let frame_builder = DisplayListFlattener::create_frame_builder(
|
||||||
FrameBuilder::empty(), // WIP, we're not really recycling anything here, clean this up.
|
FrameBuilder::empty(), // WIP, we're not really recycling anything here, clean this up.
|
||||||
|
@ -2635,14 +2632,11 @@ pub fn build_scene(config: &FrameBuilderConfig, request: SceneRequest) -> BuiltS
|
||||||
&request.view,
|
&request.view,
|
||||||
&request.output_pipelines,
|
&request.output_pipelines,
|
||||||
config,
|
config,
|
||||||
&mut pipeline_epoch_map
|
&mut new_scene
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut scene = request.scene;
|
|
||||||
scene.pipeline_epochs = pipeline_epoch_map;
|
|
||||||
|
|
||||||
BuiltScene {
|
BuiltScene {
|
||||||
scene,
|
scene: new_scene,
|
||||||
frame_builder,
|
frame_builder,
|
||||||
clip_scroll_tree,
|
clip_scroll_tree,
|
||||||
removed_pipelines: request.removed_pipelines,
|
removed_pipelines: request.removed_pipelines,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use api::{DevicePoint, LayerToWorldTransform, PremultipliedColorF};
|
use api::{DevicePoint, LayerToWorldTransform, PremultipliedColorF, WorldToLayerTransform};
|
||||||
use gpu_cache::{GpuCacheAddress, GpuDataRequest};
|
use gpu_cache::{GpuCacheAddress, GpuDataRequest};
|
||||||
use prim_store::EdgeAaSegmentMask;
|
use prim_store::EdgeAaSegmentMask;
|
||||||
use render_task::RenderTaskAddress;
|
use render_task::RenderTaskAddress;
|
||||||
|
@ -217,6 +217,7 @@ pub struct ClipScrollNodeIndex(pub u32);
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ClipScrollNodeData {
|
pub struct ClipScrollNodeData {
|
||||||
pub transform: LayerToWorldTransform,
|
pub transform: LayerToWorldTransform,
|
||||||
|
pub inv_transform: WorldToLayerTransform,
|
||||||
pub transform_kind: f32,
|
pub transform_kind: f32,
|
||||||
pub padding: [f32; 3],
|
pub padding: [f32; 3],
|
||||||
}
|
}
|
||||||
|
@ -225,6 +226,7 @@ impl ClipScrollNodeData {
|
||||||
pub fn invalid() -> Self {
|
pub fn invalid() -> Self {
|
||||||
ClipScrollNodeData {
|
ClipScrollNodeData {
|
||||||
transform: LayerToWorldTransform::identity(),
|
transform: LayerToWorldTransform::identity(),
|
||||||
|
inv_transform: WorldToLayerTransform::identity(),
|
||||||
transform_kind: 0.0,
|
transform_kind: 0.0,
|
||||||
padding: [0.0; 3],
|
padding: [0.0; 3],
|
||||||
}
|
}
|
||||||
|
@ -273,4 +275,4 @@ impl ImageSource {
|
||||||
]);
|
]);
|
||||||
request.push(self.color);
|
request.push(self.color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use api::{BoxShadowClipMode, ColorF, DeviceIntPoint, DeviceIntRect, FilterOp, LayerPoint};
|
use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceSize};
|
||||||
use api::{LayerRect, LayerToWorldScale, LayerVector2D, MixBlendMode, PipelineId};
|
use api::{LayerPoint, LayerRect, LayerToWorldScale, LayerVector2D};
|
||||||
|
use api::{BoxShadowClipMode, ColorF, FilterOp, MixBlendMode, PipelineId};
|
||||||
use api::{PremultipliedColorF, Shadow};
|
use api::{PremultipliedColorF, Shadow};
|
||||||
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowCacheKey};
|
use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowCacheKey};
|
||||||
use clip_scroll_tree::ClipScrollNodeIndex;
|
use clip_scroll_tree::ClipScrollNodeIndex;
|
||||||
|
@ -18,6 +19,21 @@ use resource_cache::CacheItem;
|
||||||
use scene::{FilterOpHelpers, SceneProperties};
|
use scene::{FilterOpHelpers, SceneProperties};
|
||||||
use tiling::RenderTargetKind;
|
use tiling::RenderTargetKind;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO(gw): Rounding the content rect here to device pixels is not
|
||||||
|
// technically correct. Ideally we should ceil() here, and ensure that
|
||||||
|
// the extra part pixel in the case of fractional sizes is correctly
|
||||||
|
// handled. For now, just use rounding which passes the existing
|
||||||
|
// Gecko tests.
|
||||||
|
// Note: zero-square tasks are prohibited in WR task tree, so
|
||||||
|
// we ensure each dimension to be at least the length of 1 after rounding.
|
||||||
|
fn to_cache_size(size: DeviceSize) -> DeviceIntSize {
|
||||||
|
DeviceIntSize::new(
|
||||||
|
1.max(size.width.round() as i32),
|
||||||
|
1.max(size.height.round() as i32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A picture represents a dynamically rendered image. It consists of:
|
A picture represents a dynamically rendered image. It consists of:
|
||||||
|
|
||||||
|
@ -474,13 +490,7 @@ impl PicturePrimitive {
|
||||||
// render the text run to a target, and then apply a gaussian
|
// render the text run to a target, and then apply a gaussian
|
||||||
// blur to that text run in order to build the actual primitive
|
// blur to that text run in order to build the actual primitive
|
||||||
// which will be blitted to the framebuffer.
|
// which will be blitted to the framebuffer.
|
||||||
|
let cache_size = to_cache_size(content_rect.size * content_scale);
|
||||||
// TODO(gw): Rounding the content rect here to device pixels is not
|
|
||||||
// technically correct. Ideally we should ceil() here, and ensure that
|
|
||||||
// the extra part pixel in the case of fractional sizes is correctly
|
|
||||||
// handled. For now, just use rounding which passes the existing
|
|
||||||
// Gecko tests.
|
|
||||||
let cache_size = (content_rect.size * content_scale).round().to_i32();
|
|
||||||
|
|
||||||
// Quote from https://drafts.csswg.org/css-backgrounds-3/#shadow-blur
|
// Quote from https://drafts.csswg.org/css-backgrounds-3/#shadow-blur
|
||||||
// "the image that would be generated by applying to the shadow a
|
// "the image that would be generated by applying to the shadow a
|
||||||
|
@ -520,7 +530,7 @@ impl PicturePrimitive {
|
||||||
// the extra part pixel in the case of fractional sizes is correctly
|
// the extra part pixel in the case of fractional sizes is correctly
|
||||||
// handled. For now, just use rounding which passes the existing
|
// handled. For now, just use rounding which passes the existing
|
||||||
// Gecko tests.
|
// Gecko tests.
|
||||||
let cache_size = (content_rect.size * content_scale).round().to_i32();
|
let cache_size = to_cache_size(content_rect.size * content_scale);
|
||||||
|
|
||||||
// Request the texture cache item for this box-shadow key. If it
|
// Request the texture cache item for this box-shadow key. If it
|
||||||
// doesn't exist in the cache, the closure is invoked to build
|
// doesn't exist in the cache, the closure is invoked to build
|
||||||
|
|
|
@ -168,7 +168,7 @@ pub struct ScreenRect {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PrimitiveMetadata {
|
pub struct PrimitiveMetadata {
|
||||||
pub opacity: PrimitiveOpacity,
|
pub opacity: PrimitiveOpacity,
|
||||||
pub clip_sources: ClipSourcesHandle,
|
pub clip_sources: Option<ClipSourcesHandle>,
|
||||||
pub prim_kind: PrimitiveKind,
|
pub prim_kind: PrimitiveKind,
|
||||||
pub cpu_prim_index: SpecificPrimitiveIndex,
|
pub cpu_prim_index: SpecificPrimitiveIndex,
|
||||||
pub gpu_location: GpuCacheHandle,
|
pub gpu_location: GpuCacheHandle,
|
||||||
|
@ -964,7 +964,7 @@ impl PrimitiveStore {
|
||||||
local_rect: &LayerRect,
|
local_rect: &LayerRect,
|
||||||
local_clip_rect: &LayerRect,
|
local_clip_rect: &LayerRect,
|
||||||
is_backface_visible: bool,
|
is_backface_visible: bool,
|
||||||
clip_sources: ClipSourcesHandle,
|
clip_sources: Option<ClipSourcesHandle>,
|
||||||
tag: Option<ItemTag>,
|
tag: Option<ItemTag>,
|
||||||
container: PrimitiveContainer,
|
container: PrimitiveContainer,
|
||||||
) -> PrimitiveIndex {
|
) -> PrimitiveIndex {
|
||||||
|
@ -1570,8 +1570,8 @@ impl PrimitiveStore {
|
||||||
let transform = &prim_run_context.scroll_node.world_content_transform;
|
let transform = &prim_run_context.scroll_node.world_content_transform;
|
||||||
let extra_clip = {
|
let extra_clip = {
|
||||||
let metadata = &self.cpu_metadata[prim_index.0];
|
let metadata = &self.cpu_metadata[prim_index.0];
|
||||||
let prim_clips = frame_state.clip_store.get_mut(&metadata.clip_sources);
|
metadata.clip_sources.as_ref().map(|ref clip_sources| {
|
||||||
if prim_clips.has_clips() {
|
let prim_clips = frame_state.clip_store.get_mut(clip_sources);
|
||||||
prim_clips.update(
|
prim_clips.update(
|
||||||
frame_state.gpu_cache,
|
frame_state.gpu_cache,
|
||||||
frame_state.resource_cache,
|
frame_state.resource_cache,
|
||||||
|
@ -1583,10 +1583,10 @@ impl PrimitiveStore {
|
||||||
combined_outer_rect = combined_outer_rect.and_then(|r| r.intersection(&outer));
|
combined_outer_rect = combined_outer_rect.and_then(|r| r.intersection(&outer));
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Arc::new(ClipChainNode {
|
Arc::new(ClipChainNode {
|
||||||
work_item: ClipWorkItem {
|
work_item: ClipWorkItem {
|
||||||
scroll_node_data_index: prim_run_context.scroll_node.node_data_index,
|
scroll_node_data_index: prim_run_context.scroll_node.node_data_index,
|
||||||
clip_sources: metadata.clip_sources.weak(),
|
clip_sources: clip_sources.weak(),
|
||||||
coordinate_system_id: prim_coordinate_system_id,
|
coordinate_system_id: prim_coordinate_system_id,
|
||||||
},
|
},
|
||||||
// The local_clip_rect a property of ClipChain nodes that are ClipScrollNodes.
|
// The local_clip_rect a property of ClipChain nodes that are ClipScrollNodes.
|
||||||
|
@ -1597,10 +1597,8 @@ impl PrimitiveStore {
|
||||||
screen_inner_rect,
|
screen_inner_rect,
|
||||||
screen_outer_rect: screen_outer_rect.unwrap_or(prim_screen_rect),
|
screen_outer_rect: screen_outer_rect.unwrap_or(prim_screen_rect),
|
||||||
prev: None,
|
prev: None,
|
||||||
}))
|
})
|
||||||
} else {
|
})
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// If everything is clipped out, then we don't need to render this primitive.
|
// If everything is clipped out, then we don't need to render this primitive.
|
||||||
|
|
|
@ -172,13 +172,49 @@ impl Document {
|
||||||
|
|
||||||
// TODO: We will probably get rid of this soon and always forward to the scene building thread.
|
// TODO: We will probably get rid of this soon and always forward to the scene building thread.
|
||||||
fn build_scene(&mut self, resource_cache: &mut ResourceCache) {
|
fn build_scene(&mut self, resource_cache: &mut ResourceCache) {
|
||||||
let frame_builder = self.create_frame_builder(resource_cache);
|
|
||||||
|
if self.view.window_size.width == 0 || self.view.window_size.height == 0 {
|
||||||
|
error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
|
||||||
|
}
|
||||||
|
|
||||||
|
let old_builder = self.frame_builder.take().unwrap_or_else(FrameBuilder::empty);
|
||||||
|
let root_pipeline_id = match self.pending.scene.root_pipeline_id {
|
||||||
|
Some(root_pipeline_id) => root_pipeline_id,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !self.pending.scene.pipelines.contains_key(&root_pipeline_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The DisplayListFlattener will re-create the up-to-date current scene's pipeline epoch
|
||||||
|
// map and clip scroll tree from the information in the pending scene.
|
||||||
|
self.current.scene.pipeline_epochs.clear();
|
||||||
|
let old_scrolling_states = self.clip_scroll_tree.drain();
|
||||||
|
|
||||||
|
let frame_builder = DisplayListFlattener::create_frame_builder(
|
||||||
|
old_builder,
|
||||||
|
&self.pending.scene,
|
||||||
|
&mut self.clip_scroll_tree,
|
||||||
|
resource_cache.get_font_instances(),
|
||||||
|
resource_cache.get_tiled_image_map(),
|
||||||
|
&self.view,
|
||||||
|
&self.output_pipelines,
|
||||||
|
&self.frame_builder_config,
|
||||||
|
&mut self.current.scene,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
|
||||||
|
|
||||||
if !self.current.removed_pipelines.is_empty() {
|
if !self.current.removed_pipelines.is_empty() {
|
||||||
warn!("Built the scene several times without rendering it.");
|
warn!("Built the scene several times without rendering it.");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current.removed_pipelines.extend(self.pending.removed_pipelines.drain(..));
|
self.current.removed_pipelines.extend(self.pending.removed_pipelines.drain(..));
|
||||||
self.frame_builder = Some(frame_builder);
|
self.frame_builder = Some(frame_builder);
|
||||||
self.current.scene = self.pending.scene.clone();
|
|
||||||
|
// Advance to the next frame.
|
||||||
|
self.frame_id.0 += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forward_transaction_to_scene_builder(
|
fn forward_transaction_to_scene_builder(
|
||||||
|
@ -312,48 +348,6 @@ impl Document {
|
||||||
// Advance to the next frame.
|
// Advance to the next frame.
|
||||||
self.frame_id.0 += 1;
|
self.frame_id.0 += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When changing this, please make the same modification to build_scene,
|
|
||||||
// which will soon replace this method completely.
|
|
||||||
pub fn create_frame_builder(&mut self, resource_cache: &mut ResourceCache) -> FrameBuilder {
|
|
||||||
if self.view.window_size.width == 0 || self.view.window_size.height == 0 {
|
|
||||||
error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
|
|
||||||
}
|
|
||||||
|
|
||||||
let old_builder = self.frame_builder.take().unwrap_or_else(FrameBuilder::empty);
|
|
||||||
let root_pipeline_id = match self.pending.scene.root_pipeline_id {
|
|
||||||
Some(root_pipeline_id) => root_pipeline_id,
|
|
||||||
None => return old_builder,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !self.pending.scene.pipelines.contains_key(&root_pipeline_id) {
|
|
||||||
return old_builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The DisplayListFlattener will re-create the up-to-date current scene's pipeline epoch
|
|
||||||
// map and clip scroll tree from the information in the pending scene.
|
|
||||||
self.current.scene.pipeline_epochs.clear();
|
|
||||||
let old_scrolling_states = self.clip_scroll_tree.drain();
|
|
||||||
|
|
||||||
let frame_builder = DisplayListFlattener::create_frame_builder(
|
|
||||||
old_builder,
|
|
||||||
&self.pending.scene,
|
|
||||||
&mut self.clip_scroll_tree,
|
|
||||||
resource_cache.get_font_instances(),
|
|
||||||
resource_cache.get_tiled_image_map(),
|
|
||||||
&self.view,
|
|
||||||
&self.output_pipelines,
|
|
||||||
&self.frame_builder_config,
|
|
||||||
&mut self.current.scene.pipeline_epochs,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
|
|
||||||
|
|
||||||
// Advance to the next frame.
|
|
||||||
self.frame_id.0 += 1;
|
|
||||||
|
|
||||||
frame_builder
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DocumentOps {
|
struct DocumentOps {
|
||||||
|
@ -1149,10 +1143,15 @@ impl RenderBackend {
|
||||||
bits: CaptureBits,
|
bits: CaptureBits,
|
||||||
profile_counters: &mut BackendProfileCounters,
|
profile_counters: &mut BackendProfileCounters,
|
||||||
) -> DebugOutput {
|
) -> DebugOutput {
|
||||||
|
use std::fs;
|
||||||
use capture::CaptureConfig;
|
use capture::CaptureConfig;
|
||||||
|
|
||||||
debug!("capture: saving {:?}", root);
|
debug!("capture: saving {:?}", root);
|
||||||
let (resources, deferred) = self.resource_cache.save_capture(&root);
|
if !root.is_dir() {
|
||||||
|
if let Err(e) = fs::create_dir_all(&root) {
|
||||||
|
panic!("Unable to create capture dir: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
let config = CaptureConfig::new(root, bits);
|
let config = CaptureConfig::new(root, bits);
|
||||||
|
|
||||||
for (&id, doc) in &mut self.documents {
|
for (&id, doc) in &mut self.documents {
|
||||||
|
@ -1175,6 +1174,9 @@ impl RenderBackend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!("\tresource cache");
|
||||||
|
let (resources, deferred) = self.resource_cache.save_capture(&config.root);
|
||||||
|
|
||||||
info!("\tbackend");
|
info!("\tbackend");
|
||||||
let backend = PlainRenderBackend {
|
let backend = PlainRenderBackend {
|
||||||
default_device_pixel_ratio: self.default_device_pixel_ratio,
|
default_device_pixel_ratio: self.default_device_pixel_ratio,
|
||||||
|
|
|
@ -1060,9 +1060,6 @@ impl ResourceCache {
|
||||||
|
|
||||||
info!("saving resource cache");
|
info!("saving resource cache");
|
||||||
let res = &self.resources;
|
let res = &self.resources;
|
||||||
if !root.is_dir() {
|
|
||||||
fs::create_dir_all(root).unwrap()
|
|
||||||
}
|
|
||||||
let path_fonts = root.join("fonts");
|
let path_fonts = root.join("fonts");
|
||||||
if !path_fonts.is_dir() {
|
if !path_fonts.is_dir() {
|
||||||
fs::create_dir(&path_fonts).unwrap();
|
fs::create_dir(&path_fonts).unwrap();
|
||||||
|
|
|
@ -146,6 +146,7 @@ impl Scene {
|
||||||
self.root_pipeline_id = None;
|
self.root_pipeline_id = None;
|
||||||
}
|
}
|
||||||
self.pipelines.remove(&pipeline_id);
|
self.pipelines.remove(&pipeline_id);
|
||||||
|
self.pipeline_epochs.remove(&pipeline_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_epoch(&mut self, pipeline_id: PipelineId, epoch: Epoch) {
|
pub fn update_epoch(&mut self, pipeline_id: PipelineId, epoch: Epoch) {
|
||||||
|
|
|
@ -401,7 +401,7 @@ impl<Src, Dst> FastTransform<Src, Dst> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&FastTransform::Offset(ref offset), &FastTransform::Offset(ref other_offset)) => {
|
(&FastTransform::Offset(ref offset), &FastTransform::Offset(ref other_offset)) => {
|
||||||
let offset = TypedVector2D::from_untyped(&offset.to_untyped());
|
let offset = TypedVector2D::from_untyped(&offset.to_untyped());
|
||||||
FastTransform::Offset((offset + *other_offset))
|
FastTransform::Offset(offset + *other_offset)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let new_transform = self.to_transform().pre_mul(&other.to_transform());
|
let new_transform = self.to_transform().pre_mul(&other.to_transform());
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
extern crate angle;
|
extern crate mozangle;
|
||||||
extern crate webrender;
|
extern crate webrender;
|
||||||
|
|
||||||
use angle::hl::{BuiltInResources, Output, ShaderSpec, ShaderValidator};
|
use mozangle::shaders::{BuiltInResources, Output, ShaderSpec, ShaderValidator};
|
||||||
|
|
||||||
// from glslang
|
// from glslang
|
||||||
const FRAGMENT_SHADER: u32 = 0x8B30;
|
const FRAGMENT_SHADER: u32 = 0x8B30;
|
||||||
|
@ -113,7 +113,7 @@ const VERSION_STRING: &str = "#version 300 es\n";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_shaders() {
|
fn validate_shaders() {
|
||||||
angle::hl::initialize().unwrap();
|
mozangle::shaders::initialize().unwrap();
|
||||||
|
|
||||||
let resources = BuiltInResources::default();
|
let resources = BuiltInResources::default();
|
||||||
let vs_validator =
|
let vs_validator =
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
22b831c02479eea31821f49a0fac7dd699083557
|
0da6c839b3a0e165f1115fb9fe286be7540c24ed
|
||||||
|
|
Загрузка…
Ссылка в новой задаче