diff --git a/.travis.yml b/.travis.yml index 0f19ada7e32..278c18bd260 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ matrix: - curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain none -y - source ~/.profile script: + # see https://github.com/servo/servo/issues/20664 + #- ./mach cargo check -p compositing --no-default-features - ./mach build -d --verbose - ./mach test-unit - ./mach clean diff --git a/appveyor.yml b/appveyor.yml index 445cd76bfe7..dfb979fe4fb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -60,6 +60,8 @@ install: build_script: - mach clean-nightlies --keep 2 --force + # see https://github.com/servo/servo/issues/20664 + #- mach cargo check -p compositing --no-default-features - mach build -d -v - mach test-unit diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 7bc4dd296e9..879dfe00249 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -10,10 +10,13 @@ build = "build.rs" name = "compositing" path = "lib.rs" +[features] +default = [] + [dependencies] euclid = "0.17" gfx_traits = {path = "../gfx_traits"} -gleam = "0.4.34" +gleam = { version = "0.4.34", optional = true } image = "0.18" ipc-channel = "0.10" libc = "0.2" diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index b102a2a1cff..8caaaee1636 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -8,12 +8,16 @@ use compositor_thread::{CompositorProxy, CompositorReceiver}; use compositor_thread::{InitialCompositorState, Msg}; use euclid::{TypedPoint2D, TypedVector2D, TypedScale}; use gfx_traits::Epoch; -use gleam::gl; -use image::{DynamicImage, ImageFormat, RgbImage}; -use ipc_channel::ipc::{self, IpcSharedMemory}; +#[cfg(feature = "gleam")] +use gl; +#[cfg(feature = "gleam")] +use image::{DynamicImage, ImageFormat}; +use ipc_channel::ipc; use libc::c_void; use msg::constellation_msg::{PipelineId, PipelineIndex, PipelineNamespaceId}; -use net_traits::image::base::{Image, PixelFormat}; +use net_traits::image::base::Image; +#[cfg(feature = "gleam")] +use net_traits::image::base::PixelFormat; use nonzero::NonZeroU32; use profile_traits::time::{self, ProfilerCategory, profile}; use script_traits::{AnimationState, AnimationTickType, ConstellationMsg, LayoutControlMsg}; @@ -21,7 +25,7 @@ use script_traits::{MouseButton, MouseEventType, ScrollState, TouchEventType, To use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; use script_traits::CompositorEvent::{MouseMoveEvent, MouseButtonEvent, TouchEvent}; use servo_config::opts; -use servo_geometry::{DeviceIndependentPixel, DeviceUintLength}; +use servo_geometry::DeviceIndependentPixel; use std::collections::HashMap; use std::env; use std::fs::{File, create_dir_all}; @@ -39,6 +43,7 @@ use webrender_api::{self, DeviceIntPoint, DevicePoint, HitTestFlags, HitTestResu use webrender_api::{LayoutVector2D, ScrollEventPhase, ScrollLocation}; use windowing::{self, EmbedderCoordinates, MouseWindowEvent, WebRenderDebugOption, WindowMethods}; + #[derive(Debug, PartialEq)] enum UnableToComposite { WindowUnprepared, @@ -176,9 +181,6 @@ pub struct IOCompositor { /// The webrender interface, if enabled. webrender_api: webrender_api::RenderApi, - /// GL functions interface (may be GL or GLES) - gl: Rc, - /// Map of the pending paint metrics per layout thread. /// The layout thread for each specific pipeline expects the compositor to /// paint frames with specific given IDs (epoch). Once the compositor paints @@ -254,58 +256,6 @@ enum CompositeTarget { PngFile } -struct RenderTargetInfo { - framebuffer_ids: Vec, - renderbuffer_ids: Vec, - texture_ids: Vec, -} - -impl RenderTargetInfo { - fn empty() -> RenderTargetInfo { - RenderTargetInfo { - framebuffer_ids: Vec::new(), - renderbuffer_ids: Vec::new(), - texture_ids: Vec::new(), - } - } -} - -fn initialize_png(gl: &gl::Gl, width: DeviceUintLength, height: DeviceUintLength) -> RenderTargetInfo { - let framebuffer_ids = gl.gen_framebuffers(1); - gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]); - - let texture_ids = gl.gen_textures(1); - gl.bind_texture(gl::TEXTURE_2D, texture_ids[0]); - - gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width.get() as gl::GLsizei, - height.get() as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as gl::GLint); - gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as gl::GLint); - - gl.framebuffer_texture_2d(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, - texture_ids[0], 0); - - gl.bind_texture(gl::TEXTURE_2D, 0); - - let renderbuffer_ids = gl.gen_renderbuffers(1); - let depth_rb = renderbuffer_ids[0]; - gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); - gl.renderbuffer_storage(gl::RENDERBUFFER, - gl::DEPTH_COMPONENT24, - width.get() as gl::GLsizei, - height.get() as gl::GLsizei); - gl.framebuffer_renderbuffer(gl::FRAMEBUFFER, - gl::DEPTH_ATTACHMENT, - gl::RENDERBUFFER, - depth_rb); - - RenderTargetInfo { - framebuffer_ids: framebuffer_ids, - renderbuffer_ids: renderbuffer_ids, - texture_ids: texture_ids, - } -} - #[derive(Clone)] pub struct RenderNotifier { compositor_proxy: CompositorProxy, @@ -343,17 +293,15 @@ impl webrender_api::RenderNotifier for RenderNotifier { } impl IOCompositor { - fn new(window: Rc, state: InitialCompositorState) - -> IOCompositor { + fn new(window: Rc, state: InitialCompositorState) -> Self { let composite_target = match opts::get().output_file { Some(_) => CompositeTarget::PngFile, None => CompositeTarget::Window }; IOCompositor { - gl: window.gl(), embedder_coordinates: window.get_coordinates(), - window: window, + window, port: state.receiver, root_pipeline: None, pipeline_details: HashMap::new(), @@ -362,7 +310,7 @@ impl IOCompositor { touch_handler: TouchHandler::new(), pending_scroll_zoom_events: Vec::new(), waiting_for_results_of_scroll: false, - composite_target: composite_target, + composite_target, shutdown_state: ShutdownState::NotShuttingDown, page_zoom: TypedScale::new(1.0), viewport_zoom: PinchZoomFactor::new(1.0), @@ -384,7 +332,7 @@ impl IOCompositor { } } - pub fn create(window: Rc, state: InitialCompositorState) -> IOCompositor { + pub fn create(window: Rc, state: InitialCompositorState) -> Self { let mut compositor = IOCompositor::new(window, state); // Set the size of the root layer. @@ -567,9 +515,11 @@ impl IOCompositor { /// Sets or unsets the animations-running flag for the given pipeline, and schedules a /// recomposite if necessary. - fn change_running_animations_state(&mut self, - pipeline_id: PipelineId, - animation_state: AnimationState) { + fn change_running_animations_state( + &mut self, + pipeline_id: PipelineId, + animation_state: AnimationState, + ) { match animation_state { AnimationState::AnimationsPresent => { let visible = self.pipeline_details(pipeline_id).visible; @@ -1285,9 +1235,18 @@ impl IOCompositor { } } - let render_target_info = match target { - CompositeTarget::Window => RenderTargetInfo::empty(), - _ => initialize_png(&*self.gl, width, height) + let rt_info = match target { + #[cfg(feature = "gleam")] + CompositeTarget::Window => { + gl::RenderTargetInfo::default() + } + #[cfg(feature = "gleam")] + CompositeTarget::WindowAndPng | + CompositeTarget::PngFile => { + gl::initialize_png(&*self.window.gl(), width, height) + } + #[cfg(not(feature = "gleam"))] + _ => () }; profile(ProfilerCategory::Compositing, None, self.time_profiler_chan.clone(), || { @@ -1332,24 +1291,25 @@ impl IOCompositor { let rv = match target { CompositeTarget::Window => None, + #[cfg(feature = "gleam")] CompositeTarget::WindowAndPng => { - let img = self.draw_img(render_target_info, - width, - height); + let img = gl::draw_img(&*self.window.gl(), rt_info, width, height); Some(Image { width: img.width(), height: img.height(), format: PixelFormat::RGB8, - bytes: IpcSharedMemory::from_bytes(&*img), + bytes: ipc::IpcSharedMemory::from_bytes(&*img), id: None, }) } + #[cfg(feature = "gleam")] CompositeTarget::PngFile => { + let gl = &*self.window.gl(); profile(ProfilerCategory::ImageSaving, None, self.time_profiler_chan.clone(), || { match opts::get().output_file.as_ref() { Some(path) => match File::create(path) { Ok(mut file) => { - let img = self.draw_img(render_target_info, width, height); + let img = gl::draw_img(gl, rt_info, width, height); let dynamic_image = DynamicImage::ImageRgb8(img); if let Err(e) = dynamic_image.save(&mut file, ImageFormat::PNG) { error!("Failed to save {} ({}).", path, e); @@ -1362,6 +1322,8 @@ impl IOCompositor { }); None } + #[cfg(not(feature = "gleam"))] + _ => None, }; // Perform the page flip. This will likely block for a while. @@ -1378,44 +1340,6 @@ impl IOCompositor { Ok(rv) } - fn draw_img(&self, - render_target_info: RenderTargetInfo, - width: DeviceUintLength, - height: DeviceUintLength) - -> RgbImage { - let width = width.get() as usize; - let height = height.get() as usize; - // For some reason, OSMesa fails to render on the 3rd - // attempt in headless mode, under some conditions. - // I think this can only be some kind of synchronization - // bug in OSMesa, but explicitly un-binding any vertex - // array here seems to work around that bug. - // See https://github.com/servo/servo/issues/18606. - self.gl.bind_vertex_array(0); - - let mut pixels = self.gl.read_pixels(0, 0, - width as gl::GLsizei, - height as gl::GLsizei, - gl::RGB, gl::UNSIGNED_BYTE); - - self.gl.bind_framebuffer(gl::FRAMEBUFFER, 0); - - self.gl.delete_buffers(&render_target_info.texture_ids); - self.gl.delete_renderbuffers(&render_target_info.renderbuffer_ids); - self.gl.delete_framebuffers(&render_target_info.framebuffer_ids); - - // flip image vertically (texture is upside down) - let orig_pixels = pixels.clone(); - let stride = width * 3; - for y in 0..height { - let dst_start = y * stride; - let src_start = (height - y - 1) * stride; - let src_slice = &orig_pixels[src_start .. src_start + stride]; - (&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]); - } - RgbImage::from_raw(width as u32, height as u32, pixels).expect("Flipping image failed!") - } - fn composite_if_necessary(&mut self, reason: CompositingReason) { if self.composition_request == CompositionRequest::NoCompositingNecessary { if opts::get().is_running_problem_test { diff --git a/components/compositing/gl.rs b/components/compositing/gl.rs new file mode 100644 index 00000000000..4c7f1261fbe --- /dev/null +++ b/components/compositing/gl.rs @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + + +use gleam::gl; +use image::RgbImage; +use servo_geometry::DeviceUintLength; + + +#[derive(Default)] +pub struct RenderTargetInfo { + framebuffer_ids: Vec, + renderbuffer_ids: Vec, + texture_ids: Vec, +} + +pub fn initialize_png( + gl: &gl::Gl, width: DeviceUintLength, height: DeviceUintLength +) -> RenderTargetInfo { + let framebuffer_ids = gl.gen_framebuffers(1); + gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_ids[0]); + + let texture_ids = gl.gen_textures(1); + gl.bind_texture(gl::TEXTURE_2D, texture_ids[0]); + + gl.tex_image_2d(gl::TEXTURE_2D, 0, gl::RGB as gl::GLint, width.get() as gl::GLsizei, + height.get() as gl::GLsizei, 0, gl::RGB, gl::UNSIGNED_BYTE, None); + gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as gl::GLint); + gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as gl::GLint); + + gl.framebuffer_texture_2d(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, + texture_ids[0], 0); + + gl.bind_texture(gl::TEXTURE_2D, 0); + + let renderbuffer_ids = gl.gen_renderbuffers(1); + let depth_rb = renderbuffer_ids[0]; + gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb); + gl.renderbuffer_storage(gl::RENDERBUFFER, + gl::DEPTH_COMPONENT24, + width.get() as gl::GLsizei, + height.get() as gl::GLsizei); + gl.framebuffer_renderbuffer(gl::FRAMEBUFFER, + gl::DEPTH_ATTACHMENT, + gl::RENDERBUFFER, + depth_rb); + + RenderTargetInfo { + framebuffer_ids, + renderbuffer_ids, + texture_ids, + } +} + +pub fn draw_img( + gl: &gl::Gl, + render_target_info: RenderTargetInfo, + width: DeviceUintLength, + height: DeviceUintLength, +) -> RgbImage { + let width = width.get() as usize; + let height = height.get() as usize; + // For some reason, OSMesa fails to render on the 3rd + // attempt in headless mode, under some conditions. + // I think this can only be some kind of synchronization + // bug in OSMesa, but explicitly un-binding any vertex + // array here seems to work around that bug. + // See https://github.com/servo/servo/issues/18606. + gl.bind_vertex_array(0); + + let mut pixels = gl.read_pixels( + 0, 0, + width as gl::GLsizei, + height as gl::GLsizei, + gl::RGB, gl::UNSIGNED_BYTE, + ); + + gl.bind_framebuffer(gl::FRAMEBUFFER, 0); + + gl.delete_buffers(&render_target_info.texture_ids); + gl.delete_renderbuffers(&render_target_info.renderbuffer_ids); + gl.delete_framebuffers(&render_target_info.framebuffer_ids); + + // flip image vertically (texture is upside down) + let orig_pixels = pixels.clone(); + let stride = width * 3; + for y in 0..height { + let dst_start = y * stride; + let src_start = (height - y - 1) * stride; + let src_slice = &orig_pixels[src_start .. src_start + stride]; + (&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]); + } + + RgbImage::from_raw(width as u32, height as u32, pixels) + .expect("Flipping image failed!") +} diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index e1a870f9695..f19230ebcdd 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -6,7 +6,9 @@ extern crate euclid; extern crate gfx_traits; +#[cfg(feature = "gleam")] extern crate gleam; +#[cfg(feature = "gleam")] extern crate image; extern crate ipc_channel; extern crate libc; @@ -38,6 +40,8 @@ use style_traits::CSSPixel; mod compositor; pub mod compositor_thread; +#[cfg(feature = "gleam")] +mod gl; mod touch; pub mod windowing; diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 4bfe455ab5b..11143e5eaa9 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -6,6 +6,7 @@ use compositor_thread::EventLoopWaker; use euclid::TypedScale; +#[cfg(feature = "gleam")] use gleam::gl; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::{Key, KeyModifiers, KeyState, TopLevelBrowsingContextId, TraversalDirection}; @@ -13,6 +14,7 @@ use script_traits::{MouseButton, TouchEventType, TouchId}; use servo_geometry::{DeviceIndependentPixel, DeviceUintLength}; use servo_url::ServoUrl; use std::fmt::{Debug, Error, Formatter}; +#[cfg(feature = "gleam")] use std::rc::Rc; use style_traits::DevicePixel; use webrender_api::{DeviceIntPoint, DevicePoint, DeviceUintSize, DeviceUintRect, ScrollLocation}; @@ -126,6 +128,7 @@ pub trait WindowMethods { /// proceed and false if it should not. fn prepare_for_composite(&self, width: DeviceUintLength, height: DeviceUintLength) -> bool; /// Return the GL function pointer trait. + #[cfg(feature = "gleam")] fn gl(&self) -> Rc; /// Returns a thread-safe object to wake up the window's event loop. fn create_event_loop_waker(&self) -> Box; diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index b2a28d58da1..3929593ef00 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -32,7 +32,7 @@ bluetooth_traits = {path = "../bluetooth_traits"} bluetooth = {path = "../bluetooth"} canvas = {path = "../canvas"} canvas_traits = {path = "../canvas_traits"} -compositing = {path = "../compositing"} +compositing = {path = "../compositing", features = ["gleam"]} constellation = {path = "../constellation"} debugger = {path = "../debugger"} devtools = {path = "../devtools"} diff --git a/ports/servo/glutin_app/keyutils.rs b/ports/servo/glutin_app/keyutils.rs index cecce496a1d..4f7047b96d9 100644 --- a/ports/servo/glutin_app/keyutils.rs +++ b/ports/servo/glutin_app/keyutils.rs @@ -3,10 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use servo::msg::constellation_msg::{self, Key, KeyModifiers}; -use winit::{self, VirtualKeyCode}; +use winit::VirtualKeyCode; bitflags! { - pub struct GlutinKeyModifiers: u8 { + pub struct WinitKeyModifiers: u8 { const LEFT_CONTROL = 1; const RIGHT_CONTROL = 2; const LEFT_SHIFT = 4; @@ -131,129 +131,130 @@ pub fn char_to_script_key(c: char) -> Option { } } -pub fn glutin_key_to_script_key(key: winit::VirtualKeyCode) -> Result { +pub fn winit_key_to_script_key(key: VirtualKeyCode) -> Result { + use winit::VirtualKeyCode::*; // TODO(negge): add more key mappings - match key { - VirtualKeyCode::A => Ok(Key::A), - VirtualKeyCode::B => Ok(Key::B), - VirtualKeyCode::C => Ok(Key::C), - VirtualKeyCode::D => Ok(Key::D), - VirtualKeyCode::E => Ok(Key::E), - VirtualKeyCode::F => Ok(Key::F), - VirtualKeyCode::G => Ok(Key::G), - VirtualKeyCode::H => Ok(Key::H), - VirtualKeyCode::I => Ok(Key::I), - VirtualKeyCode::J => Ok(Key::J), - VirtualKeyCode::K => Ok(Key::K), - VirtualKeyCode::L => Ok(Key::L), - VirtualKeyCode::M => Ok(Key::M), - VirtualKeyCode::N => Ok(Key::N), - VirtualKeyCode::O => Ok(Key::O), - VirtualKeyCode::P => Ok(Key::P), - VirtualKeyCode::Q => Ok(Key::Q), - VirtualKeyCode::R => Ok(Key::R), - VirtualKeyCode::S => Ok(Key::S), - VirtualKeyCode::T => Ok(Key::T), - VirtualKeyCode::U => Ok(Key::U), - VirtualKeyCode::V => Ok(Key::V), - VirtualKeyCode::W => Ok(Key::W), - VirtualKeyCode::X => Ok(Key::X), - VirtualKeyCode::Y => Ok(Key::Y), - VirtualKeyCode::Z => Ok(Key::Z), + Ok(match key { + A => Key::A, + B => Key::B, + C => Key::C, + D => Key::D, + E => Key::E, + F => Key::F, + G => Key::G, + H => Key::H, + I => Key::I, + J => Key::J, + K => Key::K, + L => Key::L, + M => Key::M, + N => Key::N, + O => Key::O, + P => Key::P, + Q => Key::Q, + R => Key::R, + S => Key::S, + T => Key::T, + U => Key::U, + V => Key::V, + W => Key::W, + X => Key::X, + Y => Key::Y, + Z => Key::Z, - VirtualKeyCode::Numpad0 => Ok(Key::Kp0), - VirtualKeyCode::Numpad1 => Ok(Key::Kp1), - VirtualKeyCode::Numpad2 => Ok(Key::Kp2), - VirtualKeyCode::Numpad3 => Ok(Key::Kp3), - VirtualKeyCode::Numpad4 => Ok(Key::Kp4), - VirtualKeyCode::Numpad5 => Ok(Key::Kp5), - VirtualKeyCode::Numpad6 => Ok(Key::Kp6), - VirtualKeyCode::Numpad7 => Ok(Key::Kp7), - VirtualKeyCode::Numpad8 => Ok(Key::Kp8), - VirtualKeyCode::Numpad9 => Ok(Key::Kp9), + Numpad0 => Key::Kp0, + Numpad1 => Key::Kp1, + Numpad2 => Key::Kp2, + Numpad3 => Key::Kp3, + Numpad4 => Key::Kp4, + Numpad5 => Key::Kp5, + Numpad6 => Key::Kp6, + Numpad7 => Key::Kp7, + Numpad8 => Key::Kp8, + Numpad9 => Key::Kp9, - VirtualKeyCode::Key0 => Ok(Key::Num0), - VirtualKeyCode::Key1 => Ok(Key::Num1), - VirtualKeyCode::Key2 => Ok(Key::Num2), - VirtualKeyCode::Key3 => Ok(Key::Num3), - VirtualKeyCode::Key4 => Ok(Key::Num4), - VirtualKeyCode::Key5 => Ok(Key::Num5), - VirtualKeyCode::Key6 => Ok(Key::Num6), - VirtualKeyCode::Key7 => Ok(Key::Num7), - VirtualKeyCode::Key8 => Ok(Key::Num8), - VirtualKeyCode::Key9 => Ok(Key::Num9), + Key0 => Key::Num0, + Key1 => Key::Num1, + Key2 => Key::Num2, + Key3 => Key::Num3, + Key4 => Key::Num4, + Key5 => Key::Num5, + Key6 => Key::Num6, + Key7 => Key::Num7, + Key8 => Key::Num8, + Key9 => Key::Num9, - VirtualKeyCode::Return => Ok(Key::Enter), - VirtualKeyCode::Space => Ok(Key::Space), - VirtualKeyCode::Escape => Ok(Key::Escape), - VirtualKeyCode::Equals => Ok(Key::Equal), - VirtualKeyCode::Minus => Ok(Key::Minus), - VirtualKeyCode::Back => Ok(Key::Backspace), - VirtualKeyCode::PageDown => Ok(Key::PageDown), - VirtualKeyCode::PageUp => Ok(Key::PageUp), + Return => Key::Enter, + Space => Key::Space, + Escape => Key::Escape, + Equals => Key::Equal, + Minus => Key::Minus, + Back => Key::Backspace, + PageDown => Key::PageDown, + PageUp => Key::PageUp, - VirtualKeyCode::Insert => Ok(Key::Insert), - VirtualKeyCode::Home => Ok(Key::Home), - VirtualKeyCode::Delete => Ok(Key::Delete), - VirtualKeyCode::End => Ok(Key::End), + Insert => Key::Insert, + Home => Key::Home, + Delete => Key::Delete, + End => Key::End, - VirtualKeyCode::Left => Ok(Key::Left), - VirtualKeyCode::Up => Ok(Key::Up), - VirtualKeyCode::Right => Ok(Key::Right), - VirtualKeyCode::Down => Ok(Key::Down), + Left => Key::Left, + Up => Key::Up, + Right => Key::Right, + Down => Key::Down, - VirtualKeyCode::LShift => Ok(Key::LeftShift), - VirtualKeyCode::LControl => Ok(Key::LeftControl), - VirtualKeyCode::LAlt => Ok(Key::LeftAlt), - VirtualKeyCode::LWin => Ok(Key::LeftSuper), - VirtualKeyCode::RShift => Ok(Key::RightShift), - VirtualKeyCode::RControl => Ok(Key::RightControl), - VirtualKeyCode::RAlt => Ok(Key::RightAlt), - VirtualKeyCode::RWin => Ok(Key::RightSuper), + LShift => Key::LeftShift, + LControl => Key::LeftControl, + LAlt => Key::LeftAlt, + LWin => Key::LeftSuper, + RShift => Key::RightShift, + RControl => Key::RightControl, + RAlt => Key::RightAlt, + RWin => Key::RightSuper, - VirtualKeyCode::Apostrophe => Ok(Key::Apostrophe), - VirtualKeyCode::Backslash => Ok(Key::Backslash), - VirtualKeyCode::Comma => Ok(Key::Comma), - VirtualKeyCode::Grave => Ok(Key::GraveAccent), - VirtualKeyCode::LBracket => Ok(Key::LeftBracket), - VirtualKeyCode::Period => Ok(Key::Period), - VirtualKeyCode::RBracket => Ok(Key::RightBracket), - VirtualKeyCode::Semicolon => Ok(Key::Semicolon), - VirtualKeyCode::Slash => Ok(Key::Slash), - VirtualKeyCode::Tab => Ok(Key::Tab), - VirtualKeyCode::Subtract => Ok(Key::Minus), + Apostrophe => Key::Apostrophe, + Backslash => Key::Backslash, + Comma => Key::Comma, + Grave => Key::GraveAccent, + LBracket => Key::LeftBracket, + Period => Key::Period, + RBracket => Key::RightBracket, + Semicolon => Key::Semicolon, + Slash => Key::Slash, + Tab => Key::Tab, + Subtract => Key::Minus, - VirtualKeyCode::F1 => Ok(Key::F1), - VirtualKeyCode::F2 => Ok(Key::F2), - VirtualKeyCode::F3 => Ok(Key::F3), - VirtualKeyCode::F4 => Ok(Key::F4), - VirtualKeyCode::F5 => Ok(Key::F5), - VirtualKeyCode::F6 => Ok(Key::F6), - VirtualKeyCode::F7 => Ok(Key::F7), - VirtualKeyCode::F8 => Ok(Key::F8), - VirtualKeyCode::F9 => Ok(Key::F9), - VirtualKeyCode::F10 => Ok(Key::F10), - VirtualKeyCode::F11 => Ok(Key::F11), - VirtualKeyCode::F12 => Ok(Key::F12), + F1 => Key::F1, + F2 => Key::F2, + F3 => Key::F3, + F4 => Key::F4, + F5 => Key::F5, + F6 => Key::F6, + F7 => Key::F7, + F8 => Key::F8, + F9 => Key::F9, + F10 => Key::F10, + F11 => Key::F11, + F12 => Key::F12, - VirtualKeyCode::NavigateBackward => Ok(Key::NavigateBackward), - VirtualKeyCode::NavigateForward => Ok(Key::NavigateForward), - _ => Err(()), - } + NavigateBackward => Key::NavigateBackward, + NavigateForward => Key::NavigateForward, + _ => return Err(()), + }) } -pub fn glutin_mods_to_script_mods(modifiers: GlutinKeyModifiers) -> constellation_msg::KeyModifiers { +pub fn winit_mods_to_script_mods(modifiers: WinitKeyModifiers) -> constellation_msg::KeyModifiers { let mut result = constellation_msg::KeyModifiers::empty(); - if modifiers.intersects(GlutinKeyModifiers::LEFT_SHIFT | GlutinKeyModifiers::RIGHT_SHIFT) { + if modifiers.intersects(WinitKeyModifiers::LEFT_SHIFT | WinitKeyModifiers::RIGHT_SHIFT) { result.insert(KeyModifiers::SHIFT); } - if modifiers.intersects(GlutinKeyModifiers::LEFT_CONTROL | GlutinKeyModifiers::RIGHT_CONTROL) { + if modifiers.intersects(WinitKeyModifiers::LEFT_CONTROL | WinitKeyModifiers::RIGHT_CONTROL) { result.insert(KeyModifiers::CONTROL); } - if modifiers.intersects(GlutinKeyModifiers::LEFT_ALT | GlutinKeyModifiers::RIGHT_ALT) { + if modifiers.intersects(WinitKeyModifiers::LEFT_ALT | WinitKeyModifiers::RIGHT_ALT) { result.insert(KeyModifiers::ALT); } - if modifiers.intersects(GlutinKeyModifiers::LEFT_SUPER | GlutinKeyModifiers::RIGHT_SUPER) { + if modifiers.intersects(WinitKeyModifiers::LEFT_SUPER | WinitKeyModifiers::RIGHT_SUPER) { result.insert(KeyModifiers::SUPER); } result diff --git a/ports/servo/glutin_app/window.rs b/ports/servo/glutin_app/window.rs index 6ee0f9dee66..436f7518eee 100644 --- a/ports/servo/glutin_app/window.rs +++ b/ports/servo/glutin_app/window.rs @@ -2,13 +2,13 @@ * 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/. */ -//! A windowing implementation using glutin. +//! A windowing implementation using winit. use euclid::{Length, TypedPoint2D, TypedVector2D, TypedScale, TypedSize2D}; #[cfg(target_os = "windows")] use gdi32; use gleam::gl; -use glutin::{self, Api, GlContext, GlRequest}; +use glutin::{Api, ContextBuilder, GlContext, GlRequest, GlWindow}; #[cfg(any(target_os = "linux", target_os = "macos"))] use osmesa_sys; use servo::compositing::compositor_thread::EventLoopWaker; @@ -31,7 +31,7 @@ use std::rc::Rc; use std::sync::Arc; use std::thread; use std::time; -use super::keyutils::{self, GlutinKeyModifiers}; +use super::keyutils::{self, WinitKeyModifiers}; #[cfg(target_os = "windows")] use user32; #[cfg(target_os = "windows")] @@ -138,7 +138,7 @@ impl HeadlessContext { } enum WindowKind { - Window(glutin::GlWindow, RefCell), + Window(GlWindow, RefCell), Headless(HeadlessContext), } @@ -151,7 +151,7 @@ pub struct Window { mouse_down_point: Cell>, event_queue: RefCell>, mouse_pos: Cell>, - key_modifiers: Cell, + key_modifiers: Cell, last_pressed_key: Cell>, animation_state: Cell, fullscreen: Cell, @@ -203,7 +203,7 @@ impl Window { window_builder = builder_with_platform_options(window_builder); - let mut context_builder = glutin::ContextBuilder::new() + let mut context_builder = ContextBuilder::new() .with_gl(Window::gl_version()) .with_vsync(opts::get().enable_vsync); @@ -211,7 +211,7 @@ impl Window { context_builder = context_builder.with_multisampling(MULTISAMPLES) } - let glutin_window = glutin::GlWindow::new(window_builder, context_builder, &events_loop) + let glutin_window = GlWindow::new(window_builder, context_builder, &events_loop) .expect("Failed to create window."); unsafe { @@ -270,7 +270,7 @@ impl Window { mouse_down_point: Cell::new(TypedPoint2D::new(0, 0)), mouse_pos: Cell::new(TypedPoint2D::new(0, 0)), - key_modifiers: Cell::new(GlutinKeyModifiers::empty()), + key_modifiers: Cell::new(WinitKeyModifiers::empty()), last_pressed_key: Cell::new(None), gl: gl.clone(), @@ -347,13 +347,13 @@ impl Window { if self.is_animating() { // We block on compositing (servo_callback ends up calling swap_buffers) events_loop.borrow_mut().poll_events(|e| { - self.glutin_event_to_servo_event(e); + self.winit_event_to_servo_event(e); }); stop = servo_callback(); } else { - // We block on glutin's event loop (window events) + // We block on winit's event loop (window events) events_loop.borrow_mut().run_forever(|e| { - self.glutin_event_to_servo_event(e); + self.winit_event_to_servo_event(e); if !self.event_queue.borrow().is_empty() { if !self.suspended.get() { stop = servo_callback(); @@ -398,7 +398,7 @@ impl Window { } fn handle_received_character(&self, ch: char) { - let modifiers = keyutils::glutin_mods_to_script_mods(self.key_modifiers.get()); + let modifiers = keyutils::winit_mods_to_script_mods(self.key_modifiers.get()); if keyutils::is_identifier_ignorable(&ch) { return } @@ -425,14 +425,14 @@ impl Window { fn toggle_keyboard_modifiers(&self, virtual_key_code: VirtualKeyCode) { match virtual_key_code { - VirtualKeyCode::LControl => self.toggle_modifier(GlutinKeyModifiers::LEFT_CONTROL), - VirtualKeyCode::RControl => self.toggle_modifier(GlutinKeyModifiers::RIGHT_CONTROL), - VirtualKeyCode::LShift => self.toggle_modifier(GlutinKeyModifiers::LEFT_SHIFT), - VirtualKeyCode::RShift => self.toggle_modifier(GlutinKeyModifiers::RIGHT_SHIFT), - VirtualKeyCode::LAlt => self.toggle_modifier(GlutinKeyModifiers::LEFT_ALT), - VirtualKeyCode::RAlt => self.toggle_modifier(GlutinKeyModifiers::RIGHT_ALT), - VirtualKeyCode::LWin => self.toggle_modifier(GlutinKeyModifiers::LEFT_SUPER), - VirtualKeyCode::RWin => self.toggle_modifier(GlutinKeyModifiers::RIGHT_SUPER), + VirtualKeyCode::LControl => self.toggle_modifier(WinitKeyModifiers::LEFT_CONTROL), + VirtualKeyCode::RControl => self.toggle_modifier(WinitKeyModifiers::RIGHT_CONTROL), + VirtualKeyCode::LShift => self.toggle_modifier(WinitKeyModifiers::LEFT_SHIFT), + VirtualKeyCode::RShift => self.toggle_modifier(WinitKeyModifiers::RIGHT_SHIFT), + VirtualKeyCode::LAlt => self.toggle_modifier(WinitKeyModifiers::LEFT_ALT), + VirtualKeyCode::RAlt => self.toggle_modifier(WinitKeyModifiers::RIGHT_ALT), + VirtualKeyCode::LWin => self.toggle_modifier(WinitKeyModifiers::LEFT_SUPER), + VirtualKeyCode::RWin => self.toggle_modifier(WinitKeyModifiers::RIGHT_SUPER), _ => {} } } @@ -440,7 +440,7 @@ impl Window { fn handle_keyboard_input(&self, element_state: ElementState, virtual_key_code: VirtualKeyCode) { self.toggle_keyboard_modifiers(virtual_key_code); - if let Ok(key) = keyutils::glutin_key_to_script_key(virtual_key_code) { + if let Ok(key) = keyutils::winit_key_to_script_key(virtual_key_code) { let state = match element_state { ElementState::Pressed => KeyState::Pressed, ElementState::Released => KeyState::Released, @@ -450,12 +450,12 @@ impl Window { self.last_pressed_key.set(Some(key)); } } - let modifiers = keyutils::glutin_mods_to_script_mods(self.key_modifiers.get()); + let modifiers = keyutils::winit_mods_to_script_mods(self.key_modifiers.get()); self.event_queue.borrow_mut().push(WindowEvent::KeyEvent(None, key, state, modifiers)); } } - fn glutin_event_to_servo_event(&self, event: winit::Event) { + fn winit_event_to_servo_event(&self, event: winit::Event) { match event { Event::WindowEvent { event: winit::WindowEvent::ReceivedCharacter(ch), @@ -505,7 +505,7 @@ impl Window { } let scroll_location = ScrollLocation::Delta(TypedVector2D::new(dx, dy)); - let phase = glutin_phase_to_touch_event_type(phase); + let phase = winit_phase_to_touch_event_type(phase); let event = WindowEvent::Scroll(scroll_location, self.mouse_pos.get(), phase); self.event_queue.borrow_mut().push(event); }, @@ -515,7 +515,7 @@ impl Window { } => { use servo::script_traits::TouchId; - let phase = glutin_phase_to_touch_event_type(touch.phase); + let phase = winit_phase_to_touch_event_type(touch.phase); let id = TouchId(touch.id as i32); let point = TypedPoint2D::new(touch.location.0 as f32, touch.location.1 as f32); self.event_queue.borrow_mut().push(WindowEvent::Touch(phase, id, point)); @@ -560,7 +560,7 @@ impl Window { } } - fn toggle_modifier(&self, modifier: GlutinKeyModifiers) { + fn toggle_modifier(&self, modifier: WinitKeyModifiers) { let mut modifiers = self.key_modifiers.get(); modifiers.toggle(modifier); self.key_modifiers.set(modifiers); @@ -636,7 +636,7 @@ impl Window { WindowKind::Window(ref window, ..) => { use winit::MouseCursor; - let glutin_cursor = match cursor { + let winit_cursor = match cursor { CursorKind::Auto => MouseCursor::Default, CursorKind::None => MouseCursor::NoneCursor, CursorKind::Default => MouseCursor::Default, @@ -674,7 +674,7 @@ impl Window { CursorKind::ZoomIn => MouseCursor::ZoomIn, CursorKind::ZoomOut => MouseCursor::ZoomOut, }; - window.set_cursor(glutin_cursor); + window.set_cursor(winit_cursor); } WindowKind::Headless(..) => {} } @@ -786,7 +786,7 @@ impl WindowMethods for Window { } } -fn glutin_phase_to_touch_event_type(phase: TouchPhase) -> TouchEventType { +fn winit_phase_to_touch_event_type(phase: TouchPhase) -> TouchEventType { match phase { TouchPhase::Started => TouchEventType::Down, TouchPhase::Moved => TouchEventType::Move,