net: Don't load the placeholder image for background images, only for

image fragments.

This also changes the way the placeholder is handled in the image cache
task to decode it up front instead of each time an image fails to load,
both because it was more convenient to implement that way and because
it saves CPU cycles to do so.

This matches the behavior of Gecko and WebKit. It improves the look of
our cached copy of Wikipedia.
This commit is contained in:
Patrick Walton 2015-04-03 14:24:22 -07:00
parent e52197d126
commit 7e7675c1dc
11 changed files with 135 additions and 38 deletions

View file

@ -12,7 +12,7 @@ use std::sync::mpsc::{channel, Sender};
/// image load completes. It is typically used to trigger a reflow
/// and/or repaint.
pub trait ImageResponder : Send {
fn respond(&self, Option<Arc<Image>>);
fn respond(&self, ImageResponse);
}
/// The current state of an image in the cache.
@ -23,6 +23,17 @@ pub enum ImageState {
NotRequested,
}
/// The returned image.
#[derive(Clone)]
pub enum ImageResponse {
/// The requested image was loaded.
Loaded(Arc<Image>),
/// The requested image failed to load, so a placeholder was loaded instead.
PlaceholderLoaded(Arc<Image>),
/// Neither the requested image nor the placeholder could be loaded.
None
}
/// Channel for sending commands to the image cache.
#[derive(Clone)]
pub struct ImageCacheChan(pub Sender<ImageCacheResult>);
@ -31,7 +42,7 @@ pub struct ImageCacheChan(pub Sender<ImageCacheResult>);
/// caller.
pub struct ImageCacheResult {
pub responder: Option<Box<ImageResponder>>,
pub image: Option<Arc<Image>>,
pub image_response: ImageResponse,
}
/// Commands that the image cache understands.
@ -45,12 +56,18 @@ pub enum ImageCacheCommand {
/// TODO(gw): Profile this on some real world sites and see
/// if it's worth caching the results of this locally in each
/// layout / paint task.
GetImageIfAvailable(Url, Sender<Result<Arc<Image>, ImageState>>),
GetImageIfAvailable(Url, UsePlaceholder, Sender<Result<Arc<Image>, ImageState>>),
/// Clients must wait for a response before shutting down the ResourceTask
Exit(Sender<()>),
}
#[derive(Copy, Clone, PartialEq)]
pub enum UsePlaceholder {
No,
Yes,
}
/// The client side of the image cache task. This can be safely cloned
/// and passed to different tasks.
#[derive(Clone)]
@ -78,9 +95,10 @@ impl ImageCacheTask {
}
/// Get the current state of an image. See ImageCacheCommand::GetImageIfAvailable.
pub fn get_image_if_available(&self, url: Url) -> Result<Arc<Image>, ImageState> {
pub fn get_image_if_available(&self, url: Url, use_placeholder: UsePlaceholder)
-> Result<Arc<Image>, ImageState> {
let (sender, receiver) = channel();
let msg = ImageCacheCommand::GetImageIfAvailable(url, sender);
let msg = ImageCacheCommand::GetImageIfAvailable(url, use_placeholder, sender);
self.chan.send(msg).unwrap();
receiver.recv().unwrap()
}
@ -92,3 +110,4 @@ impl ImageCacheTask {
response_port.recv().unwrap();
}
}