Commit 3331cac2 authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

aw: Stop relying on is_layer

We use View.getGlobalVisibleRect, and the transform and viewport from
functor to compute info for the viewport:
* the tile memory budget, which ideally is computed from the size of
  the visible portion of webview
* the viewport and transform used to raster the right tiles at the
  right scale

We usually use getGlobalVisibleRect and transform from functor
together if is_layer is false, making the assumption that they both
transform between the window space and view space. This turns out not
to be true.

Instead, use getGlobalVisibleRect to compute the tile budget. And
always use the viewport and transform from functor together for
tile raster, since they are guaranteed to work together.

Change-Id: I4d1346501dab14dbb7b7ca160e0c88fee64aa3ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1506759
Auto-Submit: Bo <boliu@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarTobias Sargeant <tobiasjs@chromium.org>
Commit-Queue: Bo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638647}
parent bd863dd3
...@@ -161,8 +161,10 @@ void BrowserViewRenderer::UpdateMemoryPolicy() { ...@@ -161,8 +161,10 @@ void BrowserViewRenderer::UpdateMemoryPolicy() {
if (g_memory_override_in_bytes) { if (g_memory_override_in_bytes) {
bytes_limit = static_cast<size_t>(g_memory_override_in_bytes); bytes_limit = static_cast<size_t>(g_memory_override_in_bytes);
} else { } else {
gfx::Rect interest_rect = // Note we are using |last_on_draw_global_visible_rect_| rather than
offscreen_pre_raster_ || external_draw_constraints_.is_layer // |external_draw_constraints_.viewport_size|. This is to reduce budget
// for a webview that's much smaller than the surface it's rendering.
gfx::Rect interest_rect = offscreen_pre_raster_
? gfx::Rect(size_) ? gfx::Rect(size_)
: last_on_draw_global_visible_rect_; : last_on_draw_global_visible_rect_;
size_t width = interest_rect.width(); size_t width = interest_rect.width();
...@@ -226,35 +228,24 @@ bool BrowserViewRenderer::OnDrawHardware() { ...@@ -226,35 +228,24 @@ bool BrowserViewRenderer::OnDrawHardware() {
gfx::Transform transform_for_tile_priority = gfx::Transform transform_for_tile_priority =
external_draw_constraints_.transform; external_draw_constraints_.transform;
gfx::Rect viewport_rect_for_tile_priority = // Do not override (ie leave empty) for offscreen raster.
ComputeViewportRectForTilePriority(); gfx::Size viewport_size_for_tile_priority =
offscreen_pre_raster_ ? gfx::Size()
: external_draw_constraints_.viewport_size;
scoped_refptr<content::SynchronousCompositor::FrameFuture> future = scoped_refptr<content::SynchronousCompositor::FrameFuture> future =
compositor_->DemandDrawHwAsync(size_, viewport_rect_for_tile_priority, compositor_->DemandDrawHwAsync(size_,
gfx::Rect(viewport_size_for_tile_priority),
transform_for_tile_priority); transform_for_tile_priority);
std::unique_ptr<ChildFrame> child_frame = std::make_unique<ChildFrame>( std::unique_ptr<ChildFrame> child_frame = std::make_unique<ChildFrame>(
std::move(future), compositor_id_, std::move(future), compositor_id_, viewport_size_for_tile_priority,
viewport_rect_for_tile_priority.IsEmpty(), transform_for_tile_priority, transform_for_tile_priority, offscreen_pre_raster_);
offscreen_pre_raster_, external_draw_constraints_.is_layer);
ReturnUnusedResource( ReturnUnusedResource(
current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame))); current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)));
return true; return true;
} }
gfx::Rect BrowserViewRenderer::ComputeViewportRectForTilePriority() {
// If the WebView is on a layer, WebView does not know what transform is
// applied onto the layer so global visible rect does not make sense here.
// In this case, just use the surface rect for tiling.
// Leave viewport_rect_for_tile_priority empty if offscreen_pre_raster_ is on.
gfx::Rect viewport_rect_for_tile_priority;
if (!offscreen_pre_raster_ && !external_draw_constraints_.is_layer) {
viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_;
}
return viewport_rect_for_tile_priority;
}
void BrowserViewRenderer::OnParentDrawConstraintsUpdated( void BrowserViewRenderer::OnParentDrawConstraintsUpdated(
CompositorFrameConsumer* compositor_frame_consumer) { CompositorFrameConsumer* compositor_frame_consumer) {
DCHECK(compositor_frame_consumer); DCHECK(compositor_frame_consumer);
......
...@@ -179,7 +179,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient, ...@@ -179,7 +179,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
void ReturnResourceFromParent( void ReturnResourceFromParent(
CompositorFrameConsumer* compositor_frame_consumer); CompositorFrameConsumer* compositor_frame_consumer);
void ReleaseHardware(); void ReleaseHardware();
gfx::Rect ComputeViewportRectForTilePriority();
gfx::Vector2d max_scroll_offset() const; gfx::Vector2d max_scroll_offset() const;
......
...@@ -162,8 +162,10 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { ...@@ -162,8 +162,10 @@ class TestAnimateInAndOutOfScreen : public RenderingTest {
TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {} TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {}
void StartTest() override { void StartTest() override {
new_constraints_ = ParentCompositorDrawConstraints( initial_constraints_ = ParentCompositorDrawConstraints(
false, gfx::Transform(), window_->surface_size().IsEmpty()); window_->surface_size(), gfx::Transform());
new_constraints_ = ParentCompositorDrawConstraints(window_->surface_size(),
gfx::Transform());
new_constraints_.transform.Scale(2.0, 2.0); new_constraints_.transform.Scale(2.0, 2.0);
browser_view_renderer_->PostInvalidate(ActiveCompositor()); browser_view_renderer_->PostInvalidate(ActiveCompositor());
} }
...@@ -212,12 +214,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { ...@@ -212,12 +214,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest {
bool DrawConstraintsEquals( bool DrawConstraintsEquals(
const ParentCompositorDrawConstraints& constraints1, const ParentCompositorDrawConstraints& constraints1,
const ParentCompositorDrawConstraints& constraints2) { const ParentCompositorDrawConstraints& constraints2) {
if (constraints1.is_layer != constraints2.is_layer || return constraints1 == constraints2;
constraints1.transform != constraints2.transform)
return false;
return !constraints1.is_layer ||
constraints1.surface_rect_empty == constraints2.surface_rect_empty;
} }
void OnParentDrawConstraintsUpdated() override { void OnParentDrawConstraintsUpdated() override {
......
...@@ -14,17 +14,14 @@ namespace android_webview { ...@@ -14,17 +14,14 @@ namespace android_webview {
ChildFrame::ChildFrame( ChildFrame::ChildFrame(
scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future, scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future,
const CompositorID& compositor_id, const CompositorID& compositor_id,
bool viewport_rect_for_tile_priority_empty, const gfx::Size& viewport_size_for_tile_priority,
const gfx::Transform& transform_for_tile_priority, const gfx::Transform& transform_for_tile_priority,
bool offscreen_pre_raster, bool offscreen_pre_raster)
bool is_layer)
: frame_future(std::move(frame_future)), : frame_future(std::move(frame_future)),
compositor_id(compositor_id), compositor_id(compositor_id),
viewport_rect_for_tile_priority_empty( viewport_size_for_tile_priority(viewport_size_for_tile_priority),
viewport_rect_for_tile_priority_empty),
transform_for_tile_priority(transform_for_tile_priority), transform_for_tile_priority(transform_for_tile_priority),
offscreen_pre_raster(offscreen_pre_raster), offscreen_pre_raster(offscreen_pre_raster) {}
is_layer(is_layer) {}
ChildFrame::~ChildFrame() { ChildFrame::~ChildFrame() {
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/containers/circular_deque.h" #include "base/containers/circular_deque.h"
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/android/synchronous_compositor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h" #include "ui/gfx/transform.h"
namespace viz { namespace viz {
...@@ -24,10 +25,9 @@ class ChildFrame { ...@@ -24,10 +25,9 @@ class ChildFrame {
ChildFrame( ChildFrame(
scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future, scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future,
const CompositorID& compositor_id, const CompositorID& compositor_id,
bool viewport_rect_for_tile_priority_empty, const gfx::Size& viewport_size_for_tile_priority,
const gfx::Transform& transform_for_tile_priority, const gfx::Transform& transform_for_tile_priority,
bool offscreen_pre_raster, bool offscreen_pre_raster);
bool is_layer);
~ChildFrame(); ~ChildFrame();
// Helper to move frame from |frame_future| to |frame|. // Helper to move frame from |frame_future| to |frame|.
...@@ -40,10 +40,9 @@ class ChildFrame { ...@@ -40,10 +40,9 @@ class ChildFrame {
std::unique_ptr<viz::CompositorFrame> frame; std::unique_ptr<viz::CompositorFrame> frame;
// The id of the compositor this |frame| comes from. // The id of the compositor this |frame| comes from.
const CompositorID compositor_id; const CompositorID compositor_id;
const bool viewport_rect_for_tile_priority_empty; const gfx::Size viewport_size_for_tile_priority;
const gfx::Transform transform_for_tile_priority; const gfx::Transform transform_for_tile_priority;
const bool offscreen_pre_raster; const bool offscreen_pre_raster;
const bool is_layer;
private: private:
DISALLOW_COPY_AND_ASSIGN(ChildFrame); DISALLOW_COPY_AND_ASSIGN(ChildFrame);
......
...@@ -143,8 +143,7 @@ void HardwareRenderer::DrawGL(HardwareRendererDrawParams* params) { ...@@ -143,8 +143,7 @@ void HardwareRenderer::DrawGL(HardwareRendererDrawParams* params) {
// Need to post the new transform matrix back to child compositor // Need to post the new transform matrix back to child compositor
// because there is no onDraw during a Render Thread animation, and child // because there is no onDraw during a Render Thread animation, and child
// compositor might not have the tiles rasterized as the animation goes on. // compositor might not have the tiles rasterized as the animation goes on.
ParentCompositorDrawConstraints draw_constraints(params->is_layer, transform, ParentCompositorDrawConstraints draw_constraints(viewport, transform);
viewport.IsEmpty());
if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) { if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) {
render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT( render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT(
draw_constraints); draw_constraints);
......
...@@ -8,36 +8,22 @@ ...@@ -8,36 +8,22 @@
namespace android_webview { namespace android_webview {
ParentCompositorDrawConstraints::ParentCompositorDrawConstraints() ParentCompositorDrawConstraints::ParentCompositorDrawConstraints() = default;
: is_layer(false), surface_rect_empty(true) {}
ParentCompositorDrawConstraints::ParentCompositorDrawConstraints( ParentCompositorDrawConstraints::ParentCompositorDrawConstraints(
bool is_layer, const gfx::Size& viewport_size,
const gfx::Transform& transform, const gfx::Transform& transform)
bool surface_rect_empty) : viewport_size(viewport_size), transform(transform) {}
: is_layer(is_layer),
transform(transform),
surface_rect_empty(surface_rect_empty) {}
bool ParentCompositorDrawConstraints::NeedUpdate( bool ParentCompositorDrawConstraints::NeedUpdate(
const ChildFrame& frame) const { const ChildFrame& frame) const {
if (is_layer != frame.is_layer || return viewport_size != frame.viewport_size_for_tile_priority ||
transform != frame.transform_for_tile_priority) { transform != frame.transform_for_tile_priority;
return true;
}
// Viewport for tile priority does not depend on surface rect in this case.
if (frame.offscreen_pre_raster || is_layer)
return false;
// Workaround for corner case. See crbug.com/417479.
return frame.viewport_rect_for_tile_priority_empty && !surface_rect_empty;
} }
bool ParentCompositorDrawConstraints::operator==( bool ParentCompositorDrawConstraints::operator==(
const ParentCompositorDrawConstraints& other) const { const ParentCompositorDrawConstraints& other) const {
return is_layer == other.is_layer && transform == other.transform && return viewport_size == other.viewport_size && transform == other.transform;
surface_rect_empty == other.surface_rect_empty;
} }
} // namespace android_webview } // namespace android_webview
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_ #ifndef ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
#define ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_ #define ANDROID_WEBVIEW_BROWSER_GFX_PARENT_COMPOSITOR_DRAW_CONSTRAINTS_H_
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h" #include "ui/gfx/transform.h"
namespace android_webview { namespace android_webview {
...@@ -12,14 +13,12 @@ namespace android_webview { ...@@ -12,14 +13,12 @@ namespace android_webview {
class ChildFrame; class ChildFrame;
struct ParentCompositorDrawConstraints { struct ParentCompositorDrawConstraints {
bool is_layer; gfx::Size viewport_size;
gfx::Transform transform; gfx::Transform transform;
bool surface_rect_empty;
ParentCompositorDrawConstraints(); ParentCompositorDrawConstraints();
ParentCompositorDrawConstraints(bool is_layer, ParentCompositorDrawConstraints(const gfx::Size& viewport_size,
const gfx::Transform& transform, const gfx::Transform& transform);
bool surface_rect_empty);
bool NeedUpdate(const ChildFrame& frame) const; bool NeedUpdate(const ChildFrame& frame) const;
bool operator==(const ParentCompositorDrawConstraints& other) const; bool operator==(const ParentCompositorDrawConstraints& other) const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment