1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_VIZ_CLIENT_FRAME_EVICTION_MANAGER_H_ 6 #define COMPONENTS_VIZ_CLIENT_FRAME_EVICTION_MANAGER_H_ 7 8 #include <stddef.h> 9 10 #include <list> 11 #include <map> 12 13 #include "base/macros.h" 14 #include "base/memory/memory_pressure_listener.h" 15 #include "base/memory/singleton.h" 16 #include "base/optional.h" 17 #include "components/viz/client/viz_client_export.h" 18 19 namespace viz { 20 21 class FrameEvictionManagerClient { 22 public: ~FrameEvictionManagerClient()23 virtual ~FrameEvictionManagerClient() {} 24 virtual void EvictCurrentFrame() = 0; 25 }; 26 27 // This class is responsible for globally managing which renderers keep their 28 // compositor frame when offscreen. We actively discard compositor frames for 29 // offscreen tabs, but keep a minimum amount, as an LRU cache, to make switching 30 // between a small set of tabs faster. The limit is a soft limit, because 31 // clients can lock their frame to prevent it from being discarded, e.g. if the 32 // tab is visible, or while capturing a screenshot. 33 class VIZ_CLIENT_EXPORT FrameEvictionManager { 34 public: 35 // Pauses frame eviction within its scope. 36 class VIZ_CLIENT_EXPORT ScopedPause { 37 public: 38 ScopedPause(); 39 ~ScopedPause(); 40 41 private: 42 DISALLOW_COPY_AND_ASSIGN(ScopedPause); 43 }; 44 45 static FrameEvictionManager* GetInstance(); 46 47 void AddFrame(FrameEvictionManagerClient*, bool locked); 48 void RemoveFrame(FrameEvictionManagerClient*); 49 void LockFrame(FrameEvictionManagerClient*); 50 void UnlockFrame(FrameEvictionManagerClient*); 51 52 size_t GetMaxNumberOfSavedFrames() const; 53 54 // For testing only set_max_number_of_saved_frames(size_t max_number_of_saved_frames)55 void set_max_number_of_saved_frames(size_t max_number_of_saved_frames) { 56 max_number_of_saved_frames_ = max_number_of_saved_frames; 57 } 58 59 // React on memory pressure events to adjust the number of cached frames. 60 // Please make this private when crbug.com/443824 has been fixed. 61 void OnMemoryPressure( 62 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); 63 64 // Purges all unlocked frames, allowing us to reclaim resources. 65 void PurgeAllUnlockedFrames(); 66 67 private: 68 friend struct base::DefaultSingletonTraits<FrameEvictionManager>; 69 70 FrameEvictionManager(); 71 ~FrameEvictionManager(); 72 73 void CullUnlockedFrames(size_t saved_frame_limit); 74 75 void PurgeMemory(int percentage); 76 77 // Pauses/unpauses frame eviction. 78 void Pause(); 79 void Unpause(); 80 81 // Listens for system under pressure notifications and adjusts number of 82 // cached frames accordingly. 83 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; 84 85 std::map<FrameEvictionManagerClient*, size_t> locked_frames_; 86 std::list<FrameEvictionManagerClient*> unlocked_frames_; 87 size_t max_number_of_saved_frames_; 88 89 // Counter of the outstanding pauses. 90 int pause_count_ = 0; 91 92 // Argument of the last CullUnlockedFrames call while paused. 93 base::Optional<size_t> pending_unlocked_frame_limit_; 94 95 DISALLOW_COPY_AND_ASSIGN(FrameEvictionManager); 96 }; 97 98 } // namespace viz 99 100 #endif // COMPONENTS_VIZ_CLIENT_FRAME_EVICTION_MANAGER_H_ 101