1#![deny(missing_docs)]
6
7use std::cell::Cell;
8use std::fmt;
9use std::marker::PhantomData;
10use std::path::PathBuf;
11use std::sync::Arc;
12use std::u32;
13use api::{MinimapData, SnapshotImageKey};
14use crate::api::channel::{Sender, single_msg_channel, unbounded_channel};
15use crate::api::{BuiltDisplayList, IdNamespace, ExternalScrollId, Parameter, BoolParameter};
16use crate::api::{FontKey, FontInstanceKey, NativeFontHandle};
17use crate::api::{BlobImageData, BlobImageKey, ImageData, ImageDescriptor, ImageKey, Epoch, QualitySettings};
18use crate::api::{BlobImageParams, BlobImageRequest, BlobImageResult, AsyncBlobImageRasterizer, BlobImageHandler};
19use crate::api::{DocumentId, PipelineId, PropertyBindingId, PropertyBindingKey, ExternalEvent};
20use crate::api::{HitTestResult, HitTesterRequest, ApiHitTester, PropertyValue, DynamicProperties};
21use crate::api::{SampledScrollOffset, TileSize, NotificationRequest, DebugFlags};
22use crate::api::{GlyphDimensionRequest, GlyphIndexRequest, GlyphIndex, GlyphDimensions};
23use crate::api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation, RenderReasons};
24use crate::api::DEFAULT_TILE_SIZE;
25use crate::api::units::*;
26use crate::api_resources::ApiResources;
27use glyph_rasterizer::SharedFontResources;
28use crate::scene_builder_thread::{SceneBuilderRequest, SceneBuilderResult};
29use crate::intern::InterningMemoryReport;
30use crate::profiler::{self, TransactionProfile};
31#[cfg(feature = "debugger")]
32use crate::debugger::{DebugQuery, DebuggerClient};
33
34#[repr(C)]
35#[derive(Clone, Copy, Debug)]
36#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
37struct ResourceId(pub u32);
38
39#[derive(Clone)]
43#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
44pub enum ResourceUpdate {
45 AddImage(AddImage),
47 UpdateImage(UpdateImage),
49 DeleteImage(ImageKey),
55 AddBlobImage(AddBlobImage),
57 UpdateBlobImage(UpdateBlobImage),
59 DeleteBlobImage(BlobImageKey),
61 SetBlobImageVisibleArea(BlobImageKey, DeviceIntRect),
63 AddSnapshotImage(AddSnapshotImage),
65 DeleteSnapshotImage(SnapshotImageKey),
67 AddFont(AddFont),
69 DeleteFont(FontKey),
75 AddFontInstance(AddFontInstance),
77 DeleteFontInstance(FontInstanceKey),
83}
84
85impl fmt::Debug for ResourceUpdate {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 match self {
88 ResourceUpdate::AddImage(ref i) => f.write_fmt(format_args!(
89 "ResourceUpdate::AddImage size({:?})",
90 &i.descriptor.size
91 )),
92 ResourceUpdate::UpdateImage(ref i) => f.write_fmt(format_args!(
93 "ResourceUpdate::UpdateImage size({:?})",
94 &i.descriptor.size
95 )),
96 ResourceUpdate::AddBlobImage(ref i) => f.write_fmt(format_args!(
97 "ResourceUFpdate::AddBlobImage size({:?})",
98 &i.descriptor.size
99 )),
100 ResourceUpdate::UpdateBlobImage(i) => f.write_fmt(format_args!(
101 "ResourceUpdate::UpdateBlobImage size({:?})",
102 &i.descriptor.size
103 )),
104 ResourceUpdate::DeleteImage(..) => f.write_str("ResourceUpdate::DeleteImage"),
105 ResourceUpdate::DeleteBlobImage(..) => f.write_str("ResourceUpdate::DeleteBlobImage"),
106 ResourceUpdate::SetBlobImageVisibleArea(..) => f.write_str("ResourceUpdate::SetBlobImageVisibleArea"),
107 ResourceUpdate::AddSnapshotImage(..) => f.write_str("ResourceUpdate::AddSnapshotImage"),
108 ResourceUpdate::DeleteSnapshotImage(..) => f.write_str("ResourceUpdate::DeleteSnapshotImage"),
109 ResourceUpdate::AddFont(..) => f.write_str("ResourceUpdate::AddFont"),
110 ResourceUpdate::DeleteFont(..) => f.write_str("ResourceUpdate::DeleteFont"),
111 ResourceUpdate::AddFontInstance(..) => f.write_str("ResourceUpdate::AddFontInstance"),
112 ResourceUpdate::DeleteFontInstance(..) => f.write_str("ResourceUpdate::DeleteFontInstance"),
113 }
114 }
115}
116
117#[derive(Clone, Debug)]
120pub enum GenerateFrame {
121 Yes {
123 id: u64,
126 present: bool,
129 tracked: bool,
132 },
133 No,
135}
136
137impl GenerateFrame {
138 pub fn as_bool(&self) -> bool {
140 match self {
141 GenerateFrame::Yes { .. } => true,
142 GenerateFrame::No => false,
143 }
144 }
145
146 pub fn present(&self) -> bool {
149 match self {
150 GenerateFrame::Yes { present, .. } => *present,
151 GenerateFrame::No => false,
152 }
153 }
154
155 pub fn tracked(&self) -> bool {
158 match self {
159 GenerateFrame::Yes { tracked, .. } => *tracked,
160 GenerateFrame::No => false,
161 }
162 }
163
164 pub fn id(&self) -> Option<u64> {
166 match self {
167 GenerateFrame::Yes { id, .. } => Some(*id),
168 GenerateFrame::No => None,
169 }
170 }
171}
172
173pub struct Transaction {
180 scene_ops: Vec<SceneMsg>,
182 frame_ops: Vec<FrameMsg>,
184
185 notifications: Vec<NotificationRequest>,
186
187 pub resource_updates: Vec<ResourceUpdate>,
189
190 use_scene_builder_thread: bool,
198
199 generate_frame: GenerateFrame,
203
204 creation_time: u64,
206
207 pub invalidate_rendered_frame: bool,
210
211 low_priority: bool,
212
213 pub render_reasons: RenderReasons,
215}
216
217impl Transaction {
218 pub fn new() -> Self {
220 Transaction {
221 scene_ops: Vec::new(),
222 frame_ops: Vec::new(),
223 resource_updates: Vec::new(),
224 notifications: Vec::new(),
225 use_scene_builder_thread: true,
226 generate_frame: GenerateFrame::No,
227 creation_time: zeitstempel::now(),
228 invalidate_rendered_frame: false,
229 low_priority: false,
230 render_reasons: RenderReasons::empty(),
231 }
232 }
233
234 pub fn skip_scene_builder(&mut self) {
243 self.use_scene_builder_thread = false;
244 }
245
246 pub fn use_scene_builder_thread(&mut self) {
248 self.use_scene_builder_thread = true;
249 }
250
251 pub fn is_empty(&self) -> bool {
253 !self.generate_frame.as_bool() &&
254 !self.invalidate_rendered_frame &&
255 self.scene_ops.is_empty() &&
256 self.frame_ops.is_empty() &&
257 self.resource_updates.is_empty() &&
258 self.notifications.is_empty()
259 }
260
261 pub fn update_epoch(&mut self, pipeline_id: PipelineId, epoch: Epoch) {
263 self.scene_ops.push(SceneMsg::UpdateEpoch(pipeline_id, epoch));
266 self.frame_ops.push(FrameMsg::UpdateEpoch(pipeline_id, epoch));
269 }
273
274 pub fn set_root_pipeline(&mut self, pipeline_id: PipelineId) {
289 self.scene_ops.push(SceneMsg::SetRootPipeline(pipeline_id));
290 }
291
292 pub fn remove_pipeline(&mut self, pipeline_id: PipelineId) {
296 self.scene_ops.push(SceneMsg::RemovePipeline(pipeline_id));
297 }
298
299 pub fn set_display_list(
311 &mut self,
312 epoch: Epoch,
313 (pipeline_id, mut display_list): (PipelineId, BuiltDisplayList),
314 ) {
315 display_list.set_send_time_ns(zeitstempel::now());
316 self.scene_ops.push(
317 SceneMsg::SetDisplayList {
318 display_list,
319 epoch,
320 pipeline_id,
321 }
322 );
323 }
324
325 pub fn update_resources(&mut self, mut resources: Vec<ResourceUpdate>) {
327 self.resource_updates.append(&mut resources);
328 }
329
330 pub fn notify(&mut self, event: NotificationRequest) {
342 self.notifications.push(event);
343 }
344
345 pub fn set_document_view(
347 &mut self,
348 device_rect: DeviceIntRect,
349 ) {
350 window_size_sanity_check(device_rect.size());
351 self.scene_ops.push(
352 SceneMsg::SetDocumentView {
353 device_rect,
354 },
355 );
356 }
357
358 pub fn set_scroll_offsets(
362 &mut self,
363 id: ExternalScrollId,
364 sampled_scroll_offsets: Vec<SampledScrollOffset>,
365 ) {
366 self.frame_ops.push(FrameMsg::SetScrollOffsets(id, sampled_scroll_offsets));
367 }
368
369 pub fn set_quality_settings(&mut self, settings: QualitySettings) {
371 self.scene_ops.push(SceneMsg::SetQualitySettings { settings });
372 }
373
374 pub fn set_is_transform_async_zooming(&mut self, is_zooming: bool, animation_id: PropertyBindingId) {
376 self.frame_ops.push(FrameMsg::SetIsTransformAsyncZooming(is_zooming, animation_id));
377 }
378
379 pub fn set_minimap_data(&mut self, id: ExternalScrollId, minimap_data: MinimapData) {
381 self.frame_ops.push(FrameMsg::SetMinimapData(id, minimap_data));
382 }
383
384 pub fn generate_frame(&mut self, id: u64, present: bool, tracked: bool, reasons: RenderReasons) {
392 self.generate_frame = GenerateFrame::Yes{ id, present, tracked };
393 self.render_reasons |= reasons;
394 }
395
396 pub fn invalidate_rendered_frame(&mut self, reasons: RenderReasons) {
403 self.invalidate_rendered_frame = true;
404 self.render_reasons |= reasons
405 }
406
407 pub fn reset_dynamic_properties(&mut self) {
410 self.frame_ops.push(FrameMsg::ResetDynamicProperties);
411 }
412
413 pub fn append_dynamic_properties(&mut self, properties: DynamicProperties) {
416 self.frame_ops.push(FrameMsg::AppendDynamicProperties(properties));
417 }
418
419 pub fn append_dynamic_transform_properties(&mut self, transforms: Vec<PropertyValue<LayoutTransform>>) {
424 self.frame_ops.push(FrameMsg::AppendDynamicTransformProperties(transforms));
425 }
426
427 pub fn get_frame_ops(self) -> Vec<FrameMsg> {
429 self.frame_ops
430 }
431
432 fn finalize(self, document_id: DocumentId) -> Box<TransactionMsg> {
433 Box::new(TransactionMsg {
434 document_id,
435 scene_ops: self.scene_ops,
436 frame_ops: self.frame_ops,
437 resource_updates: self.resource_updates,
438 notifications: self.notifications,
439 use_scene_builder_thread: self.use_scene_builder_thread,
440 generate_frame: self.generate_frame,
441 creation_time: Some(self.creation_time),
442 invalidate_rendered_frame: self.invalidate_rendered_frame,
443 low_priority: self.low_priority,
444 blob_rasterizer: None,
445 blob_requests: Vec::new(),
446 rasterized_blobs: Vec::new(),
447 profile: TransactionProfile::new(),
448 render_reasons: self.render_reasons,
449 })
450 }
451
452 pub fn add_image(
454 &mut self,
455 key: ImageKey,
456 descriptor: ImageDescriptor,
457 data: ImageData,
458 tiling: Option<TileSize>,
459 ) {
460 self.resource_updates.push(ResourceUpdate::AddImage(AddImage {
461 key,
462 descriptor,
463 data,
464 tiling,
465 }));
466 }
467
468 pub fn update_image(
470 &mut self,
471 key: ImageKey,
472 descriptor: ImageDescriptor,
473 data: ImageData,
474 dirty_rect: &ImageDirtyRect,
475 ) {
476 self.resource_updates.push(ResourceUpdate::UpdateImage(UpdateImage {
477 key,
478 descriptor,
479 data,
480 dirty_rect: *dirty_rect,
481 }));
482 }
483
484 pub fn delete_image(&mut self, key: ImageKey) {
486 self.resource_updates.push(ResourceUpdate::DeleteImage(key));
487 }
488
489 pub fn add_blob_image(
491 &mut self,
492 key: BlobImageKey,
493 descriptor: ImageDescriptor,
494 data: Arc<BlobImageData>,
495 visible_rect: DeviceIntRect,
496 tile_size: Option<TileSize>,
497 ) {
498 self.resource_updates.push(
499 ResourceUpdate::AddBlobImage(AddBlobImage {
500 key,
501 descriptor,
502 data,
503 visible_rect,
504 tile_size: tile_size.unwrap_or(DEFAULT_TILE_SIZE),
505 })
506 );
507 }
508
509 pub fn update_blob_image(
511 &mut self,
512 key: BlobImageKey,
513 descriptor: ImageDescriptor,
514 data: Arc<BlobImageData>,
515 visible_rect: DeviceIntRect,
516 dirty_rect: &BlobDirtyRect,
517 ) {
518 self.resource_updates.push(
519 ResourceUpdate::UpdateBlobImage(UpdateBlobImage {
520 key,
521 descriptor,
522 data,
523 visible_rect,
524 dirty_rect: *dirty_rect,
525 })
526 );
527 }
528
529 pub fn delete_blob_image(&mut self, key: BlobImageKey) {
531 self.resource_updates.push(ResourceUpdate::DeleteBlobImage(key));
532 }
533
534 pub fn set_blob_image_visible_area(&mut self, key: BlobImageKey, area: DeviceIntRect) {
536 self.resource_updates.push(ResourceUpdate::SetBlobImageVisibleArea(key, area));
537 }
538
539 pub fn add_snapshot_image(
541 &mut self,
542 key: SnapshotImageKey,
543 ) {
544 self.resource_updates.push(
545 ResourceUpdate::AddSnapshotImage(AddSnapshotImage { key })
546 );
547 }
548
549 pub fn delete_snapshot_image(&mut self, key: SnapshotImageKey) {
551 self.resource_updates.push(ResourceUpdate::DeleteSnapshotImage(key));
552 }
553
554 pub fn add_raw_font(&mut self, key: FontKey, bytes: Vec<u8>, index: u32) {
556 self.resource_updates
557 .push(ResourceUpdate::AddFont(AddFont::Raw(key, Arc::new(bytes), index)));
558 }
559
560 pub fn add_native_font(&mut self, key: FontKey, native_handle: NativeFontHandle) {
562 self.resource_updates
563 .push(ResourceUpdate::AddFont(AddFont::Native(key, native_handle)));
564 }
565
566 pub fn delete_font(&mut self, key: FontKey) {
568 self.resource_updates.push(ResourceUpdate::DeleteFont(key));
569 }
570
571 pub fn add_font_instance(
573 &mut self,
574 key: FontInstanceKey,
575 font_key: FontKey,
576 glyph_size: f32,
577 options: Option<FontInstanceOptions>,
578 platform_options: Option<FontInstancePlatformOptions>,
579 variations: Vec<FontVariation>,
580 ) {
581 self.resource_updates
582 .push(ResourceUpdate::AddFontInstance(AddFontInstance {
583 key,
584 font_key,
585 glyph_size,
586 options,
587 platform_options,
588 variations,
589 }));
590 }
591
592 pub fn delete_font_instance(&mut self, key: FontInstanceKey) {
594 self.resource_updates.push(ResourceUpdate::DeleteFontInstance(key));
595 }
596
597 pub fn set_low_priority(&mut self, low_priority: bool) {
602 self.low_priority = low_priority;
603 }
604
605 pub fn is_low_priority(&self) -> bool {
607 self.low_priority
608 }
609
610 pub fn render_offscreen(&mut self, pipeline_id: PipelineId) {
615 self.scene_ops.push(SceneMsg::RenderOffscreen(pipeline_id));
616 }
617}
618
619pub struct DocumentTransaction {
621 pub document_id: DocumentId,
623 pub transaction: Transaction,
625}
626
627pub struct TransactionMsg {
629 pub document_id: DocumentId,
631 pub scene_ops: Vec<SceneMsg>,
633 pub frame_ops: Vec<FrameMsg>,
635 pub resource_updates: Vec<ResourceUpdate>,
637 pub generate_frame: GenerateFrame,
639 pub creation_time: Option<u64>,
641 pub invalidate_rendered_frame: bool,
644 pub use_scene_builder_thread: bool,
646 pub low_priority: bool,
648
649 pub notifications: Vec<NotificationRequest>,
651 pub blob_rasterizer: Option<Box<dyn AsyncBlobImageRasterizer>>,
653 pub blob_requests: Vec<BlobImageParams>,
655 pub rasterized_blobs: Vec<(BlobImageRequest, BlobImageResult)>,
657 pub profile: TransactionProfile,
659 pub render_reasons: RenderReasons,
661}
662
663impl fmt::Debug for TransactionMsg {
664 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
665 writeln!(f, "threaded={}, genframe={:?}, invalidate={}, low_priority={}",
666 self.use_scene_builder_thread,
667 self.generate_frame,
668 self.invalidate_rendered_frame,
669 self.low_priority,
670 ).unwrap();
671 for scene_op in &self.scene_ops {
672 writeln!(f, "\t\t{:?}", scene_op).unwrap();
673 }
674
675 for frame_op in &self.frame_ops {
676 writeln!(f, "\t\t{:?}", frame_op).unwrap();
677 }
678
679 for resource_update in &self.resource_updates {
680 writeln!(f, "\t\t{:?}", resource_update).unwrap();
681 }
682 Ok(())
683 }
684}
685
686impl TransactionMsg {
687 pub fn is_empty(&self) -> bool {
689 !self.generate_frame.as_bool() &&
690 !self.invalidate_rendered_frame &&
691 self.scene_ops.is_empty() &&
692 self.frame_ops.is_empty() &&
693 self.resource_updates.is_empty() &&
694 self.notifications.is_empty()
695 }
696}
697
698#[derive(Clone)]
702#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
703pub struct AddImage {
704 pub key: ImageKey,
706 pub descriptor: ImageDescriptor,
708 pub data: ImageData,
710 pub tiling: Option<TileSize>,
716}
717
718#[derive(Clone)]
720#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
721pub struct UpdateImage {
722 pub key: ImageKey,
724 pub descriptor: ImageDescriptor,
726 pub data: ImageData,
728 pub dirty_rect: ImageDirtyRect,
733}
734
735#[derive(Clone)]
739#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
740pub struct AddBlobImage {
741 pub key: BlobImageKey,
743 pub descriptor: ImageDescriptor,
745 pub data: Arc<BlobImageData>,
747 pub visible_rect: DeviceIntRect,
756 pub tile_size: TileSize,
762}
763
764#[derive(Clone)]
766#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
767pub struct UpdateBlobImage {
768 pub key: BlobImageKey,
770 pub descriptor: ImageDescriptor,
772 pub data: Arc<BlobImageData>,
774 pub visible_rect: DeviceIntRect,
776 pub dirty_rect: BlobDirtyRect,
779}
780
781#[derive(Clone)]
785#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
786pub struct AddSnapshotImage {
787 pub key: SnapshotImageKey,
789}
790
791#[derive(Clone)]
796#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
797pub enum AddFont {
798 Raw(FontKey, Arc<Vec<u8>>, u32),
800 Native(FontKey, NativeFontHandle),
802}
803
804#[derive(Clone)]
809#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
810pub struct AddFontInstance {
811 pub key: FontInstanceKey,
813 pub font_key: FontKey,
815 pub glyph_size: f32,
817 pub options: Option<FontInstanceOptions>,
819 pub platform_options: Option<FontInstancePlatformOptions>,
821 pub variations: Vec<FontVariation>,
823}
824
825pub enum SceneMsg {
827 UpdateEpoch(PipelineId, Epoch),
829 SetRootPipeline(PipelineId),
831 RemovePipeline(PipelineId),
833 SetDisplayList {
835 display_list: BuiltDisplayList,
837 epoch: Epoch,
839 pipeline_id: PipelineId,
841 },
842 RenderOffscreen(PipelineId),
847 SetDocumentView {
849 device_rect: DeviceIntRect,
851 },
852 SetQualitySettings {
854 settings: QualitySettings,
856 },
857}
858
859pub enum FrameMsg {
861 UpdateEpoch(PipelineId, Epoch),
863 HitTest(WorldPoint, Sender<HitTestResult>),
865 RequestHitTester(Sender<Arc<dyn ApiHitTester>>),
867 SetScrollOffsets(ExternalScrollId, Vec<SampledScrollOffset>),
869 ResetDynamicProperties,
871 AppendDynamicProperties(DynamicProperties),
873 AppendDynamicTransformProperties(Vec<PropertyValue<LayoutTransform>>),
875 SetIsTransformAsyncZooming(bool, PropertyBindingId),
877 SetMinimapData(ExternalScrollId, MinimapData)
879}
880
881impl fmt::Debug for SceneMsg {
882 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
883 f.write_str(match *self {
884 SceneMsg::UpdateEpoch(..) => "SceneMsg::UpdateEpoch",
885 SceneMsg::SetDisplayList { .. } => "SceneMsg::SetDisplayList",
886 SceneMsg::RemovePipeline(..) => "SceneMsg::RemovePipeline",
887 SceneMsg::SetDocumentView { .. } => "SceneMsg::SetDocumentView",
888 SceneMsg::SetRootPipeline(..) => "SceneMsg::SetRootPipeline",
889 SceneMsg::SetQualitySettings { .. } => "SceneMsg::SetQualitySettings",
890 SceneMsg::RenderOffscreen(..) => "SceneMsg::BuildOffscreen",
891 })
892 }
893}
894
895impl fmt::Debug for FrameMsg {
896 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
897 f.write_str(match *self {
898 FrameMsg::UpdateEpoch(..) => "FrameMsg::UpdateEpoch",
899 FrameMsg::HitTest(..) => "FrameMsg::HitTest",
900 FrameMsg::RequestHitTester(..) => "FrameMsg::RequestHitTester",
901 FrameMsg::SetScrollOffsets(..) => "FrameMsg::SetScrollOffsets",
902 FrameMsg::ResetDynamicProperties => "FrameMsg::ResetDynamicProperties",
903 FrameMsg::AppendDynamicProperties(..) => "FrameMsg::AppendDynamicProperties",
904 FrameMsg::AppendDynamicTransformProperties(..) => "FrameMsg::AppendDynamicTransformProperties",
905 FrameMsg::SetIsTransformAsyncZooming(..) => "FrameMsg::SetIsTransformAsyncZooming",
906 FrameMsg::SetMinimapData(..) => "FrameMsg::SetMinimapData",
907 })
908 }
909}
910
911bitflags!{
912 #[derive(Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
915 pub struct CaptureBits: u8 {
916 const SCENE = 0x1;
918 const FRAME = 0x2;
920 const TILE_CACHE = 0x4;
922 const EXTERNAL_RESOURCES = 0x8;
924 }
925}
926
927bitflags!{
928 #[derive(Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
930 pub struct ClearCache: u8 {
931 const IMAGES = 0b1;
933 const GLYPHS = 0b10;
935 const GLYPH_DIMENSIONS = 0b100;
937 const RENDER_TASKS = 0b1000;
939 const TEXTURE_CACHE = 0b10000;
941 const RENDER_TARGETS = 0b100000;
943 }
944}
945
946#[derive(Clone, Debug)]
949pub struct CapturedDocument {
950 pub document_id: DocumentId,
952 pub root_pipeline_id: Option<PipelineId>,
954}
955
956pub enum DebugCommand {
958 SetFlags(DebugFlags),
960 GetDebugFlags(Sender<DebugFlags>),
962 SaveCapture(PathBuf, CaptureBits),
964 LoadCapture(PathBuf, Option<(u32, u32)>, Sender<CapturedDocument>),
966 StartCaptureSequence(PathBuf, CaptureBits),
968 StopCaptureSequence,
970 ClearCaches(ClearCache),
972 EnableNativeCompositor(bool),
974 SetBatchingLookback(u32),
976 InvalidateGpuCache,
978 SimulateLongSceneBuild(u32),
981 SetPictureTileSize(Option<DeviceIntSize>),
983 SetMaximumSurfaceSize(Option<usize>),
985 GenerateFrame,
987 #[cfg(feature = "debugger")]
988 Query(DebugQuery),
990 #[cfg(feature = "debugger")]
991 AddDebugClient(DebuggerClient),
993}
994
995pub enum ApiMsg {
997 CloneApi(Sender<IdNamespace>),
999 CloneApiByClient(IdNamespace),
1001 AddDocument(DocumentId, DeviceIntSize),
1003 UpdateDocuments(Vec<Box<TransactionMsg>>),
1005 MemoryPressure,
1007 ReportMemory(Sender<Box<MemoryReport>>),
1009 DebugCommand(DebugCommand),
1011 SceneBuilderResult(SceneBuilderResult),
1013}
1014
1015impl fmt::Debug for ApiMsg {
1016 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1017 f.write_str(match *self {
1018 ApiMsg::CloneApi(..) => "ApiMsg::CloneApi",
1019 ApiMsg::CloneApiByClient(..) => "ApiMsg::CloneApiByClient",
1020 ApiMsg::AddDocument(..) => "ApiMsg::AddDocument",
1021 ApiMsg::UpdateDocuments(..) => "ApiMsg::UpdateDocuments",
1022 ApiMsg::MemoryPressure => "ApiMsg::MemoryPressure",
1023 ApiMsg::ReportMemory(..) => "ApiMsg::ReportMemory",
1024 ApiMsg::DebugCommand(..) => "ApiMsg::DebugCommand",
1025 ApiMsg::SceneBuilderResult(..) => "ApiMsg::SceneBuilderResult",
1026 })
1027 }
1028}
1029
1030pub struct RenderApiSender {
1035 api_sender: Sender<ApiMsg>,
1036 scene_sender: Sender<SceneBuilderRequest>,
1037 low_priority_scene_sender: Sender<SceneBuilderRequest>,
1038 blob_image_handler: Option<Box<dyn BlobImageHandler>>,
1039 fonts: SharedFontResources,
1040}
1041
1042impl RenderApiSender {
1043 pub fn new(
1045 api_sender: Sender<ApiMsg>,
1046 scene_sender: Sender<SceneBuilderRequest>,
1047 low_priority_scene_sender: Sender<SceneBuilderRequest>,
1048 blob_image_handler: Option<Box<dyn BlobImageHandler>>,
1049 fonts: SharedFontResources,
1050 ) -> Self {
1051 RenderApiSender {
1052 api_sender,
1053 scene_sender,
1054 low_priority_scene_sender,
1055 blob_image_handler,
1056 fonts,
1057 }
1058 }
1059
1060 pub fn create_api(&self) -> RenderApi {
1062 let (sync_tx, sync_rx) = single_msg_channel();
1063 let msg = ApiMsg::CloneApi(sync_tx);
1064 self.api_sender.send(msg).expect("Failed to send CloneApi message");
1065 let namespace_id = sync_rx.recv().expect("Failed to receive CloneApi reply");
1066 RenderApi {
1067 api_sender: self.api_sender.clone(),
1068 scene_sender: self.scene_sender.clone(),
1069 low_priority_scene_sender: self.low_priority_scene_sender.clone(),
1070 namespace_id,
1071 next_id: Cell::new(ResourceId(0)),
1072 resources: ApiResources::new(
1073 self.blob_image_handler.as_ref().map(|handler| handler.create_similar()),
1074 self.fonts.clone(),
1075 ),
1076 }
1077 }
1078
1079 pub fn create_api_by_client(&self, namespace_id: IdNamespace) -> RenderApi {
1085 let msg = ApiMsg::CloneApiByClient(namespace_id);
1086 self.api_sender.send(msg).expect("Failed to send CloneApiByClient message");
1087 RenderApi {
1088 api_sender: self.api_sender.clone(),
1089 scene_sender: self.scene_sender.clone(),
1090 low_priority_scene_sender: self.low_priority_scene_sender.clone(),
1091 namespace_id,
1092 next_id: Cell::new(ResourceId(0)),
1093 resources: ApiResources::new(
1094 self.blob_image_handler.as_ref().map(|handler| handler.create_similar()),
1095 self.fonts.clone(),
1096 ),
1097 }
1098 }
1099}
1100
1101pub struct RenderApi {
1103 api_sender: Sender<ApiMsg>,
1104 scene_sender: Sender<SceneBuilderRequest>,
1105 low_priority_scene_sender: Sender<SceneBuilderRequest>,
1106 namespace_id: IdNamespace,
1107 next_id: Cell<ResourceId>,
1108 resources: ApiResources,
1109}
1110
1111impl RenderApi {
1112 pub fn get_namespace_id(&self) -> IdNamespace {
1114 self.namespace_id
1115 }
1116
1117 pub fn create_sender(&self) -> RenderApiSender {
1119 RenderApiSender::new(
1120 self.api_sender.clone(),
1121 self.scene_sender.clone(),
1122 self.low_priority_scene_sender.clone(),
1123 self.resources.blob_image_handler.as_ref().map(|handler| handler.create_similar()),
1124 self.resources.get_fonts(),
1125 )
1126 }
1127
1128 pub fn add_document(&self, initial_size: DeviceIntSize) -> DocumentId {
1134 let new_id = self.next_unique_id();
1135 self.add_document_with_id(initial_size, new_id)
1136 }
1137
1138 pub fn add_document_with_id(&self,
1140 initial_size: DeviceIntSize,
1141 id: u32) -> DocumentId {
1142 window_size_sanity_check(initial_size);
1143
1144 let document_id = DocumentId::new(self.namespace_id, id);
1145
1146 self.api_sender.send(
1152 ApiMsg::AddDocument(document_id, initial_size)
1153 ).unwrap();
1154 self.scene_sender.send(
1155 SceneBuilderRequest::AddDocument(document_id, initial_size)
1156 ).unwrap();
1157
1158 document_id
1159 }
1160
1161 pub fn delete_document(&self, document_id: DocumentId) {
1163 self.low_priority_scene_sender.send(
1164 SceneBuilderRequest::DeleteDocument(document_id)
1165 ).unwrap();
1166 }
1167
1168 pub fn generate_font_key(&self) -> FontKey {
1170 let new_id = self.next_unique_id();
1171 FontKey::new(self.namespace_id, new_id)
1172 }
1173
1174 pub fn generate_font_instance_key(&self) -> FontInstanceKey {
1176 let new_id = self.next_unique_id();
1177 FontInstanceKey::new(self.namespace_id, new_id)
1178 }
1179
1180 pub fn get_glyph_dimensions(
1186 &self,
1187 key: FontInstanceKey,
1188 glyph_indices: Vec<GlyphIndex>,
1189 ) -> Vec<Option<GlyphDimensions>> {
1190 let (sender, rx) = single_msg_channel();
1191 let msg = SceneBuilderRequest::GetGlyphDimensions(GlyphDimensionRequest {
1192 key,
1193 glyph_indices,
1194 sender
1195 });
1196 self.low_priority_scene_sender.send(msg).unwrap();
1197 rx.recv().unwrap()
1198 }
1199
1200 pub fn get_glyph_indices(&self, key: FontKey, text: &str) -> Vec<Option<u32>> {
1203 let (sender, rx) = single_msg_channel();
1204 let msg = SceneBuilderRequest::GetGlyphIndices(GlyphIndexRequest {
1205 key,
1206 text: text.to_string(),
1207 sender,
1208 });
1209 self.low_priority_scene_sender.send(msg).unwrap();
1210 rx.recv().unwrap()
1211 }
1212
1213 pub fn generate_image_key(&self) -> ImageKey {
1215 let new_id = self.next_unique_id();
1216 ImageKey::new(self.namespace_id, new_id)
1217 }
1218
1219 pub fn generate_blob_image_key(&self) -> BlobImageKey {
1221 BlobImageKey(self.generate_image_key())
1222 }
1223
1224 pub fn send_external_event(&self, evt: ExternalEvent) {
1228 let msg = SceneBuilderRequest::ExternalEvent(evt);
1229 self.low_priority_scene_sender.send(msg).unwrap();
1230 }
1231
1232 pub fn notify_memory_pressure(&self) {
1235 self.api_sender.send(ApiMsg::MemoryPressure).unwrap();
1236 }
1237
1238 pub fn report_memory(&self, _ops: malloc_size_of::MallocSizeOfOps) -> MemoryReport {
1240 let (tx, rx) = single_msg_channel();
1241 self.api_sender.send(ApiMsg::ReportMemory(tx)).unwrap();
1242 *rx.recv().unwrap()
1243 }
1244
1245 pub fn set_debug_flags(&mut self, flags: DebugFlags) {
1247 self.resources.set_debug_flags(flags);
1248 let cmd = DebugCommand::SetFlags(flags);
1249 self.api_sender.send(ApiMsg::DebugCommand(cmd)).unwrap();
1250 self.scene_sender.send(SceneBuilderRequest ::SetFlags(flags)).unwrap();
1251 self.low_priority_scene_sender.send(SceneBuilderRequest ::SetFlags(flags)).unwrap();
1252 }
1253
1254 pub fn stop_render_backend(&self) {
1256 self.low_priority_scene_sender.send(SceneBuilderRequest::StopRenderBackend).unwrap();
1257 }
1258
1259 pub fn shut_down(&self, synchronously: bool) {
1261 if synchronously {
1262 let (tx, rx) = single_msg_channel();
1263 self.low_priority_scene_sender.send(SceneBuilderRequest::ShutDown(Some(tx))).unwrap();
1264 rx.recv().unwrap();
1265 } else {
1266 self.low_priority_scene_sender.send(SceneBuilderRequest::ShutDown(None)).unwrap();
1267 }
1268 }
1269
1270 pub fn generate_property_binding_key<T: Copy>(&self) -> PropertyBindingKey<T> {
1273 let new_id = self.next_unique_id();
1274 PropertyBindingKey {
1275 id: PropertyBindingId {
1276 namespace: self.namespace_id,
1277 uid: new_id,
1278 },
1279 _phantom: PhantomData,
1280 }
1281 }
1282
1283 #[inline]
1284 fn next_unique_id(&self) -> u32 {
1285 let ResourceId(id) = self.next_id.get();
1286 self.next_id.set(ResourceId(id + 1));
1287 id
1288 }
1289
1290 #[doc(hidden)]
1292 pub fn send_message(&self, msg: ApiMsg) {
1293 self.api_sender.send(msg).unwrap();
1294 }
1295
1296 fn frame_message(&self, msg: FrameMsg, document_id: DocumentId) -> Box<TransactionMsg> {
1298 Box::new(TransactionMsg {
1299 document_id,
1300 scene_ops: Vec::new(),
1301 frame_ops: vec![msg],
1302 resource_updates: Vec::new(),
1303 notifications: Vec::new(),
1304 generate_frame: GenerateFrame::No,
1305 creation_time: None,
1306 invalidate_rendered_frame: false,
1307 use_scene_builder_thread: false,
1308 low_priority: false,
1309 blob_rasterizer: None,
1310 blob_requests: Vec::new(),
1311 rasterized_blobs: Vec::new(),
1312 profile: TransactionProfile::new(),
1313 render_reasons: RenderReasons::empty(),
1314 })
1315 }
1316
1317 fn send_frame_msg(&self, document_id: DocumentId, msg: FrameMsg) {
1319 self.api_sender
1323 .send(ApiMsg::UpdateDocuments(vec![self.frame_message(msg, document_id)]))
1324 .unwrap()
1325 }
1326
1327 pub fn send_transaction(&mut self, document_id: DocumentId, transaction: Transaction) {
1329 let mut transaction = transaction.finalize(document_id);
1330
1331 self.resources.update(&mut transaction);
1332
1333 if transaction.generate_frame.as_bool() {
1334 transaction.profile.start_time(profiler::API_SEND_TIME);
1335 transaction.profile.start_time(profiler::TOTAL_FRAME_CPU_TIME);
1336 }
1337
1338 if transaction.use_scene_builder_thread {
1339 let sender = if transaction.low_priority {
1340 &mut self.low_priority_scene_sender
1341 } else {
1342 &mut self.scene_sender
1343 };
1344
1345 sender.send(SceneBuilderRequest::Transactions(vec![transaction]))
1346 .expect("send by scene sender failed");
1347 } else {
1348 self.api_sender.send(ApiMsg::UpdateDocuments(vec![transaction]))
1349 .expect("send by api sender failed");
1350 }
1351 }
1352
1353 pub fn hit_test(&self,
1359 document_id: DocumentId,
1360 point: WorldPoint,
1361 ) -> HitTestResult {
1362 let (tx, rx) = single_msg_channel();
1363
1364 self.send_frame_msg(
1365 document_id,
1366 FrameMsg::HitTest(point, tx)
1367 );
1368 rx.recv().unwrap()
1369 }
1370
1371 pub fn request_hit_tester(&self, document_id: DocumentId) -> HitTesterRequest {
1373 let (tx, rx) = single_msg_channel();
1374 self.send_frame_msg(
1375 document_id,
1376 FrameMsg::RequestHitTester(tx)
1377 );
1378
1379 HitTesterRequest { rx }
1380 }
1381
1382 #[doc(hidden)]
1385 pub fn wake_scene_builder(&self) {
1386 self.scene_sender.send(SceneBuilderRequest::WakeUp).unwrap();
1387 }
1388
1389 pub fn flush_scene_builder(&self) {
1393 let (tx, rx) = single_msg_channel();
1394 self.low_priority_scene_sender.send(SceneBuilderRequest::Flush(tx)).unwrap();
1395 rx.recv().unwrap(); }
1397
1398 pub fn save_capture(&self, path: PathBuf, bits: CaptureBits) {
1400 let msg = ApiMsg::DebugCommand(DebugCommand::SaveCapture(path, bits));
1401 self.send_message(msg);
1402 }
1403
1404 pub fn load_capture(&self, path: PathBuf, ids: Option<(u32, u32)>) -> Vec<CapturedDocument> {
1406 self.flush_scene_builder();
1409
1410 let (tx, rx) = unbounded_channel();
1411 let msg = ApiMsg::DebugCommand(DebugCommand::LoadCapture(path, ids, tx));
1412 self.send_message(msg);
1413
1414 let mut documents = Vec::new();
1415 while let Ok(captured_doc) = rx.recv() {
1416 documents.push(captured_doc);
1417 }
1418 documents
1419 }
1420
1421 pub fn start_capture_sequence(&self, path: PathBuf, bits: CaptureBits) {
1423 let msg = ApiMsg::DebugCommand(DebugCommand::StartCaptureSequence(path, bits));
1424 self.send_message(msg);
1425 }
1426
1427 pub fn stop_capture_sequence(&self) {
1429 let msg = ApiMsg::DebugCommand(DebugCommand::StopCaptureSequence);
1430 self.send_message(msg);
1431 }
1432
1433 pub fn get_debug_flags(&self) -> DebugFlags {
1435 let (tx, rx) = unbounded_channel();
1436 let msg = ApiMsg::DebugCommand(DebugCommand::GetDebugFlags(tx));
1437 self.send_message(msg);
1438 rx.recv().unwrap()
1439 }
1440
1441 pub fn send_debug_cmd(&self, cmd: DebugCommand) {
1443 let msg = ApiMsg::DebugCommand(cmd);
1444 self.send_message(msg);
1445 }
1446
1447 pub fn set_parameter(&mut self, parameter: Parameter) {
1449 if let Parameter::Bool(BoolParameter::Multithreading, enabled) = parameter {
1450 self.resources.enable_multithreading(enabled);
1451 }
1452
1453 let _ = self.low_priority_scene_sender.send(
1454 SceneBuilderRequest::SetParameter(parameter)
1455 );
1456 }
1457}
1458
1459impl Drop for RenderApi {
1460 fn drop(&mut self) {
1461 let msg = SceneBuilderRequest::ClearNamespace(self.namespace_id);
1462 let _ = self.low_priority_scene_sender.send(msg);
1463 }
1464}
1465
1466
1467fn window_size_sanity_check(size: DeviceIntSize) {
1468 use crate::api::MAX_RENDER_TASK_SIZE;
1471 if size.width > MAX_RENDER_TASK_SIZE || size.height > MAX_RENDER_TASK_SIZE {
1472 panic!("Attempting to create a {}x{} window/document", size.width, size.height);
1473 }
1474}
1475
1476#[repr(C)]
1480#[allow(missing_docs)]
1481#[derive(AddAssign, Clone, Debug, Default)]
1482pub struct MemoryReport {
1483 pub clip_stores: usize,
1487 pub gpu_cache_metadata: usize,
1488 pub gpu_cache_cpu_mirror: usize,
1489 pub hit_testers: usize,
1490 pub fonts: usize,
1491 pub weak_fonts: usize,
1492 pub images: usize,
1493 pub rasterized_blobs: usize,
1494 pub shader_cache: usize,
1495 pub interning: InterningMemoryReport,
1496 pub display_list: usize,
1497 pub upload_staging_memory: usize,
1498 pub swgl: usize,
1499 pub frame_allocator: usize,
1500 pub render_tasks: usize,
1501
1502 pub gpu_cache_textures: usize,
1506 pub vertex_data_textures: usize,
1507 pub render_target_textures: usize,
1508 pub picture_tile_textures: usize,
1509 pub atlas_textures: usize,
1510 pub standalone_textures: usize,
1511 pub texture_cache_structures: usize,
1512 pub depth_target_textures: usize,
1513 pub texture_upload_pbos: usize,
1514 pub swap_chain: usize,
1515 pub render_texture_hosts: usize,
1516 pub upload_staging_textures: usize,
1517}