diff options
Diffstat (limited to 'gfx/wr/webrender/src/prepare.rs')
-rw-r--r-- | gfx/wr/webrender/src/prepare.rs | 135 |
1 files changed, 114 insertions, 21 deletions
diff --git a/gfx/wr/webrender/src/prepare.rs b/gfx/wr/webrender/src/prepare.rs index d9b4521cfc..a7eca830f8 100644 --- a/gfx/wr/webrender/src/prepare.rs +++ b/gfx/wr/webrender/src/prepare.rs @@ -28,7 +28,7 @@ use crate::prim_store::line_dec::MAX_LINE_DECORATION_RESOLUTION; use crate::prim_store::*; use crate::quad; use crate::pattern::Pattern; -use crate::prim_store::gradient::GradientGpuBlockBuilder; +use crate::prim_store::gradient::{radial_gradient_pattern, conic_gradient_pattern, GradientGpuBlockBuilder}; use crate::render_backend::DataStores; use crate::render_task_graph::RenderTaskId; use crate::render_task_cache::RenderTaskCacheKeyKind; @@ -174,6 +174,7 @@ fn prepare_prim_for_render( pic_context.subpixel_mode, frame_state, frame_context, + data_stores, scratch, tile_caches, ) { @@ -211,6 +212,34 @@ fn prepare_prim_for_render( let prim_instance = &mut prim_instances[prim_instance_index]; if !is_passthrough { + fn may_need_repetition(stretch_size: LayoutSize, prim_rect: LayoutRect) -> bool { + stretch_size.width < prim_rect.width() || + stretch_size.height < prim_rect.height() + } + // Bug 1887841: At the moment the quad shader does not support repetitions. + // Bug 1888349: Some primitives have brush segments that aren't handled by + // the quad infrastructure yet. + let disable_quad_path = match &prim_instance.kind { + PrimitiveInstanceKind::Rectangle { .. } => false, + PrimitiveInstanceKind::LinearGradient { data_handle, .. } => { + let prim_data = &data_stores.linear_grad[*data_handle]; + !prim_data.brush_segments.is_empty() || + may_need_repetition(prim_data.stretch_size, prim_data.common.prim_rect) + } + PrimitiveInstanceKind::RadialGradient { data_handle, .. } => { + let prim_data = &data_stores.radial_grad[*data_handle]; + !prim_data.brush_segments.is_empty() || + may_need_repetition(prim_data.stretch_size, prim_data.common.prim_rect) + } + PrimitiveInstanceKind::ConicGradient { .. } => { + // TODO(nical) Enable quad conic gradients. + true + // let prim_data = &data_stores.conic_grad[*data_handle]; + // !prim_data.brush_segments.is_empty() || + // may_need_repetition(prim_data.stretch_size, prim_data.common.prim_rect) + } + _ => true, + }; // In this initial patch, we only support non-masked primitives through the new // quad rendering path. Follow up patches will extend this to support masks, and @@ -218,18 +247,19 @@ fn prepare_prim_for_render( // to skip the entry point to `update_clip_task` as that does old-style segmenting // and mask generation. let should_update_clip_task = match prim_instance.kind { - PrimitiveInstanceKind::Rectangle { ref mut use_legacy_path, .. } => { - *use_legacy_path = !can_use_clip_chain_for_quad_path( + PrimitiveInstanceKind::Rectangle { use_legacy_path: ref mut no_quads, .. } + | PrimitiveInstanceKind::RadialGradient { cached: ref mut no_quads, .. } + | PrimitiveInstanceKind::ConicGradient { cached: ref mut no_quads, .. } + => { + *no_quads = disable_quad_path || !can_use_clip_chain_for_quad_path( &prim_instance.vis.clip_chain, frame_state.clip_store, data_stores, ); - *use_legacy_path - } - PrimitiveInstanceKind::Picture { .. } => { - false + *no_quads } + PrimitiveInstanceKind::Picture { .. } => false, _ => true, }; @@ -365,7 +395,7 @@ fn prepare_interned_prim_for_render( frame_state.rg_builder, None, false, - RenderTaskParent::Surface(pic_context.surface_index), + RenderTaskParent::Surface, &mut frame_state.surface_builder, |rg_builder, _| { rg_builder.add().init(RenderTask::new_dynamic( @@ -520,7 +550,7 @@ fn prepare_interned_prim_for_render( frame_state.rg_builder, None, false, // TODO(gw): We don't calculate opacity for borders yet! - RenderTaskParent::Surface(pic_context.surface_index), + RenderTaskParent::Surface, &mut frame_state.surface_builder, |rg_builder, _| { rg_builder.add().init(RenderTask::new_dynamic( @@ -669,7 +699,6 @@ fn prepare_interned_prim_for_render( image_data.update( common_data, image_instance, - pic_context.surface_index, prim_spatial_node_index, frame_state, frame_context, @@ -692,7 +721,7 @@ fn prepare_interned_prim_for_render( // Update the template this instane references, which may refresh the GPU // cache with any shared template data. - prim_data.update(frame_state, pic_context.surface_index); + prim_data.update(frame_state); if prim_data.stretch_size.width >= prim_data.common.prim_rect.width() && prim_data.stretch_size.height >= prim_data.common.prim_rect.height() { @@ -758,7 +787,7 @@ fn prepare_interned_prim_for_render( // Update the template this instance references, which may refresh the GPU // cache with any shared template data. - prim_data.update(frame_state, pic_context.surface_index); + prim_data.update(frame_state); if prim_data.tile_spacing != LayoutSize::zero() { prim_data.common.may_need_repetition = false; @@ -780,16 +809,49 @@ fn prepare_interned_prim_for_render( } } } - PrimitiveInstanceKind::RadialGradient { data_handle, ref mut visible_tiles_range, .. } => { + PrimitiveInstanceKind::RadialGradient { data_handle, ref mut visible_tiles_range, cached, .. } => { profile_scope!("RadialGradient"); let prim_data = &mut data_stores.radial_grad[*data_handle]; + if !*cached { + // The scaling parameter is used to compensate for when we reduce the size + // of the render task for cached gradients. Here we aren't applying any. + let no_scale = DeviceVector2D::one(); + + let pattern = radial_gradient_pattern( + prim_data.center, + no_scale, + &prim_data.params, + prim_data.extend_mode, + &prim_data.stops, + &mut frame_state.frame_gpu_data, + ); + + quad::push_quad( + &pattern, + &prim_data.common.prim_rect, + prim_instance_index, + prim_spatial_node_index, + &prim_instance.vis.clip_chain, + device_pixel_scale, + frame_context, + pic_context, + targets, + &data_stores.clip, + frame_state, + pic_state, + scratch, + ); + + return; + } + prim_data.common.may_need_repetition = prim_data.stretch_size.width < prim_data.common.prim_rect.width() - || prim_data.stretch_size.height < prim_data.common.prim_rect.height(); + || prim_data.stretch_size.height < prim_data.common.prim_rect.height(); // Update the template this instane references, which may refresh the GPU // cache with any shared template data. - prim_data.update(frame_state, pic_context.surface_index); + prim_data.update(frame_state); if prim_data.tile_spacing != LayoutSize::zero() { prim_data.common.may_need_repetition = false; @@ -810,20 +872,50 @@ fn prepare_interned_prim_for_render( prim_instance.clear_visibility(); } } - - // TODO(gw): Consider whether it's worth doing segment building - // for gradient primitives. } - PrimitiveInstanceKind::ConicGradient { data_handle, ref mut visible_tiles_range, .. } => { + PrimitiveInstanceKind::ConicGradient { data_handle, ref mut visible_tiles_range, cached, .. } => { profile_scope!("ConicGradient"); let prim_data = &mut data_stores.conic_grad[*data_handle]; + if !*cached { + // The scaling parameter is used to compensate for when we reduce the size + // of the render task for cached gradients. Here we aren't applying any. + let no_scale = DeviceVector2D::one(); + + let pattern = conic_gradient_pattern( + prim_data.center, + no_scale, + &prim_data.params, + prim_data.extend_mode, + &prim_data.stops, + &mut frame_state.frame_gpu_data, + ); + + quad::push_quad( + &pattern, + &prim_data.common.prim_rect, + prim_instance_index, + prim_spatial_node_index, + &prim_instance.vis.clip_chain, + device_pixel_scale, + frame_context, + pic_context, + targets, + &data_stores.clip, + frame_state, + pic_state, + scratch, + ); + + return; + } + prim_data.common.may_need_repetition = prim_data.stretch_size.width < prim_data.common.prim_rect.width() || prim_data.stretch_size.height < prim_data.common.prim_rect.height(); // Update the template this instane references, which may refresh the GPU // cache with any shared template data. - prim_data.update(frame_state, pic_context.surface_index); + prim_data.update(frame_state); if prim_data.tile_spacing != LayoutSize::zero() { prim_data.common.may_need_repetition = false; @@ -870,7 +962,8 @@ fn prepare_interned_prim_for_render( // may have changed due to downscaling. We could handle this separate // case as a follow up. Some(PictureCompositeMode::Filter(Filter::Blur { .. })) | - Some(PictureCompositeMode::Filter(Filter::DropShadows { .. })) => { + Some(PictureCompositeMode::Filter(Filter::DropShadows { .. })) | + Some(PictureCompositeMode::SVGFEGraph( .. )) => { true } _ => { |