mirror of
https://github.com/servo/servo.git
synced 2025-08-09 15:35:34 +01:00
Avoid dropping image requests on the ground from non-script-initiated reflow.
This commit is contained in:
parent
541ecbfe21
commit
980eb5ac33
6 changed files with 96 additions and 47 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue