// Copyright (c) 2012 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 "content/renderer/gpu_benchmarking_extension.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/command_line.h"
#include "base/debug/profiler.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "cc/layers/layer.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/trees/layer_tree_host.h"
#include "content/common/input/actions_parser.h"
#include "content/common/input/synthetic_gesture_params.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
#include "content/common/input/synthetic_pointer_action_list_params.h"
#include "content/common/input/synthetic_pointer_action_params.h"
#include "content/common/input/synthetic_smooth_drag_gesture_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input/synthetic_tap_gesture_params.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/chrome_object_extensions_utils.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/v8_value_converter.h"
#include "content/renderer/compositor/layer_tree_view.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/skia_benchmarking_extension.h"
#include "gin/arguments.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/ipc/common/gpu_messages.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_image_cache.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/docs/SkXPSDocument.h"
// Note that headers in third_party/skia/src are fragile.  This is
// an experimental, fragile, and diagnostic-only document type.
#include "third_party/skia/src/utils/SkMultiPictureDocument.h"
#include "ui/events/base_event_utils.h"
#include "v8/include/v8.h"

#if defined(OS_WIN) && !defined(NDEBUG)
// XpsObjectModel.h indirectly includes <wincrypt.h> which is
// incompatible with Chromium's OpenSSL. By including wincrypt_shim.h
// first, problems are avoided.
#include "base/win/wincrypt_shim.h"

#include <XpsObjectModel.h>
#include <objbase.h>
#include <wrl/client.h>
#endif

using blink::WebImageCache;
using blink::WebLocalFrame;
using blink::WebPrivatePtr;
using blink::WebSize;
using blink::WebView;

namespace content {

namespace {
class SkPictureSerializer {
 public:
  explicit SkPictureSerializer(const base::FilePath& dirpath)
      : dirpath_(dirpath), layer_id_(0) {
    // Let skia register known effect subclasses. This basically enables
    // reflection on those subclasses required for picture serialization.
    SkiaBenchmarking::Initialize();
  }

  // Recursively serializes the layer tree.
  // Each layer in the tree is serialized into a separate skp file
  // in the given directory.
  void Serialize(const cc::Layer* root_layer) {
    for (auto* layer : *root_layer->layer_tree_host()) {
      sk_sp<SkPicture> picture = layer->GetPicture();
      if (!picture)
        continue;

      // Serialize picture to file.
      // TODO(alokp): Note that for this to work Chrome needs to be launched
      // with
      // --no-sandbox command-line flag. Get rid of this limitation.
      // CRBUG: 139640.
      std::string filename = "layer_" + base::IntToString(layer_id_++) + ".skp";
      std::string filepath = dirpath_.AppendASCII(filename).MaybeAsASCII();
      DCHECK(!filepath.empty());
      SkFILEWStream file(filepath.c_str());
      DCHECK(file.isValid());

      auto data = picture->serialize();
      file.write(data->data(), data->size());
      file.fsync();
    }
  }

 private:
  base::FilePath dirpath_;
  int layer_id_;
};

template <typename T>
bool GetArg(gin::Arguments* args, T* value) {
  if (!args->GetNext(value)) {
    args->ThrowError();
    return false;
  }
  return true;
}

template <>
bool GetArg(gin::Arguments* args, int* value) {
  float number;
  bool ret = GetArg(args, &number);
  *value = number;
  return ret;
}

template <typename T>
bool GetOptionalArg(gin::Arguments* args, T* value) {
  if (args->PeekNext().IsEmpty())
    return true;
  if (args->PeekNext()->IsUndefined()) {
    args->Skip();
    return true;
  }
  return GetArg(args, value);
}

class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
 public:
  CallbackAndContext(v8::Isolate* isolate,
                     v8::Local<v8::Function> callback,
                     v8::Local<v8::Context> context)
      : isolate_(isolate) {
    callback_.Reset(isolate_, callback);
    context_.Reset(isolate_, context);
  }

  v8::Isolate* isolate() { return isolate_; }

  v8::Local<v8::Function> GetCallback() {
    return v8::Local<v8::Function>::New(isolate_, callback_);
  }

  v8::Local<v8::Context> GetContext() {
    return v8::Local<v8::Context>::New(isolate_, context_);
  }

 private:
  friend class base::RefCounted<CallbackAndContext>;

  virtual ~CallbackAndContext() {
    callback_.Reset();
    context_.Reset();
  }

  v8::Isolate* isolate_;
  v8::Persistent<v8::Function> callback_;
  v8::Persistent<v8::Context> context_;
  DISALLOW_COPY_AND_ASSIGN(CallbackAndContext);
};

class GpuBenchmarkingContext {
 public:
  GpuBenchmarkingContext() = default;

  bool Init(bool init_compositor) {
    web_frame_ = WebLocalFrame::FrameForCurrentContext();
    if (!web_frame_)
      return false;

    web_view_ = web_frame_->View();
    if (!web_view_) {
      web_frame_ = nullptr;
      return false;
    }

    render_view_impl_ = RenderViewImpl::FromWebView(web_view_);
    if (!render_view_impl_) {
      web_frame_ = nullptr;
      web_view_ = nullptr;
      return false;
    }

    if (!init_compositor)
      return true;

    layer_tree_view_ = render_view_impl_->GetWidget()->layer_tree_view();
    if (!layer_tree_view_) {
      web_frame_ = nullptr;
      web_view_ = nullptr;
      render_view_impl_ = nullptr;
      return false;
    }

    return true;
  }

