Skip to content
Permalink
Browse files

Add media (WindowGLContext) module in canvas_trait

This module adds a structure (WindowGLContext) which holds the
OpenGL parameters that are going to be used by servo-media player
to render video frames using OpenGL.

In order to fill this structure, three new methods were added to
WindowMethods trait. In this patch only the Glutin-based
implementation provides a simple boilerplate.

The WindowGLContext is created in the entry point of libservo, when
the application window is created, and later passed to the
constellation, the pipeline and to the window element in dom, thus
htmlmediaelement has a mean to obtain these parameters via its
window.
  • Loading branch information...
ceyusa authored and ferjm committed Jun 18, 2019
1 parent e9f46f9 commit 9f4f9dc750ea98e70dbdab8b2a0e5ef6c98dd889

Some generated files are not rendered by default. Learn more.

@@ -25,6 +25,7 @@ pixels = {path = "../pixels"}
serde = "1.0"
serde_bytes = "0.10"
servo_config = {path = "../config"}
servo-media = {git = "https://github.com/servo/media"}
typetag = "0.1"
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
webvr_traits = {path = "../webvr_traits"}
@@ -14,6 +14,7 @@ extern crate malloc_size_of_derive;
extern crate serde;

pub mod canvas;
pub mod media;
#[macro_use]
pub mod webgl;
mod webgl_channel;
@@ -0,0 +1,29 @@
/* 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 servo_media::player::context::{GlApi, GlContext, NativeDisplay, PlayerGLContext};

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WindowGLContext {
/// Application's GL Context
pub gl_context: GlContext,
/// Application's GL Api
pub gl_api: GlApi,
/// Application's native display
pub native_display: NativeDisplay,
}

impl PlayerGLContext for WindowGLContext {
fn get_gl_context(&self) -> GlContext {
self.gl_context.clone()
}

fn get_native_display(&self) -> NativeDisplay {
self.native_display.clone()
}

fn get_gl_api(&self) -> GlApi {
self.gl_api.clone()
}
}
@@ -33,6 +33,7 @@ pixels = {path = "../pixels", optional = true}
profile_traits = {path = "../profile_traits"}
script_traits = {path = "../script_traits"}
servo_geometry = {path = "../geometry"}
servo-media = {git = "https://github.com/servo/media"}
servo_url = {path = "../url"}
style_traits = {path = "../style_traits"}
time = "0.1.17"
@@ -12,6 +12,7 @@ use keyboard_types::KeyboardEvent;
use msg::constellation_msg::{PipelineId, TopLevelBrowsingContextId, TraversalDirection};
use script_traits::{MouseButton, TouchEventType, TouchId, WheelDelta};
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")]
@@ -157,6 +158,12 @@ 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
fn get_gl_context(&self) -> GlContext;
/// Get the native display
fn get_native_display(&self) -> NativeDisplay;
/// Get the GL api
fn get_gl_api(&self) -> GlApi;
}

pub trait EmbedderMethods {
@@ -107,6 +107,7 @@ use canvas::canvas_paint_thread::CanvasPaintThread;
use canvas::webgl_thread::WebGLThreads;
use canvas_traits::canvas::CanvasId;
use canvas_traits::canvas::CanvasMsg;
use canvas_traits::media::WindowGLContext;
use compositing::compositor_thread::CompositorProxy;
use compositing::compositor_thread::Msg as ToCompositorMsg;
use compositing::SendableFrameTree;
@@ -409,6 +410,9 @@ pub struct Constellation<Message, LTF, STF> {
/// Like --disable-text-aa, this is useful for reftests where pixel perfect
/// results are required.
enable_canvas_antialiasing: bool,

/// Application window's GL Context for Media player
player_context: WindowGLContext,
}

/// State needed to construct a constellation.
@@ -457,6 +461,9 @@ pub struct InitialConstellationState {

/// The XR device registry
pub webxr_registry: webxr_api::Registry,

/// Application window's GL Context for Media player
pub player_context: WindowGLContext,
}

/// Data needed for webdriver
@@ -753,6 +760,7 @@ where
is_running_problem_test,
hard_fail,
enable_canvas_antialiasing,
player_context: state.player_context,
};

constellation.run();
@@ -994,6 +1002,7 @@ where
.map(|threads| threads.pipeline()),
webvr_chan: self.webvr_chan.clone(),
webxr_registry: self.webxr_registry.clone(),
player_context: self.player_context.clone(),
});

let pipeline = match result {
@@ -5,6 +5,7 @@
use crate::event_loop::EventLoop;
use background_hang_monitor::HangMonitorRegister;
use bluetooth_traits::BluetoothRequest;
use canvas_traits::media::WindowGLContext;
use canvas_traits::webgl::WebGLPipeline;
use compositing::compositor_thread::Msg as CompositorMsg;
use compositing::CompositionPipeline;
@@ -191,6 +192,9 @@ pub struct InitialPipelineState {

/// The XR device registry
pub webxr_registry: webxr_api::Registry,

/// Application window's GL Context for Media player
pub player_context: WindowGLContext,
}

pub struct NewPipeline {
@@ -309,6 +313,7 @@ impl Pipeline {
webgl_chan: state.webgl_chan,
webvr_chan: state.webvr_chan,
webxr_registry: state.webxr_registry,
player_context: state.player_context,
};

// Spawn the child process.
@@ -515,6 +520,7 @@ pub struct UnprivilegedPipelineContent {
webgl_chan: Option<WebGLPipeline>,
webvr_chan: Option<IpcSender<WebVRMsg>>,
webxr_registry: webxr_api::Registry,
player_context: WindowGLContext,
}

impl UnprivilegedPipelineContent {
@@ -563,6 +569,7 @@ impl UnprivilegedPipelineContent {
webrender_document: self.webrender_document,
webrender_api_sender: self.webrender_api_sender.clone(),
layout_is_busy: layout_thread_busy_flag.clone(),
player_context: self.player_context.clone(),
},
self.load_data.clone(),
self.opts.profile_script_events,
@@ -71,7 +71,6 @@ use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseLis
use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType};
use script_layout_interface::HTMLMediaData;
use servo_config::pref;
use servo_media::player::context::{GlContext, NativeDisplay, PlayerGLContext};
use servo_media::player::frame::{Frame, FrameRenderer};
use servo_media::player::{PlaybackState, Player, PlayerError, PlayerEvent, StreamType};
use servo_media::{ServoMedia, SupportsMediaType};
@@ -162,16 +161,6 @@ impl FrameRenderer for MediaFrameRenderer {
}
}

struct PlayerContextDummy();
impl PlayerGLContext for PlayerContextDummy {
fn get_gl_context(&self) -> GlContext {
return GlContext::Unknown;
}
fn get_native_display(&self) -> NativeDisplay {
return NativeDisplay::Unknown;
}
}

#[must_root]
#[derive(JSTraceable, MallocSizeOf)]
enum SrcObject {
@@ -1222,22 +1211,23 @@ impl HTMLMediaElement {
_ => StreamType::Seekable,
};

let window = window_from_node(self);
let (action_sender, action_receiver) = ipc::channel().unwrap();
let renderer: Option<Arc<Mutex<dyn FrameRenderer>>> = match self.media_type_id() {
HTMLMediaElementTypeId::HTMLAudioElement => None,
HTMLMediaElementTypeId::HTMLVideoElement => Some(self.frame_renderer.clone()),
};

let player = ServoMedia::get().unwrap().create_player(
stream_type,
action_sender,
renderer,
Box::new(PlayerContextDummy()),
Box::new(window.get_player_context()),
);

*self.player.borrow_mut() = Some(player);

let trusted_node = Trusted::new(self);
let window = window_from_node(self);
let (task_source, canceller) = window
.task_manager()
.media_element_task_source_with_canceller();
@@ -68,6 +68,7 @@ use crate::webdriver_handlers::jsval_to_webdriver;
use app_units::Au;
use base64;
use bluetooth_traits::BluetoothRequest;
use canvas_traits::media::WindowGLContext;
use canvas_traits::webgl::WebGLChan;
use crossbeam_channel::{unbounded, Sender, TryRecvError};
use cssparser::{Parser, ParserInput, SourceLocation};
@@ -318,6 +319,10 @@ pub struct Window {
/// Replace unpaired surrogates in DOM strings with U+FFFD.
/// See <https://github.com/servo/servo/issues/6564>
replace_surrogates: bool,

/// Window's GL context from application
#[ignore_malloc_size_of = "defined in script_thread"]
player_context: WindowGLContext,
}

impl Window {
@@ -481,6 +486,10 @@ impl Window {
pub fn unminify_js(&self) -> bool {
self.unminify_js
}

pub fn get_player_context(&self) -> WindowGLContext {
self.player_context.clone()
}
}

// https://html.spec.whatwg.org/multipage/#atob
@@ -2074,6 +2083,7 @@ impl Window {
is_headless: bool,
replace_surrogates: bool,
user_agent: Cow<'static, str>,
player_context: WindowGLContext,
) -> DomRoot<Self> {
let layout_rpc: Box<dyn LayoutRPC + Send> = {
let (rpc_send, rpc_recv) = unbounded();
@@ -2154,6 +2164,7 @@ impl Window {
unminify_js,
userscripts_path,
replace_surrogates,
player_context,
});

unsafe { WindowBinding::Wrap(runtime.cx(), win) }

0 comments on commit 9f4f9dc

Please sign in to comment.
You can’t perform that action at this time.