Commit 99ec37a9 authored by Fady Samuel's avatar Fady Samuel Committed by Commit Bot

Surface synchronization: Use longer deadlines when appropriate

When surface synchronization is off, we lock the UI compositor on
Android during the first frame and resize in order to avoid producing
a CompositorFrame until the renderer has an appropriate frame ready.

Prior to this CL, with surface sync on, we used the default deadline
for synchronization. With this CL, we use the same deadlines that were
used prior to surface sync on versions of Android O or newer.

On versions older than O, we set the deadline for resize to 0.

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: Idb8f2b3891a9ae1bd43be4d81dbec3ccdb5ff436
Bug: 672962, 857542
Reviewed-on: https://chromium-review.googlesource.com/1132324
Commit-Queue: Fady Samuel <fsamuel@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575436}
parent d5b59b2d
......@@ -1372,8 +1372,15 @@ void RenderWidgetHostViewAndroid::ShowInternal() {
if (delegated_frame_host_ &&
delegated_frame_host_->IsPrimarySurfaceEvicted()) {
SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
base::nullopt);
ui::WindowAndroidCompositor* compositor =
view_.GetWindowAndroid() ? view_.GetWindowAndroid()->GetCompositor()
: nullptr;
SynchronizeVisualProperties(
compositor && compositor->IsDrawingFirstVisibleFrame()
? cc::DeadlinePolicy::UseSpecifiedDeadline(
ui::DelegatedFrameHostAndroid::FirstFrameTimeoutFrames())
: cc::DeadlinePolicy::UseDefaultDeadline(),
base::nullopt);
}
host()->WasShown(false /* record_presentation_time */);
......@@ -1976,8 +1983,10 @@ void RenderWidgetHostViewAndroid::UpdateNativeViewTree(
StartObservingRootWindow();
if (resize) {
SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
base::nullopt);
SynchronizeVisualProperties(
cc::DeadlinePolicy::UseSpecifiedDeadline(
ui::DelegatedFrameHostAndroid::ResizeTimeoutFrames()),
base::nullopt);
}
if (!touch_selection_controller_) {
......@@ -2069,8 +2078,10 @@ void RenderWidgetHostViewAndroid::OnSizeChanged() {
void RenderWidgetHostViewAndroid::OnPhysicalBackingSizeChanged() {
EvictFrameIfNecessary();
SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
base::nullopt);
SynchronizeVisualProperties(
cc::DeadlinePolicy::UseSpecifiedDeadline(
ui::DelegatedFrameHostAndroid::ResizeTimeoutFrames()),
base::nullopt);
}
void RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged(bool visible) {
......
......@@ -26,16 +26,6 @@ namespace ui {
namespace {
// Wait up to 5 seconds for the first frame to be produced. Having Android
// display a placeholder for a longer period of time is preferable to drawing
// nothing, and the first frame can take a while on low-end systems.
static const int64_t kFirstFrameTimeoutSeconds = 5;
// Wait up to 1 second for a frame of the correct size to be produced. Android
// OS will only wait 4 seconds, so we limit this to 1 second to make sure we
// have always produced a frame before the OS stops waiting.
static const int64_t kResizeTimeoutSeconds = 1;
scoped_refptr<cc::SurfaceLayer> CreateSurfaceLayer(
const viz::SurfaceId& primary_surface_id,
const viz::SurfaceId& fallback_surface_id,
......@@ -225,8 +215,8 @@ void DelegatedFrameHostAndroid::AttachToCompositor(
// a renderer frame is available instead.
if (!enable_surface_synchronization_ &&
compositor->IsDrawingFirstVisibleFrame() && !HasDelegatedContent()) {
compositor_attach_until_frame_lock_ = compositor->GetCompositorLock(
this, base::TimeDelta::FromSeconds(kFirstFrameTimeoutSeconds));
compositor_attach_until_frame_lock_ =
compositor->GetCompositorLock(this, FirstFrameTimeout());
}
compositor->AddChildFrameSink(frame_sink_id_);
if (!enable_viz_)
......@@ -267,12 +257,9 @@ void DelegatedFrameHostAndroid::WasShown(
if (!enable_surface_synchronization_)
return;
// Use the default deadline to synchronize web content with browser UI.
// TODO(fsamuel): We probably want to use the deadlines
// kFirstFrameTimeoutSeconds and kResizeTimeoutSeconds for equivalent
// cases with surface synchronization too.
EmbedSurface(new_pending_local_surface_id, new_pending_size_in_pixels,
cc::DeadlinePolicy::UseDefaultDeadline());
EmbedSurface(
new_pending_local_surface_id, new_pending_size_in_pixels,
cc::DeadlinePolicy::UseSpecifiedDeadline(FirstFrameTimeoutFrames()));
}
void DelegatedFrameHostAndroid::EmbedSurface(
......@@ -284,6 +271,8 @@ void DelegatedFrameHostAndroid::EmbedSurface(
pending_local_surface_id_ = new_pending_local_surface_id;
pending_surface_size_in_pixels_ = new_pending_size_in_pixels;
viz::SurfaceId current_primary_surface_id =
content_layer_->primary_surface_id();
if (!frame_evictor_->visible()) {
// If the tab is resized while hidden, reset the fallback so that the next
......@@ -299,10 +288,28 @@ void DelegatedFrameHostAndroid::EmbedSurface(
// is visible, EmbedSurface will be called again. See WasShown.
return;
}
viz::SurfaceId primary_surface_id(frame_sink_id_, pending_local_surface_id_);
content_layer_->SetPrimarySurfaceId(primary_surface_id, deadline_policy);
content_layer_->SetBounds(new_pending_size_in_pixels);
if (!current_primary_surface_id.is_valid() ||
current_primary_surface_id.local_surface_id() !=
pending_local_surface_id_) {
if (base::android::BuildInfo::GetInstance()->sdk_int() <
base::android::SDK_VERSION_OREO) {
// On version of Android earlier than Oreo, we would like to produce new
// content as soon as possible or the OS will create an additional black
// gutter. We only reset the deadline on the first frame (no bounds yet
// specified) or on resize, and only if the deadline policy is not
// infinite.
if (deadline_policy.policy_type() !=
cc::DeadlinePolicy::kUseInfiniteDeadline &&
(content_layer_->bounds().IsEmpty() ||
content_layer_->bounds() != pending_surface_size_in_pixels_)) {
deadline_policy = cc::DeadlinePolicy::UseSpecifiedDeadline(0u);
}
}
viz::SurfaceId primary_surface_id(frame_sink_id_,
pending_local_surface_id_);
content_layer_->SetPrimarySurfaceId(primary_surface_id, deadline_policy);
content_layer_->SetBounds(new_pending_size_in_pixels);
}
}
void DelegatedFrameHostAndroid::PixelSizeWillChange(
......@@ -322,8 +329,8 @@ void DelegatedFrameHostAndroid::PixelSizeWillChange(
if (registered_parent_compositor_) {
if (HasSavedFrame() && content_layer_->bounds() != expected_pixel_size_) {
compositor_pending_resize_lock_ =
registered_parent_compositor_->GetCompositorLock(
this, base::TimeDelta::FromSeconds(kResizeTimeoutSeconds));
registered_parent_compositor_->GetCompositorLock(this,
ResizeTimeout());
}
}
}
......
......@@ -62,6 +62,26 @@ class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
~DelegatedFrameHostAndroid() override;
// Wait up to 5 seconds for the first frame to be produced. Having Android
// display a placeholder for a longer period of time is preferable to drawing
// nothing, and the first frame can take a while on low-end systems.
static constexpr base::TimeDelta FirstFrameTimeout() {
return base::TimeDelta::FromSeconds(5);
}
static constexpr int64_t FirstFrameTimeoutFrames() {
return FirstFrameTimeout() / viz::BeginFrameArgs::DefaultInterval();
}
// Wait up to 1 second for a frame of the correct size to be produced. Android
// OS will only wait 4 seconds, so we limit this to 1 second to make sure we
// have always produced a frame before the OS stops waiting.
static constexpr base::TimeDelta ResizeTimeout() {
return base::TimeDelta::FromSeconds(1);
}
static constexpr int64_t ResizeTimeoutFrames() {
return ResizeTimeout() / viz::BeginFrameArgs::DefaultInterval();
}
void SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
viz::CompositorFrame frame,
......
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