// Copyright 2011 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/single_thread_proxy.h"

#include "base/auto_reset.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/devtools_instrumentation.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/input/browser_controls_offset_manager.h"
#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/scheduler/commit_earlyout_reason.h"
#include "cc/scheduler/compositor_timing_history.h"
#include "cc/scheduler/scheduler.h"
#include "cc/trees/latency_info_swap_promise.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_common.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/mutator_host.h"
#include "cc/trees/render_frame_metadata_observer.h"
#include "cc/trees/scoped_abort_remaining_swap_promises.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gpu/context_provider.h"

namespace cc {

std::unique_ptr<Proxy> SingleThreadProxy::Create(
    LayerTreeHost* layer_tree_host,
    LayerTreeHostSingleThreadClient* client,
    TaskRunnerProvider* task_runner_provider) {
  return base::WrapUnique(
      new SingleThreadProxy(layer_tree_host, client, task_runner_provider));
}

SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host,
                                     LayerTreeHostSingleThreadClient* client,
                                     TaskRunnerProvider* task_runner_provider)
    : layer_tree_host_(layer_tree_host),
      single_thread_client_(client),
      task_runner_provider_(task_runner_provider),
      next_frame_is_newly_committed_frame_(false),
#if DCHECK_IS_ON()
      inside_impl_frame_(false),
#endif
      inside_draw_(false),
      defer_main_frame_update_(false),
      animate_requested_(false),
      commit_requested_(false),
      inside_synchronous_composite_(false),
      needs_impl_frame_(false),
      layer_tree_frame_sink_creation_requested_(false),
      layer_tree_frame_sink_lost_(true),
      frame_sink_bound_weak_factory_(this),
      weak_factory_(this) {
  TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
  DCHECK(task_runner_provider_);
  DCHECK(task_runner_provider_->IsMainThread());
  DCHECK(layer_tree_host);
}

void SingleThreadProxy::Start() {
  DebugScopedSetImplThread impl(task_runner_provider_);

  const LayerTreeSettings& settings = layer_tree_host_->GetSettings();
  DCHECK(settings.single_thread_proxy_scheduler ||
         !settings.enable_checker_imaging)
      << "Checker-imaging is not supported in synchronous single threaded mode";
  if (settings.single_thread_proxy_scheduler && !scheduler_on_impl_thread_) {
    SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
    scheduler_settings.commit_to_active_tree = CommitToActiveTree();

    std::unique_ptr<CompositorTimingHistory> compositor_timing_history(
        new CompositorTimingHistory(
            scheduler_settings.using_synchronous_renderer_compositor,
            CompositorTimingHistory::BROWSER_UMA,
            layer_tree_host_->rendering_stats_instrumentation()));
    scheduler_on_impl_thread_.reset(
        new Scheduler(this, scheduler_settings, layer_tree_host_->GetId(),
                      task_runner_provider_->MainThreadTaskRunner(),
                      std::move(compositor_timing_history)));
  }

  host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this);
}

SingleThreadProxy::~SingleThreadProxy() {
  TRACE_EVENT0("cc", "SingleThreadProxy::~SingleThreadProxy");
  DCHECK(task_runner_provider_->IsMainThread());
  // Make sure Stop() got called or never Started.
  DCHECK(!host_impl_);
}

bool SingleThreadProxy::IsStarted() const {
  DCHECK(task_runner_provider_->IsMainThread());
  return !!host_impl_;
}

bool SingleThreadProxy::CommitToActiveTree() const {
  // With SingleThreadProxy we skip the pending tree and commit directly to the
  // active tree.
  return true;
}

void SingleThreadProxy::SetVisible(bool visible) {
  TRACE_EVENT1("cc", "SingleThreadProxy::SetVisible", "visible", visible);
  DebugScopedSetImplThread impl(task_runner_provider_);

  host_impl_->SetVisible(visible);

  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetVisible(host_impl_->visible());
}

