Skip to content

Commit

Permalink
feat: patch from @jdm for video layout sizes (servo#31416)
Browse files Browse the repository at this point in the history
  • Loading branch information
eerii committed Mar 8, 2024
1 parent 0f4522c commit 2c30c42
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 55 deletions.
2 changes: 1 addition & 1 deletion components/layout/display_list/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1897,7 +1897,7 @@ impl Fragment {
}
},
SpecificFragmentInfo::Media(ref fragment_info) => {
if let Some((ref image_key, _, _)) = fragment_info.current_frame {
if let Some(ref image_key) = fragment_info.current_frame {
let base = create_base_display_item(state);
state.add_image_item(
base,
Expand Down
22 changes: 7 additions & 15 deletions components/layout/fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,17 @@ impl CanvasFragmentInfo {

#[derive(Clone)]
pub struct MediaFragmentInfo {
pub current_frame: Option<(webrender_api::ImageKey, i32, i32)>,
pub current_frame: Option<webrender_api::ImageKey>,
pub width: i32,
pub height: i32,
}

impl MediaFragmentInfo {
pub fn new(data: HTMLMediaData) -> MediaFragmentInfo {
MediaFragmentInfo {
current_frame: data.current_frame,
width: data.width,
height: data.height,
}
}
}
Expand Down Expand Up @@ -1041,13 +1045,7 @@ impl Fragment {
Au(0)
}
},
SpecificFragmentInfo::Media(ref info) => {
if let Some((_, width, _)) = info.current_frame {
Au::from_px(width)
} else {
Au(0)
}
},
SpecificFragmentInfo::Media(ref info) => Au::from_px(info.width),
SpecificFragmentInfo::Canvas(ref info) => info.dom_width,
SpecificFragmentInfo::Svg(ref info) => info.dom_width,
// Note: Currently for replaced element with no intrinsic size,
Expand All @@ -1071,13 +1069,7 @@ impl Fragment {
Au(0)
}
},
SpecificFragmentInfo::Media(ref info) => {
if let Some((_, _, height)) = info.current_frame {
Au::from_px(height)
} else {
Au(0)
}
},
SpecificFragmentInfo::Media(ref info) => Au::from_px(info.height),
SpecificFragmentInfo::Canvas(ref info) => info.dom_height,
SpecificFragmentInfo::Svg(ref info) => info.dom_height,
SpecificFragmentInfo::Iframe(_) => Au::from_px(DEFAULT_REPLACED_HEIGHT),
Expand Down
22 changes: 14 additions & 8 deletions components/layout_2020/display_list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,20 @@ impl Fragment {
.translate(containing_block.origin.to_vector());

let common = builder.common_properties(rect.to_webrender(), &i.style);
builder.wr().push_image(
&common,
rect.to_webrender(),
image_rendering(i.style.get_inherited_box().image_rendering),
wr::AlphaType::PremultipliedAlpha,
i.image_key,
wr::ColorF::WHITE,
);
if let Some(image_key) = i.image_key {
builder.wr().push_image(
&common,
rect.to_webrender(),
image_rendering(i.style.get_inherited_box().image_rendering),
wr::AlphaType::PremultipliedAlpha,
image_key,
wr::ColorF::WHITE,
);
} else {
builder
.wr()
.push_rect(&common, rect.to_webrender(), wr::ColorF::WHITE);
}
},
Visibility::Hidden => (),
Visibility::Collapse => (),
Expand Down
10 changes: 5 additions & 5 deletions components/layout_2020/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub(crate) trait NodeExt<'dom>: 'dom + LayoutNode<'dom> {
fn as_image(self) -> Option<(Option<Arc<NetImage>>, PhysicalSize<f64>)>;
fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize<f64>)>;
fn as_iframe(self) -> Option<(PipelineId, BrowsingContextId)>;
fn as_video(self) -> Option<(webrender_api::ImageKey, PhysicalSize<f64>)>;
fn as_video(self) -> Option<(Option<webrender_api::ImageKey>, PhysicalSize<f64>)>;
fn style(self, context: &LayoutContext) -> ServoArc<ComputedValues>;

fn get_style_and_layout_data(self) -> Option<StyleAndLayoutData<'dom>>;
Expand Down Expand Up @@ -126,11 +126,11 @@ where
Some((resource, PhysicalSize::new(width, height)))
}

fn as_video(self) -> Option<(webrender_api::ImageKey, PhysicalSize<f64>)> {
fn as_video(self) -> Option<(Option<webrender_api::ImageKey>, PhysicalSize<f64>)> {
let node = self.to_threadsafe();
let frame_data = node.media_data()?.current_frame?;
let (width, height) = (frame_data.1 as f64, frame_data.2 as f64);
Some((frame_data.0, PhysicalSize::new(width, height)))
let media_data = node.media_data()?;
let (width, height) = (media_data.width as f64, media_data.height as f64);
Some((media_data.current_frame, PhysicalSize::new(width, height)))
}

fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize<f64>)> {
Expand Down
2 changes: 1 addition & 1 deletion components/layout_2020/fragment_tree/fragment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub(crate) struct ImageFragment {
pub style: ServoArc<ComputedValues>,
pub rect: LogicalRect<Length>,
#[serde(skip_serializing)]
pub image_key: ImageKey,
pub image_key: Option<ImageKey>,
}

#[derive(Serialize)]
Expand Down
10 changes: 5 additions & 5 deletions components/layout_2020/replaced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub(crate) enum ReplacedContentKind {
Image(Option<Arc<Image>>),
IFrame(IFrameInfo),
Canvas(CanvasInfo),
Video(VideoInfo),
Video(Option<VideoInfo>),
}

impl ReplacedContent {
Expand All @@ -153,7 +153,7 @@ impl ReplacedContent {
)
} else if let Some((image_key, intrinsic_size_in_dots)) = element.as_video() {
(
ReplacedContentKind::Video(VideoInfo { image_key }),
ReplacedContentKind::Video(image_key.map(|key| VideoInfo { image_key: key })),
Some(intrinsic_size_in_dots),
)
} else {
Expand Down Expand Up @@ -269,7 +269,7 @@ impl ReplacedContent {
start_corner: LogicalVec2::zero(),
size: size.into(),
},
image_key,
image_key: Some(image_key),
})
})
.into_iter()
Expand All @@ -281,7 +281,7 @@ impl ReplacedContent {
start_corner: LogicalVec2::zero(),
size: size.into(),
},
image_key: video.image_key,
image_key: video.as_ref().map(|video| video.image_key),
})],
ReplacedContentKind::IFrame(iframe) => {
vec![Fragment::IFrame(IFrameFragment {
Expand Down Expand Up @@ -327,7 +327,7 @@ impl ReplacedContent {
start_corner: LogicalVec2::zero(),
size: size.into(),
},
image_key,
image_key: Some(image_key),
})]
},
}
Expand Down
21 changes: 5 additions & 16 deletions components/script/dom/htmlmediaelement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use net_traits::{
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, Metadata, NetworkError,
ResourceFetchTiming, ResourceTimingType,
};
use script_layout_interface::HTMLMediaData;
use script_traits::{ImageUpdate, WebrenderIpcSender};
use servo_config::pref;
use servo_media::player::audio::AudioRenderer;
Expand Down Expand Up @@ -66,7 +65,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::blob::Blob;
use crate::dom::document::Document;
Expand Down Expand Up @@ -1934,6 +1933,10 @@ impl HTMLMediaElement {
}
}

pub fn get_current_frame_data(&self) -> Option<(ImageKey, i32, i32)> {
self.video_renderer.lock().unwrap().current_frame.clone()
}

/// By default the audio is rendered through the audio sink automatically
/// selected by the servo-media Player instance. However, in some cases, like
/// the WebAudio MediaElementAudioSourceNode, we need to set a custom audio
Expand Down Expand Up @@ -2463,20 +2466,6 @@ impl VirtualMethods for HTMLMediaElement {
}
}

pub trait LayoutHTMLMediaElementHelpers {
fn data(self) -> HTMLMediaData;
}

impl LayoutHTMLMediaElementHelpers for LayoutDom<'_, HTMLMediaElement> {
#[allow(unsafe_code)]
fn data(self) -> HTMLMediaData {
let media = unsafe { &*self.unsafe_get() };
HTMLMediaData {
current_frame: media.video_renderer.lock().unwrap().current_frame.clone(),
}
}
}

#[derive(JSTraceable, MallocSizeOf)]
pub enum MediaElementMicrotask {
ResourceSelectionTask {
Expand Down
23 changes: 22 additions & 1 deletion components/script/dom/htmlvideoelement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use net_traits::{
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, FetchResponseMsg,
NetworkError, ResourceFetchTiming, ResourceTimingType,
};
use script_layout_interface::HTMLMediaData;
use servo_media::player::video::VideoFrame;
use servo_url::ServoUrl;

Expand All @@ -30,7 +31,7 @@ use crate::dom::bindings::codegen::Bindings::HTMLVideoElementBinding::HTMLVideoE
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element};
Expand Down Expand Up @@ -418,3 +419,23 @@ impl PosterFrameFetchContext {
}
}
}

pub trait LayoutHTMLVideoElementHelpers {
fn data(self) -> HTMLMediaData;
}

impl LayoutHTMLVideoElementHelpers for LayoutDom<'_, HTMLVideoElement> {
#[allow(unsafe_code)]
fn data(self) -> HTMLMediaData {
let video = unsafe { &*self.unsafe_get() };
let current_frame = video.htmlmediaelement.get_current_frame_data();
let current_frame = current_frame.as_ref();
let width = video.get_video_width() as i32;
let height = video.get_video_height() as i32;
HTMLMediaData {
current_frame: current_frame.map(|frame| frame.0),
width: current_frame.map_or(width, |frame| frame.1),
height: current_frame.map_or(height, |frame| frame.2),
}
}
}
4 changes: 2 additions & 2 deletions components/script/dom/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ use crate::dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMe
use crate::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
use crate::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use crate::dom::htmllinkelement::HTMLLinkElement;
use crate::dom::htmlmediaelement::{HTMLMediaElement, LayoutHTMLMediaElementHelpers};
use crate::dom::htmlstyleelement::HTMLStyleElement;
use crate::dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers};
use crate::dom::htmlvideoelement::{HTMLVideoElement, LayoutHTMLVideoElementHelpers};
use crate::dom::mouseevent::MouseEvent;
use crate::dom::mutationobserver::{Mutation, MutationObserver, RegisteredObserver};
use crate::dom::nodelist::NodeList;
Expand Down Expand Up @@ -1552,7 +1552,7 @@ impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> {
}

fn media_data(self) -> Option<HTMLMediaData> {
self.downcast::<HTMLMediaElement>()
self.downcast::<HTMLVideoElement>()
.map(|media| media.data())
}

Expand Down
4 changes: 3 additions & 1 deletion components/shared/script_layout/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ pub struct PendingImage {
}

pub struct HTMLMediaData {
pub current_frame: Option<(ImageKey, i32, i32)>,
pub current_frame: Option<ImageKey>,
pub width: i32,
pub height: i32,
}

pub struct LayoutConfig {
Expand Down

0 comments on commit 2c30c42

Please sign in to comment.