aboutsummaryrefslogtreecommitdiffstats
path: root/components/net/image_cache_thread.rs
diff options
context:
space:
mode:
authorGlenn Watson <gw@intuitionlibrary.com>2016-02-18 07:57:31 +1000
committerGlenn Watson <gw@intuitionlibrary.com>2016-02-18 10:35:29 +1000
commitc0531c312fdb0783e4d121b4c2d7f15d4f5cdc1f (patch)
treeced94496eb3f3b4149f1c2d3b0b02422bb3b5471 /components/net/image_cache_thread.rs
parentf7f0eea47035f4316d09db26315bf8ebb72637c9 (diff)
downloadservo-c0531c312fdb0783e4d121b4c2d7f15d4f5cdc1f.tar.gz
servo-c0531c312fdb0783e4d121b4c2d7f15d4f5cdc1f.zip
Add WebRender integration to Servo.
WebRender is an experimental GPU accelerated rendering backend for Servo. The WebRender backend can be specified by running Servo with the -w option (otherwise the default rendering backend will be used). WebRender has many bugs, and missing features - but it is usable to browse most websites - please report any WebRender specific rendering bugs you encounter!
Diffstat (limited to 'components/net/image_cache_thread.rs')
-rw-r--r--components/net/image_cache_thread.rs63
1 files changed, 55 insertions, 8 deletions
diff --git a/components/net/image_cache_thread.rs b/components/net/image_cache_thread.rs
index e7d960068e0..22797bda379 100644
--- a/components/net/image_cache_thread.rs
+++ b/components/net/image_cache_thread.rs
@@ -5,7 +5,7 @@
use immeta::load_from_buf;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
-use net_traits::image::base::{Image, ImageMetadata, load_from_memory};
+use net_traits::image::base::{Image, ImageMetadata, load_from_memory, PixelFormat};
use net_traits::image_cache_thread::ImageResponder;
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState};
use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder};
@@ -23,6 +23,7 @@ use url::Url;
use util::resource_files::resources_dir_path;
use util::thread::spawn_named;
use util::threadpool::ThreadPool;
+use webrender_traits;
///
/// TODO(gw): Remaining work on image cache:
@@ -51,6 +52,12 @@ struct PendingLoad {
url: Arc<Url>
}
+enum LoadResult {
+ Loaded(Image),
+ PlaceholderLoaded(Arc<Image>),
+ None
+}
+
impl PendingLoad {
fn new(url: Arc<Url>) -> PendingLoad {
PendingLoad {
@@ -250,6 +257,9 @@ struct ImageCache {
// The placeholder image used when an image fails to load
placeholder_image: Option<Arc<Image>>,
+
+ // Webrender API instance, if enabled.
+ webrender_api: Option<webrender_traits::RenderApi>,
}
/// Message that the decoder worker threads send to main image cache thread.
@@ -265,6 +275,16 @@ enum SelectResult {
Decoder(DecoderMsg),
}
+fn convert_format(format: PixelFormat) -> webrender_traits::ImageFormat {
+ match format {
+ PixelFormat::K8 | PixelFormat::KA8 => {
+ panic!("Not support by webrender yet");
+ }
+ PixelFormat::RGB8 => webrender_traits::ImageFormat::RGB8,
+ PixelFormat::RGBA8 => webrender_traits::ImageFormat::RGBA8,
+ }
+}
+
impl ImageCache {
fn run(&mut self) {
let mut exit_sender: Option<IpcSender<()>> = None;
@@ -381,10 +401,10 @@ impl ImageCache {
Err(_) => {
match self.placeholder_image.clone() {
Some(placeholder_image) => {
- self.complete_load(msg.key, ImageResponse::PlaceholderLoaded(
+ self.complete_load(msg.key, LoadResult::PlaceholderLoaded(
placeholder_image))
}
- None => self.complete_load(msg.key, ImageResponse::None),
+ None => self.complete_load(msg.key, LoadResult::None),
}
}
}
@@ -395,16 +415,34 @@ impl ImageCache {
// Handle a message from one of the decoder worker threads
fn handle_decoder(&mut self, msg: DecoderMsg) {
let image = match msg.image {
- None => ImageResponse::None,
- Some(image) => ImageResponse::Loaded(Arc::new(image)),
+ None => LoadResult::None,
+ Some(image) => LoadResult::Loaded(image),
};
self.complete_load(msg.key, image);
}
// Change state of a url from pending -> loaded.
- fn complete_load(&mut self, key: LoadKey, image_response: ImageResponse) {
+ fn complete_load(&mut self, key: LoadKey, mut load_result: LoadResult) {
let pending_load = self.pending_loads.remove(&key).unwrap();
+ if let Some(ref webrender_api) = self.webrender_api {
+ match load_result {
+ LoadResult::Loaded(ref mut image) => {
+ let format = convert_format(image.format);
+ let mut bytes = Vec::new();
+ bytes.extend_from_slice(&*image.bytes);
+ image.id = Some(webrender_api.add_image(image.width, image.height, format, bytes));
+ }
+ LoadResult::PlaceholderLoaded(..) | LoadResult::None => {}
+ }
+ }
+
+ let image_response = match load_result {
+ LoadResult::Loaded(image) => ImageResponse::Loaded(Arc::new(image)),
+ LoadResult::PlaceholderLoaded(image) => ImageResponse::PlaceholderLoaded(image),
+ LoadResult::None => ImageResponse::None,
+ };
+
let completed_load = CompletedLoad::new(image_response.clone());
self.completed_loads.insert(pending_load.url, completed_load);
@@ -510,7 +548,8 @@ impl ImageCache {
}
/// Create a new image cache.
-pub fn new_image_cache_thread(resource_thread: ResourceThread) -> ImageCacheThread {
+pub fn new_image_cache_thread(resource_thread: ResourceThread,
+ webrender_api: Option<webrender_traits::RenderApi>) -> ImageCacheThread {
let (ipc_command_sender, ipc_command_receiver) = ipc::channel().unwrap();
let (progress_sender, progress_receiver) = channel();
let (decoder_sender, decoder_receiver) = channel();
@@ -526,7 +565,14 @@ pub fn new_image_cache_thread(resource_thread: ResourceThread) -> ImageCacheThre
file.read_to_end(&mut image_data)
});
let placeholder_image = result.ok().map(|_| {
- Arc::new(load_from_memory(&image_data).unwrap())
+ let mut image = load_from_memory(&image_data).unwrap();
+ if let Some(ref webrender_api) = webrender_api {
+ let format = convert_format(image.format);
+ let mut bytes = Vec::new();
+ bytes.extend_from_slice(&*image.bytes);
+ image.id = Some(webrender_api.add_image(image.width, image.height, format, bytes));
+ }
+ Arc::new(image)
});
// Ask the router to proxy messages received over IPC to us.
@@ -543,6 +589,7 @@ pub fn new_image_cache_thread(resource_thread: ResourceThread) -> ImageCacheThre
completed_loads: HashMap::new(),
resource_thread: resource_thread,
placeholder_image: placeholder_image,
+ webrender_api: webrender_api,
};
cache.run();