// Copyright 2014 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 "android_webview/browser/browser_view_renderer.h"

#include <utility>

#include "android_webview/browser/browser_view_renderer_client.h"
#include "android_webview/browser/compositor_frame_consumer.h"
#include "android_webview/common/aw_switches.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/supports_user_data.h"
#include "base/trace_event/trace_event_argument.h"
#include "cc/output/compositor_frame.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/geometry/vector2d_conversions.h"

namespace android_webview {

namespace {

const double kEpsilon = 1e-8;

// Used to calculate memory allocation. Determined experimentally.
const size_t kMemoryMultiplier = 20;
const size_t kBytesPerPixel = 4;
const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
uint64_t g_memory_override_in_bytes = 0u;

const void* const kBrowserViewRendererUserDataKey =
    &kBrowserViewRendererUserDataKey;

class BrowserViewRendererUserData : public base::SupportsUserData::Data {
 public:
  explicit BrowserViewRendererUserData(BrowserViewRenderer* ptr) : bvr_(ptr) {}

  static BrowserViewRenderer* GetBrowserViewRenderer(
      content::WebContents* web_contents) {
    if (!web_contents)
      return NULL;
    BrowserViewRendererUserData* data =
        static_cast<BrowserViewRendererUserData*>(
            web_contents->GetUserData(kBrowserViewRendererUserDataKey));
    return data ? data->bvr_ : NULL;
  }

 private:
  BrowserViewRenderer* bvr_;
};

}  // namespace

// static
void BrowserViewRenderer::CalculateTileMemoryPolicy() {
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();

  // If the value was overridden on the command line, use the specified value.
  bool client_hard_limit_bytes_overridden =
      cl->HasSwitch(switches::kForceGpuMemAvailableMb);
  if (client_hard_limit_bytes_overridden) {
    base::StringToUint64(
        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
            switches::kForceGpuMemAvailableMb),
        &g_memory_override_in_bytes);
    g_memory_override_in_bytes *= 1024 * 1024;
  }
}

// static
BrowserViewRenderer* BrowserViewRenderer::FromWebContents(
    content::WebContents* web_contents) {
  return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents);
}

BrowserViewRenderer::BrowserViewRenderer(
    BrowserViewRendererClient* client,
    const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
    : client_(client),
      ui_task_runner_(ui_task_runner),
      sync_on_draw_hardware_(base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kSyncOnDrawHardware)),
      current_compositor_frame_consumer_(nullptr),
      compositor_(nullptr),
      is_paused_(false),
      view_visible_(false),
      window_visible_(false),
      attached_to_window_(false),
      was_attached_(false),
      hardware_enabled_(false),
      dip_scale_(0.f),
      page_scale_factor_(1.f),
      min_page_scale_factor_(0.f),
      max_page_scale_factor_(0.f),
      on_new_picture_enable_(false),
      clear_view_(false),
      offscreen_pre_raster_(false),
      allow_async_draw_(false) {}

BrowserViewRenderer::~BrowserViewRenderer() {
  DCHECK(compositor_map_.empty());
  SetCurrentCompositorFrameConsumer(nullptr);
  while (compositor_frame_consumers_.size()) {
    RemoveCompositorFrameConsumer(*compositor_frame_consumers_.begin());
  }
}

void BrowserViewRenderer::SetCurrentCompositorFrameConsumer(
    CompositorFrameConsumer* compositor_frame_consumer) {
  if (compositor_frame_consumer == current_compositor_frame_consumer_) {
    return;
  }
  current_compositor_frame_consumer_ = compositor_frame_consumer;
  if (current_compositor_frame_consumer_) {
    compositor_frame_consumers_.insert(current_compositor_frame_consumer_);
    current_compositor_frame_consumer_->SetCompositorFrameProducer(this);
    OnParentDrawConstraintsUpdated(current_compositor_frame_consumer_);
  }
}

void BrowserViewRenderer::RegisterWithWebContents(
    content::WebContents* web_contents) {
  web_contents->SetUserData(
      kBrowserViewRendererUserDataKey,
      base::MakeUnique<BrowserViewRendererUserData>(this));
}

void BrowserViewRenderer::TrimMemory() {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory");
  // Just set the memory limit to 0 and drop all tiles. This will be reset to
  // normal levels in the next DrawGL call.
  if (!offscreen_pre_raster_)
    ReleaseHardware();
}

void BrowserViewRenderer::UpdateMemoryPolicy() {
  if (!compositor_) {
    return;
  }

  if (!hardware_enabled_) {
    compositor_->SetMemoryPolicy(0u);
    return;
  }

  size_t bytes_limit = 0u;
  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_;
    size_t width = interest_rect.width();
    size_t height = interest_rect.height();
    bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
    // Round up to a multiple of kMemoryAllocationStep.
    bytes_limit =
        (bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
  }

  compositor_->SetMemoryPolicy(bytes_limit);
}

content::SynchronousCompositor* BrowserViewRenderer::FindCompositor(
    const CompositorID& compositor_id) const {
  const auto& compositor_iterator = compositor_map_.find(compositor_id);
  if (compositor_iterator == compositor_map_.end())
    return nullptr;

  return compositor_iterator->second;
}

void BrowserViewRenderer::PrepareToDraw(const gfx::Vector2d& scroll,
                                        const gfx::Rect& global_visible_rect) {
  last_on_draw_scroll_offset_ = scroll;
  last_on_draw_global_visible_rect_ = global_visible_rect;
}

bool BrowserViewRenderer::CanOnDraw() {
  if (!compositor_) {
    TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoCompositor",
                         TRACE_EVENT_SCOPE_THREAD);
    return false;
  }
  if (clear_view_) {
    TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_ClearView",
                         TRACE_EVENT_SCOPE_THREAD);
    return false;
  }

  return true;
}

bool BrowserViewRenderer::OnDrawHardware() {
  DCHECK(current_compositor_frame_consumer_);
  TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware");

  current_compositor_frame_consumer_->InitializeHardwareDrawIfNeededOnUI();

  if (!CanOnDraw()) {
    return false;
  }

  current_compositor_frame_consumer_->SetScrollOffsetOnUI(
      last_on_draw_scroll_offset_);
  hardware_enabled_ = true;

  external_draw_constraints_ =
      current_compositor_frame_consumer_->GetParentDrawConstraintsOnUI();

  ReturnResourceFromParent(current_compositor_frame_consumer_);
  UpdateMemoryPolicy();

  gfx::Transform transform_for_tile_priority =
      external_draw_constraints_.transform;

  gfx::Rect viewport_rect_for_tile_priority =
      ComputeViewportRectForTilePriority();

  scoped_refptr<content::SynchronousCompositor::FrameFuture> future; // Async.
  content::SynchronousCompositor::Frame frame; // Sync.
  bool async = !sync_on_draw_hardware_ && allow_async_draw_;
  if (async) {
    future = compositor_->DemandDrawHwAsync(
        size_, viewport_rect_for_tile_priority, transform_for_tile_priority);
  } else {
    frame = compositor_->DemandDrawHw(size_, viewport_rect_for_tile_priority,
                                      transform_for_tile_priority);
  }

  if (!frame.frame && !future) {
    TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame",
                         TRACE_EVENT_SCOPE_THREAD);
    return current_compositor_frame_consumer_->HasFrameOnUI();
  }

  allow_async_draw_ = true;
  std::unique_ptr<ChildFrame> child_frame = base::MakeUnique<ChildFrame>(
      std::move(future), frame.layer_tree_frame_sink_id, std::move(frame.frame),
      compositor_id_, viewport_rect_for_tile_priority.IsEmpty(),
      transform_for_tile_priority, offscreen_pre_raster_,
      external_draw_constraints_.is_layer);

  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);
  if (compositor_frame_consumer != current_compositor_frame_consumer_)
    return;
  PostInvalidate(compositor_);
  external_draw_constraints_ =
      current_compositor_frame_consumer_->GetParentDrawConstraintsOnUI();
  UpdateMemoryPolicy();
}

void BrowserViewRenderer::RemoveCompositorFrameConsumer(
    CompositorFrameConsumer* compositor_frame_consumer) {
  DCHECK(compositor_frame_consumers_.count(compositor_frame_consumer));
  compositor_frame_consumers_.erase(compositor_frame_consumer);
  if (current_compositor_frame_consumer_ == compositor_frame_consumer) {
    SetCurrentCompositorFrameConsumer(nullptr);
  }

  // At this point the compositor frame consumer has to hand back all resources
  // to the child compositor.
  compositor_frame_consumer->DeleteHardwareRendererOnUI();
  ReturnUncommittedFrames(
      compositor_frame_consumer->PassUncommittedFrameOnUI());
  ReturnResourceFromParent(compositor_frame_consumer);
  compositor_frame_consumer->SetCompositorFrameProducer(nullptr);
}

void BrowserViewRenderer::ReturnUncommittedFrames(
    ChildFrameQueue child_frames) {
  for (auto& child_frame : child_frames)
    ReturnUnusedResource(std::move(child_frame));
}

void BrowserViewRenderer::ReturnUnusedResource(
    std::unique_ptr<ChildFrame> child_frame) {
  if (!child_frame.get() || !child_frame->frame.get())
    return;

  std::vector<viz::ReturnedResource> resources =
      viz::TransferableResource::ReturnResources(
          child_frame->frame->resource_list);
  content::SynchronousCompositor* compositor =
      FindCompositor(child_frame->compositor_id);
  if (compositor && !resources.empty())
    compositor->ReturnResources(child_frame->layer_tree_frame_sink_id,
                                std::move(resources));
}

void BrowserViewRenderer::ReturnResourceFromParent(
    CompositorFrameConsumer* compositor_frame_consumer) {
  CompositorFrameConsumer::ReturnedResourcesMap returned_resource_map;
  compositor_frame_consumer->SwapReturnedResourcesOnUI(&returned_resource_map);
  for (auto& pair : returned_resource_map) {
    CompositorID compositor_id = pair.first;
    content::SynchronousCompositor* compositor = FindCompositor(compositor_id);
    std::vector<viz::ReturnedResource> resources;
    resources.swap(pair.second.resources);

    if (compositor && !resources.empty()) {
      compositor->ReturnResources(pair.second.layer_tree_frame_sink_id,
                                  resources);
    }
  }
}

bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) {
  return CanOnDraw() && CompositeSW(canvas);
}

sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width,
                                                     int height) {
  TRACE_EVENT0("android_webview", "BrowserViewRenderer::CapturePicture");

  // Return empty Picture objects for empty SkPictures.
  if (width <= 0 || height <= 0) {
    SkPictureRecorder emptyRecorder;
    emptyRecorder.beginRecording(0, 0);
    return emptyRecorder.finishRecordingAsPicture();
  }

  SkPictureRecorder recorder;
  SkCanvas* rec_canvas = recorder.beginRecording(width, height, NULL, 0);
  if (compositor_) {
    {
      // Reset scroll back to the origin, will go back to the old
      // value when scroll_reset is out of scope.
      base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_dip_,
                                                   gfx::Vector2dF());
      compositor_->DidChangeRootLayerScrollOffset(
          gfx::ScrollOffset(scroll_offset_dip_));
      CompositeSW(rec_canvas);
    }
    compositor_->DidChangeRootLayerScrollOffset(
        gfx::ScrollOffset(scroll_offset_dip_));
  }
  return recorder.finishRecordingAsPicture();
}

void BrowserViewRenderer::EnableOnNewPicture(bool enabled) {
  on_new_picture_enable_ = enabled;
}

