Bug 1519106 - Converge towards the max number of tiles faster. r=kats
authorNicolas Silva <nsilva@mozilla.com>
Wed, 17 Apr 2019 14:41:47 +0000
changeset 469851 902bff64318d963ea1d5505eebd0f66b11d55f28
parent 469850 d6c9841c74cdc5cdb84becbd304afcdebf13a3cf
child 469852 58a63a9525b874c59da463c70a5c25ad846471a8
push id35883
push userbtara@mozilla.com
push dateWed, 17 Apr 2019 21:47:29 +0000
treeherdermozilla-central@02b89c29412b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1519106
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1519106 - Converge towards the max number of tiles faster. r=kats Differential Revision: https://phabricator.services.mozilla.com/D27728
gfx/wr/webrender/src/resource_cache.rs
--- a/gfx/wr/webrender/src/resource_cache.rs
+++ b/gfx/wr/webrender/src/resource_cache.rs
@@ -1205,36 +1205,30 @@ impl ResourceCache {
 
                 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. Even if we don't, the loop
-                // below to reduce the number of tiles is linear and can take
-                // a long time to complete. These preliminary conditions help
-                // get us there faster and avoid the overflow.
-                if tiles.size.width > MAX_TILES_PER_REQUEST {
-                    tiles.origin.x += (tiles.size.width - MAX_TILES_PER_REQUEST) / 2;
-                    tiles.size.width = MAX_TILES_PER_REQUEST;
-                }
-                if tiles.size.height > MAX_TILES_PER_REQUEST {
-                    tiles.origin.y += (tiles.size.height - MAX_TILES_PER_REQUEST) / 2;
-                    tiles.size.height = MAX_TILES_PER_REQUEST;
-                }
-                while tiles.size.width as i32 * tiles.size.height as i32 > MAX_TILES_PER_REQUEST {
+                // 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 diff = tiles.size.width * tiles.size.height - MAX_TILES_PER_REQUEST;
                     // Remove tiles in the largest dimension.
                     if tiles.size.width > tiles.size.height {
-                        tiles.size.width -= 2;
-                        tiles.origin.x += 1;
+                        tiles.size.width -= diff / tiles.size.height + 1;
+                        tiles.origin.x += diff / (2 * tiles.size.height);
                     } else {
-                        tiles.size.height -= 2;
-                        tiles.origin.y += 1;
+                        tiles.size.height -= diff / tiles.size.width + 1;
+                        tiles.origin.y += diff / (2 * tiles.size.height);
                     }
                 }
 
                 // 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 {