aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/context.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2016-12-29 14:07:57 -0500
committerJosh Matthews <josh@joshmatthews.net>2017-02-22 14:19:35 -0500
commit980eb5ac33b16d7310d0b5b20d8c3f94b4b2c241 (patch)
treed5da2086eea069c55be666d94985cd3a4e9f574a /components/layout/context.rs
parent541ecbfe21d0e79d1eb8b6f197325adc5065b684 (diff)
downloadservo-980eb5ac33b16d7310d0b5b20d8c3f94b4b2c241.tar.gz
servo-980eb5ac33b16d7310d0b5b20d8c3f94b4b2c241.zip
Avoid dropping image requests on the ground from non-script-initiated reflow.
Diffstat (limited to 'components/layout/context.rs')
-rw-r--r--components/layout/context.rs39
1 files changed, 28 insertions, 11 deletions
diff --git a/components/layout/context.rs b/components/layout/context.rs
index 13029dd80bf..1dff9f6ea5e 100644
--- a/components/layout/context.rs
+++ b/components/layout/context.rs
@@ -9,7 +9,7 @@ use gfx::display_list::{WebRenderImageInfo, OpaqueNode};
use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context::FontContext;
use heapsize::HeapSizeOf;
-use net_traits::image_cache_thread::{ImageCacheThread, ImageState};
+use net_traits::image_cache_thread::{ImageCacheThread, ImageState, CanRequestImages};
use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
use opaque_node::OpaqueNodeMethods;
use parking_lot::RwLock;
@@ -92,13 +92,15 @@ pub struct LayoutContext {
/// A list of in-progress image loads to be shared with the script thread.
/// A None value means that this layout was not initiated by the script thread.
- pub pending_images: Mutex<Vec<PendingImage>>
+ pub pending_images: Option<Mutex<Vec<PendingImage>>>
}
impl Drop for LayoutContext {
fn drop(&mut self) {
if !thread::panicking() {
- assert!(self.pending_images.lock().unwrap().is_empty());
+ if let Some(ref pending_images) = self.pending_images {
+ assert!(pending_images.lock().unwrap().is_empty());
+ }
}
}
}
@@ -114,10 +116,20 @@ impl LayoutContext {
url: ServoUrl,
use_placeholder: UsePlaceholder)
-> Option<ImageOrMetadataAvailable> {
+ //XXXjdm For cases where we do not request an image, we still need to
+ // ensure the node gets another script-initiated reflow or it
+ // won't be requested at all.
+ let can_request = if self.pending_images.is_some() {
+ CanRequestImages::Yes
+ } else {
+ CanRequestImages::No
+ };
+
// See if the image is already available
let result = self.image_cache_thread.lock().unwrap()
.find_image_or_metadata(url.clone(),
- use_placeholder);
+ use_placeholder,
+ can_request);
match result {
Ok(image_or_metadata) => Some(image_or_metadata),
// Image failed to load, so just return nothing
@@ -129,18 +141,23 @@ impl LayoutContext {
node: node.to_untrusted_node_address(),
id: id,
};
- self.pending_images.lock().unwrap().push(image);
+ self.pending_images.as_ref().unwrap().lock().unwrap().push(image);
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.
Err(ImageState::Pending(id)) => {
- let image = PendingImage {
- state: PendingImageState::PendingResponse,
- node: node.to_untrusted_node_address(),
- id: id,
- };
- self.pending_images.lock().unwrap().push(image);
+ //XXXjdm if self.pending_images is not available, we should make sure that
+ // this node gets marked dirty again so it gets a script-initiated
+ // reflow that deals with this properly.
+ if let Some(ref pending_images) = self.pending_images {
+ let image = PendingImage {
+ state: PendingImageState::PendingResponse,
+ node: node.to_untrusted_node_address(),
+ id: id,
+ };
+ pending_images.lock().unwrap().push(image);
+ }
None
}
}