mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Refactored image cache task - details below.
* Simpler image cache API for clients to use. * Significantly fewer threads. * One thread for image cache task (multiplexes commands, decoder threads and async resource requests). * 4 threads for decoder worker tasks. * Removed ReflowEvent hacks in script and layout tasks. * Image elements pass a Trusted<T> to image cache, which is used to dirty nodes via script task. Previous use of Untrusted addresses was unsafe. * Image requests such as background-image on layout / paint threads trigger repaint only rather than full reflow. * Add reflow batching for when multiple images load quickly. * Reduces the number of paints loading wikipedia from ~95 to ~35. * Reasonably simple to add proper prefetch support in a follow up PR. * Async loaded images always construct Image fragments now, instead of generic. * Image fragments support the image not being present. * Simpler implementation of synchronous image loading for reftests. * Removed image holder. * image.onload support. * image NaturalWidth and NaturalHeight support. * Updated WPT expectations.
This commit is contained in:
parent
e278e5b9a2
commit
d8aef7208e
33 changed files with 2785 additions and 1679 deletions
|
@ -13,17 +13,18 @@ use gfx::display_list::OpaqueNode;
|
|||
use gfx::font_cache_task::FontCacheTask;
|
||||
use gfx::font_context::FontContext;
|
||||
use msg::constellation_msg::ConstellationChan;
|
||||
use net_traits::image::base::Image;
|
||||
use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageState};
|
||||
use script::layout_interface::{Animation, LayoutChan};
|
||||
use script_traits::UntrustedNodeAddress;
|
||||
use net_traits::local_image_cache::LocalImageCache;
|
||||
use std::boxed;
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::{channel, Sender};
|
||||
use style::selector_matching::Stylist;
|
||||
use url::Url;
|
||||
use util::geometry::Au;
|
||||
use util::opts;
|
||||
|
||||
struct LocalLayoutContext {
|
||||
font_context: FontContext,
|
||||
|
@ -55,8 +56,11 @@ fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext)
|
|||
|
||||
/// Layout information shared among all workers. This must be thread-safe.
|
||||
pub struct SharedLayoutContext {
|
||||
/// The local image cache.
|
||||
pub image_cache: Arc<Mutex<LocalImageCache<UntrustedNodeAddress>>>,
|
||||
/// The shared image cache task.
|
||||
pub image_cache_task: ImageCacheTask,
|
||||
|
||||
/// A channel for the image cache to send responses to.
|
||||
pub image_cache_sender: ImageCacheChan,
|
||||
|
||||
/// The current screen size.
|
||||
pub screen_size: Size2D<Au>,
|
||||
|
@ -139,4 +143,42 @@ impl<'a> LayoutContext<'a> {
|
|||
&mut cached_context.style_sharing_candidate_cache
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_or_request_image(&self, url: Url) -> Option<Arc<Image>> {
|
||||
// See if the image is already available
|
||||
let result = self.shared.image_cache_task.get_image_if_available(url.clone());
|
||||
|
||||
match result {
|
||||
Ok(image) => Some(image),
|
||||
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();
|
||||
|
||||
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) = channel();
|
||||
self.shared.image_cache_task.request_image(url,
|
||||
ImageCacheChan(sync_tx),
|
||||
None);
|
||||
sync_rx.recv().unwrap().image
|
||||
}
|
||||
// Not yet requested, async mode - request image from the cache
|
||||
(ImageState::NotRequested, false) => {
|
||||
self.shared.image_cache_task.request_image(url,
|
||||
self.shared.image_cache_sender.clone(),
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue