Skip to content

Commit 69c1a57

Browse files
committed
Port linear gradients to be interned primitives.
1 parent 05d4ecc commit 69c1a57

File tree

8 files changed

+608
-352
lines changed

8 files changed

+608
-352
lines changed

webrender/src/batch.rs

+89-30
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ impl AlphaBatchBuilder {
908908
PrimitiveInstanceKind::Rectangle { .. } |
909909
PrimitiveInstanceKind::YuvImage { .. } |
910910
PrimitiveInstanceKind::Image { .. } |
911+
PrimitiveInstanceKind::LinearGradient { .. } |
911912
PrimitiveInstanceKind::Clear => {
912913
unreachable!();
913914
}
@@ -1410,8 +1411,7 @@ impl AlphaBatchBuilder {
14101411
let is_multiple_primitives = match prim.details {
14111412
PrimitiveDetails::Brush(ref brush) => {
14121413
match brush.kind {
1413-
BrushKind::LinearGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
1414-
BrushKind::RadialGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
1414+
BrushKind::RadialGradient { visible_tiles_range, .. } => !visible_tiles_range.is_empty(),
14151415
}
14161416
}
14171417
};
@@ -1450,22 +1450,9 @@ impl AlphaBatchBuilder {
14501450
}
14511451

14521452
match brush.kind {
1453-
BrushKind::LinearGradient { ref stops_handle, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
1454-
add_gradient_tiles(
1455-
visible_tiles,
1456-
stops_handle,
1457-
BrushBatchKind::LinearGradient,
1458-
specified_blend_mode,
1459-
bounding_rect,
1460-
clip_task_address,
1461-
gpu_cache,
1462-
&mut self.batch_list,
1463-
&prim_header,
1464-
prim_headers,
1465-
z_id,
1466-
);
1467-
}
1468-
BrushKind::RadialGradient { ref stops_handle, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
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+
14691456
add_gradient_tiles(
14701457
visible_tiles,
14711458
stops_handle,
@@ -1894,6 +1881,89 @@ impl AlphaBatchBuilder {
18941881
}
18951882
}
18961883
}
1884+
(
1885+
PrimitiveInstanceKind::LinearGradient { visible_tiles_range, .. },
1886+
PrimitiveTemplateKind::LinearGradient { stops_handle, ref brush_segments, .. }
1887+
) => {
1888+
let specified_blend_mode = BlendMode::PremultipliedAlpha;
1889+
1890+
let mut prim_header = PrimitiveHeader {
1891+
local_rect: prim_data.prim_rect,
1892+
local_clip_rect: prim_instance.combined_local_clip_rect,
1893+
task_address,
1894+
specific_prim_address: GpuCacheAddress::invalid(),
1895+
clip_task_address,
1896+
transform_id,
1897+
};
1898+
1899+
if visible_tiles_range.is_empty() {
1900+
let non_segmented_blend_mode = if !prim_data.opacity.is_opaque ||
1901+
prim_instance.clip_task_index != ClipTaskIndex::INVALID ||
1902+
transform_kind == TransformedRectKind::Complex
1903+
{
1904+
specified_blend_mode
1905+
} else {
1906+
BlendMode::None
1907+
};
1908+
1909+
let batch_params = BrushBatchParameters::shared(
1910+
BrushBatchKind::LinearGradient,
1911+
BatchTextures::no_texture(),
1912+
[
1913+
stops_handle.as_int(gpu_cache),
1914+
0,
1915+
0,
1916+
],
1917+
0,
1918+
);
1919+
1920+
prim_header.specific_prim_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);
1921+
1922+
let prim_header_index = prim_headers.push(
1923+
&prim_header,
1924+
z_id,
1925+
batch_params.prim_user_data,
1926+
);
1927+
1928+
let segments = if brush_segments.is_empty() {
1929+
None
1930+
} else {
1931+
Some(brush_segments.as_slice())
1932+
};
1933+
1934+
self.add_segmented_prim_to_batch(
1935+
segments,
1936+
prim_data.opacity,
1937+
&batch_params,
1938+
specified_blend_mode,
1939+
non_segmented_blend_mode,
1940+
prim_header_index,
1941+
clip_task_address,
1942+
bounding_rect,
1943+
transform_kind,
1944+
render_tasks,
1945+
z_id,
1946+
prim_instance.clip_task_index,
1947+
ctx,
1948+
);
1949+
} else {
1950+
let visible_tiles = &ctx.scratch.gradient_tiles[*visible_tiles_range];
1951+
1952+
add_gradient_tiles(
1953+
visible_tiles,
1954+
stops_handle,
1955+
BrushBatchKind::LinearGradient,
1956+
specified_blend_mode,
1957+
bounding_rect,
1958+
clip_task_address,
1959+
gpu_cache,
1960+
&mut self.batch_list,
1961+
&prim_header,
1962+
prim_headers,
1963+
z_id,
1964+
);
1965+
}
1966+
}
18971967
_ => {
18981968
unreachable!();
18991969
}
@@ -2243,18 +2313,6 @@ impl BrushPrimitive {
22432313
0,
22442314
))
22452315
}
2246-
BrushKind::LinearGradient { ref stops_handle, .. } => {
2247-
Some(BrushBatchParameters::shared(
2248-
BrushBatchKind::LinearGradient,
2249-
BatchTextures::no_texture(),
2250-
[
2251-
stops_handle.as_int(gpu_cache),
2252-
0,
2253-
0,
2254-
],
2255-
0,
2256-
))
2257-
}
22582316
}
22592317
}
22602318
}
@@ -2286,6 +2344,7 @@ impl PrimitiveInstance {
22862344
PrimitiveInstanceKind::NormalBorder { .. } |
22872345
PrimitiveInstanceKind::ImageBorder { .. } |
22882346
PrimitiveInstanceKind::Rectangle { .. } |
2347+
PrimitiveInstanceKind::LinearGradient { .. } |
22892348
PrimitiveInstanceKind::Clear => {
22902349
return true;
22912350
}

webrender/src/border.rs

+24-31
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use api::{LayoutSideOffsets, LayoutSizeAu, LayoutPrimitiveInfo, LayoutToDeviceSc
77
use api::{DeviceVector2D, DevicePoint, LayoutRect, LayoutSize, NormalBorder, DeviceIntSize};
88
use api::{AuHelpers, LayoutPoint, RepeatMode, TexelRect};
99
use ellipse::Ellipse;
10-
use euclid::{SideOffsets2D, vec2};
10+
use euclid::vec2;
1111
use display_list_flattener::DisplayListFlattener;
1212
use gpu_types::{BorderInstance, BorderSegment, BrushFlags};
13-
use prim_store::{BorderSegmentInfo, BrushSegment};
13+
use prim_store::{BorderSegmentInfo, BrushSegment, NinePatchDescriptor};
1414
use prim_store::{EdgeAaSegmentMask, PrimitiveContainer, ScrollNodeAndClipChain};
1515
use util::{lerp, RectHelpers};
1616

@@ -1130,51 +1130,44 @@ pub fn build_border_instances(
11301130

11311131
pub fn create_nine_patch_segments(
11321132
rect: &LayoutRect,
1133-
widths: &LayoutSideOffsets,
1134-
width: i32,
1135-
height: i32,
1136-
slice: SideOffsets2D<i32>,
1137-
fill: bool,
1138-
repeat_horizontal: RepeatMode,
1139-
repeat_vertical: RepeatMode,
1140-
outset: SideOffsets2D<f32>,
1133+
nine_patch: &NinePatchDescriptor,
11411134
) -> Vec<BrushSegment> {
11421135
// Calculate the modified rect as specific by border-image-outset
11431136
let origin = LayoutPoint::new(
1144-
rect.origin.x - outset.left,
1145-
rect.origin.y - outset.top,
1137+
rect.origin.x - nine_patch.outset.left,
1138+
rect.origin.y - nine_patch.outset.top,
11461139
);
11471140
let size = LayoutSize::new(
1148-
rect.size.width + outset.left + outset.right,
1149-
rect.size.height + outset.top + outset.bottom,
1141+
rect.size.width + nine_patch.outset.left + nine_patch.outset.right,
1142+
rect.size.height + nine_patch.outset.top + nine_patch.outset.bottom,
11501143
);
11511144
let rect = LayoutRect::new(origin, size);
11521145

11531146
// Calculate the local texel coords of the slices.
11541147
let px0 = 0.0;
1155-
let px1 = slice.left as f32;
1156-
let px2 = width as f32 - slice.right as f32;
1157-
let px3 = width as f32;
1148+
let px1 = nine_patch.slice.left as f32;
1149+
let px2 = nine_patch.width as f32 - nine_patch.slice.right as f32;
1150+
let px3 = nine_patch.width as f32;
11581151

11591152
let py0 = 0.0;
1160-
let py1 = slice.top as f32;
1161-
let py2 = height as f32 - slice.bottom as f32;
1162-
let py3 = height as f32;
1153+
let py1 = nine_patch.slice.top as f32;
1154+
let py2 = nine_patch.height as f32 - nine_patch.slice.bottom as f32;
1155+
let py3 = nine_patch.height as f32;
11631156

11641157
let tl_outer = LayoutPoint::new(rect.origin.x, rect.origin.y);
1165-
let tl_inner = tl_outer + vec2(widths.left, widths.top);
1158+
let tl_inner = tl_outer + vec2(nine_patch.widths.left, nine_patch.widths.top);
11661159

11671160
let tr_outer = LayoutPoint::new(rect.origin.x + rect.size.width, rect.origin.y);
1168-
let tr_inner = tr_outer + vec2(-widths.right, widths.top);
1161+
let tr_inner = tr_outer + vec2(-nine_patch.widths.right, nine_patch.widths.top);
11691162

11701163
let bl_outer = LayoutPoint::new(rect.origin.x, rect.origin.y + rect.size.height);
1171-
let bl_inner = bl_outer + vec2(widths.left, -widths.bottom);
1164+
let bl_inner = bl_outer + vec2(nine_patch.widths.left, -nine_patch.widths.bottom);
11721165

11731166
let br_outer = LayoutPoint::new(
11741167
rect.origin.x + rect.size.width,
11751168
rect.origin.y + rect.size.height,
11761169
);
1177-
let br_inner = br_outer - vec2(widths.right, widths.bottom);
1170+
let br_inner = br_outer - vec2(nine_patch.widths.right, nine_patch.widths.bottom);
11781171

11791172
fn add_segment(
11801173
segments: &mut Vec<BrushSegment>,
@@ -1254,13 +1247,13 @@ pub fn create_nine_patch_segments(
12541247
);
12551248

12561249
// Center
1257-
if fill {
1250+
if nine_patch.fill {
12581251
add_segment(
12591252
&mut segments,
12601253
LayoutRect::from_floats(tl_inner.x, tl_inner.y, tr_inner.x, bl_inner.y),
12611254
TexelRect::new(px1, py1, px2, py2),
1262-
repeat_horizontal,
1263-
repeat_vertical
1255+
nine_patch.repeat_horizontal,
1256+
nine_patch.repeat_vertical
12641257
);
12651258
}
12661259

@@ -1271,15 +1264,15 @@ pub fn create_nine_patch_segments(
12711264
&mut segments,
12721265
LayoutRect::from_floats(tl_inner.x, tl_outer.y, tr_inner.x, tl_inner.y),
12731266
TexelRect::new(px1, py0, px2, py1),
1274-
repeat_horizontal,
1267+
nine_patch.repeat_horizontal,
12751268
RepeatMode::Stretch,
12761269
);
12771270
// Bottom
12781271
add_segment(
12791272
&mut segments,
12801273
LayoutRect::from_floats(bl_inner.x, bl_inner.y, br_inner.x, bl_outer.y),
12811274
TexelRect::new(px1, py2, px2, py3),
1282-
repeat_horizontal,
1275+
nine_patch.repeat_horizontal,
12831276
RepeatMode::Stretch,
12841277
);
12851278
// Left
@@ -1288,15 +1281,15 @@ pub fn create_nine_patch_segments(
12881281
LayoutRect::from_floats(tl_outer.x, tl_inner.y, tl_inner.x, bl_inner.y),
12891282
TexelRect::new(px0, py1, px1, py2),
12901283
RepeatMode::Stretch,
1291-
repeat_vertical,
1284+
nine_patch.repeat_vertical,
12921285
);
12931286
// Right
12941287
add_segment(
12951288
&mut segments,
12961289
LayoutRect::from_floats(tr_inner.x, tr_inner.y, br_outer.x, br_inner.y),
12971290
TexelRect::new(px2, py1, px3, py2),
12981291
RepeatMode::Stretch,
1299-
repeat_vertical,
1292+
nine_patch.repeat_vertical,
13001293
);
13011294

13021295
segments

0 commit comments

Comments
 (0)