Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / content / common / gpu / gpu_memory_manager_unittest.cc
blob567ee25bf12cca61c721de123439bd8a496409d1
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; }
26 uint64_t ShareGroupTracingGUID() const override { return 0; }
28 private:
29 ~FakeMemoryTracker() override {}
32 namespace content {
34 // This class is used to collect all stub assignments during a
35 // Manage() call.
36 class ClientAssignmentCollector {
37 public:
38 struct ClientMemoryStat {
39 MemoryAllocation allocation;
41 typedef base::hash_map<GpuMemoryManagerClient*, ClientMemoryStat>
42 ClientMemoryStatMap;
44 static const ClientMemoryStatMap& GetClientStatsForLastManage() {
45 return client_memory_stats_for_last_manage_;
47 static void ClearAllStats() {
48 client_memory_stats_for_last_manage_.clear();
50 static void AddClientStat(GpuMemoryManagerClient* client,
51 const MemoryAllocation& allocation) {
52 DCHECK(!client_memory_stats_for_last_manage_.count(client));
53 client_memory_stats_for_last_manage_[client].allocation = allocation;
56 private:
57 static ClientMemoryStatMap client_memory_stats_for_last_manage_;
60 ClientAssignmentCollector::ClientMemoryStatMap
61 ClientAssignmentCollector::client_memory_stats_for_last_manage_;
63 class FakeClient : public GpuMemoryManagerClient {
64 public:
65 GpuMemoryManager* memmgr_;
66 bool suggest_have_frontbuffer_;
67 MemoryAllocation allocation_;
68 uint64 total_gpu_memory_;
69 gfx::Size surface_size_;
70 GpuMemoryManagerClient* share_group_;
71 scoped_refptr<gpu::gles2::MemoryTracker> memory_tracker_;
72 scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
73 scoped_ptr<GpuMemoryManagerClientState> client_state_;
75 // This will create a client with no surface
76 FakeClient(GpuMemoryManager* memmgr, GpuMemoryManagerClient* share_group)
77 : memmgr_(memmgr),
78 suggest_have_frontbuffer_(false),
79 total_gpu_memory_(0),
80 share_group_(share_group),
81 memory_tracker_(NULL) {
82 if (!share_group_) {
83 memory_tracker_ = new FakeMemoryTracker();
84 tracking_group_.reset(
85 memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
87 client_state_.reset(memmgr_->CreateClientState(this, false, true));
90 // This will create a client with a surface
91 FakeClient(GpuMemoryManager* memmgr, int32 surface_id, bool visible)
92 : memmgr_(memmgr),
93 suggest_have_frontbuffer_(false),
94 total_gpu_memory_(0),
95 share_group_(NULL),
96 memory_tracker_(NULL) {
97 memory_tracker_ = new FakeMemoryTracker();
98 tracking_group_.reset(
99 memmgr_->CreateTrackingGroup(0, memory_tracker_.get()));
100 client_state_.reset(
101 memmgr_->CreateClientState(this, surface_id != 0, visible));
104 ~FakeClient() override {
105 client_state_.reset();
106 tracking_group_.reset();
107 memory_tracker_ = NULL;
110 void SetMemoryAllocation(const MemoryAllocation& alloc) override {
111 allocation_ = alloc;
112 ClientAssignmentCollector::AddClientStat(this, alloc);
115 void SuggestHaveFrontBuffer(bool suggest_have_frontbuffer) override {
116 suggest_have_frontbuffer_ = suggest_have_frontbuffer;
119 bool GetTotalGpuMemory(uint64* bytes) override {
120 if (total_gpu_memory_) {
121 *bytes = total_gpu_memory_;
122 return true;
124 return false;
126 void SetTotalGpuMemory(uint64 bytes) { total_gpu_memory_ = bytes; }
128 gpu::gles2::MemoryTracker* GetMemoryTracker() const override {
129 if (share_group_)
130 return share_group_->GetMemoryTracker();
131 return memory_tracker_.get();
134 gfx::Size GetSurfaceSize() const override { return surface_size_; }
135 void SetSurfaceSize(gfx::Size size) { surface_size_ = size; }
137 void SetVisible(bool visible) {
138 client_state_->SetVisible(visible);
141 uint64 BytesWhenVisible() const {
142 return allocation_.bytes_limit_when_visible;
146 class GpuMemoryManagerTest : public testing::Test {
147 protected:
148 static const uint64 kFrontbufferLimitForTest = 3;
150 GpuMemoryManagerTest()
151 : memmgr_(0, kFrontbufferLimitForTest) {
152 memmgr_.TestingDisableScheduleManage();
155 void SetUp() override {}
157 static int32 GenerateUniqueSurfaceId() {
158 static int32 surface_id_ = 1;
159 return surface_id_++;
162 bool IsAllocationForegroundForSurfaceYes(
163 const MemoryAllocation& alloc) {
164 return true;
166 bool IsAllocationBackgroundForSurfaceYes(
167 const MemoryAllocation& alloc) {
168 return true;
170 bool IsAllocationHibernatedForSurfaceYes(
171 const MemoryAllocation& alloc) {
172 return true;
174 bool IsAllocationForegroundForSurfaceNo(
175 const MemoryAllocation& alloc) {
176 return alloc.bytes_limit_when_visible != 0;
178 bool IsAllocationBackgroundForSurfaceNo(
179 const MemoryAllocation& alloc) {
180 return alloc.bytes_limit_when_visible != 0;
182 bool IsAllocationHibernatedForSurfaceNo(
183 const MemoryAllocation& alloc) {
184 return alloc.bytes_limit_when_visible == 0;
187 void Manage() {
188 ClientAssignmentCollector::ClearAllStats();
189 memmgr_.Manage();
192 GpuMemoryManager memmgr_;
195 // Test GpuMemoryManager::Manage basic functionality.
196 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
197 // according to visibility and last used time for stubs with surface.
198 // Expect memory allocation to be shared according to share groups for stubs
199 // without a surface.
200 TEST_F(GpuMemoryManagerTest, TestManageBasicFunctionality) {
201 // Test stubs with surface.
202 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
203 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
205 Manage();
206 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
207 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
209 // Test stubs without surface, with share group of 1 stub.
210 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
212 Manage();
213 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
214 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
215 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
216 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
218 // Test stub without surface, with share group of multiple stubs.
219 FakeClient stub5(&memmgr_ , &stub2);
221 Manage();
222 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
225 // Test GpuMemoryManager::Manage functionality: changing visibility.
226 // Expect memory allocation to set suggest_have_frontbuffer/backbuffer
227 // according to visibility and last used time for stubs with surface.
228 // Expect memory allocation to be shared according to share groups for stubs
229 // without a surface.
230 TEST_F(GpuMemoryManagerTest, TestManageChangingVisibility) {
231 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
232 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
234 FakeClient stub3(&memmgr_, &stub1), stub4(&memmgr_, &stub2);
235 FakeClient stub5(&memmgr_ , &stub2);
237 Manage();
238 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
239 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
240 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
241 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
242 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
244 stub1.SetVisible(false);
245 stub2.SetVisible(true);
247 Manage();
248 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
249 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
250 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
251 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
252 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
255 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
256 // of visible stubs.
257 // Expect all allocations to continue to have frontbuffer.
258 TEST_F(GpuMemoryManagerTest, TestManageManyVisibleStubs) {
259 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
260 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
261 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
262 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
264 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub2);
265 FakeClient stub7(&memmgr_ , &stub2);
267 Manage();
268 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
269 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
270 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub3.allocation_));
271 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub4.allocation_));
272 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub5.allocation_));
273 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub6.allocation_));
274 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub7.allocation_));
277 // Test GpuMemoryManager::Manage functionality: Test more than threshold number
278 // of not visible stubs.
279 // Expect the stubs surpassing the threshold to not have a backbuffer.
280 TEST_F(GpuMemoryManagerTest, TestManageManyNotVisibleStubs) {
281 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
282 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
283 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
284 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
285 stub4.SetVisible(false);
286 stub3.SetVisible(false);
287 stub2.SetVisible(false);
288 stub1.SetVisible(false);
290 FakeClient stub5(&memmgr_ , &stub1), stub6(&memmgr_ , &stub4);
291 FakeClient stub7(&memmgr_ , &stub1);
293 Manage();
294 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
295 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
296 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
297 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
298 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
299 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
300 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
303 // Test GpuMemoryManager::Manage functionality: Test changing the last used
304 // time of stubs when doing so causes change in which stubs surpass threshold.
305 // Expect frontbuffer to be dropped for the older stub.
306 TEST_F(GpuMemoryManagerTest, TestManageChangingLastUsedTime) {
307 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), true),
308 stub2(&memmgr_, GenerateUniqueSurfaceId(), true),
309 stub3(&memmgr_, GenerateUniqueSurfaceId(), true),
310 stub4(&memmgr_, GenerateUniqueSurfaceId(), true);
312 FakeClient stub5(&memmgr_ , &stub3), stub6(&memmgr_ , &stub4);
313 FakeClient stub7(&memmgr_ , &stub3);
315 // Make stub4 be the least-recently-used client
316 stub4.SetVisible(false);
317 stub3.SetVisible(false);
318 stub2.SetVisible(false);
319 stub1.SetVisible(false);
321 Manage();
322 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
323 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
324 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub3.allocation_));
325 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub4.allocation_));
326 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub5.allocation_));
327 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub6.allocation_));
328 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub7.allocation_));
330 // Make stub3 become the least-recently-used client.
331 stub2.SetVisible(true);
332 stub2.SetVisible(false);
333 stub4.SetVisible(true);
334 stub4.SetVisible(false);
336 Manage();
337 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
338 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
339 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub3.allocation_));
340 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub4.allocation_));
341 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub5.allocation_));
342 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub6.allocation_));
343 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub7.allocation_));
346 // Test GpuMemoryManager::Manage functionality: Test changing importance of
347 // enough stubs so that every stub in share group crosses threshold.
348 // Expect memory allocation of the stubs without surface to share memory
349 // allocation with the most visible stub in share group.
350 TEST_F(GpuMemoryManagerTest, TestManageChangingImportanceShareGroup) {
351 FakeClient stub_ignore_a(&memmgr_, GenerateUniqueSurfaceId(), true),
352 stub_ignore_b(&memmgr_, GenerateUniqueSurfaceId(), false),
353 stub_ignore_c(&memmgr_, GenerateUniqueSurfaceId(), false);
354 FakeClient stub1(&memmgr_, GenerateUniqueSurfaceId(), false),
355 stub2(&memmgr_, GenerateUniqueSurfaceId(), false);
357 FakeClient stub3(&memmgr_, &stub2), stub4(&memmgr_, &stub2);
359 // stub1 and stub2 keep their non-hibernated state because they're
360 // either visible or the 2 most recently used clients (through the
361 // first three checks).
362 stub1.SetVisible(true);
363 stub2.SetVisible(true);
364 Manage();
365 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub1.allocation_));
366 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
367 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub3.allocation_));
368 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
370 stub1.SetVisible(false);
371 Manage();
372 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
373 EXPECT_TRUE(IsAllocationForegroundForSurfaceYes(stub2.allocation_));
374 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
375 EXPECT_TRUE(IsAllocationForegroundForSurfaceNo(stub4.allocation_));
377 stub2.SetVisible(false);
378 Manage();
379 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub1.allocation_));
380 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
381 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
382 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
384 // stub_ignore_b will cause stub1 to become hibernated (because
385 // stub_ignore_a, stub_ignore_b, and stub2 are all non-hibernated and more
386 // important).
387 stub_ignore_b.SetVisible(true);
388 stub_ignore_b.SetVisible(false);
389 Manage();
390 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
391 EXPECT_TRUE(IsAllocationBackgroundForSurfaceYes(stub2.allocation_));
392 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub3.allocation_));
393 EXPECT_TRUE(IsAllocationBackgroundForSurfaceNo(stub4.allocation_));
395 // stub_ignore_c will cause stub2 to become hibernated (because
396 // stub_ignore_a, stub_ignore_b, and stub_ignore_c are all non-hibernated
397 // and more important).
398 stub_ignore_c.SetVisible(true);
399 stub_ignore_c.SetVisible(false);
400 Manage();
401 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub1.allocation_));
402 EXPECT_TRUE(IsAllocationHibernatedForSurfaceYes(stub2.allocation_));
403 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub3.allocation_));
404 EXPECT_TRUE(IsAllocationHibernatedForSurfaceNo(stub4.allocation_));
407 } // namespace content