aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/htmlmediaelement.rs98
1 files changed, 89 insertions, 9 deletions
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index cee7259af06..abd6613f340 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -60,6 +60,7 @@ use crate::script_thread::ScriptThread;
use crate::task_source::TaskSource;
use canvas_traits::media::*;
use dom_struct::dom_struct;
+use euclid::Size2D;
use headers::{ContentLength, ContentRange, HeaderMapExt};
use html5ever::{LocalName, Prefix};
use http::header::{self, HeaderMap, HeaderValue};
@@ -87,12 +88,57 @@ use webrender_api::{ExternalImageData, ExternalImageId, ExternalImageType, Textu
use webrender_api::{ImageData, ImageDescriptor, ImageFormat, ImageKey, RenderApi};
use webrender_api::{RenderApiSender, Transaction};
+#[derive(PartialEq)]
+enum FrameStatus {
+ Locked,
+ Unlocked,
+}
+
+struct FrameHolder(FrameStatus, Frame);
+
+impl FrameHolder {
+ fn new(frame: Frame) -> FrameHolder {
+ FrameHolder(FrameStatus::Unlocked, frame)
+ }
+
+ fn lock(&mut self) {
+ if self.0 == FrameStatus::Unlocked {
+ self.0 = FrameStatus::Locked;
+ };
+ }
+
+ fn unlock(&mut self) {
+ if self.0 == FrameStatus::Locked {
+ self.0 = FrameStatus::Unlocked;
+ };
+ }
+
+ fn set(&mut self, new_frame: Frame) {
+ if self.0 == FrameStatus::Unlocked {
+ self.1 = new_frame
+ };
+ }
+
+ fn get(&self) -> (u32, Size2D<i32>, usize) {
+ if self.0 == FrameStatus::Locked {
+ (
+ self.1.get_texture_id(),
+ Size2D::new(self.1.get_width(), self.1.get_height()),
+ 0,
+ )
+ } else {
+ unreachable!();
+ }
+ }
+}
+
pub struct MediaFrameRenderer {
id: u64,
api: RenderApi,
current_frame: Option<(ImageKey, i32, i32)>,
old_frame: Option<ImageKey>,
very_old_frame: Option<ImageKey>,
+ current_frame_holder: Option<FrameHolder>,
}
impl MediaFrameRenderer {
@@ -103,6 +149,7 @@ impl MediaFrameRenderer {
current_frame: None,
old_frame: None,
very_old_frame: None,
+ current_frame_holder: None,
}
}
@@ -140,6 +187,10 @@ impl FrameRenderer for MediaFrameRenderer {
ImageData::Raw(frame.get_data()),
&webrender_api::DirtyRect::All,
);
+ } else if self.id != 0 {
+ self.current_frame_holder
+ .get_or_insert_with(|| FrameHolder::new(frame.clone()))
+ .set(frame);
}
if let Some(old_image_key) = self.old_frame.take() {
@@ -151,6 +202,11 @@ impl FrameRenderer for MediaFrameRenderer {
let new_image_key = self.api.generate_image_key();
+ /* update current_frame */
+ *image_key = new_image_key;
+ *width = frame.get_width();
+ *height = frame.get_height();
+
if !frame.is_gl_texture() {
txn.add_image(
new_image_key,
@@ -169,15 +225,15 @@ impl FrameRenderer for MediaFrameRenderer {
}),
None,
);
- }
- /* update current_frame */
- *image_key = new_image_key;
- *width = frame.get_width();
- *height = frame.get_height();
+ self.current_frame_holder
+ .get_or_insert_with(|| FrameHolder::new(frame.clone()))
+ .set(frame);
+ }
},
None => {
let image_key = self.api.generate_image_key();
+ self.current_frame = Some((image_key, frame.get_width(), frame.get_height()));
if !frame.is_gl_texture() {
txn.add_image(
@@ -197,9 +253,9 @@ impl FrameRenderer for MediaFrameRenderer {
}),
None,
);
- }
- self.current_frame = Some((image_key, frame.get_width(), frame.get_height()));
+ self.current_frame_holder = Some(FrameHolder::new(frame));
+ }
},
}
self.api.update_resources(txn.resource_updates);
@@ -1325,11 +1381,35 @@ impl HTMLMediaElement {
ROUTER.add_route(
image_receiver.to_opaque(),
Box::new(move |message| {
- let msg: GLPlayerMsgForward = message.to().unwrap();
- let _this = trusted_node.clone();
+ let msg = message.to().unwrap();
+ let this = trusted_node.clone();
if let Err(err) = task_source.queue_with_canceller(
task!(handle_glplayer_message: move || {
trace!("GLPlayer message {:?}", msg);
+ let frame_renderer = this.root().frame_renderer.clone();
+
+ match msg {
+ GLPlayerMsgForward::Lock(sender) => {
+ frame_renderer
+ .lock()
+ .unwrap()
+ .current_frame_holder
+ .as_mut()
+ .map(|holder| {
+ holder.lock();
+ sender.send(holder.get()).unwrap();
+ });
+ },
+ GLPlayerMsgForward::Unlock() => {
+ frame_renderer
+ .lock()
+ .unwrap()
+ .current_frame_holder
+ .as_mut()
+ .map(|holder| holder.unlock());
+ },
+ _ => (),
+ }
}),
&canceller,
) {