void BrowserViewRenderer::ClearView() {
  TRACE_EVENT_INSTANT0("android_webview",
                       "BrowserViewRenderer::ClearView",
                       TRACE_EVENT_SCOPE_THREAD);
  if (clear_view_)
    return;

  clear_view_ = true;
  // Always invalidate ignoring the compositor to actually clear the webview.
  PostInvalidate(compositor_);
}

void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) {
  if (offscreen_pre_raster_ != enable) {
    offscreen_pre_raster_ = enable;
    UpdateMemoryPolicy();
  }
}

void BrowserViewRenderer::SetIsPaused(bool paused) {
  TRACE_EVENT_INSTANT1("android_webview",
                       "BrowserViewRenderer::SetIsPaused",
                       TRACE_EVENT_SCOPE_THREAD,
                       "paused",
                       paused);
  is_paused_ = paused;
}

void BrowserViewRenderer::SetViewVisibility(bool view_visible) {
  TRACE_EVENT_INSTANT1("android_webview",
                       "BrowserViewRenderer::SetViewVisibility",
                       TRACE_EVENT_SCOPE_THREAD,
                       "view_visible",
                       view_visible);
  view_visible_ = view_visible;
}

void BrowserViewRenderer::SetWindowVisibility(bool window_visible) {
  TRACE_EVENT_INSTANT1("android_webview",
                       "BrowserViewRenderer::SetWindowVisibility",
                       TRACE_EVENT_SCOPE_THREAD,
                       "window_visible",
                       window_visible);
  window_visible_ = window_visible;
}

void BrowserViewRenderer::OnSizeChanged(int width, int height) {
  TRACE_EVENT_INSTANT2("android_webview",
                       "BrowserViewRenderer::OnSizeChanged",
                       TRACE_EVENT_SCOPE_THREAD,
                       "width",
                       width,
                       "height",
                       height);
  size_.SetSize(width, height);
  if (offscreen_pre_raster_)
    UpdateMemoryPolicy();
}

void BrowserViewRenderer::OnAttachedToWindow(int width, int height) {
  TRACE_EVENT2("android_webview",
               "BrowserViewRenderer::OnAttachedToWindow",
               "width",
               width,
               "height",
               height);
  attached_to_window_ = true;
  was_attached_ = true;

  size_.SetSize(width, height);
  if (offscreen_pre_raster_)
    UpdateMemoryPolicy();
}

void BrowserViewRenderer::OnDetachedFromWindow() {
  TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
  attached_to_window_ = false;
  ReleaseHardware();
}

void BrowserViewRenderer::ZoomBy(float delta) {
  if (!compositor_)
    return;
  compositor_->SynchronouslyZoomBy(
      delta, gfx::Point(size_.width() / 2, size_.height() / 2));
}

void BrowserViewRenderer::OnComputeScroll(base::TimeTicks animation_time) {
  if (!compositor_)
    return;
  TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnComputeScroll");
  compositor_->OnComputeScroll(animation_time);
}

void BrowserViewRenderer::ReleaseHardware() {
  for (auto* compositor_frame_consumer : compositor_frame_consumers_) {
    ReturnUncommittedFrames(
        compositor_frame_consumer->PassUncommittedFrameOnUI());
    ReturnResourceFromParent(compositor_frame_consumer);
    DCHECK(compositor_frame_consumer->ReturnedResourcesEmptyOnUI());
  }
  hardware_enabled_ = false;
  UpdateMemoryPolicy();
}

bool BrowserViewRenderer::IsVisible() const {
  // Ignore |window_visible_| if |attached_to_window_| is false.
  return view_visible_ && (!attached_to_window_ || window_visible_);
}

bool BrowserViewRenderer::IsClientVisible() const {
  // When WebView is not paused, we declare it visible even before it is
  // attached to window to allow for background operations. If it ever gets
  // attached though, the WebView is visible as long as it is attached
  // to a window and the window is visible.
  return is_paused_
             ? false
             : !was_attached_ || (attached_to_window_ && window_visible_);
}

gfx::Rect BrowserViewRenderer::GetScreenRect() const {
  return gfx::Rect(client_->GetLocationOnScreen(), size_);
}

void BrowserViewRenderer::DidInitializeCompositor(
    content::SynchronousCompositor* compositor,
    int process_id,
    int routing_id) {
  TRACE_EVENT_INSTANT0("android_webview",
                       "BrowserViewRenderer::DidInitializeCompositor",
                       TRACE_EVENT_SCOPE_THREAD);
  DCHECK(compositor);
  CompositorID compositor_id(process_id, routing_id);
  // This assumes that a RenderViewHost has at most 1 synchronous compositor
  // througout its lifetime.
  DCHECK(compositor_map_.count(compositor_id) == 0);
  compositor_map_[compositor_id] = compositor;

  // At this point, the RVHChanged event for the new RVH that contains the
  // |compositor| might have been fired already, in which case just set the
  // current compositor with the new compositor.
  if (!compositor_ && compositor_id.Equals(compositor_id_))
    compositor_ = compositor;
}

void BrowserViewRenderer::DidDestroyCompositor(
    content::SynchronousCompositor* compositor,
    int process_id,
    int routing_id) {
  TRACE_EVENT_INSTANT0("android_webview",
                       "BrowserViewRenderer::DidDestroyCompositor",
                       TRACE_EVENT_SCOPE_THREAD);
  CompositorID compositor_id(process_id, routing_id);
  DCHECK(compositor_map_.count(compositor_id));
  if (compositor_ == compositor) {
    compositor_ = nullptr;
  }

  compositor_map_.erase(compositor_id);
}

void BrowserViewRenderer::SetActiveCompositorID(
    const CompositorID& compositor_id) {
  // Set the old compositor memory policy to 0.
  if (!compositor_id_.Equals(compositor_id) && compositor_)
    compositor_->SetMemoryPolicy(0u);

  if (content::SynchronousCompositor* compositor =
          FindCompositor(compositor_id)) {
    compositor_ = compositor;
    UpdateMemoryPolicy();
    compositor_->DidChangeRootLayerScrollOffset(
        gfx::ScrollOffset(scroll_offset_dip_));
  } else {
    compositor_ = nullptr;
  }
  compositor_id_ = compositor_id;
}

void BrowserViewRenderer::SetDipScale(float dip_scale) {
  dip_scale_ = dip_scale;
  CHECK_GT(dip_scale_, 0.f);
}

gfx::Vector2d BrowserViewRenderer::max_scroll_offset() const {
  DCHECK_GT(dip_scale_, 0.f);
  return gfx::ToCeiledVector2d(gfx::ScaleVector2d(
      max_scroll_offset_dip_, dip_scale_ * page_scale_factor_));
}

void BrowserViewRenderer::ScrollTo(const gfx::Vector2d& scroll_offset) {
  gfx::Vector2d max_offset = max_scroll_offset();
  gfx::Vector2dF scroll_offset_dip;
  // To preserve the invariant that scrolling to the maximum physical pixel
  // value also scrolls to the maximum dip pixel value we transform the physical
  // offset into the dip offset by using a proportion (instead of dividing by
  // dip_scale * page_scale_factor).
  if (max_offset.x()) {
    scroll_offset_dip.set_x((scroll_offset.x() * max_scroll_offset_dip_.x()) /
                            max_offset.x());
  }
  if (max_offset.y()) {
    scroll_offset_dip.set_y((scroll_offset.y() * max_scroll_offset_dip_.y()) /
                            max_offset.y());
  }

  DCHECK_LE(0.f, scroll_offset_dip.x());
  DCHECK_LE(0.f, scroll_offset_dip.y());
  DCHECK(scroll_offset_dip.x() < max_scroll_offset_dip_.x() ||
         scroll_offset_dip.x() - max_scroll_offset_dip_.x() < kEpsilon)
      << scroll_offset_dip.x() << " " << max_scroll_offset_dip_.x();
  DCHECK(scroll_offset_dip.y() < max_scroll_offset_dip_.y() ||
         scroll_offset_dip.y() - max_scroll_offset_dip_.y() < kEpsilon)
      << scroll_offset_dip.y() << " " << max_scroll_offset_dip_.y();

  if (scroll_offset_dip_ == scroll_offset_dip)
    return;

  scroll_offset_dip_ = scroll_offset_dip;

  TRACE_EVENT_INSTANT2("android_webview",
               "BrowserViewRenderer::ScrollTo",
               TRACE_EVENT_SCOPE_THREAD,
               "x",
               scroll_offset_dip.x(),
               "y",
               scroll_offset_dip.y());

  if (compositor_) {
    compositor_->DidChangeRootLayerScrollOffset(
        gfx::ScrollOffset(scroll_offset_dip_));
  }
}

