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 "android_webview/browser/global_tile_manager.h" 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "android_webview/browser/global_tile_manager_client.h" 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/lazy_instance.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::SynchronousCompositorMemoryPolicy; 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace android_webview { 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace { 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::LazyInstance<GlobalTileManager>::Leaky g_tile_manager = 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// The soft limit of the number of file descriptors per process is 1024 on 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Android and gralloc buffers may not be the only thing that uses file 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// descriptors. For each tile, there is a gralloc buffer backing it, which 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// uses 2 FDs. 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const size_t kNumTilesLimit = 450; 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GlobalTileManager* GlobalTileManager::GetInstance() { 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return g_tile_manager.Pointer(); 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GlobalTileManager::Remove(Key key) { 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(mru_list_.end() != key); 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_allocated_tiles_ -= (*key)->GetMemoryPolicy().num_resources_limit; 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mru_list_.erase(key); 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(IsConsistent()); 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)size_t GlobalTileManager::Evict(size_t desired_num_tiles, Key key) { 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t total_evicted_tiles = 0; 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Evicts from the least recent drawn view, until the disired number of tiles 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // can be reclaimed, or until we've evicted all inactive views. 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ListType::reverse_iterator it; 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (it = mru_list_.rbegin(); it != mru_list_.rend(); it++) { 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // key represents the view that requested the eviction, so we don't need to 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // evict the requester itself. And we only evict the inactive views, 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // which are all the views after the requester. 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (*it == *key) 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t evicted_tiles = (*it)->GetMemoryPolicy().num_resources_limit; 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SynchronousCompositorMemoryPolicy zero_policy; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (*it)->SetMemoryPolicy(zero_policy, true); 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) total_evicted_tiles += evicted_tiles; 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (total_evicted_tiles >= desired_num_tiles) 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) break; 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return total_evicted_tiles; 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GlobalTileManager::SetTileLimit(size_t num_tiles_limit) { 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) num_tiles_limit_ = num_tiles_limit; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GlobalTileManager::RequestTiles( 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SynchronousCompositorMemoryPolicy new_policy, 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Key key) { 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(IsConsistent()); 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t new_num_of_tiles = new_policy.num_resources_limit; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci size_t old_num_of_tiles = (*key)->GetMemoryPolicy().num_resources_limit; 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t num_of_active_views = std::distance(mru_list_.begin(), key) + 1; 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t tiles_per_view_limit; 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (num_of_active_views == 0) 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tiles_per_view_limit = num_tiles_limit_; 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tiles_per_view_limit = num_tiles_limit_ / num_of_active_views; 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_num_of_tiles = std::min(new_num_of_tiles, tiles_per_view_limit); 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t new_total_allocated_tiles = 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) total_allocated_tiles_ - old_num_of_tiles + new_num_of_tiles; 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Has enough tiles to satisfy the request. 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (new_total_allocated_tiles <= num_tiles_limit_) { 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) total_allocated_tiles_ = new_total_allocated_tiles; 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_policy.num_resources_limit = new_num_of_tiles; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (*key)->SetMemoryPolicy(new_policy, false); 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Does not have enough tiles. Now evict other clients' tiles. 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t tiles_left = num_tiles_limit_ - total_allocated_tiles_; 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t evicted_tiles = 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Evict(new_total_allocated_tiles - num_tiles_limit_, key); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (evicted_tiles >= new_total_allocated_tiles - num_tiles_limit_) { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_total_allocated_tiles -= evicted_tiles; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) total_allocated_tiles_ = new_total_allocated_tiles; 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_policy.num_resources_limit = new_num_of_tiles; 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (*key)->SetMemoryPolicy(new_policy, false); 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) total_allocated_tiles_ = num_tiles_limit_; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_policy.num_resources_limit = 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tiles_left + old_num_of_tiles + evicted_tiles; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (*key)->SetMemoryPolicy(new_policy, false); 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GlobalTileManager::Key GlobalTileManager::PushBack( 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GlobalTileManagerClient* client) { 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(mru_list_.end() == 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::find(mru_list_.begin(), mru_list_.end(), client)); 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mru_list_.push_back(client); 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Key back = mru_list_.end(); 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) back--; 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return back; 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GlobalTileManager::DidUse(Key key) { 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(mru_list_.end() != key); 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mru_list_.splice(mru_list_.begin(), mru_list_, key); 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GlobalTileManager::GlobalTileManager() 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : num_tiles_limit_(kNumTilesLimit), total_allocated_tiles_(0) { 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GlobalTileManager::~GlobalTileManager() { 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool GlobalTileManager::IsConsistent() const { 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t total_tiles = 0; 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ListType::const_iterator it; 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (it = mru_list_.begin(); it != mru_list_.end(); it++) { 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci total_tiles += (*it)->GetMemoryPolicy().num_resources_limit; 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool is_consistent = (total_tiles <= num_tiles_limit_ && 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) total_tiles == total_allocated_tiles_); 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return is_consistent; 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace webview 153