Skip to content

Commit ec129d9

Browse files
committed
Port radial gradients to be interned primitives.
1 parent 604c69a commit ec129d9

File tree

6 files changed

+358
-311
lines changed

6 files changed

+358
-311
lines changed

webrender/src/batch.rs

Lines changed: 88 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ use gpu_types::{PrimitiveInstanceData, RasterizationSpace, GlyphInstance};
1515
use gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, TransformPalette};
1616
use internal_types::{FastHashMap, SavedTargetIndex, TextureSource};
1717
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureSurface};
18-
use prim_store::{BrushKind, BrushPrimitive, DeferredResolve, PrimitiveTemplateKind, PrimitiveDataStore};
18+
use prim_store::{DeferredResolve, PrimitiveTemplateKind, PrimitiveDataStore};
1919
use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveInstanceKind};
2020
use prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity, SegmentInstanceIndex};
21-
use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex, PrimitiveDetails};
21+
use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex};
2222
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree};
2323
use renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
2424
use renderer::BLOCKS_PER_UV_RECT;
@@ -909,6 +909,7 @@ impl AlphaBatchBuilder {
909909
PrimitiveInstanceKind::YuvImage { .. } |
910910
PrimitiveInstanceKind::Image { .. } |
911911
PrimitiveInstanceKind::LinearGradient { .. } |
912+
PrimitiveInstanceKind::RadialGradient { .. } |
912913
PrimitiveInstanceKind::Clear => {
913914
unreachable!();
914915
}
@@ -1401,102 +1402,9 @@ impl AlphaBatchBuilder {
14011402
}
14021403
}
14031404
(
1404-
PrimitiveInstanceKind::LegacyPrimitive { prim_index },
1405+
PrimitiveInstanceKind::LegacyPrimitive { .. },
14051406
PrimitiveTemplateKind::Unused,
14061407
) => {
1407-
let prim = &ctx.prim_store.primitives[prim_index.0];
1408-
1409-
// If the primitive is internally decomposed into multiple sub-primitives we may not
1410-
// use some of the per-primitive data and get it from each sub-primitive instead.
1411-
let is_multiple_primitives = match prim.details {
1412-
PrimitiveDetails::Brush(ref brush) => {
1413-
match brush.kind {
1414-
BrushKind::RadialGradient { visible_tiles_range, .. } => !visible_tiles_range.is_empty(),
1415-
}
1416-
}
1417-
};
1418-
1419-
let specified_blend_mode = BlendMode::PremultipliedAlpha;
1420-
1421-
match prim.details {
1422-
PrimitiveDetails::Brush(ref brush) => {
1423-
let non_segmented_blend_mode = if !brush.opacity.is_opaque ||
1424-
prim_instance.clip_task_index != ClipTaskIndex::INVALID ||
1425-
transform_kind == TransformedRectKind::Complex
1426-
{
1427-
specified_blend_mode
1428-
} else {
1429-
BlendMode::None
1430-
};
1431-
1432-
let prim_cache_address = if is_multiple_primitives {
1433-
GpuCacheAddress::invalid()
1434-
} else {
1435-
gpu_cache.get_address(&brush.gpu_location)
1436-
};
1437-
1438-
let prim_header = PrimitiveHeader {
1439-
local_rect: prim.local_rect,
1440-
local_clip_rect: prim_instance.combined_local_clip_rect,
1441-
task_address,
1442-
specific_prim_address: prim_cache_address,
1443-
clip_task_address,
1444-
transform_id,
1445-
};
1446-
1447-
if prim_instance.is_chased() {
1448-
println!("\ttask target {:?}", self.target_rect);
1449-
println!("\t{:?}", prim_header);
1450-
}
1451-
1452-
match brush.kind {
1453-
BrushKind::RadialGradient { ref stops_handle, visible_tiles_range, .. } if !visible_tiles_range.is_empty() => {
1454-
let visible_tiles = &ctx.scratch.gradient_tiles[visible_tiles_range];
1455-
1456-
add_gradient_tiles(
1457-
visible_tiles,
1458-
stops_handle,
1459-
BrushBatchKind::RadialGradient,
1460-
specified_blend_mode,
1461-
bounding_rect,
1462-
clip_task_address,
1463-
gpu_cache,
1464-
&mut self.batch_list,
1465-
&prim_header,
1466-
prim_headers,
1467-
z_id,
1468-
);
1469-
}
1470-
_ => {
1471-
if let Some(params) = brush.get_batch_params(
1472-
gpu_cache,
1473-
) {
1474-
let prim_header_index = prim_headers.push(&prim_header, z_id, params.prim_user_data);
1475-
if prim_instance.is_chased() {
1476-
println!("\t{:?} {:?}, task relative bounds {:?}",
1477-
params.batch_kind, prim_header_index, bounding_rect);
1478-
}
1479-
1480-
self.add_segmented_prim_to_batch(
1481-
brush.segment_desc.as_ref().map(|desc| desc.segments.as_slice()),
1482-
brush.opacity,
1483-
&params,
1484-
specified_blend_mode,
1485-
non_segmented_blend_mode,
1486-
prim_header_index,
1487-
clip_task_address,
1488-
bounding_rect,
1489-
transform_kind,
1490-
render_tasks,
1491-
z_id,
1492-
prim_instance.clip_task_index,
1493-
ctx,
1494-
);
1495-
}
1496-
}
1497-
}
1498-
}
1499-
}
15001408
}
15011409
(
15021410
PrimitiveInstanceKind::ImageBorder { .. },
@@ -1964,6 +1872,89 @@ impl AlphaBatchBuilder {
19641872
);
19651873
}
19661874
}
1875+
(
1876+
PrimitiveInstanceKind::RadialGradient { visible_tiles_range, .. },
1877+
PrimitiveTemplateKind::RadialGradient { stops_handle, ref brush_segments, .. }
1878+
) => {
1879+
let specified_blend_mode = BlendMode::PremultipliedAlpha;
1880+
1881+
let mut prim_header = PrimitiveHeader {
1882+
local_rect: prim_data.prim_rect,
1883+
local_clip_rect: prim_instance.combined_local_clip_rect,
1884+
task_address,
1885+
specific_prim_address: GpuCacheAddress::invalid(),
1886+
clip_task_address,
1887+
transform_id,
1888+
};
1889+
1890+
if visible_tiles_range.is_empty() {
1891+
let non_segmented_blend_mode = if !prim_data.opacity.is_opaque ||
1892+
prim_instance.clip_task_index != ClipTaskIndex::INVALID ||
1893+
transform_kind == TransformedRectKind::Complex
1894+
{
1895+
specified_blend_mode
1896+
} else {
1897+
BlendMode::None
1898+
};
1899+
1900+
let batch_params = BrushBatchParameters::shared(
1901+
BrushBatchKind::RadialGradient,
1902+
BatchTextures::no_texture(),
1903+
[
1904+
stops_handle.as_int(gpu_cache),
1905+
0,
1906+
0,
1907+
],
1908+
0,
1909+
);
1910+
1911+
prim_header.specific_prim_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);
1912+
1913+
let prim_header_index = prim_headers.push(
1914+
&prim_header,
1915+
z_id,
1916+
batch_params.prim_user_data,
1917+
);
1918+
1919+
let segments = if brush_segments.is_empty() {
1920+
None
1921+
} else {
1922+
Some(brush_segments.as_slice())
1923+
};
1924+
1925+
self.add_segmented_prim_to_batch(
1926+
segments,
1927+
prim_data.opacity,
1928+
&batch_params,
1929+
specified_blend_mode,
1930+
non_segmented_blend_mode,
1931+
prim_header_index,
1932+
clip_task_address,
1933+
bounding_rect,
1934+
transform_kind,
1935+
render_tasks,
1936+
z_id,
1937+
prim_instance.clip_task_index,
1938+
ctx,
1939+
);
1940+
} else {
1941+
let visible_tiles = &ctx.scratch.gradient_tiles[*visible_tiles_range];
1942+
1943+
add_gradient_tiles(
1944+
visible_tiles,
1945+
stops_handle,
1946+
BrushBatchKind::RadialGradient,
1947+
specified_blend_mode,
1948+
bounding_rect,
1949+
clip_task_address,
1950+
gpu_cache,
1951+
&mut self.batch_list,
1952+
&prim_header,
1953+
prim_headers,
1954+
z_id,
1955+
);
1956+
}
1957+
}
19671958
_ => {
19681959
unreachable!();
19691960
}
@@ -2295,28 +2286,6 @@ impl BrushBatchParameters {
22952286
}
22962287
}
22972288