void BrowserViewRenderer::DidUpdateContent(
    content::SynchronousCompositor* compositor) {
  TRACE_EVENT_INSTANT0("android_webview",
                       "BrowserViewRenderer::DidUpdateContent",
                       TRACE_EVENT_SCOPE_THREAD);
  if (compositor != compositor_)
    return;

  clear_view_ = false;
  if (on_new_picture_enable_)
    client_->OnNewPicture();
}

void BrowserViewRenderer::SetTotalRootLayerScrollOffset(
    const gfx::Vector2dF& scroll_offset_dip) {
  if (scroll_offset_dip_ == scroll_offset_dip)
    return;
  scroll_offset_dip_ = scroll_offset_dip;

  gfx::Vector2d max_offset = max_scroll_offset();
  gfx::Vector2d scroll_offset;
  // For an explanation as to why this is done this way see the comment in
  // BrowserViewRenderer::ScrollTo.
  if (max_scroll_offset_dip_.x()) {
    scroll_offset.set_x((scroll_offset_dip.x() * max_offset.x()) /
                        max_scroll_offset_dip_.x());
  }

  if (max_scroll_offset_dip_.y()) {
    scroll_offset.set_y((scroll_offset_dip.y() * max_offset.y()) /
                        max_scroll_offset_dip_.y());
  }

  DCHECK_LE(0, scroll_offset.x());
  DCHECK_LE(0, scroll_offset.y());
  DCHECK_LE(scroll_offset.x(), max_offset.x());
  DCHECK_LE(scroll_offset.y(), max_offset.y());

  client_->ScrollContainerViewTo(scroll_offset);
}

void BrowserViewRenderer::UpdateRootLayerState(
    content::SynchronousCompositor* compositor,
    const gfx::Vector2dF& total_scroll_offset_dip,
    const gfx::Vector2dF& max_scroll_offset_dip,
    const gfx::SizeF& scrollable_size_dip,
    float page_scale_factor,
    float min_page_scale_factor,
    float max_page_scale_factor) {
  if (compositor != compositor_)
    return;

  TRACE_EVENT_INSTANT1(
      "android_webview",
      "BrowserViewRenderer::UpdateRootLayerState",
      TRACE_EVENT_SCOPE_THREAD,
      "state",
      RootLayerStateAsValue(total_scroll_offset_dip, scrollable_size_dip));

  DCHECK_GE(max_scroll_offset_dip.x(), 0.f);
  DCHECK_GE(max_scroll_offset_dip.y(), 0.f);
  DCHECK_GT(page_scale_factor, 0.f);
  // SetDipScale should have been called at least once before this is called.
  DCHECK_GT(dip_scale_, 0.f);

  if (max_scroll_offset_dip_ != max_scroll_offset_dip ||
      scrollable_size_dip_ != scrollable_size_dip ||
      page_scale_factor_ != page_scale_factor ||
      min_page_scale_factor_ != min_page_scale_factor ||
      max_page_scale_factor_ != max_page_scale_factor) {
    max_scroll_offset_dip_ = max_scroll_offset_dip;
    scrollable_size_dip_ = scrollable_size_dip;
    page_scale_factor_ = page_scale_factor;
    min_page_scale_factor_ = min_page_scale_factor;
    max_page_scale_factor_ = max_page_scale_factor;

    client_->UpdateScrollState(max_scroll_offset(), scrollable_size_dip,
                               page_scale_factor, min_page_scale_factor,
                               max_page_scale_factor);
  }
  SetTotalRootLayerScrollOffset(total_scroll_offset_dip);
}

