From 8bb1732258c44e6850618a8f2fbb2927bc01b090 Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Thu, 9 Jan 2020 17:28:46 -0600 Subject: [PATCH] Update surfman to 0.2 and remove glutin --- Cargo.lock | 100 ++-- Cargo.toml | 2 + components/canvas/Cargo.toml | 3 +- components/canvas/webgl_mode/inprocess.rs | 46 +- components/canvas/webgl_thread.rs | 442 ++++++++++----- components/canvas_traits/webgl.rs | 2 +- components/compositing/Cargo.toml | 1 + components/compositing/compositor.rs | 66 ++- components/compositing/compositor_thread.rs | 4 + components/compositing/lib.rs | 1 + components/compositing/windowing.rs | 21 +- components/config/prefs.rs | 6 +- .../script/dom/webgl_extensions/extensions.rs | 22 +- components/script/dom/webglrenderbuffer.rs | 2 +- components/script/dom/webglshader.rs | 45 +- components/servo/Cargo.toml | 3 +- components/servo/lib.rs | 95 ++-- components/webrender_surfman/Cargo.toml | 17 + components/webrender_surfman/lib.rs | 213 ++++++++ components/webrender_traits/Cargo.toml | 1 + components/webrender_traits/lib.rs | 2 + etc/taskcluster/decision_task.py | 19 +- ports/glutin/Cargo.toml | 7 +- ports/glutin/app.rs | 61 +-- ports/glutin/context.rs | 172 ------ ports/glutin/embedder.rs | 23 +- ports/glutin/events_loop.rs | 35 +- ports/glutin/headed_window.rs | 512 ++++++++---------- ports/glutin/headless_window.rs | 191 ++----- ports/glutin/keyutils.rs | 6 +- ports/glutin/main2.rs | 20 +- ports/glutin/window_trait.rs | 10 +- ports/gstplugin/Cargo.toml | 4 +- ports/gstplugin/servowebsrc.rs | 311 +++-------- ports/libsimpleservo/api/Cargo.toml | 1 + ports/libsimpleservo/api/src/lib.rs | 46 +- ports/libsimpleservo/capi/Cargo.toml | 1 + ports/libsimpleservo/capi/src/lib.rs | 14 +- python/servo/command_base.py | 28 - python/servo/post_build_commands.py | 3 +- python/servo/testing_commands.py | 20 +- resources/prefs.json | 1 + servo-tidy.toml | 4 - support/hololens/ServoApp/DefaultUrl.h | 2 +- support/hololens/ServoApp/ServoApp.vcxproj | 4 +- .../ServoApp/ServoControl/OpenGLES.cpp | 48 -- .../hololens/ServoApp/ServoControl/OpenGLES.h | 11 +- .../hololens/ServoApp/ServoControl/Servo.cpp | 11 +- .../hololens/ServoApp/ServoControl/Servo.h | 6 +- .../ServoApp/ServoControl/ServoControl.cpp | 49 +- .../ServoApp/ServoControl/ServoControl.h | 12 +- support/hololens/ServoApp/packages.config | 2 +- .../css-images/gradients-with-border.html.ini | 4 + .../css/text_node_opacity.html.ini | 2 - .../meta/css/text_node_opacity.html.ini | 2 - tests/wpt/webgl/meta/MANIFEST.json | 2 +- .../gl-disabled-vertex-attrib.html.ini | 6 + ...x-attrib-unconsumed-out-of-bounds.html.ini | 4 + .../gl-vertex-attrib-zero-issues.html.ini | 42 ++ ...le-instanced-arrays-out-of-bounds.html.ini | 5 +- ...ader-varying-packing-restrictions.html.ini | 59 +- .../misc/shaders-with-invariance.html.ini | 12 + ...d-attrib-location-long-names-test.html.ini | 10 + .../gl-bind-attrib-location-test.html.ini | 10 + .../reading/read-pixels-test.html.ini | 61 ++- .../renderbuffers/feedback-loop.html.ini | 3 + .../rendering/line-rendering-quality.html.ini | 8 + .../rendering/point-no-attributes.html.ini | 6 + .../rendering-stencil-large-viewport.html.ini | 2 - .../misc/copy-tex-image-2d-formats.html.ini | 18 + .../copy-tex-image-and-sub-image-2d.html.ini | 2 + ...ut-of-bounds-uniform-array-access.html.ini | 6 +- .../bound-buffer-size-change-test.html.ini | 100 ++++ ...-dynamic-indexing-swizzled-lvalue.html.ini | 6 + .../read-pixels-pack-parameters.html.ini | 58 ++ .../framebuffer-object-attachment.html.ini | 2 + .../renderbuffers/framebuffer-test.html.ini | 4 + .../invalidate-framebuffer.html.ini | 5 +- ...litframebuffer-filter-outofbounds.html.ini | 36 +- ...amebuffer-multisampled-readbuffer.html.ini | 19 +- ...litframebuffer-outside-readbuffer.html.ini | 6 +- .../blitframebuffer-scissor-enabled.html.ini | 12 +- .../clear-func-buffer-type-match.html.ini | 30 +- .../framebuffer-unsupported.html.ini | 6 +- ...r-type-mismatch-color-buffer-type.html.ini | 27 +- .../rendering/line-rendering-quality.html.ini | 4 + .../rendering/rgb-format-support.html.ini | 27 +- .../uniform-block-buffer-size.html.ini | 4 + .../state/gl-object-get-calls.html.ini | 6 + .../too-small-buffers.html.ini | 360 +++++++++++- ...unwritten-output-defaults-to-zero.html.ini | 4 - .../shader-varying-packing-restrictions.html | 15 +- .../webgl/tools/import-conformance-tests.py | 1 + .../shader-varying-packing-restrictions.patch | 54 ++ 94 files changed, 2265 insertions(+), 1513 deletions(-) create mode 100644 components/webrender_surfman/Cargo.toml create mode 100644 components/webrender_surfman/lib.rs delete mode 100644 ports/glutin/context.rs create mode 100644 tests/wpt/metadata/css/css-images/gradients-with-border.html.ini delete mode 100644 tests/wpt/mozilla/meta-layout-2020/css/text_node_opacity.html.ini delete mode 100644 tests/wpt/mozilla/meta/css/text_node_opacity.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/attribs/gl-disabled-vertex-attrib.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-zero-issues.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-long-names-test.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-test.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/rendering/line-rendering-quality.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/rendering/point-no-attributes.html.ini delete mode 100644 tests/wpt/webgl/meta/conformance/rendering/rendering-stencil-large-viewport.html.ini create mode 100644 tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-2d-formats.html.ini create mode 100644 tests/wpt/webgl/meta/conformance2/buffers/bound-buffer-size-change-test.html.ini create mode 100644 tests/wpt/webgl/meta/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html.ini create mode 100644 tests/wpt/webgl/meta/conformance2/reading/read-pixels-pack-parameters.html.ini create mode 100644 tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini delete mode 100644 tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini create mode 100644 tests/wpt/webgl/tools/shader-varying-packing-restrictions.patch diff --git a/Cargo.lock b/Cargo.lock index ab8a04885f6..4cab8f65ada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -502,12 +502,13 @@ dependencies = [ "raqote", "servo_config", "sparkle", - "surfman 0.1.4", - "surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "surfman", + "surfman-chains", "surfman-chains-api", "time", "webrender", "webrender_api", + "webrender_surfman", "webrender_traits", "webxr-api", ] @@ -591,6 +592,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg_aliases" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6da2b592f5a2e590c3d94c44313bab369f2286cfe1e4134c830bf3317814866" + [[package]] name = "cgl" version = "0.2.3" @@ -772,6 +779,7 @@ dependencies = [ "toml", "webrender", "webrender_api", + "webrender_surfman", "webxr", ] @@ -3203,11 +3211,12 @@ dependencies = [ "sparkle", "style", "style_traits", - "surfman 0.1.4", + "surfman", "webdriver_server", "webgpu", "webrender", "webrender_api", + "webrender_surfman", "webrender_traits", "webxr", "webxr-api", @@ -3976,11 +3985,6 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" -[[package]] -name = "osmesa-src" -version = "0.1.1" -source = "git+https://github.com/servo/osmesa-src#1a9519c3675ebc1117cbb18ed6db420b5941cb8b" - [[package]] name = "osmesa-sys" version = "0.1.2" @@ -4946,22 +4950,21 @@ dependencies = [ "euclid", "getopts", "gleam 0.9.2", - "glutin", "image", "keyboard-types", "lazy_static", "libc", "libservo", "log", - "osmesa-src", - "osmesa-sys", "servo-media", "shellwords", "sig", + "surfman", "tinyfiledialogs", "webxr", "webxr-api", "winapi", + "winit", "winres", ] @@ -5025,8 +5028,8 @@ dependencies = [ "log", "servo-media", "sparkle", - "surfman 0.2.0", - "surfman-chains 0.3.0 (git+https://github.com/asajeffrey/surfman-chains?branch=multi)", + "surfman", + "surfman-chains", "surfman-chains-api", ] @@ -5370,6 +5373,7 @@ dependencies = [ "libservo", "log", "servo-media", + "surfman", "webxr", "webxr-api", "winapi", @@ -5386,6 +5390,7 @@ dependencies = [ "libc", "log", "simpleservo", + "surfman", "winapi", ] @@ -5676,47 +5681,20 @@ dependencies = [ "webrender_api", ] -[[package]] -name = "surfman" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bf043642ad98aaa51956091c4f829a400bad5f023b5f0095ecda61f925c63d" -dependencies = [ - "bitflags", - "cgl 0.3.2", - "cocoa 0.19.1", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "display-link", - "euclid", - "gl_generator 0.11.0", - "io-surface", - "lazy_static", - "libc", - "log", - "mach", - "objc", - "osmesa-sys", - "wayland-sys 0.24.0", - "winapi", - "winit", - "wio", - "x11", -] - [[package]] name = "surfman" version = "0.2.0" -source = "git+https://github.com/pcwalton/surfman?branch=multi#fb782262617e7ca839a4e487b116a5199afaf963" +source = "git+https://github.com/servo/surfman#41ac1ee64bc2d1978aeed0f8bf549c57f20ec7c8" dependencies = [ "bitflags", + "cfg_aliases", "cgl 0.3.2", "cocoa 0.19.1", "core-foundation 0.6.4", "core-graphics 0.17.3", "display-link", "euclid", - "gl_generator 0.11.0", + "gl_generator 0.13.1", "io-surface", "lazy_static", "libc", @@ -5734,27 +5712,13 @@ dependencies = [ [[package]] name = "surfman-chains" version = "0.3.0" -source = "git+https://github.com/asajeffrey/surfman-chains?branch=multi#e775b8c7807659958a4f20cf8e6eca4290f35124" +source = "git+https://github.com/asajeffrey/surfman-chains#b949a240d73ef86d3c4bd22bc3d93933fac21ee9" dependencies = [ "euclid", "fnv", "log", "sparkle", - "surfman 0.2.0", - "surfman-chains-api", -] - -[[package]] -name = "surfman-chains" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a679f5be9644bbf93662f3b1a704cc6b81c147d4b7d6d5c8d8b6f453176f01" -dependencies = [ - "euclid", - "fnv", - "log", - "sparkle", - "surfman 0.1.4", + "surfman", "surfman-chains-api", ] @@ -6591,18 +6555,28 @@ dependencies = [ "sha2", ] +[[package]] +name = "webrender_surfman" +version = "0.0.1" +dependencies = [ + "euclid", + "surfman", + "surfman-chains", +] + [[package]] name = "webrender_traits" version = "0.0.1" dependencies = [ "euclid", + "servo_geometry", "webrender_api", ] [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#373a2fa762a859054070dad921ace05bea9fa712" +source = "git+https://github.com/servo/webxr#0d9c83f333920b98d95adf9666b0a365258990a3" dependencies = [ "android_injected_glue", "bindgen", @@ -6615,8 +6589,8 @@ dependencies = [ "log", "openxr", "serde", - "surfman 0.1.4", - "surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "surfman", + "surfman-chains", "time", "webxr-api", "winapi", @@ -6626,7 +6600,7 @@ dependencies = [ [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#373a2fa762a859054070dad921ace05bea9fa712" +source = "git+https://github.com/servo/webxr#0d9c83f333920b98d95adf9666b0a365258990a3" dependencies = [ "euclid", "ipc-channel", diff --git a/Cargo.toml b/Cargo.toml index 253038351bd..747681deaf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,3 +32,5 @@ mio = { git = "https://github.com/servo/mio.git", branch = "servo" } winapi = { git = "https://github.com/servo/winapi-rs", branch = "patch-1" } spirv_cross = { git = "https://github.com/servo/spirv_cross", branch = "wgpu-servo" } backtrace = { git = "https://github.com/MeFisto94/backtrace-rs", branch = "fix-strtab-freeing-crash" } +surfman-chains = { git = "https://github.com/asajeffrey/surfman-chains" } +surfman = { git = "https://github.com/servo/surfman" } diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 0917ad981a0..9dba07b7a15 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -38,9 +38,10 @@ servo_config = {path = "../config"} sparkle = "0.1.22" webrender = {git = "https://github.com/servo/webrender"} webrender_api = {git = "https://github.com/servo/webrender"} +webrender_surfman = {path = "../webrender_surfman"} webrender_traits = {path = "../webrender_traits"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} # NOTE: the sm-angle feature only enables angle on windows, not other platforms! -surfman = { version = "0.1", features = ["sm-angle", "sm-osmesa"] } +surfman = { version = "0.2", features = ["sm-angle","sm-angle-default"] } surfman-chains = "0.3" surfman-chains-api = "0.2" diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index a5707c29069..ff744481770 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -15,19 +15,19 @@ use std::collections::HashMap; use std::default::Default; use std::rc::Rc; use std::sync::{Arc, Mutex}; -use surfman::platform::generic::universal::context::Context; -use surfman::platform::generic::universal::device::Device; -use surfman::platform::generic::universal::surface::SurfaceTexture; +use surfman::Device; use surfman::SurfaceInfo; +use surfman::SurfaceTexture; use surfman_chains::SwapChains; use surfman_chains_api::SwapChainAPI; use surfman_chains_api::SwapChainsAPI; +use webrender_surfman::WebrenderSurfman; use webrender_traits::{WebrenderExternalImageApi, WebrenderExternalImageRegistry}; use webxr_api::SwapChainId as WebXRSwapChainId; pub struct WebGLComm { pub webgl_threads: WebGLThreads, - pub webxr_swap_chains: SwapChains, + pub webxr_swap_chains: SwapChains, pub webxr_surface_providers: SurfaceProviders, pub image_handler: Box, pub output_handler: Option>, @@ -37,8 +37,7 @@ pub struct WebGLComm { impl WebGLComm { /// Creates a new `WebGLComm` object. pub fn new( - device: Device, - context: Context, + surfman: WebrenderSurfman, webrender_gl: Rc, webrender_api_sender: webrender_api::RenderApiSender, external_images: Arc>, @@ -60,8 +59,8 @@ impl WebGLComm { webrender_swap_chains: webrender_swap_chains.clone(), webxr_swap_chains: webxr_swap_chains.clone(), webxr_surface_providers: webxr_surface_providers.clone(), - connection: device.connection(), - adapter: device.adapter(), + connection: surfman.connection(), + adapter: surfman.adapter(), api_type, runnable_receiver, }; @@ -72,7 +71,7 @@ impl WebGLComm { None }; - let external = WebGLExternalImages::new(device, context, webrender_swap_chains); + let external = WebGLExternalImages::new(surfman, webrender_swap_chains); WebGLThread::run_on_own_thread(init); @@ -89,23 +88,15 @@ impl WebGLComm { /// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads. struct WebGLExternalImages { - device: Device, - context: Context, - swap_chains: SwapChains, + surfman: WebrenderSurfman, + swap_chains: SwapChains, locked_front_buffers: FnvHashMap, } -impl Drop for WebGLExternalImages { - fn drop(&mut self) { - let _ = self.device.destroy_context(&mut self.context); - } -} - impl WebGLExternalImages { - fn new(device: Device, context: Context, swap_chains: SwapChains) -> Self { + fn new(surfman: WebrenderSurfman, swap_chains: SwapChains) -> Self { Self { - device, - context, + surfman, swap_chains, locked_front_buffers: FnvHashMap::default(), } @@ -119,13 +110,10 @@ impl WebGLExternalImages { id: front_buffer_id, size, .. - } = self.device.surface_info(&front_buffer); + } = self.surfman.surface_info(&front_buffer); debug!("... getting texture for surface {:?}", front_buffer_id); - let front_buffer_texture = self - .device - .create_surface_texture(&mut self.context, front_buffer) - .unwrap(); - let gl_texture = front_buffer_texture.gl_texture(); + let front_buffer_texture = self.surfman.create_surface_texture(front_buffer).unwrap(); + let gl_texture = self.surfman.surface_texture_object(&front_buffer_texture); self.locked_front_buffers.insert(id, front_buffer_texture); @@ -135,8 +123,8 @@ impl WebGLExternalImages { fn unlock_swap_chain(&mut self, id: WebGLContextId) -> Option<()> { let locked_front_buffer = self.locked_front_buffers.remove(&id)?; let locked_front_buffer = self - .device - .destroy_surface_texture(&mut self.context, locked_front_buffer) + .surfman + .destroy_surface_texture(locked_front_buffer) .unwrap(); debug!("... unlocked chain {:?}", id); diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index bb643bf3192..a8736e39280 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -47,7 +47,6 @@ use euclid::default::Size2D; use fnv::FnvHashMap; use half::f16; use pixels::{self, PixelFormat}; -use servo_config::opts; use sparkle::gl; use sparkle::gl::GLint; use sparkle::gl::GLuint; @@ -59,12 +58,12 @@ use std::slice; use std::sync::{Arc, Mutex}; use std::thread; use surfman; -use surfman::platform::generic::universal::adapter::Adapter; -use surfman::platform::generic::universal::connection::Connection; -use surfman::platform::generic::universal::context::Context; -use surfman::platform::generic::universal::device::Device; +use surfman::Adapter; +use surfman::Connection; +use surfman::Context; use surfman::ContextAttributeFlags; use surfman::ContextAttributes; +use surfman::Device; use surfman::GLVersion; use surfman::SurfaceAccess; use surfman::SurfaceInfo; @@ -87,30 +86,130 @@ struct GLContextData { attributes: GLContextAttributes, } +#[derive(Debug)] pub struct GLState { webgl_version: WebGLVersion, gl_version: GLVersion, + requested_flags: ContextAttributeFlags, + // This is the WebGL view of the color mask + // The GL view may be different: if the GL context supports alpha + // but the WebGL context doesn't, then color_write_mask.3 might be true + // but the GL color write mask is false. + color_write_mask: [bool; 4], clear_color: (f32, f32, f32, f32), scissor_test_enabled: bool, + // The WebGL view of the stencil write mask (see comment re `color_write_mask`) stencil_write_mask: (u32, u32), + stencil_test_enabled: bool, stencil_clear_value: i32, + // The WebGL view of the depth write mask (see comment re `color_write_mask`) depth_write_mask: bool, + depth_test_enabled: bool, depth_clear_value: f64, + // True when the default framebuffer is bound to DRAW_FRAMEBUFFER + drawing_to_default_framebuffer: bool, default_vao: gl::GLuint, } +impl GLState { + // Are we faking having no alpha / depth / stencil? + fn fake_no_alpha(&self) -> bool { + self.drawing_to_default_framebuffer & + !self.requested_flags.contains(ContextAttributeFlags::ALPHA) + } + + fn fake_no_depth(&self) -> bool { + self.drawing_to_default_framebuffer & + !self.requested_flags.contains(ContextAttributeFlags::DEPTH) + } + + fn fake_no_stencil(&self) -> bool { + self.drawing_to_default_framebuffer & + !self + .requested_flags + .contains(ContextAttributeFlags::STENCIL) + } + + // We maintain invariants between the GLState object and the GL state. + fn restore_invariant(&self, gl: &Gl) { + self.restore_clear_color_invariant(gl); + self.restore_scissor_invariant(gl); + self.restore_alpha_invariant(gl); + self.restore_depth_invariant(gl); + self.restore_stencil_invariant(gl); + } + + fn restore_clear_color_invariant(&self, gl: &Gl) { + let (r, g, b, a) = self.clear_color; + gl.clear_color(r, g, b, a); + } + + fn restore_scissor_invariant(&self, gl: &Gl) { + if self.scissor_test_enabled { + gl.enable(gl::SCISSOR_TEST); + } else { + gl.disable(gl::SCISSOR_TEST); + } + } + + fn restore_alpha_invariant(&self, gl: &Gl) { + let [r, g, b, a] = self.color_write_mask; + if self.fake_no_alpha() { + gl.color_mask(r, g, b, false); + } else { + gl.color_mask(r, g, b, a); + } + } + + fn restore_depth_invariant(&self, gl: &Gl) { + if self.fake_no_depth() { + gl.depth_mask(false); + gl.disable(gl::DEPTH_TEST); + } else { + gl.depth_mask(self.depth_write_mask); + if self.depth_test_enabled { + gl.enable(gl::DEPTH_TEST); + } else { + gl.disable(gl::DEPTH_TEST); + } + } + } + + fn restore_stencil_invariant(&self, gl: &Gl) { + if self.fake_no_stencil() { + gl.stencil_mask(0); + gl.disable(gl::STENCIL_TEST); + } else { + let (f, b) = self.stencil_write_mask; + gl.stencil_mask_separate(gl::FRONT, f); + gl.stencil_mask_separate(gl::BACK, b); + if self.stencil_test_enabled { + gl.enable(gl::STENCIL_TEST); + } else { + gl.disable(gl::STENCIL_TEST); + } + } + } +} + impl Default for GLState { fn default() -> GLState { GLState { gl_version: GLVersion { major: 1, minor: 0 }, webgl_version: WebGLVersion::WebGL1, + requested_flags: ContextAttributeFlags::empty(), + color_write_mask: [true, true, true, true], clear_color: (0., 0., 0., 0.), scissor_test_enabled: false, + // Should these be 0xFFFF_FFFF? stencil_write_mask: (0, 0), + stencil_test_enabled: false, stencil_clear_value: 0, depth_write_mask: true, + depth_test_enabled: false, depth_clear_value: 1., default_vao: 0, + drawing_to_default_framebuffer: true, } } } @@ -138,9 +237,9 @@ pub(crate) struct WebGLThread { /// The receiver that should be used to send WebGL messages for processing. sender: WebGLSender, /// The swap chains used by webrender - webrender_swap_chains: SwapChains, + webrender_swap_chains: SwapChains, /// The swap chains used by webxr - webxr_swap_chains: SwapChains, + webxr_swap_chains: SwapChains, /// The set of all surface providers corresponding to WebXR sessions. webxr_surface_providers: SurfaceProviders, /// A channel to allow arbitrary threads to execute tasks that run in the WebGL thread. @@ -150,9 +249,9 @@ pub(crate) struct WebGLThread { } pub type WebGlExecutor = crossbeam_channel::Sender; -pub type WebGlRunnable = Box; +pub type WebGlRunnable = Box; pub type SurfaceProviders = Arc>>; -pub type SurfaceProvider = Box; +pub type SurfaceProvider = Box + Send>; /// The data required to initialize an instance of the WebGLThread type. pub(crate) struct WebGLThreadInit { @@ -161,8 +260,8 @@ pub(crate) struct WebGLThreadInit { pub external_images: Arc>, pub sender: WebGLSender, pub receiver: WebGLReceiver, - pub webrender_swap_chains: SwapChains, - pub webxr_swap_chains: SwapChains, + pub webrender_swap_chains: SwapChains, + pub webxr_swap_chains: SwapChains, pub connection: Connection, pub adapter: Adapter, pub api_type: gl::GlType, @@ -190,7 +289,9 @@ impl WebGLThread { }: WebGLThreadInit, ) -> Self { WebGLThread { - device: Device::new(&connection, &adapter).expect("Couldn't open WebGL device!"), + device: connection + .create_device(&adapter) + .expect("Couldn't open WebGL device!"), webrender_api: webrender_api_sender.create_api(), contexts: Default::default(), cached_context_info: Default::default(), @@ -236,7 +337,7 @@ impl WebGLThread { } recv(self.runnable_receiver) -> msg => { if let Ok(msg) = msg { - msg(); + msg(&self.device); } else { self.runnable_receiver = crossbeam_channel::never(); } @@ -303,7 +404,7 @@ impl WebGLThread { .unwrap(); }, WebGLMsg::ResizeContext(ctx_id, size, sender) => { - self.resize_webgl_context(ctx_id, size, sender); + let _ = sender.send(self.resize_webgl_context(ctx_id, size)); }, WebGLMsg::RemoveContext(ctx_id) => { self.remove_webgl_context(ctx_id); @@ -394,21 +495,35 @@ impl WebGLThread { requested_size: Size2D, attributes: GLContextAttributes, ) -> Result<(WebGLContextId, webgl::GLLimits), String> { - debug!("WebGLThread::create_webgl_context({:?})", requested_size); + debug!( + "WebGLThread::create_webgl_context({:?}, {:?}, {:?})", + webgl_version, requested_size, attributes + ); // Creating a new GLContext may make the current bound context_id dirty. // Clear it to ensure that make_current() is called in subsequent commands. self.bound_context_id = None; + let requested_flags = + attributes.to_surfman_context_attribute_flags(webgl_version, self.api_type); + // Some GL implementations seem to only allow famebuffers + // to have alpha, depth and stencil if their creating context does. + // WebGL requires all contexts to be able to create framebuffers with + // alpha, depth and stencil. So we always create a context with them, + // and fake not having them if requested. + let flags = requested_flags | + ContextAttributeFlags::ALPHA | + ContextAttributeFlags::DEPTH | + ContextAttributeFlags::STENCIL; let context_attributes = &ContextAttributes { - version: webgl_version.to_surfman_version(), - flags: attributes.to_surfman_context_attribute_flags(webgl_version), + version: webgl_version.to_surfman_version(self.api_type), + flags: flags, }; let context_descriptor = self .device .create_context_descriptor(&context_attributes) - .unwrap(); + .map_err(|err| format!("Failed to create context descriptor: {:?}", err))?; let safe_size = Size2D::new( requested_size.width.min(SAFE_VIEWPORT_DIMS[0]).max(1), @@ -423,30 +538,30 @@ impl WebGLThread { let mut ctx = self .device .create_context(&context_descriptor) - .expect("Failed to create the GL context!"); + .map_err(|err| format!("Failed to create the GL context: {:?}", err))?; let surface = self .device - .create_surface(&ctx, surface_access, &surface_type) - .expect("Failed to create the initial surface!"); + .create_surface(&ctx, surface_access, surface_type) + .map_err(|err| format!("Failed to create the initial surface: {:?}", err))?; self.device .bind_surface_to_context(&mut ctx, surface) - .unwrap(); + .map_err(|err| format!("Failed to bind initial surface: {:?}", err))?; // https://github.com/pcwalton/surfman/issues/7 self.device .make_context_current(&ctx) - .expect("failed to make new context current"); + .map_err(|err| format!("Failed to make new context current: {:?}", err))?; let id = WebGLContextId( self.external_images .lock() - .unwrap() + .expect("Lock poisoned?") .next_id(WebrenderImageHandlerType::WebGL) .0, ); self.webrender_swap_chains .create_attached_swap_chain(id, &mut self.device, &mut ctx, surface_provider) - .expect("Failed to create the swap chain"); + .map_err(|err| format!("Failed to create swap chain: {:?}", err))?; let swap_chain = self .webrender_swap_chains @@ -456,7 +571,7 @@ impl WebGLThread { debug!( "Created webgl context {:?}/{:?}", id, - self.device.context_id(&ctx) + self.device.context_id(&ctx), ); let gl = match self.api_type { @@ -475,34 +590,33 @@ impl WebGLThread { debug!("Resizing swap chain from {} to {}", safe_size, size); swap_chain .resize(&mut self.device, &mut ctx, size.to_i32()) - .expect("Failed to resize swap chain"); + .map_err(|err| format!("Failed to resize swap chain: {:?}", err))?; } + let descriptor = self.device.context_descriptor(&ctx); + let descriptor_attributes = self.device.context_descriptor_attributes(&descriptor); + let gl_version = descriptor_attributes.version; + let has_alpha = requested_flags.contains(ContextAttributeFlags::ALPHA); + let texture_target = current_wr_texture_target(&self.device); + self.device.make_context_current(&ctx).unwrap(); let framebuffer = self .device .context_surface_info(&ctx) - .unwrap() - .unwrap() + .map_err(|err| format!("Failed to get context surface info: {:?}", err))? + .ok_or_else(|| format!("Failed to get context surface info"))? .framebuffer_object; + gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer); gl.viewport(0, 0, size.width as i32, size.height as i32); gl.scissor(0, 0, size.width as i32, size.height as i32); - gl.clear_color(0., 0., 0., 0.); + gl.clear_color(0., 0., 0., !has_alpha as u32 as f32); gl.clear_depth(1.); gl.clear_stencil(0); gl.clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); + gl.clear_color(0., 0., 0., 0.); debug_assert_eq!(gl.get_error(), gl::NO_ERROR); - let descriptor = self.device.context_descriptor(&ctx); - let descriptor_attributes = self.device.context_descriptor_attributes(&descriptor); - - let gl_version = descriptor_attributes.version; - let has_alpha = descriptor_attributes - .flags - .contains(ContextAttributeFlags::ALPHA); - let texture_target = current_wr_texture_target(&self.device); - let use_apple_vertex_array = WebGLImpl::needs_apple_vertex_arrays(gl_version); let default_vao = if let Some(vao) = WebGLImpl::create_vertex_array(&gl, use_apple_vertex_array, webgl_version) @@ -517,9 +631,15 @@ impl WebGLThread { let state = GLState { gl_version, webgl_version, + requested_flags, default_vao, ..Default::default() }; + debug!("Created state {:?}", state); + + state.restore_invariant(&*gl); + debug_assert_eq!(gl.get_error(), gl::NO_ERROR); + self.contexts.insert( id, GLContextData { @@ -549,8 +669,7 @@ impl WebGLThread { &mut self, context_id: WebGLContextId, requested_size: Size2D, - sender: WebGLSender>, - ) { + ) -> Result<(), String> { let data = Self::make_current_if_needed_mut( &self.device, context_id, @@ -568,16 +687,17 @@ impl WebGLThread { // Resize the swap chains if let Some(swap_chain) = self.webrender_swap_chains.get(context_id) { + let alpha = data + .state + .requested_flags + .contains(ContextAttributeFlags::ALPHA); + let clear_color = [0.0, 0.0, 0.0, !alpha as i32 as f32]; swap_chain .resize(&mut self.device, &mut data.ctx, size.to_i32()) - .expect("Failed to resize swap chain"); - // temporary, till https://github.com/pcwalton/surfman/issues/35 is fixed - self.device - .make_context_current(&data.ctx) - .expect("Failed to make context current again"); + .map_err(|err| format!("Failed to resize swap chain: {:?}", err))?; swap_chain - .clear_surface(&mut self.device, &mut data.ctx, &*data.gl) - .expect("Failed to clear resized swap chain"); + .clear_surface(&mut self.device, &mut data.ctx, &*data.gl, clear_color) + .map_err(|err| format!("Failed to clear resized swap chain: {:?}", err))?; } else { error!("Failed to find swap chain"); } @@ -587,11 +707,9 @@ impl WebGLThread { // Update WR image if needed. let info = self.cached_context_info.get_mut(&context_id).unwrap(); - let context_descriptor = self.device.context_descriptor(&data.ctx); - let has_alpha = self - .device - .context_descriptor_attributes(&context_descriptor) - .flags + let has_alpha = data + .state + .requested_flags .contains(ContextAttributeFlags::ALPHA); let texture_target = current_wr_texture_target(&self.device); Self::update_wr_external_image( @@ -605,7 +723,7 @@ impl WebGLThread { debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR); - sender.send(Ok(())).unwrap(); + Ok(()) } /// Removes a WebGLContext and releases attached resources. @@ -697,8 +815,13 @@ impl WebGLThread { // TODO: if preserveDrawingBuffer is true, then blit the front buffer to the back buffer // https://github.com/servo/servo/issues/24604 debug!("Clearing {:?}", swap_id); + let alpha = data + .state + .requested_flags + .contains(ContextAttributeFlags::ALPHA); + let clear_color = [0.0, 0.0, 0.0, !alpha as i32 as f32]; swap_chain - .clear_surface(&mut self.device, &mut data.ctx, &*data.gl) + .clear_surface(&mut self.device, &mut data.ctx, &*data.gl, clear_color) .unwrap(); debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR); @@ -1084,7 +1207,10 @@ impl WebGLImpl { state.stencil_clear_value = stencil; gl.clear_stencil(stencil); }, - WebGLCommand::ColorMask(r, g, b, a) => gl.color_mask(r, g, b, a), + WebGLCommand::ColorMask(r, g, b, a) => { + state.color_write_mask = [r, g, b, a]; + state.restore_alpha_invariant(gl); + }, WebGLCommand::CopyTexImage2D( target, level, @@ -1109,22 +1235,40 @@ impl WebGLImpl { WebGLCommand::DepthFunc(func) => gl.depth_func(func), WebGLCommand::DepthMask(flag) => { state.depth_write_mask = flag; - gl.depth_mask(flag); + state.restore_depth_invariant(gl); }, WebGLCommand::DepthRange(near, far) => { gl.depth_range(near.max(0.).min(1.) as f64, far.max(0.).min(1.) as f64) }, - WebGLCommand::Disable(cap) => { - if cap == gl::SCISSOR_TEST { + WebGLCommand::Disable(cap) => match cap { + gl::SCISSOR_TEST => { state.scissor_test_enabled = false; - } - gl.disable(cap); + state.restore_scissor_invariant(gl); + }, + gl::DEPTH_TEST => { + state.depth_test_enabled = false; + state.restore_depth_invariant(gl); + }, + gl::STENCIL_TEST => { + state.stencil_test_enabled = false; + state.restore_stencil_invariant(gl); + }, + _ => gl.disable(cap), }, - WebGLCommand::Enable(cap) => { - if cap == gl::SCISSOR_TEST { + WebGLCommand::Enable(cap) => match cap { + gl::SCISSOR_TEST => { state.scissor_test_enabled = true; - } - gl.enable(cap); + state.restore_scissor_invariant(gl); + }, + gl::DEPTH_TEST => { + state.depth_test_enabled = true; + state.restore_depth_invariant(gl); + }, + gl::STENCIL_TEST => { + state.stencil_test_enabled = true; + state.restore_stencil_invariant(gl); + }, + _ => gl.enable(cap), }, WebGLCommand::FramebufferRenderbuffer(target, attachment, renderbuffertarget, rb) => { let attach = |attachment| { @@ -1221,7 +1365,7 @@ impl WebGLImpl { }, WebGLCommand::StencilMask(mask) => { state.stencil_write_mask = (mask, mask); - gl.stencil_mask(mask); + state.restore_stencil_invariant(gl); }, WebGLCommand::StencilMaskSeparate(face, mask) => { if face == gl::FRONT { @@ -1229,7 +1373,7 @@ impl WebGLImpl { } else { state.stencil_write_mask.1 = mask; } - gl.stencil_mask_separate(face, mask); + state.restore_stencil_invariant(gl); }, WebGLCommand::StencilOp(fail, zfail, zpass) => gl.stencil_op(fail, zfail, zpass), WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass) => { @@ -1321,7 +1465,7 @@ impl WebGLImpl { gl.bind_buffer(target, id.map_or(0, WebGLBufferId::get)) }, WebGLCommand::BindFramebuffer(target, request) => { - Self::bind_framebuffer(gl, target, request, ctx, device) + Self::bind_framebuffer(gl, target, request, ctx, device, state) }, WebGLCommand::BindRenderbuffer(target, id) => { gl.bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)) @@ -1557,11 +1701,15 @@ impl WebGLImpl { Self::bind_vertex_array(gl, id, use_apple_vertex_array, state.webgl_version); }, WebGLCommand::GetParameterBool(param, ref sender) => { - let mut value = [0]; - unsafe { - gl.get_boolean_v(param as u32, &mut value); - } - sender.send(value[0] != 0).unwrap() + let value = match param { + webgl::ParameterBool::DepthWritemask => state.depth_write_mask, + _ => unsafe { + let mut value = [0]; + gl.get_boolean_v(param as u32, &mut value); + value[0] != 0 + }, + }; + sender.send(value).unwrap() }, WebGLCommand::FenceSync(ref sender) => { let value = gl.fence_sync(gl::SYNC_GPU_COMMANDS_COMPLETE, 0); @@ -1588,19 +1736,25 @@ impl WebGLImpl { gl.delete_sync(sync_id.get() as *const _); }, WebGLCommand::GetParameterBool4(param, ref sender) => { - let mut value = [0; 4]; - unsafe { - gl.get_boolean_v(param as u32, &mut value); - } - let value = [value[0] != 0, value[1] != 0, value[2] != 0, value[3] != 0]; + let value = match param { + webgl::ParameterBool4::ColorWritemask => state.color_write_mask, + }; sender.send(value).unwrap() }, WebGLCommand::GetParameterInt(param, ref sender) => { - let mut value = [0]; - unsafe { - gl.get_integer_v(param as u32, &mut value); - } - sender.send(value[0]).unwrap() + let value = match param { + webgl::ParameterInt::AlphaBits if state.fake_no_alpha() => 0, + webgl::ParameterInt::DepthBits if state.fake_no_depth() => 0, + webgl::ParameterInt::StencilBits if state.fake_no_stencil() => 0, + webgl::ParameterInt::StencilWritemask => state.stencil_write_mask.0 as i32, + webgl::ParameterInt::StencilBackWritemask => state.stencil_write_mask.1 as i32, + _ => unsafe { + let mut value = [0]; + gl.get_integer_v(param as u32, &mut value); + value[0] + }, + }; + sender.send(value).unwrap() }, WebGLCommand::GetParameterInt2(param, ref sender) => { let mut value = [0; 2]; @@ -1978,15 +2132,25 @@ impl WebGLImpl { sender.send(value).unwrap(); }, WebGLCommand::BindBufferBase(target, index, id) => { - gl.bind_buffer_base(target, index, id.map_or(0, WebGLBufferId::get)) + // https://searchfox.org/mozilla-central/rev/13b081a62d3f3e3e3120f95564529257b0bf451c/dom/canvas/WebGLContextBuffers.cpp#208-210 + // BindBufferBase/Range will fail (on some drivers) if the buffer name has + // never been bound. (GenBuffers makes a name, but BindBuffer initializes + // that name as a real buffer object) + let id = id.map_or(0, WebGLBufferId::get); + gl.bind_buffer(target, id); + gl.bind_buffer(target, 0); + gl.bind_buffer_base(target, index, id); + }, + WebGLCommand::BindBufferRange(target, index, id, offset, size) => { + // https://searchfox.org/mozilla-central/rev/13b081a62d3f3e3e3120f95564529257b0bf451c/dom/canvas/WebGLContextBuffers.cpp#208-210 + // BindBufferBase/Range will fail (on some drivers) if the buffer name has + // never been bound. (GenBuffers makes a name, but BindBuffer initializes + // that name as a real buffer object) + let id = id.map_or(0, WebGLBufferId::get); + gl.bind_buffer(target, id); + gl.bind_buffer(target, 0); + gl.bind_buffer_range(target, index, id, offset as isize, size as isize); }, - WebGLCommand::BindBufferRange(target, index, id, offset, size) => gl.bind_buffer_range( - target, - index, - id.map_or(0, WebGLBufferId::get), - offset as isize, - size as isize, - ), WebGLCommand::ClearBufferfv(buffer, draw_buffer, ref value) => { gl.clear_buffer_fv(buffer, draw_buffer, value) }, @@ -2065,47 +2229,17 @@ impl WebGLImpl { bits | if enabled { bit } else { 0 } }); - if state.scissor_test_enabled { - gl.disable(gl::SCISSOR_TEST); - } - - if color { - gl.clear_color(0., 0., 0., 0.); - } - - if depth { - gl.depth_mask(true); - gl.clear_depth(1.); - } - - if stencil { - gl.stencil_mask_separate(gl::FRONT, 0xFFFFFFFF); - gl.stencil_mask_separate(gl::BACK, 0xFFFFFFFF); - gl.clear_stencil(0); - } - + gl.disable(gl::SCISSOR_TEST); + gl.color_mask(true, true, true, true); + gl.clear_color(0., 0., 0., 0.); + gl.depth_mask(true); + gl.clear_depth(1.); + gl.stencil_mask_separate(gl::FRONT, 0xFFFFFFFF); + gl.stencil_mask_separate(gl::BACK, 0xFFFFFFFF); + gl.clear_stencil(0); gl.clear(bits); - if state.scissor_test_enabled { - gl.enable(gl::SCISSOR_TEST); - } - - if color { - let (r, g, b, a) = state.clear_color; - gl.clear_color(r, g, b, a); - } - - if depth { - gl.depth_mask(state.depth_write_mask); - gl.clear_depth(state.depth_clear_value); - } - - if stencil { - let (front, back) = state.stencil_write_mask; - gl.stencil_mask_separate(gl::FRONT, front); - gl.stencil_mask_separate(gl::BACK, back); - gl.clear_stencil(state.stencil_clear_value); - } + state.restore_invariant(gl); } #[allow(unsafe_code)] @@ -2213,6 +2347,7 @@ impl WebGLImpl { &mut transform_feedback_mode, ); } + ProgramLinkInfo { linked: true, active_attribs, @@ -2243,7 +2378,7 @@ impl WebGLImpl { // array object functions, but support a set of APPLE extension functions that // provide VAO support instead. fn needs_apple_vertex_arrays(gl_version: GLVersion) -> bool { - cfg!(target_os = "macos") && !opts::get().headless && gl_version.major < 3 + cfg!(target_os = "macos") && gl_version.major < 3 } #[allow(unsafe_code)] @@ -2427,8 +2562,8 @@ impl WebGLImpl { /// Updates the swap buffers if the context surface needs to be changed fn attach_surface( context_id: WebGLContextId, - webrender_swap_chains: &SwapChains, - webxr_swap_chains: &SwapChains, + webrender_swap_chains: &SwapChains, + webxr_swap_chains: &SwapChains, request: WebGLFramebufferBindingRequest, ctx: &mut Context, device: &mut Device, @@ -2479,6 +2614,7 @@ impl WebGLImpl { request: WebGLFramebufferBindingRequest, ctx: &Context, device: &Device, + state: &mut GLState, ) { let id = match request { WebGLFramebufferBindingRequest::Explicit(WebGLFramebufferId::Transparent(id)) => { @@ -2496,6 +2632,12 @@ impl WebGLImpl { debug!("WebGLImpl::bind_framebuffer: {:?}", id); gl.bind_framebuffer(target, id); + + if (target == gl::FRAMEBUFFER) || (target == gl::DRAW_FRAMEBUFFER) { + state.drawing_to_default_framebuffer = + request == WebGLFramebufferBindingRequest::Default; + state.restore_invariant(gl); + } } #[inline] @@ -2885,27 +3027,41 @@ fn flip_pixels_y( // Clamp a size to the current GL context's max viewport fn clamp_viewport(gl: &Gl, size: Size2D) -> Size2D { - let mut max_size = [i32::max_value(), i32::max_value()]; + let mut max_viewport = [i32::max_value(), i32::max_value()]; + let mut max_renderbuffer = [i32::max_value()]; #[allow(unsafe_code)] unsafe { - gl.get_integer_v(gl::MAX_VIEWPORT_DIMS, &mut max_size); + gl.get_integer_v(gl::MAX_VIEWPORT_DIMS, &mut max_viewport); + gl.get_integer_v(gl::MAX_RENDERBUFFER_SIZE, &mut max_renderbuffer); debug_assert_eq!(gl.get_error(), gl::NO_ERROR); } Size2D::new( - size.width.min(max_size[0] as u32).max(1), - size.height.min(max_size[1] as u32).max(1), + size.width + .min(max_viewport[0] as u32) + .min(max_renderbuffer[0] as u32) + .max(1), + size.height + .min(max_viewport[1] as u32) + .min(max_renderbuffer[0] as u32) + .max(1), ) } trait ToSurfmanVersion { - fn to_surfman_version(self) -> GLVersion; + fn to_surfman_version(self, api_type: gl::GlType) -> GLVersion; } impl ToSurfmanVersion for WebGLVersion { - fn to_surfman_version(self) -> GLVersion { + fn to_surfman_version(self, api_type: gl::GlType) -> GLVersion { + if api_type == gl::GlType::Gles { + return GLVersion::new(3, 0); + } match self { - WebGLVersion::WebGL1 => GLVersion::new(2, 0), - WebGLVersion::WebGL2 => GLVersion::new(3, 0), + // We make use of GL_PACK_PIXEL_BUFFER, which needs at least GL2.1 + // We make use of compatibility mode, which needs at most GL3.0 + WebGLVersion::WebGL1 => GLVersion::new(2, 1), + // The WebGL2 conformance tests use std140 layout, which needs at GL3.1 + WebGLVersion::WebGL2 => GLVersion::new(3, 2), } } } @@ -2914,6 +3070,7 @@ trait SurfmanContextAttributeFlagsConvert { fn to_surfman_context_attribute_flags( &self, webgl_version: WebGLVersion, + api_type: gl::GlType, ) -> ContextAttributeFlags; } @@ -2921,12 +3078,13 @@ impl SurfmanContextAttributeFlagsConvert for GLContextAttributes { fn to_surfman_context_attribute_flags( &self, webgl_version: WebGLVersion, + api_type: gl::GlType, ) -> ContextAttributeFlags { let mut flags = ContextAttributeFlags::empty(); flags.set(ContextAttributeFlags::ALPHA, self.alpha); flags.set(ContextAttributeFlags::DEPTH, self.depth); flags.set(ContextAttributeFlags::STENCIL, self.stencil); - if webgl_version == WebGLVersion::WebGL1 { + if (webgl_version == WebGLVersion::WebGL1) && (api_type == gl::GlType::Gl) { flags.set(ContextAttributeFlags::COMPATIBILITY_PROFILE, true); } flags diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index e1537055280..510e20a590d 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -667,7 +667,7 @@ pub enum WebGLFramebufferId { Opaque(WebGLOpaqueFramebufferId), } -#[derive(Clone, Copy, Debug, Deserialize, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum WebGLFramebufferBindingRequest { Explicit(WebGLFramebufferId), Default, diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index a6dcd9894d1..50f1d6f8456 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -40,6 +40,7 @@ style_traits = {path = "../style_traits"} time = "0.1.17" webrender = {git = "https://github.com/servo/webrender", features = ["capture"]} webrender_api = {git = "https://github.com/servo/webrender"} +webrender_surfman = {path = "../webrender_surfman"} webxr = {git = "https://github.com/servo/webxr"} [build-dependencies] diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 19898928420..5a495ed1aa8 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -19,6 +19,7 @@ use gfx_traits::Epoch; use image::{DynamicImage, ImageFormat}; use ipc_channel::ipc; use libc::c_void; +use log::warn; use msg::constellation_msg::{PipelineId, PipelineIndex, PipelineNamespaceId}; use net_traits::image::base::Image; use net_traits::image_cache::CorsStatus; @@ -46,6 +47,7 @@ use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor}; use time::{now, precise_time_ns, precise_time_s}; use webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePoint, LayoutVector2D}; use webrender_api::{self, HitTestFlags, HitTestResult, ScrollLocation}; +use webrender_surfman::WebrenderSurfman; #[derive(Debug, PartialEq)] enum UnableToComposite { @@ -178,6 +180,12 @@ pub struct IOCompositor { /// The webrender interface, if enabled. webrender_api: webrender_api::RenderApi, + /// The surfman instance that webrender targets + webrender_surfman: WebrenderSurfman, + + /// The GL bindings for webrender + webrender_gl: Rc, + /// Some XR devices want to run on the main thread. pub webxr_main_thread: webxr::MainThreadRegistry, @@ -316,6 +324,8 @@ impl IOCompositor { webrender: state.webrender, webrender_document: state.webrender_document, webrender_api: state.webrender_api, + webrender_surfman: state.webrender_surfman, + webrender_gl: state.webrender_gl, webxr_main_thread: state.webxr_main_thread, pending_paint_metrics: HashMap::new(), cursor: Cursor::None, @@ -345,6 +355,9 @@ impl IOCompositor { convert_mouse_to_touch, ); + // Make sure the GL state is OK + compositor.assert_gl_framebuffer_complete(); + // Set the size of the root layer. compositor.update_zoom_transform(); @@ -352,7 +365,9 @@ impl IOCompositor { } pub fn deinit(self) { - self.window.make_gl_context_current(); + if let Err(err) = self.webrender_surfman.make_gl_context_current() { + warn!("Failed to make GL context current: {:?}", err); + } self.webrender.deinit(); } @@ -1238,7 +1253,22 @@ impl IOCompositor { ) -> Result, UnableToComposite> { let size = self.embedder_coordinates.framebuffer.to_u32(); - self.window.make_gl_context_current(); + if let Err(err) = self.webrender_surfman.make_gl_context_current() { + warn!("Failed to make GL context current: {:?}", err); + } + self.assert_no_gl_error(); + + // Bind the webrender framebuffer + let framebuffer_object = self + .webrender_surfman + .context_surface_info() + .unwrap_or(None) + .map(|info| info.framebuffer_object) + .unwrap_or(0); + self.webrender_gl + .bind_framebuffer(gleam::gl::FRAMEBUFFER, framebuffer_object); + self.assert_gl_framebuffer_complete(); + self.webrender.update(); let wait_for_stable_image = match target { @@ -1266,7 +1296,7 @@ impl IOCompositor { CompositeTarget::Window => gl::RenderTargetInfo::default(), #[cfg(feature = "gl")] CompositeTarget::WindowAndPng | CompositeTarget::PngFile => gl::initialize_png( - &*self.window.gl(), + &*self.webrender_gl, FramebufferUintLength::new(size.width), FramebufferUintLength::new(size.height), ), @@ -1347,7 +1377,7 @@ impl IOCompositor { #[cfg(feature = "gl")] CompositeTarget::WindowAndPng => { let img = gl::draw_img( - &*self.window.gl(), + &*self.webrender_gl, rt_info, x, y, @@ -1365,7 +1395,7 @@ impl IOCompositor { }, #[cfg(feature = "gl")] CompositeTarget::PngFile => { - let gl = &*self.window.gl(); + let gl = &*self.webrender_gl; profile( ProfilerCategory::ImageSaving, None, @@ -1399,7 +1429,9 @@ impl IOCompositor { }; // Perform the page flip. This will likely block for a while. - self.window.present(); + if let Err(err) = self.webrender_surfman.present() { + warn!("Failed to present surface: {:?}", err); + } self.last_composite_time = precise_time_ns(); @@ -1426,11 +1458,13 @@ impl IOCompositor { } fn clear_background(&self) { - let gl = self.window.gl(); + let gl = &self.webrender_gl; + self.assert_gl_framebuffer_complete(); // Make framebuffer fully transparent. gl.clear_color(0.0, 0.0, 0.0, 0.0); gl.clear(gleam::gl::COLOR_BUFFER_BIT); + self.assert_gl_framebuffer_complete(); // Make the viewport white. let viewport = self.embedder_coordinates.get_flipped_viewport(); @@ -1444,6 +1478,24 @@ impl IOCompositor { gl.enable(gleam::gl::SCISSOR_TEST); gl.clear(gleam::gl::COLOR_BUFFER_BIT); gl.disable(gleam::gl::SCISSOR_TEST); + self.assert_gl_framebuffer_complete(); + } + + #[track_caller] + fn assert_no_gl_error(&self) { + debug_assert_eq!(self.webrender_gl.get_error(), gleam::gl::NO_ERROR); + } + + #[track_caller] + fn assert_gl_framebuffer_complete(&self) { + debug_assert_eq!( + ( + self.webrender_gl.get_error(), + self.webrender_gl + .check_frame_buffer_status(gleam::gl::FRAMEBUFFER) + ), + (gleam::gl::NO_ERROR, gleam::gl::FRAMEBUFFER_COMPLETE) + ); } fn get_root_pipeline_id(&self) -> Option { diff --git a/components/compositing/compositor_thread.rs b/components/compositing/compositor_thread.rs index 245ed1055ea..cbd715af0dd 100644 --- a/components/compositing/compositor_thread.rs +++ b/components/compositing/compositor_thread.rs @@ -17,12 +17,14 @@ use profile_traits::mem; use profile_traits::time; use script_traits::{AnimationState, EventResult, MouseButton, MouseEventType}; use std::fmt::{Debug, Error, Formatter}; +use std::rc::Rc; use std::sync::atomic::AtomicBool; use std::sync::Arc; use style_traits::viewport::ViewportConstraints; use style_traits::CSSPixel; use webrender_api; use webrender_api::units::{DeviceIntPoint, DeviceIntSize}; +use webrender_surfman::WebrenderSurfman; /// Sends messages to the compositor. pub struct CompositorProxy { @@ -166,6 +168,8 @@ pub struct InitialCompositorState { pub webrender: webrender::Renderer, pub webrender_document: webrender_api::DocumentId, pub webrender_api: webrender_api::RenderApi, + pub webrender_surfman: WebrenderSurfman, + pub webrender_gl: Rc, pub webxr_main_thread: webxr::MainThreadRegistry, pub pending_wr_frame: Arc, } diff --git a/components/compositing/lib.rs b/components/compositing/lib.rs index cc4f86922ff..da11e95fd55 100644 --- a/components/compositing/lib.rs +++ b/components/compositing/lib.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #![deny(unsafe_code)] +#![feature(track_caller)] #[macro_use] extern crate log; diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index b3a48026e30..7a2784e08fd 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -7,8 +7,6 @@ use canvas::{SurfaceProviders, WebGlExecutor}; use embedder_traits::{EmbedderProxy, EventLoopWaker}; use euclid::Scale; -#[cfg(feature = "gl")] -use gleam::gl; use keyboard_types::KeyboardEvent; use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId, TraversalDirection}; use script_traits::{MediaSessionActionType, MouseButton, TouchEventType, TouchId, WheelDelta}; @@ -16,14 +14,13 @@ use servo_geometry::DeviceIndependentPixel; use servo_media::player::context::{GlApi, GlContext, NativeDisplay}; use servo_url::ServoUrl; use std::fmt::{Debug, Error, Formatter}; -#[cfg(feature = "gl")] -use std::rc::Rc; use std::time::Duration; use style_traits::DevicePixel; use webrender_api::units::DevicePoint; use webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize}; use webrender_api::ScrollLocation; +use webrender_surfman::WebrenderSurfman; #[derive(Clone)] pub enum MouseWindowEvent { @@ -148,14 +145,10 @@ pub enum AnimationState { Animating, } +// TODO: this trait assumes that the window is responsible +// for creating the GL context, making it current, buffer +// swapping, etc. Really that should all be done by surfman. pub trait WindowMethods { - /// Presents the window to the screen (perhaps by page flipping). - fn present(&self); - /// Make the OpenGL context current. - fn make_gl_context_current(&self); - /// Return the GL function pointer trait. - #[cfg(feature = "gl")] - fn gl(&self) -> Rc; /// Get the coordinates of the native window, the screen and the framebuffer. fn get_coordinates(&self) -> EmbedderCoordinates; /// Set whether the application is currently animating. @@ -163,12 +156,14 @@ pub trait WindowMethods { /// will want to avoid blocking on UI events, and just /// run the event loop at the vsync interval. fn set_animation_state(&self, _state: AnimationState); - /// Get the GL context + /// Get the media GL context fn get_gl_context(&self) -> GlContext; - /// Get the native display + /// Get the media native display fn get_native_display(&self) -> NativeDisplay; /// Get the GL api fn get_gl_api(&self) -> GlApi; + /// Get the webrender surfman instance + fn webrender_surfman(&self) -> WebrenderSurfman; } pub trait EmbedderMethods { diff --git a/components/config/prefs.rs b/components/config/prefs.rs index 82f4d6a0057..2561ebf937f 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -321,7 +321,11 @@ mod gen { subpixel_text_antialiasing: { #[serde(rename = "gfx.subpixel-text-antialiasing.enabled")] enabled: bool, - } + }, + texture_swizzling: { + #[serde(rename = "gfx.texture-swizzling.enabled")] + enabled: bool, + }, }, js: { asmjs: { diff --git a/components/script/dom/webgl_extensions/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs index 2dc3ef8f11f..04e110b7ed0 100644 --- a/components/script/dom/webgl_extensions/extensions.rs +++ b/components/script/dom/webgl_extensions/extensions.rs @@ -52,12 +52,24 @@ const DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL1: [GLenum; 3] = [ OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES, ]; +// Param names that are implemented for glGetParameter in a WebGL 2.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/ +const DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL2: [GLenum; 1] = + [EXTTextureFilterAnisotropicConstants::MAX_TEXTURE_MAX_ANISOTROPY_EXT]; + // Param names that are implemented for glGetTexParameter in a WebGL 1.0 context // but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. // Example: https://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/ const DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL1: [GLenum; 1] = [EXTTextureFilterAnisotropicConstants::TEXTURE_MAX_ANISOTROPY_EXT]; +// Param names that are implemented for glGetTexParameter in a WebGL 2.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/ +const DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL2: [GLenum; 1] = + [EXTTextureFilterAnisotropicConstants::TEXTURE_MAX_ANISOTROPY_EXT]; + // Param names that are implemented for glGetVertexAttrib in a WebGL 1.0 context // but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. // Example: https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/ @@ -116,8 +128,14 @@ impl WebGLExtensionFeatures { ), WebGLVersion::WebGL2 => ( Default::default(), - Default::default(), - Default::default(), + DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL2 + .iter() + .cloned() + .collect(), + DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL2 + .iter() + .cloned() + .collect(), Default::default(), true, true, diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index 51f1bdbad4e..f1a3ba99c53 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -233,7 +233,7 @@ impl WebGLRenderbuffer { ), ); let samples = receiver.recv().unwrap(); - if sample_count < 0 || sample_count as usize > samples.len() { + if sample_count < 0 || sample_count > samples.get(0).cloned().unwrap_or(0) { return Err(WebGLError::InvalidOperation); } } diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index 5302c6c78ad..9be334f6595 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -277,8 +277,49 @@ impl WebGLShader { }, }; - match validator.compile_and_translate(&[&source]) { - Ok(translated_source) => { + // Replicating + // https://searchfox.org/mozilla-central/rev/c621276fbdd9591f52009042d959b9e19b66d49f/dom/canvas/WebGLShaderValidator.cpp#32 + let options = mozangle::shaders::ffi::SH_VARIABLES | + mozangle::shaders::ffi::SH_ENFORCE_PACKING_RESTRICTIONS | + mozangle::shaders::ffi::SH_OBJECT_CODE | + mozangle::shaders::ffi::SH_INIT_GL_POSITION | + mozangle::shaders::ffi::SH_INITIALIZE_UNINITIALIZED_LOCALS | + mozangle::shaders::ffi::SH_INIT_OUTPUT_VARIABLES | + mozangle::shaders::ffi::SH_LIMIT_EXPRESSION_COMPLEXITY | + mozangle::shaders::ffi::SH_LIMIT_CALL_STACK_DEPTH | + if cfg!(target_os = "macos") { + // Work around https://bugs.webkit.org/show_bug.cgi?id=124684, + // https://chromium.googlesource.com/angle/angle/+/5e70cf9d0b1bb + mozangle::shaders::ffi::SH_UNFOLD_SHORT_CIRCUIT | + // Work around that Mac drivers handle struct scopes incorrectly. + mozangle::shaders::ffi::SH_REGENERATE_STRUCT_NAMES | + // Work around that Intel drivers on Mac OSX handle for-loop incorrectly. + mozangle::shaders::ffi::SH_ADD_AND_TRUE_TO_LOOP_CONDITION + } else { + // We want to do this everywhere, but to do this on Mac, we need + // to do it only on Mac OSX > 10.6 as this causes the shader + // compiler in 10.6 to crash + mozangle::shaders::ffi::SH_CLAMP_INDIRECT_ARRAY_BOUNDS + }; + + // Replicating + // https://github.com/servo/mozangle/blob/706a9baaf8026c1a3cb6c67ba63aa5f4734264d0/src/shaders/mod.rs#L226 + let options = options | + mozangle::shaders::ffi::SH_VALIDATE | + mozangle::shaders::ffi::SH_OBJECT_CODE | + mozangle::shaders::ffi::SH_VARIABLES | // For uniform_name_map() + mozangle::shaders::ffi::SH_EMULATE_ABS_INT_FUNCTION | // To workaround drivers + mozangle::shaders::ffi::SH_EMULATE_ISNAN_FLOAT_FUNCTION | // To workaround drivers + mozangle::shaders::ffi::SH_EMULATE_ATAN2_FLOAT_FUNCTION | // To workaround drivers + mozangle::shaders::ffi::SH_CLAMP_INDIRECT_ARRAY_BOUNDS | + mozangle::shaders::ffi::SH_INIT_GL_POSITION | + mozangle::shaders::ffi::SH_ENFORCE_PACKING_RESTRICTIONS | + mozangle::shaders::ffi::SH_LIMIT_EXPRESSION_COMPLEXITY | + mozangle::shaders::ffi::SH_LIMIT_CALL_STACK_DEPTH; + + match validator.compile(&[&source], options) { + Ok(()) => { + let translated_source = validator.object_code(); debug!("Shader translated: {}", translated_source); // NOTE: At this point we should be pretty sure that the compilation in the paint thread // will succeed. diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 68d3fa2cd6a..ca933bb848c 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -81,11 +81,12 @@ style_traits = {path = "../style_traits", features = ["servo"]} webgpu = {path = "../webgpu"} webrender = {git = "https://github.com/servo/webrender"} webrender_api = {git = "https://github.com/servo/webrender"} +webrender_surfman = {path = "../webrender_surfman"} webrender_traits = {path = "../webrender_traits"} webdriver_server = {path = "../webdriver_server", optional = true} webxr-api = {git = "https://github.com/servo/webxr"} webxr = {git = "https://github.com/servo/webxr"} -surfman = { version = "0.1", features = ["sm-osmesa"] } +surfman = "0.2" gstreamer = { version = "0.15", optional = true } [target.'cfg(all(not(target_os = "windows"), not(target_os = "ios"), not(target_os="android"), not(target_arch="arm"), not(target_arch="aarch64")))'.dependencies] diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 1bd9ace8035..82ac035fc4c 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -51,6 +51,7 @@ pub use style; pub use style_traits; pub use webgpu; pub use webrender_api; +pub use webrender_surfman; pub use webrender_traits; #[cfg(feature = "webdriver")] @@ -116,14 +117,9 @@ use std::path::PathBuf; use std::rc::Rc; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex}; -#[cfg(not(target_os = "windows"))] -use surfman::platform::default::device::Device as HWDevice; -#[cfg(not(target_os = "windows"))] -use surfman::platform::generic::osmesa::device::Device as SWDevice; -#[cfg(not(target_os = "windows"))] -use surfman::platform::generic::universal::context::Context; -use surfman::platform::generic::universal::device::Device; +use surfman::GLApi; use webrender::{RendererKind, ShaderPrecacheFlags}; +use webrender_surfman::WebrenderSurfman; use webrender_traits::WebrenderImageHandlerType; use webrender_traits::{WebrenderExternalImageHandlers, WebrenderExternalImageRegistry}; @@ -353,8 +349,28 @@ where .unwrap_or(default_user_agent_string_for(DEFAULT_USER_AGENT).into()), }; + // Initialize surfman + let webrender_surfman = window.webrender_surfman(); + + // Get GL bindings + let webrender_gl = match webrender_surfman.connection().gl_api() { + GLApi::GL => unsafe { gl::GlFns::load_with(|s| webrender_surfman.get_proc_address(s)) }, + GLApi::GLES => unsafe { + gl::GlesFns::load_with(|s| webrender_surfman.get_proc_address(s)) + }, + }; + // Make sure the gl context is made current. - window.make_gl_context_current(); + webrender_surfman.make_gl_context_current().unwrap(); + debug_assert_eq!(webrender_gl.get_error(), gleam::gl::NO_ERROR,); + + // Bind the webrender framebuffer + let framebuffer_object = webrender_surfman + .context_surface_info() + .unwrap_or(None) + .map(|info| info.framebuffer_object) + .unwrap_or(0); + webrender_gl.bind_framebuffer(gleam::gl::FRAMEBUFFER, framebuffer_object); // Reserving a namespace to create TopLevelBrowserContextId. PipelineNamespace::install(PipelineNamespaceId(0)); @@ -407,7 +423,7 @@ where let window_size = Size2D::from_untyped(viewport_size.to_i32().to_untyped()); webrender::Renderer::new( - window.gl(), + webrender_gl.clone(), render_notifier, webrender::RendererOptions { device_pixel_ratio, @@ -422,6 +438,7 @@ where }, renderer_kind: renderer_kind, enable_subpixel_aa: opts.enable_subpixel_text_antialiasing, + allow_texture_swizzling: pref!(gfx.texture_swizzling.enabled), clear_color: None, ..Default::default() }, @@ -451,7 +468,8 @@ where .expect("Failed to create WebXR device registry"); let (webgl_threads, webgl_extras) = create_webgl_threads( - &*window, + webrender_surfman.clone(), + webrender_gl.clone(), &mut webrender, webrender_api_sender.clone(), &mut webxr_main_thread, @@ -542,6 +560,8 @@ where webrender, webrender_document, webrender_api, + webrender_surfman, + webrender_gl, webxr_main_thread, pending_wr_frame, }, @@ -806,6 +826,10 @@ where log::set_max_level(filter); } + pub fn window(&self) -> &Window { + &self.compositor.window + } + pub fn deinit(self) { self.compositor.deinit(); } @@ -1030,8 +1054,9 @@ fn create_sandbox() { } // Initializes the WebGL thread. -fn create_webgl_threads( - window: &W, +fn create_webgl_threads( + webrender_surfman: WebrenderSurfman, + webrender_gl: Rc, webrender: &mut webrender::Renderer, webrender_api_sender: webrender_api::RenderApiSender, webxr_main_thread: &mut webxr::MainThreadRegistry, @@ -1040,45 +1065,8 @@ fn create_webgl_threads( ) -> ( Option, Option<(SurfaceProviders, WebGlExecutor)>, -) -where - W: WindowMethods + 'static + ?Sized, -{ - // Create a `surfman` device and context. - window.make_gl_context_current(); - - #[cfg(not(target_os = "windows"))] - let (device, context) = unsafe { - if opts::get().headless { - let (device, context) = match SWDevice::from_current_context() { - Ok(a) => a, - Err(e) => { - warn!("Failed to create software graphics context: {:?}", e); - return (None, None); - }, - }; - (Device::Software(device), Context::Software(context)) - } else { - let (device, context) = match HWDevice::from_current_context() { - Ok(a) => a, - Err(e) => { - warn!("Failed to create hardware graphics context: {:?}", e); - return (None, None); - }, - }; - (Device::Hardware(device), Context::Hardware(context)) - } - }; - #[cfg(target_os = "windows")] - let (device, context) = match unsafe { Device::from_current_context() } { - Ok(a) => a, - Err(e) => { - warn!("Failed to create graphics context: {:?}", e); - return (None, None); - }, - }; - - let gl_type = match window.gl().get_type() { +) { + let gl_type = match webrender_gl.get_type() { gleam::gl::GlType::Gl => sparkle::gl::GlType::Gl, gleam::gl::GlType::Gles => sparkle::gl::GlType::Gles, }; @@ -1091,9 +1079,8 @@ where output_handler, webgl_executor, } = WebGLComm::new( - device, - context, - window.gl(), + webrender_surfman, + webrender_gl, webrender_api_sender, external_images, gl_type, diff --git a/components/webrender_surfman/Cargo.toml b/components/webrender_surfman/Cargo.toml new file mode 100644 index 00000000000..e82f553d2cc --- /dev/null +++ b/components/webrender_surfman/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "webrender_surfman" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +edition = "2018" +publish = false + +[lib] +name = "webrender_surfman" +path = "lib.rs" + +[dependencies] +euclid = "0.20" +surfman = "0.2" +surfman-chains = "0.3" + diff --git a/components/webrender_surfman/lib.rs b/components/webrender_surfman/lib.rs new file mode 100644 index 00000000000..193298808bc --- /dev/null +++ b/components/webrender_surfman/lib.rs @@ -0,0 +1,213 @@ +/* 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 https://mozilla.org/MPL/2.0/. */ + +#![deny(unsafe_code)] + +use euclid::default::Size2D; + +use std::cell::RefCell; +use std::ffi::c_void; +use std::rc::Rc; +use surfman::Adapter; +use surfman::Connection; +use surfman::Context; +use surfman::ContextAttributeFlags; +use surfman::ContextAttributes; +use surfman::Device; +use surfman::Error; +use surfman::GLApi; +use surfman::GLVersion; +use surfman::NativeContext; +use surfman::NativeDevice; +use surfman::NativeWidget; +use surfman::Surface; +use surfman::SurfaceAccess; +use surfman::SurfaceInfo; +use surfman::SurfaceTexture; +use surfman::SurfaceType; +use surfman_chains::SurfmanProvider; +use surfman_chains::SwapChain; + +/// A bridge between webrender and surfman +// TODO: move this into a different crate so that script doesn't depend on surfman +#[derive(Clone)] +pub struct WebrenderSurfman(Rc); + +struct WebrenderSurfmanData { + device: RefCell, + context: RefCell, + // We either render to a swap buffer or to a native widget + swap_chain: Option>, +} + +impl Drop for WebrenderSurfmanData { + fn drop(&mut self) { + let ref mut device = self.device.borrow_mut(); + let ref mut context = self.context.borrow_mut(); + if let Some(ref swap_chain) = self.swap_chain { + let _ = swap_chain.destroy(device, context); + } + let _ = device.destroy_context(context); + } +} + +impl WebrenderSurfman { + pub fn create( + connection: &Connection, + adapter: &Adapter, + surface_type: SurfaceType, + ) -> Result { + let mut device = connection.create_device(&adapter)?; + let flags = ContextAttributeFlags::ALPHA | + ContextAttributeFlags::DEPTH | + ContextAttributeFlags::STENCIL; + let version = match connection.gl_api() { + GLApi::GLES => GLVersion { major: 3, minor: 0 }, + GLApi::GL => GLVersion { major: 3, minor: 2 }, + }; + let context_attributes = ContextAttributes { flags, version }; + let context_descriptor = device.create_context_descriptor(&context_attributes)?; + let mut context = device.create_context(&context_descriptor)?; + let surface_access = SurfaceAccess::GPUOnly; + let headless = match surface_type { + SurfaceType::Widget { .. } => false, + SurfaceType::Generic { .. } => true, + }; + let surface = device.create_surface(&context, surface_access, surface_type)?; + device + .bind_surface_to_context(&mut context, surface) + .map_err(|(err, mut surface)| { + let _ = device.destroy_surface(&mut context, &mut surface); + err + })?; + let swap_chain = if headless { + let surface_provider = Box::new(SurfmanProvider::new(surface_access)); + Some(SwapChain::create_attached( + &mut device, + &mut context, + surface_provider, + )?) + } else { + None + }; + let device = RefCell::new(device); + let context = RefCell::new(context); + let data = WebrenderSurfmanData { + device, + context, + swap_chain, + }; + Ok(WebrenderSurfman(Rc::new(data))) + } + + pub fn create_surface_texture( + &self, + surface: Surface, + ) -> Result { + let ref device = self.0.device.borrow(); + let ref mut context = self.0.context.borrow_mut(); + device.create_surface_texture(context, surface) + } + + pub fn destroy_surface_texture( + &self, + surface_texture: SurfaceTexture, + ) -> Result { + let ref device = self.0.device.borrow(); + let ref mut context = self.0.context.borrow_mut(); + device.destroy_surface_texture(context, surface_texture) + } + + pub fn make_gl_context_current(&self) -> Result<(), Error> { + let ref device = self.0.device.borrow(); + let ref context = self.0.context.borrow(); + device.make_context_current(context) + } + + pub fn swap_chain(&self) -> Result<&SwapChain, Error> { + self.0.swap_chain.as_ref().ok_or(Error::WidgetAttached) + } + + pub fn resize(&self, size: Size2D) -> Result<(), Error> { + let ref mut device = self.0.device.borrow_mut(); + let ref mut context = self.0.context.borrow_mut(); + if let Some(swap_chain) = self.0.swap_chain.as_ref() { + return swap_chain.resize(device, context, size); + } + let mut surface = device.unbind_surface_from_context(context)?.unwrap(); + device.resize_surface(context, &mut surface, size)?; + device + .bind_surface_to_context(context, surface) + .map_err(|(err, mut surface)| { + let _ = device.destroy_surface(context, &mut surface); + err + }) + } + + pub fn present(&self) -> Result<(), Error> { + let ref mut device = self.0.device.borrow_mut(); + let ref mut context = self.0.context.borrow_mut(); + if let Some(ref swap_chain) = self.0.swap_chain { + return swap_chain.swap_buffers(device, context); + } + let mut surface = device.unbind_surface_from_context(context)?.unwrap(); + device.present_surface(context, &mut surface)?; + device + .bind_surface_to_context(context, surface) + .map_err(|(err, mut surface)| { + let _ = device.destroy_surface(context, &mut surface); + err + }) + } + + pub fn connection(&self) -> Connection { + let ref device = self.0.device.borrow(); + device.connection() + } + + pub fn adapter(&self) -> Adapter { + let ref device = self.0.device.borrow(); + device.adapter() + } + + pub fn native_context(&self) -> NativeContext { + let ref device = self.0.device.borrow(); + let ref context = self.0.context.borrow(); + device.native_context(context) + } + + pub fn native_device(&self) -> NativeDevice { + let ref device = self.0.device.borrow(); + device.native_device() + } + + pub fn context_attributes(&self) -> ContextAttributes { + let ref device = self.0.device.borrow(); + let ref context = self.0.context.borrow(); + let ref descriptor = device.context_descriptor(context); + device.context_descriptor_attributes(descriptor) + } + + pub fn context_surface_info(&self) -> Result, Error> { + let ref device = self.0.device.borrow(); + let ref context = self.0.context.borrow(); + device.context_surface_info(context) + } + + pub fn surface_info(&self, surface: &Surface) -> SurfaceInfo { + let ref device = self.0.device.borrow(); + device.surface_info(surface) + } + + pub fn surface_texture_object(&self, surface: &SurfaceTexture) -> u32 { + let ref device = self.0.device.borrow(); + device.surface_texture_object(surface) + } + + pub fn get_proc_address(&self, name: &str) -> *const c_void { + let ref device = self.0.device.borrow(); + let ref context = self.0.context.borrow(); + device.get_proc_address(context, name) + } +} diff --git a/components/webrender_traits/Cargo.toml b/components/webrender_traits/Cargo.toml index 29d2bf8aa9f..bf4720038c5 100644 --- a/components/webrender_traits/Cargo.toml +++ b/components/webrender_traits/Cargo.toml @@ -12,5 +12,6 @@ path = "lib.rs" [dependencies] euclid = "0.20" +servo_geometry = {path = "../geometry"} webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/webrender_traits/lib.rs b/components/webrender_traits/lib.rs index 75c5f60272e..b6dfea27169 100644 --- a/components/webrender_traits/lib.rs +++ b/components/webrender_traits/lib.rs @@ -5,8 +5,10 @@ #![deny(unsafe_code)] use euclid::default::Size2D; + use std::collections::HashMap; use std::sync::{Arc, Mutex}; + use webrender_api::units::TexelRect; /// This trait is used as a bridge between the different GL clients diff --git a/etc/taskcluster/decision_task.py b/etc/taskcluster/decision_task.py index 968fe6bdc11..48a21cb04a7 100644 --- a/etc/taskcluster/decision_task.py +++ b/etc/taskcluster/decision_task.py @@ -492,9 +492,7 @@ def macos_release_build_with_debug_assertions(priority=None): "./etc/ci/lockfile_changed.sh", "tar -czf target.tar.gz" + " target/release/servo" + - " target/release/build/osmesa-src-*/output" + - " target/release/build/osmesa-src-*/out/src/gallium/targets/osmesa/.libs" + - " target/release/build/osmesa-src-*/out/src/mapi/shared-glapi/.libs", + " resources", ])) .with_artifacts("repo/target.tar.gz") .find_or_create("build.macos_x64_release_w_assertions." + CONFIG.tree_hash()) @@ -522,8 +520,7 @@ def linux_release_build_with_debug_assertions(layout_2020): ./etc/ci/lockfile_changed.sh tar -czf /target.tar.gz \ target/release/servo \ - target/release/build/osmesa-src-*/output \ - target/release/build/osmesa-src-*/out/lib/gallium + resources sccache --show-stats """ % build_args) .with_artifacts("/target.tar.gz") @@ -573,12 +570,17 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes, start = 1 # Skip the "extra" WPT testing, a.k.a. chunk 0 name_prefix = "Layout 2020 " job_id_prefix = "2020-" - args = "--layout-2020" + args = ["--layout-2020"] else: start = 0 name_prefix = "" job_id_prefix = "" - args = "" + args = [] + + # Our Mac CI runs on machines with an Intel 4000 GPU, so need to work around + # https://github.com/servo/webrender/wiki/Driver-issues#bug-1570736---texture-swizzling-affects-wrap-modes-on-some-intel-gpus + if platform == "macOS x64": + args += ["--pref gfx.texture-swizzling.enabled=false"] if chunks == "all": chunks = range(start, total_chunks + 1) @@ -604,7 +606,7 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes, TOTAL_CHUNKS=str(total_chunks), THIS_CHUNK=str(this_chunk), PROCESSES=str(processes), - WPT_ARGS=args, + WPT_ARGS=" ".join(args), GST_DEBUG="3", ) ) @@ -613,7 +615,6 @@ def wpt_chunks(platform, make_chunk_task, build_task, total_chunks, processes, # https://github.com/servo/servo/issues/22438 if this_chunk == 0: task.with_script(""" - ./mach test-wpt-failure time python2 ./mach test-wpt --release --binary-arg=--multiprocess \ --processes $PROCESSES \ --log-raw test-wpt-mp.log \ diff --git a/ports/glutin/Cargo.toml b/ports/glutin/Cargo.toml index 2e59f45c329..918ebfb591d 100644 --- a/ports/glutin/Cargo.toml +++ b/ports/glutin/Cargo.toml @@ -53,7 +53,6 @@ clipboard = "0.5" euclid = "0.20" getopts = "0.2.11" gleam = "0.9" -glutin = "0.21.0" keyboard-types = "0.4.3" lazy_static = "1" libservo = {path = "../../components/servo"} @@ -61,19 +60,17 @@ libc = "0.2" log = "0.4" servo-media = {git = "https://github.com/servo/media"} shellwords = "1.0.0" +surfman = { version = "0.2", features = ["sm-winit", "sm-x11"] } tinyfiledialogs = "3.0" webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] } webxr = { git = "https://github.com/servo/webxr", features = ["ipc", "glwindow", "headless"] } +winit = "0.19" [target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies] image = "0.23" [target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies] -osmesa-sys = "0.1.2" sig = "1.0" [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3", features = ["wingdi", "winuser", "winnt", "winbase", "processenv", "namedpipeapi", "ntdef", "minwindef", "handleapi", "debugapi"] } - -[target.'cfg(any(target_os = "macos", all(target_arch = "x86_64", target_os = "linux")))'.dependencies] -osmesa-src = {git = "https://github.com/servo/osmesa-src"} diff --git a/ports/glutin/app.rs b/ports/glutin/app.rs index 4a404a308dc..7b4adca6e28 100644 --- a/ports/glutin/app.rs +++ b/ports/glutin/app.rs @@ -9,7 +9,7 @@ use crate::embedder::EmbedderCallbacks; use crate::events_loop::EventsLoop; use crate::window_trait::WindowPortsMethods; use crate::{headed_window, headless_window}; -use glutin::WindowId; +use winit::WindowId; use servo::compositing::windowing::WindowEvent; use servo::config::opts::{self, parse_url_or_filename}; use servo::servo_config::pref; @@ -20,6 +20,7 @@ use std::collections::HashMap; use std::env; use std::mem; use std::rc::Rc; +use webxr::glwindow::GlWindowDiscovery; thread_local! { pub static WINDOWS: RefCell>> = RefCell::new(HashMap::new()); @@ -35,9 +36,6 @@ pub struct App { impl App { pub fn run( - angle: bool, - enable_vsync: bool, - use_msaa: bool, no_native_titlebar: bool, device_pixels_per_px: Option, user_agent: Option, @@ -50,21 +48,31 @@ impl App { } else { Rc::new(headed_window::Window::new( opts::get().initial_window_size, - None, events_loop.clone(), - angle, - enable_vsync, - use_msaa, no_native_titlebar, device_pixels_per_px, )) }; + let xr_discovery = if pref!(dom.webxr.glwindow) { + let window = window.clone(); + let surfman = window.webrender_surfman(); + let events_loop = events_loop.clone(); + let factory = Box::new(move || Ok(window.new_glwindow(&*events_loop.borrow()))); + Some(GlWindowDiscovery::new( + surfman.connection(), + surfman.adapter(), + surfman.context_attributes(), + factory, + )) + } else { + None + }; + // Implements embedder methods, used by libservo and constellation. let embedder = Box::new(EmbedderCallbacks::new( - window.clone(), events_loop.clone(), - window.gl(), + xr_discovery, )); // Handle browser state. @@ -93,36 +101,36 @@ impl App { } // This function decides whether the event should be handled during `run_forever`. - fn winit_event_to_servo_event(&self, event: glutin::Event) -> glutin::ControlFlow { + fn winit_event_to_servo_event(&self, event: winit::Event) -> winit::ControlFlow { match event { // App level events - glutin::Event::Suspended(suspended) => { + winit::Event::Suspended(suspended) => { self.suspended.set(suspended); if !suspended { self.event_queue.borrow_mut().push(WindowEvent::Idle); } }, - glutin::Event::Awakened => { + winit::Event::Awakened => { self.event_queue.borrow_mut().push(WindowEvent::Idle); }, - glutin::Event::DeviceEvent { .. } => {}, + winit::Event::DeviceEvent { .. } => {}, // Window level events - glutin::Event::WindowEvent { + winit::Event::WindowEvent { window_id, event, .. } => { return WINDOWS.with(|windows| { match windows.borrow().get(&window_id) { None => { warn!("Got an event from unknown window"); - glutin::ControlFlow::Break + winit::ControlFlow::Break }, Some(window) => { // Resize events need to be handled during run_forever - let cont = if let glutin::WindowEvent::Resized(_) = event { - glutin::ControlFlow::Continue + let cont = if let winit::WindowEvent::Resized(_) = event { + winit::ControlFlow::Continue } else { - glutin::ControlFlow::Break + winit::ControlFlow::Break }; window.winit_event_to_servo_event(event); return cont; @@ -131,7 +139,7 @@ impl App { }); }, } - glutin::ControlFlow::Break + winit::ControlFlow::Break } fn run_loop(self) { @@ -146,7 +154,7 @@ impl App { // If there's no animations running then we block on the window event loop. self.events_loop.borrow_mut().run_forever(|e| { let cont = self.winit_event_to_servo_event(e); - if cont == glutin::ControlFlow::Continue { + if cont == winit::ControlFlow::Continue { // Note we need to be careful to make sure that any events // that are handled during run_forever aren't re-entrant, // since we are handling them while holding onto a mutable borrow @@ -237,14 +245,3 @@ pub fn register_window(window: Rc) { w.borrow_mut().insert(window.id(), window); }); } - -pub fn gl_version(angle: bool) -> glutin::GlRequest { - if angle { - glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)) - } else { - glutin::GlRequest::GlThenGles { - opengl_version: (3, 2), - opengles_version: (3, 0), - } - } -} diff --git a/ports/glutin/context.rs b/ports/glutin/context.rs deleted file mode 100644 index 77dc4775bed..00000000000 --- a/ports/glutin/context.rs +++ /dev/null @@ -1,172 +0,0 @@ -/* 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 https://mozilla.org/MPL/2.0/. */ - -use glutin::os::ContextTraitExt; -use glutin::{ContextBuilder, CreationError, EventsLoop, NotCurrent, PossiblyCurrent, WindowedContext, WindowBuilder}; -use servo_media::player::context::GlContext as RawContext; -use std::os::raw; - -pub enum GlContext { - Current(WindowedContext), - NotCurrent(WindowedContext), - // Used a temporary value as we switch from Current to NotCurrent. - None, -} - -impl GlContext { - pub fn window(&self) -> &glutin::Window { - match self { - GlContext::Current(c) => c.window(), - GlContext::NotCurrent(c) => c.window(), - GlContext::None => unreachable!(), - } - } - pub fn resize(&mut self, size: glutin::dpi::PhysicalSize) { - if let GlContext::NotCurrent(_) = self { - self.make_current(); - } - match self { - GlContext::Current(c) => c.resize(size), - _ => unreachable!(), - } - } - pub fn make_current(&mut self) { - *self = match std::mem::replace(self, GlContext::None) { - GlContext::Current(c) => { - warn!("Making an already current context current"); - // Servo thinks that that this window is current, - // but it might be wrong, since other code may have - // changed the current GL context. Just to be on - // the safe side, we make it current anyway. - let c = unsafe { - c.make_current().expect("Couldn't make window current") - }; - GlContext::Current(c) - }, - GlContext::NotCurrent(c) => { - let c = unsafe { - c.make_current().expect("Couldn't make window current") - }; - GlContext::Current(c) - } - GlContext::None => unreachable!(), - } - } - pub fn make_not_current(&mut self) { - *self = match std::mem::replace(self, GlContext::None) { - GlContext::Current(c) => { - let c = unsafe { - c.make_not_current().expect("Couldn't make window not current") - }; - GlContext::NotCurrent(c) - }, - GlContext::NotCurrent(c) => { - warn!("Making an already not current context not current"); - GlContext::NotCurrent(c) - } - GlContext::None => unreachable!(), - } - } - pub fn swap_buffers(&self) { - match self { - GlContext::Current(c) => { - if let Err(err) = c.swap_buffers() { - warn!("Failed to swap window buffers ({}).", err); - } - }, - GlContext::NotCurrent(_) => { - error!("Context is not current. Forgot to call prepare_for_composite?"); - }, - GlContext::None => unreachable!(), - }; - } - #[allow(unreachable_code, unused_variables)] - pub fn raw_context(&self) -> RawContext { - match self { - GlContext::Current(c) => { - #[cfg(target_os = "linux")] - { - use glutin::os::unix::RawHandle; - - let raw_handle = unsafe { c.raw_handle() }; - return match raw_handle { - RawHandle::Egl(handle) => RawContext::Egl(handle as usize), - RawHandle::Glx(handle) => RawContext::Glx(handle as usize), - }; - } - - #[cfg(target_os = "windows")] - { - use glutin::os::windows::RawHandle; - - let raw_handle = unsafe { c.raw_handle() }; - return match raw_handle { - RawHandle::Egl(handle) => RawContext::Egl(handle as usize), - // @TODO(victor): RawContext::Wgl in servo-media - RawHandle::Wgl(_) => unimplemented!(), - } - } - - // @TODO(victor): https://github.com/rust-windowing/glutin/pull/1221 - // https://github.com/servo/media/pull/315 - #[cfg(target_os = "macos")] - return unimplemented!(); - - #[cfg(not(any( - target_os = "linux", - target_os = "windows", - target_os = "macos", - )))] - unimplemented!() - } - GlContext::NotCurrent(_) => { - error!("Context is not current."); - RawContext::Unknown - } - GlContext::None => unreachable!(), - } - } - - pub fn new_window( - &self, - cb: ContextBuilder, - wb: WindowBuilder, - el: &EventsLoop - ) -> Result, CreationError> - where - T: glutin::ContextCurrentState, - { - match self { - GlContext::Current(ref c) => { - cb.with_shared_lists(c).build_windowed(wb, el) - }, - GlContext::NotCurrent(ref c) => { - cb.with_shared_lists(c).build_windowed(wb, el) - }, - GlContext::None => { - cb.build_windowed(wb, el) - }, - } - } - - #[allow(dead_code)] - pub fn egl_display(&self) -> Option<*const raw::c_void> { - match self { - GlContext::Current(c) => unsafe { c.get_egl_display() }, - GlContext::NotCurrent(_) => { - error!("Context is not current."); - None - }, - GlContext::None => unreachable!(), - } - } - - pub fn get_api(&self) -> glutin::Api { - match self { - GlContext::Current(c) => c.get_api(), - GlContext::NotCurrent(c) => c.get_api(), - GlContext::None => unreachable!(), - } - } -} diff --git a/ports/glutin/embedder.rs b/ports/glutin/embedder.rs index 421ef622953..e770911cff8 100644 --- a/ports/glutin/embedder.rs +++ b/ports/glutin/embedder.rs @@ -5,31 +5,27 @@ //! Implements the global methods required by Servo (not window/gl/compositor related). use crate::events_loop::EventsLoop; -use crate::window_trait::WindowPortsMethods; -use gleam::gl; use servo::canvas::{SurfaceProviders, WebGlExecutor}; use servo::compositing::windowing::EmbedderMethods; use servo::embedder_traits::{EmbedderProxy, EventLoopWaker}; -use servo::servo_config::{opts, pref}; +use servo::servo_config::pref; use std::cell::RefCell; use std::rc::Rc; +use webxr::glwindow::GlWindowDiscovery; pub struct EmbedderCallbacks { - window: Rc, events_loop: Rc>, - gl: Rc, + xr_discovery: Option, } impl EmbedderCallbacks { pub fn new( - window: Rc, events_loop: Rc>, - gl: Rc, + xr_discovery: Option, ) -> EmbedderCallbacks { EmbedderCallbacks { - window, events_loop, - gl, + xr_discovery, } } } @@ -48,13 +44,8 @@ impl EmbedderMethods for EmbedderCallbacks { ) { if pref!(dom.webxr.test) { xr.register_mock(webxr::headless::HeadlessMockDiscovery::new()); - } else if !opts::get().headless && pref!(dom.webxr.glwindow) { - warn!("Creating test XR device"); - let gl = self.gl.clone(); - let window = self.window.clone(); - let factory = Box::new(move || window.new_window()); - let discovery = webxr::glwindow::GlWindowDiscovery::new(gl, factory); - xr.register(discovery); + } else if let Some(xr_discovery) = self.xr_discovery.take() { + xr.register(xr_discovery); } } } diff --git a/ports/glutin/events_loop.rs b/ports/glutin/events_loop.rs index 9dff3492d9e..20ebbed12b1 100644 --- a/ports/glutin/events_loop.rs +++ b/ports/glutin/events_loop.rs @@ -5,7 +5,7 @@ //! An event loop implementation that works in headless mode. -use glutin; +use winit; use servo::embedder_traits::EventLoopWaker; use std::sync::{Arc, Condvar, Mutex}; use std::rc::Rc; @@ -14,8 +14,8 @@ use std::time; #[allow(dead_code)] enum EventLoop { - /// A real Glutin windowing event loop. - Glutin(Option), + /// A real Winit windowing event loop. + Winit(Option), /// A fake event loop which contains a signalling flag used to ensure /// that pending events get processed in a timely fashion, and a condition /// variable to allow waiting on that flag changing state. @@ -29,14 +29,14 @@ impl EventsLoop { // but on Linux, the event loop requires a X11 server. #[cfg(not(target_os = "linux"))] pub fn new(_headless: bool) -> Rc> { - Rc::new(RefCell::new(EventsLoop(EventLoop::Glutin(Some(glutin::EventsLoop::new()))))) + Rc::new(RefCell::new(EventsLoop(EventLoop::Winit(Some(winit::EventsLoop::new()))))) } #[cfg(target_os = "linux")] pub fn new(headless: bool) -> Rc> { let events_loop = if headless { EventLoop::Headless(Arc::new((Mutex::new(false), Condvar::new()))) } else { - EventLoop::Glutin(Some(glutin::EventsLoop::new())) + EventLoop::Winit(Some(winit::EventsLoop::new())) }; Rc::new(RefCell::new(EventsLoop(events_loop))) } @@ -45,7 +45,7 @@ impl EventsLoop { impl EventsLoop { pub fn create_event_loop_waker(&self) -> Box { match self.0 { - EventLoop::Glutin(ref events_loop) => { + EventLoop::Winit(ref events_loop) => { let events_loop = events_loop .as_ref() .expect("Can't create waker for unavailable event loop."); @@ -55,17 +55,18 @@ impl EventsLoop { Box::new(HeadlessEventLoopWaker(data.clone())), } } - pub fn as_winit(&self) -> &glutin::EventsLoop { + pub fn as_winit(&self) -> &winit::EventsLoop { match self.0 { - EventLoop::Glutin(Some(ref event_loop)) => event_loop, - EventLoop::Glutin(None) | EventLoop::Headless(..) => + EventLoop::Winit(Some(ref event_loop)) => event_loop, + EventLoop::Winit(None) | EventLoop::Headless(..) => panic!("Can't access winit event loop while using the fake headless event loop"), } } - pub fn poll_events(&mut self, callback: F) where F: FnMut(glutin::Event) { + + pub fn poll_events(&mut self, callback: F) where F: FnMut(winit::Event) { match self.0 { - EventLoop::Glutin(Some(ref mut events_loop)) => events_loop.poll_events(callback), - EventLoop::Glutin(None) => (), + EventLoop::Winit(Some(ref mut events_loop)) => events_loop.poll_events(callback), + EventLoop::Winit(None) => (), EventLoop::Headless(ref data) => { // This is subtle - the use of the event loop in App::run_loop // optionally calls run_forever, then always calls poll_events. @@ -80,9 +81,9 @@ impl EventsLoop { } } } - pub fn run_forever(&mut self, mut callback: F) where F: FnMut(glutin::Event) -> glutin::ControlFlow { + pub fn run_forever(&mut self, mut callback: F) where F: FnMut(winit::Event) -> winit::ControlFlow { match self.0 { - EventLoop::Glutin(ref mut events_loop) => { + EventLoop::Winit(ref mut events_loop) => { let events_loop = events_loop .as_mut() .expect("Can't run an unavailable event loop."); @@ -92,7 +93,7 @@ impl EventsLoop { let &(ref flag, ref condvar) = &**data; while !*flag.lock().unwrap() { self.sleep(flag, condvar); - if callback(glutin::Event::Awakened) == glutin::ControlFlow::Break { + if callback(winit::Event::Awakened) == winit::ControlFlow::Break { break; } } @@ -115,10 +116,10 @@ impl EventsLoop { } struct HeadedEventLoopWaker { - proxy: Arc, + proxy: Arc, } impl HeadedEventLoopWaker { - fn new(events_loop: &glutin::EventsLoop) -> HeadedEventLoopWaker { + fn new(events_loop: &winit::EventsLoop) -> HeadedEventLoopWaker { let proxy = Arc::new(events_loop.create_proxy()); HeadedEventLoopWaker { proxy } } diff --git a/ports/glutin/headed_window.rs b/ports/glutin/headed_window.rs index 36d3fc88d5f..abfe328431a 100644 --- a/ports/glutin/headed_window.rs +++ b/ports/glutin/headed_window.rs @@ -2,27 +2,21 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -//! A glutin window implementation. +//! A winit window implementation. -use crate::app; -use crate::context::GlContext; use crate::events_loop::EventsLoop; use crate::keyutils::keyboard_event_from_winit; use crate::window_trait::{WindowPortsMethods, LINE_HEIGHT}; use euclid::{ - Angle, default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, + Angle, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector2D, Vector3D, }; -use gleam::gl; -use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalSize}; +use winit::dpi::{LogicalPosition, LogicalSize, PhysicalSize}; #[cfg(target_os = "macos")] -use glutin::os::macos::{ActivationPolicy, WindowBuilderExt}; -#[cfg(target_os = "linux")] -use glutin::os::unix::WindowExt; -use glutin::Api; +use winit::os::macos::{ActivationPolicy, WindowBuilderExt}; #[cfg(any(target_os = "linux", target_os = "windows"))] -use glutin::Icon; -use glutin::{ElementState, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode}; +use winit::Icon; +use winit::{ElementState, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase, VirtualKeyCode}; #[cfg(any(target_os = "linux", target_os = "windows"))] use image; use keyboard_types::{Key, KeyState, KeyboardEvent}; @@ -30,22 +24,32 @@ use servo::compositing::windowing::{AnimationState, MouseWindowEvent, WindowEven use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods}; use servo::embedder_traits::Cursor; use servo::script_traits::{TouchEventType, WheelMode, WheelDelta}; -use servo::servo_config::{opts, pref}; +use servo::servo_config::opts; +use servo::servo_config::pref; use servo::servo_geometry::DeviceIndependentPixel; use servo::style_traits::DevicePixel; use servo::webrender_api::ScrollLocation; use servo::webrender_api::units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize}; +use servo::webrender_surfman::WebrenderSurfman; use servo_media::player::context::{GlApi, GlContext as PlayerGLContext, NativeDisplay}; use std::cell::{Cell, RefCell}; use std::mem; use std::rc::Rc; +#[cfg(target_os = "linux")] +use surfman::platform::generic::multi::connection::NativeConnection; +#[cfg(target_os = "linux")] +use surfman::platform::generic::multi::context::NativeContext; +use surfman::Connection; +use surfman::Device; +use surfman::GLApi; +use surfman::GLVersion; +use surfman::NativeWidget; +use surfman::SurfaceType; #[cfg(target_os = "windows")] use winapi; -const MULTISAMPLES: u16 = 16; - #[cfg(target_os = "macos")] -fn builder_with_platform_options(mut builder: glutin::WindowBuilder) -> glutin::WindowBuilder { +fn builder_with_platform_options(mut builder: winit::WindowBuilder) -> winit::WindowBuilder { if opts::get().output_file.is_some() { // Prevent the window from showing in Dock.app, stealing focus, // when generating an output file. @@ -55,31 +59,25 @@ fn builder_with_platform_options(mut builder: glutin::WindowBuilder) -> glutin:: } #[cfg(not(target_os = "macos"))] -fn builder_with_platform_options(builder: glutin::WindowBuilder) -> glutin::WindowBuilder { +fn builder_with_platform_options(builder: winit::WindowBuilder) -> winit::WindowBuilder { builder } pub struct Window { - gl_context: RefCell, - events_loop: Rc>, + winit_window: winit::Window, + webrender_surfman: WebrenderSurfman, screen_size: Size2D, inner_size: Cell>, - mouse_down_button: Cell>, + mouse_down_button: Cell>, mouse_down_point: Cell>, - primary_monitor: glutin::MonitorId, + primary_monitor: winit::MonitorId, event_queue: RefCell>, mouse_pos: Cell>, last_pressed: Cell>, animation_state: Cell, fullscreen: Cell, - gl: Rc, - xr_rotation: Cell>, - xr_translation: Cell>, - angle: bool, - enable_vsync: bool, - use_msaa: bool, - no_native_titlebar: bool, device_pixels_per_px: Option, + xr_window_poses: RefCell>>, } #[cfg(not(target_os = "windows"))] @@ -97,11 +95,7 @@ fn window_creation_scale_factor() -> Scale, - sharing: Option<&Window>, events_loop: Rc>, - angle: bool, - enable_vsync: bool, - use_msaa: bool, no_native_titlebar: bool, device_pixels_per_px: Option, ) -> Window { @@ -117,7 +111,7 @@ impl Window { let width = win_size.to_untyped().width; let height = win_size.to_untyped().height; - let mut window_builder = glutin::WindowBuilder::new() + let mut window_builder = winit::WindowBuilder::new() .with_title("Servo".to_string()) .with_decorations(!no_native_titlebar) .with_transparency(no_native_titlebar) @@ -127,39 +121,14 @@ impl Window { window_builder = builder_with_platform_options(window_builder); - let mut context_builder = glutin::ContextBuilder::new() - .with_gl(app::gl_version(angle)) - .with_vsync(enable_vsync); - - if use_msaa { - context_builder = context_builder.with_multisampling(MULTISAMPLES) - } - - let context = match sharing { - Some(sharing) => sharing.gl_context.borrow().new_window( - context_builder, - window_builder, - events_loop.borrow().as_winit() - ), - None => context_builder.build_windowed(window_builder, events_loop.borrow().as_winit()), - }.expect("Failed to create window."); + let winit_window = window_builder.build(events_loop.borrow().as_winit()).expect("Failed to create window."); #[cfg(any(target_os = "linux", target_os = "windows"))] { let icon_bytes = include_bytes!("../../resources/servo64.png"); - context.window().set_window_icon(Some(load_icon(icon_bytes))); + winit_window.set_window_icon(Some(load_icon(icon_bytes))); } - if let Some(sharing) = sharing { - debug!("Making window {:?} not current", sharing.gl_context.borrow().window().id()); - sharing.gl_context.borrow_mut().make_not_current(); - } - - let context = unsafe { - debug!("Making window {:?} current", context.window().id()); - context.make_current().expect("Couldn't make window current") - }; - let primary_monitor = events_loop.borrow().as_winit().get_primary_monitor(); let PhysicalSize { @@ -168,59 +137,43 @@ impl Window { } = primary_monitor.get_dimensions(); let screen_size = Size2D::new(screen_width as u32, screen_height as u32); // TODO(ajeffrey): can this fail? - let LogicalSize { width, height } = context - .window() + let LogicalSize { width, height } = winit_window .get_inner_size() .expect("Failed to get window inner size."); let inner_size = Size2D::new(width as u32, height as u32); - context.window().show(); + winit_window.show(); - let gl = if let Some(sharing) = sharing { - sharing.gl.clone() - } else { match context.get_api() { - Api::OpenGl => unsafe { - gl::GlFns::load_with(|s| context.get_proc_address(s) as *const _) - }, - Api::OpenGlEs => unsafe { - gl::GlesFns::load_with(|s| context.get_proc_address(s) as *const _) - }, - Api::WebGl => unreachable!("webgl is unsupported"), - } }; + // Initialize surfman + let connection = Connection::from_winit_window(&winit_window).expect("Failed to create connection"); + let adapter = connection.create_adapter().expect("Failed to create adapter"); + let native_widget = connection + .create_native_widget_from_winit_window(&winit_window) + .expect("Failed to create native widget"); + let surface_type = SurfaceType::Widget { native_widget }; + let webrender_surfman = WebrenderSurfman::create( + &connection, + &adapter, + surface_type, + ).expect("Failed to create WR surfman"); - gl.clear_color(0.6, 0.6, 0.6, 1.0); - gl.clear(gl::COLOR_BUFFER_BIT); - gl.finish(); - - let context = GlContext::Current(context); - - debug!("Created window {:?}", context.window().id()); - let window = Window { - gl_context: RefCell::new(context), - events_loop, + debug!("Created window {:?}", winit_window.id()); + Window { + winit_window, + webrender_surfman, event_queue: RefCell::new(vec![]), mouse_down_button: Cell::new(None), mouse_down_point: Cell::new(Point2D::new(0, 0)), mouse_pos: Cell::new(Point2D::new(0, 0)), last_pressed: Cell::new(None), - gl: gl.clone(), animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), inner_size: Cell::new(inner_size), primary_monitor, screen_size, - xr_rotation: Cell::new(Rotation3D::identity()), - xr_translation: Cell::new(Vector3D::zero()), - angle, - enable_vsync, - use_msaa, - no_native_titlebar, device_pixels_per_px, - }; - - window.present(); - - window + xr_window_poses: RefCell::new(vec![]), + } } fn handle_received_character(&self, mut ch: char) { @@ -245,7 +198,10 @@ impl Window { KeyboardEvent::default() }; event.key = Key::Character(ch.to_string()); - self.handle_xr_translation(&event); + let xr_poses = self.xr_window_poses.borrow(); + for xr_window_pose in &*xr_poses { + xr_window_pose.handle_xr_translation(&event); + } self.event_queue .borrow_mut() .push(WindowEvent::Keyboard(event)); @@ -258,68 +214,21 @@ impl Window { self.last_pressed.set(Some(event)); } else if event.key != Key::Unidentified { self.last_pressed.set(None); - self.handle_xr_rotation(&input); + let xr_poses = self.xr_window_poses.borrow(); + for xr_window_pose in &*xr_poses { + xr_window_pose.handle_xr_rotation(&input); + } self.event_queue .borrow_mut() .push(WindowEvent::Keyboard(event)); } } - fn handle_xr_translation(&self, input: &KeyboardEvent) { - if input.state != KeyState::Down { - return; - } - const NORMAL_TRANSLATE: f32 = 0.1; - const QUICK_TRANSLATE: f32 = 1.0; - let mut x = 0.0; - let mut z = 0.0; - match input.key { - Key::Character(ref k) => match &**k { - "w" => z = -NORMAL_TRANSLATE, - "W" => z = -QUICK_TRANSLATE, - "s" => z = NORMAL_TRANSLATE, - "S" => z = QUICK_TRANSLATE, - "a" => x = -NORMAL_TRANSLATE, - "A" => x = -QUICK_TRANSLATE, - "d" => x = NORMAL_TRANSLATE, - "D" => x = QUICK_TRANSLATE, - _ => return, - }, - _ => return, - }; - let (old_x, old_y, old_z) = self.xr_translation.get().to_tuple(); - let vec = Vector3D::new(x + old_x, old_y, z + old_z); - self.xr_translation.set(vec); - } - - fn handle_xr_rotation(&self, input: &KeyboardInput) { - if input.state != glutin::ElementState::Pressed { - return; - } - let mut x = 0.0; - let mut y = 0.0; - match input.virtual_keycode { - Some(VirtualKeyCode::Up) => x = 1.0, - Some(VirtualKeyCode::Down) => x = -1.0, - Some(VirtualKeyCode::Left) => y = 1.0, - Some(VirtualKeyCode::Right) => y = -1.0, - _ => return, - }; - if input.modifiers.shift { - x = 10.0 * x; - y = 10.0 * y; - } - let x: Rotation3D<_, UnknownUnit, UnknownUnit> = Rotation3D::around_x(Angle::degrees(x)); - let y: Rotation3D<_, UnknownUnit, UnknownUnit> = Rotation3D::around_y(Angle::degrees(y)); - let rotation = self.xr_rotation.get().post_rotate(&x).post_rotate(&y); - self.xr_rotation.set(rotation); - } - /// Helper function to handle a click fn handle_mouse( &self, - button: glutin::MouseButton, - action: glutin::ElementState, + button: winit::MouseButton, + action: winit::ElementState, coords: Point2D, ) { use servo::script_traits::MouseButton; @@ -359,7 +268,7 @@ impl Window { } fn device_hidpi_factor(&self) -> Scale { - Scale::new(self.gl_context.borrow().window().get_hidpi_factor() as f32) + Scale::new(self.winit_window.get_hidpi_factor() as f32) } fn servo_hidpi_factor(&self) -> Scale { @@ -385,33 +294,31 @@ impl WindowPortsMethods for Window { fn page_height(&self) -> f32 { let dpr = self.servo_hidpi_factor(); let size = self - .gl_context - .borrow() - .window() + .winit_window .get_inner_size() .expect("Failed to get window inner size."); size.height as f32 * dpr.get() } fn set_title(&self, title: &str) { - self.gl_context.borrow().window().set_title(title); + self.winit_window.set_title(title); } fn set_inner_size(&self, size: DeviceIntSize) { let size = size.to_f32() / self.device_hidpi_factor(); - self.gl_context.borrow_mut().window() + self.winit_window .set_inner_size(LogicalSize::new(size.width.into(), size.height.into())) } fn set_position(&self, point: DeviceIntPoint) { let point = point.to_f32() / self.device_hidpi_factor(); - self.gl_context.borrow_mut().window() + self.winit_window .set_position(LogicalPosition::new(point.x.into(), point.y.into())) } fn set_fullscreen(&self, state: bool) { if self.fullscreen.get() != state { - self.gl_context.borrow_mut().window() + self.winit_window .set_fullscreen(if state { Some(self.primary_monitor.clone()) } else { None }); } self.fullscreen.set(state); @@ -422,7 +329,7 @@ impl WindowPortsMethods for Window { } fn set_cursor(&self, cursor: Cursor) { - use glutin::MouseCursor; + use winit::MouseCursor; let winit_cursor = match cursor { Cursor::Default => MouseCursor::Default, @@ -461,27 +368,27 @@ impl WindowPortsMethods for Window { Cursor::ZoomOut => MouseCursor::ZoomOut, _ => MouseCursor::Default, }; - self.gl_context.borrow_mut().window().set_cursor(winit_cursor); + self.winit_window.set_cursor(winit_cursor); } fn is_animating(&self) -> bool { self.animation_state.get() == AnimationState::Animating } - fn id(&self) -> glutin::WindowId { - self.gl_context.borrow().window().id() + fn id(&self) -> winit::WindowId { + self.winit_window.id() } - fn winit_event_to_servo_event(&self, event: glutin::WindowEvent) { + fn winit_event_to_servo_event(&self, event: winit::WindowEvent) { match event { - glutin::WindowEvent::ReceivedCharacter(ch) => self.handle_received_character(ch), - glutin::WindowEvent::KeyboardInput { input, .. } => self.handle_keyboard_input(input), - glutin::WindowEvent::MouseInput { state, button, .. } => { + winit::WindowEvent::ReceivedCharacter(ch) => self.handle_received_character(ch), + winit::WindowEvent::KeyboardInput { input, .. } => self.handle_keyboard_input(input), + winit::WindowEvent::MouseInput { state, button, .. } => { if button == MouseButton::Left || button == MouseButton::Right { self.handle_mouse(button, state, self.mouse_pos.get()); } }, - glutin::WindowEvent::CursorMoved { position, .. } => { + winit::WindowEvent::CursorMoved { position, .. } => { let pos = position.to_physical(self.device_hidpi_factor().get() as f64); let (x, y): (i32, i32) = pos.into(); self.mouse_pos.set(Point2D::new(x, y)); @@ -491,7 +398,7 @@ impl WindowPortsMethods for Window { x as f32, y as f32, ))); }, - glutin::WindowEvent::MouseWheel { delta, phase, .. } => { + winit::WindowEvent::MouseWheel { delta, phase, .. } => { let (mut dx, mut dy, mode) = match delta { MouseScrollDelta::LineDelta(dx, dy) => (dx as f64, (dy * LINE_HEIGHT) as f64, WheelMode::DeltaLine), @@ -524,7 +431,7 @@ impl WindowPortsMethods for Window { self.event_queue.borrow_mut().push(wheel_event); self.event_queue.borrow_mut().push(scroll_event); }, - glutin::WindowEvent::Touch(touch) => { + winit::WindowEvent::Touch(touch) => { use servo::script_traits::TouchId; let phase = winit_phase_to_touch_event_type(touch.phase); @@ -537,19 +444,19 @@ impl WindowPortsMethods for Window { .borrow_mut() .push(WindowEvent::Touch(phase, id, point)); }, - glutin::WindowEvent::Refresh => { + winit::WindowEvent::Refresh => { self.event_queue.borrow_mut().push(WindowEvent::Refresh); }, - glutin::WindowEvent::CloseRequested => { + winit::WindowEvent::CloseRequested => { self.event_queue.borrow_mut().push(WindowEvent::Quit); }, - glutin::WindowEvent::Resized(size) => { - let physical_size = size.to_physical(self.device_hidpi_factor().get() as f64); - self.gl_context.borrow_mut().resize(physical_size); - // window.set_inner_size() takes DeviceIndependentPixel. + winit::WindowEvent::Resized(size) => { let (width, height) = size.into(); let new_size = Size2D::new(width, height); if self.inner_size.get() != new_size { + let physical_size = size.to_physical(self.device_hidpi_factor().get() as f64); + let physical_size = Size2D::new(physical_size.width, physical_size.height); + self.webrender_surfman.resize(physical_size.to_i32()).expect("Failed to resize"); self.inner_size.set(new_size); self.event_queue.borrow_mut().push(WindowEvent::Resize); } @@ -557,75 +464,40 @@ impl WindowPortsMethods for Window { _ => {}, } } -} -impl webxr::glwindow::GlWindow for Window { - fn make_current(&self) { - debug!("Making window {:?} current", self.gl_context.borrow().window().id()); - self.gl_context.borrow_mut().make_current(); - } + fn new_glwindow(&self, events_loop: &EventsLoop) -> Box { + let size = self.winit_window.get_outer_size() + .expect("Failed to get window outer size"); - fn swap_buffers(&self) { - debug!("Swapping buffers on window {:?}", self.gl_context.borrow().window().id()); - self.gl_context.borrow().swap_buffers(); - self.gl_context.borrow_mut().make_not_current(); - } + let mut window_builder = winit::WindowBuilder::new() + .with_title("Servo XR".to_string()) + .with_dimensions(size) + .with_visibility(true); - fn size(&self) -> UntypedSize2D { - let dpr = self.device_hidpi_factor().get() as f64; - let size = self - .gl_context - .borrow() - .window() - .get_inner_size() - .expect("Failed to get window inner size."); - let size = size.to_physical(dpr); - let (w, h): (u32, u32) = size.into(); - Size2D::new(w as i32, h as i32) - } + window_builder = builder_with_platform_options(window_builder); - fn get_rotation(&self) -> Rotation3D { - self.xr_rotation.get().clone() - } + let winit_window = window_builder.build(events_loop.as_winit()) + .expect("Failed to create window."); - fn get_translation(&self) -> Vector3D { - self.xr_translation.get().clone() - } - - fn new_window(&self) -> Result, ()> { - let window = Rc::new(Window::new( - self.inner_size.get(), - Some(self), - self.events_loop.clone(), - self.angle, - self.enable_vsync, - self.use_msaa, - self.no_native_titlebar, - self.device_pixels_per_px, - )); - app::register_window(window.clone()); - Ok(window) + let pose = Rc::new(XRWindowPose { + xr_rotation: Cell::new(Rotation3D::identity()), + xr_translation: Cell::new(Vector3D::zero()), + }); + self.xr_window_poses.borrow_mut().push(pose.clone()); + Box::new(XRWindow { winit_window, pose }) } } impl WindowMethods for Window { - fn gl(&self) -> Rc { - self.gl.clone() - } - fn get_coordinates(&self) -> EmbedderCoordinates { // TODO(ajeffrey): can this fail? let dpr = self.device_hidpi_factor(); let LogicalSize { width, height } = self - .gl_context - .borrow() - .window() + .winit_window .get_outer_size() .expect("Failed to get window outer size."); let LogicalPosition { x, y } = self - .gl_context - .borrow() - .window() + .winit_window .get_position() .unwrap_or(LogicalPosition::new(0., 0.)); let win_size = (Size2D::new(width as f32, height as f32) * dpr).to_i32(); @@ -633,45 +505,58 @@ impl WindowMethods for Window { let screen = (self.screen_size.to_f32() * dpr).to_i32(); let LogicalSize { width, height } = self - .gl_context - .borrow() - .window() + .winit_window .get_inner_size() .expect("Failed to get window inner size."); let inner_size = (Size2D::new(width as f32, height as f32) * dpr).to_i32(); let viewport = DeviceIntRect::new(Point2D::zero(), inner_size); let framebuffer = DeviceIntSize::from_untyped(viewport.size.to_untyped()); - EmbedderCoordinates { viewport, framebuffer, window: (win_size, win_origin), screen: screen, - // FIXME: Glutin doesn't have API for available size. Fallback to screen size + // FIXME: Winit doesn't have API for available size. Fallback to screen size screen_avail: screen, hidpi_factor: self.servo_hidpi_factor(), } } - fn present(&self) { - self.gl_context.borrow().swap_buffers(); - self.gl_context.borrow_mut().make_not_current(); - } - fn set_animation_state(&self, state: AnimationState) { self.animation_state.set(state); } - fn make_gl_context_current(&self) { - self.gl_context.borrow_mut().make_current(); + fn webrender_surfman(&self) -> WebrenderSurfman { + self.webrender_surfman.clone() } fn get_gl_context(&self) -> PlayerGLContext { - if pref!(media.glvideo.enabled) { - return self.gl_context.borrow().raw_context(); + if !pref!(media.glvideo.enabled) { + return PlayerGLContext::Unknown; } - return PlayerGLContext::Unknown; + #[allow(unused_variables)] + let native_context = self.webrender_surfman.native_context(); + + #[cfg(target_os = "windows")] + return PlayerGLContext::Egl(native_context.egl_context as usize); + + #[cfg(target_os = "linux")] + return match native_context { + NativeContext::Default(NativeContext::Default(native_context)) => + PlayerGLContext::Egl(native_context.egl_context as usize), + NativeContext::Default(NativeContext::Alternate(native_context)) => + PlayerGLContext::Egl(native_context.egl_context as usize), + NativeContext::Alternate(_) => unimplemented!(), + }; + + // @TODO(victor): https://github.com/servo/media/pull/315 + #[cfg(target_os = "macos")] + #[allow(unreachable_code)] + return unimplemented!(); + + #[cfg(not(any(target_os = "linux", target_os = "windows", target_os = "macos")))] + return unimplemented!(); } fn get_native_display(&self) -> NativeDisplay { @@ -679,48 +564,41 @@ impl WindowMethods for Window { return NativeDisplay::Unknown; } + #[allow(unused_variables)] + let native_connection = self.webrender_surfman.connection().native_connection(); + #[allow(unused_variables)] + let native_device = self.webrender_surfman.native_device(); + + #[cfg(target_os = "windows")] + return NativeDisplay::Egl(native_device.egl_display as usize); + #[cfg(target_os = "linux")] - { - if let Some(display) = self.gl_context.borrow().window().get_wayland_display() { - return NativeDisplay::Wayland(display as usize); - } else if let Some(display) = - self.gl_context.borrow().window().get_xlib_display() - { - return NativeDisplay::X11(display as usize); - } - } + return match native_connection { + NativeConnection::Default(NativeConnection::Default(conn)) => + NativeDisplay::Egl(conn.0 as usize), + NativeConnection::Default(NativeConnection::Alternate(conn)) => + NativeDisplay::X11(conn.x11_display as usize), + NativeConnection::Alternate(_) => unimplemented!(), + }; - #[cfg(any(target_os = "linux", target_os = "windows"))] - { - if let Some(display) = self.gl_context.borrow().egl_display() { - return NativeDisplay::Egl(display as usize); - } - } + // @TODO(victor): https://github.com/servo/media/pull/315 + #[cfg(target_os = "macos")] + #[allow(unreachable_code)] + return unimplemented!(); - NativeDisplay::Unknown + #[cfg(not(any(target_os = "linux", target_os = "windows", target_os = "macos")))] + return unimplemented!(); } fn get_gl_api(&self) -> GlApi { - let api = self.gl_context.borrow().get_api(); - - let version = self.gl.get_string(gl::VERSION); - let version = version.trim_start_matches("OpenGL ES "); - let mut values = version.split(&['.', ' '][..]); - let major = values - .next() - .and_then(|v| v.parse::().ok()) - .unwrap_or(1); - let minor = values - .next() - .and_then(|v| v.parse::().ok()) - .unwrap_or(20); - + let api = self.webrender_surfman.connection().gl_api(); + let attributes = self.webrender_surfman.context_attributes(); + let GLVersion { major, minor } = attributes.version; match api { - glutin::Api::OpenGl if major >= 3 && minor >= 2 => GlApi::OpenGL3, - glutin::Api::OpenGl => GlApi::OpenGL, - glutin::Api::OpenGlEs if major > 1 => GlApi::Gles2, - glutin::Api::OpenGlEs => GlApi::Gles1, - _ => GlApi::None, + GLApi::GL if major >= 3 && minor >= 2 => GlApi::OpenGL3, + GLApi::GL => GlApi::OpenGL, + GLApi::GLES if major > 1 => GlApi::Gles2, + GLApi::GLES => GlApi::Gles1, } } } @@ -748,3 +626,81 @@ fn load_icon(icon_bytes: &[u8]) -> Icon { }; Icon::from_rgba(icon_rgba, icon_width, icon_height).expect("Failed to load icon") } + +struct XRWindow { + winit_window: winit::Window, + pose: Rc, +} + +struct XRWindowPose { + xr_rotation: Cell>, + xr_translation: Cell>, +} + +impl webxr::glwindow::GlWindow for XRWindow { + fn get_native_widget(&self, device: &Device) -> NativeWidget { + device.connection() + .create_native_widget_from_winit_window(&self.winit_window) + .expect("Failed to create native widget") + } + + fn get_rotation(&self) -> Rotation3D { + self.pose.xr_rotation.get().clone() + } + + fn get_translation(&self) -> Vector3D { + self.pose.xr_translation.get().clone() + } +} + +impl XRWindowPose { + fn handle_xr_translation(&self, input: &KeyboardEvent) { + if input.state != KeyState::Down { + return; + } + const NORMAL_TRANSLATE: f32 = 0.1; + const QUICK_TRANSLATE: f32 = 1.0; + let mut x = 0.0; + let mut z = 0.0; + match input.key { + Key::Character(ref k) => match &**k { + "w" => z = -NORMAL_TRANSLATE, + "W" => z = -QUICK_TRANSLATE, + "s" => z = NORMAL_TRANSLATE, + "S" => z = QUICK_TRANSLATE, + "a" => x = -NORMAL_TRANSLATE, + "A" => x = -QUICK_TRANSLATE, + "d" => x = NORMAL_TRANSLATE, + "D" => x = QUICK_TRANSLATE, + _ => return, + }, + _ => return, + }; + let (old_x, old_y, old_z) = self.xr_translation.get().to_tuple(); + let vec = Vector3D::new(x + old_x, old_y, z + old_z); + self.xr_translation.set(vec); + } + + fn handle_xr_rotation(&self, input: &KeyboardInput) { + if input.state != winit::ElementState::Pressed { + return; + } + let mut x = 0.0; + let mut y = 0.0; + match input.virtual_keycode { + Some(VirtualKeyCode::Up) => x = 1.0, + Some(VirtualKeyCode::Down) => x = -1.0, + Some(VirtualKeyCode::Left) => y = 1.0, + Some(VirtualKeyCode::Right) => y = -1.0, + _ => return, + }; + if input.modifiers.shift { + x = 10.0 * x; + y = 10.0 * y; + } + let x: Rotation3D<_, UnknownUnit, UnknownUnit> = Rotation3D::around_x(Angle::degrees(x)); + let y: Rotation3D<_, UnknownUnit, UnknownUnit> = Rotation3D::around_y(Angle::degrees(y)); + let rotation = self.xr_rotation.get().post_rotate(&x).post_rotate(&y); + self.xr_rotation.set(rotation); + } +} diff --git a/ports/glutin/headless_window.rs b/ports/glutin/headless_window.rs index c24d142fda5..b2c7a59d36e 100644 --- a/ports/glutin/headless_window.rs +++ b/ports/glutin/headless_window.rs @@ -4,93 +4,28 @@ //! A headless window implementation. +use crate::events_loop::EventsLoop; use crate::window_trait::WindowPortsMethods; -use euclid::{default::Size2D as UntypedSize2D, Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; -use gleam::gl; -use glutin; +use euclid::{Point2D, Rotation3D, Scale, Size2D, UnknownUnit, Vector3D}; +use winit; use servo::compositing::windowing::{AnimationState, WindowEvent}; use servo::compositing::windowing::{EmbedderCoordinates, WindowMethods}; use servo::servo_geometry::DeviceIndependentPixel; use servo::style_traits::DevicePixel; -use servo::webrender_api::units::{DeviceIntRect, DeviceIntSize}; +use servo::webrender_api::units::DeviceIntRect; use servo_media::player::context as MediaPlayerCtxt; +use servo::webrender_surfman::WebrenderSurfman; use std::cell::Cell; -#[cfg(any(target_os = "linux", target_os = "macos"))] -use std::cell::RefCell; -#[cfg(any(target_os = "linux", target_os = "macos"))] -use std::ffi::CString; -#[cfg(any(target_os = "linux", target_os = "macos"))] -use std::mem; -use std::os::raw::c_void; -use std::ptr; use std::rc::Rc; - -#[cfg(any(target_os = "linux", target_os = "macos"))] -struct HeadlessContext { - width: u32, - height: u32, - context: osmesa_sys::OSMesaContext, - buffer: RefCell>, -} - -#[cfg(not(any(target_os = "linux", target_os = "macos")))] -struct HeadlessContext { - width: u32, - height: u32, -} - -impl HeadlessContext { - #[cfg(any(target_os = "linux", target_os = "macos"))] - fn new(width: u32, height: u32, share: Option<&HeadlessContext>) -> HeadlessContext { - let mut attribs = Vec::new(); - - attribs.push(osmesa_sys::OSMESA_PROFILE); - attribs.push(osmesa_sys::OSMESA_CORE_PROFILE); - attribs.push(osmesa_sys::OSMESA_CONTEXT_MAJOR_VERSION); - attribs.push(3); - attribs.push(osmesa_sys::OSMESA_CONTEXT_MINOR_VERSION); - attribs.push(3); - attribs.push(0); - - let share = share.map_or(ptr::null_mut(), |share| share.context as *mut _); - - let context = unsafe { osmesa_sys::OSMesaCreateContextAttribs(attribs.as_ptr(), share) }; - - assert!(!context.is_null()); - - HeadlessContext { - width: width, - height: height, - context: context, - buffer: RefCell::new(vec![0; (width * height) as usize]), - } - } - - #[cfg(not(any(target_os = "linux", target_os = "macos")))] - fn new(width: u32, height: u32, _share: Option<&HeadlessContext>) -> HeadlessContext { - HeadlessContext { - width: width, - height: height, - } - } - - #[cfg(any(target_os = "linux", target_os = "macos"))] - fn get_proc_address(s: &str) -> *const c_void { - let c_str = CString::new(s).expect("Unable to create CString"); - unsafe { mem::transmute(osmesa_sys::OSMesaGetProcAddress(c_str.as_ptr())) } - } - - #[cfg(not(any(target_os = "linux", target_os = "macos")))] - fn get_proc_address(_: &str) -> *const c_void { - ptr::null() as *const _ - } -} +use surfman::Connection; +use surfman::Device; +use surfman::NativeWidget; +use surfman::SurfaceType; pub struct Window { - context: HeadlessContext, + webrender_surfman: WebrenderSurfman, animation_state: Cell, fullscreen: Cell, - gl: Rc, device_pixels_per_px: Option, } @@ -99,18 +34,19 @@ impl Window { size: Size2D, device_pixels_per_px: Option, ) -> Rc { - let context = HeadlessContext::new(size.width, size.height, None); - let gl = unsafe { gl::GlFns::load_with(|s| HeadlessContext::get_proc_address(s)) }; - - // Print some information about the headless renderer that - // can be useful in diagnosing CI failures on build machines. - println!("{}", gl.get_string(gl::VENDOR)); - println!("{}", gl.get_string(gl::RENDERER)); - println!("{}", gl.get_string(gl::VERSION)); + // Initialize surfman + let connection = Connection::new().expect("Failed to create connection"); + let adapter = connection.create_software_adapter().expect("Failed to create adapter"); + let size = size.to_untyped().to_i32(); + let surface_type = SurfaceType::Generic { size }; + let webrender_surfman = WebrenderSurfman::create( + &connection, + &adapter, + surface_type, + ).expect("Failed to create WR surfman"); let window = Window { - context, - gl, + webrender_surfman, animation_state: Cell::new(AnimationState::Idle), fullscreen: Cell::new(false), device_pixels_per_px, @@ -136,13 +72,18 @@ impl WindowPortsMethods for Window { false } - fn id(&self) -> glutin::WindowId { - unsafe { glutin::WindowId::dummy() } + fn id(&self) -> winit::WindowId { + unsafe { winit::WindowId::dummy() } } fn page_height(&self) -> f32 { + let height = self.webrender_surfman + .context_surface_info() + .unwrap_or(None) + .map(|info| info.size.height) + .unwrap_or(0); let dpr = self.servo_hidpi_factor(); - self.context.height as f32 * dpr.get() + height as f32 * dpr.get() } fn set_fullscreen(&self, state: bool) { @@ -157,24 +98,27 @@ impl WindowPortsMethods for Window { self.animation_state.get() == AnimationState::Animating } - fn winit_event_to_servo_event(&self, _event: glutin::WindowEvent) { + fn winit_event_to_servo_event(&self, _event: winit::WindowEvent) { // Not expecting any winit events. } + + fn new_glwindow(&self, _events_loop: &EventsLoop) -> Box { + unimplemented!() + } } impl WindowMethods for Window { - fn gl(&self) -> Rc { - self.gl.clone() - } - - fn get_coordinates(&self) -> EmbedderCoordinates { + fn get_coordinates(&self) -> EmbedderCoordinates { let dpr = self.servo_hidpi_factor(); - let size = (Size2D::new(self.context.width, self.context.height).to_f32() * dpr).to_i32(); + let size = self.webrender_surfman + .context_surface_info() + .unwrap_or(None) + .map(|info| Size2D::from_untyped(info.size)) + .unwrap_or(Size2D::new(0, 0)); let viewport = DeviceIntRect::new(Point2D::zero(), size); - let framebuffer = DeviceIntSize::from_untyped(size.to_untyped()); EmbedderCoordinates { viewport, - framebuffer, + framebuffer: size, window: (size, Point2D::zero()), screen: size, screen_avail: size, @@ -182,31 +126,11 @@ impl WindowMethods for Window { } } - fn present(&self) {} - - fn set_animation_state(&self, state: AnimationState) { + fn set_animation_state(&self, state: AnimationState) { self.animation_state.set(state); } - #[cfg(any(target_os = "linux", target_os = "macos"))] - fn make_gl_context_current(&self) { - unsafe { - let mut buffer = self.context.buffer.borrow_mut(); - let ret = osmesa_sys::OSMesaMakeCurrent( - self.context.context, - buffer.as_mut_ptr() as *mut _, - gl::UNSIGNED_BYTE, - self.context.width as i32, - self.context.height as i32, - ); - assert_ne!(ret, 0); - }; - } - - #[cfg(not(any(target_os = "linux", target_os = "macos")))] - fn make_gl_context_current(&self) {} - - fn get_gl_context(&self) -> MediaPlayerCtxt::GlContext { + fn get_gl_context(&self) -> MediaPlayerCtxt::GlContext { MediaPlayerCtxt::GlContext::Unknown } @@ -217,32 +141,17 @@ impl WindowMethods for Window { fn get_gl_api(&self) -> MediaPlayerCtxt::GlApi { MediaPlayerCtxt::GlApi::None } + + fn webrender_surfman(&self) -> WebrenderSurfman { + self.webrender_surfman.clone() + } } impl webxr::glwindow::GlWindow for Window { - fn make_current(&self) {} - fn swap_buffers(&self) {} - fn size(&self) -> UntypedSize2D { - let dpr = self.servo_hidpi_factor().get(); - Size2D::new( - (self.context.width as f32 * dpr) as gl::GLsizei, - (self.context.height as f32 * dpr) as gl::GLsizei, - ) - } - fn new_window(&self) -> Result, ()> { - let width = self.context.width; - let height = self.context.height; - let share = Some(&self.context); - let context = HeadlessContext::new(width, height, share); - let gl = self.gl.clone(); - Ok(Rc::new(Window { - context, - gl, - animation_state: Cell::new(AnimationState::Idle), - fullscreen: Cell::new(false), - device_pixels_per_px: self.device_pixels_per_px, - })) + fn get_native_widget(&self, _device: &Device) -> NativeWidget { + unimplemented!() } + fn get_rotation(&self) -> Rotation3D { Rotation3D::identity() } diff --git a/ports/glutin/keyutils.rs b/ports/glutin/keyutils.rs index 7dd7fdf5ca5..9d7b3285454 100644 --- a/ports/glutin/keyutils.rs +++ b/ports/glutin/keyutils.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use glutin::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode}; +use winit::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode}; use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers}; // Some shortcuts use Cmd on Mac and Control on other systems. @@ -18,7 +18,7 @@ pub const CMD_OR_ALT: Modifiers = Modifiers::META; pub const CMD_OR_ALT: Modifiers = Modifiers::ALT; fn get_servo_key_from_winit_key(key: Option) -> Key { - use glutin::VirtualKeyCode::*; + use winit::VirtualKeyCode::*; // TODO: figure out how to map NavigateForward, NavigateBackward // TODO: map the remaining keys if possible let key = if let Some(key) = key { @@ -127,7 +127,7 @@ fn get_servo_key_from_winit_key(key: Option) -> Key { } fn get_servo_location_from_winit_key(key: Option) -> Location { - use glutin::VirtualKeyCode::*; + use winit::VirtualKeyCode::*; // TODO: add more numpad keys let key = if let Some(key) = key { key diff --git a/ports/glutin/main2.rs b/ports/glutin/main2.rs index dcd179ad370..707cf1d422c 100644 --- a/ports/glutin/main2.rs +++ b/ports/glutin/main2.rs @@ -13,7 +13,6 @@ extern crate sig; mod app; mod backtrace; mod browser; -mod context; mod embedder; mod events_loop; mod headed_window; @@ -95,12 +94,6 @@ pub fn main() { "clean-shutdown", "Do not shutdown until all threads have finished (macos only)", ); - opts.optflag( - "", - "disable-vsync", - "Disable vsync mode in the compositor to allow profiling at more than monitor refresh rate", - ); - opts.optflag("", "msaa", "Use multisample antialiasing in WebRender."); opts.optflag("b", "no-native-titlebar", "Do not use native titlebar"); opts.optopt("", "device-pixel-ratio", "Device pixels per px", ""); opts.optopt( @@ -170,28 +163,19 @@ pub fn main() { process::exit(0); } - let angle = opts_matches.opt_present("angle"); let clean_shutdown = opts_matches.opt_present("clean-shutdown"); let do_not_use_native_titlebar = opts_matches.opt_present("no-native-titlebar") || !(pref!(shell.native_titlebar.enabled)); - let enable_vsync = !opts_matches.opt_present("disable-vsync"); - let use_msaa = opts_matches.opt_present("msaa"); let device_pixels_per_px = opts_matches.opt_str("device-pixel-ratio").map(|dppx_str| { dppx_str.parse().unwrap_or_else(|err| { error!("Error parsing option: --device-pixel-ratio ({})", err); process::exit(1); }) }); + let user_agent = opts_matches.opt_str("u"); - App::run( - angle, - enable_vsync, - use_msaa, - do_not_use_native_titlebar, - device_pixels_per_px, - user_agent, - ); + App::run(do_not_use_native_titlebar, device_pixels_per_px, user_agent); platform::deinit(clean_shutdown) } diff --git a/ports/glutin/window_trait.rs b/ports/glutin/window_trait.rs index 6a1fd57f631..9fee3a66075 100644 --- a/ports/glutin/window_trait.rs +++ b/ports/glutin/window_trait.rs @@ -5,7 +5,8 @@ //! Definition of Window. //! Implemented by headless and headed windows. -use glutin; +use crate::events_loop::EventsLoop; +use winit; use servo::compositing::windowing::{WindowEvent, WindowMethods}; use servo::embedder_traits::Cursor; use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize}; @@ -13,17 +14,18 @@ use servo::webrender_api::units::{DeviceIntPoint, DeviceIntSize}; // This should vary by zoom level and maybe actual text size (focused or under cursor) pub const LINE_HEIGHT: f32 = 38.0; -pub trait WindowPortsMethods: WindowMethods + webxr::glwindow::GlWindow { +pub trait WindowPortsMethods: WindowMethods { fn get_events(&self) -> Vec; - fn id(&self) -> glutin::WindowId; + fn id(&self) -> winit::WindowId; fn has_events(&self) -> bool; fn page_height(&self) -> f32; fn get_fullscreen(&self) -> bool; - fn winit_event_to_servo_event(&self, event: glutin::WindowEvent); + fn winit_event_to_servo_event(&self, event: winit::WindowEvent); fn is_animating(&self) -> bool; fn set_title(&self, _title: &str) {} fn set_inner_size(&self, _size: DeviceIntSize) {} fn set_position(&self, _point: DeviceIntPoint) {} fn set_fullscreen(&self, _state: bool) {} fn set_cursor(&self, _cursor: Cursor) {} + fn new_glwindow(&self, events_loop: &EventsLoop) -> Box; } diff --git a/ports/gstplugin/Cargo.toml b/ports/gstplugin/Cargo.toml index 60d3e6efdb8..fa044a3043c 100644 --- a/ports/gstplugin/Cargo.toml +++ b/ports/gstplugin/Cargo.toml @@ -30,9 +30,9 @@ lazy_static = "1.4" libservo = {path = "../../components/servo"} servo-media = {git = "https://github.com/servo/media"} sparkle = "0.1" -surfman = { git = "https://github.com/pcwalton/surfman", branch = "multi" } +surfman = { git = "https://github.com/servo/surfman" } surfman-chains-api = "0.2" -surfman-chains = { git = "https://github.com/asajeffrey/surfman-chains", branch = "multi" } +surfman-chains = { git = "https://github.com/asajeffrey/surfman-chains" } [build-dependencies] gst-plugin-version-helper = "0.1" diff --git a/ports/gstplugin/servowebsrc.rs b/ports/gstplugin/servowebsrc.rs index b956c2f34c0..05505927db2 100644 --- a/ports/gstplugin/servowebsrc.rs +++ b/ports/gstplugin/servowebsrc.rs @@ -76,35 +76,20 @@ use servo::embedder_traits::EventLoopWaker; use servo::msg::constellation_msg::TopLevelBrowsingContextId; use servo::servo_url::ServoUrl; use servo::webrender_api::units::DevicePixel; +use servo::webrender_surfman::WebrenderSurfman; use servo::Servo; use sparkle::gl; use sparkle::gl::types::GLuint; use sparkle::gl::Gl; -use surfman::connection::Connection as ConnectionAPI; -use surfman::device::Device as DeviceAPI; -use surfman::ContextAttributeFlags; -use surfman::ContextAttributes; -use surfman::GLApi; -use surfman::GLVersion; -use surfman::SurfaceAccess; +use surfman::Connection; +use surfman::Context; +use surfman::Device; use surfman::SurfaceType; -use surfman_chains::SurfmanProvider; use surfman_chains::SwapChain; use surfman_chains_api::SwapChainAPI; -// For the moment, we only support wayland and cgl. -#[cfg(target_os = "macos")] -use surfman::platform::macos::cgl::device::Device; -#[cfg(all(unix, not(target_os = "macos")))] -use surfman::platform::unix::wayland::device::Device; - -type Context = ::Context; -type Connection = ::Connection; -type NativeContext = ::NativeContext; -type NativeConnection = ::NativeConnection; - use std::cell::RefCell; use std::collections::HashMap; use std::convert::TryFrom; @@ -165,7 +150,7 @@ impl std::fmt::Debug for ConnectionWhichImplementsDebug { #[derive(Debug)] enum ServoWebSrcMsg { - Start(ConnectionWhichImplementsDebug, GLVersion, ServoUrl), + Start(ConnectionWhichImplementsDebug, ServoUrl), GetSwapChain(Sender>), Resize(Size2D), Heartbeat, @@ -180,41 +165,25 @@ const DEFAULT_FRAME_DURATION: Duration = Duration::from_micros(16_667); struct ServoThread { receiver: Receiver, - swap_chain: SwapChain, - gfx: Rc>, servo: Servo, } -struct ServoThreadGfx { - device: Device, - context: Context, - gl: Rc, -} - impl ServoThread { fn new(receiver: Receiver) -> Self { - let (connection, version, url) = match receiver.recv() { - Ok(ServoWebSrcMsg::Start(connection, version, url)) => (connection.0, version, url), + let (connection, url) = match receiver.recv() { + Ok(ServoWebSrcMsg::Start(connection, url)) => (connection.0, url), e => panic!("Failed to start ({:?})", e), }; - info!( - "Created new servo thread (GL v{}.{} for {})", - version.major, version.minor, url - ); + info!("Created new servo thread for {}", url); let embedder = Box::new(ServoWebSrcEmbedder); - let window = Rc::new(ServoWebSrcWindow::new(connection, version)); - let swap_chain = window.swap_chain.clone(); - let gfx = window.gfx.clone(); + let window = Rc::new(ServoWebSrcWindow::new(connection)); + let mut servo = Servo::new(embedder, window, None); + let id = TopLevelBrowsingContextId::new(); servo.handle_events(vec![WindowEvent::NewBrowser(url, id)]); - Self { - receiver, - swap_chain, - gfx, - servo, - } + Self { receiver, servo } } fn run(&mut self) { @@ -222,9 +191,7 @@ impl ServoThread { debug!("Servo thread handling message {:?}", msg); match msg { ServoWebSrcMsg::Start(..) => error!("Already started"), - ServoWebSrcMsg::GetSwapChain(sender) => sender - .send(self.swap_chain.clone()) - .expect("Failed to send swap chain"), + ServoWebSrcMsg::GetSwapChain(sender) => self.send_swap_chain(sender), ServoWebSrcMsg::Resize(size) => self.resize(size), ServoWebSrcMsg::Heartbeat => self.servo.handle_events(vec![]), ServoWebSrcMsg::Stop => break, @@ -233,43 +200,24 @@ impl ServoThread { self.servo.handle_events(vec![WindowEvent::Quit]); } - fn resize(&mut self, size: Size2D) { - { - let mut gfx = self.gfx.borrow_mut(); - let gfx = &mut *gfx; - self.swap_chain - .resize(&mut gfx.device, &mut gfx.context, size.to_untyped()) - .expect("Failed to resize"); - gfx.gl.viewport(0, 0, size.width, size.height); - let fbo = gfx - .device - .context_surface_info(&gfx.context) - .expect("Failed to get context info") - .expect("Failed to get context info") - .framebuffer_object; - gfx.device - .make_context_current(&gfx.context) - .expect("Failed to make current"); - gfx.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo); - debug_assert_eq!( - ( - gfx.gl.check_framebuffer_status(gl::FRAMEBUFFER), - gfx.gl.get_error() - ), - (gl::FRAMEBUFFER_COMPLETE, gl::NO_ERROR) - ); - } - self.servo.handle_events(vec![WindowEvent::Resize]); + fn send_swap_chain(&mut self, sender: Sender>) { + let swap_chain = self + .servo + .window() + .webrender_surfman + .swap_chain() + .expect("Failed to get swap chain") + .clone(); + sender.send(swap_chain).expect("Failed to send swap chain"); } -} -impl Drop for ServoThread { - fn drop(&mut self) { - let mut gfx = self.gfx.borrow_mut(); - let gfx = &mut *gfx; - self.swap_chain - .destroy(&mut gfx.device, &mut gfx.context) - .expect("Failed to destroy swap chain") + fn resize(&mut self, size: Size2D) { + let _ = self + .servo + .window() + .webrender_surfman + .resize(size.to_untyped()); + self.servo.handle_events(vec![WindowEvent::Resize]); } } @@ -290,154 +238,35 @@ impl EventLoopWaker for ServoWebSrcEmbedder { } struct ServoWebSrcWindow { - swap_chain: SwapChain, - gfx: Rc>, - gl: Rc, + webrender_surfman: WebrenderSurfman, } impl ServoWebSrcWindow { - fn new(connection: Connection, version: GLVersion) -> Self { - let flags = ContextAttributeFlags::DEPTH | - ContextAttributeFlags::STENCIL | - ContextAttributeFlags::ALPHA; - let attributes = ContextAttributes { version, flags }; - + fn new(connection: Connection) -> Self { let adapter = connection .create_adapter() .expect("Failed to create adapter"); - let mut device = connection - .create_device(&adapter) - .expect("Failed to create device"); - let descriptor = device - .create_context_descriptor(&attributes) - .expect("Failed to create descriptor"); - let mut context = device - .create_context(&descriptor) - .expect("Failed to create context"); - - let (gleam, gl) = unsafe { - match device.gl_api() { - GLApi::GL => ( - gleam::gl::GlFns::load_with(|s| device.get_proc_address(&context, s)), - Gl::gl_fns(gl::ffi_gl::Gl::load_with(|s| { - device.get_proc_address(&context, s) - })), - ), - GLApi::GLES => ( - gleam::gl::GlesFns::load_with(|s| device.get_proc_address(&context, s)), - Gl::gles_fns(gl::ffi_gles::Gles2::load_with(|s| { - device.get_proc_address(&context, s) - })), - ), - } - }; - - device - .make_context_current(&mut context) - .expect("Failed to make context current"); - debug_assert_eq!(gl.get_error(), gl::NO_ERROR); - let access = SurfaceAccess::GPUOnly; let size = Size2D::new(512, 512); let surface_type = SurfaceType::Generic { size }; - let surface = device - .create_surface(&mut context, access, surface_type) - .expect("Failed to create surface"); + let webrender_surfman = WebrenderSurfman::create(&connection, &adapter, surface_type) + .expect("Failed to create surfman"); - device - .bind_surface_to_context(&mut context, surface) - .expect("Failed to bind surface"); - let fbo = device - .context_surface_info(&context) - .expect("Failed to get context info") - .expect("Failed to get context info") - .framebuffer_object; - gl.viewport(0, 0, size.width, size.height); - gl.bind_framebuffer(gl::FRAMEBUFFER, fbo); - gl.clear_color(0.0, 0.0, 0.0, 1.0); - gl.clear(gl::COLOR_BUFFER_BIT); - debug_assert_eq!( - (gl.check_framebuffer_status(gl::FRAMEBUFFER), gl.get_error()), - (gl::FRAMEBUFFER_COMPLETE, gl::NO_ERROR) - ); - - let provider = Box::new(SurfmanProvider::new(access)); - let swap_chain = SwapChain::create_attached(&mut device, &mut context, provider) - .expect("Failed to create swap chain"); - - device.make_no_context_current().unwrap(); - - let gfx = Rc::new(RefCell::new(ServoThreadGfx { - device, - context, - gl, - })); - - Self { - swap_chain, - gfx, - gl: gleam, - } + Self { webrender_surfman } } } impl WindowMethods for ServoWebSrcWindow { - fn present(&self) { - debug!("EMBEDDER present"); - let mut gfx = self.gfx.borrow_mut(); - let gfx = &mut *gfx; - gfx.device - .make_context_current(&mut gfx.context) - .expect("Failed to make context current"); - debug_assert_eq!( - ( - gfx.gl.check_framebuffer_status(gl::FRAMEBUFFER), - gfx.gl.get_error() - ), - (gl::FRAMEBUFFER_COMPLETE, gl::NO_ERROR) - ); - self.swap_chain - .swap_buffers(&mut gfx.device, &mut gfx.context) - .expect("Failed to swap buffers"); - let fbo = gfx - .device - .context_surface_info(&gfx.context) - .expect("Failed to get context info") - .expect("Failed to get context info") - .framebuffer_object; - gfx.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo); - debug_assert_eq!( - ( - gfx.gl.check_framebuffer_status(gl::FRAMEBUFFER), - gfx.gl.get_error() - ), - (gl::FRAMEBUFFER_COMPLETE, gl::NO_ERROR) - ); - let _ = gfx.device.make_no_context_current(); - } - - fn make_gl_context_current(&self) { - debug!("EMBEDDER make_context_current"); - let mut gfx = self.gfx.borrow_mut(); - let gfx = &mut *gfx; - gfx.device - .make_context_current(&mut gfx.context) - .expect("Failed to make context current"); - debug!("EMBEDDER done make_context_current"); - debug_assert_eq!( - ( - gfx.gl.check_framebuffer_status(gl::FRAMEBUFFER), - gfx.gl.get_error() - ), - (gl::FRAMEBUFFER_COMPLETE, gl::NO_ERROR) - ); - } - - fn gl(&self) -> Rc { - self.gl.clone() + fn webrender_surfman(&self) -> WebrenderSurfman { + self.webrender_surfman.clone() } fn get_coordinates(&self) -> EmbedderCoordinates { - let size = Size2D::from_untyped(self.swap_chain.size()); + let size = self + .webrender_surfman + .context_surface_info() + .unwrap_or(None) + .map(|info| Size2D::from_untyped(info.size)) + .unwrap_or(Size2D::new(0, 0)); info!("EMBEDDER coordinates {}", size); let origin = Point2D::origin(); EmbedderCoordinates { @@ -658,11 +487,6 @@ impl BaseSrcImpl for ServoWebSrc { )); } let gl_context = unsafe { GLContext::from_glib_borrow(gst_gl_context) }; - let gl_version = gl_context.get_gl_version(); - let version = GLVersion { - major: gl_version.0 as u8, - minor: gl_version.1 as u8, - }; // Get the surfman connection on the GL thread let mut task = BootstrapSurfmanOnGLThread { @@ -683,7 +507,6 @@ impl BaseSrcImpl for ServoWebSrc { // Inform servo we're starting let _ = self.sender.send(ServoWebSrcMsg::Start( ConnectionWhichImplementsDebug(connection), - version, url, )); Ok(()) @@ -784,11 +607,32 @@ impl ServoWebSrc { gl_context .activate(true) .expect("Failed to activate GL context"); - let native_connection = - NativeConnection::current().expect("Failed to bootstrap native connection"); - let connection = unsafe { Connection::from_native_connection(native_connection) } - .expect("Failed to bootstrap surfman connection"); - Some(connection) + // TODO: support other connections on linux? + #[cfg(target_os = "linux")] + { + use surfman::platform::generic::multi; + use surfman::platform::unix::wayland; + let native_connection = wayland::connection::NativeConnection::current() + .expect("Failed to bootstrap native connection"); + let wayland_connection = unsafe { + wayland::connection::Connection::from_native_connection(native_connection) + .expect("Failed to bootstrap wayland connection") + }; + let connection = multi::connection::Connection::Default( + multi::connection::Connection::Default(wayland_connection), + ); + Some(connection) + } + #[cfg(not(target_os = "linux"))] + { + use surfman::connection::Connection as ConnectionAPI; + type NativeConnection = ::NativeConnection; + let native_connection = + NativeConnection::current().expect("Failed to bootstrap native connection"); + let connection = unsafe { Connection::from_native_connection(native_connection) } + .expect("Failed to bootstrap surfman connection"); + Some(connection) + } } } @@ -840,8 +684,21 @@ impl ServoWebSrc { let device = connection .create_device(&adapter) .expect("Failed to bootstrap surfman device"); - let native_context = - NativeContext::current().expect("Failed to bootstrap native context"); + #[cfg(target_os = "linux")] + let native_context = { + use surfman::platform::generic::multi; + use surfman::platform::unix::wayland; + multi::context::NativeContext::Default(multi::context::NativeContext::Default( + wayland::context::NativeContext::current() + .expect("Failed to bootstrap native context"), + )) + }; + #[cfg(not(target_os = "linux"))] + let native_context = { + use surfman::device::Device as DeviceAPI; + type NativeContext = ::NativeContext; + NativeContext::current().expect("Failed to bootstrap native context") + }; let context = unsafe { device .create_context_from_native_context(native_context) @@ -995,5 +852,3 @@ impl ServoWebSrc { Ok(()) } } - -// TODO: Implement that trait for more platforms diff --git a/ports/libsimpleservo/api/Cargo.toml b/ports/libsimpleservo/api/Cargo.toml index 4ea4d8d8e35..29f0bba18e0 100644 --- a/ports/libsimpleservo/api/Cargo.toml +++ b/ports/libsimpleservo/api/Cargo.toml @@ -12,6 +12,7 @@ ipc-channel = "0.14" libservo = { path = "../../../components/servo" } log = "0.4" servo-media = { git = "https://github.com/servo/media" } +surfman = { version = "0.2", features = ["sm-angle-default"] } webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] } webxr = { git = "https://github.com/servo/webxr"} diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index d33281b0739..afd2dd89cc2 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -32,6 +32,7 @@ use servo::servo_config::{pref, set_pref}; use servo::servo_url::ServoUrl; use servo::webrender_api::units::DevicePixel; use servo::webrender_api::ScrollLocation; +use servo::webrender_surfman::WebrenderSurfman; use servo::{self, gl, BrowserId, Servo}; use servo_media::player::context as MediaPlayerContext; use std::cell::RefCell; @@ -39,6 +40,8 @@ use std::mem; use std::os::raw::c_void; use std::path::PathBuf; use std::rc::Rc; +use surfman::Connection; +use surfman::SurfaceType; thread_local! { pub static SERVO: RefCell> = RefCell::new(None); @@ -58,6 +61,7 @@ pub struct InitOptions { pub enable_subpixel_text_antialiasing: bool, pub gl_context_pointer: Option<*const c_void>, pub native_display_pointer: Option<*const c_void>, + pub native_widget: *mut c_void, } #[derive(Clone, Debug)] @@ -84,12 +88,6 @@ impl Coordinates { /// Callbacks. Implemented by embedder. Called by Servo. pub trait HostTrait { - /// Will be called from the thread used for the init call. - /// Will be called when the GL buffer has been updated. - fn flush(&self); - /// Will be called before drawing. - /// Time to make the targetted GL context current. - fn make_current(&self); /// Show alert. fn prompt_alert(&self, msg: String, trusted: bool); /// Ask Yes/No question. @@ -211,13 +209,28 @@ pub fn init( gl.clear(gl::COLOR_BUFFER_BIT); gl.finish(); + // Initialize surfman + let connection = Connection::new().or(Err("Failed to create connection"))?; + let adapter = connection + .create_adapter() + .or(Err("Failed to create adapter"))?; + let native_widget = unsafe { + connection.create_native_widget_from_ptr( + init_opts.native_widget, + init_opts.coordinates.framebuffer.to_untyped(), + ) + }; + let surface_type = SurfaceType::Widget { native_widget }; + let webrender_surfman = WebrenderSurfman::create(&connection, &adapter, surface_type) + .or(Err("Failed to create surface manager"))?; + let window_callbacks = Rc::new(ServoWindowCallbacks { host_callbacks: callbacks, - gl: gl.clone(), coordinates: RefCell::new(init_opts.coordinates), density: init_opts.density, gl_context_pointer: init_opts.gl_context_pointer, native_display_pointer: init_opts.native_display_pointer, + webrender_surfman, }); let embedder_callbacks = Box::new(ServoEmbedderCallbacks { @@ -723,12 +736,12 @@ struct ServoEmbedderCallbacks { } struct ServoWindowCallbacks { - gl: Rc, host_callbacks: Box, coordinates: RefCell, density: f32, gl_context_pointer: Option<*const c_void>, native_display_pointer: Option<*const c_void>, + webrender_surfman: WebrenderSurfman, } impl EmbedderMethods for ServoEmbedderCallbacks { @@ -798,7 +811,7 @@ impl EmbedderMethods for ServoEmbedderCallbacks { struct GlThread(WebGlExecutor); impl webxr::openxr::GlThread for GlThread { - fn execute(&self, runnable: Box) { + fn execute(&self, runnable: Box) { let _ = self.0.send(runnable); } fn clone(&self) -> Box { @@ -835,19 +848,8 @@ impl EmbedderMethods for ServoEmbedderCallbacks { } impl WindowMethods for ServoWindowCallbacks { - fn make_gl_context_current(&self) { - debug!("WindowMethods::prepare_for_composite"); - self.host_callbacks.make_current(); - } - - fn present(&self) { - debug!("WindowMethods::present"); - self.host_callbacks.flush(); - } - - fn gl(&self) -> Rc { - debug!("WindowMethods::gl"); - self.gl.clone() + fn webrender_surfman(&self) -> WebrenderSurfman { + self.webrender_surfman.clone() } fn set_animation_state(&self, state: AnimationState) { diff --git a/ports/libsimpleservo/capi/Cargo.toml b/ports/libsimpleservo/capi/Cargo.toml index 6695abbefeb..eb8274f250e 100644 --- a/ports/libsimpleservo/capi/Cargo.toml +++ b/ports/libsimpleservo/capi/Cargo.toml @@ -18,6 +18,7 @@ log = "0.4" lazy_static = "1" env_logger = "0.7" backtrace = "0.3" +surfman = "0.2" [target.'cfg(target_os = "windows")'.dependencies] libc = "0.2" diff --git a/ports/libsimpleservo/capi/src/lib.rs b/ports/libsimpleservo/capi/src/lib.rs index 60bd6a2f7a4..d3e86424d28 100644 --- a/ports/libsimpleservo/capi/src/lib.rs +++ b/ports/libsimpleservo/capi/src/lib.rs @@ -203,8 +203,6 @@ where /// Callback used by Servo internals #[repr(C)] pub struct CHostCallbacks { - pub flush: extern "C" fn(), - pub make_current: extern "C" fn(), pub on_load_started: extern "C" fn(), pub on_load_ended: extern "C" fn(), pub on_title_changed: extern "C" fn(title: *const c_char), @@ -245,6 +243,7 @@ pub struct CInitOptions { pub enable_subpixel_text_antialiasing: bool, pub vslogger_mod_list: *const *const c_char, pub vslogger_mod_size: u32, + pub native_widget: *mut c_void, } #[repr(C)] @@ -442,6 +441,7 @@ unsafe fn init( enable_subpixel_text_antialiasing: opts.enable_subpixel_text_antialiasing, gl_context_pointer: gl_context, native_display_pointer: display, + native_widget: opts.native_widget, }; let wakeup = Box::new(WakeupCallback::new(wakeup)); @@ -750,16 +750,6 @@ impl HostCallbacks { } impl HostTrait for HostCallbacks { - fn flush(&self) { - debug!("flush"); - (self.0.flush)(); - } - - fn make_current(&self) { - debug!("make_current"); - (self.0.make_current)(); - } - fn on_load_started(&self) { debug!("on_load_started"); (self.0.on_load_started)(); diff --git a/python/servo/command_base.py b/python/servo/command_base.py index 875d7e62ca2..104aa746b61 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -223,34 +223,6 @@ def append_to_path_env(string, env, name): env[name] = variable -def set_osmesa_env(bin_path, env, show_vars): - """Set proper LD_LIBRARY_PATH and DRIVE for software rendering on Linux and OSX""" - if is_linux(): - dep_path = find_dep_path_newest('osmesa-src', bin_path) - if not dep_path: - return None - osmesa_path = path.join(dep_path, "out", "lib", "gallium") - append_to_path_env(osmesa_path, env, "LD_LIBRARY_PATH") - env["GALLIUM_DRIVER"] = "softpipe" - if show_vars: - print("GALLIUM_DRIVER=" + env["GALLIUM_DRIVER"]) - print("LD_LIBRARY_PATH=" + env["LD_LIBRARY_PATH"]) - elif is_macosx(): - osmesa_dep_path = find_dep_path_newest('osmesa-src', bin_path) - if not osmesa_dep_path: - return None - osmesa_path = path.join(osmesa_dep_path, - "out", "src", "gallium", "targets", "osmesa", ".libs") - glapi_path = path.join(osmesa_dep_path, - "out", "src", "mapi", "shared-glapi", ".libs") - append_to_path_env(osmesa_path + ":" + glapi_path, env, "DYLD_LIBRARY_PATH") - env["GALLIUM_DRIVER"] = "softpipe" - if show_vars: - print("GALLIUM_DRIVER=" + env["GALLIUM_DRIVER"]) - print("DYLD_LIBRARY_PATH=" + env["DYLD_LIBRARY_PATH"]) - return env - - def gstreamer_root(target, env, topdir=None): if is_windows(): arch = { diff --git a/python/servo/post_build_commands.py b/python/servo/post_build_commands.py index 7df253e4ca3..52035850961 100644 --- a/python/servo/post_build_commands.py +++ b/python/servo/post_build_commands.py @@ -24,7 +24,7 @@ from mach.decorators import ( from servo.command_base import ( CommandBase, check_call, check_output, BIN_SUFFIX, - is_linux, set_osmesa_env, + is_linux, ) @@ -126,7 +126,6 @@ class PostBuildCommands(CommandBase): args = [bin or self.get_nightly_binary_path(nightly) or self.get_binary_path(release, dev)] if headless: - set_osmesa_env(args[0], env, debugger is not None) args.append('-z') if software: diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 7bee7633f90..dea6adce257 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -33,8 +33,8 @@ from mach.decorators import ( ) from servo.command_base import ( - BuildNotFound, CommandBase, - call, check_call, check_output, set_osmesa_env, + CommandBase, + call, check_call, check_output, ) from servo.util import host_triple @@ -197,8 +197,6 @@ class MachCommands(CommandBase): @CommandArgument('--submit', '-a', default=False, action="store_true", help="submit the data to perfherder") def test_perf(self, base=None, date=None, submit=False): - self.set_software_rendering_env(True, False) - env = self.build_env() cmd = ["bash", "test_perf.sh"] if base: @@ -441,8 +439,6 @@ class MachCommands(CommandBase): # Helper for test_css and test_wpt: def wptrunner(self, run_file, **kwargs): - self.set_software_rendering_env(kwargs['release'], kwargs['debugger']) - # By default, Rayon selects the number of worker threads # based on the available CPU count. This doesn't work very # well when running tests on CI, since we run so many @@ -753,18 +749,6 @@ class MachCommands(CommandBase): return check_call( [run_file, "|".join(tests), bin_path, base_dir]) - def set_software_rendering_env(self, use_release, show_vars): - # On Linux and mac, find the OSMesa software rendering library and - # add it to the dynamic linker search path. - try: - bin_path = self.get_binary_path(use_release, not use_release) - if not set_osmesa_env(bin_path, os.environ, show_vars): - print("Warning: Cannot set the path to OSMesa library.") - except BuildNotFound: - # This can occur when cross compiling (e.g. arm64), in which case - # we won't run the tests anyway so can safely ignore this step. - pass - def setup_clangfmt(env): cmd = "clang-format.exe" if sys.platform == "win32" else "clang-format" diff --git a/resources/prefs.json b/resources/prefs.json index 9e0f6d95b5d..980012ea2fd 100644 --- a/resources/prefs.json +++ b/resources/prefs.json @@ -38,6 +38,7 @@ "dom.webxr.test": false, "dom.worklet.timeout_ms": 10, "gfx.subpixel-text-antialiasing.enabled": true, + "gfx.texture-swizzling.enabled": true, "js.asmjs.enabled": true, "js.asyncstack.enabled": false, "js.baseline.enabled": true, diff --git a/servo-tidy.toml b/servo-tidy.toml index c70ac96877b..8fc5387d24a 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -48,10 +48,6 @@ packages = [ "quote", "unicode-xid", - # These can be removed once servo is updated to surfman 0.2 - "surfman", - "surfman-chains", - # https://github.com/servo/servo/pull/25518 "core-foundation", "core-foundation-sys", diff --git a/support/hololens/ServoApp/DefaultUrl.h b/support/hololens/ServoApp/DefaultUrl.h index 35fbe247930..98a30fa39df 100644 --- a/support/hololens/ServoApp/DefaultUrl.h +++ b/support/hololens/ServoApp/DefaultUrl.h @@ -1,3 +1,3 @@ #pragma once -#define DEFAULT_URL L"https://servo.org/hl-home/" +#define DEFAULT_URL L"https://servo.org/hl-home/" \ No newline at end of file diff --git a/support/hololens/ServoApp/ServoApp.vcxproj b/support/hololens/ServoApp/ServoApp.vcxproj index a39b23f4737..1fcd54e529f 100644 --- a/support/hololens/ServoApp/ServoApp.vcxproj +++ b/support/hololens/ServoApp/ServoApp.vcxproj @@ -947,7 +947,7 @@ - + @@ -957,6 +957,6 @@ - + diff --git a/support/hololens/ServoApp/ServoControl/OpenGLES.cpp b/support/hololens/ServoApp/ServoControl/OpenGLES.cpp index 8889ee23d77..a89e5e373d4 100644 --- a/support/hololens/ServoApp/ServoControl/OpenGLES.cpp +++ b/support/hololens/ServoApp/ServoControl/OpenGLES.cpp @@ -187,51 +187,3 @@ void OpenGLES::Reset() { Cleanup(); Initialize(); } - -EGLSurface OpenGLES::CreateSurface(SwapChainPanel const &panel, float dpi) { - EGLSurface surface = EGL_NO_SURFACE; - - const EGLint surfaceAttributes[] = {EGL_NONE}; - - PropertySet surfaceCreationProperties; - - surfaceCreationProperties.Insert(EGLNativeWindowTypeProperty, panel); - // How to set size and or scale: - // Insert(EGLRenderSurfaceSizeProperty), - // PropertyValue::CreateSize(*renderSurfaceSize)); - surfaceCreationProperties.Insert(EGLRenderResolutionScaleProperty, - PropertyValue::CreateSingle(dpi)); - - EGLNativeWindowType win = static_cast( - winrt::get_abi(surfaceCreationProperties)); - surface = - eglCreateWindowSurface(mEglDisplay, mEglConfig, win, surfaceAttributes); - - if (surface == EGL_NO_SURFACE) { - throw winrt::hresult_error(E_FAIL, L"Failed to create EGL surface"); - } - - return surface; -} - -void OpenGLES::GetSurfaceDimensions(const EGLSurface surface, EGLint *width, - EGLint *height) { - eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width); - eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height); -} - -void OpenGLES::DestroySurface(const EGLSurface surface) { - if (mEglDisplay != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) { - eglDestroySurface(mEglDisplay, surface); - } -} - -void OpenGLES::MakeCurrent(const EGLSurface surface) { - if (eglMakeCurrent(mEglDisplay, surface, surface, mEglContext) == EGL_FALSE) { - throw winrt::hresult_error(E_FAIL, L"Failed to make EGLSurface current"); - } -} - -EGLBoolean OpenGLES::SwapBuffers(const EGLSurface surface) { - return (eglSwapBuffers(mEglDisplay, surface)); -} diff --git a/support/hololens/ServoApp/ServoControl/OpenGLES.h b/support/hololens/ServoApp/ServoControl/OpenGLES.h index 96d96859194..ad952dd3439 100644 --- a/support/hololens/ServoApp/ServoControl/OpenGLES.h +++ b/support/hololens/ServoApp/ServoControl/OpenGLES.h @@ -9,15 +9,10 @@ public: OpenGLES(); ~OpenGLES(); - EGLSurface - CreateSurface(winrt::Windows::UI::Xaml::Controls::SwapChainPanel const &, - float dpi); + EGLNativeWindowType + GetNativeWindow(winrt::Windows::UI::Xaml::Controls::SwapChainPanel const &, + float dpi); - void GetSurfaceDimensions(const EGLSurface surface, EGLint *width, - EGLint *height); - void DestroySurface(const EGLSurface surface); - void MakeCurrent(const EGLSurface surface); - EGLBoolean SwapBuffers(const EGLSurface surface); void Reset(); private: diff --git a/support/hololens/ServoApp/ServoControl/Servo.cpp b/support/hololens/ServoApp/ServoControl/Servo.cpp index 5b59620bf05..6ee482fd9f9 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.cpp +++ b/support/hololens/ServoApp/ServoControl/Servo.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "Servo.h" +#include namespace winrt::servo { @@ -21,10 +22,6 @@ void on_url_changed(const char *url) { sServo->Delegate().OnServoURLChanged(char2hstring(url)); } -void flush() { sServo->Delegate().Flush(); } - -void make_current() { sServo->Delegate().MakeCurrent(); } - void wakeup() { sServo->Delegate().WakeUp(); } bool on_allow_navigation(const char *url) { @@ -107,7 +104,8 @@ const char *prompt_input(const char *message, const char *default, } Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, - float dpi, ServoDelegate &aDelegate) + EGLNativeWindowType eglNativeWindow, float dpi, + ServoDelegate &aDelegate) : mWindowHeight(height), mWindowWidth(width), mDelegate(aDelegate) { SetEnvironmentVariableA("PreviewRuntimeEnabled", "1"); @@ -119,6 +117,7 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, o.height = mWindowHeight; o.density = dpi; o.enable_subpixel_text_antialiasing = false; + o.native_widget = eglNativeWindow; // Note about logs: // By default: all modules are enabled. Only warn level-logs are displayed. @@ -142,8 +141,6 @@ Servo::Servo(hstring url, hstring args, GLsizei width, GLsizei height, sServo = this; // FIXME; capi::CHostCallbacks c; - c.flush = &flush; - c.make_current = &make_current; c.on_load_started = &on_load_started; c.on_load_ended = &on_load_ended; c.on_title_changed = &on_title_changed; diff --git a/support/hololens/ServoApp/ServoControl/Servo.h b/support/hololens/ServoApp/ServoControl/Servo.h index 7b3b3b00ed3..5b4b93bc811 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.h +++ b/support/hololens/ServoApp/ServoControl/Servo.h @@ -5,6 +5,7 @@ #pragma once #include "pch.h" +#include #include "logs.h" #include @@ -23,7 +24,8 @@ class ServoDelegate; class Servo { public: - Servo(hstring, hstring, GLsizei, GLsizei, float, ServoDelegate &); + Servo(hstring, hstring, GLsizei, GLsizei, EGLNativeWindowType, float, + ServoDelegate &); ~Servo(); ServoDelegate &Delegate() { return mDelegate; } @@ -100,8 +102,6 @@ public: virtual void OnServoAnimatingChanged(bool) = 0; virtual void OnServoIMEStateChanged(bool) = 0; virtual void OnServoDevtoolsStarted(bool, const unsigned int) = 0; - virtual void Flush() = 0; - virtual void MakeCurrent() = 0; virtual void OnServoMediaSessionMetadata(hstring, hstring, hstring) = 0; virtual void OnServoMediaSessionPlaybackStateChange(int) = 0; virtual void OnServoPromptAlert(hstring, bool) = 0; diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.cpp b/support/hololens/ServoApp/ServoControl/ServoControl.cpp index 4d1349ee370..9c5869d44e9 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.cpp +++ b/support/hololens/ServoApp/ServoControl/ServoControl.cpp @@ -72,7 +72,7 @@ void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) { InitializeCriticalSection(&mGLLock); InitializeConditionVariable(&mDialogCondVar); InitializeCriticalSection(&mDialogLock); - CreateRenderSurface(); + CreateNativeWindow(); StartRenderLoop(); } @@ -80,22 +80,26 @@ Controls::SwapChainPanel ServoControl::Panel() { return GetTemplateChild(L"swapChainPanel").as(); } -void ServoControl::CreateRenderSurface() { - if (mRenderSurface == EGL_NO_SURFACE) { - mRenderSurface = mOpenGLES.CreateSurface(Panel(), mDPI); - } +void ServoControl::CreateNativeWindow() { + mPanelWidth = Panel().ActualWidth() * mDPI; + mPanelHeight = Panel().ActualHeight() * mDPI; + mNativeWindowProperties.Insert(EGLNativeWindowTypeProperty, Panel()); + // How to set size and or scale: + // Insert(EGLRenderSurfaceSizeProperty), + // PropertyValue::CreateSize(*renderSurfaceSize)); + mNativeWindowProperties.Insert(EGLRenderResolutionScaleProperty, + PropertyValue::CreateSingle(mDPI)); } -void ServoControl::DestroyRenderSurface() { - mOpenGLES.DestroySurface(mRenderSurface); - mRenderSurface = EGL_NO_SURFACE; +EGLNativeWindowType ServoControl::GetNativeWindow() { + EGLNativeWindowType win = + static_cast(winrt::get_abi(mNativeWindowProperties)); + + return win; } void ServoControl::RecoverFromLostDevice() { StopRenderLoop(); - DestroyRenderSurface(); - mOpenGLES.Reset(); - CreateRenderSurface(); StartRenderLoop(); } @@ -311,18 +315,12 @@ void ServoControl::RunOnGLThread(std::function task) { void ServoControl::Loop() { log("BrowserPage::Loop(). GL thread: %i", GetCurrentThreadId()); - mOpenGLES.MakeCurrent(mRenderSurface); - - EGLint panelWidth = 0; - EGLint panelHeight = 0; - mOpenGLES.GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight); - glViewport(0, 0, panelWidth, panelHeight); - if (mServo == nullptr) { log("Entering loop"); ServoDelegate *sd = static_cast(this); - mServo = std::make_unique(mInitialURL, mArgs, panelWidth, - panelHeight, mDPI, *sd); + EGLNativeWindowType win = GetNativeWindow(); + mServo = std::make_unique(mInitialURL, mArgs, mPanelWidth, + mPanelHeight, win, mDPI, *sd); } else { // FIXME: this will fail since create_task didn't pick the thread // where Servo was running initially. @@ -406,17 +404,6 @@ void ServoControl::OnServoURLChanged(hstring url) { }); } -void ServoControl::Flush() { - if (mOpenGLES.SwapBuffers(mRenderSurface) != GL_TRUE) { - // The call to eglSwapBuffers might not be successful (i.e. due to Device - // Lost) If the call fails, then we must reinitialize EGL and the GL - // resources. - RunOnUIThread([=] { RecoverFromLostDevice(); }); - } -} - -void ServoControl::MakeCurrent() { mOpenGLES.MakeCurrent(mRenderSurface); } - void ServoControl::WakeUp() { RunOnGLThread([=] {}); } diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.h b/support/hololens/ServoApp/ServoControl/ServoControl.h index 6eaf4459f4b..dbc9e91ca92 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.h +++ b/support/hololens/ServoApp/ServoControl/ServoControl.h @@ -4,6 +4,8 @@ #include "Servo.h" #include "DefaultUrl.h" +using namespace winrt::Windows::Foundation::Collections; + namespace winrt::ServoApp::implementation { struct ServoControl : ServoControlT, public servo::ServoDelegate { @@ -108,8 +110,6 @@ struct ServoControl : ServoControlT, public servo::ServoDelegate { virtual void OnServoShutdownComplete(); virtual void OnServoTitleChanged(winrt::hstring); virtual void OnServoURLChanged(winrt::hstring); - virtual void Flush(); - virtual void MakeCurrent(); virtual bool OnServoAllowNavigation(winrt::hstring); virtual void OnServoAnimatingChanged(bool); virtual void OnServoIMEStateChanged(bool); @@ -150,14 +150,16 @@ private: std::optional secondaryButton, std::optional input); + int mPanelHeight = 0; + int mPanelWidth = 0; float mDPI = 1; hstring mInitialURL = DEFAULT_URL; hstring mCurrentUrl = L""; bool mTransient = false; Windows::UI::Xaml::Controls::SwapChainPanel ServoControl::Panel(); - void CreateRenderSurface(); - void DestroyRenderSurface(); + void CreateNativeWindow(); + EGLNativeWindowType GetNativeWindow(); void RecoverFromLostDevice(); void StartRenderLoop(); @@ -204,7 +206,7 @@ private: void TryLoadUri(hstring); std::unique_ptr mServo; - EGLSurface mRenderSurface{EGL_NO_SURFACE}; + PropertySet mNativeWindowProperties; OpenGLES mOpenGLES; bool mAnimating = false; bool mLooping = false; diff --git a/support/hololens/ServoApp/packages.config b/support/hololens/ServoApp/packages.config index fa1a5cf1668..149f1735c5d 100644 --- a/support/hololens/ServoApp/packages.config +++ b/support/hololens/ServoApp/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/tests/wpt/metadata/css/css-images/gradients-with-border.html.ini b/tests/wpt/metadata/css/css-images/gradients-with-border.html.ini new file mode 100644 index 00000000000..71cd86c3497 --- /dev/null +++ b/tests/wpt/metadata/css/css-images/gradients-with-border.html.ini @@ -0,0 +1,4 @@ +[gradients-with-border.html] + type: reftest + fuzzy: /css/css-images/gradients-with-border-ref.html:0-1;0-1 + expected: PASS diff --git a/tests/wpt/mozilla/meta-layout-2020/css/text_node_opacity.html.ini b/tests/wpt/mozilla/meta-layout-2020/css/text_node_opacity.html.ini deleted file mode 100644 index c3d01daa76d..00000000000 --- a/tests/wpt/mozilla/meta-layout-2020/css/text_node_opacity.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[text_node_opacity.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/css/text_node_opacity.html.ini b/tests/wpt/mozilla/meta/css/text_node_opacity.html.ini deleted file mode 100644 index c3d01daa76d..00000000000 --- a/tests/wpt/mozilla/meta/css/text_node_opacity.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[text_node_opacity.html] - expected: FAIL diff --git a/tests/wpt/webgl/meta/MANIFEST.json b/tests/wpt/webgl/meta/MANIFEST.json index 5270f6dee2c..44ac07f9206 100644 --- a/tests/wpt/webgl/meta/MANIFEST.json +++ b/tests/wpt/webgl/meta/MANIFEST.json @@ -10867,7 +10867,7 @@ ] ], "shader-varying-packing-restrictions.html": [ - "8a7fd1a4201883e63af071122cd5003120dfb23e", + "d289bbeabb9b2db31cb6ba50df97d63ccce7d5c6", [ null, {} diff --git a/tests/wpt/webgl/meta/conformance/attribs/gl-disabled-vertex-attrib.html.ini b/tests/wpt/webgl/meta/conformance/attribs/gl-disabled-vertex-attrib.html.ini new file mode 100644 index 00000000000..a00316b2dd1 --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/attribs/gl-disabled-vertex-attrib.html.ini @@ -0,0 +1,6 @@ +[gl-disabled-vertex-attrib.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #15: should be green\nat (0, 0) expected: 0,255,0,255 was 255,255,255,255] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html.ini b/tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html.ini new file mode 100644 index 00000000000..810fa6b02fe --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html.ini @@ -0,0 +1,4 @@ +[gl-vertex-attrib-unconsumed-out-of-bounds.html] + bug: https://github.com/servo/servo/issues/26004 + expected: + if os == "mac": CRASH diff --git a/tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-zero-issues.html.ini b/tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-zero-issues.html.ini new file mode 100644 index 00000000000..72b2f372cc4 --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/attribs/gl-vertex-attrib-zero-issues.html.ini @@ -0,0 +1,42 @@ +[gl-vertex-attrib-zero-issues.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #19: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #31: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #11: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #13: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #25: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #7: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #23: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #29: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #5: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #17: canvas should be green\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/extensions/angle-instanced-arrays-out-of-bounds.html.ini b/tests/wpt/webgl/meta/conformance/extensions/angle-instanced-arrays-out-of-bounds.html.ini index 16f534368c1..cf33ab0cfed 100644 --- a/tests/wpt/webgl/meta/conformance/extensions/angle-instanced-arrays-out-of-bounds.html.ini +++ b/tests/wpt/webgl/meta/conformance/extensions/angle-instanced-arrays-out-of-bounds.html.ini @@ -1,5 +1,8 @@ [angle-instanced-arrays-out-of-bounds.html] - bug: https://github.com/servo/servo/issues/20599 + bug: https://github.com/servo/servo/issues/20599 https://github.com/servo/servo/issues/25990 + expected: + if os == "mac": CRASH + [WebGL test #32: getError expected: INVALID_OPERATION. Was NO_ERROR : after evaluating: ext.drawElementsInstancedANGLE(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, 0, 1)] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance/glsl/misc/shader-varying-packing-restrictions.html.ini b/tests/wpt/webgl/meta/conformance/glsl/misc/shader-varying-packing-restrictions.html.ini index 34ac3c0182c..ef4cb2577f4 100644 --- a/tests/wpt/webgl/meta/conformance/glsl/misc/shader-varying-packing-restrictions.html.ini +++ b/tests/wpt/webgl/meta/conformance/glsl/misc/shader-varying-packing-restrictions.html.ini @@ -1,41 +1,72 @@ [shader-varying-packing-restrictions.html] - bug: https://github.com/servo/servo/issues/20601 - [WebGL test #2: [unexpected link status\] shaders with varying array of float with 33 elements (one past maximum) accessing last element should fail] + [WebGL test #9: [unexpected link status\] shaders with varying array of vec2 with one more than the maximum number of elements accessing first element should fail] expected: FAIL - [WebGL test #3: [unexpected link status\] shaders with varying array of float with 33 elements (one past maximum) accessing first element should fail] + [WebGL test #8: [unexpected link status\] shaders with varying array of vec2 with one more than the maximum number of elements accessing last element should fail] expected: FAIL - [WebGL test #8: [unexpected link status\] shaders with varying array of vec2 with 33 elements (one past maximum) accessing last element should fail] + [WebGL test #34: [unexpected link status\] shaders with one more than the maximum number of varyings of mat3 should fail] expected: FAIL - [WebGL test #9: [unexpected link status\] shaders with varying array of vec2 with 33 elements (one past maximum) accessing first element should fail] + [WebGL test #14: [unexpected link status\] shaders with varying array of vec3 with one more than the maximum number of elements accessing last element should fail] expected: FAIL - [WebGL test #14: [unexpected link status\] shaders with varying array of vec3 with 33 elements (one past maximum) accessing last element should fail] + [WebGL test #32: [unexpected link status\] shaders with varying array of mat3 with one more than the maximum number of elements accessing last element should fail] expected: FAIL - [WebGL test #15: [unexpected link status\] shaders with varying array of vec3 with 33 elements (one past maximum) accessing first element should fail] + [WebGL test #28: [unexpected link status\] shaders with one more than the maximum number of varyings of mat2 should fail] expected: FAIL - [WebGL test #16: [unexpected link status\] shaders with 33 varyings of vec3 (one past maximum) should fail] + [WebGL test #16: [unexpected link status\] shaders with one more than the maximum number of varyings of vec3 should fail] expected: FAIL - [WebGL test #26: [unexpected link status\] shaders with varying array of mat2 with 17 elements (one past maximum) accessing last element should fail] + [WebGL test #26: [unexpected link status\] shaders with varying array of mat2 with one more than the maximum number of elements accessing last element should fail] expected: FAIL - [WebGL test #27: [unexpected link status\] shaders with varying array of mat2 with 17 elements (one past maximum) accessing first element should fail] + [WebGL test #27: [unexpected link status\] shaders with varying array of mat2 with one more than the maximum number of elements accessing first element should fail] expected: FAIL - [WebGL test #28: [unexpected link status\] shaders with 17 varyings of mat2 (one past maximum) should fail] + [WebGL test #33: [unexpected link status\] shaders with varying array of mat3 with one more than the maximum number of elements accessing first element should fail] expected: FAIL - [WebGL test #32: [unexpected link status\] shaders with varying array of mat3 with 11 elements (one past maximum) accessing last element should fail] + [WebGL test #3: [unexpected link status\] shaders with varying array of float with one more than the maximum number of elements accessing first element should fail] expected: FAIL - [WebGL test #33: [unexpected link status\] shaders with varying array of mat3 with 11 elements (one past maximum) accessing first element should fail] + [WebGL test #2: [unexpected link status\] shaders with varying array of float with one more than the maximum number of elements accessing last element should fail] expected: FAIL - [WebGL test #34: [unexpected link status\] shaders with 11 varyings of mat3 (one past maximum) should fail] + [WebGL test #15: [unexpected link status\] shaders with varying array of vec3 with one more than the maximum number of elements accessing first element should fail] expected: FAIL + [WebGL test #10: [unexpected link status\] shaders with one more than the maximum number of varyings of vec2 should fail] + expected: + if os == "mac": FAIL + + [WebGL test #38: [unexpected link status\] shaders with varying array of mat4 with one more than the maximum number of elements accessing last element should fail] + expected: + if os == "mac": FAIL + + [WebGL test #21: [unexpected link status\] shaders with varying array of vec4 with one more than the maximum number of elements accessing first element should fail] + expected: + if os == "mac": FAIL + + [WebGL test #40: [unexpected link status\] shaders with one more than the maximum number of varyings of mat4 should fail] + expected: + if os == "mac": FAIL + + [WebGL test #22: [unexpected link status\] shaders with one more than the maximum number of varyings of vec4 should fail] + expected: + if os == "mac": FAIL + + [WebGL test #4: [unexpected link status\] shaders with one more than the maximum number of varyings of float should fail] + expected: + if os == "mac": FAIL + + [WebGL test #39: [unexpected link status\] shaders with varying array of mat4 with one more than the maximum number of elements accessing first element should fail] + expected: + if os == "mac": FAIL + + [WebGL test #20: [unexpected link status\] shaders with varying array of vec4 with one more than the maximum number of elements accessing last element should fail] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/glsl/misc/shaders-with-invariance.html.ini b/tests/wpt/webgl/meta/conformance/glsl/misc/shaders-with-invariance.html.ini index a5af6d1b7af..a72b2c87ae9 100644 --- a/tests/wpt/webgl/meta/conformance/glsl/misc/shaders-with-invariance.html.ini +++ b/tests/wpt/webgl/meta/conformance/glsl/misc/shaders-with-invariance.html.ini @@ -9,3 +9,15 @@ [WebGL test #12: [unexpected link status\] vertex shader with variant gl_PointSize and fragment shader with invariant gl_PointCoord must fail] expected: FAIL + [WebGL test #3: [unexpected link status\] vertex shader with invariant (global setting) varying and fragment shader with invariant varying must succeed] + expected: + if os == "mac": FAIL + + [WebGL test #2: [unexpected link status\] vertex shader with invariant (global setting) varying and fragment shader with variant varying must fail] + expected: + if os == "mac": FAIL + + [WebGL test #8: [unexpected link status\] vertex shader with invariant gl_Position and fragment shader with invariant gl_FragCoord must succeed] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-long-names-test.html.ini b/tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-long-names-test.html.ini new file mode 100644 index 00000000000..5a965f128de --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-long-names-test.html.ini @@ -0,0 +1,10 @@ +[gl-bind-attrib-location-long-names-test.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #4: should be green\nat (0, 0) expected: 0,255,0,255 was 255,255,255,255] + expected: + if os == "mac": FAIL + + [WebGL test #8: should be green\nat (0, 0) expected: 255,0,0,255 was 255,255,255,255] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-test.html.ini b/tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-test.html.ini new file mode 100644 index 00000000000..e923e309f48 --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/programs/gl-bind-attrib-location-test.html.ini @@ -0,0 +1,10 @@ +[gl-bind-attrib-location-test.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #13: Line 15 should be red for at least 10 rgba pixels starting 20 pixels in\nat (20, 15) expected: 255,0,0,255 was 0,0,0,255] + expected: + if os == "mac": FAIL + + [WebGL test #7: Line 15 should be red for at least 10 rgba pixels starting 20 pixels in\nat (20, 15) expected: 0,255,0,255 was 0,0,0,255] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/reading/read-pixels-test.html.ini b/tests/wpt/webgl/meta/conformance/reading/read-pixels-test.html.ini index 9e6d4b07dd5..4ccdc18f7f6 100644 --- a/tests/wpt/webgl/meta/conformance/reading/read-pixels-test.html.ini +++ b/tests/wpt/webgl/meta/conformance/reading/read-pixels-test.html.ini @@ -1,3 +1,62 @@ [read-pixels-test.html] bug: https://github.com/servo/servo/issues/12859 - expected: TIMEOUT + [WebGL test #49: getError expected: INVALID_OPERATION. Was INVALID_ENUM : Should not be able to read as ALPHA / UNSIGNED_BYTE] + expected: FAIL + + [WebGL test #45: getError expected: INVALID_OPERATION. Was INVALID_ENUM : Should not be able to read as RGB / UNSIGNED_BYTE] + expected: FAIL + + [WebGL test #47: getError expected: INVALID_OPERATION. Was INVALID_ENUM : Should not be able to read as RGBA / UNSIGNED_SHORT_5_5_5_1] + expected: FAIL + + [WebGL test #46: getError expected: INVALID_OPERATION. Was INVALID_ENUM : Should not be able to read as RGB / UNSIGNED_SHORT_5_6_5] + expected: FAIL + + [WebGL test #48: getError expected: INVALID_OPERATION. Was INVALID_ENUM : Should not be able to read as RGBA / UNSIGNED_SHORT_4_4_4_4] + expected: FAIL + + [WebGL test #37: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as 0x8d99] + expected: FAIL + + [WebGL test #33: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as LUMINANCE] + expected: FAIL + + [WebGL test #42: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as UNSIGNED_INT] + expected: FAIL + + [WebGL test #38: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as 0x84fa] + expected: FAIL + + [WebGL test #30: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as DEPTH_STENCIL] + expected: FAIL + + [WebGL test #43: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as 0x8368] + expected: FAIL + + [WebGL test #29: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as DEPTH_COMPONENT] + expected: FAIL + + [WebGL test #35: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as 0x1903] + expected: FAIL + + [WebGL test #41: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as BYTE] + expected: FAIL + + [WebGL test #31: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as 0x8229] + expected: FAIL + + [WebGL test #36: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as 0x8228] + expected: FAIL + + [WebGL test #32: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as RGBA4] + expected: FAIL + + [WebGL test #40: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as SHORT] + expected: FAIL + + [WebGL test #34: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as LUMINANCE_ALPHA] + expected: FAIL + + [WebGL test #39: getError expected: INVALID_ENUM. Was INVALID_OPERATION : Should not be able to read as UNSIGNED_SHORT] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance/renderbuffers/feedback-loop.html.ini b/tests/wpt/webgl/meta/conformance/renderbuffers/feedback-loop.html.ini index 8f49daa21c3..aa1102ac28a 100644 --- a/tests/wpt/webgl/meta/conformance/renderbuffers/feedback-loop.html.ini +++ b/tests/wpt/webgl/meta/conformance/renderbuffers/feedback-loop.html.ini @@ -3,3 +3,6 @@ [WebGL test #3: getError expected: INVALID_OPERATION. Was NO_ERROR : after draw with invalid feedback loop] expected: FAIL + [WebGL test #5: Should be blue.\nat (0, 0) expected: 0,0,255,255 was 0,255,0,255] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance/rendering/line-rendering-quality.html.ini b/tests/wpt/webgl/meta/conformance/rendering/line-rendering-quality.html.ini new file mode 100644 index 00000000000..17c4baf3aef --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/rendering/line-rendering-quality.html.ini @@ -0,0 +1,8 @@ +[line-rendering-quality.html] + bug: https://github.com/servo/servo/issues/25937 + [WebGL test #5: Found 0 lines, looking in the vertical direction, expected 2] + expected: FAIL + + [WebGL test #11: Found 0 lines, looking in the vertical direction, expected 2] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance/rendering/point-no-attributes.html.ini b/tests/wpt/webgl/meta/conformance/rendering/point-no-attributes.html.ini new file mode 100644 index 00000000000..e8de6c6eab6 --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/rendering/point-no-attributes.html.ini @@ -0,0 +1,6 @@ +[point-no-attributes.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #1: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 0,0,0,0] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/rendering/rendering-stencil-large-viewport.html.ini b/tests/wpt/webgl/meta/conformance/rendering/rendering-stencil-large-viewport.html.ini deleted file mode 100644 index 436684031a6..00000000000 --- a/tests/wpt/webgl/meta/conformance/rendering/rendering-stencil-large-viewport.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[rendering-stencil-large-viewport.html] - expected: TIMEOUT diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-2d-formats.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-2d-formats.html.ini new file mode 100644 index 00000000000..45916a4184d --- /dev/null +++ b/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-2d-formats.html.ini @@ -0,0 +1,18 @@ +[copy-tex-image-2d-formats.html] + bug: https://github.com/servo/servo/issues/25995 + [WebGL test #43: should be 64,64,64,255\nat (0, 0) expected: 64,64,64,255 was 0,0,0,255] + expected: + if os == "mac": FAIL + + [WebGL test #2: should be 0,0,0,127\nat (0, 0) expected: 0,0,0,127 was 0,0,0,0] + expected: + if os == "mac": FAIL + + [WebGL test #5: should be 64,64,64,255\nat (0, 0) expected: 64,64,64,255 was 0,0,0,255] + expected: + if os == "mac": FAIL + + [WebGL test #8: should be 64,64,64,127\nat (0, 0) expected: 64,64,64,127 was 0,0,0,0] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html.ini index bef676b52ff..b6b70abce5d 100644 --- a/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html.ini +++ b/tests/wpt/webgl/meta/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html.ini @@ -1,4 +1,6 @@ [copy-tex-image-and-sub-image-2d.html] + disabled: + if os == "mac": https://github.com/servo/servo/issues/26000 [WebGL test #315: 0, 1 should render 0,0,0,0 (+/-1)\nat (0, 1) expected: 0,0,0,0 was 136,136,136,136] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance/uniforms/out-of-bounds-uniform-array-access.html.ini b/tests/wpt/webgl/meta/conformance/uniforms/out-of-bounds-uniform-array-access.html.ini index eced269a4fe..b884c61ff2a 100644 --- a/tests/wpt/webgl/meta/conformance/uniforms/out-of-bounds-uniform-array-access.html.ini +++ b/tests/wpt/webgl/meta/conformance/uniforms/out-of-bounds-uniform-array-access.html.ini @@ -1,5 +1,7 @@ [out-of-bounds-uniform-array-access.html] - expected: TIMEOUT + expected: + if os == "linux": TIMEOUT [Overall test] - expected: NOTRUN + expected: + if os == "linux": NOTRUN diff --git a/tests/wpt/webgl/meta/conformance2/buffers/bound-buffer-size-change-test.html.ini b/tests/wpt/webgl/meta/conformance2/buffers/bound-buffer-size-change-test.html.ini new file mode 100644 index 00000000000..64dbd617a0a --- /dev/null +++ b/tests/wpt/webgl/meta/conformance2/buffers/bound-buffer-size-change-test.html.ini @@ -0,0 +1,100 @@ +[bound-buffer-size-change-test.html] + [WebGL test #38: gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #23: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #4: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #28: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0) should be 4. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #22: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0) should be 4. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #33: gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1) should be 12. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #16: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #7: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #35: gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #37: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 16. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #39: gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1) should be 12. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #21: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0) should be 8. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #40: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 16. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #15: gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #25: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_START, 0) should be 4. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #32: gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #14: gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #11: gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, 1) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #36: gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1) should be 12. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #3: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #5: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #6: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #24: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0) should be 8. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #34: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 16. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #26: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #2: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #20: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0) should be [object WebGLBuffer\]. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #27: gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, 0) should be 8. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #12: gl.getIndexedParameter(gl.UNIFORM_BUFFER_SIZE, 1) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #13: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 0. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #34: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 256. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #37: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 256. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + + [WebGL test #40: gl.getIndexedParameter(gl.UNIFORM_BUFFER_START, 1) should be 256. Threw exception TypeError: gl.getIndexedParameter is not a function] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html.ini b/tests/wpt/webgl/meta/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html.ini new file mode 100644 index 00000000000..546c48af92b --- /dev/null +++ b/tests/wpt/webgl/meta/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html.ini @@ -0,0 +1,6 @@ +[vector-dynamic-indexing-swizzled-lvalue.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #0: should be green\nat (0, 0) expected: 0,255,0,255 was 255,0,0,255] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/reading/read-pixels-pack-parameters.html.ini b/tests/wpt/webgl/meta/conformance2/reading/read-pixels-pack-parameters.html.ini new file mode 100644 index 00000000000..33f08b0632b --- /dev/null +++ b/tests/wpt/webgl/meta/conformance2/reading/read-pixels-pack-parameters.html.ini @@ -0,0 +1,58 @@ +[read-pixels-pack-parameters.html] + bug: https://github.com/servo/servo/issues/26004 + [WebGL test #243: last pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #257: first pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #246: first pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #245: last pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #256: last pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #254: skipped bytes changed at index 0: expected 1 got 249] + expected: + if os == "mac": FAIL + + [WebGL test #241: skipped bytes changed at index 0: expected 1 got 249] + expected: + if os == "mac": FAIL + + [WebGL test #260: last pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #244: first pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #247: last pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #242: first pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #255: first pixel of row 0: expected [249,102,0,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #259: first pixel of row 2: expected [134,87,234,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + + [WebGL test #258: last pixel of row 1: expected [2,200,102,255\], got [1,2,3,4\]] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini b/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini index fa43cf3d5d6..6ea855e6f72 100644 --- a/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini +++ b/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-object-attachment.html.ini @@ -1,4 +1,6 @@ [framebuffer-object-attachment.html] + expected: + if os == "mac": TIMEOUT [WebGL test #45: getError expected: NO_ERROR. Was INVALID_ENUM : ] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-test.html.ini b/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-test.html.ini index 9361819dbfb..3cb32539cf7 100644 --- a/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-test.html.ini +++ b/tests/wpt/webgl/meta/conformance2/renderbuffers/framebuffer-test.html.ini @@ -1,4 +1,8 @@ [framebuffer-test.html] + [WebGL test #37: gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE) should be 0. Was 8.] + expected: + if os == "mac": FAIL + [WebGL test #38: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read framebuffer with no attachment.] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/renderbuffers/invalidate-framebuffer.html.ini b/tests/wpt/webgl/meta/conformance2/renderbuffers/invalidate-framebuffer.html.ini index d57af99063c..d31804f6f0f 100644 --- a/tests/wpt/webgl/meta/conformance2/renderbuffers/invalidate-framebuffer.html.ini +++ b/tests/wpt/webgl/meta/conformance2/renderbuffers/invalidate-framebuffer.html.ini @@ -1,5 +1,8 @@ [invalidate-framebuffer.html] - expected: ERROR + bug: https://github.com/servo/servo/issues/20529 + expected: + if os == "linux": ERROR + if os == "mac": TIMEOUT [WebGL test #17: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-filter-outofbounds.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-filter-outofbounds.html.ini index 1781da338a6..47772230fdf 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-filter-outofbounds.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-filter-outofbounds.html.ini @@ -1,25 +1,25 @@ [blitframebuffer-filter-outofbounds.html] - [WebGL test #1: framebuffer not complete] - expected: FAIL - - [WebGL test #2: framebuffer not complete] - expected: FAIL - - [WebGL test #3: framebuffer not complete] - expected: FAIL - [WebGL test #4: framebuffer not complete] expected: FAIL - [WebGL test #5: framebuffer not complete] - expected: FAIL - - [WebGL test #6: framebuffer not complete] - expected: FAIL - - [WebGL test #7: framebuffer not complete] - expected: FAIL - [WebGL test #8: framebuffer not complete] expected: FAIL + [WebGL test #1: framebuffer not complete] + expected: FAIL + + [WebGL test #6: framebuffer not complete] + expected: FAIL + + [WebGL test #3: framebuffer not complete] + expected: FAIL + + [WebGL test #2: framebuffer not complete] + expected: FAIL + + [WebGL test #7: framebuffer not complete] + expected: FAIL + + [WebGL test #5: framebuffer not complete] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html.ini index dfe456b6f2f..e953831a6f1 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html.ini @@ -1,7 +1,20 @@ [blitframebuffer-multisampled-readbuffer.html] - [WebGL test #2: Framebuffer incomplete.] - expected: FAIL + expected: + if os =="mac": ERROR [WebGL test #1: Framebuffer incomplete.] - expected: FAIL + expected: + if os == "linux": FAIL + + [WebGL test #2: Framebuffer incomplete.] + expected: + if os == "linux": FAIL + + [WebGL test #1: getError expected: NO_ERROR. Was INVALID_ENUM : setup draw framebuffer should succeed] + expected: + if os == "mac": FAIL + + [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] + expected: + if os == "mac": FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-outside-readbuffer.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-outside-readbuffer.html.ini index 636fe9d6c08..72e978948ab 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-outside-readbuffer.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-outside-readbuffer.html.ini @@ -1,13 +1,13 @@ [blitframebuffer-outside-readbuffer.html] - [WebGL test #1: framebuffer not complete] + [WebGL test #4: framebuffer not complete] expected: FAIL - [WebGL test #2: framebuffer not complete] + [WebGL test #1: framebuffer not complete] expected: FAIL [WebGL test #3: framebuffer not complete] expected: FAIL - [WebGL test #4: framebuffer not complete] + [WebGL test #2: framebuffer not complete] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-scissor-enabled.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-scissor-enabled.html.ini index 0c050bac07d..9cb0e56b3d5 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-scissor-enabled.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/blitframebuffer-scissor-enabled.html.ini @@ -1,17 +1,17 @@ [blitframebuffer-scissor-enabled.html] - [WebGL test #1: Framebuffer incomplete.] - expected: FAIL - [WebGL test #2: Framebuffer incomplete.] expected: FAIL [WebGL test #3: Framebuffer incomplete.] expected: FAIL - [WebGL test #4: Framebuffer incomplete.] + [WebGL test #8: Framebuffer incomplete.] expected: FAIL - [WebGL test #5: Framebuffer incomplete.] + [WebGL test #1: Framebuffer incomplete.] + expected: FAIL + + [WebGL test #4: Framebuffer incomplete.] expected: FAIL [WebGL test #6: Framebuffer incomplete.] @@ -20,6 +20,6 @@ [WebGL test #7: Framebuffer incomplete.] expected: FAIL - [WebGL test #8: Framebuffer incomplete.] + [WebGL test #5: Framebuffer incomplete.] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/clear-func-buffer-type-match.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/clear-func-buffer-type-match.html.ini index eae2c252214..2e26fd64d03 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/clear-func-buffer-type-match.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/clear-func-buffer-type-match.html.ini @@ -1,5 +1,31 @@ [clear-func-buffer-type-match.html] - expected: TIMEOUT - [WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] + [WebGL test #18: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferiv and RGBA8 buffer] + expected: FAIL + + [WebGL test #7: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferuiv and float buffer] + expected: FAIL + + [WebGL test #10: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferfv and UINT buffer] + expected: FAIL + + [WebGL test #14: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferiv and float buffer] + expected: FAIL + + [WebGL test #11: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferiv and UINT buffer] + expected: FAIL + + [WebGL test #4: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferuiv and INT buffer] + expected: FAIL + + [WebGL test #3: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferfv and INT buffer] + expected: FAIL + + [WebGL test #2: getError expected: INVALID_OPERATION. Was NO_ERROR : clear and INT buffer] + expected: FAIL + + [WebGL test #9: getError expected: INVALID_OPERATION. Was NO_ERROR : clear and UINT buffer] + expected: FAIL + + [WebGL test #19: getError expected: INVALID_OPERATION. Was NO_ERROR : clearBufferuiv and RGBA8 buffer] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-unsupported.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-unsupported.html.ini index ca468321826..43c9e6393e4 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-unsupported.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/framebuffer-unsupported.html.ini @@ -1,11 +1,11 @@ [framebuffer-unsupported.html] expected: ERROR - [WebGL test #4: checkFramebufferStatus expects [FRAMEBUFFER_UNSUPPORTED\], was FRAMEBUFFER_COMPLETE] - expected: FAIL - [WebGL test #7: checkFramebufferStatus expects [FRAMEBUFFER_UNSUPPORTED\], was FRAMEBUFFER_COMPLETE] expected: FAIL [WebGL test #8: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL + [WebGL test #4: checkFramebufferStatus expects [FRAMEBUFFER_UNSUPPORTED\], was FRAMEBUFFER_COMPLETE] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html.ini index a63bce3601f..2ccc49a0d01 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html.ini @@ -1,5 +1,28 @@ [fs-color-type-mismatch-color-buffer-type.html] - expected: TIMEOUT - [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] + [WebGL test #2: Framebuffer incomplete.] + expected: FAIL + + [WebGL test #3: Framebuffer incomplete.] + expected: FAIL + + [WebGL test #8: getError expected: NO_ERROR. Was INVALID_ENUM : If color buffers' type mismatch the type of fragment shader's outputs, geneate INVALID_OPERATION. Otherwise, it should be NO_ERROR] + expected: FAIL + + [WebGL test #4: Framebuffer incomplete.] + expected: FAIL + + [WebGL test #11: getError expected: INVALID_OPERATION. Was NO_ERROR : If color buffers' type mismatch the type of fragment shader's outputs, geneate INVALID_OPERATION. Otherwise, it should be NO_ERROR] + expected: FAIL + + [WebGL test #6: Framebuffer incomplete.] + expected: FAIL + + [WebGL test #7: Framebuffer incomplete.] + expected: FAIL + + [WebGL test #13: getError expected: INVALID_OPERATION. Was NO_ERROR : If color buffers' type mismatch the type of fragment shader's outputs, geneate INVALID_OPERATION. Otherwise, it should be NO_ERROR] + expected: FAIL + + [WebGL test #5: Framebuffer incomplete.] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/line-rendering-quality.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/line-rendering-quality.html.ini index 0e6f6c09150..012d35afad3 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/line-rendering-quality.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/line-rendering-quality.html.ini @@ -1,5 +1,9 @@ [line-rendering-quality.html] expected: ERROR + bug: https://github.com/servo/servo/issues/25937 + [WebGL test #5: Found 0 lines, looking in the vertical direction, expected 2] + expected: + if os == "linux": FAIL [WebGL test #10: successfullyParsed should be true. Threw exception ReferenceError: can't access lexical declaration `successfullyParsed' before initialization] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/rgb-format-support.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/rgb-format-support.html.ini index 37f90550f16..787a9347164 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/rgb-format-support.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/rgb-format-support.html.ini @@ -1,10 +1,25 @@ [rgb-format-support.html] - [WebGL test #15: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : should be no errors from clear()] - expected: FAIL + [WebGL test #24: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : should be no errors from clear()] + expected: + if os == "linux": FAIL - [WebGL test #14: framebuffer with texture is incomplete] - expected: FAIL + [WebGL test #23: framebuffer with texture is incomplete] + expected: + if os == "linux": FAIL - [WebGL test #13: getError expected: NO_ERROR. Was INVALID_ENUM : should be no errors from texture setup] - expected: FAIL + [WebGL test #22: getError expected: NO_ERROR. Was INVALID_ENUM : should be no errors from texture setup] + expected: + if os == "linux": FAIL + + [WebGL test #18: getError expected: NO_ERROR. Was INVALID_FRAMEBUFFER_OPERATION : should be no errors from clear()] + expected: + if os == "mac": FAIL + + [WebGL test #17: framebuffer with texture is incomplete] + expected: + if os == "mac": FAIL + + [WebGL test #16: getError expected: NO_ERROR. Was INVALID_ENUM : should be no errors from texture setup] + expected: + if os == "mac": FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini new file mode 100644 index 00000000000..145e06de388 --- /dev/null +++ b/tests/wpt/webgl/meta/conformance2/rendering/uniform-block-buffer-size.html.ini @@ -0,0 +1,4 @@ +[uniform-block-buffer-size.html] + bug: https://github.com/servo/servo/issues/25990 + expected: + if os == "mac": CRASH diff --git a/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini b/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini index 53227633539..c8728fc9e57 100644 --- a/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini +++ b/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini @@ -1,4 +1,8 @@ [gl-object-get-calls.html] + bug: https://github.com/servo/servo/issues/26128 + expected: + if os == "mac": TIMEOUT + [WebGL test #201: gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_WRAP_R) should be 33071 (of type number). Was null (of type object).] expected: FAIL @@ -104,3 +108,5 @@ [WebGL test #183: getRenderbufferParameter did not generate INVALID_ENUM for invalid parameter enum: NO_ERROR] expected: FAIL + [WebGL test #183: getRenderbufferParameter did not generate INVALID_ENUM for invalid parameter enum: NO_ERROR] + expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/transform_feedback/too-small-buffers.html.ini b/tests/wpt/webgl/meta/conformance2/transform_feedback/too-small-buffers.html.ini index 98de660ccba..8c268d27e75 100644 --- a/tests/wpt/webgl/meta/conformance2/transform_feedback/too-small-buffers.html.ini +++ b/tests/wpt/webgl/meta/conformance2/transform_feedback/too-small-buffers.html.ini @@ -1,2 +1,360 @@ [too-small-buffers.html] - expected: TIMEOUT + expected: + if os == "linux": TIMEOUT + + [WebGL test #60: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #87: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #121: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #11: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #71: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #47: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #9: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #110: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #84: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #107: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #117: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #54: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #29: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #19: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #83: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #37: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #78: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #130: getError expected: INVALID_OPERATION. Was NO_ERROR : integer overflow and/or buffer too small] + expected: + if os == "mac": FAIL + + [WebGL test #66: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #12: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #7: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #34: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #77: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #74: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #31: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #15: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #120: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #49: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #56: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #73: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #33: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #97: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #116: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #91: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #90: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #95: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #119: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #65: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #23: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #35: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #68: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #16: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #57: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #61: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #38: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #21: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #129: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #89: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #32: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #115: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #14: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #25: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #113: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #102: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #5: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #42: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #108: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #18: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #36: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #99: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #100: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #55: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #67: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #80: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #53: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #105: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #79: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #63: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #24: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #125: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #76: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #96: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #98: buffer should match expected values] + expected: + if os == "mac": FAIL + + [WebGL test #122: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #93: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #109: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #75: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #6: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #58: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #118: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #13: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #26: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #41: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #126: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #51: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #48: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #3: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + + [WebGL test #103: getError expected: INVALID_OPERATION. Was NO_ERROR : draw] + expected: + if os == "mac": FAIL + + [WebGL test #45: getError expected: NO_ERROR. Was INVALID_OPERATION : before draw] + expected: + if os == "mac": FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini b/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini deleted file mode 100644 index 7dc585a49f0..00000000000 --- a/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[unwritten-output-defaults-to-zero.html] - [WebGL test #4: buffer should match expected values] - expected: FAIL - diff --git a/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html b/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html index 8a7fd1a4201..d289bbeabb9 100644 --- a/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html +++ b/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html @@ -135,7 +135,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: minVars, fcode: fcode}, info), fShaderSuccess: true, linkSuccess: true, - passMsg: "shaders with varying array of " + info.type + " with " + minVars + " elements (the minimum required) should succeed", + // Try to use deterministic test names + passMsg: "shaders with varying array of " + info.type + " with the minimum number of elements should succeed", }); // Test array[max + 1] accessing last element. WebGL requires this to fail. @@ -147,7 +148,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: numVars + 1, fcode: fcode}, info), fShaderSuccess: false, linkSuccess: false, - passMsg: "shaders with varying array of " + info.type + " with " + (numVars + 1) + " elements (one past maximum) accessing last element should fail", + // Try to use deterministic test names + passMsg: "shaders with varying array of " + info.type + " with one more than the maximum number of elements accessing last element should fail", }); // Test array[max + 1] accessing first element. WebGL requires this to fail but ES allows truncating array. @@ -159,7 +161,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: numVars + 1, fcode: fcode}, info), fShaderSuccess: false, linkSuccess: false, - passMsg: "shaders with varying array of " + info.type + " with " + (numVars + 1) + " elements (one past maximum) accessing first element should fail", + // Try to use deterministic test names + passMsg: "shaders with varying array of " + info.type + " with one more than the maximum number of elements accessing first element should fail", }); // Note: We can't test max varyings as actual GL drivers are only required to be able to @@ -189,7 +192,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { fShaderSource: wtu.replaceParams(fVaryingTestSource, generateCode(numMax + 1), info), fShaderSuccess: false, linkSuccess: false, - passMsg: "shaders with " + (numMax + 1) + " varyings of " + info.type + " (one past maximum) should fail", + // Try to use deterministic test names + passMsg: "shaders with one more than the maximum number of varyings of " + info.type + " should fail", }); // Test required varyings of type. @@ -199,7 +203,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { fShaderSource: wtu.replaceParams(fVaryingTestSource, generateCode(minVars), info), fShaderSuccess: true, linkSuccess: true, - passMsg: "shaders with " + minVars + " varyings of " + info.type + " (the minimum required) should succeed", + // Try to use deterministic test names + passMsg: "shaders with the minimum number of varyings of " + info.type + " should succeed", }); } diff --git a/tests/wpt/webgl/tools/import-conformance-tests.py b/tests/wpt/webgl/tools/import-conformance-tests.py index 9440abab4d0..0f6b203dcc3 100755 --- a/tests/wpt/webgl/tools/import-conformance-tests.py +++ b/tests/wpt/webgl/tools/import-conformance-tests.py @@ -16,6 +16,7 @@ PATCHES = [ ("timeout.patch", None), ("set-zero-timeout.patch", "js/webgl-test-utils.js"), ("compressed-images.patch", "conformance/extensions/webgl-compressed-texture-s3tc.html"), + ("shader-varying-packing-restrictions.patch", "conformance/glsl/misc/shader-varying-packing-restrictions.html"), ] # Fix for 'UnicodeDecodeError: 'ascii' codec can't decode byte' diff --git a/tests/wpt/webgl/tools/shader-varying-packing-restrictions.patch b/tests/wpt/webgl/tools/shader-varying-packing-restrictions.patch new file mode 100644 index 00000000000..d29e823bb58 --- /dev/null +++ b/tests/wpt/webgl/tools/shader-varying-packing-restrictions.patch @@ -0,0 +1,54 @@ +diff --git a/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html b/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html +index 8a7fd1a420..d289bbeabb 100644 +--- a/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html ++++ b/tests/wpt/webgl/tests/conformance/glsl/misc/shader-varying-packing-restrictions.html +@@ -135,7 +135,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { + fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: minVars, fcode: fcode}, info), + fShaderSuccess: true, + linkSuccess: true, +- passMsg: "shaders with varying array of " + info.type + " with " + minVars + " elements (the minimum required) should succeed", ++ // Try to use deterministic test names ++ passMsg: "shaders with varying array of " + info.type + " with the minimum number of elements should succeed", + }); + + // Test array[max + 1] accessing last element. WebGL requires this to fail. +@@ -147,7 +148,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { + fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: numVars + 1, fcode: fcode}, info), + fShaderSuccess: false, + linkSuccess: false, +- passMsg: "shaders with varying array of " + info.type + " with " + (numVars + 1) + " elements (one past maximum) accessing last element should fail", ++ // Try to use deterministic test names ++ passMsg: "shaders with varying array of " + info.type + " with one more than the maximum number of elements accessing last element should fail", + }); + + // Test array[max + 1] accessing first element. WebGL requires this to fail but ES allows truncating array. +@@ -159,7 +161,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { + fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: numVars + 1, fcode: fcode}, info), + fShaderSuccess: false, + linkSuccess: false, +- passMsg: "shaders with varying array of " + info.type + " with " + (numVars + 1) + " elements (one past maximum) accessing first element should fail", ++ // Try to use deterministic test names ++ passMsg: "shaders with varying array of " + info.type + " with one more than the maximum number of elements accessing first element should fail", + }); + + // Note: We can't test max varyings as actual GL drivers are only required to be able to +@@ -189,7 +192,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { + fShaderSource: wtu.replaceParams(fVaryingTestSource, generateCode(numMax + 1), info), + fShaderSuccess: false, + linkSuccess: false, +- passMsg: "shaders with " + (numMax + 1) + " varyings of " + info.type + " (one past maximum) should fail", ++ // Try to use deterministic test names ++ passMsg: "shaders with one more than the maximum number of varyings of " + info.type + " should fail", + }); + + // Test required varyings of type. +@@ -199,7 +203,8 @@ for (var ii = 0; ii < varyingTypes.length; ++ii) { + fShaderSource: wtu.replaceParams(fVaryingTestSource, generateCode(minVars), info), + fShaderSuccess: true, + linkSuccess: true, +- passMsg: "shaders with " + minVars + " varyings of " + info.type + " (the minimum required) should succeed", ++ // Try to use deterministic test names ++ passMsg: "shaders with the minimum number of varyings of " + info.type + " should succeed", + }); + } +