From 78af0cd556df427621a35a2137471d808e5989c0 Mon Sep 17 00:00:00 2001 From: Sotaro Ikeda Date: Mon, 27 Mar 2017 15:05:20 +0900 Subject: [PATCH] Allow to not depend on offscreen_gl_context --- .travis.yml | 1 + webrender/Cargo.toml | 5 +- webrender/src/internal_types.rs | 131 ++------------------------------ webrender/src/lib.rs | 8 ++ webrender/src/render_backend.rs | 7 +- webrender/src/renderer.rs | 3 +- webrender/src/webgl_stubs.rs | 59 ++++++++++++++ webrender/src/webgl_types.rs | 130 +++++++++++++++++++++++++++++++ webrender_traits/Cargo.toml | 3 +- webrender_traits/src/api.rs | 23 +++++- webrender_traits/src/lib.rs | 3 + 11 files changed, 241 insertions(+), 132 deletions(-) create mode 100644 webrender/src/webgl_stubs.rs create mode 100644 webrender/src/webgl_types.rs diff --git a/.travis.yml b/.travis.yml index 35e89ed6c5..3c7b3e09de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,7 @@ script: - servo-tidy - if [ $BUILD_KIND = DEBUG ]; then (cd webrender_traits && cargo test --verbose --features "ipc"); fi - if [ $BUILD_KIND = DEBUG ]; then (cd webrender_traits && cargo test --verbose); fi + - if [ $BUILD_KIND = DEBUG ]; then (cd webrender && cargo build --verbose --no-default-features); fi - if [ $BUILD_KIND = DEBUG ]; then (cd webrender && cargo test --verbose); fi - if [ $BUILD_KIND = DEBUG ]; then (cd sample && cargo test --verbose); fi - if [ $BUILD_KIND = DEBUG ]; then (cd sample && cargo build --verbose --features=profiler); fi diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml index fe238beee5..86a5778cd4 100644 --- a/webrender/Cargo.toml +++ b/webrender/Cargo.toml @@ -7,9 +7,10 @@ repository = "https://github.com/servo/webrender" build = "build.rs" [features] -default = ["freetype-lib"] +default = ["freetype-lib", "webgl"] freetype-lib = ["freetype/servo-freetype-sys"] profiler = ["thread_profiler/thread_profiler"] +webgl = ["offscreen_gl_context", "webrender_traits/webgl"] [dependencies] app_units = "0.4" @@ -22,7 +23,7 @@ gleam = "0.4.1" lazy_static = "0.2" log = "0.3" num-traits = "0.1.32" -offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"]} +offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"], optional = true} time = "0.1" threadpool = "1.3.2" webrender_traits = {path = "../webrender_traits"} diff --git a/webrender/src/internal_types.rs b/webrender/src/internal_types.rs index 933d052561..0ab245c9e4 100644 --- a/webrender/src/internal_types.rs +++ b/webrender/src/internal_types.rs @@ -6,11 +6,6 @@ use app_units::Au; use device::TextureFilter; use euclid::{TypedPoint2D, UnknownUnit}; use fnv::FnvHasher; -use gleam::gl; -use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle}; -use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher}; -use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle}; -use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits}; use profiler::BackendProfileCounters; use std::collections::{HashMap, HashSet}; use std::f32; @@ -20,9 +15,9 @@ use std::path::PathBuf; use std::sync::Arc; use tiling; use renderer::BlendMode; -use webrender_traits::{Epoch, ColorF, PipelineId, DeviceIntSize}; +use webrender_traits::{Epoch, ColorF, PipelineId}; use webrender_traits::{ImageFormat, NativeFontHandle}; -use webrender_traits::{ExternalImageId, ScrollLayerId, WebGLCommand}; +use webrender_traits::{ExternalImageId, ScrollLayerId}; use webrender_traits::{ImageData}; use webrender_traits::{DeviceUintRect}; @@ -48,125 +43,11 @@ pub struct CacheTextureId(pub usize); pub enum SourceTexture { Invalid, TextureCache(CacheTextureId), - WebGL(u32), // Is actually a gl::GLuint External(ExternalImageId), -} - -pub enum GLContextHandleWrapper { - Native(NativeGLContextHandle), - OSMesa(OSMesaContextHandle), -} - -impl GLContextHandleWrapper { - pub fn current_native_handle() -> Option { - NativeGLContext::current_handle().map(GLContextHandleWrapper::Native) - } - - pub fn current_osmesa_handle() -> Option { - OSMesaContext::current_handle().map(GLContextHandleWrapper::OSMesa) - } - - pub fn new_context(&self, - size: DeviceIntSize, - attributes: GLContextAttributes, - dispatcher: Option>) -> Result { - match *self { - GLContextHandleWrapper::Native(ref handle) => { - let ctx = GLContext::::new_shared_with_dispatcher(size.to_untyped(), - attributes, - ColorAttachmentType::Texture, - gl::GlType::default(), - Some(handle), - dispatcher); - ctx.map(GLContextWrapper::Native) - } - GLContextHandleWrapper::OSMesa(ref handle) => { - let ctx = GLContext::::new_shared_with_dispatcher(size.to_untyped(), - attributes, - ColorAttachmentType::Texture, - gl::GlType::default(), - Some(handle), - dispatcher); - ctx.map(GLContextWrapper::OSMesa) - } - } - } -} - -pub enum GLContextWrapper { - Native(GLContext), - OSMesa(GLContext), -} - -impl GLContextWrapper { - pub fn make_current(&self) { - match *self { - GLContextWrapper::Native(ref ctx) => { - ctx.make_current().unwrap(); - } - GLContextWrapper::OSMesa(ref ctx) => { - ctx.make_current().unwrap(); - } - } - } - - pub fn unbind(&self) { - match *self { - GLContextWrapper::Native(ref ctx) => { - ctx.unbind().unwrap(); - } - GLContextWrapper::OSMesa(ref ctx) => { - ctx.unbind().unwrap(); - } - } - } - - pub fn apply_command(&self, cmd: WebGLCommand) { - match *self { - GLContextWrapper::Native(ref ctx) => { - cmd.apply(ctx); - } - GLContextWrapper::OSMesa(ref ctx) => { - cmd.apply(ctx); - } - } - } - - pub fn get_info(&self) -> (DeviceIntSize, u32, GLLimits) { - match *self { - GLContextWrapper::Native(ref ctx) => { - let (real_size, texture_id) = { - let draw_buffer = ctx.borrow_draw_buffer().unwrap(); - (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap()) - }; - - let limits = ctx.borrow_limits().clone(); - - (DeviceIntSize::from_untyped(&real_size), texture_id, limits) - } - GLContextWrapper::OSMesa(ref ctx) => { - let (real_size, texture_id) = { - let draw_buffer = ctx.borrow_draw_buffer().unwrap(); - (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap()) - }; - - let limits = ctx.borrow_limits().clone(); - - (DeviceIntSize::from_untyped(&real_size), texture_id, limits) - } - } - } - - pub fn resize(&mut self, size: &DeviceIntSize) -> Result<(), &'static str> { - match *self { - GLContextWrapper::Native(ref mut ctx) => { - ctx.resize(size.to_untyped()) - } - GLContextWrapper::OSMesa(ref mut ctx) => { - ctx.resize(size.to_untyped()) - } - } - } + #[cfg_attr(not(feature = "webgl"), allow(dead_code))] + /// This is actually a gl::GLuint, with the shared texture id between the + /// main context and the WebGL context. + WebGL(u32), } const COLOR_FLOAT_TO_FIXED: f32 = 255.0; diff --git a/webrender/src/lib.rs b/webrender/src/lib.rs index 75f9cb5023..0e8067469d 100644 --- a/webrender/src/lib.rs +++ b/webrender/src/lib.rs @@ -77,6 +77,13 @@ mod texture_cache; mod tiling; mod util; +#[cfg(feature = "webgl")] +mod webgl_types; + +#[cfg(not(feature = "webgl"))] +#[path = "webgl_stubs.rs"] +mod webgl_types; + mod shader_source { include!(concat!(env!("OUT_DIR"), "/shaders.rs")); } @@ -127,6 +134,7 @@ extern crate num_traits; //extern crate notify; extern crate time; extern crate webrender_traits; +#[cfg(feature = "webgl")] extern crate offscreen_gl_context; extern crate byteorder; extern crate threadpool; diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index a2e89fb1cf..238399244f 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -5,8 +5,7 @@ use byteorder::{LittleEndian, ReadBytesExt}; use frame::Frame; use frame_builder::FrameBuilderConfig; -use internal_types::{FontTemplate, GLContextHandleWrapper, GLContextWrapper}; -use internal_types::{SourceTexture, ResultMsg, RendererFrame}; +use internal_types::{FontTemplate, SourceTexture, ResultMsg, RendererFrame}; use profiler::{BackendProfileCounters, TextureCacheProfileCounters}; use record::ApiRecordingReceiver; use resource_cache::ResourceCache; @@ -18,12 +17,16 @@ use std::sync::mpsc::Sender; use texture_cache::TextureCache; use thread_profiler::register_thread_with_profiler; use threadpool::ThreadPool; +use webgl_types::{GLContextHandleWrapper, GLContextWrapper}; use webrender_traits::{DeviceIntPoint, DeviceUintPoint, DeviceUintRect, DeviceUintSize, LayerPoint}; use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace, ImageData}; use webrender_traits::{PipelineId, RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId}; use webrender_traits::channel::{PayloadHelperMethods, PayloadReceiver, PayloadSender, MsgReceiver}; use webrender_traits::{BlobImageRenderer, VRCompositorCommand, VRCompositorHandler}; +#[cfg(feature = "webgl")] use offscreen_gl_context::GLContextDispatcher; +#[cfg(not(feature = "webgl"))] +use webgl_types::GLContextDispatcher; /// The render backend is responsible for transforming high level display lists into /// GPU-friendly work which is then submitted to the renderer in the form of a frame::Frame. diff --git a/webrender/src/renderer.rs b/webrender/src/renderer.rs index 50903ee167..a54a455796 100644 --- a/webrender/src/renderer.rs +++ b/webrender/src/renderer.rs @@ -21,7 +21,7 @@ use gpu_store::{GpuStore, GpuStoreLayout}; use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp}; use internal_types::{ExternalImageUpdateList, TextureUpdateList, PackedVertex, RenderTargetMode}; use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, SourceTexture}; -use internal_types::{BatchTextures, TextureSampler, GLContextHandleWrapper}; +use internal_types::{BatchTextures, TextureSampler}; use prim_store::GradientData; use profiler::{Profiler, BackendProfileCounters}; use profiler::{GpuProfileTag, RendererProfileTimers, RendererProfileCounters}; @@ -47,6 +47,7 @@ use tiling::{AlphaRenderTarget, CacheClipInstance, PrimitiveInstance, ColorRende use time::precise_time_ns; use thread_profiler::{register_thread_with_profiler, write_profile}; use util::TransformedRectKind; +use webgl_types::GLContextHandleWrapper; use webrender_traits::{ColorF, Epoch, PipelineId, RenderNotifier, RenderDispatcher}; use webrender_traits::{ExternalImageId, ImageData, ImageFormat, RenderApiSender}; use webrender_traits::{DeviceIntRect, DevicePoint, DeviceIntPoint, DeviceIntSize, DeviceUintSize}; diff --git a/webrender/src/webgl_stubs.rs b/webrender/src/webgl_stubs.rs new file mode 100644 index 0000000000..0283cd0ece --- /dev/null +++ b/webrender/src/webgl_stubs.rs @@ -0,0 +1,59 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Stubs for the types contained in webgl_types.rs +//! +//! The API surface provided here should be roughly the same to the one provided +//! in webgl_types, modulo completely compiled-out stuff. + +use webrender_traits::DeviceIntSize; +use webrender_traits::{GLContextAttributes, GLLimits}; +use webrender_traits::WebGLCommand; + +pub struct GLContextHandleWrapper; + +impl GLContextHandleWrapper { + pub fn new_context(&self, + _: DeviceIntSize, + _: GLContextAttributes, + _: Option>) -> Result { + unreachable!() + } + + pub fn current_native_handle() -> Option { + None + } + + pub fn current_osmesa_handle() -> Option { + None + } +} + +pub struct GLContextWrapper; + +impl GLContextWrapper { + pub fn make_current(&self) { + unreachable!() + } + + pub fn unbind(&self) { + unreachable!() + } + + pub fn apply_command(&self, _: WebGLCommand) { + unreachable!() + } + + pub fn get_info(&self) -> (DeviceIntSize, u32, GLLimits) { + unreachable!() + } + + pub fn resize(&mut self, _: &DeviceIntSize) -> Result<(), &'static str> { + unreachable!() + } +} + +pub trait GLContextDispatcher { + fn dispatch(&self, Box); +} diff --git a/webrender/src/webgl_types.rs b/webrender/src/webgl_types.rs new file mode 100644 index 0000000000..24fbf7a688 --- /dev/null +++ b/webrender/src/webgl_types.rs @@ -0,0 +1,130 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! A set of WebGL-related types, in their own module so it's easy to +//! compile it off. + +use gleam::gl; +use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle}; +use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher}; +use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle}; +use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits}; +use webrender_traits::{WebGLCommand, DeviceIntSize}; + +pub enum GLContextHandleWrapper { + Native(NativeGLContextHandle), + OSMesa(OSMesaContextHandle), +} + +impl GLContextHandleWrapper { + pub fn current_native_handle() -> Option { + NativeGLContext::current_handle().map(GLContextHandleWrapper::Native) + } + + pub fn current_osmesa_handle() -> Option { + OSMesaContext::current_handle().map(GLContextHandleWrapper::OSMesa) + } + + pub fn new_context(&self, + size: DeviceIntSize, + attributes: GLContextAttributes, + dispatcher: Option>) -> Result { + match *self { + GLContextHandleWrapper::Native(ref handle) => { + let ctx = GLContext::::new_shared_with_dispatcher(size.to_untyped(), + attributes, + ColorAttachmentType::Texture, + gl::GlType::default(), + Some(handle), + dispatcher); + ctx.map(GLContextWrapper::Native) + } + GLContextHandleWrapper::OSMesa(ref handle) => { + let ctx = GLContext::::new_shared_with_dispatcher(size.to_untyped(), + attributes, + ColorAttachmentType::Texture, + gl::GlType::default(), + Some(handle), + dispatcher); + ctx.map(GLContextWrapper::OSMesa) + } + } + } +} + +pub enum GLContextWrapper { + Native(GLContext), + OSMesa(GLContext), +} + +impl GLContextWrapper { + pub fn make_current(&self) { + match *self { + GLContextWrapper::Native(ref ctx) => { + ctx.make_current().unwrap(); + } + GLContextWrapper::OSMesa(ref ctx) => { + ctx.make_current().unwrap(); + } + } + } + + pub fn unbind(&self) { + match *self { + GLContextWrapper::Native(ref ctx) => { + ctx.unbind().unwrap(); + } + GLContextWrapper::OSMesa(ref ctx) => { + ctx.unbind().unwrap(); + } + } + } + + pub fn apply_command(&self, cmd: WebGLCommand) { + match *self { + GLContextWrapper::Native(ref ctx) => { + cmd.apply(ctx); + } + GLContextWrapper::OSMesa(ref ctx) => { + cmd.apply(ctx); + } + } + } + + pub fn get_info(&self) -> (DeviceIntSize, u32, GLLimits) { + match *self { + GLContextWrapper::Native(ref ctx) => { + let (real_size, texture_id) = { + let draw_buffer = ctx.borrow_draw_buffer().unwrap(); + (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap()) + }; + + let limits = ctx.borrow_limits().clone(); + + (DeviceIntSize::from_untyped(&real_size), texture_id, limits) + } + GLContextWrapper::OSMesa(ref ctx) => { + let (real_size, texture_id) = { + let draw_buffer = ctx.borrow_draw_buffer().unwrap(); + (draw_buffer.size(), draw_buffer.get_bound_texture_id().unwrap()) + }; + + let limits = ctx.borrow_limits().clone(); + + (DeviceIntSize::from_untyped(&real_size), texture_id, limits) + } + } + } + + pub fn resize(&mut self, size: &DeviceIntSize) -> Result<(), &'static str> { + match *self { + GLContextWrapper::Native(ref mut ctx) => { + ctx.resize(size.to_untyped()) + } + GLContextWrapper::OSMesa(ref mut ctx) => { + ctx.resize(size.to_untyped()) + } + } + } +} diff --git a/webrender_traits/Cargo.toml b/webrender_traits/Cargo.toml index 2ac3d7361d..029dd2c361 100644 --- a/webrender_traits/Cargo.toml +++ b/webrender_traits/Cargo.toml @@ -8,6 +8,7 @@ repository = "https://github.com/servo/webrender" [features] nightly = ["euclid/unstable", "serde/unstable"] ipc = ["ipc-channel"] +webgl = ["offscreen_gl_context"] [dependencies] app_units = "0.4" @@ -16,7 +17,7 @@ euclid = "0.11" gleam = "0.4" heapsize = "0.3.6" ipc-channel = {version = "0.7", optional = true} -offscreen_gl_context = {version = "0.8", features = ["serde"]} +offscreen_gl_context = {version = "0.8", features = ["serde"], optional = true} serde = "0.9" serde_derive = "0.9" diff --git a/webrender_traits/src/api.rs b/webrender_traits/src/api.rs index e79fb9067d..a33a77f720 100644 --- a/webrender_traits/src/api.rs +++ b/webrender_traits/src/api.rs @@ -4,6 +4,7 @@ use byteorder::{LittleEndian, WriteBytesExt}; use channel::{self, MsgSender, PayloadHelperMethods, PayloadSender}; +#[cfg(feature = "webgl")] use offscreen_gl_context::{GLContextAttributes, GLLimits}; use std::cell::Cell; use std::fmt; @@ -11,7 +12,9 @@ use std::marker::PhantomData; use {AuxiliaryLists, AuxiliaryListsDescriptor, BuiltDisplayList, BuiltDisplayListDescriptor}; use {ColorF, DeviceIntPoint, DeviceIntSize, DeviceUintRect, DeviceUintSize, FontKey}; use {GlyphDimensions, GlyphKey, ImageData, ImageDescriptor, ImageKey, LayoutPoint, LayoutSize}; -use {LayoutTransform, NativeFontHandle, ScrollLayerId, WebGLCommand, WebGLContextId, WorldPoint}; +use {LayoutTransform, NativeFontHandle, ScrollLayerId, WorldPoint}; +#[cfg(feature = "webgl")] +use {WebGLCommand, WebGLContextId}; pub type TileSize = u16; @@ -100,6 +103,24 @@ impl fmt::Debug for ApiMsg { #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] pub struct Epoch(pub u32); +#[cfg(not(feature = "webgl"))] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] +pub struct WebGLContextId(pub usize); + +#[cfg(not(feature = "webgl"))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GLContextAttributes([u8; 0]); + +#[cfg(not(feature = "webgl"))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct GLLimits([u8; 0]); + +#[cfg(not(feature = "webgl"))] +#[derive(Clone, Deserialize, Serialize)] +pub enum WebGLCommand { + Flush, +} + #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct PipelineId(pub u32, pub u32); diff --git a/webrender_traits/src/lib.rs b/webrender_traits/src/lib.rs index c4fc1ec9d7..48ba6a7a4e 100644 --- a/webrender_traits/src/lib.rs +++ b/webrender_traits/src/lib.rs @@ -14,6 +14,7 @@ extern crate gleam; extern crate heapsize; #[cfg(feature = "ipc")] extern crate ipc_channel; +#[cfg(feature = "webgl")] extern crate offscreen_gl_context; extern crate serde; #[macro_use] @@ -33,6 +34,7 @@ mod display_item; mod display_list; mod font; mod image; +#[cfg(feature = "webgl")] mod webgl; pub use api::*; @@ -42,4 +44,5 @@ pub use display_list::*; pub use font::*; pub use image::*; pub use units::*; +#[cfg(feature = "webgl")] pub use webgl::*;