Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trim the render work done after a scene build #2936

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -4,9 +4,7 @@

use api::DevicePixelScale;
use clip::{ClipChain, ClipChainNode, ClipSourcesIndex, ClipStore, ClipWorkItem};
use clip_scroll_tree::{ClipChainIndex};
use gpu_cache::GpuCache;
use resource_cache::ResourceCache;
use clip_scroll_tree::{ClipChainIndex, ClipRenderContext};
use spatial_node::SpatialNode;

#[derive(Debug)]
@@ -32,13 +30,16 @@ impl ClipNode {
&mut self,
device_pixel_scale: DevicePixelScale,
clip_store: &mut ClipStore,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
render_context: &mut Option<ClipRenderContext>,
clip_chains: &mut [ClipChain],
spatial_nodes: &[SpatialNode],
) {
let clip_sources = clip_store.get_mut(self.clip_sources_index);
clip_sources.update(gpu_cache, resource_cache, device_pixel_scale);
if let &mut Some(ref mut context) = render_context {
clip_sources.update(context.gpu_cache,
context.resource_cache,
device_pixel_scale);
}
let spatial_node = &spatial_nodes[clip_sources.spatial_node_index.0];

let (screen_inner_rect, screen_outer_rect) = clip_sources.get_screen_bounds(
@@ -66,6 +66,11 @@ impl ClipChainIndex {
pub const NO_CLIP: Self = ClipChainIndex(0);
}

pub struct ClipRenderContext<'a> {
pub resource_cache: &'a mut ResourceCache,
pub gpu_cache: &'a mut GpuCache,
}

pub struct ClipScrollTree {
/// Nodes which determine the positions (offsets and transforms) for primitives
/// and clips.
@@ -223,12 +228,15 @@ impl ClipScrollTree {
screen_rect: &DeviceIntRect,
device_pixel_scale: DevicePixelScale,
clip_store: &mut ClipStore,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
render_context: &mut Option<ClipRenderContext>,
pan: WorldPoint,
scene_properties: &SceneProperties,
) -> TransformPalette {
let mut transform_palette = TransformPalette::new(self.spatial_nodes.len());
) -> Option<TransformPalette> {
let mut transform_palette = if render_context.is_some() {
Some(TransformPalette::new(self.spatial_nodes.len()))
} else {
None
};
if self.spatial_nodes.is_empty() {
return transform_palette;
}
@@ -259,8 +267,7 @@ impl ClipScrollTree {
clip_node.update(
device_pixel_scale,
clip_store,
resource_cache,
gpu_cache,
render_context,
&mut self.clip_chains,
&self.spatial_nodes,
);
@@ -275,7 +282,7 @@ impl ClipScrollTree {
node_index: SpatialNodeIndex,
state: &mut TransformUpdateState,
next_coordinate_system_id: &mut CoordinateSystemId,
transform_palette: &mut TransformPalette,
transform_palette: &mut Option<TransformPalette>,
scene_properties: &SceneProperties,
) {
// TODO(gw): This is an ugly borrow check workaround to clone these.
@@ -288,7 +295,9 @@ impl ClipScrollTree {
};

node.update(&mut state, next_coordinate_system_id, scene_properties);
node.push_gpu_data(transform_palette, node_index);
if let &mut Some(ref mut palette) = transform_palette {
node.push_gpu_data(palette, node_index);
}

if node.children.is_empty() {
return;
@@ -6,7 +6,7 @@ use api::{BuiltDisplayList, ColorF, DeviceIntPoint, DeviceIntRect, DevicePixelSc
use api::{DeviceUintPoint, DeviceUintRect, DeviceUintSize, DocumentLayer, FontRenderMode};
use api::{LayoutPoint, LayoutRect, LayoutSize, PipelineId, WorldPoint};
use clip::{ClipChain, ClipStore};
use clip_scroll_tree::{ClipScrollTree, SpatialNodeIndex};
use clip_scroll_tree::{ClipRenderContext, ClipScrollTree, SpatialNodeIndex};
use display_list_flattener::{DisplayListFlattener};
use gpu_cache::GpuCache;
use gpu_types::{PrimitiveHeaders, TransformPalette, UvRectKind};
@@ -302,6 +302,24 @@ impl FrameBuilder {
}
}

pub fn update_clip_scroll_tree(
&mut self,
clip_render_context: &mut Option<ClipRenderContext>,
clip_scroll_tree: &mut ClipScrollTree,
device_pixel_scale: DevicePixelScale,
pan: WorldPoint,
scene_properties: &SceneProperties,
) -> Option<TransformPalette> {
clip_scroll_tree.update_tree(
&self.screen_rect.to_i32(),
device_pixel_scale,
&mut self.clip_store,
clip_render_context,
pan,
scene_properties,
)
}

pub fn build(
&mut self,
resource_cache: &mut ResourceCache,
@@ -330,15 +348,19 @@ impl FrameBuilder {
resource_cache.begin_frame(frame_id);
gpu_cache.begin_frame();

let transform_palette = clip_scroll_tree.update_tree(
&self.screen_rect.to_i32(),
device_pixel_scale,
&mut self.clip_store,
resource_cache,
gpu_cache,
pan,
scene_properties,
);
let transform_palette = {
let clip_render_context = ClipRenderContext {
resource_cache,
gpu_cache,
};
self.update_clip_scroll_tree(
&mut Some(clip_render_context),
clip_scroll_tree,
device_pixel_scale,
pan,
scene_properties
)
}.expect("Must get a palette since we provided a render context");

self.update_scroll_bars(clip_scroll_tree, gpu_cache);

@@ -359,6 +359,22 @@ impl Document {
}).unwrap();
}

fn rebuild_hit_tester(&mut self) {
let accumulated_scale_factor = self.view.accumulated_scale_factor();
let pan = self.view.pan.to_f32() / accumulated_scale_factor;

let frame_builder = self.frame_builder.as_mut().unwrap();
let palette = frame_builder.update_clip_scroll_tree(
&mut None,
&mut self.clip_scroll_tree,
accumulated_scale_factor,
pan,
&self.dynamic_properties,
);
debug_assert!(!palette.is_some());
self.hit_tester = Some(frame_builder.create_hit_tester(&self.clip_scroll_tree));
}

fn render(
&mut self,
resource_cache: &mut ResourceCache,
@@ -448,6 +464,7 @@ impl Document {
struct DocumentOps {
scroll: bool,
build: bool,
rebuild_hit_tester: bool,
render: bool,
composite: bool,
}
@@ -457,6 +474,7 @@ impl DocumentOps {
DocumentOps {
scroll: false,
build: false,
rebuild_hit_tester: false,
render: false,
composite: false,
}
@@ -469,16 +487,17 @@ impl DocumentOps {
}
}

fn render() -> Self {
fn rebuild_hit_tester() -> Self {
DocumentOps {
render: true,
rebuild_hit_tester: true,
..DocumentOps::nop()
}
}

fn combine(&mut self, other: Self) {
self.scroll = self.scroll || other.scroll;
self.build = self.build || other.build;
self.rebuild_hit_tester = self.rebuild_hit_tester || other.rebuild_hit_tester;
self.render = self.render || other.render;
self.composite = self.composite || other.composite;
}
@@ -730,9 +749,8 @@ impl RenderBackend {
if let Some(mut built_scene) = built_scene.take() {
doc.new_async_scene_ready(built_scene);
// After applying the new scene we need to
// rebuild the hit-tester, so we trigger a render
// step.
ops = DocumentOps::render();
// rebuild the hit-tester.
ops = DocumentOps::rebuild_hit_tester();
}
if let Some(tx) = result_tx {
let (resume_tx, resume_rx) = channel();
@@ -766,7 +784,7 @@ impl RenderBackend {
self.resource_cache.set_blob_rasterizer(rasterizer);
}

if !transaction_msg.is_empty() || ops.render {
if !transaction_msg.is_empty() || ops.rebuild_hit_tester {
self.update_document(
document_id,
transaction_msg,
@@ -1061,7 +1079,7 @@ impl RenderBackend {
// fiddle with things after a potentially long scene build, but just
// before rendering. This is useful for rendering with the latest
// async transforms.
if op.render || transaction_msg.generate_frame {
if op.render || op.rebuild_hit_tester || transaction_msg.generate_frame {
if let Some(ref sampler) = self.sampler {
transaction_msg.frame_ops.append(&mut sampler.sample());
}
@@ -1148,6 +1166,8 @@ impl RenderBackend {
// new_frame_ready callback below) has the right flags.
let msg = ResultMsg::PublishPipelineInfo(doc.updated_pipeline_info());
self.result_tx.send(msg).unwrap();
} else if op.rebuild_hit_tester {
doc.rebuild_hit_tester();
}

if transaction_msg.generate_frame {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.