void SingleThreadProxy::RequestNewLayerTreeFrameSink() {
  DCHECK(task_runner_provider_->IsMainThread());
  layer_tree_frame_sink_creation_callback_.Cancel();
  if (layer_tree_frame_sink_creation_requested_)
    return;
  layer_tree_frame_sink_creation_requested_ = true;
  layer_tree_host_->RequestNewLayerTreeFrameSink();
}

void SingleThreadProxy::ReleaseLayerTreeFrameSink() {
  layer_tree_frame_sink_lost_ = true;
  frame_sink_bound_weak_factory_.InvalidateWeakPtrs();
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
  return host_impl_->ReleaseLayerTreeFrameSink();
}

void SingleThreadProxy::SetLayerTreeFrameSink(
    LayerTreeFrameSink* layer_tree_frame_sink) {
  DCHECK(task_runner_provider_->IsMainThread());
  DCHECK(layer_tree_frame_sink_creation_requested_);

  bool success;
  {
    DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
    DebugScopedSetImplThread impl(task_runner_provider_);
    success = host_impl_->InitializeFrameSink(layer_tree_frame_sink);
  }

  if (success) {
    frame_sink_bound_weak_ptr_ = frame_sink_bound_weak_factory_.GetWeakPtr();
    layer_tree_host_->DidInitializeLayerTreeFrameSink();
    if (scheduler_on_impl_thread_)
      scheduler_on_impl_thread_->DidCreateAndInitializeLayerTreeFrameSink();
    else if (!inside_synchronous_composite_)
      SetNeedsCommit();
    layer_tree_frame_sink_creation_requested_ = false;
    layer_tree_frame_sink_lost_ = false;
  } else {
    // DidFailToInitializeLayerTreeFrameSink is treated as a
    // RequestNewLayerTreeFrameSink, and so
    // layer_tree_frame_sink_creation_requested remains true.
    layer_tree_host_->DidFailToInitializeLayerTreeFrameSink();
  }
}

void SingleThreadProxy::SetNeedsAnimate() {
  TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
  DCHECK(task_runner_provider_->IsMainThread());
  if (animate_requested_)
    return;
  animate_requested_ = true;
  DebugScopedSetImplThread impl(task_runner_provider_);
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
}

void SingleThreadProxy::SetNeedsUpdateLayers() {
  TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
  DCHECK(task_runner_provider_->IsMainThread());
  SetNeedsCommit();
}

void SingleThreadProxy::DoCommit() {
  TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
  DCHECK(task_runner_provider_->IsMainThread());

  layer_tree_host_->WillCommit();
  devtools_instrumentation::ScopedCommitTrace commit_task(
      layer_tree_host_->GetId());

  // Commit immediately.
  {
    DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
    DebugScopedSetImplThread impl(task_runner_provider_);

    host_impl_->ReadyToCommit();
    host_impl_->BeginCommit();

    if (host_impl_->EvictedUIResourcesExist())
      layer_tree_host_->GetUIResourceManager()->RecreateUIResources();

    layer_tree_host_->FinishCommitOnImplThread(host_impl_.get());

    if (scheduler_on_impl_thread_)
      scheduler_on_impl_thread_->DidCommit();

    IssueImageDecodeFinishedCallbacks();
    host_impl_->CommitComplete();

    // Commit goes directly to the active tree, but we need to synchronously
    // "activate" the tree still during commit to satisfy any potential
    // SetNextCommitWaitsForActivation calls.  Unfortunately, the tree
    // might not be ready to draw, so DidActivateSyncTree must set
    // the flag to force the tree to not draw until textures are ready.
    NotifyReadyToActivate();
  }
}

void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() {
  DCHECK(task_runner_provider_->IsImplThread());

  layer_tree_host_->ImageDecodesFinished(
      host_impl_->TakeCompletedImageDecodeRequests());
}

void SingleThreadProxy::CommitComplete() {
  // Commit complete happens on the main side after activate to satisfy any
  // SetNextCommitWaitsForActivation calls.
  DCHECK(!host_impl_->pending_tree())
      << "Activation is expected to have synchronously occurred by now.";

  DebugScopedSetMainThread main(task_runner_provider_);
  layer_tree_host_->CommitComplete();
  layer_tree_host_->DidBeginMainFrame();

  next_frame_is_newly_committed_frame_ = true;
}

void SingleThreadProxy::SetNeedsCommit() {
  DCHECK(task_runner_provider_->IsMainThread());
  single_thread_client_->RequestScheduleComposite();
  if (commit_requested_)
    return;
  commit_requested_ = true;
  DebugScopedSetImplThread impl(task_runner_provider_);
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
}

void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
  TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
  DCHECK(task_runner_provider_->IsMainThread());
  DebugScopedSetImplThread impl(task_runner_provider_);
  host_impl_->SetViewportDamage(damage_rect);
  SetNeedsRedrawOnImplThread();
}

void SingleThreadProxy::SetNextCommitWaitsForActivation() {
  // Activation always forced in commit, so nothing to do.
  DCHECK(task_runner_provider_->IsMainThread());
}

bool SingleThreadProxy::RequestedAnimatePending() {
  return animate_requested_ || commit_requested_ || needs_impl_frame_;
}

void SingleThreadProxy::SetDeferMainFrameUpdate(bool defer_main_frame_update) {
  DCHECK(task_runner_provider_->IsMainThread());
  // Deferring commits only makes sense if there's a scheduler.
  if (!scheduler_on_impl_thread_)
    return;
  if (defer_main_frame_update_ == defer_main_frame_update)
    return;

  if (defer_main_frame_update)
    TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
                             this);
  else
    TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferMainFrameUpdate",
                           this);

  defer_main_frame_update_ = defer_main_frame_update;
  scheduler_on_impl_thread_->SetDeferMainFrameUpdate(defer_main_frame_update);
}

bool SingleThreadProxy::CommitRequested() const {
  DCHECK(task_runner_provider_->IsMainThread());
  return commit_requested_;
}

void SingleThreadProxy::Stop() {
  TRACE_EVENT0("cc", "SingleThreadProxy::stop");
  DCHECK(task_runner_provider_->IsMainThread());
  {
    DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
    DebugScopedSetImplThread impl(task_runner_provider_);

    // Prevent the scheduler from performing actions while we're in an
    // inconsistent state.
    if (scheduler_on_impl_thread_)
      scheduler_on_impl_thread_->Stop();
    // Take away the LayerTreeFrameSink before destroying things so it doesn't
    // try to call into its client mid-shutdown.
    host_impl_->ReleaseLayerTreeFrameSink();

    // It is important to destroy LTHI before the Scheduler since it can make
    // callbacks that access it during destruction cleanup.
    host_impl_ = nullptr;
    scheduler_on_impl_thread_ = nullptr;
  }
  layer_tree_host_ = nullptr;
}

void SingleThreadProxy::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) {
  DCHECK(task_runner_provider_->IsMainThread());
  DebugScopedSetImplThread impl(task_runner_provider_);
  host_impl_->SetLayerTreeMutator(std::move(mutator));
}

void SingleThreadProxy::SetPaintWorkletLayerPainter(
    std::unique_ptr<PaintWorkletLayerPainter> painter) {
  NOTREACHED();
}

void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
  TRACE_EVENT1("cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw",
               can_draw);
  DCHECK(task_runner_provider_->IsImplThread());
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetCanDraw(can_draw);
}

void SingleThreadProxy::NotifyReadyToActivate() {
  TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToActivate");
  DebugScopedSetImplThread impl(task_runner_provider_);
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->NotifyReadyToActivate();
}

void SingleThreadProxy::NotifyReadyToDraw() {
  TRACE_EVENT0("cc", "SingleThreadProxy::NotifyReadyToDraw");
  DebugScopedSetImplThread impl(task_runner_provider_);
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->NotifyReadyToDraw();
}

void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
  single_thread_client_->RequestScheduleComposite();
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetNeedsRedraw();
}

void SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread() {
  TRACE_EVENT0("cc",
               "SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread");
  single_thread_client_->RequestScheduleComposite();
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetNeedsOneBeginImplFrame();
  needs_impl_frame_ = true;
}

void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() {
  TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsPrepareTilesOnImplThread");
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetNeedsPrepareTiles();
}

void SingleThreadProxy::SetNeedsCommitOnImplThread() {
  single_thread_client_->RequestScheduleComposite();
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetNeedsBeginMainFrame();
  commit_requested_ = true;
}

void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
  TRACE_EVENT1("cc", "SingleThreadProxy::SetVideoNeedsBeginFrames",
               "needs_begin_frames", needs_begin_frames);
  // In tests the layer tree is destroyed after the scheduler is.
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetVideoNeedsBeginFrames(needs_begin_frames);
}

void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
    std::unique_ptr<MutatorEvents> events) {
  TRACE_EVENT0(
      "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
  DCHECK(task_runner_provider_->IsImplThread());
  DebugScopedSetMainThread main(task_runner_provider_);
  layer_tree_host_->SetAnimationEvents(std::move(events));
}

size_t SingleThreadProxy::CompositedAnimationsCount() const {
  return 0;
}

size_t SingleThreadProxy::MainThreadAnimationsCount() const {
  return 0;
}

bool SingleThreadProxy::CurrentFrameHadRAF() const {
  return false;
}

bool SingleThreadProxy::NextFrameHasPendingRAF() const {
  return false;
}

bool SingleThreadProxy::IsInsideDraw() {
  return inside_draw_;
}

void SingleThreadProxy::DidActivateSyncTree() {
  CommitComplete();
}

void SingleThreadProxy::WillPrepareTiles() {
  DCHECK(task_runner_provider_->IsImplThread());
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->WillPrepareTiles();
}

void SingleThreadProxy::DidPrepareTiles() {
  DCHECK(task_runner_provider_->IsImplThread());
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->DidPrepareTiles();
}

void SingleThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
  layer_tree_host_->DidCompletePageScaleAnimation();
}

void SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread() {
  TRACE_EVENT0("cc",
               "SingleThreadProxy::DidLoseLayerTreeFrameSinkOnImplThread");
  {
    DebugScopedSetMainThread main(task_runner_provider_);
    // This must happen before we notify the scheduler as it may try to recreate
    // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
    layer_tree_host_->DidLoseLayerTreeFrameSink();
  }
  single_thread_client_->DidLoseLayerTreeFrameSink();
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->DidLoseLayerTreeFrameSink();
  layer_tree_frame_sink_lost_ = true;
}

void SingleThreadProxy::SetBeginFrameSource(viz::BeginFrameSource* source) {
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->SetBeginFrameSource(source);
}

void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() {
  TRACE_EVENT0("cc,benchmark",
               "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread");
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->DidReceiveCompositorFrameAck();
  if (layer_tree_host_->GetSettings().send_compositor_frame_ack) {
    // We do a PostTask here because freeing resources in some cases (such as in
    // TextureLayer) is PostTasked and we want to make sure ack is received
    // after resources are returned.
    task_runner_provider_->MainThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::BindOnce(&SingleThreadProxy::DidReceiveCompositorFrameAck,
                       frame_sink_bound_weak_ptr_));
  }
}

void SingleThreadProxy::OnDrawForLayerTreeFrameSink(
    bool resourceless_software_draw,
    bool skip_draw) {
  NOTREACHED() << "Implemented by ThreadProxy for synchronous compositor.";
}

void SingleThreadProxy::NeedsImplSideInvalidation(
    bool needs_first_draw_on_activation) {
  if (scheduler_on_impl_thread_) {
    scheduler_on_impl_thread_->SetNeedsImplSideInvalidation(
        needs_first_draw_on_activation);
  }
}