std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
BrowserViewRenderer::RootLayerStateAsValue(
    const gfx::Vector2dF& total_scroll_offset_dip,
    const gfx::SizeF& scrollable_size_dip) {
  std::unique_ptr<base::trace_event::TracedValue> state(
      new base::trace_event::TracedValue());

  state->SetDouble("total_scroll_offset_dip.x", total_scroll_offset_dip.x());
  state->SetDouble("total_scroll_offset_dip.y", total_scroll_offset_dip.y());

  state->SetDouble("max_scroll_offset_dip.x", max_scroll_offset_dip_.x());
  state->SetDouble("max_scroll_offset_dip.y", max_scroll_offset_dip_.y());

  state->SetDouble("scrollable_size_dip.width", scrollable_size_dip.width());
  state->SetDouble("scrollable_size_dip.height", scrollable_size_dip.height());

  state->SetDouble("page_scale_factor", page_scale_factor_);
  return std::move(state);
}

void BrowserViewRenderer::DidOverscroll(
    content::SynchronousCompositor* compositor,
    const gfx::Vector2dF& accumulated_overscroll,
    const gfx::Vector2dF& latest_overscroll_delta,
    const gfx::Vector2dF& current_fling_velocity) {
  if (compositor != compositor_)
    return;

  const float physical_pixel_scale = dip_scale_ * page_scale_factor_;
  if (accumulated_overscroll == latest_overscroll_delta)
    overscroll_rounding_error_ = gfx::Vector2dF();
  gfx::Vector2dF scaled_overscroll_delta =
      gfx::ScaleVector2d(latest_overscroll_delta, physical_pixel_scale);
  gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d(
      scaled_overscroll_delta + overscroll_rounding_error_);
  overscroll_rounding_error_ =
      scaled_overscroll_delta - rounded_overscroll_delta;
  gfx::Vector2dF fling_velocity_pixels =
      gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale);

  client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels);
}

ui::TouchHandleDrawable* BrowserViewRenderer::CreateDrawable() {
  return client_->CreateDrawable();
}

void BrowserViewRenderer::PostInvalidate(
    content::SynchronousCompositor* compositor) {
  TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate",
                       TRACE_EVENT_SCOPE_THREAD);
  if (compositor != compositor_)
    return;

  client_->PostInvalidate();
}

bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) {
  DCHECK(compositor_);
  return compositor_->DemandDrawSw(canvas);
}

std::string BrowserViewRenderer::ToString() const {
  std::string str;
  base::StringAppendF(&str, "is_paused: %d ", is_paused_);
  base::StringAppendF(&str, "view_visible: %d ", view_visible_);
  base::StringAppendF(&str, "window_visible: %d ", window_visible_);
  base::StringAppendF(&str, "dip_scale: %f ", dip_scale_);
  base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_);
  base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str());
  base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_);
  base::StringAppendF(&str,
                      "global visible rect: %s ",
                      last_on_draw_global_visible_rect_.ToString().c_str());
  base::StringAppendF(
      &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str());
  base::StringAppendF(&str,
                      "overscroll_rounding_error_: %s ",
                      overscroll_rounding_error_.ToString().c_str());
  base::StringAppendF(
      &str, "on_new_picture_enable: %d ", on_new_picture_enable_);
  base::StringAppendF(&str, "clear_view: %d ", clear_view_);
  return str;
}

}  // namespace android_webview
