зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1587713 - Don't limit the number of rasterized blob tiles per transaction. r=jrmuizel
If this change lands without making waves, a lot of complicated blob infrastructure will be removed as a followup. Differential Revision: https://phabricator.services.mozilla.com/D49185 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d60ad185ac
Коммит
4a8849bcc4
|
@ -436,9 +436,7 @@ pub struct BlobImageRasterizerEpoch(usize);
|
||||||
|
|
||||||
/// Stores parameters for clearing blob image tiles.
|
/// Stores parameters for clearing blob image tiles.
|
||||||
///
|
///
|
||||||
/// The clearing is necessary when originally requested tile range exceeds
|
/// TODO(nical) this can be removed.
|
||||||
/// MAX_TILES_PER_REQUEST. In this case, some tiles are not rasterized by
|
|
||||||
/// AsyncBlobImageRasterizer. They need to be cleared.
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct BlobImageClearParams {
|
pub struct BlobImageClearParams {
|
||||||
pub key: BlobImageKey,
|
pub key: BlobImageKey,
|
||||||
|
@ -730,35 +728,6 @@ impl ResourceCache {
|
||||||
self.blob_image_rasterizer = Some(rasterizer);
|
self.blob_image_rasterizer = Some(rasterizer);
|
||||||
self.blob_image_rasterizer_consumed_epoch = supp.epoch;
|
self.blob_image_rasterizer_consumed_epoch = supp.epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discard blob image tiles that are not rendered by AsyncBlobImageRasterizer.
|
|
||||||
// It happens when originally requested tile range exceeds MAX_TILES_PER_REQUEST.
|
|
||||||
for req in supp.clear_requests {
|
|
||||||
let tiles = match self.rasterized_blob_images.get_mut(&req.key) {
|
|
||||||
Some(RasterizedBlob::Tiled(tiles)) => tiles,
|
|
||||||
_ => { continue; }
|
|
||||||
};
|
|
||||||
|
|
||||||
tiles.retain(|tile, _| {
|
|
||||||
!req.original_tile_range.contains(*tile) ||
|
|
||||||
req.actual_tile_range.contains(*tile)
|
|
||||||
});
|
|
||||||
|
|
||||||
let texture_cache = &mut self.texture_cache;
|
|
||||||
match self.cached_images.try_get_mut(&req.key.as_image()) {
|
|
||||||
Some(&mut ImageResult::Multi(ref mut entries)) => {
|
|
||||||
entries.retain(|key, entry| {
|
|
||||||
if !req.original_tile_range.contains(key.tile.unwrap()) ||
|
|
||||||
req.actual_tile_range.contains(key.tile.unwrap()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
entry.mark_unused(texture_cache);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_rasterized_blob_images(
|
pub fn add_rasterized_blob_images(
|
||||||
|
@ -1266,7 +1235,6 @@ impl ResourceCache {
|
||||||
return (None, Vec::new());
|
return (None, Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut blob_tiles_clear_requests = Vec::new();
|
|
||||||
let mut blob_request_params = Vec::new();
|
let mut blob_request_params = Vec::new();
|
||||||
for key in keys {
|
for key in keys {
|
||||||
let template = self.blob_image_templates.get_mut(key).unwrap();
|
let template = self.blob_image_templates.get_mut(key).unwrap();
|
||||||
|
@ -1274,7 +1242,7 @@ impl ResourceCache {
|
||||||
if let Some(tile_size) = template.tiling {
|
if let Some(tile_size) = template.tiling {
|
||||||
// If we know that only a portion of the blob image is in the viewport,
|
// If we know that only a portion of the blob image is in the viewport,
|
||||||
// only request these visible tiles since blob images can be huge.
|
// only request these visible tiles since blob images can be huge.
|
||||||
let mut tiles = compute_tile_range(
|
let tiles = compute_tile_range(
|
||||||
&template.visible_rect,
|
&template.visible_rect,
|
||||||
tile_size,
|
tile_size,
|
||||||
);
|
);
|
||||||
|
@ -1302,46 +1270,6 @@ impl ResourceCache {
|
||||||
DirtyRect::All => tiles,
|
DirtyRect::All => tiles,
|
||||||
};
|
};
|
||||||
|
|
||||||
let original_tile_range = tiles;
|
|
||||||
|
|
||||||
// This code tries to keep things sane if Gecko sends
|
|
||||||
// nonsensical blob image requests.
|
|
||||||
// Constant here definitely needs to be tweaked.
|
|
||||||
const MAX_TILES_PER_REQUEST: i32 = 512;
|
|
||||||
// For truly nonsensical requests, we might run into overflow
|
|
||||||
// when computing width * height, so we first check each extent
|
|
||||||
// individually.
|
|
||||||
while !tiles.size.is_empty_or_negative()
|
|
||||||
&& (tiles.size.width > MAX_TILES_PER_REQUEST
|
|
||||||
|| tiles.size.height > MAX_TILES_PER_REQUEST
|
|
||||||
|| tiles.size.width * tiles.size.height > MAX_TILES_PER_REQUEST) {
|
|
||||||
let limit = 46340; // sqrt(i32::MAX) rounded down to avoid overflow.
|
|
||||||
let w = tiles.size.width.min(limit);
|
|
||||||
let h = tiles.size.height.min(limit);
|
|
||||||
let diff = w * h - MAX_TILES_PER_REQUEST;
|
|
||||||
// Remove tiles in the largest dimension.
|
|
||||||
if tiles.size.width > tiles.size.height {
|
|
||||||
tiles.size.width -= diff / h + 1;
|
|
||||||
tiles.origin.x += diff / (2 * h);
|
|
||||||
} else {
|
|
||||||
tiles.size.height -= diff / w + 1;
|
|
||||||
tiles.origin.y += diff / (2 * w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// When originally requested tile range exceeds MAX_TILES_PER_REQUEST,
|
|
||||||
// some tiles are not rasterized by AsyncBlobImageRasterizer.
|
|
||||||
// They need to be cleared.
|
|
||||||
if original_tile_range != tiles {
|
|
||||||
let clear_params = BlobImageClearParams {
|
|
||||||
key: *key,
|
|
||||||
original_tile_range,
|
|
||||||
actual_tile_range: tiles,
|
|
||||||
};
|
|
||||||
blob_tiles_clear_requests.push(clear_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for_each_tile_in_range(&tiles, |tile| {
|
for_each_tile_in_range(&tiles, |tile| {
|
||||||
let still_valid = template.valid_tiles_after_bounds_change
|
let still_valid = template.valid_tiles_after_bounds_change
|
||||||
.map(|valid_tiles| valid_tiles.contains(tile))
|
.map(|valid_tiles| valid_tiles.contains(tile))
|
||||||
|
@ -1431,7 +1359,7 @@ impl ResourceCache {
|
||||||
self.blob_image_rasterizer_produced_epoch.0 += 1;
|
self.blob_image_rasterizer_produced_epoch.0 += 1;
|
||||||
let info = AsyncBlobImageInfo {
|
let info = AsyncBlobImageInfo {
|
||||||
epoch: self.blob_image_rasterizer_produced_epoch,
|
epoch: self.blob_image_rasterizer_produced_epoch,
|
||||||
clear_requests: blob_tiles_clear_requests,
|
clear_requests: Vec::new(),
|
||||||
};
|
};
|
||||||
let handler = self.blob_image_handler.as_mut().unwrap();
|
let handler = self.blob_image_handler.as_mut().unwrap();
|
||||||
handler.prepare_resources(&self.resources, &blob_request_params);
|
handler.prepare_resources(&self.resources, &blob_request_params);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче