mirror of
https://github.com/servo/servo.git
synced 2025-06-19 22:59:03 +01:00
Servo currently uses `heapsize`, but Stylo/Gecko use `malloc_size_of`. `malloc_size_of` is better -- it handles various cases that `heapsize` does not -- so this patch changes Servo to use `malloc_size_of`. This patch makes the following changes to the `malloc_size_of` crate. - Adds `MallocSizeOf` trait implementations for numerous types, some built-in (e.g. `VecDeque`), some external and Servo-only (e.g. `string_cache`). - Makes `enclosing_size_of_op` optional, because vanilla jemalloc doesn't support that operation. - For `HashSet`/`HashMap`, falls back to a computed estimate when `enclosing_size_of_op` isn't available. - Adds an extern "C" `malloc_size_of` function that does the actual heap measurement; this is based on the same functions from the `heapsize` crate. This patch makes the following changes elsewhere. - Converts all the uses of `heapsize` to instead use `malloc_size_of`. - Disables the "heapsize"/"heap_size" feature for the external crates that provide it. - Removes the `HeapSizeOf` implementation from `hashglobe`. - Adds `ignore` annotations to a few `Rc`/`Arc`, because `malloc_size_of` doesn't derive those types, unlike `heapsize`.
124 lines
4.5 KiB
Rust
124 lines
4.5 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
use FetchResponseMsg;
|
|
use image::base::{Image, ImageMetadata};
|
|
use ipc_channel::ipc::IpcSender;
|
|
use servo_url::ServoUrl;
|
|
use std::sync::Arc;
|
|
use webrender_api;
|
|
|
|
// ======================================================================
|
|
// Aux structs and enums.
|
|
// ======================================================================
|
|
|
|
/// Whether a consumer is in a position to request images or not. This can occur
|
|
/// when animations are being processed by the layout thread while the script
|
|
/// thread is executing in parallel.
|
|
#[derive(Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
pub enum CanRequestImages {
|
|
No,
|
|
Yes,
|
|
}
|
|
|
|
/// Indicating either entire image or just metadata availability
|
|
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
|
pub enum ImageOrMetadataAvailable {
|
|
ImageAvailable(#[ignore_malloc_size_of = "Arc"] Arc<Image>, ServoUrl),
|
|
MetadataAvailable(ImageMetadata),
|
|
}
|
|
|
|
/// This is optionally passed to the image cache when requesting
|
|
/// and image, and returned to the specified event loop when the
|
|
/// image load completes. It is typically used to trigger a reflow
|
|
/// and/or repaint.
|
|
#[derive(Clone, Deserialize, Serialize)]
|
|
pub struct ImageResponder {
|
|
id: PendingImageId,
|
|
sender: IpcSender<PendingImageResponse>,
|
|
}
|
|
|
|
impl ImageResponder {
|
|
pub fn new(sender: IpcSender<PendingImageResponse>, id: PendingImageId) -> ImageResponder {
|
|
ImageResponder {
|
|
sender: sender,
|
|
id: id,
|
|
}
|
|
}
|
|
|
|
pub fn respond(&self, response: ImageResponse) {
|
|
debug!("Notifying listener");
|
|
// This send can fail if thread waiting for this notification has panicked.
|
|
// That's not a case that's worth warning about.
|
|
// TODO(#15501): are there cases in which we should perform cleanup?
|
|
let _ = self.sender.send(PendingImageResponse {
|
|
response: response,
|
|
id: self.id,
|
|
});
|
|
}
|
|
}
|
|
|
|
/// The returned image.
|
|
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
|
pub enum ImageResponse {
|
|
/// The requested image was loaded.
|
|
Loaded(#[ignore_malloc_size_of = "Arc"] Arc<Image>, ServoUrl),
|
|
/// The request image metadata was loaded.
|
|
MetadataLoaded(ImageMetadata),
|
|
/// The requested image failed to load, so a placeholder was loaded instead.
|
|
PlaceholderLoaded(#[ignore_malloc_size_of = "Arc"] Arc<Image>, ServoUrl),
|
|
/// Neither the requested image nor the placeholder could be loaded.
|
|
None,
|
|
}
|
|
|
|
/// The current state of an image in the cache.
|
|
#[derive(Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
pub enum ImageState {
|
|
Pending(PendingImageId),
|
|
LoadError,
|
|
NotRequested(PendingImageId),
|
|
}
|
|
|
|
/// The unique id for an image that has previously been requested.
|
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
|
|
pub struct PendingImageId(pub u64);
|
|
|
|
#[derive(Debug, Deserialize, Serialize)]
|
|
pub struct PendingImageResponse {
|
|
pub response: ImageResponse,
|
|
pub id: PendingImageId,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Deserialize, Eq, Hash, PartialEq, Serialize)]
|
|
pub enum UsePlaceholder {
|
|
No,
|
|
Yes,
|
|
}
|
|
|
|
// ======================================================================
|
|
// ImageCache public API.
|
|
// ======================================================================
|
|
|
|
pub trait ImageCache: Sync + Send {
|
|
fn new(webrender_api: webrender_api::RenderApi) -> Self where Self: Sized;
|
|
|
|
/// Return any available metadata or image for the given URL,
|
|
/// or an indication that the image is not yet available if it is in progress,
|
|
/// or else reserve a slot in the cache for the URL if the consumer can request images.
|
|
fn find_image_or_metadata(&self,
|
|
url: ServoUrl,
|
|
use_placeholder: UsePlaceholder,
|
|
can_request: CanRequestImages)
|
|
-> Result<ImageOrMetadataAvailable, ImageState>;
|
|
|
|
/// Add a new listener for the given pending image id. If the image is already present,
|
|
/// the responder will still receive the expected response.
|
|
fn add_listener(&self, id: PendingImageId, listener: ImageResponder);
|
|
|
|
/// Inform the image cache about a response for a pending request.
|
|
fn notify_pending_response(&self, id: PendingImageId, action: FetchResponseMsg);
|
|
|
|
/// Ensure an image has a webrender key.
|
|
fn set_webrender_image_key(&self, image: &mut Image);
|
|
}
|