// 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/gpu/gpu_child_thread.h"

#include <stddef.h>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/lazy_instance.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_local.h"
#include "base/threading/worker_pool.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/establish_channel_params.h"
#include "content/common/gpu_host_messages.h"
#include "content/common/mojo/constants.h"
#include "content/gpu/gpu_service_factory.h"
#include "content/gpu/gpu_watchdog_thread.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/mojo_shell_connection.h"
#include "content/public/gpu/content_gpu_client.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_sync_message_filter.h"
#include "media/gpu/ipc/service/gpu_jpeg_decode_accelerator.h"
#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h"
#include "media/gpu/ipc/service/gpu_video_encode_accelerator.h"
#include "media/gpu/ipc/service/media_service.h"
#include "services/shell/public/cpp/interface_registry.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"
#include "ui/gl/init/gl_factory.h"
#include "url/gurl.h"

#if defined(USE_OZONE)
#include "ui/ozone/public/gpu_platform_support.h"
#include "ui/ozone/public/ozone_platform.h"
#endif

#if defined(OS_ANDROID)
#include "media/base/android/media_client_android.h"
#include "media/gpu/avda_surface_tracker.h"
#endif

namespace content {
namespace {

static base::LazyInstance<scoped_refptr<ThreadSafeSender> >
    g_thread_safe_sender = LAZY_INSTANCE_INITIALIZER;

bool GpuProcessLogMessageHandler(int severity,
                                 const char* file, int line,
                                 size_t message_start,
                                 const std::string& str) {
  std::string header = str.substr(0, message_start);
  std::string message = str.substr(message_start);

  g_thread_safe_sender.Get()->Send(
      new GpuHostMsg_OnLogMessage(severity, header, message));

  return false;
}

// Message filter used to to handle GpuMsg_CreateGpuMemoryBuffer messages
// on the IO thread. This allows the UI thread in the browser process to remain
// fast at all times.
class GpuMemoryBufferMessageFilter : public IPC::MessageFilter {
 public:
  explicit GpuMemoryBufferMessageFilter(
      gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory)
      : gpu_memory_buffer_factory_(gpu_memory_buffer_factory),
        sender_(nullptr) {}

  // Overridden from IPC::MessageFilter:
  void OnFilterAdded(IPC::Sender* sender) override {
    DCHECK(!sender_);
    sender_ = sender;
  }
  void OnFilterRemoved() override {
    DCHECK(sender_);
    sender_ = nullptr;
  }
  bool OnMessageReceived(const IPC::Message& message) override {
    DCHECK(sender_);
    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(GpuMemoryBufferMessageFilter, message)
      IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()
    return handled;
  }

 protected:
  ~GpuMemoryBufferMessageFilter() override {}

  void OnCreateGpuMemoryBuffer(
      const GpuMsg_CreateGpuMemoryBuffer_Params& params) {
    TRACE_EVENT2("gpu", "GpuMemoryBufferMessageFilter::OnCreateGpuMemoryBuffer",
                 "id", params.id.id, "client_id", params.client_id);

    DCHECK(gpu_memory_buffer_factory_);
    sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated(
        gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
            params.id, params.size, params.format, params.usage,
            params.client_id, params.surface_handle)));
  }

  gpu::GpuMemoryBufferFactory* const gpu_memory_buffer_factory_;
  IPC::Sender* sender_;
};

ChildThreadImpl::Options GetOptions(
    gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory) {
  ChildThreadImpl::Options::Builder builder;

  builder.AddStartupFilter(
      new GpuMemoryBufferMessageFilter(gpu_memory_buffer_factory));

#if defined(USE_OZONE)
  IPC::MessageFilter* message_filter = ui::OzonePlatform::GetInstance()
                                           ->GetGpuPlatformSupport()
                                           ->GetMessageFilter();
  if (message_filter)
    builder.AddStartupFilter(message_filter);
#endif

  builder.ConnectToBrowser(true);

  return builder.Build();
}

}  // namespace