void SingleThreadProxy::NotifyImageDecodeRequestFinished() {
  // If we don't have a scheduler, then just issue the callbacks here.
  // Otherwise, schedule a commit.
  if (!scheduler_on_impl_thread_) {
    DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
    DebugScopedSetImplThread impl(task_runner_provider_);

    IssueImageDecodeFinishedCallbacks();
    return;
  }
  SetNeedsCommitOnImplThread();
}

void SingleThreadProxy::DidPresentCompositorFrameOnImplThread(
    uint32_t frame_token,
    std::vector<LayerTreeHost::PresentationTimeCallback> callbacks,
    const gfx::PresentationFeedback& feedback) {
  layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks),
                                              feedback);
}

void SingleThreadProxy::DidGenerateLocalSurfaceIdAllocationOnImplThread(
    const viz::LocalSurfaceIdAllocation& allocation) {
  layer_tree_host_->DidGenerateLocalSurfaceIdAllocation(allocation);
}

void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
  if (scheduler_on_impl_thread_) {
    scheduler_on_impl_thread_->SetMainThreadWantsBeginMainFrameNotExpected(
        new_state);
  }
}

void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
                                             bool raster) {
  TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
  DCHECK(task_runner_provider_->IsMainThread());
#if DCHECK_IS_ON()
  DCHECK(!inside_impl_frame_);
#endif
  base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true);

  if (layer_tree_frame_sink_lost_) {
    RequestNewLayerTreeFrameSink();
    // RequestNewLayerTreeFrameSink could have synchronously created an output
    // surface, so check again before returning.
    if (layer_tree_frame_sink_lost_)
      return;
  }

  viz::BeginFrameArgs begin_frame_args(viz::BeginFrameArgs::Create(
      BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
      frame_begin_time, base::TimeTicks(),
      viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL));

  // Start the impl frame.
  {
    DebugScopedSetImplThread impl(task_runner_provider_);
    WillBeginImplFrame(begin_frame_args);
  }

  // Run the "main thread" and get it to commit.
  {
#if DCHECK_IS_ON()
    DCHECK(inside_impl_frame_);
#endif
    animate_requested_ = false;
    needs_impl_frame_ = false;
    // Prevent new commits from being requested inside DoBeginMainFrame.
    // Note: We do not want to prevent SetNeedsAnimate from requesting
    // a commit here.
    commit_requested_ = true;
    DoBeginMainFrame(begin_frame_args);
    commit_requested_ = false;
    DoPainting();
    DoCommit();

    DCHECK_EQ(
        0u,
        layer_tree_host_->GetSwapPromiseManager()->num_queued_swap_promises())
        << "Commit should always succeed and transfer promises.";
  }

  // Finish the impl frame.
  {
    DebugScopedSetImplThread impl(task_runner_provider_);
    host_impl_->ActivateSyncTree();
    if (raster) {
      host_impl_->PrepareTiles();
      host_impl_->SynchronouslyInitializeAllTiles();
    }

    // TODO(danakj): Don't do this last... we prepared the wrong things. D:
    host_impl_->Animate();

    if (raster) {
      LayerTreeHostImpl::FrameData frame;
      frame.begin_frame_ack = viz::BeginFrameAck(begin_frame_args, true);
      DoComposite(&frame);
    }

    // DoComposite could abort, but because this is a synchronous composite
    // another draw will never be scheduled, so break remaining promises.
    host_impl_->active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);

    DidFinishImplFrame();
  }
}

bool SingleThreadProxy::SupportsImplScrolling() const {
  return false;
}

bool SingleThreadProxy::ShouldComposite() const {
  DCHECK(task_runner_provider_->IsImplThread());
  return host_impl_->visible() && host_impl_->CanDraw();
}

void SingleThreadProxy::ScheduleRequestNewLayerTreeFrameSink() {
  if (layer_tree_frame_sink_creation_callback_.IsCancelled() &&
      !layer_tree_frame_sink_creation_requested_) {
    layer_tree_frame_sink_creation_callback_.Reset(
        base::BindOnce(&SingleThreadProxy::RequestNewLayerTreeFrameSink,
                       weak_factory_.GetWeakPtr()));
    task_runner_provider_->MainThreadTaskRunner()->PostTask(
        FROM_HERE, layer_tree_frame_sink_creation_callback_.callback());
  }
}

DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) {
  TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");

  DrawResult draw_result;
  bool draw_frame;
  {
    DebugScopedSetImplThread impl(task_runner_provider_);
    base::AutoReset<bool> mark_inside(&inside_draw_, true);

    // We guard PrepareToDraw() with CanDraw() because it always returns a valid
    // frame, so can only be used when such a frame is possible. Since
    // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
    // CanDraw() as well.
    if (!ShouldComposite()) {
      return DRAW_ABORTED_CANT_DRAW;
    }

    // This CapturePostTasks should be destroyed before
    // DidCommitAndDrawFrame() is called since that goes out to the
    // embedder, and we want the embedder to receive its callbacks before that.
    // NOTE: This maintains consistent ordering with the ThreadProxy since
    // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
    // there as the main thread is not blocked, so any posted tasks inside
    // the swap buffers will execute first.
    DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);

    draw_result = host_impl_->PrepareToDraw(frame);
    draw_frame = draw_result == DRAW_SUCCESS;
    if (draw_frame) {
      if (host_impl_->DrawLayers(frame)) {
        if (scheduler_on_impl_thread_)
          // Drawing implies we submitted a frame to the LayerTreeFrameSink.
          scheduler_on_impl_thread_->DidSubmitCompositorFrame();
        single_thread_client_->DidSubmitCompositorFrame();
      }
    }
    host_impl_->DidDrawAllLayers(*frame);

    bool start_ready_animations = draw_frame;
    host_impl_->UpdateAnimationState(start_ready_animations);
  }
  DidCommitAndDrawFrame();

  return draw_result;
}

void SingleThreadProxy::DidCommitAndDrawFrame() {
  if (next_frame_is_newly_committed_frame_) {
    DebugScopedSetMainThread main(task_runner_provider_);
    next_frame_is_newly_committed_frame_ = false;
    layer_tree_host_->DidCommitAndDrawFrame();
  }
}

bool SingleThreadProxy::MainFrameWillHappenForTesting() {
  if (!scheduler_on_impl_thread_)
    return false;
  return scheduler_on_impl_thread_->MainFrameForTestingWillHappen();
}

void SingleThreadProxy::ClearHistory() {
  DCHECK(task_runner_provider_->IsImplThread());
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->ClearHistory();
}

void SingleThreadProxy::SetRenderFrameObserver(
    std::unique_ptr<RenderFrameMetadataObserver> observer) {
  host_impl_->SetRenderFrameObserver(std::move(observer));
}

void SingleThreadProxy::UpdateBrowserControlsState(
    BrowserControlsState constraints,
    BrowserControlsState current,
    bool animate) {
  host_impl_->browser_controls_manager()->UpdateBrowserControlsState(
      constraints, current, animate);
}

bool SingleThreadProxy::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
  DebugScopedSetImplThread impl(task_runner_provider_);
#if DCHECK_IS_ON()
  DCHECK(!inside_impl_frame_)
      << "WillBeginImplFrame called while already inside an impl frame!";
  inside_impl_frame_ = true;
#endif
  return host_impl_->WillBeginImplFrame(args);
}

