Skip to content

Commit 39e6038

Browse files
author
bors-servo
authored
Auto merge of #1758 - glennw:small-target, r=kvark
Initialize render targets to the required size, saving memory and clear time. We have the information available that tells us the worst case *actual* size requirement for each render pass array texture. Keep track of that and only create targets of that size. This is a quite significant GPU memory saving, and also a large performance win on *some* GPU architectures (seems to be a good benefit on the Intel GPUs I've tested with). <!-- 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/1758) <!-- Reviewable:end -->
2 parents 9c5f868 + 3a5b792 commit 39e6038

File tree

5 files changed

+42
-31
lines changed

5 files changed

+42
-31
lines changed

webrender/src/renderer.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,12 +3040,12 @@ impl Renderer {
30403040
let alpha_target_count = pass.required_target_count(RenderTargetKind::Alpha);
30413041

30423042
if let Some(texture) = pass.color_texture.as_mut() {
3043-
debug_assert!(pass.max_color_target_size.width > 0);
3044-
debug_assert!(pass.max_color_target_size.height > 0);
3043+
debug_assert!(pass.max_used_color_target_size.width > 0);
3044+
debug_assert!(pass.max_used_color_target_size.height > 0);
30453045
self.device.init_texture(
30463046
texture,
3047-
pass.max_color_target_size.width,
3048-
pass.max_color_target_size.height,
3047+
pass.max_used_color_target_size.width,
3048+
pass.max_used_color_target_size.height,
30493049
ImageFormat::BGRA8,
30503050
TextureFilter::Linear,
30513051
RenderTargetMode::RenderTarget,
@@ -3054,12 +3054,12 @@ impl Renderer {
30543054
);
30553055
}
30563056
if let Some(texture) = pass.alpha_texture.as_mut() {
3057-
debug_assert!(pass.max_alpha_target_size.width > 0);
3058-
debug_assert!(pass.max_alpha_target_size.height > 0);
3057+
debug_assert!(pass.max_used_alpha_target_size.width > 0);
3058+
debug_assert!(pass.max_used_alpha_target_size.height > 0);
30593059
self.device.init_texture(
30603060
texture,
3061-
pass.max_alpha_target_size.width,
3062-
pass.max_alpha_target_size.height,
3061+
pass.max_used_alpha_target_size.width,
3062+
pass.max_used_alpha_target_size.height,
30633063
ImageFormat::A8,
30643064
TextureFilter::Nearest,
30653065
RenderTargetMode::RenderTarget,
@@ -3125,17 +3125,17 @@ impl Renderer {
31253125
for (target_index, target) in pass.alpha_targets.targets.iter().enumerate() {
31263126
let projection = Transform3D::ortho(
31273127
0.0,
3128-
pass.max_alpha_target_size.width as f32,
3128+
pass.max_used_alpha_target_size.width as f32,
31293129
0.0,
3130-
pass.max_alpha_target_size.height as f32,
3130+
pass.max_used_alpha_target_size.height as f32,
31313131
ORTHO_NEAR_PLANE,
31323132
ORTHO_FAR_PLANE,
31333133
);
31343134

31353135
self.draw_alpha_target(
31363136
(pass.alpha_texture.as_ref().unwrap(), target_index as i32),
31373137
target,
3138-
pass.max_alpha_target_size,
3138+
pass.max_used_alpha_target_size,
31393139
&projection,
31403140
);
31413141
}
@@ -3165,7 +3165,7 @@ impl Renderer {
31653165
ORTHO_FAR_PLANE,
31663166
)
31673167
} else {
3168-
size = pass.max_color_target_size;
3168+
size = pass.max_used_color_target_size;
31693169
clear_color = Some([0.0, 0.0, 0.0, 0.0]);
31703170
projection = Transform3D::ortho(
31713171
0.0,

webrender/src/tiling.rs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -977,10 +977,18 @@ impl<T: RenderTarget> RenderTargetList<T> {
977977
gpu_cache: &mut GpuCache,
978978
render_tasks: &mut RenderTaskTree,
979979
deferred_resolves: &mut Vec<DeferredResolve>,
980-
) {
980+
) -> DeviceUintSize {
981+
let mut max_used_size = DeviceUintSize::zero();
982+
981983
for target in &mut self.targets {
984+
let used_rect = target.used_rect();
985+
max_used_size.width = cmp::max(max_used_size.width, used_rect.size.width as u32);
986+
max_used_size.height = cmp::max(max_used_size.height, used_rect.size.height as u32);
987+
982988
target.build(ctx, gpu_cache, render_tasks, deferred_resolves);
983989
}
990+
991+
max_used_size
984992
}
985993

986994
fn add_task(
@@ -1076,8 +1084,7 @@ impl RenderTarget for ColorRenderTarget {
10761084
fn used_rect(&self) -> DeviceIntRect {
10771085
self.allocator
10781086
.as_ref()
1079-
.expect("bug: used_rect called on framebuffer")
1080-
.used_rect
1087+
.map_or(DeviceIntRect::zero(), |allocator| allocator.used_rect)
10811088
}
10821089

10831090
fn build(
@@ -1302,8 +1309,10 @@ pub struct RenderPass {
13021309
pub color_texture: Option<Texture>,
13031310
pub alpha_texture: Option<Texture>,
13041311
dynamic_tasks: FastHashMap<RenderTaskKey, DynamicTaskInfo>,
1305-
pub max_color_target_size: DeviceUintSize,
1306-
pub max_alpha_target_size: DeviceUintSize,
1312+
pub color_allocator_size: DeviceUintSize,
1313+
pub alpha_allocator_size: DeviceUintSize,
1314+
pub max_used_color_target_size: DeviceUintSize,
1315+
pub max_used_alpha_target_size: DeviceUintSize,
13071316
}
13081317

13091318
impl RenderPass {
@@ -1316,8 +1325,10 @@ impl RenderPass {
13161325
color_texture: None,
13171326
alpha_texture: None,
13181327
dynamic_tasks: FastHashMap::default(),
1319-
max_color_target_size: DeviceUintSize::new(MIN_TARGET_SIZE, MIN_TARGET_SIZE),
1320-
max_alpha_target_size: DeviceUintSize::new(MIN_TARGET_SIZE, MIN_TARGET_SIZE),
1328+
color_allocator_size: DeviceUintSize::new(MIN_TARGET_SIZE, MIN_TARGET_SIZE),
1329+
alpha_allocator_size: DeviceUintSize::new(MIN_TARGET_SIZE, MIN_TARGET_SIZE),
1330+
max_used_color_target_size: DeviceUintSize::zero(),
1331+
max_used_alpha_target_size: DeviceUintSize::zero(),
13211332
}
13221333
}
13231334

@@ -1329,16 +1340,16 @@ impl RenderPass {
13291340
) {
13301341
match target_kind {
13311342
RenderTargetKind::Color => {
1332-
self.max_color_target_size.width =
1333-
cmp::max(self.max_color_target_size.width, size.width as u32);
1334-
self.max_color_target_size.height =
1335-
cmp::max(self.max_color_target_size.height, size.height as u32);
1343+
self.color_allocator_size.width =
1344+
cmp::max(self.color_allocator_size.width, size.width as u32);
1345+
self.color_allocator_size.height =
1346+
cmp::max(self.color_allocator_size.height, size.height as u32);
13361347
}
13371348
RenderTargetKind::Alpha => {
1338-
self.max_alpha_target_size.width =
1339-
cmp::max(self.max_alpha_target_size.width, size.width as u32);
1340-
self.max_alpha_target_size.height =
1341-
cmp::max(self.max_alpha_target_size.height, size.height as u32);
1349+
self.alpha_allocator_size.width =
1350+
cmp::max(self.alpha_allocator_size.width, size.width as u32);
1351+
self.alpha_allocator_size.height =
1352+
cmp::max(self.alpha_allocator_size.height, size.height as u32);
13421353
}
13431354
}
13441355

@@ -1396,9 +1407,9 @@ impl RenderPass {
13961407
let alloc_size = DeviceUintSize::new(size.width as u32, size.height as u32);
13971408
let (alloc_origin, target_index) = match target_kind {
13981409
RenderTargetKind::Color => self.color_targets
1399-
.allocate(alloc_size, self.max_color_target_size),
1410+
.allocate(alloc_size, self.color_allocator_size),
14001411
RenderTargetKind::Alpha => self.alpha_targets
1401-
.allocate(alloc_size, self.max_alpha_target_size),
1412+
.allocate(alloc_size, self.alpha_allocator_size),
14021413
};
14031414

14041415
let origin = Some((
@@ -1446,9 +1457,9 @@ impl RenderPass {
14461457
}
14471458
}
14481459

1449-
self.color_targets
1460+
self.max_used_color_target_size = self.color_targets
14501461
.build(ctx, gpu_cache, render_tasks, deferred_resolves);
1451-
self.alpha_targets
1462+
self.max_used_alpha_target_size =self.alpha_targets
14521463
.build(ctx, gpu_cache, render_tasks, deferred_resolves);
14531464
}
14541465
}
-3 Bytes
Loading
Loading
0 Bytes
Loading

0 commit comments

Comments
 (0)