GpuChildThread::GpuChildThread(
    GpuWatchdogThread* watchdog_thread,
    bool dead_on_arrival,
    const gpu::GPUInfo& gpu_info,
    const DeferredMessages& deferred_messages,
    gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory)
    : ChildThreadImpl(GetOptions(gpu_memory_buffer_factory)),
      dead_on_arrival_(dead_on_arrival),
      gpu_info_(gpu_info),
      deferred_messages_(deferred_messages),
      in_browser_process_(false),
      gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {
  watchdog_thread_ = watchdog_thread;
#if defined(OS_WIN)
  target_services_ = NULL;
#endif
  g_thread_safe_sender.Get() = thread_safe_sender();
}

GpuChildThread::GpuChildThread(
    const gpu::GpuPreferences& gpu_preferences,
    const InProcessChildThreadParams& params,
    gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory)
    : ChildThreadImpl(ChildThreadImpl::Options::Builder()
                          .InBrowserProcess(params)
                          .UseMojoChannel(true)
                          .AddStartupFilter(new GpuMemoryBufferMessageFilter(
                              gpu_memory_buffer_factory))
                          .ConnectToBrowser(true)
                          .Build()),
      gpu_preferences_(gpu_preferences),
      dead_on_arrival_(false),
      in_browser_process_(true),
      gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {
#if defined(OS_WIN)
  target_services_ = NULL;
#endif
  DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
             switches::kSingleProcess) ||
         base::CommandLine::ForCurrentProcess()->HasSwitch(
             switches::kInProcessGPU));

  if (!gl::init::InitializeGLOneOff())
    VLOG(1) << "gl::init::InitializeGLOneOff failed";

  g_thread_safe_sender.Get() = thread_safe_sender();
}

GpuChildThread::~GpuChildThread() {
  while (!deferred_messages_.empty()) {
    delete deferred_messages_.front();
    deferred_messages_.pop();
  }
}

void GpuChildThread::Shutdown() {
  ChildThreadImpl::Shutdown();
  logging::SetLogMessageHandler(NULL);
}

void GpuChildThread::Init(const base::Time& process_start_time) {
  process_start_time_ = process_start_time;

#if defined(OS_ANDROID)
  // When running in in-process mode, this has been set in the browser at
  // ChromeBrowserMainPartsAndroid::PreMainMessageLoopRun().
  if (!in_browser_process_)
    media::SetMediaClientAndroid(GetContentClient()->GetMediaClientAndroid());
#endif
  // We don't want to process any incoming interface requests until
  // OnInitialize() is invoked.
  GetInterfaceRegistry()->PauseBinding();

  if (GetContentClient()->gpu())  // NULL in tests.
    GetContentClient()->gpu()->Initialize(this);
}

void GpuChildThread::OnFieldTrialGroupFinalized(const std::string& trial_name,
                                                const std::string& group_name) {
  Send(new GpuHostMsg_FieldTrialActivated(trial_name));
}

bool GpuChildThread::Send(IPC::Message* msg) {
  // The GPU process must never send a synchronous IPC message to the browser
  // process. This could result in deadlock.
  DCHECK(!msg->is_sync());

  return ChildThreadImpl::Send(msg);
}

bool GpuChildThread::OnControlMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(GpuChildThread, msg)
    IPC_MESSAGE_HANDLER(GpuMsg_Initialize, OnInitialize)
    IPC_MESSAGE_HANDLER(GpuMsg_Finalize, OnFinalize)
    IPC_MESSAGE_HANDLER(GpuMsg_CollectGraphicsInfo, OnCollectGraphicsInfo)
    IPC_MESSAGE_HANDLER(GpuMsg_GetVideoMemoryUsageStats,
                        OnGetVideoMemoryUsageStats)
    IPC_MESSAGE_HANDLER(GpuMsg_Clean, OnClean)
    IPC_MESSAGE_HANDLER(GpuMsg_Crash, OnCrash)
    IPC_MESSAGE_HANDLER(GpuMsg_Hang, OnHang)
    IPC_MESSAGE_HANDLER(GpuMsg_DisableWatchdog, OnDisableWatchdog)
    IPC_MESSAGE_HANDLER(GpuMsg_GpuSwitched, OnGpuSwitched)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  if (handled)
    return true;

