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

Support overscroll for browser.html prototyping. #951

Merged
merged 1 commit into from Mar 3, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -93,7 +93,8 @@ fn main() {
.. Default::default()
};

let (mut renderer, sender) = webrender::renderer::Renderer::new(opts).unwrap();
let size = DeviceUintSize::new(width, height);
let (mut renderer, sender) = webrender::renderer::Renderer::new(opts, size).unwrap();
let api = sender.create_api();

let notifier = Box::new(Notifier::new(window.create_window_proxy()));
@@ -37,6 +37,10 @@ pub struct ClipScrollNode {
/// Viewing rectangle in the coordinate system of the parent reference frame.
pub local_viewport_rect: LayerRect,

/// Clip rect of this node - typically the same as viewport rect, except
/// in overscroll cases.
pub local_clip_rect: LayerRect,

/// Viewport rectangle clipped against parent layer(s) viewport rectangles.
/// This is in the coordinate system of the parent reference frame.
pub combined_local_viewport_rect: LayerRect,
@@ -61,14 +65,16 @@ pub struct ClipScrollNode {

impl ClipScrollNode {
pub fn new(local_viewport_rect: &LayerRect,
local_clip_rect: &LayerRect,
content_size: LayerSize,
pipeline_id: PipelineId)
-> ClipScrollNode {
ClipScrollNode {
scrolling: ScrollingState::new(),
content_size: content_size,
local_viewport_rect: *local_viewport_rect,
combined_local_viewport_rect: *local_viewport_rect,
local_clip_rect: *local_clip_rect,
combined_local_viewport_rect: *local_clip_rect,
world_viewport_transform: LayerToWorldTransform::identity(),
world_content_transform: LayerToWorldTransform::identity(),
children: Vec::new(),
@@ -78,6 +84,7 @@ impl ClipScrollNode {
}

pub fn new_reference_frame(local_viewport_rect: &LayerRect,
local_clip_rect: &LayerRect,
content_size: LayerSize,
local_transform: &LayerToScrollTransform,
pipeline_id: PipelineId)
@@ -86,7 +93,8 @@ impl ClipScrollNode {
scrolling: ScrollingState::new(),
content_size: content_size,
local_viewport_rect: *local_viewport_rect,
combined_local_viewport_rect: *local_viewport_rect,
local_clip_rect: *local_clip_rect,
combined_local_viewport_rect: *local_clip_rect,
world_viewport_transform: LayerToWorldTransform::identity(),
world_content_transform: LayerToWorldTransform::identity(),
children: Vec::new(),
@@ -177,7 +185,7 @@ impl ClipScrollNode {
// we do the intersection and get our combined viewport rect in the coordinate system
// starting from our origin.
self.combined_local_viewport_rect =
parent_combined_viewport_in_local_space.intersection(&self.local_viewport_rect)
parent_combined_viewport_in_local_space.intersection(&self.local_clip_rect)
.unwrap_or(LayerRect::zero());

// The transformation for this viewport in world coordinates is the transformation for
@@ -70,21 +70,25 @@ impl ClipScrollTree {
pub fn establish_root(&mut self,
pipeline_id: PipelineId,
viewport_size: &LayerSize,
viewport_offset: LayerPoint,
clip_size: LayerSize,
content_size: &LayerSize) {
debug_assert!(self.nodes.is_empty());

let identity = LayerToScrollTransform::identity();
let transform = LayerToScrollTransform::create_translation(viewport_offset.x, viewport_offset.y, 0.0);
let viewport = LayerRect::new(LayerPoint::zero(), *viewport_size);

let clip = LayerRect::new(LayerPoint::new(-viewport_offset.x, -viewport_offset.y),
LayerSize::new(clip_size.width, clip_size.height));
let root_reference_frame_id = ScrollLayerId::root_reference_frame(pipeline_id);
self.root_reference_frame_id = root_reference_frame_id;
let reference_frame = ClipScrollNode::new_reference_frame(&viewport,
&clip,
viewport.size,
&identity,
&transform,
pipeline_id);
self.nodes.insert(self.root_reference_frame_id, reference_frame);

let scroll_node = ClipScrollNode::new(&viewport, *content_size, pipeline_id);
let scroll_node = ClipScrollNode::new(&viewport, &clip, *content_size, pipeline_id);
let topmost_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id);
self.topmost_scroll_layer_id = topmost_scroll_layer_id;
self.add_node(scroll_node, topmost_scroll_layer_id, root_reference_frame_id);
@@ -297,7 +301,7 @@ impl ClipScrollTree {
}

let root_reference_frame_id = self.root_reference_frame_id();
let root_viewport = self.nodes[&root_reference_frame_id].local_viewport_rect;
let root_viewport = self.nodes[&root_reference_frame_id].local_clip_rect;
self.update_node_transform(root_reference_frame_id,
&LayerToWorldTransform::identity(),
&as_scroll_parent_rect(&root_viewport),
@@ -391,7 +395,7 @@ impl ClipScrollTree {
};
self.current_reference_frame_id += 1;

let node = ClipScrollNode::new_reference_frame(&rect, rect.size, &transform, pipeline_id);
let node = ClipScrollNode::new_reference_frame(&rect, &rect, rect.size, &transform, pipeline_id);
self.add_node(node, reference_frame_id, parent_id);
reference_frame_id
}
@@ -20,7 +20,7 @@ use webrender_traits::{AuxiliaryLists, ClipRegion, ColorF, DisplayItem, Epoch, F
use webrender_traits::{LayerPoint, LayerRect, LayerSize, LayerToScrollTransform, LayoutTransform, TileOffset};
use webrender_traits::{MixBlendMode, PipelineId, ScrollEventPhase, ScrollLayerId, ScrollLayerState};
use webrender_traits::{ScrollLocation, ScrollPolicy, ServoScrollRootId, SpecificDisplayItem};
use webrender_traits::{StackingContext, WorldPoint, ImageDisplayItem, DeviceUintSize};
use webrender_traits::{StackingContext, WorldPoint, ImageDisplayItem, DeviceUintRect, DeviceUintSize};

#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
pub struct FrameId(pub u32);
@@ -228,7 +228,12 @@ impl Frame {
self.clip_scroll_tree.discard_frame_state_for_pipeline(pipeline_id);
}

pub fn create(&mut self, scene: &Scene, resource_cache: &mut ResourceCache) {
pub fn create(&mut self,
scene: &Scene,
resource_cache: &mut ResourceCache,
window_size: DeviceUintSize,
inner_rect: DeviceUintRect,
device_pixel_ratio: f32) {
let root_pipeline_id = match scene.root_pipeline_id {
Some(root_pipeline_id) => root_pipeline_id,
None => return,
@@ -245,6 +250,11 @@ impl Frame {
None => return,
};

if window_size.width == 0 || window_size.height == 0 {
println!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
return;
}

let old_scrolling_states = self.reset();
self.pipeline_auxiliary_lists = scene.pipeline_auxiliary_lists.clone();

@@ -258,8 +268,19 @@ impl Frame {
}
};

let inner_origin = inner_rect.origin.to_f32();
let viewport_offset = LayerPoint::new((inner_origin.x / device_pixel_ratio).round(),
(inner_origin.y / device_pixel_ratio).round());
let outer_size = window_size.to_f32();
let outer_size = LayerSize::new((outer_size.width / device_pixel_ratio).round(),
(outer_size.height / device_pixel_ratio).round());
let clip_size = LayerSize::new(outer_size.width + 2.0 * viewport_offset.x,
outer_size.height + 2.0 * viewport_offset.y);

self.clip_scroll_tree.establish_root(root_pipeline_id,
&root_pipeline.viewport_size,
viewport_offset,
clip_size,
&root_clip.main.size);

let background_color = root_pipeline.background_color.and_then(|color| {
@@ -270,7 +291,7 @@ impl Frame {
}
});

let mut frame_builder = FrameBuilder::new(root_pipeline.viewport_size,
let mut frame_builder = FrameBuilder::new(window_size,
background_color,
self.frame_builder_config);

@@ -327,7 +348,7 @@ impl Frame {
}

let clip_rect = clip.main.translate(&reference_frame_relative_offset);
let node = ClipScrollNode::new(&clip_rect, *content_size, pipeline_id);
let node = ClipScrollNode::new(&clip_rect, &clip_rect, *content_size, pipeline_id);
self.clip_scroll_tree.add_node(node, new_scroll_layer_id, parent_scroll_layer_id);
context.builder.push_clip_scroll_node(new_scroll_layer_id, clip);

@@ -498,6 +519,7 @@ impl Frame {
current_scroll_layer_id);
let iframe_scroll_layer_id = ScrollLayerId::root_scroll_layer(pipeline_id);
let node = ClipScrollNode::new(&LayerRect::new(LayerPoint::zero(), iframe_rect.size),
&LayerRect::new(LayerPoint::zero(), iframe_rect.size),
iframe_clip.main.size,
pipeline_id);
self.clip_scroll_tree.add_node(node.clone(),
@@ -27,7 +27,7 @@ use tiling::{ScrollLayerIndex, StackingContext, StackingContextIndex};
use util::{self, pack_as_float, rect_from_points_f, subtract_rect};
use util::{RectHelpers, TransformedRectKind};
use webrender_traits::{BorderDetails, BorderDisplayItem, BorderSide, BorderStyle};
use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, device_length, DeviceIntPoint};
use webrender_traits::{BoxShadowClipMode, ClipRegion, ColorF, DeviceIntPoint};
use webrender_traits::{DeviceIntRect, DeviceIntSize, DeviceUintSize, ExtendMode, FontKey, TileOffset};
use webrender_traits::{FontRenderMode, GlyphOptions, ImageKey, ImageRendering, ItemRange};
use webrender_traits::{LayerPoint, LayerRect, LayerSize, PipelineId, RepeatMode, ScrollLayerId};
@@ -102,7 +102,7 @@ impl FrameBuilderConfig {
}

pub struct FrameBuilder {
screen_rect: LayerRect,
screen_size: DeviceUintSize,
background_color: Option<ColorF>,
prim_store: PrimitiveStore,
cmds: Vec<PrimitiveRunCmd>,
@@ -125,11 +125,11 @@ pub struct FrameBuilder {
}

impl FrameBuilder {
pub fn new(viewport_size: LayerSize,
pub fn new(screen_size: DeviceUintSize,
background_color: Option<ColorF>,
config: FrameBuilderConfig) -> FrameBuilder {
FrameBuilder {
screen_rect: LayerRect::new(LayerPoint::zero(), viewport_size),
screen_size: screen_size,
background_color: background_color,
stacking_context_store: Vec::new(),
scroll_layer_store: Vec::new(),
@@ -1150,10 +1150,8 @@ impl FrameBuilder {

let screen_rect = DeviceIntRect::new(
DeviceIntPoint::zero(),
DeviceIntSize::from_lengths(device_length(self.screen_rect.size.width as f32,
device_pixel_ratio),
device_length(self.screen_rect.size.height as f32,
device_pixel_ratio)));
DeviceIntSize::new(self.screen_size.width as i32,
self.screen_size.height as i32));

// Pick a size for the cache render targets to be. The main requirement is that it
// has to be at least as large as the framebuffer size. This ensures that it will
@@ -1219,7 +1217,7 @@ impl FrameBuilder {
Frame {
device_pixel_ratio: device_pixel_ratio,
background_color: self.background_color,
viewport_size: self.screen_rect.size,
window_size: self.screen_size,
profile_counters: profile_counters,
passes: passes,
cache_size: cache_size,
@@ -18,6 +18,7 @@ use std::sync::mpsc::Sender;
use texture_cache::TextureCache;
use thread_profiler::register_thread_with_profiler;
use threadpool::ThreadPool;
use webrender_traits::{DeviceUintPoint, DeviceUintRect, DeviceUintSize};
use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace, ImageData};
use webrender_traits::{PipelineId, RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId};
use webrender_traits::channel::{PayloadHelperMethods, PayloadReceiver, PayloadSender, MsgReceiver};
@@ -36,6 +37,8 @@ pub struct RenderBackend {

device_pixel_ratio: f32,
page_zoom_factor: f32,
window_size: DeviceUintSize,
inner_rect: DeviceUintRect,
next_namespace_id: IdNamespace,

resource_cache: ResourceCache,
@@ -70,7 +73,8 @@ impl RenderBackend {
recorder: Option<Box<ApiRecordingReceiver>>,
main_thread_dispatcher: Arc<Mutex<Option<Box<RenderDispatcher>>>>,
blob_image_renderer: Option<Box<BlobImageRenderer>>,
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>) -> RenderBackend {
vr_compositor_handler: Arc<Mutex<Option<Box<VRCompositorHandler>>>>,
initial_window_size: DeviceUintSize) -> RenderBackend {

let resource_cache = ResourceCache::new(texture_cache, workers, blob_image_renderer, enable_aa);

@@ -94,7 +98,9 @@ impl RenderBackend {
recorder: recorder,
main_thread_dispatcher: main_thread_dispatcher,
next_webgl_id: 0,
vr_compositor_handler: vr_compositor_handler
vr_compositor_handler: vr_compositor_handler,
window_size: initial_window_size,
inner_rect: DeviceUintRect::new(DeviceUintPoint::zero(), initial_window_size),
}
}

@@ -145,6 +151,10 @@ impl RenderBackend {
ApiMsg::SetPageZoom(factor) => {
self.page_zoom_factor = factor.get();
}
ApiMsg::SetWindowParameters(window_size, inner_rect) => {
self.window_size = window_size;
self.inner_rect = inner_rect;
}
ApiMsg::CloneApi(sender) => {
let result = self.next_namespace_id;

@@ -426,7 +436,13 @@ impl RenderBackend {
webgl_context.unbind();
}

self.frame.create(&self.scene, &mut self.resource_cache);
let device_pixel_ratio = self.device_pixel_ratio * self.page_zoom_factor;

self.frame.create(&self.scene,
&mut self.resource_cache,
self.window_size,
self.inner_rect,
device_pixel_ratio);
}

fn render(&mut self,
@@ -509,7 +509,8 @@ impl Renderer {
/// };
/// let (renderer, sender) = Renderer::new(opts);
/// ```
pub fn new(mut options: RendererOptions) -> Result<(Renderer, RenderApiSender), InitError> {
pub fn new(mut options: RendererOptions,
initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> {
let (api_tx, api_rx) = try!{ channel::msg_channel() };
let (payload_tx, payload_rx) = try!{ channel::payload_channel() };
let (result_tx, result_rx) = channel();
@@ -801,7 +802,8 @@ impl Renderer {
recorder,
backend_main_thread_dispatcher,
blob_image_renderer,
backend_vr_compositor);
backend_vr_compositor,
initial_window_size);
backend.run(backend_profile_counters);
})};

@@ -1587,10 +1589,8 @@ impl Renderer {
// Some tests use a restricted viewport smaller than the main screen size.
// Ensure we clear the framebuffer in these tests.
// TODO(gw): Find a better solution for this?
let viewport_size = DeviceIntSize::new((frame.viewport_size.width * frame.device_pixel_ratio) as i32,
(frame.viewport_size.height * frame.device_pixel_ratio) as i32);
let needs_clear = viewport_size.width < framebuffer_size.width as i32 ||
viewport_size.height < framebuffer_size.height as i32;
let needs_clear = frame.window_size.width < framebuffer_size.width ||
frame.window_size.height < framebuffer_size.height;

self.device.disable_depth_write();
self.device.disable_stencil();
@@ -24,7 +24,7 @@ use texture_cache::TexturePage;
use util::{TransformedRect, TransformedRectKind};
use webrender_traits::{AuxiliaryLists, ColorF, DeviceIntPoint, DeviceIntRect, DeviceUintPoint};
use webrender_traits::{DeviceUintSize, FontRenderMode, ImageRendering, LayerPoint, LayerRect};
use webrender_traits::{LayerSize, LayerToWorldTransform, MixBlendMode, PipelineId, ScrollLayerId};
use webrender_traits::{LayerToWorldTransform, MixBlendMode, PipelineId, ScrollLayerId};
use webrender_traits::{WorldPoint4D, WorldToLayerTransform};

// Special sentinel value recognized by the shader. It is considered to be
@@ -1500,7 +1500,7 @@ impl CompositeOps {
/// A rendering-oriented representation of frame::Frame built by the render backend
/// and presented to the renderer.
pub struct Frame {
pub viewport_size: LayerSize,
pub window_size: DeviceUintSize,
pub background_color: Option<ColorF>,
pub device_pixel_ratio: f32,
pub cache_size: DeviceUintSize,
@@ -11,6 +11,7 @@ use {FontKey, IdNamespace, ImageKey, NativeFontHandle, PipelineId};
use {RenderApiSender, ResourceId, ScrollEventPhase, ScrollLayerState, ScrollLocation, ServoScrollRootId};
use {GlyphKey, GlyphDimensions, ImageData, WebGLContextId, WebGLCommand, TileSize};
use {DeviceIntSize, DynamicProperties, LayoutPoint, LayoutSize, WorldPoint, PropertyBindingKey, PropertyBindingId};
use {DeviceUintRect, DeviceUintSize};
use {BuiltDisplayList, AuxiliaryLists};
use VRCompositorCommand;
use {ExternalEvent, PageZoomFactor};
@@ -203,6 +204,13 @@ impl RenderApi {
self.api_sender.send(msg).unwrap();
}

pub fn set_window_parameters(&self,
window_size: DeviceUintSize,
inner_rect: DeviceUintRect) {
let msg = ApiMsg::SetWindowParameters(window_size, inner_rect);
self.api_sender.send(msg).unwrap();
}

pub fn tick_scrolling_bounce_animations(&self) {
let msg = ApiMsg::TickScrollingBounce;
self.api_sender.send(msg).unwrap();
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.