diff options
author | Glenn Watson <gw@intuitionlibrary.com> | 2016-02-18 07:57:31 +1000 |
---|---|---|
committer | Glenn Watson <gw@intuitionlibrary.com> | 2016-02-18 10:35:29 +1000 |
commit | c0531c312fdb0783e4d121b4c2d7f15d4f5cdc1f (patch) | |
tree | ced94496eb3f3b4149f1c2d3b0b02422bb3b5471 /components/net/image_cache_thread.rs | |
parent | f7f0eea47035f4316d09db26315bf8ebb72637c9 (diff) | |
download | servo-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.rs | 63 |
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(); |