summaryrefslogtreecommitdiffstats
path: root/gfx/wr/webrender/src/prepare.rs
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/wr/webrender/src/prepare.rs')
-rw-r--r--gfx/wr/webrender/src/prepare.rs135
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
}
_ => {