#if defined(USE_OZONE)
  if (ui::OzonePlatform::GetInstance()
          ->GetGpuPlatformSupport()
          ->OnMessageReceived(msg))
    return true;
#endif

  return false;
}

bool GpuChildThread::OnMessageReceived(const IPC::Message& msg) {
  if (ChildThreadImpl::OnMessageReceived(msg))
    return true;

  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(GpuChildThread, msg)
    IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
    IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
    IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
    IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
#if defined(OS_ANDROID)
    IPC_MESSAGE_HANDLER(GpuMsg_WakeUpGpu, OnWakeUpGpu);
    IPC_MESSAGE_HANDLER(GpuMsg_DestroyingVideoSurface,
                        OnDestroyingVideoSurface);
#endif
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  if (handled)
    return true;

  return false;
}

void GpuChildThread::SetActiveURL(const GURL& url) {
  GetContentClient()->SetActiveURL(url);
}

void GpuChildThread::DidCreateOffscreenContext(const GURL& active_url) {
  Send(new GpuHostMsg_DidCreateOffscreenContext(active_url));
}

void GpuChildThread::DidDestroyChannel(int client_id) {
  media_service_->RemoveChannel(client_id);
  Send(new GpuHostMsg_DestroyChannel(client_id));
}

void GpuChildThread::DidDestroyOffscreenContext(const GURL& active_url) {
  Send(new GpuHostMsg_DidDestroyOffscreenContext(active_url));
}

void GpuChildThread::DidLoseContext(bool offscreen,
                                    gpu::error::ContextLostReason reason,
                                    const GURL& active_url) {
  Send(new GpuHostMsg_DidLoseContext(offscreen, reason, active_url));
}

void GpuChildThread::GpuMemoryUmaStats(const gpu::GPUMemoryUmaStats& params) {
  Send(new GpuHostMsg_GpuMemoryUmaStats(params));
}

#if defined(OS_WIN)
void GpuChildThread::SendAcceleratedSurfaceCreatedChildWindow(
    gpu::SurfaceHandle parent_window,
    gpu::SurfaceHandle child_window) {
  Send(new GpuHostMsg_AcceleratedSurfaceCreatedChildWindow(parent_window,
                                                           child_window));
}
#endif

void GpuChildThread::StoreShaderToDisk(int32_t client_id,
                                       const std::string& key,
                                       const std::string& shader) {
  Send(new GpuHostMsg_CacheShader(client_id, key, shader));
}

void GpuChildThread::OnInitialize(const gpu::GpuPreferences& gpu_preferences) {
  gpu_preferences_ = gpu_preferences;

  gpu_info_.video_decode_accelerator_capabilities =
      media::GpuVideoDecodeAccelerator::GetCapabilities(gpu_preferences_);
  gpu_info_.video_encode_accelerator_supported_profiles =
      media::GpuVideoEncodeAccelerator::GetSupportedProfiles(
          gpu_preferences_);
  gpu_info_.jpeg_decode_accelerator_supported =
      media::GpuJpegDecodeAccelerator::IsSupported();

  // Record initialization only after collecting the GPU info because that can
  // take a significant amount of time.
  gpu_info_.initialization_time = base::Time::Now() - process_start_time_;
  Send(new GpuHostMsg_Initialized(!dead_on_arrival_, gpu_info_));
  while (!deferred_messages_.empty()) {
    Send(deferred_messages_.front());
    deferred_messages_.pop();
  }

  if (dead_on_arrival_) {
    LOG(ERROR) << "Exiting GPU process due to errors during initialization";
    base::MessageLoop::current()->QuitWhenIdle();
    return;
  }

  // We don't need to pipe log messages if we are running the GPU thread in
  // the browser process.
  if (!in_browser_process_)
    logging::SetLogMessageHandler(GpuProcessLogMessageHandler);

  gpu::SyncPointManager* sync_point_manager = nullptr;
  // Note SyncPointManager from ContentGpuClient cannot be owned by this.
  if (GetContentClient()->gpu())
    sync_point_manager = GetContentClient()->gpu()->GetSyncPointManager();
  if (!sync_point_manager) {
    if (!owned_sync_point_manager_) {
      owned_sync_point_manager_.reset(new gpu::SyncPointManager(false));
    }
    sync_point_manager = owned_sync_point_manager_.get();
  }

  // Defer creation of the render thread. This is to prevent it from handling
  // IPC messages before the sandbox has been enabled and all other necessary
  // initialization has succeeded.
  gpu_channel_manager_.reset(
      new gpu::GpuChannelManager(gpu_preferences_, this, watchdog_thread_.get(),
                            base::ThreadTaskRunnerHandle::Get().get(),
                            ChildProcess::current()->io_task_runner(),
                            ChildProcess::current()->GetShutDownEvent(),
                            sync_point_manager, gpu_memory_buffer_factory_));

  media_service_.reset(new media::MediaService(gpu_channel_manager_.get()));

#if defined(USE_OZONE)
  ui::OzonePlatform::GetInstance()
      ->GetGpuPlatformSupport()
      ->OnChannelEstablished(this);
#endif

  // Only set once per process instance.
  service_factory_.reset(new GpuServiceFactory);

  GetInterfaceRegistry()->AddInterface(base::Bind(
      &GpuChildThread::BindServiceFactoryRequest, base::Unretained(this)));

  if (GetContentClient()->gpu()) {  // NULL in tests.
    GetContentClient()->gpu()->ExposeInterfacesToBrowser(
        GetInterfaceRegistry(), gpu_preferences_);
    GetContentClient()->gpu()->ConsumeInterfacesFromBrowser(
        GetRemoteInterfaces());
  }

  GetInterfaceRegistry()->ResumeBinding();
}

void GpuChildThread::OnFinalize() {
  // Quit the GPU process
  base::MessageLoop::current()->QuitWhenIdle();
}

void GpuChildThread::StopWatchdog() {
  if (watchdog_thread_.get()) {
    watchdog_thread_->Stop();
  }
}

void GpuChildThread::OnCollectGraphicsInfo() {
  if (dead_on_arrival_)
    return;

#if defined(OS_WIN)
  // GPU full info collection should only happen on un-sandboxed GPU process
  // or single process/in-process gpu mode on Windows.
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  DCHECK(command_line->HasSwitch(switches::kDisableGpuSandbox) ||
         in_browser_process_);
#endif  // OS_WIN

  gpu::CollectInfoResult result =
      gpu::CollectContextGraphicsInfo(&gpu_info_);
  switch (result) {
    case gpu::kCollectInfoFatalFailure:
      LOG(ERROR) << "gpu::CollectGraphicsInfo failed (fatal).";
      // TODO(piman): can we signal overall failure?
      break;
    case gpu::kCollectInfoNonFatalFailure:
      DVLOG(1) << "gpu::CollectGraphicsInfo failed (non-fatal).";
      break;
    case gpu::kCollectInfoNone:
      NOTREACHED();
      break;
    case gpu::kCollectInfoSuccess:
      break;
  }
  GetContentClient()->SetGpuInfo(gpu_info_);

#if defined(OS_WIN)
  // This is slow, but it's the only thing the unsandboxed GPU process does,
  // and GpuDataManager prevents us from sending multiple collecting requests,
  // so it's OK to be blocking.
  gpu::GetDxDiagnostics(&gpu_info_.dx_diagnostics);
  gpu_info_.dx_diagnostics_info_state = gpu::kCollectInfoSuccess;
#endif  // OS_WIN

  Send(new GpuHostMsg_GraphicsInfoCollected(gpu_info_));

#if defined(OS_WIN)
  if (!in_browser_process_) {
    // The unsandboxed GPU process fulfilled its duty.  Rest in peace.
    base::MessageLoop::current()->QuitWhenIdle();
  }
#endif  // OS_WIN
}

