diff --git a/src/servo/resource/image_cache_task.rs b/src/servo/resource/image_cache_task.rs index 1363c48c2b6..9a83a3dccff 100644 --- a/src/servo/resource/image_cache_task.rs +++ b/src/servo/resource/image_cache_task.rs @@ -569,7 +569,7 @@ fn should_fail_if_requesting_image_before_requesting_decode() { image_cache_task.send(Prefetch(copy url)); // no decode message - let (chan, port) = stream(); + let (chan, _port) = stream(); image_cache_task.send(GetImage(url, chan)); image_cache_task.exit(); diff --git a/src/servo/resource/local_image_cache.rs b/src/servo/resource/local_image_cache.rs new file mode 100644 index 00000000000..6fbfb34e957 --- /dev/null +++ b/src/servo/resource/local_image_cache.rs @@ -0,0 +1,73 @@ +/*! +An adapter for ImageCacheTask that does local caching to avoid +extra message traffic, it also avoids waiting on the same image +multiple times and thus triggering reflows multiple times. +*/ + +use std::net::url::Url; +use pipes::{Port, Chan, stream}; +use image_cache_task::{ImageCacheTask, ImageResponseMsg, Prefetch, Decode, GetImage, WaitForImage}; + +pub fn LocalImageCache( + image_cache_task: ImageCacheTask, + on_image_available: ~fn(ImageResponseMsg) +) -> LocalImageCache { + LocalImageCache { + round_number: 0, + image_cache_task: move image_cache_task, + on_image_available: on_image_available + } +} + +pub struct LocalImageCache { + priv mut round_number: uint, + priv image_cache_task: ImageCacheTask, + priv on_image_available: ~fn(ImageResponseMsg) +} + +pub impl LocalImageCache { + /// The local cache will only do a single remote request for a given + /// URL in each 'round'. Layout should call this each time it begins + fn next_round() { + self.round_number += 1; + } + + fn prefetch(url: &Url) { + self.image_cache_task.send(Prefetch(copy *url)); + } + + fn decode(url: &Url) { + self.image_cache_task.send(Decode(copy *url)); + } + + // FIXME: Should return a Future + fn get_image(url: &Url) -> Port { + let (response_chan, response_port) = pipes::stream(); + self.image_cache_task.send(image_cache_task::GetImage(copy *url, response_chan)); + + let response = response_port.recv(); + match response { + image_cache_task::ImageNotReady => { + // Need to reflow when the image is available + // FIXME: Instead we should be just passing a Future + // to the caller, then to the display list. Finally, + // the compositor should be resonsible for waiting + // on the image to load and triggering layout + let image_cache_task = self.image_cache_task.clone(); + let on_image_available = copy self.on_image_available; + let url = copy *url; + do task::spawn |move url, move on_image_available| { + let (response_chan, response_port) = pipes::stream(); + image_cache_task.send(image_cache_task::WaitForImage(copy url, response_chan)); + on_image_available(response_port.recv()); + } + } + _ => () + } + + let (chan, port) = pipes::stream(); + chan.send(response); + return port; + } +} + diff --git a/src/servo/servo.rc b/src/servo/servo.rc index d147accf9a6..48534322e69 100755 --- a/src/servo/servo.rc +++ b/src/servo/servo.rc @@ -117,6 +117,7 @@ pub mod resource { pub mod file_loader; pub mod http_loader; pub mod image_cache_task; + pub mod local_image_cache; } pub mod util {