1use api::{BlobImageHandler, ColorF, CrashAnnotator, DocumentId, IdNamespace};
6use api::{VoidPtrToSizeFn, FontRenderMode, ImageFormat};
7use api::{RenderNotifier, ImageBufferKind};
8use api::units::*;
9use api::channel::unbounded_channel;
10pub use api::DebugFlags;
11
12use crate::bump_allocator::ChunkPool;
13use crate::render_api::{RenderApiSender, FrameMsg};
14use crate::composite::{CompositorKind, CompositorConfig};
15use crate::device::{
16 UploadMethod, UploadPBOPool, VertexUsageHint, Device, ProgramCache, TextureFilter
17};
18use crate::frame_builder::FrameBuilderConfig;
19use crate::glyph_cache::GlyphCache;
20use glyph_rasterizer::{GlyphRasterThread, GlyphRasterizer, SharedFontResources};
21use crate::gpu_types::PrimitiveInstanceData;
22use crate::internal_types::{FastHashMap, FastHashSet, FrameId};
23use crate::picture;
24use crate::profiler::{self, Profiler, TransactionProfile};
25use crate::device::query::{GpuProfiler, GpuDebugMethod};
26use crate::render_backend::RenderBackend;
27use crate::resource_cache::ResourceCache;
28use crate::scene_builder_thread::{SceneBuilderThread, SceneBuilderThreadChannels, LowPrioritySceneBuilderThread};
29use crate::texture_cache::{TextureCache, TextureCacheConfig};
30use crate::picture_textures::PictureTextures;
31use crate::renderer::{
32 debug, gpu_cache, vertex, gl,
33 Renderer, DebugOverlayState, BufferDamageTracker, PipelineInfo, TextureResolver,
34 RendererError, ShaderPrecacheFlags, VERTEX_DATA_TEXTURE_COUNT,
35 upload::UploadTexturePool,
36 shade::{Shaders, SharedShaders},
37};
38#[cfg(feature = "debugger")]
39use crate::debugger::Debugger;
40
41use std::{
42 mem,
43 thread,
44 cell::RefCell,
45 collections::VecDeque,
46 rc::Rc,
47 sync::{Arc, atomic::{AtomicBool, Ordering}},
48 num::NonZeroUsize,
49 path::PathBuf,
50};
51
52use tracy_rs::register_thread_with_profiler;
53use rayon::{ThreadPool, ThreadPoolBuilder};
54use malloc_size_of::MallocSizeOfOps;
55
56pub const ONE_TIME_USAGE_HINT: VertexUsageHint = VertexUsageHint::Stream;
59
60static HAS_BEEN_INITIALIZED: AtomicBool = AtomicBool::new(false);
62
63pub fn wr_has_been_initialized() -> bool {
65 HAS_BEEN_INITIALIZED.load(Ordering::SeqCst)
66}
67
68pub trait SceneBuilderHooks {
71 fn register(&self);
74 fn pre_scene_build(&self);
76 fn pre_scene_swap(&self);
78 fn post_scene_swap(&self, document_id: &Vec<DocumentId>, info: PipelineInfo, schedule_frame: bool);
82 fn post_resource_update(&self, document_ids: &Vec<DocumentId>);
86 fn post_empty_scene_build(&self);
91 fn poke(&self);
96 fn deregister(&self);
99}
100
101pub trait AsyncPropertySampler {
105 fn register(&self);
108 fn sample(&self, document_id: DocumentId, generated_frame_id: Option<u64>) -> Vec<FrameMsg>;
112 fn deregister(&self);
115}
116
117pub trait RenderBackendHooks {
118 fn init_thread(&self);
119}
120
121pub struct WebRenderOptions {
122 pub resource_override_path: Option<PathBuf>,
123 pub use_optimized_shaders: bool,
125 pub enable_aa: bool,
126 pub enable_dithering: bool,
127 pub max_recorded_profiles: usize,
128 pub precache_flags: ShaderPrecacheFlags,
129 pub enable_subpixel_aa: bool,
131 pub clear_color: ColorF,
132 pub enable_clear_scissor: Option<bool>,
133 pub max_internal_texture_size: Option<i32>,
134 pub image_tiling_threshold: i32,
135 pub upload_method: UploadMethod,
136 pub upload_pbo_default_size: usize,
138 pub batched_upload_threshold: i32,
139 pub workers: Option<Arc<ThreadPool>>,
140 pub chunk_pool: Option<Arc<ChunkPool>>,
144 pub dedicated_glyph_raster_thread: Option<GlyphRasterThread>,
145 pub enable_multithreading: bool,
146 pub blob_image_handler: Option<Box<dyn BlobImageHandler>>,
147 pub crash_annotator: Option<Box<dyn CrashAnnotator>>,
148 pub size_of_op: Option<VoidPtrToSizeFn>,
149 pub enclosing_size_of_op: Option<VoidPtrToSizeFn>,
150 pub cached_programs: Option<Rc<ProgramCache>>,
151 pub debug_flags: DebugFlags,
152 pub renderer_id: Option<u64>,
153 pub scene_builder_hooks: Option<Box<dyn SceneBuilderHooks + Send>>,
154 pub render_backend_hooks: Option<Box<dyn RenderBackendHooks + Send>>,
155 pub sampler: Option<Box<dyn AsyncPropertySampler + Send>>,
156 pub support_low_priority_transactions: bool,
157 pub namespace_alloc_by_client: bool,
158 pub shared_font_namespace: Option<IdNamespace>,
162 pub testing: bool,
163 pub gpu_supports_fast_clears: bool,
168 pub allow_dual_source_blending: bool,
169 pub allow_advanced_blend_equation: bool,
170 pub allow_texture_storage_support: bool,
173 pub allow_texture_swizzling: bool,
177 pub clear_caches_with_quads: bool,
182 pub dump_shader_source: Option<String>,
184 pub surface_origin_is_top_left: bool,
185 pub compositor_config: CompositorConfig,
187 pub enable_gpu_markers: bool,
188 pub panic_on_gl_error: bool,
191 pub picture_tile_size: Option<DeviceIntSize>,
192 pub texture_cache_config: TextureCacheConfig,
193 pub enable_instancing: bool,
197 pub reject_software_rasterizer: bool,
200 pub low_quality_pinch_zoom: bool,
206 pub max_shared_surface_size: i32,
207 pub enable_debugger: bool,
210
211 pub precise_linear_gradients: bool,
213 pub precise_radial_gradients: bool,
214 pub precise_conic_gradients: bool,
215}
216
217impl WebRenderOptions {
218 const BATCH_LOOKBACK_COUNT: usize = 10;
221
222 const MAX_INSTANCE_BUFFER_SIZE: usize = 0x20000; }
230
231impl Default for WebRenderOptions {
232 fn default() -> Self {
233 WebRenderOptions {
234 resource_override_path: None,
235 use_optimized_shaders: false,
236 enable_aa: true,
237 enable_dithering: false,
238 debug_flags: DebugFlags::empty(),
239 max_recorded_profiles: 0,
240 precache_flags: ShaderPrecacheFlags::empty(),
241 enable_subpixel_aa: false,
242 clear_color: ColorF::new(1.0, 1.0, 1.0, 1.0),
243 enable_clear_scissor: None,
244 max_internal_texture_size: None,
245 image_tiling_threshold: 4096,
246 upload_method: UploadMethod::PixelBuffer(ONE_TIME_USAGE_HINT),
249 upload_pbo_default_size: 512 * 512 * 4,
250 batched_upload_threshold: 512 * 512,
251 workers: None,
252 chunk_pool: None,
253 dedicated_glyph_raster_thread: None,
254 enable_multithreading: true,
255 blob_image_handler: None,
256 crash_annotator: None,
257 size_of_op: None,
258 enclosing_size_of_op: None,
259 renderer_id: None,
260 cached_programs: None,
261 scene_builder_hooks: None,
262 render_backend_hooks: None,
263 sampler: None,
264 support_low_priority_transactions: false,
265 namespace_alloc_by_client: false,
266 shared_font_namespace: None,
267 testing: false,
268 gpu_supports_fast_clears: false,
269 allow_dual_source_blending: true,
270 allow_advanced_blend_equation: false,
271 allow_texture_storage_support: true,
272 allow_texture_swizzling: true,
273 clear_caches_with_quads: true,
274 dump_shader_source: None,
275 surface_origin_is_top_left: false,
276 compositor_config: CompositorConfig::default(),
277 enable_gpu_markers: true,
278 panic_on_gl_error: false,
279 picture_tile_size: None,
280 texture_cache_config: TextureCacheConfig::DEFAULT,
281 enable_instancing: true,
284 reject_software_rasterizer: false,
285 low_quality_pinch_zoom: false,
286 max_shared_surface_size: 2048,
287 enable_debugger: true,
288 precise_linear_gradients: false,
289 precise_radial_gradients: false,
290 precise_conic_gradients: false,
291 }
292 }
293}
294
295pub fn create_webrender_instance(
313 gl: Rc<dyn gl::Gl>,
314 notifier: Box<dyn RenderNotifier>,
315 mut options: WebRenderOptions,
316 shaders: Option<&SharedShaders>,
317) -> Result<(Renderer, RenderApiSender), RendererError> {
318 if !wr_has_been_initialized() {
319 #[cfg(feature = "profiler")]
322 unsafe {
323 if let Ok(ref tracy_path) = std::env::var("WR_TRACY_PATH") {
324 let ok = tracy_rs::load(tracy_path);
325 info!("Load tracy from {} -> {}", tracy_path, ok);
326 }
327 }
328
329 register_thread_with_profiler("Compositor".to_owned());
330 }
331
332 HAS_BEEN_INITIALIZED.store(true, Ordering::SeqCst);
333
334 match options.compositor_config {
337 CompositorConfig::Draw { .. } | CompositorConfig::Native { .. } => {}
338 CompositorConfig::Layer { .. } => {
339 options.surface_origin_is_top_left = true;
340 }
341 }
342
343 let (api_tx, api_rx) = unbounded_channel();
344 let (result_tx, result_rx) = unbounded_channel();
345 let gl_type = gl.get_type();
346
347 let mut device = Device::new(
348 gl,
349 options.crash_annotator.clone(),
350 options.resource_override_path.clone(),
351 options.use_optimized_shaders,
352 options.upload_method.clone(),
353 options.batched_upload_threshold,
354 options.cached_programs.take(),
355 options.allow_texture_storage_support,
356 options.allow_texture_swizzling,
357 options.dump_shader_source.take(),
358 options.surface_origin_is_top_left,
359 options.panic_on_gl_error,
360 );
361
362 let color_cache_formats = device.preferred_color_formats();
363 let swizzle_settings = device.swizzle_settings();
364 let use_dual_source_blending =
365 device.get_capabilities().supports_dual_source_blending &&
366 options.allow_dual_source_blending;
367 let ext_blend_equation_advanced =
368 options.allow_advanced_blend_equation &&
369 device.get_capabilities().supports_advanced_blend_equation;
370 let ext_blend_equation_advanced_coherent =
371 device.supports_extension("GL_KHR_blend_equation_advanced_coherent");
372
373 let enable_clear_scissor = options
374 .enable_clear_scissor
375 .unwrap_or(device.get_capabilities().prefers_clear_scissor);
376
377 const MIN_TEXTURE_SIZE: i32 = 2048;
379 let mut max_internal_texture_size = device.max_texture_size();
380 if max_internal_texture_size < MIN_TEXTURE_SIZE {
381 error!(
384 "Device reporting insufficient max texture size ({})",
385 max_internal_texture_size
386 );
387 return Err(RendererError::MaxTextureSize);
388 }
389 if let Some(internal_limit) = options.max_internal_texture_size {
390 assert!(internal_limit >= MIN_TEXTURE_SIZE);
391 max_internal_texture_size = max_internal_texture_size.min(internal_limit);
392 }
393
394 if options.reject_software_rasterizer {
395 let renderer_name_lc = device.get_capabilities().renderer_name.to_lowercase();
396 if renderer_name_lc.contains("llvmpipe") || renderer_name_lc.contains("softpipe") || renderer_name_lc.contains("software rasterizer") {
397 return Err(RendererError::SoftwareRasterizer);
398 }
399 }
400
401 let image_tiling_threshold = options.image_tiling_threshold
402 .min(max_internal_texture_size);
403
404 device.begin_frame();
405
406 let shaders = match shaders {
407 Some(shaders) => Rc::clone(shaders),
408 None => {
409 let mut shaders = Shaders::new(&mut device, gl_type, &options)?;
410 if options.precache_flags.intersects(ShaderPrecacheFlags::ASYNC_COMPILE | ShaderPrecacheFlags::FULL_COMPILE) {
411 let mut pending_shaders = shaders.precache_all(options.precache_flags);
412 while shaders.resume_precache(&mut device, &mut pending_shaders)? {}
413 }
414 Rc::new(RefCell::new(shaders))
415 }
416 };
417
418 let dither_matrix_texture = if options.enable_dithering {
419 let dither_matrix: [u8; 64] = [
420 0,
421 48,
422 12,
423 60,
424 3,
425 51,
426 15,
427 63,
428 32,
429 16,
430 44,
431 28,
432 35,
433 19,
434 47,
435 31,
436 8,
437 56,
438 4,
439 52,
440 11,
441 59,
442 7,
443 55,
444 40,
445 24,
446 36,
447 20,
448 43,
449 27,
450 39,
451 23,
452 2,
453 50,
454 14,
455 62,
456 1,
457 49,
458 13,
459 61,
460 34,
461 18,
462 46,
463 30,
464 33,
465 17,
466 45,
467 29,
468 10,
469 58,
470 6,
471 54,
472 9,
473 57,
474 5,
475 53,
476 42,
477 26,
478 38,
479 22,
480 41,
481 25,
482 37,
483 21,
484 ];
485
486 let texture = device.create_texture(
487 ImageBufferKind::Texture2D,
488 ImageFormat::R8,
489 8,
490 8,
491 TextureFilter::Nearest,
492 None,
493 );
494 device.upload_texture_immediate(&texture, &dither_matrix);
495
496 Some(texture)
497 } else {
498 None
499 };
500
501 let max_primitive_instance_count =
502 WebRenderOptions::MAX_INSTANCE_BUFFER_SIZE / mem::size_of::<PrimitiveInstanceData>();
503 let vaos = vertex::RendererVAOs::new(
504 &mut device,
505 if options.enable_instancing { None } else { NonZeroUsize::new(max_primitive_instance_count) },
506 );
507
508 let texture_upload_pbo_pool = UploadPBOPool::new(&mut device, options.upload_pbo_default_size);
509 let staging_texture_pool = UploadTexturePool::new();
510 let texture_resolver = TextureResolver::new(&mut device);
511
512 let mut vertex_data_textures = Vec::new();
513 for _ in 0 .. VERTEX_DATA_TEXTURE_COUNT {
514 vertex_data_textures.push(vertex::VertexDataTextures::new());
515 }
516
517 let is_software = device.get_capabilities().renderer_name.starts_with("Software");
526
527 let supports_scatter = device.get_capabilities().supports_color_buffer_float;
531 let gpu_cache_texture = gpu_cache::GpuCacheTexture::new(
532 &mut device,
533 supports_scatter && !is_software,
534 )?;
535
536 device.end_frame();
537
538 let backend_notifier = notifier.clone();
539
540 let clear_alpha_targets_with_quads = !device.get_capabilities().supports_alpha_target_clears;
541
542 let prefer_subpixel_aa = options.enable_subpixel_aa && use_dual_source_blending;
543 let default_font_render_mode = match (options.enable_aa, prefer_subpixel_aa) {
544 (true, true) => FontRenderMode::Subpixel,
545 (true, false) => FontRenderMode::Alpha,
546 (false, _) => FontRenderMode::Mono,
547 };
548
549 let compositor_kind = match options.compositor_config {
550 CompositorConfig::Draw { max_partial_present_rects, draw_previous_partial_present_regions, .. } => {
551 CompositorKind::Draw { max_partial_present_rects, draw_previous_partial_present_regions }
552 }
553 CompositorConfig::Native { ref compositor } => {
554 let capabilities = compositor.get_capabilities(&mut device);
555
556 CompositorKind::Native {
557 capabilities,
558 }
559 }
560 CompositorConfig::Layer { .. } => {
561 CompositorKind::Layer {
562 }
563 }
564 };
565
566 let config = FrameBuilderConfig {
567 default_font_render_mode,
568 dual_source_blending_is_supported: use_dual_source_blending,
569 testing: options.testing,
570 gpu_supports_fast_clears: options.gpu_supports_fast_clears,
571 gpu_supports_advanced_blend: ext_blend_equation_advanced,
572 advanced_blend_is_coherent: ext_blend_equation_advanced_coherent,
573 gpu_supports_render_target_partial_update: device.get_capabilities().supports_render_target_partial_update,
574 external_images_require_copy: !device.get_capabilities().supports_image_external_essl3,
575 batch_lookback_count: WebRenderOptions::BATCH_LOOKBACK_COUNT,
576 background_color: Some(options.clear_color),
577 compositor_kind,
578 tile_size_override: None,
579 max_surface_override: None,
580 max_depth_ids: device.max_depth_ids(),
581 max_target_size: max_internal_texture_size,
582 force_invalidation: false,
583 is_software,
584 low_quality_pinch_zoom: options.low_quality_pinch_zoom,
585 max_shared_surface_size: options.max_shared_surface_size,
586 enable_dithering: options.enable_dithering,
587 precise_linear_gradients: options.precise_linear_gradients,
588 precise_radial_gradients: options.precise_radial_gradients,
589 precise_conic_gradients: options.precise_conic_gradients,
590 };
591 info!("WR {:?}", config);
592
593 let debug_flags = options.debug_flags;
594 let size_of_op = options.size_of_op;
595 let enclosing_size_of_op = options.enclosing_size_of_op;
596 let make_size_of_ops =
597 move || size_of_op.map(|o| MallocSizeOfOps::new(o, enclosing_size_of_op));
598 let workers = options
599 .workers
600 .take()
601 .unwrap_or_else(|| {
602 let worker = ThreadPoolBuilder::new()
603 .thread_name(|idx|{ format!("WRWorker#{}", idx) })
604 .start_handler(move |idx| {
605 register_thread_with_profiler(format!("WRWorker#{}", idx));
606 profiler::register_thread(&format!("WRWorker#{}", idx));
607 })
608 .exit_handler(move |_idx| {
609 profiler::unregister_thread();
610 })
611 .build();
612 Arc::new(worker.unwrap())
613 });
614 let sampler = options.sampler;
615 let namespace_alloc_by_client = options.namespace_alloc_by_client;
616
617 let font_namespace = if namespace_alloc_by_client {
620 options.shared_font_namespace.expect("Shared font namespace must be allocated by client")
621 } else {
622 RenderBackend::next_namespace_id()
623 };
624 let fonts = SharedFontResources::new(font_namespace);
625
626 let blob_image_handler = options.blob_image_handler.take();
627 let scene_builder_hooks = options.scene_builder_hooks;
628 let rb_thread_name = format!("WRRenderBackend#{}", options.renderer_id.unwrap_or(0));
629 let scene_thread_name = format!("WRSceneBuilder#{}", options.renderer_id.unwrap_or(0));
630 let lp_scene_thread_name = format!("WRSceneBuilderLP#{}", options.renderer_id.unwrap_or(0));
631
632 let glyph_rasterizer = GlyphRasterizer::new(
633 workers,
634 options.dedicated_glyph_raster_thread,
635 device.get_capabilities().supports_r8_texture_upload,
636 );
637
638 let (scene_builder_channels, scene_tx) =
639 SceneBuilderThreadChannels::new(api_tx.clone());
640
641 let sb_fonts = fonts.clone();
642
643 thread::Builder::new().name(scene_thread_name.clone()).spawn(move || {
644 register_thread_with_profiler(scene_thread_name.clone());
645 profiler::register_thread(&scene_thread_name);
646
647 let mut scene_builder = SceneBuilderThread::new(
648 config,
649 sb_fonts,
650 make_size_of_ops(),
651 scene_builder_hooks,
652 scene_builder_channels,
653 );
654 scene_builder.run();
655
656 profiler::unregister_thread();
657 })?;
658
659 let low_priority_scene_tx = if options.support_low_priority_transactions {
660 let (low_priority_scene_tx, low_priority_scene_rx) = unbounded_channel();
661 let lp_builder = LowPrioritySceneBuilderThread {
662 rx: low_priority_scene_rx,
663 tx: scene_tx.clone(),
664 tile_pool: api::BlobTilePool::new(),
665 };
666
667 thread::Builder::new().name(lp_scene_thread_name.clone()).spawn(move || {
668 register_thread_with_profiler(lp_scene_thread_name.clone());
669 profiler::register_thread(&lp_scene_thread_name);
670
671 let mut scene_builder = lp_builder;
672 scene_builder.run();
673
674 profiler::unregister_thread();
675 })?;
676
677 low_priority_scene_tx
678 } else {
679 scene_tx.clone()
680 };
681
682 let rb_blob_handler = blob_image_handler
683 .as_ref()
684 .map(|handler| handler.create_similar());
685
686 let texture_cache_config = options.texture_cache_config.clone();
687 let mut picture_tile_size = options.picture_tile_size.unwrap_or(picture::TILE_SIZE_DEFAULT);
688 picture_tile_size.width = picture_tile_size.width.max(128).min(4096);
690 picture_tile_size.height = picture_tile_size.height.max(128).min(4096);
691
692 let picture_texture_filter = if options.low_quality_pinch_zoom {
693 TextureFilter::Linear
694 } else {
695 TextureFilter::Nearest
696 };
697
698 let render_backend_hooks = options.render_backend_hooks.take();
699
700 let chunk_pool = options.chunk_pool.take().unwrap_or_else(|| {
701 Arc::new(ChunkPool::new())
702 });
703
704 let rb_scene_tx = scene_tx.clone();
705 let rb_fonts = fonts.clone();
706 let enable_multithreading = options.enable_multithreading;
707 thread::Builder::new().name(rb_thread_name.clone()).spawn(move || {
708 if let Some(hooks) = render_backend_hooks {
709 hooks.init_thread();
710 }
711 register_thread_with_profiler(rb_thread_name.clone());
712 profiler::register_thread(&rb_thread_name);
713
714 let texture_cache = TextureCache::new(
715 max_internal_texture_size,
716 image_tiling_threshold,
717 color_cache_formats,
718 swizzle_settings,
719 &texture_cache_config,
720 );
721
722 let picture_textures = PictureTextures::new(
723 picture_tile_size,
724 picture_texture_filter,
725 );
726
727 let glyph_cache = GlyphCache::new();
728
729 let mut resource_cache = ResourceCache::new(
730 texture_cache,
731 picture_textures,
732 glyph_rasterizer,
733 glyph_cache,
734 rb_fonts,
735 rb_blob_handler,
736 );
737
738 resource_cache.enable_multithreading(enable_multithreading);
739
740 let mut backend = RenderBackend::new(
741 api_rx,
742 result_tx,
743 rb_scene_tx,
744 resource_cache,
745 chunk_pool,
746 backend_notifier,
747 config,
748 sampler,
749 make_size_of_ops(),
750 debug_flags,
751 namespace_alloc_by_client,
752 );
753 backend.run();
754 profiler::unregister_thread();
755 })?;
756
757 let debug_method = if !options.enable_gpu_markers {
758 GpuDebugMethod::None
760 } else if device.get_capabilities().supports_khr_debug {
761 GpuDebugMethod::KHR
762 } else if device.supports_extension("GL_EXT_debug_marker") {
763 GpuDebugMethod::MarkerEXT
764 } else {
765 warn!("asking to enable_gpu_markers but no supporting extension was found");
766 GpuDebugMethod::None
767 };
768
769 info!("using {:?}", debug_method);
770
771 let gpu_profiler = GpuProfiler::new(Rc::clone(device.rc_gl()), debug_method);
772 #[cfg(feature = "capture")]
773 let read_fbo = device.create_fbo();
774
775 let mut renderer = Renderer {
776 result_rx,
777 api_tx: api_tx.clone(),
778 device,
779 active_documents: FastHashMap::default(),
780 pending_texture_updates: Vec::new(),
781 pending_texture_cache_updates: false,
782 pending_native_surface_updates: Vec::new(),
783 pending_gpu_cache_updates: Vec::new(),
784 pending_gpu_cache_clear: false,
785 pending_shader_updates: Vec::new(),
786 shaders,
787 debug: debug::LazyInitializedDebugRenderer::new(),
788 debug_flags: DebugFlags::empty(),
789 profile: TransactionProfile::new(),
790 frame_counter: 0,
791 resource_upload_time: 0.0,
792 gpu_cache_upload_time: 0.0,
793 profiler: Profiler::new(),
794 max_recorded_profiles: options.max_recorded_profiles,
795 clear_color: options.clear_color,
796 enable_clear_scissor,
797 enable_advanced_blend_barriers: !ext_blend_equation_advanced_coherent,
798 clear_caches_with_quads: options.clear_caches_with_quads,
799 clear_alpha_targets_with_quads,
800 last_time: 0,
801 gpu_profiler,
802 vaos,
803 vertex_data_textures,
804 current_vertex_data_textures: 0,
805 pipeline_info: PipelineInfo::default(),
806 dither_matrix_texture,
807 external_image_handler: None,
808 size_of_ops: make_size_of_ops(),
809 cpu_profiles: VecDeque::new(),
810 gpu_profiles: VecDeque::new(),
811 gpu_cache_texture,
812 gpu_cache_debug_chunks: Vec::new(),
813 gpu_cache_frame_id: FrameId::INVALID,
814 gpu_cache_overflow: false,
815 texture_upload_pbo_pool,
816 staging_texture_pool,
817 texture_resolver,
818 renderer_errors: Vec::new(),
819 async_frame_recorder: None,
820 async_screenshots: None,
821 #[cfg(feature = "capture")]
822 read_fbo,
823 #[cfg(feature = "replay")]
824 owned_external_images: FastHashMap::default(),
825 notifications: Vec::new(),
826 device_size: None,
827 zoom_debug_texture: None,
828 cursor_position: DeviceIntPoint::zero(),
829 shared_texture_cache_cleared: false,
830 documents_seen: FastHashSet::default(),
831 force_redraw: true,
832 compositor_config: options.compositor_config,
833 current_compositor_kind: compositor_kind,
834 allocated_native_surfaces: FastHashSet::default(),
835 debug_overlay_state: DebugOverlayState::new(),
836 buffer_damage_tracker: BufferDamageTracker::default(),
837 max_primitive_instance_count,
838 enable_instancing: options.enable_instancing,
839 consecutive_oom_frames: 0,
840 target_frame_publish_id: None,
841 pending_result_msg: None,
842 layer_compositor_frame_state_in_prev_frame: None,
843 #[cfg(feature = "debugger")]
844 debugger: Debugger::new(),
845 };
846
847 renderer.set_debug_flags(debug_flags);
850 renderer.profiler.set_ui("Default");
851
852 let sender = RenderApiSender::new(
853 api_tx,
854 scene_tx,
855 low_priority_scene_tx,
856 blob_image_handler,
857 fonts,
858 );
859
860 #[cfg(feature = "debugger")]
861 if options.enable_debugger {
862 let api = if namespace_alloc_by_client {
863 sender.create_api_by_client(IdNamespace::DEBUGGER)
864 } else {
865 sender.create_api()
866 };
867 crate::debugger::start(api);
868 }
869
870 Ok((renderer, sender))
871}