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

[wip] Introduce ViewGeometry #17091

Closed
wants to merge 1 commit 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

@@ -9,9 +9,7 @@ use compositor_thread::{InitialCompositorState, Msg, RenderListener};
use delayed_composition::DelayedCompositionTimerProxy;
use euclid::Point2D;
use euclid::point::TypedPoint2D;
use euclid::rect::TypedRect;
use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use gfx_traits::Epoch;
use gleam::gl;
use image::{DynamicImage, ImageFormat, RgbImage};
@@ -40,7 +38,7 @@ use time::{precise_time_ns, precise_time_s};
use touch::{TouchHandler, TouchAction};
use webrender;
use webrender_traits::{self, ClipId, LayoutPoint, ScrollEventPhase, ScrollLocation, ScrollClamping};
use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
use windowing::{self, ViewGeometry, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};

#[derive(Debug, PartialEq)]
enum UnableToComposite {
@@ -114,11 +112,7 @@ pub struct IOCompositor<Window: WindowMethods> {
/// The scene scale, to allow for zooming and high-resolution painting.
scale: ScaleFactor<f32, LayerPixel, DevicePixel>,

/// The size of the rendering area.
frame_size: TypedSize2D<u32, DevicePixel>,

/// The position and size of the window within the rendering area.
window_rect: TypedRect<u32, DevicePixel>,
geometry: ViewGeometry,

/// "Mobile-style" zoom that does not reflow the page.
viewport_zoom: PinchZoomFactor,
@@ -130,9 +124,6 @@ pub struct IOCompositor<Window: WindowMethods> {
/// "Desktop-style" zoom that resizes the viewport to fit the window.
page_zoom: ScaleFactor<f32, CSSPixel, DeviceIndependentPixel>,

/// The device pixel ratio for this window.
scale_factor: ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>,

channel_to_self: Box<CompositorProxy + Send>,

/// A handle to the delayed composition timer.
@@ -353,24 +344,22 @@ impl webrender_traits::RenderDispatcher for CompositorThreadDispatcher {
impl<Window: WindowMethods> IOCompositor<Window> {
fn new(window: Rc<Window>, state: InitialCompositorState)
-> IOCompositor<Window> {
let frame_size = window.framebuffer_size();
let window_rect = window.window_rect();
let scale_factor = window.hidpi_factor();

let composite_target = match opts::get().output_file {
Some(_) => CompositeTarget::PngFile,
None => CompositeTarget::Window
};

let geometry = window.get_geometry();

IOCompositor {
gl: window.gl(),
window: window,
port: state.receiver,
root_pipeline: None,
pipeline_details: HashMap::new(),
frame_size: frame_size,
window_rect: window_rect,
geometry: geometry,
scale: ScaleFactor::new(1.0),
scale_factor: scale_factor,
channel_to_self: state.sender.clone_compositor_proxy(),
delayed_composition_timer: DelayedCompositionTimerProxy::new(state.sender),
composition_request: CompositionRequest::NoCompositingNecessary,
@@ -501,7 +490,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {

(Msg::GetClientWindow(send),
ShutdownState::NotShuttingDown) => {
let rect = self.window.client_window();
let rect = self.geometry.window_rect;
if let Err(e) = send.send(rect) {
warn!("Sending response to get client window failed ({}).", e);
}
@@ -739,16 +728,24 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn send_window_size(&self, size_type: WindowSizeType) {
let dppx = self.page_zoom * self.hidpi_factor();

let window_rect = {
let offset = webrender_traits::DeviceUintPoint::new(self.window_rect.origin.x, self.window_rect.origin.y);
let size = webrender_traits::DeviceUintSize::new(self.window_rect.size.width, self.window_rect.size.height);
let viewport_rect = &self.geometry.viewport_rect;
let rendering_rect = &self.geometry.rendering_rect;

let wr_viewport_rect = {
let offset = webrender_traits::DeviceUintPoint::new(viewport_rect.origin.x, viewport_rect.origin.y);
let size = webrender_traits::DeviceUintSize::new(viewport_rect.size.width, viewport_rect.size.height);
webrender_traits::DeviceUintRect::new(offset, size)
};

let wr_rendering_rect = {
let offset = webrender_traits::DeviceUintPoint::new(rendering_rect.origin.x, rendering_rect.origin.y);
let size = webrender_traits::DeviceUintSize::new(rendering_rect.size.width, rendering_rect.size.height);
webrender_traits::DeviceUintRect::new(offset, size)
};

let frame_size = webrender_traits::DeviceUintSize::new(self.frame_size.width, self.frame_size.height);
self.webrender_api.set_window_parameters(frame_size, window_rect);
self.webrender_api.set_view_geometry(wr_rendering_rect, wr_viewport_rect);

let initial_viewport = self.window_rect.size.to_f32() / dppx;
let initial_viewport = viewport_rect.size.to_f32() / dppx;

let data = WindowSizeData {
device_pixel_ratio: dppx,
@@ -794,8 +791,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
self.initialize_compositing();
}

WindowEvent::Resize(size) => {
self.on_resize_window_event(size);
WindowEvent::Resize => {
self.on_resize_window_event();
}

WindowEvent::LoadUrl(url_string) => {
@@ -875,28 +872,19 @@ impl<Window: WindowMethods> IOCompositor<Window> {
}
}

fn on_resize_window_event(&mut self, new_size: TypedSize2D<u32, DevicePixel>) {
debug!("compositor resizing to {:?}", new_size.to_untyped());
fn on_resize_window_event(&mut self) {
let old_geometry = self.geometry;

self.geometry = self.window.get_geometry();

// A size change could also mean a resolution change.
let new_scale_factor = self.window.hidpi_factor();
if self.scale_factor != new_scale_factor {
self.scale_factor = new_scale_factor;
if self.geometry.hidpi_factor != old_geometry.hidpi_factor {
self.update_zoom_transform();
}

let new_window_rect = self.window.window_rect();
let new_frame_size = self.window.framebuffer_size();

if self.window_rect == new_window_rect &&
self.frame_size == new_frame_size {
return;
if self.geometry.rendering_rect != old_geometry.rendering_rect ||
self.geometry.viewport_rect != old_geometry.viewport_rect {
self.send_window_size(WindowSizeType::Resize);
}

self.frame_size = new_size;
self.window_rect = new_window_rect;

self.send_window_size(WindowSizeType::Resize);
}

fn on_load_url_window_event(&mut self, url_string: String) {
@@ -1289,7 +1277,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
Some(device_pixels_per_px) => ScaleFactor::new(device_pixels_per_px),
None => match opts::get().output_file {
Some(_) => ScaleFactor::new(1.0),
None => self.scale_factor
None => self.geometry.hidpi_factor,
}
}
}
@@ -1489,7 +1477,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
target: CompositeTarget)
-> Result<Option<Image>, UnableToComposite> {
let (width, height) =
(self.frame_size.width as usize, self.frame_size.height as usize);
(self.geometry.rendering_rect.size.width as usize,
self.geometry.rendering_rect.size.height as usize);
if !self.window.prepare_for_composite(width, height) {
return Err(UnableToComposite::WindowUnprepared)
}
@@ -1527,7 +1516,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
debug!("compositor: compositing");

// Paint the scene.
let size = webrender_traits::DeviceUintSize::from_untyped(&self.frame_size.to_untyped());
let size = webrender_traits::DeviceUintSize::from_untyped(&self.geometry.rendering_rect.size.to_untyped());
self.webrender.render(size);
});

@@ -9,7 +9,6 @@ use euclid::{Point2D, Size2D};
use euclid::point::TypedPoint2D;
use euclid::rect::TypedRect;
use euclid::scale_factor::ScaleFactor;
use euclid::size::TypedSize2D;
use gleam::gl;
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use net_traits::net_error_list::NetError;
@@ -28,6 +27,28 @@ pub enum MouseWindowEvent {
MouseUp(MouseButton, TypedPoint2D<f32, DevicePixel>),
}

/// The geometry of a view.
///
/// The viewport top left corner is the 0x0 CSS pixel (before scroll).
///
/// The rendering area is where content gets clipped. The rendering area
/// is equal or larger than the viewport area. This makes it possible to
/// draw content outside of the viewport.
///
/// The window rect is the outer coordinates of the window. It is equal or
/// larger than the rendering area.
#[derive(Copy, Clone)]
pub struct ViewGeometry {
/// The window outer size and position.
pub window_rect: (Size2D<u32>, Point2D<i32>),
/// The rendering area.
pub rendering_rect: TypedRect<u32, DevicePixel>,
/// The viewport area.
pub viewport_rect: TypedRect<u32, DevicePixel>,
/// The device pixel ratio for this window.
pub hidpi_factor: ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>,
}

#[derive(Clone)]
pub enum WindowNavigateMsg {
Forward,
@@ -50,8 +71,8 @@ pub enum WindowEvent {
/// Sent to initialize the GL context. The windowing system must have a valid, current GL
/// context when this message is sent.
InitializeCompositing,
/// Sent when the window is resized.
Resize(TypedSize2D<u32, DevicePixel>),
/// Sent when the geometry of the view changed.
Resize,
/// Touchpad Pressure
TouchpadPressure(TypedPoint2D<f32, DevicePixel>, f32, TouchpadPressurePhase),
/// Sent when a new URL is to be loaded.
@@ -87,7 +108,7 @@ impl Debug for WindowEvent {
WindowEvent::Idle => write!(f, "Idle"),
WindowEvent::Refresh => write!(f, "Refresh"),
WindowEvent::InitializeCompositing => write!(f, "InitializeCompositing"),
WindowEvent::Resize(..) => write!(f, "Resize"),
WindowEvent::Resize => write!(f, "Resize"),
WindowEvent::TouchpadPressure(..) => write!(f, "TouchpadPressure"),
WindowEvent::KeyEvent(..) => write!(f, "Key"),
WindowEvent::LoadUrl(..) => write!(f, "LoadUrl"),
@@ -106,17 +127,10 @@ impl Debug for WindowEvent {
}

pub trait WindowMethods {
/// Returns the rendering area size in hardware pixels.
fn framebuffer_size(&self) -> TypedSize2D<u32, DevicePixel>;
/// Returns the position and size of the window within the rendering area.
fn window_rect(&self) -> TypedRect<u32, DevicePixel>;
/// Returns the size of the window in density-independent "px" units.
fn size(&self) -> TypedSize2D<f32, DeviceIndependentPixel>;
/// Presents the window to the screen (perhaps by page flipping).
fn present(&self);

/// Return the size of the window with head and borders and position of the window values
fn client_window(&self) -> (Size2D<u32>, Point2D<i32>);
/// Get the geometry of the view and the window
fn get_geometry(&self) -> ViewGeometry;
/// Set the size inside of borders and head
fn set_inner_size(&self, size: Size2D<u32>);
/// Set the window position
@@ -141,9 +155,6 @@ pub trait WindowMethods {
/// Called when the history state has changed.
fn history_changed(&self, Vec<LoadData>, usize);

/// Returns the scale factor of the system (device pixels / device independent pixels).
fn hidpi_factor(&self) -> ScaleFactor<f32, DeviceIndependentPixel, DevicePixel>;

/// Creates a channel to the compositor. The dummy parameter is needed because we don't have
/// UFCS in Rust yet.
///
@@ -151,12 +151,14 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {

let (webrender, webrender_api_sender) = {
// TODO(gw): Duplicates device_pixels_per_screen_px from compositor. Tidy up!
let scale_factor = window.hidpi_factor().get();

let geometry = window.get_geometry();

let device_pixel_ratio = match opts.device_pixels_per_px {
Some(device_pixels_per_px) => device_pixels_per_px,
None => match opts.output_file {
Some(_) => 1.0,
None => scale_factor,
None => geometry.hidpi_factor.get(),
}
};

@@ -174,9 +176,20 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
None
};

let framebuffer_size = window.framebuffer_size();
let framebuffer_size = webrender_traits::DeviceUintSize::new(framebuffer_size.width,
framebuffer_size.height);
let rendering_rect = geometry.rendering_rect;
let viewport_rect = geometry.viewport_rect;

let wr_rendering_rect = {
let offset = webrender_traits::DeviceUintPoint::new(rendering_rect.origin.x, rendering_rect.origin.y);
let size = webrender_traits::DeviceUintSize::new(rendering_rect.size.width, rendering_rect.size.height);
webrender_traits::DeviceUintRect::new(offset, size)
};

let wr_viewport_rect = {
let offset = webrender_traits::DeviceUintPoint::new(viewport_rect.origin.x, viewport_rect.origin.y);
let size = webrender_traits::DeviceUintSize::new(viewport_rect.size.width, viewport_rect.size.height);
webrender_traits::DeviceUintRect::new(offset, size)
};

webrender::Renderer::new(window.gl(), webrender::RendererOptions {
device_pixel_ratio: device_pixel_ratio,
@@ -191,7 +204,7 @@ impl<Window> Browser<Window> where Window: WindowMethods + 'static {
renderer_kind: renderer_kind,
enable_subpixel_aa: opts.enable_subpixel_text_antialiasing,
..Default::default()
}, framebuffer_size).expect("Unable to initialize webrender!")
}, wr_rendering_rect, wr_viewport_rect).expect("Unable to initialize webrender!")
};

// Important that this call is done in a single-threaded fashion, we
@@ -7,13 +7,11 @@ use eutil::Downcast;
use interfaces::{CefBrowser, CefBrowserHost, CefClient, cef_browser_t, cef_browser_host_t, cef_client_t};
use types::cef_event_flags_t::{EVENTFLAG_ALT_DOWN, EVENTFLAG_CONTROL_DOWN, EVENTFLAG_SHIFT_DOWN};
use types::cef_key_event_type_t::{KEYEVENT_CHAR, KEYEVENT_KEYDOWN, KEYEVENT_KEYUP, KEYEVENT_RAWKEYDOWN};
use types::{cef_mouse_button_type_t, cef_mouse_event, cef_rect_t, cef_key_event, cef_window_handle_t};
use types::{cef_mouse_button_type_t, cef_mouse_event, cef_key_event, cef_window_handle_t};
use webrender_traits::ScrollLocation;
use wrappers::CefWrap;

use compositing::windowing::{WindowEvent, MouseWindowEvent};
use euclid::point::TypedPoint2D;
use euclid::size::TypedSize2D;
use libc::{c_double, c_int};
use msg::constellation_msg::{self, KeyModifiers, KeyState};
use script_traits::{MouseButton, TouchEventType};
@@ -371,22 +369,7 @@ full_cef_class_impl! {
}}

fn was_resized(&this,) -> () {{
let mut rect = cef_rect_t::zero();
if cfg!(target_os="macos") {
if check_ptr_exist!(this.get_client(), get_render_handler) &&
check_ptr_exist!(this.get_client().get_render_handler(), get_backing_rect) {
this.get_client()
.get_render_handler()
.get_backing_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
}
} else if check_ptr_exist!(this.get_client(), get_render_handler) &&
check_ptr_exist!(this.get_client().get_render_handler(), get_view_rect) {
this.get_client()
.get_render_handler()
.get_view_rect(this.downcast().browser.borrow().clone().unwrap(), &mut rect);
}
let size = TypedSize2D::new(rect.width as u32, rect.height as u32);
this.downcast().send_window_event(WindowEvent::Resize(size));
this.downcast().send_window_event(WindowEvent::Resize);
}}

fn close_browser(&this, _force: c_int [c_int],) -> () {{
@@ -18,7 +18,6 @@ extern crate gleam;
extern crate glutin_app;
extern crate script_traits;
extern crate servo_config;
extern crate servo_geometry;
extern crate servo_url;
extern crate style_traits;

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