Cherry-pick: aw: Fallback to idle upload when zero copy disabled

Clean cherry-pick of chromium crrev.com/r286935

BUG: 16550863

Change-Id: Ifaee48ed7a5fa80c001781106a02e31aae0d324f
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index 8f5b3bc..f08a564 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -73,7 +73,17 @@
 }  // namespace
 
 // static
-void BrowserViewRenderer::CalculateTileMemoryPolicy() {
+void BrowserViewRenderer::CalculateTileMemoryPolicy(bool use_zero_copy) {
+  if (!use_zero_copy) {
+    // Use chrome's default tile size, which varies from 256 to 512.
+    // Be conservative here and use the smallest tile size possible.
+    g_tile_area = 256 * 256;
+
+    // Also use a high tile limit since there are no file descriptor issues.
+    GlobalTileManager::GetInstance()->SetTileLimit(1000);
+    return;
+  }
+
   CommandLine* cl = CommandLine::ForCurrentProcess();
   const char kDefaultTileSize[] = "384";
 
diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h
index 810fb81..76a8806 100644
--- a/android_webview/browser/browser_view_renderer.h
+++ b/android_webview/browser/browser_view_renderer.h
@@ -60,7 +60,7 @@
 class BrowserViewRenderer : public content::SynchronousCompositorClient,
                             public GlobalTileManagerClient {
  public:
-  static void CalculateTileMemoryPolicy();
+  static void CalculateTileMemoryPolicy(bool use_zero_copy);
 
   BrowserViewRenderer(
       BrowserViewRendererClient* client,
diff --git a/android_webview/browser/global_tile_manager.cc b/android_webview/browser/global_tile_manager.cc
index efc3039..a2fe4b6 100644
--- a/android_webview/browser/global_tile_manager.cc
+++ b/android_webview/browser/global_tile_manager.cc
@@ -9,8 +9,10 @@
 namespace android_webview {
 
 namespace {
+
 base::LazyInstance<GlobalTileManager>::Leaky g_tile_manager =
     LAZY_INSTANCE_INITIALIZER;
+
 // The soft limit of the number of file descriptors per process is 1024 on
 // Android and gralloc buffers may not be the only thing that uses file
 // descriptors. For each tile, there is a gralloc buffer backing it, which
@@ -58,6 +60,10 @@
   return total_evicted_tiles;
 }
 
+void GlobalTileManager::SetTileLimit(size_t num_tiles_limit) {
+  num_tiles_limit_ = num_tiles_limit;
+}
+
 void GlobalTileManager::RequestTiles(size_t new_num_of_tiles, Key key) {
   DCHECK(IsConsistent());
   DCHECK(sequence_checker_.CalledOnValidSequencedThread());
@@ -65,30 +71,31 @@
   size_t num_of_active_views = std::distance(mru_list_.begin(), key) + 1;
   size_t tiles_per_view_limit;
   if (num_of_active_views == 0)
-    tiles_per_view_limit = kNumTilesLimit;
+    tiles_per_view_limit = num_tiles_limit_;
   else
-    tiles_per_view_limit = kNumTilesLimit / num_of_active_views;
+    tiles_per_view_limit = num_tiles_limit_ / num_of_active_views;
   new_num_of_tiles = std::min(new_num_of_tiles, tiles_per_view_limit);
   size_t new_total_allocated_tiles =
       total_allocated_tiles_ - old_num_of_tiles + new_num_of_tiles;
   // Has enough tiles to satisfy the request.
-  if (new_total_allocated_tiles <= kNumTilesLimit) {
+  if (new_total_allocated_tiles <= num_tiles_limit_) {
     total_allocated_tiles_ = new_total_allocated_tiles;
     (*key)->SetNumTiles(new_num_of_tiles, false);
     return;
   }
 
   // Does not have enough tiles. Now evict other clients' tiles.
-  size_t tiles_left = kNumTilesLimit - total_allocated_tiles_;
+  size_t tiles_left = num_tiles_limit_ - total_allocated_tiles_;
 
-  size_t evicted_tiles = Evict(new_total_allocated_tiles - kNumTilesLimit, key);
-  if (evicted_tiles >= new_total_allocated_tiles - kNumTilesLimit) {
+  size_t evicted_tiles =
+      Evict(new_total_allocated_tiles - num_tiles_limit_, key);
+  if (evicted_tiles >= new_total_allocated_tiles - num_tiles_limit_) {
     new_total_allocated_tiles -= evicted_tiles;
     total_allocated_tiles_ = new_total_allocated_tiles;
     (*key)->SetNumTiles(new_num_of_tiles, false);
     return;
   } else {
-    total_allocated_tiles_ = kNumTilesLimit;
+    total_allocated_tiles_ = num_tiles_limit_;
     (*key)->SetNumTiles(tiles_left + old_num_of_tiles + evicted_tiles, false);
     return;
   }
@@ -112,8 +119,8 @@
   mru_list_.splice(mru_list_.begin(), mru_list_, key);
 }
 
-GlobalTileManager::GlobalTileManager() {
-  total_allocated_tiles_ = 0;
+GlobalTileManager::GlobalTileManager()
+    : num_tiles_limit_(kNumTilesLimit), total_allocated_tiles_(0) {
 }
 
 GlobalTileManager::~GlobalTileManager() {
@@ -126,8 +133,8 @@
     total_tiles += (*it)->GetNumTiles();
   }
 
-  bool is_consistent =
-      (total_tiles <= kNumTilesLimit && total_tiles == total_allocated_tiles_);
+  bool is_consistent = (total_tiles <= num_tiles_limit_ &&
+                        total_tiles == total_allocated_tiles_);
 
   return is_consistent;
 }
diff --git a/android_webview/browser/global_tile_manager.h b/android_webview/browser/global_tile_manager.h
index ca42230..3473c20 100644
--- a/android_webview/browser/global_tile_manager.h
+++ b/android_webview/browser/global_tile_manager.h
@@ -29,6 +29,8 @@
   typedef ListType::iterator Key;
   static GlobalTileManager* GetInstance();
 
+  void SetTileLimit(size_t num_tiles_limit);
+
   // Requests the |num_of_tiles| from the available global pool. Calls
   // GlobalTileManagerClient.SetNumTiles after the manager determines how many
   // tiles are available for the client. If the number of tiles left is not
@@ -61,6 +63,8 @@
   // total_allocated_tiles_.
   bool IsConsistent() const;
 
+  size_t num_tiles_limit_;
+
   size_t total_allocated_tiles_;
   ListType mru_list_;
   base::SequenceChecker sequence_checker_;
diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc
index c6b089b..303d808 100644
--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -49,13 +49,17 @@
   content::SetContentClient(&content_client_);
 
   CommandLine* cl = CommandLine::ForCurrentProcess();
-  if (gpu_memory_buffer_factory_.get()->Initialize()) {
+  bool zero_copy_disabled_by_switch = cl->HasSwitch(switches::kDisableZeroCopy);
+  bool use_zero_copy = !zero_copy_disabled_by_switch &&
+                       gpu_memory_buffer_factory_.get()->Initialize();
+
+  if (use_zero_copy) {
     cl->AppendSwitch(switches::kEnableZeroCopy);
-  } else {
-    LOG(WARNING) << "Failed to initialize GpuMemoryBuffer factory";
+  } else if (!zero_copy_disabled_by_switch) {
+    cl->AppendSwitch(switches::kDisableZeroCopy);
   }
 
-  BrowserViewRenderer::CalculateTileMemoryPolicy();
+  BrowserViewRenderer::CalculateTileMemoryPolicy(use_zero_copy);
 
   cl->AppendSwitch(switches::kEnableBeginFrameScheduling);
   cl->AppendSwitch(switches::kEnableImplSidePainting);