void SingleThreadProxy::ScheduledActionSendBeginMainFrame(
    const viz::BeginFrameArgs& begin_frame_args) {
  TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
#if DCHECK_IS_ON()
  // Although this proxy is single-threaded, it's problematic to synchronously
  // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame.  This
  // could cause a commit to occur in between a series of SetNeedsCommit calls
  // (i.e. property modifications) causing some to fall on one frame and some to
  // fall on the next.  Doing it asynchronously instead matches the semantics of
  // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
  // synchronous commit.
  DCHECK(inside_impl_frame_)
      << "BeginMainFrame should only be sent inside a BeginImplFrame";
#endif

  host_impl_->WillSendBeginMainFrame();
  task_runner_provider_->MainThreadTaskRunner()->PostTask(
      FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
                                weak_factory_.GetWeakPtr(), begin_frame_args));
  host_impl_->DidSendBeginMainFrame();
}

void SingleThreadProxy::FrameIntervalUpdated(base::TimeDelta interval) {
  DebugScopedSetMainThread main(task_runner_provider_);
  single_thread_client_->FrameIntervalUpdated(interval);
}

void SingleThreadProxy::SendBeginMainFrameNotExpectedSoon() {
  layer_tree_host_->BeginMainFrameNotExpectedSoon();
}

void SingleThreadProxy::ScheduledActionBeginMainFrameNotExpectedUntil(
    base::TimeTicks time) {
  layer_tree_host_->BeginMainFrameNotExpectedUntil(time);
}

void SingleThreadProxy::BeginMainFrame(
    const viz::BeginFrameArgs& begin_frame_args) {
  // This checker assumes NotifyReadyToCommit in this stack causes a synchronous
  // commit.
  ScopedAbortRemainingSwapPromises swap_promise_checker(
      layer_tree_host_->GetSwapPromiseManager());

  if (scheduler_on_impl_thread_) {
    scheduler_on_impl_thread_->NotifyBeginMainFrameStarted(
        base::TimeTicks::Now());
  }

  commit_requested_ = false;
  needs_impl_frame_ = false;
  animate_requested_ = false;

  if (defer_main_frame_update_) {
    TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
                         TRACE_EVENT_SCOPE_THREAD);
    BeginMainFrameAbortedOnImplThread(
        CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
    return;
  }

  if (!layer_tree_host_->IsVisible()) {
    TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
    BeginMainFrameAbortedOnImplThread(
        CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
    return;
  }

  // Prevent new commits from being requested inside DoBeginMainFrame.
  // Note: We do not want to prevent SetNeedsAnimate from requesting
  // a commit here.
  commit_requested_ = true;

  DoBeginMainFrame(begin_frame_args);

  // New commits requested inside UpdateLayers should be respected.
  commit_requested_ = false;

  // At this point the main frame may have deferred commits to avoid committing
  // right now.
  if (defer_main_frame_update_ || begin_frame_args.animate_only) {
    TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame",
                         TRACE_EVENT_SCOPE_THREAD);
    BeginMainFrameAbortedOnImplThread(
        CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
    layer_tree_host_->DidBeginMainFrame();
    return;
  }

  // Queue the LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT swap promise only once we
  // know we will commit since QueueSwapPromise itself requests a commit.
  ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME);
  new_latency_info.AddLatencyNumberWithTimestamp(
      ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, begin_frame_args.frame_time,
      1);
  layer_tree_host_->QueueSwapPromise(
      std::make_unique<LatencyInfoSwapPromise>(new_latency_info));

  DoPainting();
}

void SingleThreadProxy::DoBeginMainFrame(
    const viz::BeginFrameArgs& begin_frame_args) {
  // The impl-side scroll deltas may be manipulated directly via the
  // InputHandler on the UI thread and the scale deltas may change when they are
  // clamped on the impl thread.
  std::unique_ptr<ScrollAndScaleSet> scroll_info =
      host_impl_->ProcessScrollDeltas();
  layer_tree_host_->ApplyScrollAndScale(scroll_info.get());

  layer_tree_host_->WillBeginMainFrame();
  layer_tree_host_->BeginMainFrame(begin_frame_args);
  layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
  layer_tree_host_->RequestMainFrameUpdate(
      false /* record_main_frame_metrics */);
}

void SingleThreadProxy::DoPainting() {
  layer_tree_host_->UpdateLayers();

  // TODO(enne): SingleThreadProxy does not support cancelling commits yet,
  // search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
  // thread_proxy.cc
  if (scheduler_on_impl_thread_)
    scheduler_on_impl_thread_->NotifyReadyToCommit();
}

void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
    CommitEarlyOutReason reason) {
  DebugScopedSetImplThread impl(task_runner_provider_);
  DCHECK(scheduler_on_impl_thread_->CommitPending());
  DCHECK(!host_impl_->pending_tree());

  std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises;
  host_impl_->BeginMainFrameAborted(reason, std::move(empty_swap_promises));
  scheduler_on_impl_thread_->BeginMainFrameAborted(reason);
}

DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() {
  DebugScopedSetImplThread impl(task_runner_provider_);
  LayerTreeHostImpl::FrameData frame;
  frame.begin_frame_ack =
      scheduler_on_impl_thread_->CurrentBeginFrameAckForActiveTree();
  return DoComposite(&frame);
}

DrawResult SingleThreadProxy::ScheduledActionDrawForced() {
  NOTREACHED();
  return INVALID_RESULT;
}

void SingleThreadProxy::ScheduledActionCommit() {
  DebugScopedSetMainThread main(task_runner_provider_);
  DoCommit();
}

void SingleThreadProxy::ScheduledActionActivateSyncTree() {
  DebugScopedSetImplThread impl(task_runner_provider_);
  host_impl_->ActivateSyncTree();
}

void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() {
  DebugScopedSetMainThread main(task_runner_provider_);
  DCHECK(scheduler_on_impl_thread_);
  // If possible, create the output surface in a post task.  Synchronously
  // creating the output surface makes tests more awkward since this differs
  // from the ThreadProxy behavior.  However, sometimes there is no
  // task runner.
  if (task_runner_provider_->MainThreadTaskRunner()) {
    ScheduleRequestNewLayerTreeFrameSink();
  } else {
    RequestNewLayerTreeFrameSink();
  }
}

void SingleThreadProxy::ScheduledActionPrepareTiles() {
  TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionPrepareTiles");
  DebugScopedSetImplThread impl(task_runner_provider_);
  host_impl_->PrepareTiles();
}

void SingleThreadProxy::ScheduledActionInvalidateLayerTreeFrameSink(
    bool needs_redraw) {
  // This is an Android WebView codepath, which only uses multi-thread
  // compositor. So this should not occur in single-thread mode.
  NOTREACHED() << "Android Webview use-case, so multi-thread only";
}

void SingleThreadProxy::ScheduledActionPerformImplSideInvalidation() {
  DCHECK(scheduler_on_impl_thread_);

  DebugScopedSetImplThread impl(task_runner_provider_);
  host_impl_->InvalidateContentOnImplSide();

  // Invalidations go directly to the active tree, so we synchronously call
  // NotifyReadyToActivate to update the scheduler and LTHI state correctly.
  // Since in single-threaded mode the scheduler will wait for a ready to draw
  // signal from LTHI, the draw will remain blocked till the invalidated tiles
  // are ready.
  NotifyReadyToActivate();
}

void SingleThreadProxy::DidFinishImplFrame() {
  host_impl_->DidFinishImplFrame();
#if DCHECK_IS_ON()
  DCHECK(inside_impl_frame_)
      << "DidFinishImplFrame called while not inside an impl frame!";
  inside_impl_frame_ = false;
#endif
}

void SingleThreadProxy::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
  DebugScopedSetImplThread impl(task_runner_provider_);
  host_impl_->DidNotProduceFrame(ack);
}

void SingleThreadProxy::WillNotReceiveBeginFrame() {
  host_impl_->DidNotNeedBeginFrame();
}

void SingleThreadProxy::DidReceiveCompositorFrameAck() {
  layer_tree_host_->DidReceiveCompositorFrameAck();
}

}  // namespace cc