void GpuChildThread::OnGetVideoMemoryUsageStats() {
  gpu::VideoMemoryUsageStats video_memory_usage_stats;
  if (gpu_channel_manager_) {
    gpu_channel_manager_->gpu_memory_manager()->GetVideoMemoryUsageStats(
        &video_memory_usage_stats);
  }
  Send(new GpuHostMsg_VideoMemoryUsageStats(video_memory_usage_stats));
}

void GpuChildThread::OnClean() {
  DVLOG(1) << "GPU: Removing all contexts";
  if (gpu_channel_manager_)
    gpu_channel_manager_->DestroyAllChannels();
}

void GpuChildThread::OnCrash() {
  DVLOG(1) << "GPU: Simulating GPU crash";
  // Good bye, cruel world.
  volatile int* it_s_the_end_of_the_world_as_we_know_it = NULL;
  *it_s_the_end_of_the_world_as_we_know_it = 0xdead;
}

void GpuChildThread::OnHang() {
  DVLOG(1) << "GPU: Simulating GPU hang";
  for (;;) {
    // Do not sleep here. The GPU watchdog timer tracks the amount of user
    // time this thread is using and it doesn't use much while calling Sleep.
  }
}

void GpuChildThread::OnDisableWatchdog() {
  DVLOG(1) << "GPU: Disabling watchdog thread";
  if (watchdog_thread_.get()) {
    // Disarm the watchdog before shutting down the message loop. This prevents
    // the future posting of tasks to the message loop.
    if (watchdog_thread_->message_loop())
      watchdog_thread_->PostAcknowledge();
    // Prevent rearming.
    watchdog_thread_->Stop();
  }
}

void GpuChildThread::OnGpuSwitched() {
  DVLOG(1) << "GPU: GPU has switched";
  // Notify observers in the GPU process.
  if (!in_browser_process_)
    ui::GpuSwitchingManager::GetInstance()->NotifyGpuSwitched();
}

void GpuChildThread::OnEstablishChannel(const EstablishChannelParams& params) {
  if (!gpu_channel_manager_)
    return;

  IPC::ChannelHandle channel_handle = gpu_channel_manager_->EstablishChannel(
      params.client_id, params.client_tracing_id, params.preempts,
      params.allow_view_command_buffers, params.allow_real_time_streams);
  media_service_->AddChannel(params.client_id);
  Send(new GpuHostMsg_ChannelEstablished(channel_handle));
}

void GpuChildThread::OnCloseChannel(int32_t client_id) {
  if (gpu_channel_manager_)
    gpu_channel_manager_->RemoveChannel(client_id);
}

void GpuChildThread::OnLoadedShader(const std::string& shader) {
  if (gpu_channel_manager_)
    gpu_channel_manager_->PopulateShaderCache(shader);
}

void GpuChildThread::OnDestroyGpuMemoryBuffer(
    gfx::GpuMemoryBufferId id,
    int client_id,
    const gpu::SyncToken& sync_token) {
  if (gpu_channel_manager_)
    gpu_channel_manager_->DestroyGpuMemoryBuffer(id, client_id, sync_token);
}

#if defined(OS_ANDROID)
void GpuChildThread::OnWakeUpGpu() {
  if (gpu_channel_manager_)
    gpu_channel_manager_->WakeUpGpu();
}

void GpuChildThread::OnDestroyingVideoSurface(int surface_id) {
  media::AVDASurfaceTracker::GetInstance()->NotifyDestroyingSurface(surface_id);
  Send(new GpuHostMsg_DestroyingVideoSurfaceAck(surface_id));
}
#endif

void GpuChildThread::OnLoseAllContexts() {
  if (gpu_channel_manager_) {
    gpu_channel_manager_->DestroyAllChannels();
    media_service_->DestroyAllChannels();
  }
}

void GpuChildThread::BindServiceFactoryRequest(
    shell::mojom::ServiceFactoryRequest request) {
  DVLOG(1) << "GPU: Binding shell::mojom::ServiceFactoryRequest";
  DCHECK(service_factory_);
  service_factory_bindings_.AddBinding(service_factory_.get(),
                                       std::move(request));
}

}  // namespace content
