mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Do not share entire FrameRenderer with layout, only current frame
This commit is contained in:
parent
1f406ef0a0
commit
8c40ef459b
8 changed files with 102 additions and 149 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -2992,7 +2992,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",
|
||||
|
@ -3226,9 +3226,9 @@ name = "servo-media"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/servo/media#e700a0834c3f38d49890d846591fd699e7405a48"
|
||||
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]]
|
||||
|
@ -3243,7 +3243,7 @@ dependencies = [
|
|||
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.66 (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)",
|
||||
]
|
||||
|
||||
|
@ -3260,8 +3260,8 @@ dependencies = [
|
|||
"gstreamer-player 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-channel 0.11.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)",
|
||||
]
|
||||
|
||||
|
@ -4545,14 +4545,14 @@ dependencies = [
|
|||
"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
|
||||
"checksum servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21069a884c33fe6ee596975e1f3849ed88c4ec857fbaf11d33672d8ebe051217"
|
||||
"checksum servo-fontconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "93f799b649b4a2bf362398910eca35240704c7e765e780349b2bb1070d892262"
|
||||
"checksum servo-fontconfig-sys 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b46d201addcfbd25c1798ad1281d98c40743824e0b0f1e611bd3d5d0d31a7b8d"
|
||||
"checksum servo-freetype-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d00ab791f66cd2ec58e72c91b6076cee20fac560463aa871404eb31dfc9c4ff"
|
||||
"checksum servo-media 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media-audio 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media-gstreamer 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"checksum servo-media-player 0.1.0 (git+https://github.com/servo/media)" = "<none>"
|
||||
"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/ferjm/media?branch=framerenderer)" = "<none>"
|
||||
"checksum servo-media-audio 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "<none>"
|
||||
"checksum servo-media-gstreamer 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "<none>"
|
||||
"checksum servo-media-player 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "<none>"
|
||||
"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)" = "<none>"
|
||||
"checksum servo_media_derive 0.1.0 (git+https://github.com/ferjm/media?branch=framerenderer)" = "<none>"
|
||||
"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"
|
||||
|
|
|
@ -22,3 +22,5 @@ opt-level = 3
|
|||
#
|
||||
# [patch."https://github.com/servo/<repository>"]
|
||||
# <crate> = { path = "/path/to/local/checkout" }
|
||||
[patch."https://github.com/servo/media"]
|
||||
servo-media = { git = "https://github.com/ferjm/media", branch = "framerenderer" }
|
||||
|
|
|
@ -2000,7 +2000,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(
|
||||
|
|
|
@ -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};
|
||||
|
@ -368,23 +366,15 @@ impl CanvasFragmentInfo {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MediaFragmentInfo {
|
||||
pub frame_source: Box<HTMLMediaFrameSource>,
|
||||
}
|
||||
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1006,7 +996,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)
|
||||
|
@ -1036,7 +1026,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)
|
||||
|
|
|
@ -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<MediaFrameRenderer>);
|
||||
|
||||
struct MediaFrameRenderer {
|
||||
api: RenderApi,
|
||||
current_frame: Option<(ImageKey, i32, i32)>,
|
||||
old_frame: Option<ImageKey>,
|
||||
very_old_frame: Option<ImageKey>,
|
||||
}
|
||||
|
||||
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<bool>,
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
player: Box<Player>,
|
||||
#[ignore_malloc_size_of = "oops"]
|
||||
frame_renderer: MediaFrameRenderer,
|
||||
#[ignore_malloc_size_of = "Arc"]
|
||||
frame_renderer: Arc<Mutex<MediaFrameRenderer>>,
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-media-networkstate>
|
||||
|
@ -136,7 +204,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()))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,7 +905,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();
|
||||
|
||||
|
@ -1026,12 +1095,9 @@ pub trait LayoutHTMLMediaElementHelpers {
|
|||
impl LayoutHTMLMediaElementHelpers for LayoutDom<HTMLMediaElement> {
|
||||
#[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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<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);
|
||||
}
|
||||
}
|
||||
|
||||
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<HTMLMediaFrameSource> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
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,7 +390,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;
|
||||
|
|
|
@ -172,12 +172,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<HTMLMediaFrameSource>;
|
||||
}
|
||||
|
||||
pub struct HTMLMediaData {
|
||||
pub frame_source: Box<HTMLMediaFrameSource>,
|
||||
pub current_frame: Option<(webrender_api::ImageKey, i32, i32)>,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue