aboutsummaryrefslogtreecommitdiffstats
path: root/components/servo/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/servo/lib.rs')
-rw-r--r--components/servo/lib.rs137
1 files changed, 117 insertions, 20 deletions
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index 5f1a09d8e71..92278eab1b7 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -17,7 +17,7 @@
//! `Servo` is fed events from a generic type that implements the
//! `WindowMethods` trait.
-use std::borrow::Cow;
+use std::borrow::{BorrowMut, Cow};
use std::cmp::max;
use std::collections::HashMap;
use std::path::PathBuf;
@@ -62,10 +62,11 @@ use euclid::Scale;
use gaol::sandbox::{ChildSandbox, ChildSandboxMethods};
use gfx::font_cache_thread::FontCacheThread;
pub use gfx::rendering_context;
+use gfx::rendering_context::RenderingContext;
pub use gleam::gl;
use ipc_channel::ipc::{self, IpcSender};
use log::{error, trace, warn, Log, Metadata, Record};
-use media::{GLPlayerThreads, WindowGLContext};
+use media::{GLPlayerThreads, GlApi, NativeDisplay, WindowGLContext};
pub use msg::constellation_msg::TopLevelBrowsingContextId;
use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId};
use net::resource_thread::new_resource_threads;
@@ -78,7 +79,13 @@ use script_traits::{ScriptToConstellationChan, WindowSizeData};
use servo_config::{opts, pref, prefs};
use servo_media::player::context::GlContext;
use servo_media::ServoMedia;
-use surfman::GLApi;
+#[cfg(target_os = "linux")]
+use surfman::platform::generic::multi::connection::NativeConnection as LinuxNativeConnection;
+#[cfg(target_os = "linux")]
+use surfman::platform::generic::multi::context::NativeContext as LinuxNativeContext;
+use surfman::{GLApi, GLVersion};
+#[cfg(target_os = "linux")]
+use surfman::{NativeConnection, NativeContext};
use webrender::{RenderApiSender, ShaderPrecacheFlags};
use webrender_api::{DocumentId, FontInstanceKey, FontKey, ImageKey};
use webrender_traits::{
@@ -388,17 +395,6 @@ where
embedder.register_webxr(&mut webxr_main_thread, embedder_proxy.clone());
}
- let glplayer_threads = match window.get_gl_context() {
- GlContext::Unknown => None,
- _ => {
- let (glplayer_threads, image_handler) =
- GLPlayerThreads::new(external_images.clone());
- external_image_handlers
- .set_handler(image_handler, WebrenderImageHandlerType::Media);
- Some(glplayer_threads)
- },
- };
-
let wgpu_image_handler = webgpu::WGPUExternalImages::new();
let wgpu_image_map = wgpu_image_handler.images.clone();
external_image_handlers.set_handler(
@@ -406,12 +402,11 @@ where
WebrenderImageHandlerType::WebGPU,
);
- let player_context = WindowGLContext {
- gl_context: window.get_gl_context(),
- native_display: window.get_native_display(),
- gl_api: window.get_gl_api(),
- glplayer_chan: glplayer_threads.as_ref().map(GLPlayerThreads::pipeline),
- };
+ let (player_context, glplayer_threads) = Self::create_media_window_gl_context(
+ external_image_handlers.borrow_mut(),
+ external_images.clone(),
+ &rendering_context,
+ );
webrender.set_external_image_handler(external_image_handlers);
@@ -494,6 +489,108 @@ where
}
}
+ #[cfg(target_os = "linux")]
+ fn get_native_media_display_and_gl_context(
+ rendering_context: &RenderingContext,
+ ) -> Option<(NativeDisplay, GlContext)> {
+ let gl_context = match rendering_context.native_context() {
+ NativeContext::Default(LinuxNativeContext::Default(native_context)) => {
+ GlContext::Egl(native_context.egl_context as usize)
+ },
+ NativeContext::Default(LinuxNativeContext::Alternate(native_context)) => {
+ GlContext::Egl(native_context.egl_context as usize)
+ },
+ NativeContext::Alternate(_) => return None,
+ };
+
+ let native_display = match rendering_context.connection().native_connection() {
+ NativeConnection::Default(LinuxNativeConnection::Default(connection)) => {
+ NativeDisplay::Egl(connection.0 as usize)
+ },
+ NativeConnection::Default(LinuxNativeConnection::Alternate(connection)) => {
+ NativeDisplay::X11(connection.x11_display as usize)
+ },
+ NativeConnection::Alternate(_) => return None,
+ };
+ Some((native_display, gl_context))
+ }
+
+ // @TODO(victor): https://github.com/servo/media/pull/315
+ #[cfg(target_os = "windows")]
+ fn get_native_media_display_and_gl_context(
+ rendering_context: &RenderingContext,
+ ) -> Option<(NativeDisplay, GlContext)> {
+ let gl_context = GlContext::Egl(rendering_context.native_context().egl_context as usize);
+ let native_display =
+ NativeDisplay::Egl(rendering_context.native_device().egl_display as usize);
+ Some((native_display, gl_context))
+ }
+
+ #[cfg(not(any(target_os = "windows", target_os = "linux")))]
+ fn get_native_media_display_and_gl_context(
+ _rendering_context: &RenderingContext,
+ ) -> Option<(NativeDisplay, GlContext)> {
+ None
+ }
+
+ fn create_media_window_gl_context(
+ external_image_handlers: &mut WebrenderExternalImageHandlers,
+ external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
+ rendering_context: &RenderingContext,
+ ) -> (WindowGLContext, Option<GLPlayerThreads>) {
+ if !pref!(media.glvideo.enabled) {
+ return (
+ WindowGLContext {
+ gl_context: GlContext::Unknown,
+ gl_api: GlApi::None,
+ native_display: NativeDisplay::Unknown,
+ glplayer_chan: None,
+ },
+ None,
+ );
+ }
+
+ let (native_display, gl_context) =
+ match Self::get_native_media_display_and_gl_context(rendering_context) {
+ Some((native_display, gl_context)) => (native_display, gl_context),
+ None => {
+ return (
+ WindowGLContext {
+ gl_context: GlContext::Unknown,
+ gl_api: GlApi::None,
+ native_display: NativeDisplay::Unknown,
+ glplayer_chan: None,
+ },
+ None,
+ );
+ },
+ };
+
+ let api = rendering_context.connection().gl_api();
+ let attributes = rendering_context.context_attributes();
+ let GLVersion { major, minor } = attributes.version;
+ let gl_api = match api {
+ GLApi::GL if major >= 3 && minor >= 2 => GlApi::OpenGL3,
+ GLApi::GL => GlApi::OpenGL,
+ GLApi::GLES if major > 1 => GlApi::Gles2,
+ GLApi::GLES => GlApi::Gles1,
+ };
+
+ assert!(!matches!(gl_context, GlContext::Unknown));
+ let (glplayer_threads, image_handler) = GLPlayerThreads::new(external_images.clone());
+ external_image_handlers.set_handler(image_handler, WebrenderImageHandlerType::Media);
+
+ (
+ WindowGLContext {
+ gl_context,
+ native_display,
+ gl_api,
+ glplayer_chan: Some(GLPlayerThreads::pipeline(&glplayer_threads)),
+ },
+ Some(glplayer_threads),
+ )
+ }
+
fn handle_window_event(&mut self, event: EmbedderEvent) -> bool {
match event {
EmbedderEvent::Idle => {},