  WebLocalFrame* web_frame() const {
    DCHECK(web_frame_ != nullptr);
    return web_frame_;
  }
  WebView* web_view() const {
    DCHECK(web_view_ != nullptr);
    return web_view_;
  }
  RenderViewImpl* render_view_impl() const {
    DCHECK(render_view_impl_ != nullptr);
    return render_view_impl_;
  }
  LayerTreeView* layer_tree_view() const {
    DCHECK(layer_tree_view_ != nullptr);
    return layer_tree_view_;
  }

 private:
  WebLocalFrame* web_frame_ = nullptr;
  WebView* web_view_ = nullptr;
  RenderViewImpl* render_view_impl_ = nullptr;
  LayerTreeView* layer_tree_view_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(GpuBenchmarkingContext);
};

void OnMicroBenchmarkCompleted(CallbackAndContext* callback_and_context,
                               std::unique_ptr<base::Value> result) {
  v8::Isolate* isolate = callback_and_context->isolate();
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = callback_and_context->GetContext();
  v8::Context::Scope context_scope(context);
  WebLocalFrame* frame = WebLocalFrame::FrameForContext(context);
  if (frame) {
    v8::Local<v8::Value> value =
        V8ValueConverter::Create()->ToV8Value(result.get(), context);
    v8::Local<v8::Value> argv[] = {value};

    frame->CallFunctionEvenIfScriptDisabled(callback_and_context->GetCallback(),
                                            v8::Object::New(isolate), 1, argv);
  }
}

void OnSyntheticGestureCompleted(CallbackAndContext* callback_and_context) {
  v8::Isolate* isolate = callback_and_context->isolate();
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = callback_and_context->GetContext();
  v8::Context::Scope context_scope(context);
  v8::Local<v8::Function> callback = callback_and_context->GetCallback();
  WebLocalFrame* frame = WebLocalFrame::FrameForContext(context);
  if (frame && !callback.IsEmpty()) {
    frame->CallFunctionEvenIfScriptDisabled(callback, v8::Object::New(isolate),
                                            0, nullptr);
  }
}

bool BeginSmoothScroll(GpuBenchmarkingContext* context,
                       gin::Arguments* args,
                       mojom::InputInjectorPtr& injector,
                       float pixels_to_scroll,
                       v8::Local<v8::Function> callback,
                       int gesture_source_type,
                       const std::string& direction,
                       float speed_in_pixels_s,
                       bool prevent_fling,
                       float start_x,
                       float start_y,
                       float fling_velocity,
                       bool precise_scrolling_deltas,
                       bool scroll_by_page,
                       bool cursor_visible) {
  gfx::Rect rect = context->render_view_impl()->GetWidget()->ViewRect();
  rect -= rect.OffsetFromOrigin();
  if (!rect.Contains(start_x, start_y)) {
    args->ThrowTypeError("Start point not in bounds");
    return false;
  }

  if (gesture_source_type == SyntheticGestureParams::MOUSE_INPUT) {
    // Ensure the mouse is visible and move to start position, in case it will
    // trigger any hover or mousemove effects.
    context->web_view()->SetIsActive(true);
    blink::WebMouseEvent mouseMove(blink::WebInputEvent::kMouseMove,
                                   blink::WebInputEvent::kNoModifiers,
                                   ui::EventTimeForNow());
    mouseMove.SetPositionInWidget(start_x, start_y);
    context->web_view()->MainFrameWidget()->HandleInputEvent(
        blink::WebCoalescedInputEvent(mouseMove));
    context->web_view()->MainFrameWidget()->SetCursorVisibilityState(
        cursor_visible);
  }

  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context->web_frame()->MainWorldScriptContext());

  SyntheticSmoothScrollGestureParams gesture_params;

  if (gesture_source_type < 0 ||
      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
    return false;
  }
  gesture_params.gesture_source_type =
      static_cast<SyntheticGestureParams::GestureSourceType>(
          gesture_source_type);

  gesture_params.speed_in_pixels_s = speed_in_pixels_s;
  gesture_params.prevent_fling = prevent_fling;
  gesture_params.precise_scrolling_deltas = precise_scrolling_deltas;
  gesture_params.scroll_by_page = scroll_by_page;

  gesture_params.anchor.SetPoint(start_x, start_y);

