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:
Glenn Watson 2015-04-20 13:34:26 +10:00
parent e278e5b9a2
commit d8aef7208e
33 changed files with 2785 additions and 1679 deletions

View file

@ -4,6 +4,7 @@
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
use dom::bindings::codegen::Bindings::HTMLObjectElementBinding;
use dom::bindings::codegen::Bindings::HTMLObjectElementBinding::HTMLObjectElementMethods;
@ -20,15 +21,15 @@ use dom::node::{Node, NodeTypeId, NodeHelpers, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use net_traits::image_cache_task::{self, ImageCacheTask};
use net_traits::image::base::Image;
use util::str::DOMString;
use std::sync::Arc;
use string_cache::Atom;
use url::Url;
#[dom_struct]
pub struct HTMLObjectElement {
htmlelement: HTMLElement,
image: DOMRefCell<Option<Arc<Image>>>,
}
impl HTMLObjectElementDerived for EventTarget {
@ -41,6 +42,7 @@ impl HTMLObjectElement {
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLObjectElement {
HTMLObjectElement {
htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLObjectElement, localName, prefix, document),
image: DOMRefCell::new(None),
}
}
@ -52,24 +54,20 @@ impl HTMLObjectElement {
}
trait ProcessDataURL {
fn process_data_url(&self, image_cache: ImageCacheTask);
fn process_data_url(&self);
}
impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
// Makes the local `data` member match the status of the `data` attribute and starts
/// prefetching the image. This method must be called after `data` is changed.
fn process_data_url(&self, image_cache: ImageCacheTask) {
fn process_data_url(&self) {
let elem: JSRef<Element> = ElementCast::from_ref(*self);
// TODO: support other values
match (elem.get_attribute(&ns!(""), &atom!("type")).map(|x| x.root().r().Value()),
elem.get_attribute(&ns!(""), &atom!("data")).map(|x| x.root().r().Value())) {
(None, Some(uri)) => {
if is_image_data(uri.as_slice()) {
let data_url = Url::parse(uri.as_slice()).unwrap();
// Issue #84
image_cache.send(image_cache_task::Msg::Prefetch(data_url));
}
(None, Some(_uri)) => {
// TODO(gw): Prefetch the image here.
}
_ => { }
}
@ -107,8 +105,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
match attr.local_name() {
&atom!("data") => {
let window = window_from_node(*self).root();
self.process_data_url(window.r().image_cache_task().clone());
self.process_data_url();
},
_ => ()
}