1use std::fmt::{Debug, Error, Formatter};
8
9use base::Epoch;
10use base::id::{PipelineId, WebViewId};
11use crossbeam_channel::Sender;
12use embedder_traits::{AnimationState, EventLoopWaker, TouchEventResult};
13use ipc_channel::ipc::IpcSender;
14use log::warn;
15use malloc_size_of_derive::MallocSizeOf;
16use smallvec::SmallVec;
17use strum_macros::IntoStaticStr;
18use webrender_api::{DocumentId, FontVariation};
19
20pub mod display_list;
21pub mod rendering_context;
22pub mod viewport_description;
23
24use std::collections::HashMap;
25use std::sync::{Arc, Mutex};
26
27use base::generic_channel::{self, GenericCallback, GenericSender};
28use bitflags::bitflags;
29use display_list::CompositorDisplayListInfo;
30use embedder_traits::ScreenGeometry;
31use euclid::default::Size2D as UntypedSize2D;
32use ipc_channel::ipc::{self, IpcSharedMemory};
33use profile_traits::mem::{OpaqueSender, ReportsChan};
34use serde::{Deserialize, Serialize};
35pub use webrender_api::ExternalImageSource;
36use webrender_api::units::{LayoutVector2D, TexelRect};
37use webrender_api::{
38 BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData,
39 ExternalImageHandler, ExternalImageId, ExternalScrollId, FontInstanceFlags, FontInstanceKey,
40 FontKey, ImageData, ImageDescriptor, ImageKey, NativeFontHandle,
41 PipelineId as WebRenderPipelineId,
42};
43
44use crate::viewport_description::ViewportDescription;
45
46#[derive(Clone)]
48pub struct CompositorProxy {
49 pub sender: Sender<Result<CompositorMsg, ipc_channel::Error>>,
50 pub cross_process_compositor_api: CrossProcessCompositorApi,
54 pub event_loop_waker: Box<dyn EventLoopWaker>,
55}
56
57impl OpaqueSender<CompositorMsg> for CompositorProxy {
58 fn send(&self, message: CompositorMsg) {
59 CompositorProxy::send(self, message)
60 }
61}
62
63impl CompositorProxy {
64 pub fn send(&self, msg: CompositorMsg) {
65 self.route_msg(Ok(msg))
66 }
67
68 pub fn route_msg(&self, msg: Result<CompositorMsg, ipc_channel::Error>) {
73 if let Err(err) = self.sender.send(msg) {
74 warn!("Failed to send response ({:?}).", err);
75 }
76 self.event_loop_waker.wake();
77 }
78}
79
80#[derive(Deserialize, IntoStaticStr, Serialize)]
82pub enum CompositorMsg {
83 ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
85 CreateOrUpdateWebView(SendableFrameTree),
87 RemoveWebView(WebViewId),
89 TouchEventProcessed(WebViewId, TouchEventResult),
91 IsReadyToSaveImageReply(bool),
93 SetThrottled(WebViewId, PipelineId, bool),
95 NewWebRenderFrameReady(DocumentId, bool),
99 PipelineExited(WebViewId, PipelineId, PipelineExitSource),
104 LoadComplete(WebViewId),
106 SendInitialTransaction(WebRenderPipelineId),
108 SendScrollNode(
110 WebViewId,
111 WebRenderPipelineId,
112 LayoutVector2D,
113 ExternalScrollId,
114 ),
115 SendDisplayList {
117 webview_id: WebViewId,
119 display_list_descriptor: BuiltDisplayListDescriptor,
121 display_list_receiver: ipc::IpcBytesReceiver,
123 },
124 GenerateFrame,
127 GenerateImageKey(IpcSender<ImageKey>),
130 GenerateImageKeysForPipeline(PipelineId),
133 UpdateImages(SmallVec<[ImageUpdate; 1]>),
135 DelayNewFrameForCanvas(PipelineId, Epoch, Vec<ImageKey>),
140
141 GenerateFontKeys(
144 usize,
145 usize,
146 GenericSender<(Vec<FontKey>, Vec<FontInstanceKey>)>,
147 ),
148 AddFont(FontKey, Arc<IpcSharedMemory>, u32),
150 AddSystemFont(FontKey, NativeFontHandle),
152 AddFontInstance(
154 FontInstanceKey,
155 FontKey,
156 f32,
157 FontInstanceFlags,
158 Vec<FontVariation>,
159 ),
160 RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
162 CollectMemoryReport(ReportsChan),
165 Viewport(WebViewId, ViewportDescription),
167}
168
169impl Debug for CompositorMsg {
170 fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
171 let string: &'static str = self.into();
172 write!(formatter, "{string}")
173 }
174}
175
176#[derive(Deserialize, Serialize)]
177pub struct SendableFrameTree {
178 pub pipeline: CompositionPipeline,
179 pub children: Vec<SendableFrameTree>,
180}
181
182#[derive(Clone, Deserialize, Serialize)]
184pub struct CompositionPipeline {
185 pub id: PipelineId,
186 pub webview_id: WebViewId,
187}
188
189#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
191pub struct CrossProcessCompositorApi(GenericCallback<CompositorMsg>);
192
193impl CrossProcessCompositorApi {
194 pub fn new(callback: GenericCallback<CompositorMsg>) -> Self {
196 CrossProcessCompositorApi(callback)
197 }
198
199 pub fn dummy() -> Self {
202 let callback = GenericCallback::new(|_msg| ()).unwrap();
203 Self(callback)
204 }
205
206 pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
208 if let Err(e) = self.0.send(CompositorMsg::SendInitialTransaction(pipeline)) {
209 warn!("Error sending initial transaction: {}", e);
210 }
211 }
212
213 pub fn send_scroll_node(
215 &self,
216 webview_id: WebViewId,
217 pipeline_id: WebRenderPipelineId,
218 point: LayoutVector2D,
219 scroll_id: ExternalScrollId,
220 ) {
221 if let Err(e) = self.0.send(CompositorMsg::SendScrollNode(
222 webview_id,
223 pipeline_id,
224 point,
225 scroll_id,
226 )) {
227 warn!("Error sending scroll node: {}", e);
228 }
229 }
230
231 pub fn delay_new_frame_for_canvas(
232 &self,
233 pipeline_id: PipelineId,
234 canvas_epoch: Epoch,
235 image_keys: Vec<ImageKey>,
236 ) {
237 if let Err(error) = self.0.send(CompositorMsg::DelayNewFrameForCanvas(
238 pipeline_id,
239 canvas_epoch,
240 image_keys,
241 )) {
242 warn!("Error delaying frames for canvas image updates {error:?}");
243 }
244 }
245
246 pub fn send_display_list(
248 &self,
249 webview_id: WebViewId,
250 display_list_info: &CompositorDisplayListInfo,
251 list: BuiltDisplayList,
252 ) {
253 let (display_list_data, display_list_descriptor) = list.into_data();
254 let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
255 if let Err(e) = self.0.send(CompositorMsg::SendDisplayList {
256 webview_id,
257 display_list_descriptor,
258 display_list_receiver,
259 }) {
260 warn!("Error sending display list: {}", e);
261 }
262
263 let display_list_info_serialized =
264 bincode::serialize(&display_list_info).unwrap_or_default();
265 if let Err(error) = display_list_sender.send(&display_list_info_serialized) {
266 warn!("Error sending display list info: {error}");
267 }
268
269 if let Err(error) = display_list_sender.send(&display_list_data.items_data) {
270 warn!("Error sending display list items: {error}");
271 }
272 if let Err(error) = display_list_sender.send(&display_list_data.cache_data) {
273 warn!("Error sending display list cache data: {error}");
274 }
275 if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) {
276 warn!("Error sending display spatial tree: {error}");
277 }
278 }
279
280 pub fn generate_frame(&self) {
282 if let Err(error) = self.0.send(CompositorMsg::GenerateFrame) {
283 warn!("Error generating frame: {error}");
284 }
285 }
286
287 pub fn generate_image_key_blocking(&self) -> Option<ImageKey> {
289 let (sender, receiver) = ipc::channel().unwrap();
290 self.0.send(CompositorMsg::GenerateImageKey(sender)).ok()?;
291 receiver.recv().ok()
292 }
293
294 pub fn generate_image_key_async(&self, pipeline_id: PipelineId) {
298 if let Err(e) = self
299 .0
300 .send(CompositorMsg::GenerateImageKeysForPipeline(pipeline_id))
301 {
302 warn!("Could not send image keys to Compositor {}", e);
303 }
304 }
305
306 pub fn add_image(
307 &self,
308 key: ImageKey,
309 descriptor: ImageDescriptor,
310 data: SerializableImageData,
311 ) {
312 self.update_images([ImageUpdate::AddImage(key, descriptor, data)].into());
313 }
314
315 pub fn update_image(
316 &self,
317 key: ImageKey,
318 descriptor: ImageDescriptor,
319 data: SerializableImageData,
320 epoch: Option<Epoch>,
321 ) {
322 self.update_images([ImageUpdate::UpdateImage(key, descriptor, data, epoch)].into());
323 }
324
325 pub fn delete_image(&self, key: ImageKey) {
326 self.update_images([ImageUpdate::DeleteImage(key)].into());
327 }
328
329 pub fn update_images(&self, updates: SmallVec<[ImageUpdate; 1]>) {
331 if let Err(e) = self.0.send(CompositorMsg::UpdateImages(updates)) {
332 warn!("error sending image updates: {}", e);
333 }
334 }
335
336 pub fn remove_unused_font_resources(
337 &self,
338 keys: Vec<FontKey>,
339 instance_keys: Vec<FontInstanceKey>,
340 ) {
341 if keys.is_empty() && instance_keys.is_empty() {
342 return;
343 }
344 let _ = self.0.send(CompositorMsg::RemoveFonts(keys, instance_keys));
345 }
346
347 pub fn add_font_instance(
348 &self,
349 font_instance_key: FontInstanceKey,
350 font_key: FontKey,
351 size: f32,
352 flags: FontInstanceFlags,
353 variations: Vec<FontVariation>,
354 ) {
355 let _x = self.0.send(CompositorMsg::AddFontInstance(
356 font_instance_key,
357 font_key,
358 size,
359 flags,
360 variations,
361 ));
362 }
363
364 pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
365 let _ = self.0.send(CompositorMsg::AddFont(font_key, data, index));
366 }
367
368 pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
369 let _ = self.0.send(CompositorMsg::AddSystemFont(font_key, handle));
370 }
371
372 pub fn fetch_font_keys(
373 &self,
374 number_of_font_keys: usize,
375 number_of_font_instance_keys: usize,
376 ) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
377 let (sender, receiver) = generic_channel::channel().expect("Could not create IPC channel");
378 let _ = self.0.send(CompositorMsg::GenerateFontKeys(
379 number_of_font_keys,
380 number_of_font_instance_keys,
381 sender,
382 ));
383 receiver.recv().unwrap()
384 }
385
386 pub fn viewport(&self, webview_id: WebViewId, description: ViewportDescription) {
387 let _ = self
388 .0
389 .send(CompositorMsg::Viewport(webview_id, description));
390 }
391
392 pub fn pipeline_exited(
393 &self,
394 webview_id: WebViewId,
395 pipeline_id: PipelineId,
396 source: PipelineExitSource,
397 ) {
398 let _ = self.0.send(CompositorMsg::PipelineExited(
399 webview_id,
400 pipeline_id,
401 source,
402 ));
403 }
404}
405
406pub trait WebrenderExternalImageApi {
413 fn lock(&mut self, id: u64) -> (ExternalImageSource<'_>, UntypedSize2D<i32>);
414 fn unlock(&mut self, id: u64);
415}
416
417pub enum WebrenderImageHandlerType {
419 WebGL,
420 Media,
421 WebGPU,
422}
423
424#[derive(Default)]
428pub struct WebrenderExternalImageRegistry {
429 external_images: HashMap<ExternalImageId, WebrenderImageHandlerType>,
431 next_image_id: u64,
433}
434
435impl WebrenderExternalImageRegistry {
436 pub fn next_id(&mut self, handler_type: WebrenderImageHandlerType) -> ExternalImageId {
437 self.next_image_id += 1;
438 let key = ExternalImageId(self.next_image_id);
439 self.external_images.insert(key, handler_type);
440 key
441 }
442
443 pub fn remove(&mut self, key: &ExternalImageId) {
444 self.external_images.remove(key);
445 }
446
447 pub fn get(&self, key: &ExternalImageId) -> Option<&WebrenderImageHandlerType> {
448 self.external_images.get(key)
449 }
450}
451
452pub struct WebrenderExternalImageHandlers {
454 webgl_handler: Option<Box<dyn WebrenderExternalImageApi>>,
456 media_handler: Option<Box<dyn WebrenderExternalImageApi>>,
458 webgpu_handler: Option<Box<dyn WebrenderExternalImageApi>>,
460 external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
462}
463
464impl WebrenderExternalImageHandlers {
465 pub fn new() -> (Self, Arc<Mutex<WebrenderExternalImageRegistry>>) {
466 let external_images = Arc::new(Mutex::new(WebrenderExternalImageRegistry::default()));
467 (
468 Self {
469 webgl_handler: None,
470 media_handler: None,
471 webgpu_handler: None,
472 external_images: external_images.clone(),
473 },
474 external_images,
475 )
476 }
477
478 pub fn set_handler(
479 &mut self,
480 handler: Box<dyn WebrenderExternalImageApi>,
481 handler_type: WebrenderImageHandlerType,
482 ) {
483 match handler_type {
484 WebrenderImageHandlerType::WebGL => self.webgl_handler = Some(handler),
485 WebrenderImageHandlerType::Media => self.media_handler = Some(handler),
486 WebrenderImageHandlerType::WebGPU => self.webgpu_handler = Some(handler),
487 }
488 }
489}
490
491impl ExternalImageHandler for WebrenderExternalImageHandlers {
492 fn lock(&mut self, key: ExternalImageId, _channel_index: u8) -> ExternalImage<'_> {
497 let external_images = self.external_images.lock().unwrap();
498 let handler_type = external_images
499 .get(&key)
500 .expect("Tried to get unknown external image");
501 match handler_type {
502 WebrenderImageHandlerType::WebGL => {
503 let (source, size) = self.webgl_handler.as_mut().unwrap().lock(key.0);
504 let texture_id = match source {
505 ExternalImageSource::NativeTexture(b) => b,
506 _ => panic!("Wrong type"),
507 };
508 ExternalImage {
509 uv: TexelRect::new(0.0, size.height as f32, size.width as f32, 0.0),
510 source: ExternalImageSource::NativeTexture(texture_id),
511 }
512 },
513 WebrenderImageHandlerType::Media => {
514 let (source, size) = self.media_handler.as_mut().unwrap().lock(key.0);
515 let texture_id = match source {
516 ExternalImageSource::NativeTexture(b) => b,
517 _ => panic!("Wrong type"),
518 };
519 ExternalImage {
520 uv: TexelRect::new(0.0, size.height as f32, size.width as f32, 0.0),
521 source: ExternalImageSource::NativeTexture(texture_id),
522 }
523 },
524 WebrenderImageHandlerType::WebGPU => {
525 let (source, size) = self.webgpu_handler.as_mut().unwrap().lock(key.0);
526 let buffer = match source {
527 ExternalImageSource::RawData(b) => b,
528 _ => panic!("Wrong type"),
529 };
530 ExternalImage {
531 uv: TexelRect::new(0.0, size.height as f32, size.width as f32, 0.0),
532 source: ExternalImageSource::RawData(buffer),
533 }
534 },
535 }
536 }
537
538 fn unlock(&mut self, key: ExternalImageId, _channel_index: u8) {
541 let external_images = self.external_images.lock().unwrap();
542 let handler_type = external_images
543 .get(&key)
544 .expect("Tried to get unknown external image");
545 match handler_type {
546 WebrenderImageHandlerType::WebGL => self.webgl_handler.as_mut().unwrap().unlock(key.0),
547 WebrenderImageHandlerType::Media => self.media_handler.as_mut().unwrap().unlock(key.0),
548 WebrenderImageHandlerType::WebGPU => {
549 self.webgpu_handler.as_mut().unwrap().unlock(key.0)
550 },
551 };
552 }
553}
554
555#[derive(Deserialize, Serialize)]
556pub enum ImageUpdate {
558 AddImage(ImageKey, ImageDescriptor, SerializableImageData),
560 DeleteImage(ImageKey),
562 UpdateImage(
564 ImageKey,
565 ImageDescriptor,
566 SerializableImageData,
567 Option<Epoch>,
568 ),
569}
570
571impl Debug for ImageUpdate {
572 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
573 match self {
574 Self::AddImage(image_key, image_desc, _) => f
575 .debug_tuple("AddImage")
576 .field(image_key)
577 .field(image_desc)
578 .finish(),
579 Self::DeleteImage(image_key) => f.debug_tuple("DeleteImage").field(image_key).finish(),
580 Self::UpdateImage(image_key, image_desc, _, epoch) => f
581 .debug_tuple("UpdateImage")
582 .field(image_key)
583 .field(image_desc)
584 .field(epoch)
585 .finish(),
586 }
587 }
588}
589
590#[derive(Debug, Deserialize, Serialize)]
591pub enum SerializableImageData {
594 Raw(IpcSharedMemory),
597 External(ExternalImageData),
600}
601
602impl From<SerializableImageData> for ImageData {
603 fn from(value: SerializableImageData) -> Self {
604 match value {
605 SerializableImageData::Raw(shared_memory) => ImageData::new(shared_memory.to_vec()),
606 SerializableImageData::External(image) => ImageData::External(image),
607 }
608 }
609}
610
611pub trait WebViewTrait {
615 fn id(&self) -> WebViewId;
616 fn screen_geometry(&self) -> Option<ScreenGeometry>;
617 fn set_animating(&self, new_value: bool);
618}
619
620#[derive(Clone, Copy, Default, Deserialize, PartialEq, Serialize)]
623pub struct PipelineExitSource(u8);
624
625bitflags! {
626 impl PipelineExitSource: u8 {
627 const Script = 1 << 0;
628 const Constellation = 1 << 1;
629 }
630}