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,10 +161,12 @@ void BrowserViewRenderer::UpdateMemoryPolicy() {
if (g_memory_override_in_bytes) {
bytes_limit = static_cast<size_t>(g_memory_override_in_bytes);
} else {
gfx::Rect interest_rect =
offscreen_pre_raster_ || external_draw_constraints_.is_layer
? gfx::Rect(size_)
: last_on_draw_global_visible_rect_;
// Note we are using |last_on_draw_global_visible_rect_| rather than
// |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_)
: last_on_draw_global_visible_rect_;
size_t width = interest_rect.width();
size_t height = interest_rect.height();
bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
......@@ -226,35 +228,24 @@ bool BrowserViewRenderer::OnDrawHardware() {
gfx::Transform transform_for_tile_priority =
external_draw_constraints_.transform;
gfx::Rect viewport_rect_for_tile_priority =
ComputeViewportRectForTilePriority();
// Do not override (ie leave empty) for offscreen raster.
gfx::Size viewport_size_for_tile_priority =
offscreen_pre_raster_ ? gfx::Size()
: external_draw_constraints_.viewport_size;
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);
std::unique_ptr<ChildFrame> child_frame = std::make_unique<ChildFrame>(
std::move(future), compositor_id_,
viewport_rect_for_tile_priority.IsEmpty(), transform_for_tile_priority,
offscreen_pre_raster_, external_draw_constraints_.is_layer);
std::move(future), compositor_id_, viewport_size_for_tile_priority,
transform_for_tile_priority, offscreen_pre_raster_);
ReturnUnusedResource(
current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)));
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(
CompositorFrameConsumer* compositor_frame_consumer) {
DCHECK(compositor_frame_consumer);
......
......@@ -179,7 +179,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient,
void ReturnResourceFromParent(
CompositorFrameConsumer* compositor_frame_consumer);
void ReleaseHardware();
gfx::Rect ComputeViewportRectForTilePriority();
gfx::Vector2d max_scroll_offset() const;
......
......@@ -162,8 +162,10 @@ class TestAnimateInAndOutOfScreen : public RenderingTest {
TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {}
void StartTest() override {
new_constraints_ = ParentCompositorDrawConstraints(
false, gfx::Transform(), window_->surface_size().IsEmpty());
initial_constraints_ = ParentCompositorDrawConstraints(
window_->surface_size(), gfx::Transform());
new_constraints_ = ParentCompositorDrawConstraints(window_->surface_size(),
gfx::Transform());
new_constraints_.transform.Scale(2.0, 2.0);
browser_view_renderer_->PostInvalidate(ActiveCompositor());
}
......@@ -212,12 +214,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest {
bool DrawConstraintsEquals(
const ParentCompositorDrawConstraints& constraints1,
const ParentCompositorDrawConstraints& constraints2) {
if (constraints1.is_layer != constraints2.is_layer ||
constraints1.transform != constraints2.transform)
return false;
return !constraints1.is_layer ||
constraints1.surface_rect_empty == constraints2.surface_rect_empty;
return constraints1 == constraints2;
}
void OnParentDrawConstraintsUpdated() override {
......
......@@ -14,17 +14,14 @@ namespace android_webview {
ChildFrame::ChildFrame(
scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future,
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,
bool offscreen_pre_raster,
bool is_layer)
bool offscreen_pre_raster)
: frame_future(std::move(frame_future)),
compositor_id(compositor_id),
viewport_rect_for_tile_priority_empty(
viewport_rect_for_tile_priority_empty),
viewport_size_for_tile_priority(viewport_size_for_tile_priority),
transform_for_tile_priority(transform_for_tile_priority),
offscreen_pre_raster(offscreen_pre_raster),
is_layer(is_layer) {}
offscreen_pre_raster(offscreen_pre_raster) {}
ChildFrame::~ChildFrame() {
}
......
......@@ -11,6 +11,7 @@
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "content/public/browser/android/synchronous_compositor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h"
namespace viz {
......@@ -24,10 +25,9 @@ class ChildFrame {
ChildFrame(
scoped_refptr<content::SynchronousCompositor::FrameFuture> frame_future,
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,
bool offscreen_pre_raster,
bool is_layer);
bool offscreen_pre_raster);
~ChildFrame();
// Helper to move frame from |frame_future| to |frame|.
......@@ -40,10 +40,9 @@ class ChildFrame {
std::unique_ptr<viz::CompositorFrame> frame;
// The id of the compositor this |frame| comes from.
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 bool offscreen_pre_raster;
const bool is_layer;
private:
DISALLOW_COPY_AND_ASSIGN(ChildFrame);
......
......@@ -143,8 +143,7 @@ void HardwareRenderer::DrawGL(HardwareRendererDrawParams* params) {
// Need to post the new transform matrix back to child compositor
// because there is no onDraw during a Render Thread animation, and child
// compositor might not have the tiles rasterized as the animation goes on.
ParentCompositorDrawConstraints draw_constraints(params->is_layer, transform,
viewport.IsEmpty());
ParentCompositorDrawConstraints draw_constraints(viewport, transform);
if (!child_frame_.get() || draw_constraints.NeedUpdate(*child_frame_)) {
render_thread_manager_->PostExternalDrawConstraintsToChildCompositorOnRT(
draw_constraints);
......
......@@ -8,36 +8,22 @@
namespace android_webview {
ParentCompositorDrawConstraints::ParentCompositorDrawConstraints()
: is_layer(false), surface_rect_empty(true) {}
ParentCompositorDrawConstraints::ParentCompositorDrawConstraints() = default;
ParentCompositorDrawConstraints::ParentCompositorDrawConstraints(
bool is_layer,
const gfx::Transform& transform,
bool surface_rect_empty)
: is_layer(is_layer),
transform(transform),
surface_rect_empty(surface_rect_empty) {}
const gfx::Size& viewport_size,
const gfx::Transform& transform)
: viewport_size(viewport_size), transform(transform) {}
bool ParentCompositorDrawConstraints::NeedUpdate(
const ChildFrame& frame) const {
if (is_layer != frame.is_layer ||
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;
return viewport_size != frame.viewport_size_for_tile_priority ||
transform != frame.transform_for_tile_priority;
}
bool ParentCompositorDrawConstraints::operator==(
const ParentCompositorDrawConstraints& other) const {
return is_layer == other.is_layer && transform == other.transform &&
surface_rect_empty == other.surface_rect_empty;
return viewport_size == other.viewport_size && transform == other.transform;
}
} // namespace android_webview
......@@ -5,6 +5,7 @@
#ifndef 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"
namespace android_webview {
......@@ -12,14 +13,12 @@ namespace android_webview {
class ChildFrame;
struct ParentCompositorDrawConstraints {
bool is_layer;
gfx::Size viewport_size;
gfx::Transform transform;
bool surface_rect_empty;
ParentCompositorDrawConstraints();
ParentCompositorDrawConstraints(bool is_layer,
const gfx::Transform& transform,
bool surface_rect_empty);
ParentCompositorDrawConstraints(const gfx::Size& viewport_size,
const gfx::Transform& transform);
bool NeedUpdate(const ChildFrame& frame) 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