diff --git a/Cargo.lock b/Cargo.lock index 89a0c44f0b211..d4a0e5523dc8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2922,7 +2922,7 @@ dependencies = [ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-media 0.1.0 (git+https://github.com/servo/media)", + "servo-media 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", "servo_allocator 0.0.1", "servo_arc 0.1.1", "servo_atoms 0.0.1", @@ -3149,30 +3149,30 @@ dependencies = [ [[package]] name = "servo-media" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/ferjm/media?branch=framerenderer#92cf9ac6ec2b9ea1ef99c38aa2ba61f9107b309f" dependencies = [ - "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", - "servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)", - "servo-media-player 0.1.0 (git+https://github.com/servo/media)", + "servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", + "servo-media-gstreamer 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", + "servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", ] [[package]] name = "servo-media-audio" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/ferjm/media?branch=framerenderer#92cf9ac6ec2b9ea1ef99c38aa2ba61f9107b309f" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "servo_media_derive 0.1.0 (git+https://github.com/servo/media)", + "servo_media_derive 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "servo-media-gstreamer" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/ferjm/media?branch=framerenderer#92cf9ac6ec2b9ea1ef99c38aa2ba61f9107b309f" dependencies = [ "byte-slice-cast 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "glib 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3182,15 +3182,15 @@ dependencies = [ "gstreamer-player 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "servo-media-audio 0.1.0 (git+https://github.com/servo/media)", - "servo-media-player 0.1.0 (git+https://github.com/servo/media)", + "servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", + "servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)", "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "servo-media-player" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/ferjm/media?branch=framerenderer#92cf9ac6ec2b9ea1ef99c38aa2ba61f9107b309f" dependencies = [ "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3276,7 +3276,7 @@ dependencies = [ [[package]] name = "servo_media_derive" version = "0.1.0" -source = "git+https://github.com/servo/media#6ecac1c6259b3995e8d6a368e49777e5c2d398ae" +source = "git+https://github.com/ferjm/media?branch=framerenderer#92cf9ac6ec2b9ea1ef99c38aa2ba61f9107b309f" dependencies = [ "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4437,12 +4437,12 @@ dependencies = [ "checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262" "checksum servo-fontconfig-sys 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa080856db55f188aaf36f01cae8c03448a6056552adb77d461179e44e1a14" "checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b" -"checksum servo-media 0.1.0 (git+https://github.com/servo/media)" = "" -"checksum servo-media-audio 0.1.0 (git+https://github.com/servo/media)" = "" -"checksum servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)" = "" -"checksum servo-media-player 0.1.0 (git+https://github.com/servo/media)" = "" +"checksum servo-media 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "" +"checksum servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "" +"checksum servo-media-gstreamer 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "" +"checksum servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "" "checksum servo-skia 0.30000019.1 (registry+https://github.com/rust-lang/crates.io-index)" = "82eddddcf9512dd7c60eccdb486e60e5bd4930afaa4da2d7d4afdff75950fb88" -"checksum servo_media_derive 0.1.0 (git+https://github.com/servo/media)" = "" +"checksum servo_media_derive 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum shared_library 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8254bf098ce4d8d7cc7cc6de438c5488adc5297e5b7ffef88816c0a91bd289c1" "checksum sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c6649e43c1a1e68d29ed56d0dc3b5b6cf3b901da77cf107c4066b9e3da036df5" diff --git a/Cargo.toml b/Cargo.toml index 069fd75fc96b6..dee0d109a8990 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,5 @@ opt-level = 3 # # [patch."https://github.com/servo/"] # = { path = "/path/to/local/checkout" } +[patch."https://github.com/servo/media"] +servo-media = { git = "https://github.com/ferjm/media", branch = "framerenderer" } diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 4bf53379e8bd1..1b8480ae7a2f2 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -1947,7 +1947,7 @@ impl FragmentDisplayListBuilding for Fragment { } }, SpecificFragmentInfo::Media(ref fragment_info) => { - if let Some((ref image_key, _, _)) = fragment_info.frame_source.get_current_frame() + if let Some((ref image_key, _, _)) = fragment_info.current_frame { let base = create_base_display_item(state); state.add_image_item( diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 686076f20e431..63c4b0ca95dfd 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -32,9 +32,7 @@ use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder}; use range::*; use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode}; -use script_layout_interface::{ - HTMLCanvasData, HTMLCanvasDataSource, HTMLMediaData, HTMLMediaFrameSource, SVGSVGData, -}; +use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource, HTMLMediaData, SVGSVGData}; use serde::ser::{Serialize, SerializeStruct, Serializer}; use servo_url::ServoUrl; use std::{f32, fmt}; @@ -377,23 +375,15 @@ impl CanvasFragmentInfo { } } +#[derive(Clone)] pub struct MediaFragmentInfo { - pub frame_source: Box, -} - -// XXX -impl Clone for MediaFragmentInfo { - fn clone(&self) -> MediaFragmentInfo { - MediaFragmentInfo { - frame_source: self.frame_source.clone_boxed(), - } - } + pub current_frame: Option<(webrender_api::ImageKey, i32, i32)>, } impl MediaFragmentInfo { pub fn new(data: HTMLMediaData) -> MediaFragmentInfo { MediaFragmentInfo { - frame_source: data.frame_source, + current_frame: data.current_frame, } } } @@ -978,7 +968,7 @@ impl Fragment { } } SpecificFragmentInfo::Media(ref info) => { - if let Some((_, width, _)) = info.frame_source.get_current_frame() { + if let Some((_, width, _)) = info.current_frame { Au::from_px(width as i32) } else { Au(0) @@ -1008,7 +998,7 @@ impl Fragment { } } SpecificFragmentInfo::Media(ref info) => { - if let Some((_, _, height)) = info.frame_source.get_current_frame() { + if let Some((_, _, height)) = info.current_frame { Au::from_px(height as i32) } else { Au(0) diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 1d8b7c0bcf227..aff14ec374ce9 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -26,7 +26,6 @@ use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::htmlsourceelement::HTMLSourceElement; use dom::mediaerror::MediaError; -use dom::mediaframerenderer::MediaFrameRenderer; use dom::node::{document_from_node, window_from_node, Node, NodeDamage, UnbindContext}; use dom::promise::Promise; use dom::virtualmethods::VirtualMethods; @@ -42,6 +41,7 @@ use network_listener::{NetworkListener, PreInvoke}; use script_layout_interface::HTMLMediaData; use script_thread::ScriptThread; use servo_media::player::{PlaybackState, Player, PlayerEvent}; +use servo_media::player::frame::{Frame, FrameRenderer}; use servo_media::ServoMedia; use servo_url::ServoUrl; use std::cell::Cell; @@ -51,9 +51,77 @@ use std::rc::Rc; use std::sync::{Arc, Mutex}; use task_source::{TaskSource, TaskSourceName}; use time::{self, Timespec, Duration}; +use webrender_api::{ImageData, ImageDescriptor, ImageFormat, ImageKey, RenderApi}; +use webrender_api::{RenderApiSender, Transaction}; unsafe_no_jsmanaged_fields!(Player); -unsafe_no_jsmanaged_fields!(MediaFrameRenderer); +unsafe_no_jsmanaged_fields!(Mutex); + +struct MediaFrameRenderer { + api: RenderApi, + current_frame: Option<(ImageKey, i32, i32)>, + old_frame: Option, + very_old_frame: Option, +} + +impl MediaFrameRenderer { + fn new(render_api_sender: RenderApiSender) -> Self { + Self { + api: render_api_sender.create_api(), + current_frame: None, + old_frame: None, + very_old_frame: None, + } + } +} + +impl FrameRenderer for MediaFrameRenderer { + fn render(&mut self, frame: Frame) { + let descriptor = ImageDescriptor::new( + frame.get_width() as u32, + frame.get_height() as u32, + ImageFormat::BGRA8, + false, + false, + ); + + let mut txn = Transaction::new(); + + let image_data = ImageData::Raw(frame.get_data().clone()); + + if let Some(old_image_key) = mem::replace(&mut self.very_old_frame, self.old_frame.take()) { + txn.delete_image(old_image_key); + } + + match self.current_frame { + Some((ref image_key, ref mut width, ref mut height)) + if *width == frame.get_width() && *height == frame.get_height() => + { + txn.update_image(*image_key, descriptor, image_data, None); + + if let Some(old_image_key) = self.old_frame.take() { + txn.delete_image(old_image_key); + } + } + Some((ref mut image_key, ref mut width, ref mut height)) => { + self.old_frame = Some(*image_key); + + let new_image_key = self.api.generate_image_key(); + txn.add_image(new_image_key, descriptor, image_data, None); + *image_key = new_image_key; + *width = frame.get_width(); + *height = frame.get_height(); + } + None => { + let image_key = self.api.generate_image_key(); + txn.add_image(image_key, descriptor, image_data, None); + self.current_frame = Some((image_key, frame.get_width(), frame.get_height())); + } + } + + self.api.update_resources(txn.resource_updates); + } +} #[dom_struct] // FIXME(nox): A lot of tasks queued for this element should probably be in the @@ -92,8 +160,8 @@ pub struct HTMLMediaElement { have_metadata: Cell, #[ignore_malloc_size_of = "servo_media"] player: Box, - #[ignore_malloc_size_of = "oops"] - frame_renderer: MediaFrameRenderer, + #[ignore_malloc_size_of = "Arc"] + frame_renderer: Arc>, } /// @@ -140,7 +208,8 @@ impl HTMLMediaElement { in_flight_play_promises_queue: Default::default(), have_metadata: Cell::new(false), player: ServoMedia::get().unwrap().create_player().unwrap(), - frame_renderer: MediaFrameRenderer::new(document.window().get_webrender_api_sender()), + frame_renderer: + Arc::new(Mutex::new(MediaFrameRenderer::new(document.window().get_webrender_api_sender()))), } } @@ -847,7 +916,7 @@ impl HTMLMediaElement { let (action_sender, action_receiver) = ipc::channel().unwrap(); self.player.register_event_handler(action_sender); - self.player.register_frame_renderer(Arc::new(self.frame_renderer.clone())); + self.player.register_frame_renderer(self.frame_renderer.clone()); // XXXferjm this can fail. self.player.setup().unwrap(); @@ -1038,12 +1107,9 @@ pub trait LayoutHTMLMediaElementHelpers { impl LayoutHTMLMediaElementHelpers for LayoutDom { #[allow(unsafe_code)] fn data(&self) -> HTMLMediaData { - unsafe { - let media = &*self.unsafe_get(); - - HTMLMediaData { - frame_source: Box::new(media.frame_renderer.clone()), - } + let media = unsafe { &*self.unsafe_get() }; + HTMLMediaData { + current_frame: media.frame_renderer.lock().unwrap().current_frame.clone(), } } } diff --git a/components/script/dom/mediaframerenderer.rs b/components/script/dom/mediaframerenderer.rs deleted file mode 100644 index 28a52c4bf7fec..0000000000000 --- a/components/script/dom/mediaframerenderer.rs +++ /dev/null @@ -1,98 +0,0 @@ -use servo_media::player::frame::{Frame, FrameRenderer}; -use script_layout_interface::HTMLMediaFrameSource; -use std::mem; -use std::sync::{Arc, Mutex}; -use webrender_api::{ - ImageData, ImageDescriptor, ImageFormat, ImageKey, RenderApi, RenderApiSender, Transaction, -}; - -#[derive(Clone)] -pub struct MediaFrameRenderer { - inner: Arc>, -} - -impl MediaFrameRenderer { - pub fn new(render_api_sender: RenderApiSender) -> MediaFrameRenderer { - MediaFrameRenderer { - inner: Arc::new(Mutex::new(MediaFrameRendererInner { - api: render_api_sender.create_api(), - current_frame: None, - old_frame: None, - very_old_frame: None, - })), - } - } -} - -impl FrameRenderer for MediaFrameRenderer { - fn render(&self, frame: Frame) { - self.inner.lock().unwrap().render(frame); - } -} - -impl HTMLMediaFrameSource for MediaFrameRenderer { - fn get_current_frame(&self) -> Option<(ImageKey, i32, i32)> { - let inner = self.inner.lock().unwrap(); - inner.current_frame.clone() - } - - fn clone_boxed(&self) -> Box { - Box::new(self.clone()) - } -} - -struct MediaFrameRendererInner { - api: RenderApi, - current_frame: Option<(ImageKey, i32, i32)>, - old_frame: Option, - very_old_frame: Option, -} - -impl MediaFrameRendererInner { - fn render(&mut self, frame: Frame) { - let descriptor = ImageDescriptor::new( - frame.get_width() as u32, - frame.get_height() as u32, - ImageFormat::BGRA8, - false, - false, - ); - - let mut txn = Transaction::new(); - - //let image_data = ImageData::new_shared(frame.get_data().clone()); - let image_data = ImageData::Raw(frame.get_data().clone()); - - if let Some(old_image_key) = mem::replace(&mut self.very_old_frame, self.old_frame.take()) { - txn.delete_image(old_image_key); - } - - match self.current_frame { - Some((ref image_key, ref mut width, ref mut height)) - if *width == frame.get_width() && *height == frame.get_height() => - { - txn.update_image(*image_key, descriptor, image_data, None); - - if let Some(old_image_key) = self.old_frame.take() { - txn.delete_image(old_image_key); - } - } - Some((ref mut image_key, ref mut width, ref mut height)) => { - self.old_frame = Some(*image_key); - - let new_image_key = self.api.generate_image_key(); - txn.add_image(new_image_key, descriptor, image_data, None); - *image_key = new_image_key; - *width = frame.get_width(); - *height = frame.get_height(); - } - None => { - let image_key = self.api.generate_image_key(); - txn.add_image(image_key, descriptor, image_data, None); - self.current_frame = Some((image_key, frame.get_width(), frame.get_height())); - } - } - - self.api.update_resources(txn.resource_updates); - } -} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index f24bc6e8d45a4..758c428497916 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -387,7 +387,6 @@ pub mod inputevent; pub mod keyboardevent; pub mod location; pub mod mediaerror; -pub mod mediaframerenderer; pub mod medialist; pub mod mediaquerylist; pub mod mediaquerylistevent; diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs index 27c5a512e4977..7261f1d884d67 100644 --- a/components/script_layout_interface/lib.rs +++ b/components/script_layout_interface/lib.rs @@ -169,12 +169,6 @@ pub struct PendingImage { pub id: PendingImageId, } -/// FIXME(victor): probably this doesn't belong here -pub trait HTMLMediaFrameSource: Send + Sync + 'static { - fn get_current_frame(&self) -> Option<(webrender_api::ImageKey, i32, i32)>; - fn clone_boxed(&self) -> Box; -} - pub struct HTMLMediaData { - pub frame_source: Box, + pub current_frame: Option<(webrender_api::ImageKey, i32, i32)>, }