New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove network requests from image cache thread #14962
Conversation
Heads up! This PR modifies the following files:
|
63e9dbc
to
15905b2
Compare
☔ The latest upstream changes (presumably #13972) made this pull request unmergeable. Please resolve the merge conflicts. |
15905b2
to
f2cda69
Compare
@bors-servo: try |
Remove network requests from image cache thread The design of initiating network requests from the image cache thread was simple, but it makes it difficult to implement image loading that conforms to the HTML specification. These changes make the implementation of HTMLImageElement responsible for network requests for `<img>` elements, and CSS-based images (background-image, bullets, etc.) are requested by the script thread to ensure that the layout thread does not attempt to retain unsafe pointers to DOM nodes during asynchronous operations. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #7708 - [X] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14962) <!-- Reviewable:end -->
💔 Test failed - linux-rel-wpt |
Gah, the gl-teximage.html failures are back again :( |
☔ The latest upstream changes (presumably #14291) made this pull request unmergeable. Please resolve the merge conflicts. |
I'm going to pursue a different design after discussion with @jrmuizel. |
f2cda69
to
e5f95a4
Compare
I changed my mind - the changes I discussed with @jrmuizel are more or less orthogonal to these changes, and this PR is already complex enough as it is. |
@Ms2ger Since nobody volunteered in response to my mailing list post, I choose you to review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments from looking at the first commit.
/// Interface to the font cache thread. | ||
pub font_cache_thread: Mutex<FontCacheThread>, | ||
|
||
/// A cache of WebRender image info. | ||
pub webrender_image_cache: Arc<RwLock<HashMap<(ServoUrl, UsePlaceholder), | ||
WebRenderImageInfo, | ||
BuildHasherDefault<FnvHasher>>>>, | ||
|
||
/// A list of in-progress image loads to be shared with the script thread. | ||
/// A None value means that this layout was not initiated by the script thread. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're only wrapping this in Option
later on.
components/layout/context.rs
Outdated
|
||
impl Drop for SharedLayoutContext { | ||
fn drop(&mut self) { | ||
assert!(self.pending_images.lock().unwrap().is_empty()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's gate this on panicking
?
components/layout/context.rs
Outdated
@@ -203,19 +171,31 @@ impl SharedLayoutContext { | |||
// Image failed to load, so just return nothing | |||
Err(ImageState::LoadError) => None, | |||
// Not yet requested, async mode - request image or metadata from the cache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove references to "async mode"
components/net/image_cache_thread.rs
Outdated
CompletedLoad { | ||
image_response: image_response, | ||
id: id, | ||
} | ||
} | ||
} | ||
|
||
/// Stores information to notify a client when the state | ||
/// of an image changes. | ||
struct ImageListener { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This struct should be removed, either in this PR or a followup
use servo_url::ServoUrl; | ||
|
||
pub fn request_image_from_cache(window: &Window, url: ServoUrl) -> ImageResponse { | ||
let image_cache = window.image_cache_thread(); | ||
panic!() | ||
/*let image_cache = window.image_cache_thread(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gets addressed in a later commit.
|
||
let context = Arc::new(Mutex::new(ImageContext { | ||
elem: trusted_node, | ||
data: vec!(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vec![]
let id = image.id; | ||
let js_runtime = self.js_runtime.borrow(); | ||
let js_runtime = js_runtime.as_ref().unwrap(); | ||
let node = from_untrusted_node_address(js_runtime.rt(), image.node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we know these are still valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script is paused during layout, and this executes immediately after the script thread resumes.
components/script/dom/window.rs
Outdated
|
||
let mut images = self.pending_layout_images.borrow_mut(); | ||
let nodes = images.entry(id).or_insert(vec![]); | ||
if nodes.iter().find(|n| **n == JS::from_ref(&*node)).is_none() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why create a JS
here?
components/script/dom/window.rs
Outdated
let window = document.window(); | ||
let image_cache = window.image_cache_thread(); | ||
image_cache.store_complete_image_bytes(self.id, self.data.clone()); | ||
document.finish_load(LoadType::Image(self.url.clone())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do layout-only images block onload?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That gets addressed in a later commit.
components/script/dom/window.rs
Outdated
})); | ||
|
||
let document = document_from_node(node); | ||
let window = window_from_node(node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document.window()
@@ -16,12 +16,17 @@ | |||
} | |||
} | |||
|
|||
var t = async_test(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap everything in the async_test
, please.
components/net/image_cache_thread.rs
Outdated
@@ -495,51 +479,76 @@ impl ImageCache { | |||
|
|||
/// Return a completed image if it exists, or None if there is no complete load | |||
/// of the complete load is not fully decoded or is unavailable. | |||
fn get_completed_image_if_available(&self, | |||
url: &ServoUrl, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
components/net/image_cache_thread.rs
Outdated
@@ -495,51 +479,76 @@ impl ImageCache { | |||
|
|||
/// Return a completed image if it exists, or None if there is no complete load | |||
/// of the complete load is not fully decoded or is unavailable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pre-existing: of -> or?
components/net/image_cache_thread.rs
Outdated
placeholder: UsePlaceholder) | ||
-> Option<Result<ImageOrMetadataAvailable, ImageState>> { | ||
self.completed_loads.get(url).map(|completed_load| { | ||
match (completed_load.image_response.clone(), placeholder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's only clone if needed?
|
||
LoadBlocker::terminate(&mut self.current_request.borrow_mut().blocker); | ||
let document = document_from_node(self); | ||
self.current_request.borrow_mut().blocker = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not borrow this as many times as possible :)
@glennw Want to look at the image cache changes in this PR? |
Remove network requests from image cache thread The design of initiating network requests from the image cache thread was simple, but it makes it difficult to implement image loading that conforms to the HTML specification. These changes make the implementation of HTMLImageElement responsible for network requests for `<img>` elements, and CSS-based images (background-image, bullets, etc.) are requested by the script thread to ensure that the layout thread does not attempt to retain unsafe pointers to DOM nodes during asynchronous operations. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #7708 - [X] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14962) <!-- Reviewable:end -->
💔 Test failed - linux-rel-wpt |
e99cba6
to
5af2603
Compare
@bors-servo: r=Ms2ger,glennw,emilio |
📌 Commit 5af2603 has been approved by |
Remove network requests from image cache thread The design of initiating network requests from the image cache thread was simple, but it makes it difficult to implement image loading that conforms to the HTML specification. These changes make the implementation of HTMLImageElement responsible for network requests for `<img>` elements, and CSS-based images (background-image, bullets, etc.) are requested by the script thread to ensure that the layout thread does not attempt to retain unsafe pointers to DOM nodes during asynchronous operations. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #7708 - [X] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14962) <!-- Reviewable:end -->
☀️ Test successful - android, arm32, arm64, linux-dev, linux-rel-css, linux-rel-wpt, mac-dev-unit, mac-rel-css, mac-rel-wpt1, mac-rel-wpt2, windows-gnu-dev, windows-msvc-dev |
…ronous drawImage tests. Upstreamed from servo/servo#14962 [ci skip]
Upstreamed from servo/servo#14962 [ci skip]
Revert unnecessary changes to canvas image drawing tests. These changes were made as part of #14962 under the assumption that images not in the document do not delay the load event. That assumption is incorrect. - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16492) <!-- Reviewable:end -->
The design of initiating network requests from the image cache thread was simple, but it makes it difficult to implement image loading that conforms to the HTML specification. These changes make the implementation of HTMLImageElement responsible for network requests for
<img>
elements, and CSS-based images (background-image, bullets, etc.) are requested by the script thread to ensure that the layout thread does not attempt to retain unsafe pointers to DOM nodes during asynchronous operations../mach build -d
does not report any errors./mach test-tidy
does not report any errorsThis change is