OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/renderer_host/backing_store_manager.h" | 5 #include "chrome/browser/renderer_host/backing_store_manager.h" |
6 | 6 |
7 #include "base/sys_info.h" | 7 #include "base/sys_info.h" |
8 #include "chrome/browser/renderer_host/backing_store.h" | 8 #include "chrome/browser/renderer_host/backing_store.h" |
9 #include "chrome/browser/renderer_host/render_widget_host.h" | 9 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 10 #include "chrome/browser/renderer_host/render_widget_host_painting_observer.h" |
10 #include "chrome/common/chrome_constants.h" | 11 #include "chrome/common/chrome_constants.h" |
11 | 12 |
12 namespace { | 13 namespace { |
13 | 14 |
14 typedef OwningMRUCache<RenderWidgetHost*, BackingStore*> BackingStoreCache; | 15 typedef OwningMRUCache<RenderWidgetHost*, BackingStore*> BackingStoreCache; |
15 static BackingStoreCache* cache = NULL; | 16 static BackingStoreCache* cache = NULL; |
16 | 17 |
17 // Returns the size of the backing store cache. | 18 // Returns the size of the backing store cache. |
18 static int GetBackingStoreCacheSize() { | 19 static size_t GetBackingStoreCacheSize() { |
19 // This uses a similar approach to GetMaxRendererProcessCount. The goal | 20 // This uses a similar approach to GetMaxRendererProcessCount. The goal |
20 // is to reduce memory pressure and swapping on low-resource machines. | 21 // is to reduce memory pressure and swapping on low-resource machines. |
21 static const int kMaxDibCountByRamTier[] = { | 22 static const size_t kMaxDibCountByRamTier[] = { |
22 2, // less than 256MB | 23 2, // less than 256MB |
23 3, // 256MB | 24 3, // 256MB |
24 4, // 512MB | 25 4, // 512MB |
25 5 // 768MB and above | 26 5 // 768MB and above |
26 }; | 27 }; |
27 | 28 |
28 static int max_size = kMaxDibCountByRamTier[ | 29 static size_t max_size = kMaxDibCountByRamTier[ |
29 std::min(base::SysInfo::AmountOfPhysicalMemoryMB() / 256, | 30 std::min(base::SysInfo::AmountOfPhysicalMemoryMB() / 256, |
30 static_cast<int>(arraysize(kMaxDibCountByRamTier)) - 1)]; | 31 static_cast<int>(arraysize(kMaxDibCountByRamTier)) - 1)]; |
31 return max_size; | 32 return max_size; |
32 } | 33 } |
33 | 34 |
| 35 // Expires the given backing store from the cache. |
| 36 void ExpireBackingStoreAt(BackingStoreCache::iterator backing_store) { |
| 37 RenderWidgetHost* rwh = backing_store->second->render_widget_host(); |
| 38 if (rwh->painting_observer()) { |
| 39 rwh->painting_observer()->WidgetWillDestroyBackingStore( |
| 40 backing_store->first, |
| 41 backing_store->second); |
| 42 } |
| 43 cache->Erase(backing_store); |
| 44 } |
| 45 |
34 // Creates the backing store for the host based on the dimensions passed in. | 46 // Creates the backing store for the host based on the dimensions passed in. |
35 // Removes the existing backing store if there is one. | 47 // Removes the existing backing store if there is one. |
36 BackingStore* CreateBackingStore(RenderWidgetHost* host, | 48 BackingStore* CreateBackingStore(RenderWidgetHost* host, |
37 const gfx::Size& backing_store_size) { | 49 const gfx::Size& backing_store_size) { |
| 50 // Remove any existing backing store in case we're replacing it. |
38 BackingStoreManager::RemoveBackingStore(host); | 51 BackingStoreManager::RemoveBackingStore(host); |
39 | 52 |
| 53 size_t max_cache_size = GetBackingStoreCacheSize(); |
| 54 if (max_cache_size > 0 && !cache) |
| 55 cache = new BackingStoreCache(BackingStoreCache::NO_AUTO_EVICT); |
| 56 |
| 57 if (cache->size() >= max_cache_size) { |
| 58 // Need to remove an old backing store to make room for the new one. We |
| 59 // don't want to do this when the backing store is being replace by a new |
| 60 // one for the same tab, but this case won't get called then: we'll have |
| 61 // removed the onld one in the RemoveBackingStore above, and the cache |
| 62 // won't be over-sized. |
| 63 // |
| 64 // Crazy C++ alert: rbegin.base() is a forward iterator pointing to end(), |
| 65 // so we need to do -- to move one back to the actual last item. |
| 66 ExpireBackingStoreAt(--cache->rbegin().base()); |
| 67 } |
| 68 |
40 BackingStore* backing_store = host->AllocBackingStore(backing_store_size); | 69 BackingStore* backing_store = host->AllocBackingStore(backing_store_size); |
41 int backing_store_cache_size = GetBackingStoreCacheSize(); | 70 if (max_cache_size > 0) |
42 if (backing_store_cache_size > 0) { | |
43 if (!cache) | |
44 cache = new BackingStoreCache(backing_store_cache_size); | |
45 cache->Put(host, backing_store); | 71 cache->Put(host, backing_store); |
46 } | |
47 return backing_store; | 72 return backing_store; |
48 } | 73 } |
49 | 74 |
50 } // namespace | 75 } // namespace |
51 | 76 |
52 // BackingStoreManager --------------------------------------------------------- | 77 // BackingStoreManager --------------------------------------------------------- |
53 | 78 |
54 // static | 79 // static |
55 BackingStore* BackingStoreManager::GetBackingStore( | 80 BackingStore* BackingStoreManager::GetBackingStore( |
56 RenderWidgetHost* host, | 81 RenderWidgetHost* host, |
(...skipping 46 matching lines...) Loading... |
103 } | 128 } |
104 | 129 |
105 // static | 130 // static |
106 void BackingStoreManager::RemoveBackingStore(RenderWidgetHost* host) { | 131 void BackingStoreManager::RemoveBackingStore(RenderWidgetHost* host) { |
107 if (!cache) | 132 if (!cache) |
108 return; | 133 return; |
109 | 134 |
110 BackingStoreCache::iterator it = cache->Peek(host); | 135 BackingStoreCache::iterator it = cache->Peek(host); |
111 if (it == cache->end()) | 136 if (it == cache->end()) |
112 return; | 137 return; |
113 | |
114 cache->Erase(it); | 138 cache->Erase(it); |
115 | 139 |
116 if (cache->empty()) { | 140 if (cache->empty()) { |
117 delete cache; | 141 delete cache; |
118 cache = NULL; | 142 cache = NULL; |
119 } | 143 } |
120 } | 144 } |
| 145 |
| 146 // static |
| 147 bool BackingStoreManager::ExpireBackingStoreForTest(RenderWidgetHost* host) { |
| 148 BackingStoreCache::iterator it = cache->Peek(host); |
| 149 if (it == cache->end()) |
| 150 return false; |
| 151 ExpireBackingStoreAt(it); |
| 152 return true; |
| 153 } |
OLD | NEW |