[go: nahoru, domu]

Reland "Add IsMobileOptimized calculation in blink"

This is a reland of d49bc9b76c55fe41849c0e7ac0437957b1ddda01

I believe the TapDelayEnabled test fails because it doesn't wait
for the renderer to get all information related to the mobile
viewport before checking the TapDelayEnabled counter. This approach is
similar to what was done in MobileOptimizedStatus test in the same
file.

Original change's description:
> Add IsMobileOptimized calculation in blink
>
> Right now IsMobileOptimized is computed in the compositor [1] and is not
> available on the main thread.
> This CL adds plumbing to have IsMobileOptimized be available as a method
> on LayerTreeHost which is accessible on the main thread.
>
> The approach is to mirror the computation of IsMobileOptimized
> done in LayerTreeHostImpl in LayerTreeHost.
>
> Once LayerTreeHost::IsMobileOptimized exists, we add a use counter to
> track how often the new kRemoveMobileViewportDoubleTap feature is used.
>
> [1] https://source.chromium.org/chromium/chromium/src/+/main:cc/trees/layer_tree_host_impl.cc;drc=2d2bd807c3ed39f0ab8e05bf8526c3861940c8c1;l=176
>
>      DoubleTapToZoomBrowserTest.MainThreadMobileOptimizedStatus
>
> Bug: 1203803
> Change-Id: I67be5f355781f803485f51f11c06f39ecdb053c6
> TEST: DoubleTapToZoomBrowserTest.UseCountRemoveMobileViewportDoubleTap
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3028413
> Commit-Queue: Liviu Tinta <liviutinta@chromium.org>
> Reviewed-by: Robert Flack <flackr@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#903329}

Bug: 1203803
Change-Id: Ibcc3ff13c4d385536ca8570462a637f260219d71
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3039763
Reviewed-by: Robert Flack <flackr@chromium.org>
Commit-Queue: Liviu Tinta <liviutinta@chromium.org>
Cr-Commit-Position: refs/heads/master@{#905432}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 9ecaa2a..3234a484 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -373,6 +373,8 @@
     "trees/layer_tree_settings.h",
     "trees/managed_memory_policy.cc",
     "trees/managed_memory_policy.h",
+    "trees/mobile_optimized_viewport_util.cc",
+    "trees/mobile_optimized_viewport_util.h",
     "trees/mutator_host.h",
     "trees/mutator_host_client.h",
     "trees/occlusion.cc",
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index 3c34b8f..fba2325 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -56,6 +56,7 @@
 #include "cc/trees/layer_tree_host_client.h"
 #include "cc/trees/layer_tree_host_impl.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "cc/trees/mobile_optimized_viewport_util.h"
 #include "cc/trees/mutator_host.h"
 #include "cc/trees/paint_holding_reason.h"
 #include "cc/trees/property_tree_builder.h"
@@ -159,6 +160,35 @@
       debug_state_.RecordRenderingStats());
 }
 
