Commit 41a2bac0 authored by Jamie Nicol's avatar Jamie Nicol
Browse files

Bug 1784049 - Free native surfaces held by tile cache on memory pressure. r=gw

When the webrender render backend receives a memory pressure event,
call a new function TileCacheInstance.memory_pressure() for each tile
cache owned by the render backend. This destroys each compositor tile
and surface owned by the cache. By additionally setting the
NativeTileId for each tile to None, we will automatically allocate new
tiles if required during the next frame build.

On Android with SWGL enabled, this helps prevent ballooning memory
usage when opening several tabs, as memory pressure events are
triggered when a tab is backgrounded.

Differential Revision: https://phabricator.services.mozilla.com/D154635
parent 7535712f
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2007,6 +2007,25 @@ impl TileCacheInstance {
        self.tile_rect.area() as usize * self.sub_slices.len()
    }

    /// Trims memory held by the tile cache, such as native surfaces.
    pub fn memory_pressure(&mut self, resource_cache: &mut ResourceCache) {
        for sub_slice in &mut self.sub_slices {
            for tile in sub_slice.tiles.values_mut() {
                if let Some(TileSurface::Texture { descriptor: SurfaceTextureDescriptor::Native { ref mut id, .. }, .. }) = tile.surface {
                    // Reseting the id to None with take() ensures that a new
                    // tile will be allocated during the next frame build.
                    if let Some(id) = id.take() {
                        resource_cache.destroy_compositor_tile(id);
                    }
                }
            }
            if let Some(native_surface) = sub_slice.native_surface.take() {
                resource_cache.destroy_compositor_surface(native_surface.opaque);
                resource_cache.destroy_compositor_surface(native_surface.alpha);
            }
        }
    }

    /// Reset this tile cache with the updated parameters from a new scene
    /// that has arrived. This allows the tile cache to be retained across
    /// new scenes.
+3 −0
Original line number Diff line number Diff line
@@ -960,6 +960,9 @@ impl RenderBackend {

                for (_, doc) in &mut self.documents {
                    doc.scratch.memory_pressure();
                    for tile_cache in self.tile_caches.values_mut() {
                        tile_cache.memory_pressure(&mut self.resource_cache);
                    }
                }

                let resource_updates = self.resource_cache.pending_updates();