1#![deny(missing_docs)]
6
7use api::precise_time_ns;
8use std::cell::Cell;
9use std::fmt;
10use std::marker::PhantomData;
11use std::path::PathBuf;
12use std::sync::Arc;
13use std::u32;
14use api::{HitTestFlags, MinimapData, SnapshotImageKey};
15use crate::api::channel::{Sender, single_msg_channel, unbounded_channel};
16use crate::api::{BuiltDisplayList, IdNamespace, ExternalScrollId, Parameter, BoolParameter};
17use crate::api::{FontKey, FontInstanceKey, NativeFontHandle};
18use crate::api::{BlobImageData, BlobImageKey, ImageData, ImageDescriptor, ImageKey, Epoch, QualitySettings};
19use crate::api::{BlobImageParams, BlobImageRequest, BlobImageResult, AsyncBlobImageRasterizer, BlobImageHandler};
20use crate::api::{DocumentId, PipelineId, PropertyBindingId, PropertyBindingKey, ExternalEvent};
21use crate::api::{HitTestResult, HitTesterRequest, ApiHitTester, PropertyValue, DynamicProperties};
22use crate::api::{SampledScrollOffset, TileSize, NotificationRequest, DebugFlags};
23use crate::api::{GlyphDimensionRequest, GlyphIndexRequest, GlyphIndex, GlyphDimensions};
24use crate::api::{FontInstanceOptions, FontInstancePlatformOptions, FontVariation, RenderReasons};
25use crate::api::DEFAULT_TILE_SIZE;
26use crate::api::units::*;
27use crate::api_resources::ApiResources;
28use glyph_rasterizer::SharedFontResources;
29use crate::scene_builder_thread::{SceneBuilderRequest, SceneBuilderResult};
30use crate::intern::InterningMemoryReport;
31use crate::profiler::{self, TransactionProfile};
32
33#[repr(C)]
34#[derive(Clone, Copy, Debug)]
35#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
36struct ResourceId(pub u32);
37
38#[derive(Clone)]
42#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
43pub enum ResourceUpdate {
44 AddImage(AddImage),
46 UpdateImage(UpdateImage),
48 DeleteImage(ImageKey),
54 AddBlobImage(AddBlobImage),
56 UpdateBlobImage(UpdateBlobImage),
58 DeleteBlobImage(BlobImageKey),
60 SetBlobImageVisibleArea(BlobImageKey, DeviceIntRect),
62 AddSnapshotImage(AddSnapshotImage),
64 DeleteSnapshotImage(SnapshotImageKey),
66 AddFont(AddFont),
68 DeleteFont(FontKey),
74 AddFontInstance(AddFontInstance),
76 DeleteFontInstance(FontInstanceKey),
82}
83
84impl fmt::Debug for ResourceUpdate {
85 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86 match self {
87 ResourceUpdate::AddImage(ref i) => f.write_fmt(format_args!(
88 "ResourceUpdate::AddImage size({:?})",
89 &i.descriptor.size
90 )),
91 ResourceUpdate::UpdateImage(ref i) => f.write_fmt(format_args!(
92 "ResourceUpdate::UpdateImage size({:?})",
93 &i.descriptor.size
94 )),
95 ResourceUpdate::AddBlobImage(ref i) => f.write_fmt(format_args!(
96 "ResourceUFpdate::AddBlobImage size({:?})",
97 &i.descriptor.size
98 )),
99 ResourceUpdate::UpdateBlobImage(i) => f.write_fmt(format_args!(
100 "ResourceUpdate::UpdateBlobImage size({:?})",
101 &i.descriptor.size
102 )),
103 ResourceUpdate::DeleteImage(..) => f.write_str("ResourceUpdate::DeleteImage"),
104 ResourceUpdate::DeleteBlobImage(..) => f.write_str("ResourceUpdate::DeleteBlobImage"),
105 ResourceUpdate::SetBlobImageVisibleArea(..) => f.write_str("ResourceUpdate::SetBlobImageVisibleArea"),
106 ResourceUpdate::AddSnapshotImage(..) => f.write_str("ResourceUpdate::AddSnapshotImage"),
107 ResourceUpdate::DeleteSnapshotImage(..) => f.write_str("ResourceUpdate::DeleteSnapshotImage"),
108 ResourceUpdate::AddFont(..) => f.write_str("ResourceUpdate::AddFont"),
109 ResourceUpdate::DeleteFont(..) => f.write_str("ResourceUpdate::DeleteFont"),
110 ResourceUpdate::AddFontInstance(..) => f.write_str("ResourceUpdate::AddFontInstance"),
111 ResourceUpdate::DeleteFontInstance(..) => f.write_str("ResourceUpdate::DeleteFontInstance"),
112 }
113 }
114}
115
116#[derive(Clone, Debug)]
119pub enum GenerateFrame {
120 Yes {
122 id: u64,
125 present: bool,
128 },
129 No,
131}
132
133impl GenerateFrame {
134 pub fn as_bool(&self) -> bool {
136 match self {
137 GenerateFrame::Yes { .. } => true,
138 GenerateFrame::No => false,
139 }
140 }
141
142 pub fn present(&self) -> bool {
145 match self {
146 GenerateFrame::Yes { present, .. } => *present,
147 GenerateFrame::No => false,
148 }
149 }
150
151 pub fn id(&self) -> Option<u64> {
153 match self {
154 GenerateFrame::Yes { id, .. } => Some(*id),
155 GenerateFrame::No => None,
156 }
157 }
158}
159
160pub struct Transaction {
167 scene_ops: Vec<SceneMsg>,
169 frame_ops: Vec<FrameMsg>,
171
172 notifications: Vec<NotificationRequest>,
173
174 pub resource_updates: Vec<ResourceUpdate>,
176
177 use_scene_builder_thread: bool,
185
186 generate_frame: GenerateFrame,
190
191 creation_time: u64,
193
194 pub invalidate_rendered_frame: bool,
197
198 low_priority: bool,
199
200 pub render_reasons: RenderReasons,
202}
203
204impl Transaction {
205 pub fn new() -> Self {
207 Transaction {
208 scene_ops: Vec::new(),
209 frame_ops: Vec::new(),
210 resource_updates: Vec::new(),
211 notifications: Vec::new(),
212 use_scene_builder_thread: true,
213 generate_frame: GenerateFrame::No,
214 creation_time: precise_time_ns(),
215 invalidate_rendered_frame: false,
216 low_priority: false,
217 render_reasons: RenderReasons::empty(),
218 }
219 }
220
221 pub fn skip_scene_builder(&mut self) {
230 self.use_scene_builder_thread = false;
231 }
232
233 pub fn use_scene_builder_thread(&mut self) {
235 self.use_scene_builder_thread = true;
236 }
237
238 pub fn is_empty(&self) -> bool {
240 !self.generate_frame.as_bool() &&
241 !self.invalidate_rendered_frame &&
242 self.scene_ops.is_empty() &&
243 self.frame_ops.is_empty() &&
244 self.resource_updates.is_empty() &&
245 self.notifications.is_empty()
246 }
247
248 pub fn update_epoch(&mut self, pipeline_id: PipelineId, epoch: Epoch) {
250 self.scene_ops.push(SceneMsg::UpdateEpoch(pipeline_id, epoch));
253 self.frame_ops.push(FrameMsg::UpdateEpoch(pipeline_id, epoch));
256 }
260
261 pub fn set_root_pipeline(&mut self, pipeline_id: PipelineId) {
276 self.scene_ops.push(SceneMsg::SetRootPipeline(pipeline_id));
277 }
278
279 pub fn remove_pipeline(&mut self, pipeline_id: PipelineId) {
283 self.scene_ops.push(SceneMsg::RemovePipeline(pipeline_id));
284 }
285
286 pub fn set_display_list(
298 &mut self,
299 epoch: Epoch,
300 (pipeline_id, mut display_list): (PipelineId, BuiltDisplayList),
301 ) {
302 display_list.set_send_time_ns(precise_time_ns());
303 self.scene_ops.push(
304 SceneMsg::SetDisplayList {
305 display_list,
306 epoch,
307 pipeline_id,
308 }
309 );
310 }
311
312 pub fn update_resources(&mut self, mut resources: Vec<ResourceUpdate>) {
314 self.resource_updates.append(&mut resources);
315 }
316
317 pub fn notify(&mut self, event: NotificationRequest) {
329 self.notifications.push(event);
330 }
331
332 pub fn set_document_view(
334 &mut self,
335 device_rect: DeviceIntRect,
336 ) {
337 window_size_sanity_check(device_rect.size());
338 self.scene_ops.push(
339 SceneMsg::SetDocumentView {
340 device_rect,
341 },
342 );
343 }
344
345 pub fn set_scroll_offsets(
349 &mut self,
350 id: ExternalScrollId,
351 sampled_scroll_offsets: Vec<SampledScrollOffset>,
352 ) {
353 self.frame_ops.push(FrameMsg::SetScrollOffsets(id, sampled_scroll_offsets));
354 }
355
356 pub fn set_quality_settings(&mut self, settings: QualitySettings) {
358 self.scene_ops.push(SceneMsg::SetQualitySettings { settings });
359 }
360
361 pub fn set_is_transform_async_zooming(&mut self, is_zooming: bool, animation_id: PropertyBindingId) {
363 self.frame_ops.push(FrameMsg::SetIsTransformAsyncZooming(is_zooming, animation_id));
364 }
365
366 pub fn set_minimap_data(&mut self, id: ExternalScrollId, minimap_data: MinimapData) {
368 self.frame_ops.push(FrameMsg::SetMinimapData(id, minimap_data));
369 }
370
371 pub fn generate_frame(&mut self, id: u64, present: bool, reasons: RenderReasons) {
379 self.generate_frame = GenerateFrame::Yes{ id, present };
380 self.render_reasons |= reasons;
381 }
382
383 pub fn invalidate_rendered_frame(&mut self, reasons: RenderReasons) {
390 self.invalidate_rendered_frame = true;
391 self.render_reasons |= reasons
392 }
393
394 pub fn reset_dynamic_properties(&mut self) {
397 self.frame_ops.push(FrameMsg::ResetDynamicProperties);
398 }
399
400 pub fn append_dynamic_properties(&mut self, properties: DynamicProperties) {
403 self.frame_ops.push(FrameMsg::AppendDynamicProperties(properties));
404 }
405
406 pub fn append_dynamic_transform_properties(&mut self, transforms: Vec<PropertyValue<LayoutTransform>>) {
411 self.frame_ops.push(FrameMsg::AppendDynamicTransformProperties(transforms));
412 }
413
414 pub fn get_frame_ops(self) -> Vec<FrameMsg> {
416 self.frame_ops
417 }
418
419 fn finalize(self, document_id: DocumentId) -> Box<TransactionMsg> {
420 Box::new(TransactionMsg {
421 document_id,
422 scene_ops: self.scene_ops,
423 frame_ops: self.frame_ops,
424 resource_updates: self.resource_updates,
425 notifications: self.notifications,
426 use_scene_builder_thread: self.use_scene_builder_thread,
427 generate_frame: self.generate_frame,
428 creation_time: Some(self.creation_time),
429 invalidate_rendered_frame: self.invalidate_rendered_frame,
430 low_priority: self.low_priority,
431 blob_rasterizer: None,
432 blob_requests: Vec::new(),
433 rasterized_blobs: Vec::new(),
434 profile: TransactionProfile::new(),
435 render_reasons: self.render_reasons,
436 })
437 }
438
439 pub fn add_image(
441 &mut self,
442 key: ImageKey,
443 descriptor: ImageDescriptor,
444 data: ImageData,
445 tiling: Option<TileSize>,
446 ) {
447 self.resource_updates.push(ResourceUpdate::AddImage(AddImage {
448 key,
449 descriptor,
450 data,
451 tiling,
452 }));
453 }
454
455 pub fn update_image(
457 &mut self,
458 key: ImageKey,
459 descriptor: ImageDescriptor,
460 data: ImageData,
461 dirty_rect: &ImageDirtyRect,
462 ) {
463 self.resource_updates.push(ResourceUpdate::UpdateImage(UpdateImage {
464 key,
465 descriptor,
466 data,
467 dirty_rect: *dirty_rect,
468 }));
469 }
470
471 pub fn delete_image(&mut self, key: ImageKey) {
473 self.resource_updates.push(ResourceUpdate::DeleteImage(key));
474 }
475
476 pub fn add_blob_image(
478 &mut self,
479 key: BlobImageKey,
480 descriptor: ImageDescriptor,
481 data: Arc<BlobImageData>,
482 visible_rect: DeviceIntRect,
483 tile_size: Option<TileSize>,
484 ) {
485 self.resource_updates.push(
486 ResourceUpdate::AddBlobImage(AddBlobImage {
487 key,
488 descriptor,
489 data,
490 visible_rect,
491 tile_size: tile_size.unwrap_or(DEFAULT_TILE_SIZE),
492 })
493 );
494 }
495
496 pub fn update_blob_image(
498 &mut self,
499 key: BlobImageKey,
500 descriptor: ImageDescriptor,
501 data: Arc<BlobImageData>,
502 visible_rect: DeviceIntRect,
503 dirty_rect: &BlobDirtyRect,
504 ) {
505 self.resource_updates.push(
506 ResourceUpdate::UpdateBlobImage(UpdateBlobImage {
507 key,
508 descriptor,
509 data,
510 visible_rect,
511 dirty_rect: *dirty_rect,
512 })
513 );
514 }
515
516 pub fn delete_blob_image(&mut self, key: BlobImageKey) {
518 self.resource_updates.push(ResourceUpdate::DeleteBlobImage(key));
519 }
520
521 pub fn set_blob_image_visible_area(&mut self, key: BlobImageKey, area: DeviceIntRect) {
523 self.resource_updates.push(ResourceUpdate::SetBlobImageVisibleArea(key, area));
524 }
525
526 pub fn add_snapshot_image(
528 &mut self,
529 key: SnapshotImageKey,
530 ) {
531 self.resource_updates.push(
532 ResourceUpdate::AddSnapshotImage(AddSnapshotImage { key })
533 );
534 }
535
536 pub fn delete_snapshot_image(&mut self, key: SnapshotImageKey) {
538 self.resource_updates.push(ResourceUpdate::DeleteSnapshotImage(key));
539 }
540
541 pub fn add_raw_font(&mut self, key: FontKey, bytes: Vec<u8>, index: u32) {
543 self.resource_updates
544 .push(ResourceUpdate::AddFont(AddFont::Raw(key, Arc::new(bytes), index)));
545 }
546
547 pub fn add_native_font(&mut self, key: FontKey, native_handle: NativeFontHandle) {
549 self.resource_updates
550 .push(ResourceUpdate::AddFont(AddFont::Native(key, native_handle)));
551 }
552
553 pub fn delete_font(&mut self, key: FontKey) {
555 self.resource_updates.push(ResourceUpdate::DeleteFont(key));
556 }
557
558 pub fn add_font_instance(
560 &mut self,
561 key: FontInstanceKey,
562 font_key: FontKey,
563 glyph_size: f32,
564 options: Option<FontInstanceOptions>,
565 platform_options: Option<FontInstancePlatformOptions>,
566 variations: Vec<FontVariation>,
567 ) {
568 self.resource_updates
569 .push(ResourceUpdate::AddFontInstance(AddFontInstance {
570 key,
571 font_key,
572 glyph_size,
573 options,
574 platform_options,
575 variations,
576 }));
577 }
578
579 pub fn delete_font_instance(&mut self, key: FontInstanceKey) {
581 self.resource_updates.push(ResourceUpdate::DeleteFontInstance(key));
582 }
583
584 pub fn set_low_priority(&mut self, low_priority: bool) {
589 self.low_priority = low_priority;
590 }
591
592 pub fn is_low_priority(&self) -> bool {
594 self.low_priority
595 }
596}
597
598pub struct DocumentTransaction {
600 pub document_id: DocumentId,
602 pub transaction: Transaction,
604}
605
606pub struct TransactionMsg {
608 pub document_id: DocumentId,
610 pub scene_ops: Vec<SceneMsg>,
612 pub frame_ops: Vec<FrameMsg>,
614 pub resource_updates: Vec<ResourceUpdate>,
616 pub generate_frame: GenerateFrame,
618 pub creation_time: Option<u64>,
620 pub invalidate_rendered_frame: bool,
623 pub use_scene_builder_thread: bool,
625 pub low_priority: bool,
627
628 pub notifications: Vec<NotificationRequest>,
630 pub blob_rasterizer: Option<Box<dyn AsyncBlobImageRasterizer>>,
632 pub blob_requests: Vec<BlobImageParams>,
634 pub rasterized_blobs: Vec<(BlobImageRequest, BlobImageResult)>,
636 pub profile: TransactionProfile,
638 pub render_reasons: RenderReasons,
640}
641
642impl fmt::Debug for TransactionMsg {
643 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
644 writeln!(f, "threaded={}, genframe={:?}, invalidate={}, low_priority={}",
645 self.use_scene_builder_thread,
646 self.generate_frame,
647 self.invalidate_rendered_frame,
648 self.low_priority,
649 ).unwrap();
650 for scene_op in &self.scene_ops {
651 writeln!(f, "\t\t{:?}", scene_op).unwrap();
652 }
653
654 for frame_op in &self.frame_ops {
655 writeln!(f, "\t\t{:?}", frame_op).unwrap();
656 }
657
658 for resource_update in &self.resource_updates {
659 writeln!(f, "\t\t{:?}", resource_update).unwrap();
660 }
661 Ok(())
662 }
663}
664
665impl TransactionMsg {
666 pub fn is_empty(&self) -> bool {
668 !self.generate_frame.as_bool() &&
669 !self.invalidate_rendered_frame &&
670 self.scene_ops.is_empty() &&
671 self.frame_ops.is_empty() &&
672 self.resource_updates.is_empty() &&
673 self.notifications.is_empty()
674 }
675}
676
677#[derive(Clone)]
681#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
682pub struct AddImage {
683 pub key: ImageKey,
685 pub descriptor: ImageDescriptor,
687 pub data: ImageData,
689 pub tiling: Option<TileSize>,
695}
696
697#[derive(Clone)]
699#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
700pub struct UpdateImage {
701 pub key: ImageKey,
703 pub descriptor: ImageDescriptor,
705 pub data: ImageData,
707 pub dirty_rect: ImageDirtyRect,
712}
713
714#[derive(Clone)]
718#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
719pub struct AddBlobImage {
720 pub key: BlobImageKey,
722 pub descriptor: ImageDescriptor,
724 pub data: Arc<BlobImageData>,
726 pub visible_rect: DeviceIntRect,
735 pub tile_size: TileSize,
741}
742
743#[derive(Clone)]
745#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
746pub struct UpdateBlobImage {
747 pub key: BlobImageKey,
749 pub descriptor: ImageDescriptor,
751 pub data: Arc<BlobImageData>,
753 pub visible_rect: DeviceIntRect,
755 pub dirty_rect: BlobDirtyRect,
758}
759
760#[derive(Clone)]
764#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
765pub struct AddSnapshotImage {
766 pub key: SnapshotImageKey,
768}
769
770#[derive(Clone)]
775#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
776pub enum AddFont {
777 Raw(FontKey, Arc<Vec<u8>>, u32),
779 Native(FontKey, NativeFontHandle),
781}
782
783#[derive(Clone)]
788#[cfg_attr(any(feature = "serde"), derive(Deserialize, Serialize))]
789pub struct AddFontInstance {
790 pub key: FontInstanceKey,
792 pub font_key: FontKey,
794 pub glyph_size: f32,
796 pub options: Option<FontInstanceOptions>,
798 pub platform_options: Option<FontInstancePlatformOptions>,
800 pub variations: Vec<FontVariation>,
802}
803
804pub enum SceneMsg {
806 UpdateEpoch(PipelineId, Epoch),
808 SetRootPipeline(PipelineId),
810 RemovePipeline(PipelineId),
812 SetDisplayList {
814 display_list: BuiltDisplayList,
816 epoch: Epoch,
818 pipeline_id: PipelineId,
820 },
821 SetDocumentView {
823 device_rect: DeviceIntRect,
825 },
826 SetQualitySettings {
828 settings: QualitySettings,
830 },
831}
832
833pub enum FrameMsg {
835 UpdateEpoch(PipelineId, Epoch),
837 HitTest(Option<PipelineId>, WorldPoint, HitTestFlags, Sender<HitTestResult>),
839 RequestHitTester(Sender<Arc<dyn ApiHitTester>>),
841 SetScrollOffsets(ExternalScrollId, Vec<SampledScrollOffset>),
843 ResetDynamicProperties,
845 AppendDynamicProperties(DynamicProperties),
847 AppendDynamicTransformProperties(Vec<PropertyValue<LayoutTransform>>),
849 SetIsTransformAsyncZooming(bool, PropertyBindingId),
851 SetMinimapData(ExternalScrollId, MinimapData)
853}
854
855impl fmt::Debug for SceneMsg {
856 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
857 f.write_str(match *self {
858 SceneMsg::UpdateEpoch(..) => "SceneMsg::UpdateEpoch",
859 SceneMsg::SetDisplayList { .. } => "SceneMsg::SetDisplayList",
860 SceneMsg::RemovePipeline(..) => "SceneMsg::RemovePipeline",
861 SceneMsg::SetDocumentView { .. } => "SceneMsg::SetDocumentView",
862 SceneMsg::SetRootPipeline(..) => "SceneMsg::SetRootPipeline",
863 SceneMsg::SetQualitySettings { .. } => "SceneMsg::SetQualitySettings",
864 })
865 }
866}
867
868impl fmt::Debug for FrameMsg {
869 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
870 f.write_str(match *self {
871 FrameMsg::UpdateEpoch(..) => "FrameMsg::UpdateEpoch",
872 FrameMsg::HitTest(..) => "FrameMsg::HitTest",
873 FrameMsg::RequestHitTester(..) => "FrameMsg::RequestHitTester",
874 FrameMsg::SetScrollOffsets(..) => "FrameMsg::SetScrollOffsets",
875 FrameMsg::ResetDynamicProperties => "FrameMsg::ResetDynamicProperties",
876 FrameMsg::AppendDynamicProperties(..) => "FrameMsg::AppendDynamicProperties",
877 FrameMsg::AppendDynamicTransformProperties(..) => "FrameMsg::AppendDynamicTransformProperties",
878 FrameMsg::SetIsTransformAsyncZooming(..) => "FrameMsg::SetIsTransformAsyncZooming",
879 FrameMsg::SetMinimapData(..) => "FrameMsg::SetMinimapData",
880 })
881 }
882}
883
884bitflags!{
885 #[derive(Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
888 pub struct CaptureBits: u8 {
889 const SCENE = 0x1;
891 const FRAME = 0x2;
893 const TILE_CACHE = 0x4;
895 const EXTERNAL_RESOURCES = 0x8;
897 }
898}
899
900bitflags!{
901 #[derive(Debug, Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
903 pub struct ClearCache: u8 {
904 const IMAGES = 0b1;
906 const GLYPHS = 0b10;
908 const GLYPH_DIMENSIONS = 0b100;
910 const RENDER_TASKS = 0b1000;
912 const TEXTURE_CACHE = 0b10000;
914 const RENDER_TARGETS = 0b100000;
916 }
917}
918
919#[derive(Clone, Debug)]
922pub struct CapturedDocument {
923 pub document_id: DocumentId,
925 pub root_pipeline_id: Option<PipelineId>,
927}
928
929#[derive(Clone)]
931pub enum DebugCommand {
932 SetFlags(DebugFlags),
934 SaveCapture(PathBuf, CaptureBits),
936 LoadCapture(PathBuf, Option<(u32, u32)>, Sender<CapturedDocument>),
938 StartCaptureSequence(PathBuf, CaptureBits),
940 StopCaptureSequence,
942 ClearCaches(ClearCache),
944 EnableNativeCompositor(bool),
946 SetBatchingLookback(u32),
948 InvalidateGpuCache,
950 SimulateLongSceneBuild(u32),
953 SetPictureTileSize(Option<DeviceIntSize>),
955 SetMaximumSurfaceSize(Option<usize>),
957}
958
959pub enum ApiMsg {
961 CloneApi(Sender<IdNamespace>),
963 CloneApiByClient(IdNamespace),
965 AddDocument(DocumentId, DeviceIntSize),
967 UpdateDocuments(Vec<Box<TransactionMsg>>),
969 MemoryPressure,
971 ReportMemory(Sender<Box<MemoryReport>>),
973 DebugCommand(DebugCommand),
975 SceneBuilderResult(SceneBuilderResult),
977}
978
979impl fmt::Debug for ApiMsg {
980 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
981 f.write_str(match *self {
982 ApiMsg::CloneApi(..) => "ApiMsg::CloneApi",
983 ApiMsg::CloneApiByClient(..) => "ApiMsg::CloneApiByClient",
984 ApiMsg::AddDocument(..) => "ApiMsg::AddDocument",
985 ApiMsg::UpdateDocuments(..) => "ApiMsg::UpdateDocuments",
986 ApiMsg::MemoryPressure => "ApiMsg::MemoryPressure",
987 ApiMsg::ReportMemory(..) => "ApiMsg::ReportMemory",
988 ApiMsg::DebugCommand(..) => "ApiMsg::DebugCommand",
989 ApiMsg::SceneBuilderResult(..) => "ApiMsg::SceneBuilderResult",
990 })
991 }
992}
993
994pub struct RenderApiSender {
999 api_sender: Sender<ApiMsg>,
1000 scene_sender: Sender<SceneBuilderRequest>,
1001 low_priority_scene_sender: Sender<SceneBuilderRequest>,
1002 blob_image_handler: Option<Box<dyn BlobImageHandler>>,
1003 fonts: SharedFontResources,
1004}
1005
1006impl RenderApiSender {
1007 pub fn new(
1009 api_sender: Sender<ApiMsg>,
1010 scene_sender: Sender<SceneBuilderRequest>,
1011 low_priority_scene_sender: Sender<SceneBuilderRequest>,
1012 blob_image_handler: Option<Box<dyn BlobImageHandler>>,
1013 fonts: SharedFontResources,
1014 ) -> Self {
1015 RenderApiSender {
1016 api_sender,
1017 scene_sender,
1018 low_priority_scene_sender,
1019 blob_image_handler,
1020 fonts,
1021 }
1022 }
1023
1024 pub fn create_api(&self) -> RenderApi {
1026 let (sync_tx, sync_rx) = single_msg_channel();
1027 let msg = ApiMsg::CloneApi(sync_tx);
1028 self.api_sender.send(msg).expect("Failed to send CloneApi message");
1029 let namespace_id = sync_rx.recv().expect("Failed to receive CloneApi reply");
1030 RenderApi {
1031 api_sender: self.api_sender.clone(),
1032 scene_sender: self.scene_sender.clone(),
1033 low_priority_scene_sender: self.low_priority_scene_sender.clone(),
1034 namespace_id,
1035 next_id: Cell::new(ResourceId(0)),
1036 resources: ApiResources::new(
1037 self.blob_image_handler.as_ref().map(|handler| handler.create_similar()),
1038 self.fonts.clone(),
1039 ),
1040 }
1041 }
1042
1043 pub fn create_api_by_client(&self, namespace_id: IdNamespace) -> RenderApi {
1049 let msg = ApiMsg::CloneApiByClient(namespace_id);
1050 self.api_sender.send(msg).expect("Failed to send CloneApiByClient message");
1051 RenderApi {
1052 api_sender: self.api_sender.clone(),
1053 scene_sender: self.scene_sender.clone(),
1054 low_priority_scene_sender: self.low_priority_scene_sender.clone(),
1055 namespace_id,
1056 next_id: Cell::new(ResourceId(0)),
1057 resources: ApiResources::new(
1058 self.blob_image_handler.as_ref().map(|handler| handler.create_similar()),
1059 self.fonts.clone(),
1060 ),
1061 }
1062 }
1063}
1064
1065pub struct RenderApi {
1067 api_sender: Sender<ApiMsg>,
1068 scene_sender: Sender<SceneBuilderRequest>,
1069 low_priority_scene_sender: Sender<SceneBuilderRequest>,
1070 namespace_id: IdNamespace,
1071 next_id: Cell<ResourceId>,
1072 resources: ApiResources,
1073}
1074
1075impl RenderApi {
1076 pub fn get_namespace_id(&self) -> IdNamespace {
1078 self.namespace_id
1079 }
1080
1081 pub fn create_sender(&self) -> RenderApiSender {
1083 RenderApiSender::new(
1084 self.api_sender.clone(),
1085 self.scene_sender.clone(),
1086 self.low_priority_scene_sender.clone(),
1087 self.resources.blob_image_handler.as_ref().map(|handler| handler.create_similar()),
1088 self.resources.get_fonts(),
1089 )
1090 }
1091
1092 pub fn add_document(&self, initial_size: DeviceIntSize) -> DocumentId {
1098 let new_id = self.next_unique_id();
1099 self.add_document_with_id(initial_size, new_id)
1100 }
1101
1102 pub fn add_document_with_id(&self,
1104 initial_size: DeviceIntSize,
1105 id: u32) -> DocumentId {
1106 window_size_sanity_check(initial_size);
1107
1108 let document_id = DocumentId::new(self.namespace_id, id);
1109
1110 self.api_sender.send(
1116 ApiMsg::AddDocument(document_id, initial_size)
1117 ).unwrap();
1118 self.scene_sender.send(
1119 SceneBuilderRequest::AddDocument(document_id, initial_size)
1120 ).unwrap();
1121
1122 document_id
1123 }
1124
1125 pub fn delete_document(&self, document_id: DocumentId) {
1127 self.low_priority_scene_sender.send(
1128 SceneBuilderRequest::DeleteDocument(document_id)
1129 ).unwrap();
1130 }
1131
1132 pub fn generate_font_key(&self) -> FontKey {
1134 let new_id = self.next_unique_id();
1135 FontKey::new(self.namespace_id, new_id)
1136 }
1137
1138 pub fn generate_font_instance_key(&self) -> FontInstanceKey {
1140 let new_id = self.next_unique_id();
1141 FontInstanceKey::new(self.namespace_id, new_id)
1142 }
1143
1144 pub fn get_glyph_dimensions(
1150 &self,
1151 key: FontInstanceKey,
1152 glyph_indices: Vec<GlyphIndex>,
1153 ) -> Vec<Option<GlyphDimensions>> {
1154 let (sender, rx) = single_msg_channel();
1155 let msg = SceneBuilderRequest::GetGlyphDimensions(GlyphDimensionRequest {
1156 key,
1157 glyph_indices,
1158 sender
1159 });
1160 self.low_priority_scene_sender.send(msg).unwrap();
1161 rx.recv().unwrap()
1162 }
1163
1164 pub fn get_glyph_indices(&self, key: FontKey, text: &str) -> Vec<Option<u32>> {
1167 let (sender, rx) = single_msg_channel();
1168 let msg = SceneBuilderRequest::GetGlyphIndices(GlyphIndexRequest {
1169 key,
1170 text: text.to_string(),
1171 sender,
1172 });
1173 self.low_priority_scene_sender.send(msg).unwrap();
1174 rx.recv().unwrap()
1175 }
1176
1177 pub fn generate_image_key(&self) -> ImageKey {
1179 let new_id = self.next_unique_id();
1180 ImageKey::new(self.namespace_id, new_id)
1181 }
1182
1183 pub fn generate_blob_image_key(&self) -> BlobImageKey {
1185 BlobImageKey(self.generate_image_key())
1186 }
1187
1188 pub fn send_external_event(&self, evt: ExternalEvent) {
1192 let msg = SceneBuilderRequest::ExternalEvent(evt);
1193 self.low_priority_scene_sender.send(msg).unwrap();
1194 }
1195
1196 pub fn notify_memory_pressure(&self) {
1199 self.api_sender.send(ApiMsg::MemoryPressure).unwrap();
1200 }
1201
1202 pub fn report_memory(&self, _ops: malloc_size_of::MallocSizeOfOps) -> MemoryReport {
1204 let (tx, rx) = single_msg_channel();
1205 self.api_sender.send(ApiMsg::ReportMemory(tx)).unwrap();
1206 *rx.recv().unwrap()
1207 }
1208
1209 pub fn set_debug_flags(&mut self, flags: DebugFlags) {
1211 self.resources.set_debug_flags(flags);
1212 let cmd = DebugCommand::SetFlags(flags);
1213 self.api_sender.send(ApiMsg::DebugCommand(cmd)).unwrap();
1214 self.scene_sender.send(SceneBuilderRequest ::SetFlags(flags)).unwrap();
1215 self.low_priority_scene_sender.send(SceneBuilderRequest ::SetFlags(flags)).unwrap();
1216 }
1217
1218 pub fn stop_render_backend(&self) {
1220 self.low_priority_scene_sender.send(SceneBuilderRequest::StopRenderBackend).unwrap();
1221 }
1222
1223 pub fn shut_down(&self, synchronously: bool) {
1225 if synchronously {
1226 let (tx, rx) = single_msg_channel();
1227 self.low_priority_scene_sender.send(SceneBuilderRequest::ShutDown(Some(tx))).unwrap();
1228 rx.recv().unwrap();
1229 } else {
1230 self.low_priority_scene_sender.send(SceneBuilderRequest::ShutDown(None)).unwrap();
1231 }
1232 }
1233
1234 pub fn generate_property_binding_key<T: Copy>(&self) -> PropertyBindingKey<T> {
1237 let new_id = self.next_unique_id();
1238 PropertyBindingKey {
1239 id: PropertyBindingId {
1240 namespace: self.namespace_id,
1241 uid: new_id,
1242 },
1243 _phantom: PhantomData,
1244 }
1245 }
1246
1247 #[inline]
1248 fn next_unique_id(&self) -> u32 {
1249 let ResourceId(id) = self.next_id.get();
1250 self.next_id.set(ResourceId(id + 1));
1251 id
1252 }
1253
1254 #[doc(hidden)]
1256 pub fn send_message(&self, msg: ApiMsg) {
1257 self.api_sender.send(msg).unwrap();
1258 }
1259
1260 fn frame_message(&self, msg: FrameMsg, document_id: DocumentId) -> Box<TransactionMsg> {
1262 Box::new(TransactionMsg {
1263 document_id,
1264 scene_ops: Vec::new(),
1265 frame_ops: vec![msg],
1266 resource_updates: Vec::new(),
1267 notifications: Vec::new(),
1268 generate_frame: GenerateFrame::No,
1269 creation_time: None,
1270 invalidate_rendered_frame: false,
1271 use_scene_builder_thread: false,
1272 low_priority: false,
1273 blob_rasterizer: None,
1274 blob_requests: Vec::new(),
1275 rasterized_blobs: Vec::new(),
1276 profile: TransactionProfile::new(),
1277 render_reasons: RenderReasons::empty(),
1278 })
1279 }
1280
1281 fn send_frame_msg(&self, document_id: DocumentId, msg: FrameMsg) {
1283 self.api_sender
1287 .send(ApiMsg::UpdateDocuments(vec![self.frame_message(msg, document_id)]))
1288 .unwrap()
1289 }
1290
1291 pub fn send_transaction(&mut self, document_id: DocumentId, transaction: Transaction) {
1293 let mut transaction = transaction.finalize(document_id);
1294
1295 self.resources.update(&mut transaction);
1296
1297 if transaction.generate_frame.as_bool() {
1298 transaction.profile.start_time(profiler::API_SEND_TIME);
1299 transaction.profile.start_time(profiler::TOTAL_FRAME_CPU_TIME);
1300 }
1301
1302 if transaction.use_scene_builder_thread {
1303 let sender = if transaction.low_priority {
1304 &mut self.low_priority_scene_sender
1305 } else {
1306 &mut self.scene_sender
1307 };
1308
1309 sender.send(SceneBuilderRequest::Transactions(vec![transaction]))
1310 .expect("send by scene sender failed");
1311 } else {
1312 self.api_sender.send(ApiMsg::UpdateDocuments(vec![transaction]))
1313 .expect("send by api sender failed");
1314 }
1315 }
1316
1317 pub fn hit_test(&self,
1323 document_id: DocumentId,
1324 pipeline_id: Option<PipelineId>,
1325 point: WorldPoint,
1326 flags: HitTestFlags,
1327 ) -> HitTestResult {
1328 let (tx, rx) = single_msg_channel();
1329
1330 self.send_frame_msg(
1331 document_id,
1332 FrameMsg::HitTest(pipeline_id, point, flags, tx)
1333 );
1334 rx.recv().unwrap()
1335 }
1336
1337 pub fn request_hit_tester(&self, document_id: DocumentId) -> HitTesterRequest {
1339 let (tx, rx) = single_msg_channel();
1340 self.send_frame_msg(
1341 document_id,
1342 FrameMsg::RequestHitTester(tx)
1343 );
1344
1345 HitTesterRequest { rx }
1346 }
1347
1348 #[doc(hidden)]
1351 pub fn wake_scene_builder(&self) {
1352 self.scene_sender.send(SceneBuilderRequest::WakeUp).unwrap();
1353 }
1354
1355 pub fn flush_scene_builder(&self) {
1359 let (tx, rx) = single_msg_channel();
1360 self.low_priority_scene_sender.send(SceneBuilderRequest::Flush(tx)).unwrap();
1361 rx.recv().unwrap(); }
1363
1364 pub fn save_capture(&self, path: PathBuf, bits: CaptureBits) {
1366 let msg = ApiMsg::DebugCommand(DebugCommand::SaveCapture(path, bits));
1367 self.send_message(msg);
1368 }
1369
1370 pub fn load_capture(&self, path: PathBuf, ids: Option<(u32, u32)>) -> Vec<CapturedDocument> {
1372 self.flush_scene_builder();
1375
1376 let (tx, rx) = unbounded_channel();
1377 let msg = ApiMsg::DebugCommand(DebugCommand::LoadCapture(path, ids, tx));
1378 self.send_message(msg);
1379
1380 let mut documents = Vec::new();
1381 while let Ok(captured_doc) = rx.recv() {
1382 documents.push(captured_doc);
1383 }
1384 documents
1385 }
1386
1387 pub fn start_capture_sequence(&self, path: PathBuf, bits: CaptureBits) {
1389 let msg = ApiMsg::DebugCommand(DebugCommand::StartCaptureSequence(path, bits));
1390 self.send_message(msg);
1391 }
1392
1393 pub fn stop_capture_sequence(&self) {
1395 let msg = ApiMsg::DebugCommand(DebugCommand::StopCaptureSequence);
1396 self.send_message(msg);
1397 }
1398
1399 pub fn send_debug_cmd(&self, cmd: DebugCommand) {
1401 let msg = ApiMsg::DebugCommand(cmd);
1402 self.send_message(msg);
1403 }
1404
1405 pub fn set_parameter(&mut self, parameter: Parameter) {
1407 if let Parameter::Bool(BoolParameter::Multithreading, enabled) = parameter {
1408 self.resources.enable_multithreading(enabled);
1409 }
1410
1411 let _ = self.low_priority_scene_sender.send(
1412 SceneBuilderRequest::SetParameter(parameter)
1413 );
1414 }
1415}
1416
1417impl Drop for RenderApi {
1418 fn drop(&mut self) {
1419 let msg = SceneBuilderRequest::ClearNamespace(self.namespace_id);
1420 let _ = self.low_priority_scene_sender.send(msg);
1421 }
1422}
1423
1424
1425fn window_size_sanity_check(size: DeviceIntSize) {
1426 use crate::api::MAX_RENDER_TASK_SIZE;
1429 if size.width > MAX_RENDER_TASK_SIZE || size.height > MAX_RENDER_TASK_SIZE {
1430 panic!("Attempting to create a {}x{} window/document", size.width, size.height);
1431 }
1432}
1433
1434#[repr(C)]
1438#[allow(missing_docs)]
1439#[derive(AddAssign, Clone, Debug, Default)]
1440pub struct MemoryReport {
1441 pub clip_stores: usize,
1445 pub gpu_cache_metadata: usize,
1446 pub gpu_cache_cpu_mirror: usize,
1447 pub hit_testers: usize,
1448 pub fonts: usize,
1449 pub weak_fonts: usize,
1450 pub images: usize,
1451 pub rasterized_blobs: usize,
1452 pub shader_cache: usize,
1453 pub interning: InterningMemoryReport,
1454 pub display_list: usize,
1455 pub upload_staging_memory: usize,
1456 pub swgl: usize,
1457 pub frame_allocator: usize,
1458 pub render_tasks: usize,
1459
1460 pub gpu_cache_textures: usize,
1464 pub vertex_data_textures: usize,
1465 pub render_target_textures: usize,
1466 pub picture_tile_textures: usize,
1467 pub atlas_textures: usize,
1468 pub standalone_textures: usize,
1469 pub texture_cache_structures: usize,
1470 pub depth_target_textures: usize,
1471 pub texture_upload_pbos: usize,
1472 pub swap_chain: usize,
1473 pub render_texture_hosts: usize,
1474 pub upload_staging_textures: usize,
1475}