1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <algorithm>
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "android_webview/browser/global_tile_manager.h"
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "android_webview/browser/global_tile_manager_client.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace {
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This should be the same as the one defined global_tile_manager.cc
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const size_t kNumTilesLimit = 450;
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const size_t kDefaultNumTiles = 150;
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using android_webview::GlobalTileManager;
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using android_webview::GlobalTileManagerClient;
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::SynchronousCompositorMemoryPolicy;
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using testing::Test;
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class MockGlobalTileManagerClient : public GlobalTileManagerClient {
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual SynchronousCompositorMemoryPolicy GetMemoryPolicy() const OVERRIDE {
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return memory_policy_;
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SetMemoryPolicy(SynchronousCompositorMemoryPolicy new_policy,
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               bool effective_immediately) OVERRIDE {
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    memory_policy_ = new_policy;
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockGlobalTileManagerClient() {
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    tile_request_.num_resources_limit = kDefaultNumTiles;
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    key_ = GlobalTileManager::GetInstance()->PushBack(this);
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ~MockGlobalTileManagerClient() {
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    GlobalTileManager::GetInstance()->Remove(key_);
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SynchronousCompositorMemoryPolicy GetTileRequest() { return tile_request_; }
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GlobalTileManager::Key GetKey() { return key_; }
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SynchronousCompositorMemoryPolicy memory_policy_;
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SynchronousCompositorMemoryPolicy tile_request_;
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GlobalTileManager::Key key_;
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class GlobalTileManagerTest : public Test {
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void SetUp() {}
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GlobalTileManager* manager() { return GlobalTileManager::GetInstance(); }
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(GlobalTileManagerTest, RequestTilesUnderLimit) {
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockGlobalTileManagerClient clients[2];
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 2; i++) {
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->DidUse(clients[i].GetKey());
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Ensure clients get what they asked for when the manager is under tile
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // limit.
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(clients[i].GetMemoryPolicy().num_resources_limit,
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              kDefaultNumTiles);
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(GlobalTileManagerTest, EvictHappensWhenOverLimit) {
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockGlobalTileManagerClient clients[4];
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 4; i++) {
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->DidUse(clients[i].GetKey());
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  size_t total_tiles = 0;
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 4; i++) {
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    total_tiles += clients[i].GetMemoryPolicy().num_resources_limit;
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure that eviction happened and kept the total number of tiles within
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // kNumTilesLimit.
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_LE(total_tiles, kNumTilesLimit);
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(GlobalTileManagerTest, RandomizedStressRequests) {
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockGlobalTileManagerClient clients[100];
92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  size_t index[100];
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 100; i++) {
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    index[i] = i;
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Fix the seed so that tests are reproducible.
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::srand(1);
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Simulate a random request order of clients.
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::random_shuffle(&index[0], &index[99]);
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 100; i++) {
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    size_t j = index[i];
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->RequestTiles(clients[j].GetTileRequest(), clients[j].GetKey());
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->DidUse(clients[j].GetKey());
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  size_t total_tiles = 0;
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 100; i++) {
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    total_tiles += clients[i].GetMemoryPolicy().num_resources_limit;
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure that eviction happened and kept the total number of tiles within
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // kNumTilesLimit.
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_LE(total_tiles, kNumTilesLimit);
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(GlobalTileManagerTest, FixedOrderedRequests) {
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockGlobalTileManagerClient clients[10];
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // 10 clients requesting resources in a fixed order. Do that for 5 rounds.
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (int round = 0; round < 5; round++) {
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    for (size_t i = 0; i < 10; i++) {
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      manager()->DidUse(clients[i].GetKey());
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure that the total tiles are divided evenly among all clients.
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 10; i++) {
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(clients[i].GetMemoryPolicy().num_resources_limit,
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              kNumTilesLimit / 10);
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(GlobalTileManagerTest, FixedOrderedRequestsWithInactiveClients) {
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MockGlobalTileManagerClient clients[20];
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // 20 clients request resources.
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 20; i++) {
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    manager()->DidUse(clients[i].GetKey());
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Now the last 10 clients become inactive. Only the first 10 clients remain
146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // active resource requesters.
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // 10 clients requesting resources in a fixed order. Do that for 5 rounds.
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (int round = 0; round < 5; round++) {
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    for (size_t i = 0; i < 10; i++) {
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      manager()->RequestTiles(clients[i].GetTileRequest(), clients[i].GetKey());
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      manager()->DidUse(clients[i].GetKey());
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure that the total tiles are divided evenly among all clients.
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < 10; i++) {
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(clients[i].GetMemoryPolicy().num_resources_limit,
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              kNumTilesLimit / 10);
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Ensure that the inactive tiles are evicted.
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 11; i < 20; i++) {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(clients[i].GetMemoryPolicy().num_resources_limit, 0u);
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
166