Skip to content

Commit

Permalink
Auto merge of #23483 - ceyusa:player-context, r=jdm
Browse files Browse the repository at this point in the history
Media player rendering with GL textures

These patches pass the application's OpenGL raw context  and the its native display address to the media player, in order to create an internal wrapped context, thus it will generate video frames as textures.

For now only EGL from glutin-based app and android are in place, though tested only in Linux glutin app.

This PR also renders the generated frame textures by Servo/Media and renders them by using a thread that connects Webrenderer's ExternalImageHandler and each instantiated player. **By now, these patches, disable the WebGL rendering**. We need to provide a ExternalImageHandler demuxer.

This PR depends on servo/media#270

- [X]  `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- This PR fixes #22300 and fixes #22920

In order to test it you must launch servo as

`./mach run -- --pref media.glvideo.enabled [...]`

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23483)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Jul 5, 2019
2 parents ee785f6 + 4fe1291 commit 0dc17af
Show file tree
Hide file tree
Showing 38 changed files with 1,282 additions and 128 deletions.
55 changes: 45 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/canvas/Cargo.toml
Expand Up @@ -37,3 +37,4 @@ serde_bytes = "0.10"
servo_config = {path = "../config"}
webrender = {git = "https://github.com/servo/webrender"}
webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]}
webrender_traits = {path = "../webrender_traits"}
26 changes: 17 additions & 9 deletions components/canvas/webgl_mode/inprocess.rs
Expand Up @@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::gl_context::GLContextFactory;
use crate::webgl_thread::{WebGLExternalImageApi, WebGLExternalImageHandler, WebGLThread};
use crate::webgl_thread::WebGLThread;
use canvas_traits::webgl::webgl_channel;
use canvas_traits::webgl::DOMToTextureCommand;
use canvas_traits::webgl::{WebGLChan, WebGLContextId, WebGLMsg, WebGLPipeline, WebGLReceiver};
Expand All @@ -13,6 +13,8 @@ use fnv::FnvHashMap;
use gleam::gl;
use servo_config::pref;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use webrender_traits::{WebrenderExternalImageApi, WebrenderExternalImageRegistry};

/// WebGL Threading API entry point that lives in the constellation.
pub struct WebGLThreads(WebGLSender<WebGLMsg>);
Expand All @@ -24,16 +26,18 @@ impl WebGLThreads {
webrender_gl: Rc<dyn gl::Gl>,
webrender_api_sender: webrender_api::RenderApiSender,
webvr_compositor: Option<Box<dyn WebVRRenderHandler>>,
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
) -> (
WebGLThreads,
Box<dyn webrender::ExternalImageHandler>,
Box<dyn WebrenderExternalImageApi>,
Option<Box<dyn webrender::OutputImageHandler>>,
) {
// This implementation creates a single `WebGLThread` for all the pipelines.
let channel = WebGLThread::start(
gl_factory,
webrender_api_sender,
webvr_compositor.map(|c| WebVRRenderWrapper(c)),
external_images,
);
let output_handler = if pref!(dom.webgl.dom_to_texture.enabled) {
Some(Box::new(OutputHandler::new(
Expand All @@ -43,8 +47,7 @@ impl WebGLThreads {
} else {
None
};
let external =
WebGLExternalImageHandler::new(WebGLExternalImages::new(webrender_gl, channel.clone()));
let external = WebGLExternalImages::new(webrender_gl, channel.clone());
(
WebGLThreads(channel),
Box::new(external),
Expand Down Expand Up @@ -87,12 +90,15 @@ impl WebGLExternalImages {
}
}

impl WebGLExternalImageApi for WebGLExternalImages {
fn lock(&mut self, ctx_id: WebGLContextId) -> (u32, Size2D<i32>) {
impl WebrenderExternalImageApi for WebGLExternalImages {
fn lock(&mut self, id: u64) -> (u32, Size2D<i32>) {
// WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue.
// The WebGLMsg::Lock message inserts a fence in the WebGL command queue.
self.webgl_channel
.send(WebGLMsg::Lock(ctx_id, self.lock_channel.0.clone()))
.send(WebGLMsg::Lock(
WebGLContextId(id as usize),
self.lock_channel.0.clone(),
))
.unwrap();
let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap();
// The next glWaitSync call is run on the WR thread and it's used to synchronize the two
Expand All @@ -103,8 +109,10 @@ impl WebGLExternalImageApi for WebGLExternalImages {
(image_id, size)
}

fn unlock(&mut self, ctx_id: WebGLContextId) {
self.webgl_channel.send(WebGLMsg::Unlock(ctx_id)).unwrap();
fn unlock(&mut self, id: u64) {
self.webgl_channel
.send(WebGLMsg::Unlock(WebGLContextId(id as usize)))
.unwrap();
}
}

Expand Down

0 comments on commit 0dc17af

Please sign in to comment.