  DCHECK(gesture_source_type != SyntheticGestureParams::TOUCH_INPUT ||
         fling_velocity == 0);
  float distance_length = pixels_to_scroll;
  gfx::Vector2dF distance;
  if (direction == "down") {
    distance.set_y(-distance_length);
    gesture_params.fling_velocity_y = fling_velocity;
  } else if (direction == "up") {
    distance.set_y(distance_length);
    gesture_params.fling_velocity_y = -fling_velocity;
  } else if (direction == "right") {
    distance.set_x(-distance_length);
    gesture_params.fling_velocity_x = fling_velocity;
  } else if (direction == "left") {
    distance.set_x(distance_length);
    gesture_params.fling_velocity_x = -fling_velocity;
  } else if (direction == "upleft") {
    distance.set_y(distance_length);
    distance.set_x(distance_length);
    gesture_params.fling_velocity_x = -fling_velocity;
    gesture_params.fling_velocity_y = -fling_velocity;
  } else if (direction == "upright") {
    distance.set_y(distance_length);
    distance.set_x(-distance_length);
    gesture_params.fling_velocity_x = fling_velocity;
    gesture_params.fling_velocity_y = -fling_velocity;
  } else if (direction == "downleft") {
    distance.set_y(-distance_length);
    distance.set_x(distance_length);
    gesture_params.fling_velocity_x = -fling_velocity;
    gesture_params.fling_velocity_y = fling_velocity;
  } else if (direction == "downright") {
    distance.set_y(-distance_length);
    distance.set_x(-distance_length);
    gesture_params.fling_velocity_x = fling_velocity;
    gesture_params.fling_velocity_y = fling_velocity;
  } else {
    return false;
  }
  gesture_params.distances.push_back(distance);

  injector->QueueSyntheticSmoothScroll(
      gesture_params, base::BindOnce(&OnSyntheticGestureCompleted,
                                     base::RetainedRef(callback_and_context)));

  return true;
}

bool BeginSmoothDrag(GpuBenchmarkingContext* context,
                     gin::Arguments* args,
                     mojom::InputInjectorPtr& injector,
                     float start_x,
                     float start_y,
                     float end_x,
                     float end_y,
                     v8::Local<v8::Function> callback,
                     int gesture_source_type,
                     float speed_in_pixels_s) {
  gfx::Rect rect = context->render_view_impl()->GetWidget()->ViewRect();
  rect -= rect.OffsetFromOrigin();
  if (!rect.Contains(start_x, start_y)) {
    args->ThrowTypeError("Start point not in bounds");
    return false;
  }
  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context->web_frame()->MainWorldScriptContext());

  SyntheticSmoothDragGestureParams gesture_params;

  gesture_params.start_point.SetPoint(start_x, start_y);
  gfx::PointF end_point(end_x, end_y);
  gfx::Vector2dF distance = end_point - gesture_params.start_point;
  gesture_params.distances.push_back(distance);
  gesture_params.speed_in_pixels_s = speed_in_pixels_s;
  gesture_params.gesture_source_type =
      static_cast<SyntheticGestureParams::GestureSourceType>(
          gesture_source_type);

  injector->QueueSyntheticSmoothDrag(
      gesture_params, base::BindOnce(&OnSyntheticGestureCompleted,
                                     base::RetainedRef(callback_and_context)));

  return true;
}

static void PrintDocument(blink::WebLocalFrame* frame, SkDocument* doc) {
  const float kPageWidth = 612.0f;   // 8.5 inch
  const float kPageHeight = 792.0f;  // 11 inch
  const float kMarginTop = 29.0f;    // 0.40 inch
  const float kMarginLeft = 29.0f;   // 0.40 inch
  const int kContentWidth = 555;     // 7.71 inch
  const int kContentHeight = 735;    // 10.21 inch
  blink::WebPrintParams params(blink::WebSize(kContentWidth, kContentHeight));
  params.printer_dpi = 300;
  int page_count = frame->PrintBegin(params);
  for (int i = 0; i < page_count; ++i) {
    SkCanvas* sk_canvas = doc->beginPage(kPageWidth, kPageHeight);
    cc::SkiaPaintCanvas canvas(sk_canvas);
    cc::PaintCanvasAutoRestore auto_restore(&canvas, true);
    canvas.translate(kMarginLeft, kMarginTop);

#if defined(OS_WIN) || defined(OS_MACOSX)
    float page_shrink = frame->GetPrintPageShrink(i);
    DCHECK_GT(page_shrink, 0);
    canvas.scale(page_shrink, page_shrink);
#endif

    frame->PrintPage(i, &canvas);
  }
  frame->PrintEnd();
}

static void PrintDocumentTofile(v8::Isolate* isolate,
                                const std::string& filename,
                                sk_sp<SkDocument> (*make_doc)(SkWStream*)) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return;

  base::FilePath path = base::FilePath::FromUTF8Unsafe(filename);
  if (!base::PathIsWritable(path.DirName())) {
    std::string msg("Path is not writable: ");
    msg.append(path.DirName().MaybeAsASCII());
    isolate->ThrowException(v8::Exception::Error(
        v8::String::NewFromUtf8(isolate, msg.c_str(),
                                v8::NewStringType::kNormal, msg.length())
            .ToLocalChecked()));
    return;
  }
  SkFILEWStream wStream(path.MaybeAsASCII().c_str());
  sk_sp<SkDocument> doc = make_doc(&wStream);
  if (doc) {
    context.web_frame()->View()->GetSettings()->SetShouldPrintBackgrounds(true);
    PrintDocument(context.web_frame(), doc.get());
    doc->close();
  }
}

// This function is only used for correctness testing of this experimental
// feature; no need for it in release builds.
// Also note:  You must execute Chrome with `--no-sandbox` and
// `--enable-gpu-benchmarking` for this to work.
#if defined(OS_WIN) && !defined(NDEBUG)
static sk_sp<SkDocument> MakeXPSDocument(SkWStream* s) {
  // I am not sure why this hasn't been initialized yet.
  (void)CoInitializeEx(nullptr,
                       COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
  // In non-sandboxed mode, we will need to create and hold on to the
  // factory before entering the sandbox.
  Microsoft::WRL::ComPtr<IXpsOMObjectFactory> factory;
  HRESULT hr = ::CoCreateInstance(CLSID_XpsOMObjectFactory, nullptr,
                                  CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory));
  if (FAILED(hr) || !factory) {
    LOG(ERROR) << "CoCreateInstance(CLSID_XpsOMObjectFactory, ...) failed:"
               << logging::SystemErrorCodeToString(hr);
  }
  return SkXPS::MakeDocument(s, factory.Get());
}
#endif
}  // namespace

gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin};

// static
void GpuBenchmarking::Install(RenderFrameImpl* frame) {
  v8::Isolate* isolate = blink::MainThreadIsolate();
  v8::HandleScope handle_scope(isolate);
  v8::Local<v8::Context> context =
      frame->GetWebFrame()->MainWorldScriptContext();
  if (context.IsEmpty())
    return;

  v8::Context::Scope context_scope(context);

  gin::Handle<GpuBenchmarking> controller =
      gin::CreateHandle(isolate, new GpuBenchmarking(frame));
  if (controller.IsEmpty())
    return;

  v8::Local<v8::Object> chrome =
      GetOrCreateChromeObject(isolate, context->Global());
  chrome->Set(gin::StringToV8(isolate, "gpuBenchmarking"), controller.ToV8());
}

GpuBenchmarking::GpuBenchmarking(RenderFrameImpl* frame)
    : render_frame_(frame) {}

GpuBenchmarking::~GpuBenchmarking() {}

void GpuBenchmarking::EnsureRemoteInterface() {
  if (!input_injector_) {
    render_frame_->GetRemoteInterfaces()->GetInterface(mojo::MakeRequest(
        &input_injector_,
        render_frame_->GetTaskRunner(blink::TaskType::kInternalDefault)));
  }
}

gin::ObjectTemplateBuilder GpuBenchmarking::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  return gin::Wrappable<GpuBenchmarking>::GetObjectTemplateBuilder(isolate)
      .SetMethod("setNeedsDisplayOnAllLayers",
                 &GpuBenchmarking::SetNeedsDisplayOnAllLayers)
      .SetMethod("setRasterizeOnlyVisibleContent",
                 &GpuBenchmarking::SetRasterizeOnlyVisibleContent)
      .SetMethod("printToSkPicture", &GpuBenchmarking::PrintToSkPicture)
      .SetMethod("printPagesToSkPictures",
                 &GpuBenchmarking::PrintPagesToSkPictures)
      .SetMethod("printPagesToXPS", &GpuBenchmarking::PrintPagesToXPS)
      .SetValue("DEFAULT_INPUT", 0)
      .SetValue("TOUCH_INPUT", 1)
      .SetValue("MOUSE_INPUT", 2)
      .SetMethod("gestureSourceTypeSupported",
                 &GpuBenchmarking::GestureSourceTypeSupported)
      .SetMethod("smoothScrollBy", &GpuBenchmarking::SmoothScrollBy)
      .SetMethod("smoothDrag", &GpuBenchmarking::SmoothDrag)
      .SetMethod("swipe", &GpuBenchmarking::Swipe)
      .SetMethod("scrollBounce", &GpuBenchmarking::ScrollBounce)
      .SetMethod("pinchBy", &GpuBenchmarking::PinchBy)
      .SetMethod("pageScaleFactor", &GpuBenchmarking::PageScaleFactor)
      .SetMethod("setPageScaleFactor", &GpuBenchmarking::SetPageScaleFactor)
      .SetMethod("setBrowserControlsShown",
                 &GpuBenchmarking::SetBrowserControlsShown)
      .SetMethod("tap", &GpuBenchmarking::Tap)
      .SetMethod("pointerActionSequence",
                 &GpuBenchmarking::PointerActionSequence)
      .SetMethod("visualViewportX", &GpuBenchmarking::VisualViewportX)
      .SetMethod("visualViewportY", &GpuBenchmarking::VisualViewportY)
      .SetMethod("visualViewportHeight", &GpuBenchmarking::VisualViewportHeight)
      .SetMethod("visualViewportWidth", &GpuBenchmarking::VisualViewportWidth)
      .SetMethod("clearImageCache", &GpuBenchmarking::ClearImageCache)
      .SetMethod("runMicroBenchmark", &GpuBenchmarking::RunMicroBenchmark)
      .SetMethod("sendMessageToMicroBenchmark",
                 &GpuBenchmarking::SendMessageToMicroBenchmark)
      .SetMethod("hasGpuChannel", &GpuBenchmarking::HasGpuChannel)
      .SetMethod("hasGpuProcess", &GpuBenchmarking::HasGpuProcess)
      .SetMethod("crashGpuProcess", &GpuBenchmarking::CrashGpuProcess)
      .SetMethod("getGpuDriverBugWorkarounds",
                 &GpuBenchmarking::GetGpuDriverBugWorkarounds)
      .SetMethod("startProfiling", &GpuBenchmarking::StartProfiling)
      .SetMethod("stopProfiling", &GpuBenchmarking::StopProfiling)
      .SetMethod("freeze", &GpuBenchmarking::Freeze);
}

void GpuBenchmarking::SetNeedsDisplayOnAllLayers() {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return;

  context.layer_tree_view()->SetNeedsDisplayOnAllLayers();
}

void GpuBenchmarking::SetRasterizeOnlyVisibleContent() {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return;

  context.layer_tree_view()->SetRasterizeOnlyVisibleContent();
}

namespace {
sk_sp<SkDocument> make_multipicturedocument(SkWStream* stream) {
  return SkMakeMultiPictureDocument(stream);
}
}  // namespace
void GpuBenchmarking::PrintPagesToSkPictures(v8::Isolate* isolate,
                                             const std::string& filename) {
  PrintDocumentTofile(isolate, filename, &make_multipicturedocument);
}

void GpuBenchmarking::PrintPagesToXPS(v8::Isolate* isolate,
                                      const std::string& filename) {
#if defined(OS_WIN) && !defined(NDEBUG)
  PrintDocumentTofile(isolate, filename, &MakeXPSDocument);
#else
  std::string msg("PrintPagesToXPS is unsupported.");
  isolate->ThrowException(v8::Exception::Error(
      v8::String::NewFromUtf8(isolate, msg.c_str(), v8::NewStringType::kNormal,
                              msg.length())
          .ToLocalChecked()));
#endif
}

void GpuBenchmarking::PrintToSkPicture(v8::Isolate* isolate,
                                       const std::string& dirname) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return;

  const cc::Layer* root_layer = context.layer_tree_view()->GetRootLayer();
  if (!root_layer)
    return;

  base::FilePath dirpath = base::FilePath::FromUTF8Unsafe(dirname);
  if (!base::CreateDirectory(dirpath) || !base::PathIsWritable(dirpath)) {
    std::string msg("Path is not writable: ");
    msg.append(dirpath.MaybeAsASCII());
    isolate->ThrowException(v8::Exception::Error(
        v8::String::NewFromUtf8(isolate, msg.c_str(),
                                v8::NewStringType::kNormal, msg.length())
            .ToLocalChecked()));
    return;
  }

  SkPictureSerializer serializer(dirpath);
  serializer.Serialize(root_layer);
}

bool GpuBenchmarking::GestureSourceTypeSupported(int gesture_source_type) {
  if (gesture_source_type < 0 ||
      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
    return false;
  }

  return SyntheticGestureParams::IsGestureSourceTypeSupported(
      static_cast<SyntheticGestureParams::GestureSourceType>(
          gesture_source_type));
}

bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return false;

  blink::WebRect rect = context.render_view_impl()->GetWidget()->ViewRect();

  float pixels_to_scroll = 0;
  v8::Local<v8::Function> callback;
  float start_x = rect.width / 2;
  float start_y = rect.height / 2;
  int gesture_source_type = SyntheticGestureParams::DEFAULT_INPUT;
  std::string direction = "down";
  float speed_in_pixels_s = 800;
  bool precise_scrolling_deltas = true;
  bool scroll_by_page = false;
  bool cursor_visible = true;

  if (!GetOptionalArg(args, &pixels_to_scroll) ||
      !GetOptionalArg(args, &callback) || !GetOptionalArg(args, &start_x) ||
      !GetOptionalArg(args, &start_y) ||
      !GetOptionalArg(args, &gesture_source_type) ||
      !GetOptionalArg(args, &direction) ||
      !GetOptionalArg(args, &speed_in_pixels_s) ||
      !GetOptionalArg(args, &precise_scrolling_deltas) ||
      !GetOptionalArg(args, &scroll_by_page) ||
      !GetOptionalArg(args, &cursor_visible)) {
    return false;
  }

  // For all touch inputs, always scroll by precise deltas.
  DCHECK(gesture_source_type != SyntheticGestureParams::TOUCH_INPUT ||
         precise_scrolling_deltas);
  // Scroll by page only for mouse inputs.
  DCHECK(!scroll_by_page ||
         gesture_source_type == SyntheticGestureParams::MOUSE_INPUT);

  EnsureRemoteInterface();
  return BeginSmoothScroll(
      &context, args, input_injector_, pixels_to_scroll, callback,
      gesture_source_type, direction, speed_in_pixels_s, true, start_x, start_y,
      0, precise_scrolling_deltas, scroll_by_page, cursor_visible);
}

bool GpuBenchmarking::SmoothDrag(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return false;

  float start_x;
  float start_y;
  float end_x;
  float end_y;
  v8::Local<v8::Function> callback;
  int gesture_source_type = SyntheticGestureParams::DEFAULT_INPUT;
  float speed_in_pixels_s = 800;

  if (!GetArg(args, &start_x) || !GetArg(args, &start_y) ||
      !GetArg(args, &end_x) || !GetArg(args, &end_y) ||
      !GetOptionalArg(args, &callback) ||
      !GetOptionalArg(args, &gesture_source_type) ||
      !GetOptionalArg(args, &speed_in_pixels_s)) {
    return false;
  }

  EnsureRemoteInterface();
  return BeginSmoothDrag(&context, args, input_injector_, start_x, start_y,
                         end_x, end_y, callback, gesture_source_type,
                         speed_in_pixels_s);
}

bool GpuBenchmarking::Swipe(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return false;

  blink::WebRect rect = context.render_view_impl()->GetWidget()->ViewRect();

  std::string direction = "up";
  float pixels_to_scroll = 0;
  v8::Local<v8::Function> callback;
  float start_x = rect.width / 2;
  float start_y = rect.height / 2;
  float speed_in_pixels_s = 800;
  float fling_velocity = 0;
  int gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;

  if (!GetOptionalArg(args, &direction) ||
      !GetOptionalArg(args, &pixels_to_scroll) ||
      !GetOptionalArg(args, &callback) || !GetOptionalArg(args, &start_x) ||
      !GetOptionalArg(args, &start_y) ||
      !GetOptionalArg(args, &speed_in_pixels_s) ||
      !GetOptionalArg(args, &fling_velocity) ||
      !GetOptionalArg(args, &gesture_source_type)) {
    return false;
  }

  // For touchpad swipe, we should be given a fling velocity, but it is not
  // needed for touchscreen swipe, because we will calculate the velocity in
  // our code.
  if (gesture_source_type == SyntheticGestureParams::TOUCHPAD_INPUT &&
      fling_velocity == 0)
    fling_velocity = 1000;

  EnsureRemoteInterface();
  return BeginSmoothScroll(
      &context, args, input_injector_, -pixels_to_scroll, callback,
      gesture_source_type, direction, speed_in_pixels_s, false, start_x,
      start_y, fling_velocity, true /* precise_scrolling_deltas */,
      false /* scroll_by_page */, true /* cursor_visible */);
}

bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return false;

  blink::WebRect content_rect =
      context.render_view_impl()->GetWidget()->ViewRect();

  std::string direction = "down";
  float distance_length = 0;
  float overscroll_length = 0;
  int repeat_count = 1;
  v8::Local<v8::Function> callback;
  float start_x = content_rect.width / 2;
  float start_y = content_rect.height / 2;
  float speed_in_pixels_s = 800;

  if (!GetOptionalArg(args, &direction) ||
      !GetOptionalArg(args, &distance_length) ||
      !GetOptionalArg(args, &overscroll_length) ||
      !GetOptionalArg(args, &repeat_count) ||
      !GetOptionalArg(args, &callback) || !GetOptionalArg(args, &start_x) ||
      !GetOptionalArg(args, &start_y) ||
      !GetOptionalArg(args, &speed_in_pixels_s)) {
    return false;
  }

  gfx::Rect rect = context.render_view_impl()->GetWidget()->ViewRect();
  rect -= rect.OffsetFromOrigin();
  if (!rect.Contains(start_x, start_y)) {
    args->ThrowTypeError("Start point not in bounds");
    return false;
  }

  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context.web_frame()->MainWorldScriptContext());

  SyntheticSmoothScrollGestureParams gesture_params;

  gesture_params.speed_in_pixels_s = speed_in_pixels_s;

  gesture_params.anchor.SetPoint(start_x, start_y);

  gfx::Vector2dF distance;
  gfx::Vector2dF overscroll;
  if (direction == "down") {
    distance.set_y(-distance_length);
    overscroll.set_y(overscroll_length);
  } else if (direction == "up") {
    distance.set_y(distance_length);
    overscroll.set_y(-overscroll_length);
  } else if (direction == "right") {
    distance.set_x(-distance_length);
    overscroll.set_x(overscroll_length);
  } else if (direction == "left") {
    distance.set_x(distance_length);
    overscroll.set_x(-overscroll_length);
  } else {
    return false;
  }

  for (int i = 0; i < repeat_count; i++) {
    gesture_params.distances.push_back(distance);
    gesture_params.distances.push_back(-distance + overscroll);
  }
  EnsureRemoteInterface();
  input_injector_->QueueSyntheticSmoothScroll(
      gesture_params, base::BindOnce(&OnSyntheticGestureCompleted,
                                     base::RetainedRef(callback_and_context)));

  return true;
}

bool GpuBenchmarking::PinchBy(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return false;

  float scale_factor;
  float anchor_x;
  float anchor_y;
  v8::Local<v8::Function> callback;
  float relative_pointer_speed_in_pixels_s = 800;
  int gesture_source_type = SyntheticGestureParams::DEFAULT_INPUT;

  if (!GetArg(args, &scale_factor) || !GetArg(args, &anchor_x) ||
      !GetArg(args, &anchor_y) || !GetOptionalArg(args, &callback) ||
      !GetOptionalArg(args, &relative_pointer_speed_in_pixels_s) ||
      !GetOptionalArg(args, &gesture_source_type)) {
    return false;
  }

  gfx::Rect rect = context.render_view_impl()->GetWidget()->ViewRect();
  rect -= rect.OffsetFromOrigin();
  if (!rect.Contains(anchor_x, anchor_y)) {
    args->ThrowTypeError("Anchor point not in bounds");
    return false;
  }

  SyntheticPinchGestureParams gesture_params;

  gesture_params.scale_factor = scale_factor;
  gesture_params.anchor.SetPoint(anchor_x, anchor_y);
  gesture_params.relative_pointer_speed_in_pixels_s =
      relative_pointer_speed_in_pixels_s;

  if (gesture_source_type < 0 ||
      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
    args->ThrowTypeError("Unknown gesture source type");
    return false;
  }

  gesture_params.gesture_source_type =
      static_cast<SyntheticGestureParams::GestureSourceType>(
          gesture_source_type);

  switch (gesture_params.gesture_source_type) {
    case SyntheticGestureParams::DEFAULT_INPUT:
    case SyntheticGestureParams::TOUCH_INPUT:
    case SyntheticGestureParams::MOUSE_INPUT:
      break;
    case SyntheticGestureParams::PEN_INPUT:
      args->ThrowTypeError(
          "Gesture is not implemented for the given source type");
      return false;
  }

  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context.web_frame()->MainWorldScriptContext());
  EnsureRemoteInterface();
  input_injector_->QueueSyntheticPinch(
      gesture_params, base::BindOnce(&OnSyntheticGestureCompleted,
                                     base::RetainedRef(callback_and_context)));

  return true;
}

float GpuBenchmarking::PageScaleFactor() {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return 0.0;
  return context.web_view()->PageScaleFactor();
}

void GpuBenchmarking::SetPageScaleFactor(float scale) {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return;
  context.web_view()->SetPageScaleFactor(scale);
}

void GpuBenchmarking::SetBrowserControlsShown(bool show) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return;
  context.layer_tree_view()->UpdateBrowserControlsState(
      cc::BrowserControlsState::kBoth,
      show ? cc::BrowserControlsState::kShown
           : cc::BrowserControlsState::kHidden,
      false);
}

float GpuBenchmarking::VisualViewportY() {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return 0.0;
  float y = context.web_view()->VisualViewportOffset().y;
  blink::WebRect rect(0, y, 0, 0);
  context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
  return rect.y;
}

float GpuBenchmarking::VisualViewportX() {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return 0.0;
  float x = context.web_view()->VisualViewportOffset().x;
  blink::WebRect rect(x, 0, 0, 0);
  context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
  return rect.x;
}

float GpuBenchmarking::VisualViewportHeight() {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return 0.0;
  float height = context.web_view()->VisualViewportSize().height;
  blink::WebRect rect(0, 0, 0, height);
  context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
  return rect.height;
}

float GpuBenchmarking::VisualViewportWidth() {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return 0.0;
  float width = context.web_view()->VisualViewportSize().width;
  blink::WebRect rect(0, 0, width, 0);
  context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
  return rect.width;
}

bool GpuBenchmarking::Tap(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return false;

  float position_x;
  float position_y;
  v8::Local<v8::Function> callback;
  int duration_ms = 50;
  int gesture_source_type = SyntheticGestureParams::DEFAULT_INPUT;

  if (!GetArg(args, &position_x) || !GetArg(args, &position_y) ||
      !GetOptionalArg(args, &callback) || !GetOptionalArg(args, &duration_ms) ||
      !GetOptionalArg(args, &gesture_source_type)) {
    return false;
  }

  gfx::Rect rect = context.render_view_impl()->GetWidget()->ViewRect();
  rect -= rect.OffsetFromOrigin();
  if (!rect.Contains(position_x, position_y)) {
    args->ThrowTypeError("Start point not in bounds");
    return false;
  }

  SyntheticTapGestureParams gesture_params;

  gesture_params.position.SetPoint(position_x, position_y);
  gesture_params.duration_ms = duration_ms;

  if (gesture_source_type < 0 ||
      gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) {
    return false;
  }
  gesture_params.gesture_source_type =
      static_cast<SyntheticGestureParams::GestureSourceType>(
          gesture_source_type);

  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context.web_frame()->MainWorldScriptContext());
  EnsureRemoteInterface();
  input_injector_->QueueSyntheticTap(
      gesture_params, base::BindOnce(&OnSyntheticGestureCompleted,
                                     base::RetainedRef(callback_and_context)));

  return true;
}

bool GpuBenchmarking::PointerActionSequence(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(false))
    return false;

  v8::Local<v8::Function> callback;

  v8::Local<v8::Object> obj;
  if (!args->GetNext(&obj)) {
    args->ThrowError();
    return false;
  }

  v8::Local<v8::Context> v8_context =
      context.web_frame()->MainWorldScriptContext();
  std::unique_ptr<base::Value> value =
      V8ValueConverter::Create()->FromV8Value(obj, v8_context);

  // Get all the pointer actions from the user input and wrap them into a
  // SyntheticPointerActionListParams object.
  ActionsParser actions_parser(value.get());
  if (!actions_parser.ParsePointerActionSequence()) {
    // TODO(dtapuska): Throw an error here, some web tests start
    // failing when this is done though.
    // args->ThrowTypeError(actions_parser.error_message());
    return false;
  }

  if (!GetOptionalArg(args, &callback)) {
    args->ThrowError();
    return false;
  }

  // At the end, we will send a 'FINISH' action and need a callback.
  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context.web_frame()->MainWorldScriptContext());
  EnsureRemoteInterface();
  input_injector_->QueueSyntheticPointerAction(
      actions_parser.gesture_params(),
      base::BindOnce(&OnSyntheticGestureCompleted,
                     base::RetainedRef(callback_and_context)));
  return true;
}

void GpuBenchmarking::ClearImageCache() {
  WebImageCache::Clear();
}

int GpuBenchmarking::RunMicroBenchmark(gin::Arguments* args) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return 0;

  std::string name;
  v8::Local<v8::Function> callback;
  v8::Local<v8::Object> arguments;

  if (!GetArg(args, &name) || !GetArg(args, &callback) ||
      !GetOptionalArg(args, &arguments)) {
    return 0;
  }

  scoped_refptr<CallbackAndContext> callback_and_context =
      new CallbackAndContext(args->isolate(), callback,
                             context.web_frame()->MainWorldScriptContext());

  v8::Local<v8::Context> v8_context = callback_and_context->GetContext();
  std::unique_ptr<base::Value> value =
      V8ValueConverter::Create()->FromV8Value(arguments, v8_context);

  return context.layer_tree_view()->ScheduleMicroBenchmark(
      name, std::move(value),
      base::BindOnce(&OnMicroBenchmarkCompleted,
                     base::RetainedRef(callback_and_context)));
}

bool GpuBenchmarking::SendMessageToMicroBenchmark(
    int id,
    v8::Local<v8::Object> message) {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return false;

  v8::Local<v8::Context> v8_context =
      context.web_frame()->MainWorldScriptContext();
  std::unique_ptr<base::Value> value =
      V8ValueConverter::Create()->FromV8Value(message, v8_context);

  return context.layer_tree_view()->SendMessageToMicroBenchmark(
      id, std::move(value));
}

bool GpuBenchmarking::HasGpuChannel() {
  gpu::GpuChannelHost* gpu_channel =
      RenderThreadImpl::current()->GetGpuChannel();
  return !!gpu_channel;
}

bool GpuBenchmarking::HasGpuProcess() {
  bool has_gpu_process = false;
  if (!RenderThreadImpl::current()->render_message_filter()->HasGpuProcess(
          &has_gpu_process)) {
    return false;
  }
  return has_gpu_process;
}

void GpuBenchmarking::CrashGpuProcess() {
  gpu::GpuChannelHost* gpu_channel =
      RenderThreadImpl::current()->GetGpuChannel();
  if (!gpu_channel)
    return;
  gpu_channel->CrashGpuProcessForTesting();
}

void GpuBenchmarking::GetGpuDriverBugWorkarounds(gin::Arguments* args) {
  std::vector<std::string> gpu_driver_bug_workarounds;
  gpu::GpuChannelHost* gpu_channel =
      RenderThreadImpl::current()->GetGpuChannel();
  if (!gpu_channel)
    return;
  const gpu::GpuFeatureInfo& gpu_feature_info = gpu_channel->gpu_feature_info();
  const std::vector<int32_t>& workarounds =
      gpu_feature_info.enabled_gpu_driver_bug_workarounds;
  for (int32_t workaround : workarounds) {
    gpu_driver_bug_workarounds.push_back(
        gpu::GpuDriverBugWorkaroundTypeToString(
            static_cast<gpu::GpuDriverBugWorkaroundType>(workaround)));
  }

  // This code must be kept in sync with compositor_util's
  // GetDriverBugWorkaroundsImpl.
  for (auto ext :
       base::SplitString(gpu_feature_info.disabled_extensions, " ",
                         base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    gpu_driver_bug_workarounds.push_back("disabled_extension_" + ext);
  }
  for (auto ext :
       base::SplitString(gpu_feature_info.disabled_webgl_extensions, " ",
                         base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    gpu_driver_bug_workarounds.push_back("disabled_webgl_extension_" + ext);
  }

  v8::Local<v8::Value> result;
  if (gin::TryConvertToV8(args->isolate(), gpu_driver_bug_workarounds, &result))
    args->Return(result);
}

void GpuBenchmarking::StartProfiling(gin::Arguments* args) {
  if (base::debug::BeingProfiled())
    return;
  std::string file_name;
  if (!GetOptionalArg(args, &file_name))
    return;
  if (!file_name.length())
    file_name = "profile.pb";
  base::debug::StartProfiling(file_name);
  base::debug::RestartProfilingAfterFork();
}

void GpuBenchmarking::StopProfiling() {
  if (base::debug::BeingProfiled())
    base::debug::StopProfiling();
}

void GpuBenchmarking::Freeze() {
  GpuBenchmarkingContext context;
  if (!context.Init(true))
    return;
  // TODO(fmeawad): Instead of forcing a visibility change, only allow
  // freezing a page if it was already hidden.
  context.web_view()->SetIsHidden(/*hidden=*/true,
                                  /*is_initial_state=*/false);
  context.web_view()->SetPageFrozen(true);
}

}  // namespace content
