mirror of
https://github.com/servo/servo.git
synced 2025-07-08 07:53:40 +01:00
compositor: only UpdateImages
that accepts SmallVec
and add helpers for single image (#37730)
Before we only offered helper to add single image (no update or delete) that got special IPC message, now we simplify this by offering all ops helpers for dealing with single image (that happens most of the time), that simply uses `update_images` under the hood. We also optimize for this use case by using `SmallVec<[ImageUpdate; 1]>` to avoid alloc. Testing: Just refactor, but code is covered by WPT tests --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
3c16db2642
commit
4dded465a4
9 changed files with 36 additions and 42 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1429,6 +1429,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"servo_geometry",
|
"servo_geometry",
|
||||||
"servo_malloc_size_of",
|
"servo_malloc_size_of",
|
||||||
|
"smallvec",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"stylo",
|
"stylo",
|
||||||
"stylo_traits",
|
"stylo_traits",
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use canvas_traits::canvas::*;
|
use canvas_traits::canvas::*;
|
||||||
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
|
use compositing_traits::{CrossProcessCompositorApi, SerializableImageData};
|
||||||
use euclid::default::{Box2D, Point2D, Rect, Size2D, Transform2D, Vector2D};
|
use euclid::default::{Box2D, Point2D, Rect, Size2D, Transform2D, Vector2D};
|
||||||
use euclid::point2;
|
use euclid::point2;
|
||||||
use fonts::{
|
use fonts::{
|
||||||
|
@ -431,7 +431,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
|
||||||
};
|
};
|
||||||
let data =
|
let data =
|
||||||
SerializableImageData::Raw(IpcSharedMemory::from_bytes(draw_target.bytes().as_ref()));
|
SerializableImageData::Raw(IpcSharedMemory::from_bytes(draw_target.bytes().as_ref()));
|
||||||
compositor_api.update_images(vec![ImageUpdate::AddImage(image_key, descriptor, data)]);
|
compositor_api.add_image(image_key, descriptor, data);
|
||||||
CanvasData {
|
CanvasData {
|
||||||
state: backend.new_paint_state(),
|
state: backend.new_paint_state(),
|
||||||
backend,
|
backend,
|
||||||
|
@ -1212,11 +1212,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
|
||||||
));
|
));
|
||||||
|
|
||||||
self.compositor_api
|
self.compositor_api
|
||||||
.update_images(vec![ImageUpdate::UpdateImage(
|
.update_image(self.image_key, descriptor, data);
|
||||||
self.image_key,
|
|
||||||
descriptor,
|
|
||||||
data,
|
|
||||||
)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
|
||||||
|
@ -1342,8 +1338,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
|
||||||
|
|
||||||
impl<B: Backend> Drop for CanvasData<'_, B> {
|
impl<B: Backend> Drop for CanvasData<'_, B> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.compositor_api
|
self.compositor_api.delete_image(self.image_key);
|
||||||
.update_images(vec![ImageUpdate::DeleteImage(self.image_key)]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -941,12 +941,6 @@ impl IOCompositor {
|
||||||
self.global.borrow_mut().send_transaction(transaction);
|
self.global.borrow_mut().send_transaction(transaction);
|
||||||
},
|
},
|
||||||
|
|
||||||
CompositorMsg::AddImage(key, desc, data) => {
|
|
||||||
let mut txn = Transaction::new();
|
|
||||||
txn.add_image(key, desc, data.into(), None);
|
|
||||||
self.global.borrow_mut().send_transaction(txn);
|
|
||||||
},
|
|
||||||
|
|
||||||
CompositorMsg::GenerateFontKeys(
|
CompositorMsg::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
|
|
|
@ -48,7 +48,6 @@ mod from_constellation {
|
||||||
Self::SendDisplayList { .. } => target!("SendDisplayList"),
|
Self::SendDisplayList { .. } => target!("SendDisplayList"),
|
||||||
Self::HitTest(..) => target!("HitTest"),
|
Self::HitTest(..) => target!("HitTest"),
|
||||||
Self::GenerateImageKey(..) => target!("GenerateImageKey"),
|
Self::GenerateImageKey(..) => target!("GenerateImageKey"),
|
||||||
Self::AddImage(..) => target!("AddImage"),
|
|
||||||
Self::UpdateImages(..) => target!("UpdateImages"),
|
Self::UpdateImages(..) => target!("UpdateImages"),
|
||||||
Self::GenerateFontKeys(..) => target!("GenerateFontKeys"),
|
Self::GenerateFontKeys(..) => target!("GenerateFontKeys"),
|
||||||
Self::AddFont(..) => target!("AddFont"),
|
Self::AddFont(..) => target!("AddFont"),
|
||||||
|
|
|
@ -200,7 +200,7 @@ impl MediaFrameRenderer {
|
||||||
|
|
||||||
impl VideoFrameRenderer for MediaFrameRenderer {
|
impl VideoFrameRenderer for MediaFrameRenderer {
|
||||||
fn render(&mut self, frame: VideoFrame) {
|
fn render(&mut self, frame: VideoFrame) {
|
||||||
let mut updates = vec![];
|
let mut updates = smallvec::smallvec![];
|
||||||
|
|
||||||
if let Some(old_image_key) = mem::replace(&mut self.very_old_frame, self.old_frame.take()) {
|
if let Some(old_image_key) = mem::replace(&mut self.very_old_frame, self.old_frame.take()) {
|
||||||
updates.push(ImageUpdate::DeleteImage(old_image_key));
|
updates.push(ImageUpdate::DeleteImage(old_image_key));
|
||||||
|
|
|
@ -34,6 +34,7 @@ profile_traits = { path = '../profile' }
|
||||||
raw-window-handle = { version = "0.6" }
|
raw-window-handle = { version = "0.6" }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
servo_geometry = { path = "../../geometry" }
|
servo_geometry = { path = "../../geometry" }
|
||||||
|
smallvec = { workspace = true }
|
||||||
strum_macros = { workspace = true }
|
strum_macros = { workspace = true }
|
||||||
stylo = { workspace = true }
|
stylo = { workspace = true }
|
||||||
stylo_traits = { workspace = true }
|
stylo_traits = { workspace = true }
|
||||||
|
|
|
@ -17,6 +17,7 @@ use ipc_channel::ipc::IpcSender;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use pixels::RasterImage;
|
use pixels::RasterImage;
|
||||||
|
use smallvec::SmallVec;
|
||||||
use strum_macros::IntoStaticStr;
|
use strum_macros::IntoStaticStr;
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
use webrender_api::DocumentId;
|
use webrender_api::DocumentId;
|
||||||
|
@ -147,10 +148,8 @@ pub enum CompositorMsg {
|
||||||
/// Create a new image key. The result will be returned via the
|
/// Create a new image key. The result will be returned via the
|
||||||
/// provided channel sender.
|
/// provided channel sender.
|
||||||
GenerateImageKey(IpcSender<ImageKey>),
|
GenerateImageKey(IpcSender<ImageKey>),
|
||||||
/// Add an image with the given data and `ImageKey`.
|
|
||||||
AddImage(ImageKey, ImageDescriptor, SerializableImageData),
|
|
||||||
/// Perform a resource update operation.
|
/// Perform a resource update operation.
|
||||||
UpdateImages(Vec<ImageUpdate>),
|
UpdateImages(SmallVec<[ImageUpdate; 1]>),
|
||||||
|
|
||||||
/// Generate a new batch of font keys which can be used to allocate
|
/// Generate a new batch of font keys which can be used to allocate
|
||||||
/// keys asynchronously.
|
/// keys asynchronously.
|
||||||
|
@ -307,13 +306,24 @@ impl CrossProcessCompositorApi {
|
||||||
descriptor: ImageDescriptor,
|
descriptor: ImageDescriptor,
|
||||||
data: SerializableImageData,
|
data: SerializableImageData,
|
||||||
) {
|
) {
|
||||||
if let Err(e) = self.0.send(CompositorMsg::AddImage(key, descriptor, data)) {
|
self.update_images([ImageUpdate::AddImage(key, descriptor, data)].into());
|
||||||
warn!("Error sending image update: {}", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_image(
|
||||||
|
&self,
|
||||||
|
key: ImageKey,
|
||||||
|
descriptor: ImageDescriptor,
|
||||||
|
data: SerializableImageData,
|
||||||
|
) {
|
||||||
|
self.update_images([ImageUpdate::UpdateImage(key, descriptor, data)].into());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_image(&self, key: ImageKey) {
|
||||||
|
self.update_images([ImageUpdate::DeleteImage(key)].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an image resource update operation.
|
/// Perform an image resource update operation.
|
||||||
pub fn update_images(&self, updates: Vec<ImageUpdate>) {
|
pub fn update_images(&self, updates: SmallVec<[ImageUpdate; 1]>) {
|
||||||
if let Err(e) = self.0.send(CompositorMsg::UpdateImages(updates)) {
|
if let Err(e) = self.0.send(CompositorMsg::UpdateImages(updates)) {
|
||||||
warn!("error sending image updates: {}", e);
|
warn!("error sending image updates: {}", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use canvas_traits::webgl::{
|
||||||
WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
|
WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
|
||||||
};
|
};
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CrossProcessCompositorApi, ImageUpdate, SerializableImageData, WebrenderExternalImageRegistry,
|
CrossProcessCompositorApi, SerializableImageData, WebrenderExternalImageRegistry,
|
||||||
WebrenderImageHandlerType,
|
WebrenderImageHandlerType,
|
||||||
};
|
};
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
|
@ -719,8 +719,7 @@ impl WebGLThread {
|
||||||
fn remove_webgl_context(&mut self, context_id: WebGLContextId) {
|
fn remove_webgl_context(&mut self, context_id: WebGLContextId) {
|
||||||
// Release webrender image keys.
|
// Release webrender image keys.
|
||||||
if let Some(info) = self.cached_context_info.remove(&context_id) {
|
if let Some(info) = self.cached_context_info.remove(&context_id) {
|
||||||
self.compositor_api
|
self.compositor_api.delete_image(info.image_key);
|
||||||
.update_images(vec![ImageUpdate::DeleteImage(info.image_key)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to make the context current so its resources can be disposed of.
|
// We need to make the context current so its resources can be disposed of.
|
||||||
|
@ -929,11 +928,7 @@ impl WebGLThread {
|
||||||
let image_data = Self::external_image_data(context_id, image_buffer_kind);
|
let image_data = Self::external_image_data(context_id, image_buffer_kind);
|
||||||
|
|
||||||
self.compositor_api
|
self.compositor_api
|
||||||
.update_images(vec![ImageUpdate::UpdateImage(
|
.update_image(info.image_key, descriptor, image_data);
|
||||||
info.image_key,
|
|
||||||
descriptor,
|
|
||||||
image_data,
|
|
||||||
)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to create a `ImageDescriptor`.
|
/// Helper function to create a `ImageDescriptor`.
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CrossProcessCompositorApi, ImageUpdate, SerializableImageData, WebrenderExternalImageApi,
|
CrossProcessCompositorApi, SerializableImageData, WebrenderExternalImageApi,
|
||||||
WebrenderImageSource,
|
WebrenderImageSource,
|
||||||
};
|
};
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
|
@ -310,7 +310,7 @@ impl ContextData {
|
||||||
warn!("Unable to send FreeBuffer({:?}) ({:?})", buffer_id, e);
|
warn!("Unable to send FreeBuffer({:?}) ({:?})", buffer_id, e);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
compositor_api.update_images(vec![ImageUpdate::DeleteImage(self.image_key)]);
|
compositor_api.delete_image(self.image_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if presentation id was updated (was newer)
|
/// Returns true if presentation id was updated (was newer)
|
||||||
|
@ -421,12 +421,11 @@ impl crate::WGPU {
|
||||||
};
|
};
|
||||||
|
|
||||||
if needs_image_update {
|
if needs_image_update {
|
||||||
self.compositor_api
|
self.compositor_api.update_image(
|
||||||
.update_images(vec![ImageUpdate::UpdateImage(
|
|
||||||
context_data.image_key,
|
context_data.image_key,
|
||||||
context_data.image_desc.0,
|
context_data.image_desc.0,
|
||||||
SerializableImageData::External(context_data.image_data),
|
SerializableImageData::External(context_data.image_data),
|
||||||
)]);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,11 +573,11 @@ fn update_wr_image(
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let old_presentation_buffer = swap_chain.data.replace(presentation_buffer);
|
let old_presentation_buffer = swap_chain.data.replace(presentation_buffer);
|
||||||
compositor_api.update_images(vec![ImageUpdate::UpdateImage(
|
compositor_api.update_image(
|
||||||
context_data.image_key,
|
context_data.image_key,
|
||||||
context_data.image_desc.0,
|
context_data.image_desc.0,
|
||||||
SerializableImageData::External(context_data.image_data),
|
SerializableImageData::External(context_data.image_data),
|
||||||
)]);
|
);
|
||||||
if let Some(old_presentation_buffer) = old_presentation_buffer {
|
if let Some(old_presentation_buffer) = old_presentation_buffer {
|
||||||
context_data.unmap_old_buffer(old_presentation_buffer)
|
context_data.unmap_old_buffer(old_presentation_buffer)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue