diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-01-31 01:18:41 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-01-31 01:18:41 +0530 |
commit | 46b3eb653579a40632f91497a3d48f1d7fbd40cc (patch) | |
tree | e45b6e5fcc181c7c8eb9647c1ba8f27f857bd86f /components/layout | |
parent | f8bdda499ef8c13f65cbc20215bd36dbc42b6439 (diff) | |
parent | 167ffa7a95ae0068d2b4f900d2207436a1799675 (diff) | |
download | servo-46b3eb653579a40632f91497a3d48f1d7fbd40cc.tar.gz servo-46b3eb653579a40632f91497a3d48f1d7fbd40cc.zip |
Auto merge of #9208 - jmr0:master-img, r=asajeffrey
Use image metadata to lay out images
Fixes #7047.
cc: @jdm
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9208)
<!-- Reviewable:end -->
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/context.rs | 51 | ||||
-rw-r--r-- | components/layout/fragment.rs | 38 |
2 files changed, 75 insertions, 14 deletions
diff --git a/components/layout/context.rs b/components/layout/context.rs index 83f2df1412a..53bb036d09c 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -17,7 +17,7 @@ use gfx_traits::LayerId; use ipc_channel::ipc::{self, IpcSender}; use net_traits::image::base::Image; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread, ImageResponse, ImageState}; -use net_traits::image_cache_thread::{UsePlaceholder}; +use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; use std::cell::{RefCell, RefMut}; use std::collections::HashMap; use std::collections::hash_state::DefaultState; @@ -155,7 +155,7 @@ impl<'a> LayoutContext<'a> { match sync_rx.recv().unwrap().image_response { ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => Some(image), - ImageResponse::None => None, + ImageResponse::None | ImageResponse::MetadataLoaded(_) => None, } } // Not yet requested, async mode - request image from the cache @@ -172,4 +172,51 @@ impl<'a> LayoutContext<'a> { } } } + + pub fn get_or_request_image_or_meta(&self, url: Url, use_placeholder: UsePlaceholder) + -> Option<ImageOrMetadataAvailable> { + // See if the image is already available + let result = self.shared.image_cache_thread.find_image_or_metadata(url.clone(), + use_placeholder); + + match result { + Ok(image_or_metadata) => Some(image_or_metadata), + Err(state) => { + // If we are emitting an output file, then we need to block on + // image load or we risk emitting an output file missing the image. + let is_sync = opts::get().output_file.is_some() || + opts::get().exit_after_load; + + match (state, is_sync) { + // Image failed to load, so just return nothing + (ImageState::LoadError, _) => None, + // Not loaded, test mode - load the image synchronously + (_, true) => { + let (sync_tx, sync_rx) = ipc::channel().unwrap(); + self.shared.image_cache_thread.request_image(url, + ImageCacheChan(sync_tx), + None); + match sync_rx.recv().unwrap().image_response { + ImageResponse::Loaded(image) | + ImageResponse::PlaceholderLoaded(image) => + Some(ImageOrMetadataAvailable::ImageAvailable(image)), + ImageResponse::None | ImageResponse::MetadataLoaded(_) => + None, + } + } + // Not yet requested, async mode - request image or metadata from the cache + (ImageState::NotRequested, false) => { + let sender = self.shared.image_cache_sender.lock().unwrap().clone(); + self.shared.image_cache_thread.request_image_and_metadata(url, sender, None); + None + } + // Image has been requested, is still pending. Return no image + // for this paint loop. When the image loads it will trigger + // a reflow and/or repaint. + (ImageState::Pending, false) => None, + } + } + } + } + } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 9fa563ce20d..45ffac1c659 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -25,8 +25,8 @@ use ipc_channel::ipc::IpcSender; use layout_debug; use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified}; use msg::constellation_msg::PipelineId; -use net_traits::image::base::Image; -use net_traits::image_cache_thread::UsePlaceholder; +use net_traits::image::base::{Image, ImageMetadata}; +use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; use rustc_serialize::{Encodable, Encoder}; use script::dom::htmlcanvaselement::HTMLCanvasData; use std::borrow::ToOwned; @@ -344,6 +344,7 @@ pub struct ImageFragmentInfo { /// The image held within this fragment. pub replaced_image_fragment_info: ReplacedImageFragmentInfo, pub image: Option<Arc<Image>>, + pub metadata: Option<ImageMetadata>, } impl ImageFragmentInfo { @@ -361,26 +362,39 @@ impl ImageFragmentInfo { .map(Au::from_px) } - let image = url.and_then(|url| { - layout_context.get_or_request_image(url, UsePlaceholder::Yes) + let image_or_metadata = url.and_then(|url| { + layout_context.get_or_request_image_or_meta(url, UsePlaceholder::Yes) }); + let (image, metadata) = match image_or_metadata { + Some(ImageOrMetadataAvailable::ImageAvailable(i)) => { + (Some(i.clone()), Some(ImageMetadata { height: i.height, width: i.width } )) + } + Some(ImageOrMetadataAvailable::MetadataAvailable(m)) => { + (None, Some(m)) + } + None => { + (None, None) + } + }; + ImageFragmentInfo { replaced_image_fragment_info: ReplacedImageFragmentInfo::new(node, convert_length(node, &atom!("width")), convert_length(node, &atom!("height"))), image: image, + metadata: metadata, } } /// Returns the original inline-size of the image. pub fn image_inline_size(&mut self) -> Au { - match self.image { - Some(ref image) => { + match self.metadata { + Some(ref metadata) => { Au::from_px(if self.replaced_image_fragment_info.writing_mode_is_vertical { - image.height + metadata.height } else { - image.width + metadata.width } as i32) } None => Au(0) @@ -389,12 +403,12 @@ impl ImageFragmentInfo { /// Returns the original block-size of the image. pub fn image_block_size(&mut self) -> Au { - match self.image { - Some(ref image) => { + match self.metadata { + Some(ref metadata) => { Au::from_px(if self.replaced_image_fragment_info.writing_mode_is_vertical { - image.width + metadata.width } else { - image.height + metadata.height } as i32) } None => Au(0) |