зеркало из 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.
|
||||
///
|
||||
/// The clearing is necessary when originally requested tile range exceeds
|
||||
/// MAX_TILES_PER_REQUEST. In this case, some tiles are not rasterized by
|
||||
/// AsyncBlobImageRasterizer. They need to be cleared.
|
||||
/// TODO(nical) this can be removed.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct BlobImageClearParams {
|
||||
pub key: BlobImageKey,
|
||||
|
@ -730,35 +728,6 @@ impl ResourceCache {
|
|||
self.blob_image_rasterizer = Some(rasterizer);
|
||||
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(
|
||||
|
@ -1266,7 +1235,6 @@ impl ResourceCache {
|
|||
return (None, Vec::new());
|
||||
}
|
||||
|
||||
let mut blob_tiles_clear_requests = Vec::new();
|
||||
let mut blob_request_params = Vec::new();
|
||||
for key in keys {
|
||||
let template = self.blob_image_templates.get_mut(key).unwrap();
|
||||
|
@ -1274,7 +1242,7 @@ impl ResourceCache {
|
|||
if let Some(tile_size) = template.tiling {
|
||||
// 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.
|
||||
let mut tiles = compute_tile_range(
|
||||
let tiles = compute_tile_range(
|
||||
&template.visible_rect,
|
||||
tile_size,
|
||||
);
|
||||
|
@ -1302,46 +1270,6 @@ impl ResourceCache {
|
|||
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| {
|
||||
let still_valid = template.valid_tiles_after_bounds_change
|
||||
.map(|valid_tiles| valid_tiles.contains(tile))
|
||||
|
@ -1431,7 +1359,7 @@ impl ResourceCache {
|
|||
self.blob_image_rasterizer_produced_epoch.0 += 1;
|
||||
let info = AsyncBlobImageInfo {
|
||||
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();
|
||||
handler.prepare_resources(&self.resources, &blob_request_params);
|
||||
|
|
Загрузка…
Ссылка в новой задаче