mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
dom: add mediaframewebrenderer
This commit is contained in:
parent
781b3b712b
commit
6e3c2fe41a
3 changed files with 100 additions and 2 deletions
|
@ -26,7 +26,8 @@ use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlsourceelement::HTMLSourceElement;
|
use dom::htmlsourceelement::HTMLSourceElement;
|
||||||
use dom::mediaerror::MediaError;
|
use dom::mediaerror::MediaError;
|
||||||
use dom::node::{window_from_node, document_from_node, Node, UnbindContext};
|
use dom::mediaframerenderer::MediaFrameRenderer;
|
||||||
|
use dom::node::{document_from_node, window_from_node, Node, NodeDamage, UnbindContext};
|
||||||
use dom::promise::Promise;
|
use dom::promise::Promise;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
@ -51,6 +52,7 @@ use task_source::{TaskSource, TaskSourceName};
|
||||||
use time::{self, Timespec, Duration};
|
use time::{self, Timespec, Duration};
|
||||||
|
|
||||||
unsafe_no_jsmanaged_fields!(Arc<Mutex<Box<Player>>>);
|
unsafe_no_jsmanaged_fields!(Arc<Mutex<Box<Player>>>);
|
||||||
|
unsafe_no_jsmanaged_fields!(MediaFrameRenderer);
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
// FIXME(nox): A lot of tasks queued for this element should probably be in the
|
// FIXME(nox): A lot of tasks queued for this element should probably be in the
|
||||||
|
@ -89,6 +91,8 @@ pub struct HTMLMediaElement {
|
||||||
have_metadata: Cell<bool>,
|
have_metadata: Cell<bool>,
|
||||||
#[ignore_malloc_size_of = "servo_media"]
|
#[ignore_malloc_size_of = "servo_media"]
|
||||||
player: Arc<Mutex<Box<Player>>>,
|
player: Arc<Mutex<Box<Player>>>,
|
||||||
|
#[ignore_malloc_size_of = "oops"]
|
||||||
|
frame_renderer: MediaFrameRenderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-media-networkstate>
|
/// <https://html.spec.whatwg.org/multipage/#dom-media-networkstate>
|
||||||
|
@ -133,6 +137,7 @@ impl HTMLMediaElement {
|
||||||
player: Arc::new(Mutex::new(
|
player: Arc::new(Mutex::new(
|
||||||
ServoMedia::get().unwrap().create_player().unwrap(),
|
ServoMedia::get().unwrap().create_player().unwrap(),
|
||||||
)),
|
)),
|
||||||
|
frame_renderer: MediaFrameRenderer::new(document.window().get_webrender_api_sender()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,6 +840,10 @@ impl HTMLMediaElement {
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.register_event_handler(action_sender);
|
.register_event_handler(action_sender);
|
||||||
|
self.player
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.register_frame_renderer(Arc::new(self.frame_renderer.clone()));
|
||||||
self.player.lock().unwrap().setup().unwrap();
|
self.player.lock().unwrap().setup().unwrap();
|
||||||
|
|
||||||
let trusted_node = Trusted::new(self);
|
let trusted_node = Trusted::new(self);
|
||||||
|
@ -882,7 +891,9 @@ impl HTMLMediaElement {
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
PlayerEvent::EndOfStream => {}
|
PlayerEvent::EndOfStream => {}
|
||||||
PlayerEvent::FrameUpdated => {}
|
PlayerEvent::FrameUpdated => {
|
||||||
|
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
|
||||||
|
}
|
||||||
PlayerEvent::Error => {
|
PlayerEvent::Error => {
|
||||||
self.error.set(Some(&*MediaError::new(
|
self.error.set(Some(&*MediaError::new(
|
||||||
&*window_from_node(self),
|
&*window_from_node(self),
|
||||||
|
|
86
components/script/dom/mediaframerenderer.rs
Normal file
86
components/script/dom/mediaframerenderer.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
use servo_media::player::frame::{Frame, FrameRenderer};
|
||||||
|
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<Mutex<MediaFrameRendererInner>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MediaFrameRendererInner {
|
||||||
|
api: RenderApi,
|
||||||
|
current_frame: Option<(ImageKey, i32, i32)>,
|
||||||
|
old_frame: Option<ImageKey>,
|
||||||
|
very_old_frame: Option<ImageKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -390,6 +390,7 @@ pub mod inputevent;
|
||||||
pub mod keyboardevent;
|
pub mod keyboardevent;
|
||||||
pub mod location;
|
pub mod location;
|
||||||
pub mod mediaerror;
|
pub mod mediaerror;
|
||||||
|
pub mod mediaframerenderer;
|
||||||
pub mod medialist;
|
pub mod medialist;
|
||||||
pub mod mediaquerylist;
|
pub mod mediaquerylist;
|
||||||
pub mod mediaquerylistevent;
|
pub mod mediaquerylistevent;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue