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.
This commit is contained in:
Víctor Manuel Jáquez Leal 2019-06-18 17:45:56 +02:00 committed by Fernando Jiménez Moreno
parent e9f46f9d72
commit 9f4f9dc750
16 changed files with 133 additions and 26 deletions

View file

@ -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();

View file

@ -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) }

View file

@ -86,6 +86,7 @@ use crate::task_source::websocket::WebsocketTaskSource;
use crate::task_source::TaskSourceName;
use crate::webdriver_handlers;
use bluetooth_traits::BluetoothRequest;
use canvas_traits::media::WindowGLContext;
use canvas_traits::webgl::WebGLPipeline;
use crossbeam_channel::{unbounded, Receiver, Sender};
use devtools_traits::CSSError;
@ -512,6 +513,8 @@ unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>);
unsafe_no_jsmanaged_fields!(dyn BackgroundHangMonitorRegister);
unsafe_no_jsmanaged_fields!(dyn BackgroundHangMonitor);
unsafe_no_jsmanaged_fields!(WindowGLContext);
#[derive(JSTraceable)]
// ScriptThread instances are rooted on creation, so this is okay
#[allow(unrooted_must_root)]
@ -646,7 +649,7 @@ pub struct ScriptThread {
/// The Webrender Document ID associated with this thread.
webrender_document: DocumentId,
/// FIXME(victor):
/// Webrender API sender.
webrender_api_sender: RenderApiSender,
/// Periodically print out on which events script threads spend their processing time.
@ -678,6 +681,9 @@ pub struct ScriptThread {
/// An optional string allowing the user agent to be set for testing.
user_agent: Cow<'static, str>,
/// Application window's GL Context for Media player
player_context: WindowGLContext,
}
/// In the event of thread panic, all data on the stack runs its destructor. However, there
@ -1239,6 +1245,7 @@ impl ScriptThread {
headless,
replace_surrogates,
user_agent,
player_context: state.player_context,
}
}
@ -2981,6 +2988,7 @@ impl ScriptThread {
self.headless,
self.replace_surrogates,
self.user_agent.clone(),
self.player_context.clone(),
);
// Initialize the browsing context for the window.