aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-01-31 01:18:41 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2016-01-31 01:18:41 +0530
commit46b3eb653579a40632f91497a3d48f1d7fbd40cc (patch)
treee45b6e5fcc181c7c8eb9647c1ba8f27f857bd86f /components/layout
parentf8bdda499ef8c13f65cbc20215bd36dbc42b6439 (diff)
parent167ffa7a95ae0068d2b4f900d2207436a1799675 (diff)
downloadservo-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.rs51
-rw-r--r--components/layout/fragment.rs38
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)