Skip to content

Commit 05d4ecc

Browse files
author
bors-servo
authored
Auto merge of #3350 - gw3583:intern-image-3, r=kvark
Port image primitives to use interning. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/3350) <!-- Reviewable:end -->
2 parents f3e489e + 37e9435 commit 05d4ecc

File tree

5 files changed

+729
-590
lines changed

5 files changed

+729
-590
lines changed

webrender/src/batch.rs

Lines changed: 149 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ use gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, Trans
1616
use internal_types::{FastHashMap, SavedTargetIndex, TextureSource};
1717
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureSurface};
1818
use prim_store::{BrushKind, BrushPrimitive, DeferredResolve, PrimitiveTemplateKind, PrimitiveDataStore};
19-
use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveInstanceKind, PrimitiveStore};
19+
use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveInstanceKind};
2020
use prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity, SegmentInstanceIndex};
21-
use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex, PrimitiveDetails, Primitive};
21+
use prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex, PrimitiveDetails};
2222
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree};
2323
use renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
2424
use renderer::BLOCKS_PER_UV_RECT;
@@ -907,6 +907,7 @@ impl AlphaBatchBuilder {
907907
PrimitiveInstanceKind::ImageBorder { .. } |
908908
PrimitiveInstanceKind::Rectangle { .. } |
909909
PrimitiveInstanceKind::YuvImage { .. } |
910+
PrimitiveInstanceKind::Image { .. } |
910911
PrimitiveInstanceKind::Clear => {
911912
unreachable!();
912913
}
@@ -1409,14 +1410,13 @@ impl AlphaBatchBuilder {
14091410
let is_multiple_primitives = match prim.details {
14101411
PrimitiveDetails::Brush(ref brush) => {
14111412
match brush.kind {
1412-
BrushKind::Image { ref visible_tiles, .. } => !visible_tiles.is_empty(),
14131413
BrushKind::LinearGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
14141414
BrushKind::RadialGradient { ref visible_tiles, .. } => !visible_tiles.is_empty(),
14151415
}
14161416
}
14171417
};
14181418

1419-
let specified_blend_mode = prim_instance.get_blend_mode(&prim.details);
1419+
let specified_blend_mode = BlendMode::PremultipliedAlpha;
14201420

14211421
match prim.details {
14221422
PrimitiveDetails::Brush(ref brush) => {
@@ -1450,41 +1450,6 @@ impl AlphaBatchBuilder {
14501450
}
14511451

14521452
match brush.kind {
1453-
BrushKind::Image { alpha_type, request, opacity_binding_index, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
1454-
let opacity_binding = ctx.prim_store.get_opacity_binding(opacity_binding_index);
1455-
1456-
for tile in visible_tiles {
1457-
if let Some((batch_kind, textures, user_data, uv_rect_address)) = get_image_tile_params(
1458-
ctx.resource_cache,
1459-
gpu_cache,
1460-
deferred_resolves,
1461-
request.with_tile(tile.tile_offset),
1462-
alpha_type,
1463-
get_shader_opacity(opacity_binding),
1464-
) {
1465-
let prim_cache_address = gpu_cache.get_address(&tile.handle);
1466-
let prim_header = PrimitiveHeader {
1467-
specific_prim_address: prim_cache_address,
1468-
local_rect: tile.local_rect,
1469-
local_clip_rect: tile.local_clip_rect,
1470-
..prim_header
1471-
};
1472-
let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
1473-
1474-
self.add_image_tile_to_batch(
1475-
batch_kind,
1476-
specified_blend_mode,
1477-
textures,
1478-
prim_header_index,
1479-
clip_task_address,
1480-
bounding_rect,
1481-
tile.edge_flags,
1482-
uv_rect_address,
1483-
z_id,
1484-
);
1485-
}
1486-
}
1487-
}
14881453
BrushKind::LinearGradient { ref stops_handle, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
14891454
add_gradient_tiles(
14901455
visible_tiles,
@@ -1517,11 +1482,7 @@ impl AlphaBatchBuilder {
15171482
}
15181483
_ => {
15191484
if let Some(params) = brush.get_batch_params(
1520-
ctx.resource_cache,
15211485
gpu_cache,
1522-
deferred_resolves,
1523-
prim_instance,
1524-
ctx.prim_store,
15251486
) {
15261487
let prim_header_index = prim_headers.push(&prim_header, z_id, params.prim_user_data);
15271488
if prim_instance.is_chased() {
@@ -1793,6 +1754,146 @@ impl AlphaBatchBuilder {
17931754
ctx,
17941755
);
17951756
}
1757+
(
1758+
PrimitiveInstanceKind::Image { image_instance_index, .. },
1759+
PrimitiveTemplateKind::Image { source, alpha_type, key, image_rendering, .. }
1760+
) => {
1761+
let image_instance = &ctx.prim_store.images[*image_instance_index];
1762+
let opacity_binding = ctx.prim_store.get_opacity_binding(image_instance.opacity_binding_index);
1763+
let specified_blend_mode = match alpha_type {
1764+
AlphaType::PremultipliedAlpha => BlendMode::PremultipliedAlpha,
1765+
AlphaType::Alpha => BlendMode::Alpha,
1766+
};
1767+
let request = ImageRequest {
1768+
key: *key,
1769+
rendering: *image_rendering,
1770+
tile: None,
1771+
};
1772+
1773+
if image_instance.visible_tiles.is_empty() {
1774+
let cache_item = match *source {
1775+
ImageSource::Default => {
1776+
resolve_image(
1777+
request,
1778+
ctx.resource_cache,
1779+
gpu_cache,
1780+
deferred_resolves,
1781+
)
1782+
}
1783+
ImageSource::Cache { ref handle, .. } => {
1784+
let rt_handle = handle
1785+
.as_ref()
1786+
.expect("bug: render task handle not allocated");
1787+
let rt_cache_entry = ctx.resource_cache
1788+
.get_cached_render_task(rt_handle);
1789+
ctx.resource_cache.get_texture_cache_item(&rt_cache_entry.handle)
1790+
}
1791+
};
1792+
1793+
if cache_item.texture_id == TextureSource::Invalid {
1794+
return;
1795+
}
1796+
1797+
let textures = BatchTextures::color(cache_item.texture_id);
1798+
1799+
let opacity = PrimitiveOpacity::from_alpha(opacity_binding);
1800+
let opacity = opacity.combine(prim_data.opacity);
1801+
1802+
let non_segmented_blend_mode = if !opacity.is_opaque ||
1803+
prim_instance.clip_task_index != ClipTaskIndex::INVALID ||
1804+
transform_kind == TransformedRectKind::Complex
1805+
{
1806+
specified_blend_mode
1807+
} else {
1808+
BlendMode::None
1809+
};
1810+
1811+
let batch_params = BrushBatchParameters::shared(
1812+
BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)),
1813+
textures,
1814+
[
1815+
ShaderColorMode::Image as i32 | ((*alpha_type as i32) << 16),
1816+
RasterizationSpace::Local as i32,
1817+
get_shader_opacity(opacity_binding),
1818+
],
1819+
cache_item.uv_rect_handle.as_int(gpu_cache),
1820+
);
1821+
1822+
debug_assert!(image_instance.segment_instance_index != SegmentInstanceIndex::INVALID);
1823+
let (prim_cache_address, segments) = if image_instance.segment_instance_index == SegmentInstanceIndex::UNUSED {
1824+
(gpu_cache.get_address(&prim_data.gpu_cache_handle), None)
1825+
} else {
1826+
let segment_instance = &ctx.scratch.segment_instances[image_instance.segment_instance_index];
1827+
let segments = Some(&ctx.scratch.segments[segment_instance.segments_range]);
1828+
(gpu_cache.get_address(&segment_instance.gpu_cache_handle), segments)
1829+
};
1830+
1831+
let prim_header = PrimitiveHeader {
1832+
local_rect: prim_data.prim_rect,
1833+
local_clip_rect: prim_instance.combined_local_clip_rect,
1834+
task_address,
1835+
specific_prim_address: prim_cache_address,
1836+
clip_task_address,
1837+
transform_id,
1838+
};
1839+
1840+
let prim_header_index = prim_headers.push(
1841+
&prim_header,
1842+
z_id,
1843+
batch_params.prim_user_data,
1844+
);
1845+
1846+
self.add_segmented_prim_to_batch(
1847+
segments,
1848+
opacity,
1849+
&batch_params,
1850+
specified_blend_mode,
1851+
non_segmented_blend_mode,
1852+
prim_header_index,
1853+
clip_task_address,
1854+
bounding_rect,
1855+
transform_kind,
1856+
render_tasks,
1857+
z_id,
1858+
prim_instance.clip_task_index,
1859+
ctx,
1860+
);
1861+
} else {
1862+
for tile in &image_instance.visible_tiles {
1863+
if let Some((batch_kind, textures, user_data, uv_rect_address)) = get_image_tile_params(
1864+
ctx.resource_cache,
1865+
gpu_cache,
1866+
deferred_resolves,
1867+
request.with_tile(tile.tile_offset),
1868+
*alpha_type,
1869+
get_shader_opacity(opacity_binding),
1870+
) {
1871+
let prim_cache_address = gpu_cache.get_address(&tile.handle);
1872+
let prim_header = PrimitiveHeader {
1873+
specific_prim_address: prim_cache_address,
1874+
local_rect: tile.local_rect,
1875+
local_clip_rect: tile.local_clip_rect,
1876+
task_address,
1877+
clip_task_address,
1878+
transform_id,
1879+
};
1880+
let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
1881+
1882+
self.add_image_tile_to_batch(
1883+
batch_kind,
1884+
specified_blend_mode,
1885+
textures,
1886+
prim_header_index,
1887+
clip_task_address,
1888+
bounding_rect,
1889+
tile.edge_flags,
1890+
uv_rect_address,
1891+
z_id,
1892+
);
1893+
}
1894+
}
1895+
}
1896+
}
17961897
_ => {
17971898
unreachable!();
17981899
}
@@ -2127,54 +2228,9 @@ impl BrushBatchParameters {
21272228
impl BrushPrimitive {
21282229
fn get_batch_params(
21292230
&self,
2130-
resource_cache: &ResourceCache,
21312231
gpu_cache: &mut GpuCache,
2132-
deferred_resolves: &mut Vec<DeferredResolve>,
2133-
prim_instance: &PrimitiveInstance,
2134-
prim_store: &PrimitiveStore,
21352232
) -> Option<BrushBatchParameters> {
21362233
match self.kind {
2137-
BrushKind::Image { alpha_type, request, ref source, opacity_binding_index, .. } => {
2138-
let cache_item = match *source {
2139-
ImageSource::Default => {
2140-
resolve_image(
2141-
request,
2142-
resource_cache,
2143-
gpu_cache,
2144-
deferred_resolves,
2145-
)
2146-
}
2147-
ImageSource::Cache { ref handle, .. } => {
2148-
let rt_handle = handle
2149-
.as_ref()
2150-
.expect("bug: render task handle not allocated");
2151-
let rt_cache_entry = resource_cache
2152-
.get_cached_render_task(rt_handle);
2153-
resource_cache.get_texture_cache_item(&rt_cache_entry.handle)
2154-
}
2155-
};
2156-
if prim_instance.is_chased() {
2157-
println!("\tsource {:?}", cache_item);
2158-
}
2159-
2160-
if cache_item.texture_id == TextureSource::Invalid {
2161-
None
2162-
} else {
2163-
let textures = BatchTextures::color(cache_item.texture_id);
2164-
let opacity_binding = prim_store.get_opacity_binding(opacity_binding_index);
2165-
2166-
Some(BrushBatchParameters::shared(
2167-
BrushBatchKind::Image(get_buffer_kind(cache_item.texture_id)),
2168-
textures,
2169-
[
2170-
ShaderColorMode::Image as i32 | ((alpha_type as i32) << 16),
2171-
RasterizationSpace::Local as i32,
2172-
get_shader_opacity(opacity_binding),
2173-
],
2174-
cache_item.uv_rect_handle.as_int(gpu_cache),
2175-
))
2176-
}
2177-
}
21782234
BrushKind::RadialGradient { ref stops_handle, .. } => {
21792235
Some(BrushBatchParameters::shared(
21802236
BrushBatchKind::RadialGradient,
@@ -2204,55 +2260,26 @@ impl BrushPrimitive {
22042260
}
22052261

22062262
impl PrimitiveInstance {
2207-
fn get_blend_mode(
2208-
&self,
2209-
details: &PrimitiveDetails,
2210-
) -> BlendMode {
2211-
match *details {
2212-
PrimitiveDetails::Brush(ref brush) => {
2213-
match brush.kind {
2214-
BrushKind::Image { alpha_type, .. } => {
2215-
match alpha_type {
2216-
AlphaType::PremultipliedAlpha => BlendMode::PremultipliedAlpha,
2217-
AlphaType::Alpha => BlendMode::Alpha,
2218-
}
2219-
}
2220-
BrushKind::RadialGradient { .. } |
2221-
BrushKind::LinearGradient { .. } => {
2222-
BlendMode::PremultipliedAlpha
2223-
}
2224-
}
2225-
}
2226-
}
2227-
}
2228-
22292263
pub fn is_cacheable(
22302264
&self,
2231-
primitives: &[Primitive],
22322265
prim_data_store: &PrimitiveDataStore,
22332266
resource_cache: &ResourceCache,
22342267
) -> bool {
22352268
let image_key = match self.kind {
2236-
PrimitiveInstanceKind::LegacyPrimitive { prim_index, .. } => {
2237-
let prim = &primitives[prim_index.0];
2238-
match prim.details {
2239-
PrimitiveDetails::Brush(BrushPrimitive { kind: BrushKind::Image{ request, .. }, .. }) => {
2240-
request.key
2241-
}
2242-
PrimitiveDetails::Brush(_) => {
2243-
return true
2244-
}
2245-
}
2246-
}
2269+
PrimitiveInstanceKind::Image { .. } |
22472270
PrimitiveInstanceKind::YuvImage { .. } => {
22482271
let prim_data = &prim_data_store[self.prim_data_handle];
22492272
match prim_data.kind {
22502273
PrimitiveTemplateKind::YuvImage { ref yuv_key, .. } => {
22512274
yuv_key[0]
22522275
}
2276+
PrimitiveTemplateKind::Image { key, .. } => {
2277+
key
2278+
}
22532279
_ => unreachable!(),
22542280
}
22552281
}
2282+
PrimitiveInstanceKind::LegacyPrimitive { .. } |
22562283
PrimitiveInstanceKind::Picture { .. } |
22572284
PrimitiveInstanceKind::TextRun { .. } |
22582285
PrimitiveInstanceKind::LineDecoration { .. } |

0 commit comments

Comments
 (0)