2298-
impl BrushPrimitive {
2299-
fn get_batch_params(
2300-
&self,
2301-
gpu_cache: &mut GpuCache,
2302-
) -> Option<BrushBatchParameters> {
2303-
match self.kind {
2304-
BrushKind::RadialGradient { ref stops_handle, .. } => {
2305-
Some(BrushBatchParameters::shared(
2306-
BrushBatchKind::RadialGradient,
2307-
BatchTextures::no_texture(),
2308-
[
2309-
stops_handle.as_int(gpu_cache),
2310-
0,
2311-
0,
2312-
],
2313-
0,
2314-
))
2315-
}
2316-
}
2317-
}
2318-
}
2319-
23202289
impl PrimitiveInstance {
23212290
pub fn is_cacheable(
23222291
&self,
@@ -2345,6 +2314,7 @@ impl PrimitiveInstance {
23452314
PrimitiveInstanceKind::ImageBorder { .. } |
23462315
PrimitiveInstanceKind::Rectangle { .. } |
23472316
PrimitiveInstanceKind::LinearGradient { .. } |
2317+
PrimitiveInstanceKind::RadialGradient { .. } |
23482318
PrimitiveInstanceKind::Clear => {
23492319
return true;
23502320
}

webrender/src/display_list_flattener.rs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,18 @@ use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore, ClipItemSceneData};
1717
use clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
1818
use frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
1919
use glyph_rasterizer::FontInstance;
20-
use gpu_cache::GpuCacheHandle;
2120
use hit_test::{HitTestingItem, HitTestingRun};
2221
use image::simplify_repeated_primitive;
2322
use internal_types::{FastHashMap, FastHashSet};
2423
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PrimitiveList};
25-
use prim_store::{BrushKind, BrushPrimitive, PrimitiveInstance, PrimitiveDataInterner, PrimitiveKeyKind};
24+
use prim_store::{PrimitiveInstance, PrimitiveDataInterner, PrimitiveKeyKind, RadialGradientParams};
2625
use prim_store::{PrimitiveKey, PrimitiveSceneData, PrimitiveInstanceKind, GradientStopKey, NinePatchDescriptor};
27-
use prim_store::{PrimitiveContainer, PrimitiveDataHandle, PrimitiveStore, PrimitiveStoreStats, BrushSegmentDescriptor};
28-
use prim_store::{ScrollNodeAndClipChain, PictureIndex, register_prim_chase_id, GradientTileRange};
26+
use prim_store::{PrimitiveContainer, PrimitiveDataHandle, PrimitiveStore, PrimitiveStoreStats};
27+
use prim_store::{ScrollNodeAndClipChain, PictureIndex, register_prim_chase_id};
2928
use render_backend::{DocumentView};
3029
use resource_cache::{FontInstanceMap, ImageRequest};
3130
use scene::{Scene, ScenePipeline, StackingContextHelpers};
3231
use scene_builder::DocumentResources;
33-
use smallvec::SmallVec;
3432
use spatial_node::{StickyFrameInfo};
3533
use std::{f32, mem};
3634
use std::collections::vec_deque::VecDeque;
@@ -600,7 +598,7 @@ impl<'a> DisplayListFlattener<'a> {
600598
}
601599
}
602600
SpecificDisplayItem::RadialGradient(ref info) => {
603-
let brush_kind = self.create_brush_kind_for_radial_gradient(
601+
let prim = self.create_radial_gradient_prim(
604602
&prim_info,
605603
info.gradient.center,
606604
info.gradient.start_offset * info.gradient.radius.width,
@@ -610,9 +608,15 @@ impl<'a> DisplayListFlattener<'a> {
610608
info.gradient.extend_mode,
611609
info.tile_size,
612610
info.tile_spacing,
611+
pipeline_id,
612+
None,
613+
);
614+
self.add_primitive(
615+
clip_and_scroll,
616+
&prim_info,
617+
Vec::new(),
618+
prim,
613619
);
614-
let prim = PrimitiveContainer::Brush(BrushPrimitive::new(brush_kind, None));
615-
self.add_primitive(clip_and_scroll, &prim_info, Vec::new(), prim);
616620
}
617621
SpecificDisplayItem::BoxShadow(ref box_shadow_info) => {
618622
let bounds = box_shadow_info
@@ -1781,7 +1785,7 @@ impl<'a> DisplayListFlattener<'a> {
17811785
}
17821786
}
17831787
NinePatchBorderSource::RadialGradient(gradient) => {
1784-
let brush_kind = self.create_brush_kind_for_radial_gradient(
1788+
self.create_radial_gradient_prim(
17851789
&info,
17861790
gradient.center,
17871791
gradient.start_offset * gradient.radius.width,
@@ -1791,16 +1795,8 @@ impl<'a> DisplayListFlattener<'a> {
17911795
gradient.extend_mode,
17921796
LayoutSize::new(border.height as f32, border.width as f32),
17931797
LayoutSize::zero(),
1794-
);
1795-
1796-
let segments = nine_patch.create_segments(&info.rect);
1797-
1798-
let descriptor = BrushSegmentDescriptor {
1799-
segments: SmallVec::from_vec(segments),
1800-
};
1801-
1802-
PrimitiveContainer::Brush(
1803-
BrushPrimitive::new(brush_kind, Some(descriptor))
1798+
pipeline_id,
1799+
Some(Box::new(nine_patch)),
18041800
)
18051801
}
18061802
};
@@ -1888,7 +1884,7 @@ impl<'a> DisplayListFlattener<'a> {
18881884
})
18891885
}
18901886

1891-
pub fn create_brush_kind_for_radial_gradient(
1887+
pub fn create_radial_gradient_prim(
18921888
&mut self,
18931889
info: &LayoutPrimitiveInfo,
18941890
center: LayoutPoint,
@@ -1899,21 +1895,38 @@ impl<'a> DisplayListFlattener<'a> {
18991895
extend_mode: ExtendMode,
19001896
stretch_size: LayoutSize,
19011897
mut tile_spacing: LayoutSize,
1902-
) -> BrushKind {
1898+
pipeline_id: PipelineId,
1899+
nine_patch: Option<Box<NinePatchDescriptor>>,
1900+
) -> PrimitiveContainer {
19031901
let mut prim_rect = info.rect;
19041902
simplify_repeated_primitive(&stretch_size, &mut tile_spacing, &mut prim_rect);
19051903

1906-
BrushKind::RadialGradient {
1907-
stops_range: stops,
1908-
extend_mode,
1909-
center,
1904+
// TODO(gw): It seems like we should be able to look this up once in
1905+
// flatten_root() and pass to all children here to avoid
1906+
// some hash lookups?
1907+
let display_list = self.scene.get_display_list_for_pipeline(pipeline_id);
1908+
1909+
let params = RadialGradientParams {
19101910
start_radius,
19111911
end_radius,
19121912
ratio_xy,
1913-
stops_handle: GpuCacheHandle::new(),
1913+
};
1914+
1915+
let stops = display_list.get(stops).map(|stop| {
1916+
GradientStopKey {
1917+
offset: stop.offset,
1918+
color: stop.color.into(),
1919+
}
1920+
}).collect();
1921+
1922+
PrimitiveContainer::RadialGradient {
1923+
extend_mode,
1924+
center,
1925+
params,
19141926
stretch_size,
19151927
tile_spacing,
1916-
visible_tiles_range: GradientTileRange::empty(),
1928+
nine_patch,
1929+
stops,
19171930
}
19181931
}
19191932

webrender/src/picture.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ impl TileCache {
447447
PrimitiveInstanceKind::Clear |
448448
PrimitiveInstanceKind::NormalBorder { .. } |
449449
PrimitiveInstanceKind::LinearGradient { .. } |
450+
PrimitiveInstanceKind::RadialGradient { .. } |
450451
PrimitiveInstanceKind::ImageBorder { .. } => {
451452
// These don't contribute dependencies
452453
}

0 commit comments

Comments
 (0)