+bool LayerTreeHost::IsMobileOptimized() const {
+  gfx::SizeF scrollable_viewport_size;
+  auto* inner_node =
+      property_trees()->scroll_tree.Node(viewport_property_ids_.inner_scroll);
+  if (!inner_node)
+    scrollable_viewport_size = gfx::SizeF();
+  else
+    scrollable_viewport_size = gfx::ScaleSize(
+        gfx::SizeF(inner_node->container_bounds),
+        1.0f / (external_page_scale_factor_ * page_scale_factor()));
+
+  gfx::SizeF scrollable_size;
+  auto* scroll_node =
+      property_trees()->scroll_tree.Node(viewport_property_ids_.outer_scroll);
+  if (!scroll_node) {
+    DCHECK(!inner_node);
+    scrollable_size = gfx::SizeF();
+  } else {
+    const auto& scroll_tree = property_trees()->scroll_tree;
+    auto size = scroll_tree.scroll_bounds(scroll_node->id);
+    size.SetToMax(gfx::SizeF(scroll_tree.container_bounds(scroll_node->id)));
+    scrollable_size = size;
+  }
+
+  return util::IsMobileOptimized(
+      min_page_scale_factor(), max_page_scale_factor(), page_scale_factor(),
+      scrollable_viewport_size, scrollable_size, is_viewport_mobile_optimized_);
+}
+
 void LayerTreeHost::InitializeThreaded(
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) {
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 2953d81..02b0cb3 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -441,6 +441,9 @@
 
   void UpdateViewportIsMobileOptimized(bool is_viewport_mobile_optimized);
 
+  // Returns if the viewport is considered to be mobile optimized.
+  bool IsMobileOptimized() const;
+
   void SetBrowserControlsParams(const BrowserControlsParams& params);
   void SetBrowserControlsShownRatio(float top_ratio, float bottom_ratio);
 
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index bc0b6ca..e1a99c0 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -93,6 +93,7 @@
 #include "cc/trees/latency_info_swap_promise_monitor.h"
 #include "cc/trees/layer_tree_frame_sink.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "cc/trees/mobile_optimized_viewport_util.h"
 #include "cc/trees/mutator_host.h"
 #include "cc/trees/presentation_time_callback_buffer.h"
 #include "cc/trees/render_frame_metadata.h"
@@ -142,11 +143,6 @@
 namespace cc {
 namespace {
 
-// Used to accommodate finite precision when comparing scaled viewport and
-// content widths. While this value may seem large, width=device-width on an N7
-// V1 saw errors of ~0.065 between computed window and content widths.
-const float kMobileViewportWidthEpsilon = 0.15f;
-
 // In BuildHitTestData we iterate all layers to find all layers that overlap
 // OOPIFs, but when the number of layers is greater than
 // |kAssumeOverlapThreshold|, it can be inefficient to accumulate layer bounds
@@ -161,25 +157,13 @@
                   gfx::DisplayColorSpaces::kConfigCount / 2,
               "sRGB cache must match the size of DisplayColorSpaces");
 
-bool HasFixedPageScale(LayerTreeImpl* active_tree) {
-  return active_tree->min_page_scale_factor() ==
-         active_tree->max_page_scale_factor();
-}
-
-bool HasMobileViewport(LayerTreeImpl* active_tree) {
-  float window_width_dip = active_tree->current_page_scale_factor() *
-                           active_tree->ScrollableViewportSize().width();
-  float content_width_css = active_tree->ScrollableSize().width();
-  return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
-}
-
 bool IsMobileOptimized(LayerTreeImpl* active_tree) {
-  bool has_mobile_viewport = HasMobileViewport(active_tree);
-  bool has_fixed_page_scale = HasFixedPageScale(active_tree);
-  return has_fixed_page_scale || has_mobile_viewport ||
-         (base::FeatureList::IsEnabled(
-              ::features::kRemoveMobileViewportDoubleTap) &&
-          active_tree->viewport_mobile_optimized());
+  return util::IsMobileOptimized(active_tree->min_page_scale_factor(),
+                                 active_tree->max_page_scale_factor(),
+                                 active_tree->current_page_scale_factor(),
+                                 active_tree->ScrollableViewportSize(),
+                                 active_tree->ScrollableSize(),
+                                 active_tree->viewport_mobile_optimized());
 }
 
 viz::ResourceFormat TileRasterBufferFormat(
diff --git a/cc/trees/mobile_optimized_viewport_util.cc b/cc/trees/mobile_optimized_viewport_util.cc
new file mode 100644
index 0000000..2f70f27a
--- /dev/null
+++ b/cc/trees/mobile_optimized_viewport_util.cc
@@ -0,0 +1,41 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/mobile_optimized_viewport_util.h"
+
+#include "base/feature_list.h"
+#include "cc/base/features.h"
+#include "ui/gfx/geometry/size_f.h"
+
+namespace cc {
+namespace util {
+namespace {
+// Used to accommodate finite precision when comparing scaled viewport and
+// content widths. While this value may seem large, width=device-width on an N7
+// V1 saw errors of ~0.065 between computed window and content widths.
+const float kMobileViewportWidthEpsilon = 0.15f;
+}  // namespace
+
+bool IsMobileOptimized(float min_page_scale_factor,
+                       float max_page_scale_factor,
+                       float current_page_scale_factor,
+                       gfx::SizeF scrollable_viewport_size,
+                       gfx::SizeF scrollable_size,
+                       bool viewport_meta_mobile_optimized) {
+  bool has_fixed_page_scale = min_page_scale_factor == max_page_scale_factor;
+
+  float window_width_dip =
+      current_page_scale_factor * scrollable_viewport_size.width();
+  float content_width_css = scrollable_size.width();
+  bool has_mobile_viewport =
+      content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
+
+  return has_mobile_viewport || has_fixed_page_scale ||
+         (base::FeatureList::IsEnabled(
+              ::features::kRemoveMobileViewportDoubleTap) &&
+          viewport_meta_mobile_optimized);
+}
+
+}  // namespace util
+}  // namespace cc
diff --git a/cc/trees/mobile_optimized_viewport_util.h b/cc/trees/mobile_optimized_viewport_util.h
new file mode 100644
index 0000000..9bd5989
--- /dev/null
+++ b/cc/trees/mobile_optimized_viewport_util.h
@@ -0,0 +1,34 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_MOBILE_OPTIMIZED_VIEWPORT_UTIL_H_
+#define CC_TREES_MOBILE_OPTIMIZED_VIEWPORT_UTIL_H_
+
+#include "ui/gfx/geometry/size_f.h"
+
+namespace cc {
+namespace util {
+
+// Returns whether the viewport should be considered mobile optimized,
+// not needing the double tap to zoom gesture.
+// Arguments:
+// min_page_scale_factor - the minimum page scale
+// max_page_scale_factor - the maximum page scale
+// current_page_scale_factor - current page scale
+// scrollable_viewport_size - the size of the user-visible scrolling viewport
+// in CSS layout coordinates
+// scrollable_size - the size of the root scrollable area in CSS layout
+// coordinates
+// viewport_meta_mobile_optimized - if the viewport meta tag is mobile
+// optimized
+bool IsMobileOptimized(float min_page_scale_factor,
+                       float max_page_scale_factor,
+                       float current_page_scale_factor,
+                       gfx::SizeF scrollable_viewport_size,
+                       gfx::SizeF scrollable_size,
+                       bool viewport_meta_mobile_optimized);
+}  // namespace util
+}  // namespace cc
+
+#endif  // CC_TREES_MOBILE_OPTIMIZED_VIEWPORT_UTIL_H_