Update V8 to version 4.7.42.
[chromium-blink-merge.git] / content / common / gpu / gpu_memory_manager_unittest.cc
blobdebd90ff76ba7a7d460c29577170f0c14272c5a6
1 // Copyright (c) 2012 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.
5 #include "content/common/gpu/gpu_memory_manager.h"
7 #include "content/common/gpu/gpu_memory_manager_client.h"
8 #include "content/common/gpu/gpu_memory_tracking.h"
9 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gfx/geometry/size_conversions.h"
13 using gpu::MemoryAllocation;
15 class FakeMemoryTracker : public gpu::gles2::MemoryTracker {
16 public:
17 void TrackMemoryAllocatedChange(
18 size_t /* old_size */,
19 size_t /* new_size */,
20 gpu::gles2::MemoryTracker::Pool /* pool */) override {}
21 bool EnsureGPUMemoryAvailable(size_t /* size_needed */) override {
22 return true;
24 uint64_t ClientTracingId() const override { return 0; }
25 int ClientId() const override { return 0; }
27 private:
28 ~FakeMemoryTracker() override {}
31 namespace content {
33 // This class is used to collect all stub assignments during a
34 // Manage() call.
35 class ClientAssignmentCollector {
36 public:
37 struct ClientMemoryStat {
38 MemoryAllocation allocation;
40 typedef base::hash_map<GpuMemoryManagerClient*, ClientMemoryStat>
41 ClientMemoryStatMap;
43 static const ClientMemoryStatMap& GetClientStatsForLastManage() {
44 return client_memory_stats_for_last_manage_;
46 static void ClearAllStats() {
47 client_memory_stats_for_last_manage_.clear();
49 static void AddClientStat(GpuMemoryManagerClient* client,
50 const MemoryAllocation& allocation) {
51 DCHECK(!client_memory_stats_for_last_manage_.count(client));
52 client_memory_stats_for_last_manage_[client].allocation = allocation;
55 private:
56 static ClientMemoryStatMap client_memory_stats_for_last_manage_;
59 ClientAssignmentCollector::ClientMemoryStatMap
60 ClientAssignmentCollector::client_memory_stats_for_last_manage_;
62 class FakeClient : public GpuMemoryManagerClient {
63 public:
64 GpuMemoryManager* memmgr_;
65 bool suggest_have_frontbuffer_;
66 MemoryAllocation allocation_;
67 uint64 total_gpu_memory_;
68 gfx::Size surface_size_;
69 GpuMemoryManagerClient* share_group_;
70 scoped_refptr<gpu::gles2::MemoryTracker> memory_tracker_;
71 scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
72 scoped_ptr<GpuMemoryManagerClientState> client_state_;
74 // This will create a client with no surface
75 FakeClient(GpuMemoryManager* memmgr, GpuMemoryManagerClient* share_group)
76 : memmgr_(memmgr),
77 suggest_have_frontbuffer_(false),
78 total_gpu_memory_(0),
79 share_group_(share_group),
80 memory_tracker_(NULL) {
81 if (!share_group_) {
82 memory_tracker_ = new FakeMemoryTracker();
83 tracking_group_.reset(
84 memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
86 client_state_.reset(memmgr_->CreateClientState(this, false, true));
89 // This will create a client with a surface
90 FakeClient(GpuMemoryManager* memmgr, int32 surface_id, bool visible)
91 : memmgr_(memmgr),
92 suggest_have_frontbuffer_(false),
93 total_gpu_memory_(0),
94 share_group_(NULL),
95 memory_tracker_(NULL) {
96 memory_tracker_ = new FakeMemoryTracker();
97 tracking_group_.reset(
98 memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
99 client_state_.reset(
100 memmgr_->CreateClientState(this, surface_id != 0, visible));
103 ~FakeClient() override {
104 client_state_.reset();
105 tracking_group_.reset();
106 memory_tracker_ = NULL;
109 void SetMemoryAllocation(const MemoryAllocation& alloc) override {
110 allocation_ = alloc;
111 ClientAssignmentCollector::AddClientStat(this, alloc);
114 void SuggestHaveFrontBuffer(bool suggest_have_frontbuffer) override {
115 suggest_have_frontbuffer_ = suggest_have_frontbuffer;
118 bool GetTotalGpuMemory(uint64* bytes) override {
119 if (total_gpu_memory_) {
120 *bytes = total_gpu_memory_;
121 return true;
123 return false;
125 void SetTotalGpuMemory(uint64 bytes) { total_gpu_memory_ = bytes; }
127 gpu::gles2::MemoryTracker* GetMemoryTracker() const override {
128 if (share_group_)
129 return share_group_->GetMemoryTracker();
130 return memory_tracker_.get();
133 gfx::Size GetSurfaceSize() const override { return surface_size_; }
134 void SetSurfaceSize(gfx::Size size) { surface_size_ = size; }
136 void SetVisible(bool visible) {
137 client_state_->SetVisible(visible);
140 uint64 BytesWhenVisible() const {
141 return allocation_.bytes_limit_when_visible;
145 class GpuMemoryManagerTest : public testing::Test {
146 protected:
147 static const uint64 kFrontbufferLimitForTest = 3;
149 GpuMemoryManagerTest()
150 : memmgr_(0, kFrontbufferLimitForTest) {
151 memmgr_.TestingDisableScheduleManage();
154 void SetUp() override {}
156 static int32 GenerateUniqueSurfaceId() {
157 static int32 surface_id_ = 1;
158 return surface_id_++;
161 bool IsAllocationForegroundForSurfaceYes(
162 const MemoryAllocation& alloc) {
163 return true;
165 bool IsAllocationBackgroundForSurfaceYes(
166 const MemoryAllocation& alloc) {
167 return true;
169 bool IsAllocationHibernatedForSurfaceYes(
170 const MemoryAllocation& alloc) {
171 return true;
173 bool IsAllocationForegroundForSurfaceNo(
174 const MemoryAllocation& alloc) {
175 return alloc.bytes_limit_when_visible != 0;
177 bool IsAllocationBackgroundForSurfaceNo(
178 const MemoryAllocation& alloc) {
179 return alloc.bytes_limit_when_visible != 0;
181 bool IsAllocationHibernatedForSurfaceNo(
182 const MemoryAllocation& alloc) {
183 return alloc.bytes_limit_when_visible == 0;
186 void Manage() {
187 ClientAssignmentCollector::ClearAllStats();
188 memmgr_.Manage();
191 GpuMemoryManager memmgr_;
194 // Test GpuMemoryManager::Manage basic functionality.
195 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
196 // according to visibility and last used time for stubs with surface.
197 // Expect memory allocation to be shared according to share groups for stubs
198 // without a surface.
199 TEST_F(GpuMemoryManagerTest, TestManageBasicFunctionality) {
200 // Test stubs with surface.
201 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
202 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
204 Manage();
205 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
206 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
208 // Test stubs without surface, with share group of 1 stub.
209 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
211 Manage();
212 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
213 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
214 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
215 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
217 // Test stub without surface, with share group of multiple stubs.
218 FakeClient stub5(&memmgr_ , &stub2);
220 Manage();
221 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
224 // Test GpuMemoryManager::Manage functionality: changing visibility.
225 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
226 // according to visibility and last used time for stubs with surface.
227 // Expect memory allocation to be shared according to share groups for stubs
228 // without a surface.
229 TEST_F(GpuMemoryManagerTest, TestManageChangingVisibility) {
230 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
231 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
233 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
234 FakeClient stub5(&memmgr_ , &stub2);
236 Manage();
237 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
238 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
239 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
240 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
241 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
243 stub1.SetVisible(false);
244 stub2.SetVisible(true);
246 Manage();
247 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
248 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
249 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
250 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
251 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
254 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
255 // of visible stubs.
256 // Expect all allocations to continue to have frontbuffer.
257 TEST_F(GpuMemoryManagerTest, TestManageManyVisibleStubs) {
258 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
259 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
260 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
261 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
263 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub2);
264 FakeClient stub7(&memmgr_ , &stub2);
266 Manage();
267 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
268 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
269 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub3.allocation_));
270 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub4.allocation_));
271 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
272 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub6.allocation_));
273 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub7.allocation_));
276 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
277 // of not visible stubs.
278 // Expect the stubs surpassing the threshold to not have a backbuffer.
279 TEST_F(GpuMemoryManagerTest, TestManageManyNotVisibleStubs) {
280 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
281 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
282 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
283 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
284 stub4.SetVisible(false);
285 stub3.SetVisible(false);
286 stub2.SetVisible(false);
287 stub1.SetVisible(false);
289 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub4);
290 FakeClient stub7(&memmgr_ , &stub1);
292 Manage();
293 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
294 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
295 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
296 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
297 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
298 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
299 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
302 // Test GpuMemoryManager::Manage functionality: Test changing the last used
303 // time of stubs when doing so causes change in which stubs surpass threshold.
304 // Expect frontbuffer to be dropped for the older stub.
305 TEST_F(GpuMemoryManagerTest, TestManageChangingLastUsedTime) {
306 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
307 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
308 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
309 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
311 FakeClient stub5(&memmgr_ , &stub3), stub6(&memmgr_ , &stub4);
312 FakeClient stub7(&memmgr_ , &stub3);
314 // Make stub4 be the least-recently-used client
315 stub4.SetVisible(false);
316 stub3.SetVisible(false);
317 stub2.SetVisible(false);
318 stub1.SetVisible(false);
320 Manage();
321 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
322 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
323 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
324 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
325 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
326 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
327 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
329 // Make stub3 become the least-recently-used client.
330 stub2.SetVisible(true);
331 stub2.SetVisible(false);
332 stub4.SetVisible(true);
333 stub4.SetVisible(false);
335 Manage();
336 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
337 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
338 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub3.allocation_));
339 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub4.allocation_));
340 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub5.allocation_));
341 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub6.allocation_));
342 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub7.allocation_));
345 // Test GpuMemoryManager::Manage functionality: Test changing importance of
346 // enough stubs so that every stub in share group crosses threshold.
347 // Expect memory allocation of the stubs without surface to share memory
348 // allocation with the most visible stub in share group.
349 TEST_F(GpuMemoryManagerTest, TestManageChangingImportanceShareGroup) {
350 FakeClient stub_ignore_a(&memmgr_, GenerateUniqueSurfaceId(), true),
351 stub_ignore_b(&memmgr_, GenerateUniqueSurfaceId(), false),
352 stub_ignore_c(&memmgr_, GenerateUniqueSurfaceId(), false);
353 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), false),
354 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
356 FakeClient stub3(&memmgr_, &stub2), stub4(&memmgr_, &stub2);
358 // stub1 and stub2 keep their non-hibernated state because they're
359 // either visible or the 2 most recently used clients (through the
360 // first three checks).
361 stub1.SetVisible(true);
362 stub2.SetVisible(true);
363 Manage();
364 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
365 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
366 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
367 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
369 stub1.SetVisible(false);
370 Manage();
371 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
372 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
373 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
374 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
376 stub2.SetVisible(false);
377 Manage();
378 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
379 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
380 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
381 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
383 // stub_ignore_b will cause stub1 to become hibernated (because
384 // stub_ignore_a, stub_ignore_b, and stub2 are all non-hibernated and more
385 // important).
386 stub_ignore_b.SetVisible(true);
387 stub_ignore_b.SetVisible(false);
388 Manage();
389 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
390 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
391 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
392 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
394 // stub_ignore_c will cause stub2 to become hibernated (because
395 // stub_ignore_a, stub_ignore_b, and stub_ignore_c are all non-hibernated
396 // and more important).
397 stub_ignore_c.SetVisible(true);
398 stub_ignore_c.SetVisible(false);
399 Manage();
400 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
401 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_));
402 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_));
403 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_));
406 } // namespace content