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

@ -250,24 +250,6 @@ impl<'a> FlowConstructor<'a> {
node.set_flow_construction_result(result);
}
/// Builds the `ImageFragmentInfo` for the given image. This is out of line to guide inlining.
fn build_fragment_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>)
-> SpecificFragmentInfo {
match url {
None => SpecificFragmentInfo::Generic,
Some(url) => {
// FIXME(pcwalton): The fact that image fragments store the cache within them makes
// little sense to me.
SpecificFragmentInfo::Image(box ImageFragmentInfo::new(node,
url,
self.layout_context
.shared
.image_cache
.clone()))
}
}
}
/// Builds the fragment for the given block or subclass thereof.
fn build_fragment_for_block(&mut self, node: &ThreadSafeLayoutNode) -> Fragment {
let specific_fragment_info = match node.type_id() {
@ -277,12 +259,17 @@ impl<'a> FlowConstructor<'a> {
}
Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLImageElement))) => {
self.build_fragment_info_for_image(node, node.image_url())
let image_info = box ImageFragmentInfo::new(node,
node.image_url(),
&self.layout_context);
SpecificFragmentInfo::Image(image_info)
}
Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLObjectElement))) => {
let data = node.get_object_data();
self.build_fragment_info_for_image(node, data)
let image_info = box ImageFragmentInfo::new(node,
node.get_object_data(),
&self.layout_context);
SpecificFragmentInfo::Image(image_info)
}
Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLTableElement))) => {
@ -1031,8 +1018,10 @@ impl<'a> FlowConstructor<'a> {
};
let marker_fragment = match node.style().get_list().list_style_image {
Some(ref url) => {
Some(Fragment::new(node,
self.build_fragment_info_for_image(node, Some((*url).clone()))))
let image_info = box ImageFragmentInfo::new(node,
Some((*url).clone()),
&self.layout_context);
Some(Fragment::new(node, SpecificFragmentInfo::Image(image_info)))
}
None => {
match ListStyleTypeContent::from_list_style_type(node.style()