| Index: content/browser/renderer_host/render_widget_host_view_android.cc
|
| diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
|
| index 3d5e597188c7408a5d07df7f34927b96ab9a78e0..0d7d63bc89d6462d9749bf4b033010812c108deb 100644
|
| --- a/content/browser/renderer_host/render_widget_host_view_android.cc
|
| +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
|
| @@ -29,6 +29,7 @@
|
| #include "cc/output/copy_output_request.h"
|
| #include "cc/output/copy_output_result.h"
|
| #include "cc/output/latency_info_swap_promise.h"
|
| +#include "cc/quads/solid_color_draw_quad.h"
|
| #include "cc/resources/single_release_callback.h"
|
| #include "cc/surfaces/surface.h"
|
| #include "cc/surfaces/surface_hittest.h"
|
| @@ -553,6 +554,25 @@ RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
|
| }
|
|
|
| void RenderWidgetHostViewAndroid::WasResized() {
|
| + // If we're entering a fullscreen transition, show black until the transition
|
| + // is completed.
|
| + if (content_view_core_ && content_view_core_->GetPhysicalBackingSize() !=
|
| + prev_physical_backing_size_) {
|
| + bool is_fullscreen = content_view_core_->GetWebContents()->IsFullscreen();
|
| + if (is_fullscreen || was_fullscreen_) {
|
| + fullscreen_transitioning_ = true;
|
| +
|
| + // Immediately queue a black frame to hide jank while we wait to receive a
|
| + // "good" frame via SubmitCompositorFrame.
|
| + cc::CompositorFrame frame;
|
| + frame.render_pass_list.push_back(CreateBlackRenderPass());
|
| + frame.metadata.root_background_color = SK_ColorBLACK;
|
| + delegated_frame_host_->ForceFrame(std::move(frame));
|
| + UpdateBackgroundColor(SK_ColorBLACK);
|
| + }
|
| + was_fullscreen_ = is_fullscreen;
|
| + prev_physical_backing_size_ = content_view_core_->GetPhysicalBackingSize();
|
| + }
|
| host_->WasResized();
|
| }
|
|
|
| @@ -1151,9 +1171,79 @@ void RenderWidgetHostViewAndroid::DidCreateNewRendererCompositorFrameSink(
|
| surface_returned_resources_.clear();
|
| }
|
|
|
| +std::unique_ptr<cc::RenderPass>
|
| +RenderWidgetHostViewAndroid::CreateBlackRenderPass() {
|
| + gfx::Rect rect(current_surface_size_);
|
| + std::unique_ptr<cc::RenderPass> rp = cc::RenderPass::Create();
|
| + rp->SetNew(1, rect, gfx::Rect(), gfx::Transform());
|
| + rp->has_transparent_background = false;
|
| + cc::SharedQuadState* sqs = rp->CreateAndAppendSharedQuadState();
|
| + sqs->SetAll(gfx::Transform(), rect, rect, rect, false, 1.0,
|
| + SkBlendMode::kColor, 1);
|
| + cc::SolidColorDrawQuad* quad =
|
| + rp->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
|
| + quad->SetNew(sqs, rect, rect, SK_ColorBLACK, false);
|
| + return rp;
|
| +}
|
| +
|
| +bool RenderWidgetHostViewAndroid::CheckForFullscreenTransitionJank(
|
| + const cc::CompositorFrameMetadata& metadata) {
|
| + // Sometimes we'll receive a new frame before WasResized initializes a
|
| + // fullscreen transition. In that case, we'll block everything until
|
| + // WasResized is called.
|
| + if (content_view_core_ &&
|
| + content_view_core_->GetWebContents()->IsFullscreen() != was_fullscreen_) {
|
| + return true;
|
| + }
|
| +
|
| + // We only check for fullscreen jank during a fullscreen transition.
|
| + if (fullscreen_transitioning_) {
|
| + bool top_controls_transitioning = metadata.top_controls_shown_ratio > 0 &&
|
| + metadata.top_controls_shown_ratio < 1;
|
| + bool bottom_controls_transitioning =
|
| + metadata.bottom_controls_shown_ratio > 0 &&
|
| + metadata.bottom_controls_shown_ratio < 1;
|
| + bool mismatched_fullscreen_states =
|
| + content_view_core_ &&
|
| + (content_view_core_->GetWebContents()->IsFullscreen() !=
|
| + metadata.is_fullscreen);
|
| + bool mismatched_layer_sizes =
|
| + content_view_core_ && (content_view_core_->GetPhysicalBackingSize() !=
|
| + metadata.device_viewport_size);
|
| +
|
| + gfx::Size modified_scrollable_viewport_size =
|
| + gfx::ToFlooredSize(gfx::ScaleSize(metadata.scrollable_viewport_size,
|
| + metadata.page_scale_factor));
|
| + bool controls_will_transition =
|
| + content_view_core_ && (content_view_core_->GetViewSize().width() ==
|
| + modified_scrollable_viewport_size.width() &&
|
| + content_view_core_->GetViewSize().height() !=
|
| + modified_scrollable_viewport_size.height());
|
| +
|
| + if (top_controls_transitioning || bottom_controls_transitioning ||
|
| + mismatched_fullscreen_states || mismatched_layer_sizes ||
|
| + controls_will_transition) {
|
| + return true;
|
| + } else {
|
| + // Done with current fullscreen transition.
|
| + fullscreen_transitioning_ = false;
|
| + }
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
|
| const cc::LocalSurfaceId& local_surface_id,
|
| cc::CompositorFrame frame) {
|
| + if (CheckForFullscreenTransitionJank(frame.metadata)) {
|
| + // Block this frame since it will look janky.
|
| + frame.render_pass_list.clear();
|
| + frame.render_pass_list.push_back(CreateBlackRenderPass());
|
| + frame.metadata.root_background_color = SK_ColorBLACK;
|
| + UpdateBackgroundColor(SK_ColorBLACK);
|
| + }
|
| +
|
| last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
| DCHECK(delegated_frame_host_);
|
| DCHECK(!frame.render_pass_list.empty());
|
|
|