mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Auto merge of #28739 - wusyong:ipc-bytes, r=jdm
Send webrender message's data through IPCBytesChannel <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix ##28738 (GitHub issue number if applicable) <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> For display list data, I tested with https://svelte.dev/docs in release build. I seems to have 20~30% improvement on `Display List Construction` when I profiling. For image data, I tested with http://slither.io/ (on the page for you to customize snek). It seems identical and I'm not sure where should I look at when profiling.
This commit is contained in:
commit
69aa81838d
2 changed files with 121 additions and 28 deletions
|
@ -626,25 +626,28 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
size,
|
||||
pipeline,
|
||||
size2,
|
||||
data,
|
||||
receiver,
|
||||
descriptor,
|
||||
)) => {
|
||||
self.waiting_on_pending_frame = true;
|
||||
let mut txn = webrender_api::Transaction::new();
|
||||
txn.set_display_list(
|
||||
epoch,
|
||||
None,
|
||||
size,
|
||||
(
|
||||
pipeline,
|
||||
size2,
|
||||
webrender_api::BuiltDisplayList::from_data(data, descriptor),
|
||||
),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, txn);
|
||||
)) => match receiver.recv() {
|
||||
Ok(data) => {
|
||||
self.waiting_on_pending_frame = true;
|
||||
let mut txn = webrender_api::Transaction::new();
|
||||
txn.set_display_list(
|
||||
epoch,
|
||||
None,
|
||||
size,
|
||||
(
|
||||
pipeline,
|
||||
size2,
|
||||
webrender_api::BuiltDisplayList::from_data(data, descriptor),
|
||||
),
|
||||
true,
|
||||
);
|
||||
txn.generate_frame();
|
||||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
Err(e) => warn!("error receiving display data: {:?}", e),
|
||||
},
|
||||
|
||||
WebrenderMsg::Layout(script_traits::WebrenderMsg::HitTest(
|
||||
|
@ -668,12 +671,25 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
let mut txn = webrender_api::Transaction::new();
|
||||
for update in updates {
|
||||
match update {
|
||||
script_traits::ImageUpdate::AddImage(key, desc, data) => {
|
||||
txn.add_image(key, desc, data, None)
|
||||
script_traits::SerializedImageUpdate::AddImage(key, desc, data) => {
|
||||
match data.to_image_data() {
|
||||
Ok(data) => txn.add_image(key, desc, data, None),
|
||||
Err(e) => warn!("error when sending image data: {:?}", e),
|
||||
}
|
||||
},
|
||||
script_traits::ImageUpdate::DeleteImage(key) => txn.delete_image(key),
|
||||
script_traits::ImageUpdate::UpdateImage(key, desc, data) => {
|
||||
txn.update_image(key, desc, data, &webrender_api::DirtyRect::All)
|
||||
script_traits::SerializedImageUpdate::DeleteImage(key) => {
|
||||
txn.delete_image(key)
|
||||
},
|
||||
script_traits::SerializedImageUpdate::UpdateImage(key, desc, data) => {
|
||||
match data.to_image_data() {
|
||||
Ok(data) => txn.update_image(
|
||||
key,
|
||||
desc,
|
||||
data,
|
||||
&webrender_api::DirtyRect::All,
|
||||
),
|
||||
Err(e) => warn!("error when sending image data: {:?}", e),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ use webrender_api::units::{
|
|||
DeviceIntSize, DevicePixel, LayoutPixel, LayoutPoint, LayoutSize, WorldPoint,
|
||||
};
|
||||
use webrender_api::{
|
||||
BuiltDisplayList, DocumentId, ExternalScrollId, ImageData, ImageDescriptor, ImageKey,
|
||||
ScrollClamping,
|
||||
BuiltDisplayList, DocumentId, ExternalImageData, ExternalScrollId, ImageData, ImageDescriptor,
|
||||
ImageKey, ScrollClamping,
|
||||
};
|
||||
use webrender_api::{BuiltDisplayListDescriptor, HitTestFlags, HitTestResult};
|
||||
|
||||
|
@ -1123,7 +1123,7 @@ pub enum WebrenderMsg {
|
|||
LayoutSize,
|
||||
webrender_api::PipelineId,
|
||||
LayoutSize,
|
||||
Vec<u8>,
|
||||
ipc::IpcBytesReceiver,
|
||||
BuiltDisplayListDescriptor,
|
||||
),
|
||||
/// Perform a hit test operation. The result will be returned via
|
||||
|
@ -1138,7 +1138,7 @@ pub enum WebrenderMsg {
|
|||
/// provided channel sender.
|
||||
GenerateImageKey(IpcSender<ImageKey>),
|
||||
/// Perform a resource update operation.
|
||||
UpdateImages(Vec<ImageUpdate>),
|
||||
UpdateImages(Vec<SerializedImageUpdate>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
|
@ -1181,16 +1181,21 @@ impl WebrenderIpcSender {
|
|||
(pipeline, size2, list): (webrender_api::PipelineId, LayoutSize, BuiltDisplayList),
|
||||
) {
|
||||
let (data, descriptor) = list.into_data();
|
||||
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||
if let Err(e) = self.0.send(WebrenderMsg::SendDisplayList(
|
||||
webrender_api::Epoch(epoch.0),
|
||||
size,
|
||||
pipeline,
|
||||
size2,
|
||||
data,
|
||||
receiver,
|
||||
descriptor,
|
||||
)) {
|
||||
warn!("Error sending display list: {}", e);
|
||||
}
|
||||
|
||||
if let Err(e) = sender.send(&data) {
|
||||
warn!("Error sending display data: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a hit test operation. Blocks until the operation is complete and
|
||||
|
@ -1219,9 +1224,48 @@ impl WebrenderIpcSender {
|
|||
|
||||
/// Perform a resource update operation.
|
||||
pub fn update_images(&self, updates: Vec<ImageUpdate>) {
|
||||
let mut senders = Vec::new();
|
||||
// Convert `ImageUpdate` to `SerializedImageUpdate` because `ImageData` may contain large
|
||||
// byes. With this conversion, we send `IpcBytesReceiver` instead and use it to send the
|
||||
// actual bytes.
|
||||
let updates = updates
|
||||
.into_iter()
|
||||
.map(|update| match update {
|
||||
ImageUpdate::AddImage(k, d, data) => {
|
||||
let data = match data {
|
||||
ImageData::Raw(r) => {
|
||||
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||
senders.push((sender, r));
|
||||
SerializedImageData::Raw(receiver)
|
||||
},
|
||||
ImageData::External(e) => SerializedImageData::External(e),
|
||||
};
|
||||
SerializedImageUpdate::AddImage(k, d, data)
|
||||
},
|
||||
ImageUpdate::DeleteImage(k) => SerializedImageUpdate::DeleteImage(k),
|
||||
ImageUpdate::UpdateImage(k, d, data) => {
|
||||
let data = match data {
|
||||
ImageData::Raw(r) => {
|
||||
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||
senders.push((sender, r));
|
||||
SerializedImageData::Raw(receiver)
|
||||
},
|
||||
ImageData::External(e) => SerializedImageData::External(e),
|
||||
};
|
||||
SerializedImageUpdate::UpdateImage(k, d, data)
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
|
||||
if let Err(e) = self.0.send(WebrenderMsg::UpdateImages(updates)) {
|
||||
warn!("error sending image updates: {}", e);
|
||||
}
|
||||
|
||||
senders.into_iter().for_each(|(tx, data)| {
|
||||
if let Err(e) = tx.send(&*data) {
|
||||
warn!("error sending image data: {}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1235,3 +1279,36 @@ pub enum ImageUpdate {
|
|||
/// Update an existing image registration.
|
||||
UpdateImage(ImageKey, ImageDescriptor, ImageData),
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
/// Serialized `ImageUpdate`.
|
||||
pub enum SerializedImageUpdate {
|
||||
/// Register a new image.
|
||||
AddImage(ImageKey, ImageDescriptor, SerializedImageData),
|
||||
/// Delete a previously registered image registration.
|
||||
DeleteImage(ImageKey),
|
||||
/// Update an existing image registration.
|
||||
UpdateImage(ImageKey, ImageDescriptor, SerializedImageData),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too
|
||||
/// slow.
|
||||
pub enum SerializedImageData {
|
||||
/// A simple series of bytes, provided by the embedding and owned by WebRender.
|
||||
/// The format is stored out-of-band, currently in ImageDescriptor.
|
||||
Raw(ipc::IpcBytesReceiver),
|
||||
/// An image owned by the embedding, and referenced by WebRender. This may
|
||||
/// take the form of a texture or a heap-allocated buffer.
|
||||
External(ExternalImageData),
|
||||
}
|
||||
|
||||
impl SerializedImageData {
|
||||
/// Convert to ``ImageData`.
|
||||
pub fn to_image_data(&self) -> Result<ImageData, ipc::IpcError> {
|
||||
match self {
|
||||
SerializedImageData::Raw(rx) => rx.recv().map(|data| ImageData::new(data)),
|
||||
SerializedImageData::External(image) => Ok(ImageData::External(image.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue