// 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 "content/browser/compositor/gpu_process_transport_factory.h"

#include <string>
#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "cc/base/histograms.h"
#include "cc/base/switches.h"
#include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/raster/task_graph_runner.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gl_helper.h"
#include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/host/renderer_settings_creation.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/display_scheduler.h"
#include "components/viz/service/display/texture_mailbox_deleter.h"
#include "components/viz/service/display_embedder/compositing_mode_reporter_impl.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
#include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
#include "content/browser/compositor/offscreen_browser_compositor_output_surface.h"
#include "content/browser/compositor/reflector_impl.h"
#include "content/browser/compositor/software_browser_compositor_output_surface.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/mus_util.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu_stream_constants.h"
#include "content/public/common/content_switches.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "gpu/vulkan/features.h"
#include "services/service_manager/runner/common/client_util.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_switches.h"
#include "ui/compositor/layer.h"
#include "ui/display/display_switches.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"

#if defined(USE_AURA)
#include "content/public/common/service_manager_connection.h"
#include "ui/aura/env.h"
#include "ui/aura/window_tree_host.h"
#endif

#if defined(OS_WIN)
#include "base/win/windows_version.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_win.h"
#include "components/viz/service/display_embedder/software_output_device_win.h"
#include "ui/gfx/win/rendering_window_manager.h"
#elif defined(USE_OZONE)
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h"
#include "components/viz/service/display_embedder/software_output_device_ozone.h"
#include "ui/ozone/public/overlay_candidates_ozone.h"
#include "ui/ozone/public/overlay_manager_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/ozone_switches.h"
#elif defined(USE_X11)
#include "components/viz/service/display_embedder/software_output_device_x11.h"
#elif defined(OS_MACOSX)
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_mac.h"
#include "components/viz/service/display_embedder/software_output_device_mac.h"
#include "content/browser/compositor/gpu_output_surface_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/base/ui_base_switches.h"
#elif defined(OS_ANDROID)
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h"
#endif
#if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
#include "gpu/ipc/common/gpu_surface_tracker.h"
#endif

#if BUILDFLAG(ENABLE_VULKAN)
#include "content/browser/compositor/vulkan_browser_compositor_output_surface.h"
#endif

using viz::ContextProvider;
using gpu::gles2::GLES2Interface;

namespace {

// The client_id used here should not conflict with the client_id generated
// from RenderWidgetHostImpl.
constexpr uint32_t kDefaultClientId = 0u;

bool IsGpuVSyncSignalSupported() {
#if defined(OS_WIN)
  // TODO(stanisc): http://crbug.com/467617 Limit to Windows 8.1+ for now
  // because of locking issue caused by waiting for VSync on Win7 and Win 8.0.
  return base::win::GetVersion() >= base::win::VERSION_WIN8_1 &&
         base::FeatureList::IsEnabled(features::kD3DVsync);
#else
  return false;
#endif  // defined(OS_WIN)
}

#if defined(OS_MACOSX)
bool IsCALayersDisabledFromCommandLine() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  return command_line->HasSwitch(switches::kDisableMacOverlays);
}
#endif

}  // namespace

namespace content {

class ExternalBeginFrameController : public viz::ExternalBeginFrameSourceClient,
                                     public viz::DisplayObserver {
 public:
  explicit ExternalBeginFrameController(ui::Compositor* compositor)
      : begin_frame_source_(this), compositor_(compositor) {}
  ~ExternalBeginFrameController() override {}

  // Issue a BeginFrame with the given |args|.
  void IssueExternalBeginFrame(const viz::BeginFrameArgs& args) {
    begin_frame_source_.OnBeginFrame(args);
  }

  viz::BeginFrameSource* begin_frame_source() { return &begin_frame_source_; }

 private:
  // viz::ExternalBeginFrameSourceClient implementation.
  void OnNeedsBeginFrames(bool needs_begin_frames) override {
    compositor_->OnNeedsExternalBeginFrames(needs_begin_frames);
  }

  // viz::DisplayObserver implementation.
  void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override {
    compositor_->OnDisplayDidFinishFrame(ack);
  }

  viz::ExternalBeginFrameSource begin_frame_source_;
  ui::Compositor* compositor_ = nullptr;
};

struct GpuProcessTransportFactory::PerCompositorData {
  gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
  BrowserCompositorOutputSurface* display_output_surface = nullptr;
  // Exactly one of |synthetic_begin_frame_source|,
  // |gpu_vsync_begin_frame_source|, and |external_begin_frame_source| is valid
  // at the same time.
  std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source;
  std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
  std::unique_ptr<ExternalBeginFrameController> external_begin_frame_controller;
  ReflectorImpl* reflector = nullptr;
  std::unique_ptr<viz::Display> display;
  bool output_is_secure = false;
};

GpuProcessTransportFactory::GpuProcessTransportFactory(
    gpu::GpuChannelEstablishFactory* gpu_channel_factory,
    viz::CompositingModeReporterImpl* compositing_mode_reporter,
    scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner)
    : frame_sink_id_allocator_(kDefaultClientId),
      renderer_settings_(
          viz::CreateRendererSettings(CreateBufferToTextureTargetMap())),
      resize_task_runner_(std::move(resize_task_runner)),
      task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
      gpu_channel_factory_(gpu_channel_factory),
      compositing_mode_reporter_(compositing_mode_reporter),
      callback_factory_(this) {
  DCHECK(gpu_channel_factory_);
  cc::SetClientNameForMetrics("Browser");

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kDisableGpuVsync)) {
    std::string display_vsync_string =
        command_line->GetSwitchValueASCII(switches::kDisableGpuVsync);
    // See comments in gl_switches about this flag.  The browser compositor
    // is only unthrottled when "gpu" or no switch value is passed, as it
    // is driven directly by the display compositor.
    if (display_vsync_string != "beginframe") {
      disable_display_vsync_ = true;
    }
  }

  if (command_line->HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw))
    wait_for_all_pipeline_stages_before_draw_ = true;

  task_graph_runner_->Start("CompositorTileWorker1",
                            base::SimpleThread::Options());
#if defined(OS_WIN)
  software_backing_ = std::make_unique<viz::OutputDeviceBacking>();
#endif

  if (command_line->HasSwitch(switches::kDisableGpu) ||
      command_line->HasSwitch(switches::kDisableGpuCompositing)) {
    DisableGpuCompositing(nullptr);
  }
}

GpuProcessTransportFactory::~GpuProcessTransportFactory() {
  DCHECK(per_compositor_data_.empty());

  if (shared_main_thread_contexts_)
    shared_main_thread_contexts_->RemoveObserver(this);

  // Make sure the lost context callback doesn't try to run during destruction.
  callback_factory_.InvalidateWeakPtrs();

  task_graph_runner_->Shutdown();
}

std::unique_ptr<viz::SoftwareOutputDevice>
GpuProcessTransportFactory::CreateSoftwareOutputDevice(
    gfx::AcceleratedWidget widget) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kHeadless))
    return base::WrapUnique(new viz::SoftwareOutputDevice);

#if defined(USE_AURA)
  if (IsUsingMus()) {
    NOTREACHED();
    return nullptr;
  }
#endif

  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_WIN)
  return std::make_unique<viz::SoftwareOutputDeviceWin>(software_backing_.get(),
                                                        widget);
#elif defined(USE_OZONE)
  return viz::SoftwareOutputDeviceOzone::Create(widget);
#elif defined(USE_X11)
  return std::make_unique<viz::SoftwareOutputDeviceX11>(widget);
#elif defined(OS_MACOSX)
  return std::make_unique<viz::SoftwareOutputDeviceMac>(widget);
#else
  NOTREACHED();
  return std::unique_ptr<viz::SoftwareOutputDevice>();
#endif
}

std::unique_ptr<viz::CompositorOverlayCandidateValidator>
CreateOverlayCandidateValidator(
#if defined(OS_MACOSX)
    gfx::AcceleratedWidget widget,
    bool disable_overlay_ca_layers) {
#else
    gfx::AcceleratedWidget widget) {
#endif
  std::unique_ptr<viz::CompositorOverlayCandidateValidator> validator;
#if defined(USE_OZONE)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kEnableHardwareOverlays)) {
    std::string enable_overlay_flag =
        command_line->GetSwitchValueASCII(switches::kEnableHardwareOverlays);
    std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates =
        ui::OzonePlatform::GetInstance()
            ->GetOverlayManager()
            ->CreateOverlayCandidates(widget);
    validator.reset(new viz::CompositorOverlayCandidateValidatorOzone(
        std::move(overlay_candidates), enable_overlay_flag));
  }
#elif defined(OS_MACOSX)
  // Overlays are only supported through the remote layer API.
  if (ui::RemoteLayerAPISupported()) {
    static bool overlays_disabled_at_command_line =
        IsCALayersDisabledFromCommandLine();
    const bool ca_layers_disabled =
        overlays_disabled_at_command_line || disable_overlay_ca_layers;
    validator.reset(
        new viz::CompositorOverlayCandidateValidatorMac(ca_layers_disabled));
  }
#elif defined(OS_ANDROID)
  validator.reset(new viz::CompositorOverlayCandidateValidatorAndroid());
#elif defined(OS_WIN)
  validator = std::make_unique<viz::CompositorOverlayCandidateValidatorWin>();
#endif

  return validator;
}

void GpuProcessTransportFactory::CreateLayerTreeFrameSink(
    base::WeakPtr<ui::Compositor> compositor) {
  DCHECK(!!compositor);
  PerCompositorData* data = per_compositor_data_[compositor.get()].get();
  if (!data) {
    data = CreatePerCompositorData(compositor.get());
  } else {
    // TODO(danakj): We can destroy the |data->display| and
    // |data->begin_frame_source| here when the compositor destroys its
    // LayerTreeFrameSink before calling back here.
    data->display_output_surface = nullptr;
  }

#if defined(OS_WIN)
  gfx::RenderingWindowManager::GetInstance()->UnregisterParent(
      compositor->widget());
#endif

  const bool use_vulkan = static_cast<bool>(SharedVulkanContextProvider());
  const bool use_gpu_compositing =
      !compositor->force_software_compositor() && !is_gpu_compositing_disabled_;
  if (use_gpu_compositing && !use_vulkan) {
    gpu_channel_factory_->EstablishGpuChannel(base::Bind(
        &GpuProcessTransportFactory::EstablishedGpuChannel,
        callback_factory_.GetWeakPtr(), compositor, use_gpu_compositing));
  } else {
    EstablishedGpuChannel(compositor, use_gpu_compositing, nullptr);
  }
}

void GpuProcessTransportFactory::EstablishedGpuChannel(
    base::WeakPtr<ui::Compositor> compositor,
    bool use_gpu_compositing,
    scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
  if (!compositor)
    return;

  if (gpu_channel_host &&
      gpu_channel_host->gpu_feature_info()
              .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
          gpu::kGpuFeatureStatusEnabled) {
    use_gpu_compositing = false;
  }
  // Gpu compositing may have been disabled in the meantime.
  if (is_gpu_compositing_disabled_)
    use_gpu_compositing = false;

  // The widget might have been released in the meantime.
  PerCompositorDataMap::iterator it =
      per_compositor_data_.find(compositor.get());
  if (it == per_compositor_data_.end())
    return;

  PerCompositorData* data = it->second.get();
  DCHECK(data);

  bool support_stencil = false;
#if defined(OS_CHROMEOS)
  // ChromeOS uses surfaceless when running on a real device and stencil
  // buffers can then be added dynamically so supporting them does not have an
  // impact on normal usage. If we are not running on a real ChromeOS device
  // but instead on a workstation for development, then stencil support is
  // useful as it allows the overdraw feedback debugging feature to be used.
  support_stencil = true;
#endif

#if defined(OS_WIN)
  gfx::RenderingWindowManager::GetInstance()->RegisterParent(
      compositor->widget());
#endif

  scoped_refptr<viz::VulkanInProcessContextProvider> vulkan_context_provider =
      SharedVulkanContextProvider();
  scoped_refptr<ui::ContextProviderCommandBuffer> context_provider;

  if (!use_gpu_compositing || vulkan_context_provider) {
    // If not using GL compositing, don't keep the old shared worker context.
    shared_worker_context_provider_ = nullptr;
  } else if (!gpu_channel_host) {
    // Failed to establish a channel, which is a fatal error, so stop trying to
    // use gpu compositing.
    use_gpu_compositing = false;
    shared_worker_context_provider_ = nullptr;
  } else {
    // Try to reuse existing worker context provider.
    if (shared_worker_context_provider_) {
      bool lost;
      {
        // Note: If context is lost, we delete reference after releasing the
        // lock.
        viz::ContextProvider::ScopedContextLock lock(
            shared_worker_context_provider_.get());
        lost = lock.ContextGL()->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
      }
      if (lost)
        shared_worker_context_provider_ = nullptr;
    }

    if (!shared_worker_context_provider_) {
      bool need_alpha_channel = false;
      const bool support_locking = true;
      shared_worker_context_provider_ = CreateContextCommon(
          gpu_channel_host, gpu::kNullSurfaceHandle, need_alpha_channel,
          false /* support_stencil */, support_locking, nullptr,
          ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
      auto result = shared_worker_context_provider_->BindToCurrentThread();
      if (result != gpu::ContextResult::kSuccess) {
        shared_worker_context_provider_ = nullptr;
        if (result == gpu::ContextResult::kFatalFailure)
          use_gpu_compositing = false;
      }
    }

    // The |context_provider| is used for both the browser compositor and the
    // display compositor. It shares resources with the worker context, so if
    // we failed to make a worker context, just start over and try again.
    if (shared_worker_context_provider_) {
      // For mus, we create an offscreen context for a mus window, and we will
      // use CommandBufferProxyImpl::TakeFrontBuffer() to take the context's
      // front buffer into a mailbox, insert a sync token, and send the
      // mailbox+sync to the ui service process.
      gpu::SurfaceHandle surface_handle = data->surface_handle;
      bool need_alpha_channel = false;
      bool support_locking = false;
      context_provider = CreateContextCommon(
          std::move(gpu_channel_host), surface_handle, need_alpha_channel,
          support_stencil, support_locking,
          shared_worker_context_provider_.get(),
          ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
      // On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in
      // a nested run loop during resize.
      context_provider->SetDefaultTaskRunner(resize_task_runner_);
      auto result = context_provider->BindToCurrentThread();
      if (result != gpu::ContextResult::kSuccess) {
        context_provider = nullptr;
        if (result == gpu::ContextResult::kFatalFailure)
          use_gpu_compositing = false;
      }
    }
  }

  bool gpu_compositing_ready =
      vulkan_context_provider ||
      (context_provider && shared_worker_context_provider_);
  UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
                        gpu_compositing_ready);
  if (!gpu_compositing_ready) {
#if defined(OS_CHROMEOS)
    // A fatal context error occured, and we can not fall back to software
    // compositing on ChromeOS. These can be unrecoverable hardware errors,
    // or bugs that should not happen: either from the client's context request,
    // in the service, or a transient error was miscategorized as fatal.
    CHECK(use_gpu_compositing);
#endif

    // Try again if we didn't give up on gpu. Otherwise, drop the shared context
    // if it exists and won't be used.
    if (!use_gpu_compositing) {
      shared_worker_context_provider_ = nullptr;
    } else {
      gpu_channel_factory_->EstablishGpuChannel(base::Bind(
          &GpuProcessTransportFactory::EstablishedGpuChannel,
          callback_factory_.GetWeakPtr(), compositor, use_gpu_compositing));
      return;
    }
  }

  BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback =
      base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor);
  GpuVSyncControl* gpu_vsync_control = nullptr;

  std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface;
#if BUILDFLAG(ENABLE_VULKAN)
  std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface;
  if (vulkan_context_provider) {
    vulkan_surface.reset(new VulkanBrowserCompositorOutputSurface(
        vulkan_context_provider, vsync_callback));
    if (!vulkan_surface->Initialize(compositor.get()->widget())) {
      vulkan_surface->Destroy();
      vulkan_surface.reset();
    } else {
      display_output_surface = std::move(vulkan_surface);
    }
  }
#endif

  if (!display_output_surface) {
    if (!use_gpu_compositing) {
      if (!is_gpu_compositing_disabled_ &&
          !compositor->force_software_compositor()) {
        // This will cause all other display compositors and FrameSink clients
        // to fall back to software compositing. If the compositor is
        // |force_software_compositor()|, then it is not a signal to others to
        // use software too - but such compositors can not embed external
        // surfaces as they are not following the correct mode.
        DisableGpuCompositing(compositor.get());
      }
      display_output_surface =
          std::make_unique<SoftwareBrowserCompositorOutputSurface>(
              CreateSoftwareOutputDevice(compositor->widget()), vsync_callback,
              compositor->task_runner());
    } else {
      DCHECK(context_provider);
      const auto& capabilities = context_provider->ContextCapabilities();
      if (data->surface_handle == gpu::kNullSurfaceHandle) {
        display_output_surface =
            std::make_unique<OffscreenBrowserCompositorOutputSurface>(
                context_provider, vsync_callback,
                std::unique_ptr<viz::CompositorOverlayCandidateValidator>());
      } else if (capabilities.surfaceless) {
#if defined(OS_MACOSX)
        const auto& gpu_feature_info = context_provider->GetGpuFeatureInfo();
        bool disable_overlay_ca_layers = gpu_feature_info.IsWorkaroundEnabled(
            gpu::DISABLE_OVERLAY_CA_LAYERS);
        display_output_surface = std::make_unique<GpuOutputSurfaceMac>(
            compositor->widget(), context_provider, data->surface_handle,
            vsync_callback,
            CreateOverlayCandidateValidator(compositor->widget(),
                                            disable_overlay_ca_layers),
            GetGpuMemoryBufferManager());
#else
        auto gpu_output_surface =
            std::make_unique<GpuSurfacelessBrowserCompositorOutputSurface>(
                context_provider, data->surface_handle, vsync_callback,
                CreateOverlayCandidateValidator(compositor->widget()),
                GL_TEXTURE_2D, GL_RGB,
                display::DisplaySnapshot::PrimaryFormat(),
                GetGpuMemoryBufferManager());
        gpu_vsync_control = gpu_output_surface.get();
        display_output_surface = std::move(gpu_output_surface);
#endif
      } else {
        std::unique_ptr<viz::CompositorOverlayCandidateValidator> validator;
#if defined(OS_WIN)
        if (capabilities.dc_layers && capabilities.use_dc_overlays_for_video)
          validator = CreateOverlayCandidateValidator(compositor->widget());
#elif !defined(OS_MACOSX)
        // Overlays are only supported on surfaceless output surfaces on Mac.
        validator = CreateOverlayCandidateValidator(compositor->widget());
#endif
        auto gpu_output_surface =
            std::make_unique<GpuBrowserCompositorOutputSurface>(
                context_provider, vsync_callback, std::move(validator));
        gpu_vsync_control = gpu_output_surface.get();
        display_output_surface = std::move(gpu_output_surface);
      }
    }
  }

  data->display_output_surface = display_output_surface.get();
  if (data->reflector)
    data->reflector->OnSourceSurfaceReady(data->display_output_surface);

  std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source;
  std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
  std::unique_ptr<ExternalBeginFrameController> external_begin_frame_controller;

  viz::BeginFrameSource* begin_frame_source = nullptr;
  if (compositor->external_begin_frames_enabled()) {
    external_begin_frame_controller =
        std::make_unique<ExternalBeginFrameController>(compositor.get());
    begin_frame_source = external_begin_frame_controller->begin_frame_source();
  } else if (!disable_display_vsync_) {
    if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
      gpu_vsync_begin_frame_source =
          std::make_unique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
      begin_frame_source = gpu_vsync_begin_frame_source.get();
    } else {
      synthetic_begin_frame_source =
          std::make_unique<viz::DelayBasedBeginFrameSource>(
              std::make_unique<viz::DelayBasedTimeSource>(
                  compositor->task_runner().get()));
      begin_frame_source = synthetic_begin_frame_source.get();
    }
  } else {
    synthetic_begin_frame_source =
        std::make_unique<viz::BackToBackBeginFrameSource>(
            std::make_unique<viz::DelayBasedTimeSource>(
                compositor->task_runner().get()));
    begin_frame_source = synthetic_begin_frame_source.get();
  }

#if defined(OS_WIN)
  gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild(
      compositor->widget());
#endif
  if (data->synthetic_begin_frame_source) {
    GetFrameSinkManager()->UnregisterBeginFrameSource(
        data->synthetic_begin_frame_source.get());
  } else if (data->gpu_vsync_begin_frame_source) {
    GetFrameSinkManager()->UnregisterBeginFrameSource(
        data->gpu_vsync_begin_frame_source.get());
  } else if (data->external_begin_frame_controller) {
    GetFrameSinkManager()->UnregisterBeginFrameSource(
        data->external_begin_frame_controller->begin_frame_source());
    data->display->RemoveObserver(data->external_begin_frame_controller.get());
  }

  auto scheduler = std::make_unique<viz::DisplayScheduler>(
      begin_frame_source, compositor->task_runner().get(),
      display_output_surface->capabilities().max_frames_pending,
      wait_for_all_pipeline_stages_before_draw_);

  // The Display owns and uses the |display_output_surface| created above.
  data->display = std::make_unique<viz::Display>(
      viz::ServerSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
      renderer_settings_, compositor->frame_sink_id(),
      std::move(display_output_surface), std::move(scheduler),
      std::make_unique<viz::TextureMailboxDeleter>(
          compositor->task_runner().get()));
  GetFrameSinkManager()->RegisterBeginFrameSource(begin_frame_source,
                                                  compositor->frame_sink_id());
  // Note that we are careful not to destroy prior BeginFrameSource objects
  // until we have reset |data->display|.
  data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
  data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source);
  data->external_begin_frame_controller =
      std::move(external_begin_frame_controller);

  if (data->external_begin_frame_controller)
    data->display->AddObserver(data->external_begin_frame_controller.get());

  // The |delegated_output_surface| is given back to the compositor, it
  // delegates to the Display as its root surface. Importantly, it shares the
  // same ContextProvider as the Display's output surface.
  auto layer_tree_frame_sink =
      vulkan_context_provider
          ? std::make_unique<viz::DirectLayerTreeFrameSink>(
                compositor->frame_sink_id(), GetHostFrameSinkManager(),
                GetFrameSinkManager(), data->display.get(),
                static_cast<scoped_refptr<viz::VulkanContextProvider>>(
                    vulkan_context_provider))
          : std::make_unique<viz::DirectLayerTreeFrameSink>(
                compositor->frame_sink_id(), GetHostFrameSinkManager(),
                GetFrameSinkManager(), data->display.get(), context_provider,
                shared_worker_context_provider_, GetGpuMemoryBufferManager(),
                viz::ServerSharedBitmapManager::current());
  data->display->Resize(compositor->size());
  data->display->SetOutputIsSecure(data->output_is_secure);
  compositor->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
}

void GpuProcessTransportFactory::DisableGpuCompositing(
    ui::Compositor* guilty_compositor) {
  // Change the result of IsGpuCompositingDisabled() before notifying anything.
  is_gpu_compositing_disabled_ = true;

  // This will notify all CompositingModeWatchers.
  compositing_mode_reporter_->SetUsingSoftwareCompositing();

  // Consumers of the shared main thread context aren't CompositingModeWatchers,
  // so inform them about the compositing mode switch by acting like the context
  // was lost. This also destroys the contexts since they aren't created when
  // gpu compositing isn't being used.
  OnLostMainThreadSharedContext();

  // This class chooses the compositing mode for all ui::Compositors and display
  // compositors, so it is not a CompositingModeWatcher also. Here we remove the
  // FrameSink from every compositor that needs to fall back to software
  // compositing (except the |guilty_compositor| which is already doing so).
  //
  // Releasing the FrameSink from the compositor will remove it from
  // |per_compositor_data_|, so we can't do that while iterating though the
  // collection.
  std::vector<ui::Compositor*> to_release;
  to_release.reserve(per_compositor_data_.size());
  for (auto& pair : per_compositor_data_) {
    ui::Compositor* compositor = pair.first;
    // The |guilty_compositor| is in the process of setting up its FrameSink
    // so removing it from |per_compositor_data_| would be both pointless and
    // the cause of a crash.
    // Compositors with |force_software_compositor()| do not follow the global
    // compositing mode, so they do not need to changed.
    if (compositor != guilty_compositor &&
        !compositor->force_software_compositor())
      to_release.push_back(compositor);
  }
  for (ui::Compositor* compositor : to_release) {
    // Compositor expects to be not visible when releasing its FrameSink.
    bool visible = compositor->IsVisible();
    compositor->SetVisible(false);
    gfx::AcceleratedWidget widget = compositor->ReleaseAcceleratedWidget();
    compositor->SetAcceleratedWidget(widget);
    if (visible)
      compositor->SetVisible(true);
  }
}

std::unique_ptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
    ui::Compositor* source_compositor,
    ui::Layer* target_layer) {
  PerCompositorData* source_data =
      per_compositor_data_[source_compositor].get();
  DCHECK(source_data);

  std::unique_ptr<ReflectorImpl> reflector(
      new ReflectorImpl(source_compositor, target_layer));
  source_data->reflector = reflector.get();
  if (auto* source_surface = source_data->display_output_surface)
    reflector->OnSourceSurfaceReady(source_surface);
  return std::move(reflector);
}

void GpuProcessTransportFactory::RemoveReflector(ui::Reflector* reflector) {
  ReflectorImpl* reflector_impl = static_cast<ReflectorImpl*>(reflector);
  PerCompositorData* data =
      per_compositor_data_[reflector_impl->mirrored_compositor()].get();
  DCHECK(data);
  data->reflector->Shutdown();
  data->reflector = nullptr;
}

void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
#if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
  if (data->surface_handle)
    gpu::GpuSurfaceTracker::Get()->RemoveSurface(data->surface_handle);
#endif
  if (data->synthetic_begin_frame_source) {
    GetFrameSinkManager()->UnregisterBeginFrameSource(
        data->synthetic_begin_frame_source.get());
  } else if (data->gpu_vsync_begin_frame_source) {
    GetFrameSinkManager()->UnregisterBeginFrameSource(
        data->gpu_vsync_begin_frame_source.get());
  } else if (data->external_begin_frame_controller) {
    GetFrameSinkManager()->UnregisterBeginFrameSource(
        data->external_begin_frame_controller->begin_frame_source());
    data->display->RemoveObserver(data->external_begin_frame_controller.get());
  }
  per_compositor_data_.erase(it);
  if (per_compositor_data_.empty()) {
    // Destroying the GLHelper may cause some async actions to be cancelled,
    // causing things to request a new GLHelper. Due to crbug.com/176091 the
    // GLHelper created in this case would be lost/leaked if we just reset()
    // on the |gl_helper_| variable directly. So instead we call reset() on a
    // local std::unique_ptr.
    std::unique_ptr<viz::GLHelper> helper = std::move(gl_helper_);

    // If there are any observer left at this point, make sure they clean up
    // before we destroy the GLHelper.
    for (auto& observer : observer_list_)
      observer.OnLostResources();

    helper.reset();
    DCHECK(!gl_helper_) << "Destroying the GLHelper should not cause a new "
                           "GLHelper to be created.";
  }
#if defined(OS_WIN)
  gfx::RenderingWindowManager::GetInstance()->UnregisterParent(
      compositor->widget());
#endif
}

double GpuProcessTransportFactory::GetRefreshRate() const {
  return 60.0;
}

gpu::GpuMemoryBufferManager*
GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
  return gpu_channel_factory_->GetGpuMemoryBufferManager();
}

cc::TaskGraphRunner* GpuProcessTransportFactory::GetTaskGraphRunner() {
  return task_graph_runner_.get();
}

bool GpuProcessTransportFactory::IsGpuCompositingDisabled() {
  return is_gpu_compositing_disabled_;
}

ui::ContextFactory* GpuProcessTransportFactory::GetContextFactory() {
  return this;
}

ui::ContextFactoryPrivate*
GpuProcessTransportFactory::GetContextFactoryPrivate() {
  return this;
}

viz::FrameSinkId GpuProcessTransportFactory::AllocateFrameSinkId() {
  return frame_sink_id_allocator_.NextFrameSinkId();
}

viz::HostFrameSinkManager*
GpuProcessTransportFactory::GetHostFrameSinkManager() {
  return BrowserMainLoop::GetInstance()->host_frame_sink_manager();
}

void GpuProcessTransportFactory::SetDisplayVisible(ui::Compositor* compositor,
                                                   bool visible) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  // The compositor will always SetVisible on the Display once it is set up, so
  // do nothing if |display| is null.
  if (data->display)
    data->display->SetVisible(visible);
}

void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor,
                                               const gfx::Size& size) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  if (data->display)
    data->display->Resize(size);
}

void GpuProcessTransportFactory::SetDisplayColorSpace(
    ui::Compositor* compositor,
    const gfx::ColorSpace& blending_color_space,
    const gfx::ColorSpace& output_color_space) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  // The compositor will always SetColorSpace on the Display once it is set up,
  // so do nothing if |display| is null.
  if (data->display)
    data->display->SetColorSpace(blending_color_space, output_color_space);
}

void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval(
    ui::Compositor* compositor,
    base::TimeDelta interval) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  if (data->synthetic_begin_frame_source)
    data->synthetic_begin_frame_source->SetAuthoritativeVSyncInterval(interval);
}

void GpuProcessTransportFactory::SetDisplayVSyncParameters(
    ui::Compositor* compositor,
    base::TimeTicks timebase,
    base::TimeDelta interval) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  if (data->synthetic_begin_frame_source) {
    data->synthetic_begin_frame_source->OnUpdateVSyncParameters(timebase,
                                                                interval);
  } else if (data->gpu_vsync_begin_frame_source) {
    data->gpu_vsync_begin_frame_source->OnVSync(timebase, interval);
  }
}

void GpuProcessTransportFactory::IssueExternalBeginFrame(
    ui::Compositor* compositor,
    const viz::BeginFrameArgs& args) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  if (data->external_begin_frame_controller) {
    data->external_begin_frame_controller->IssueExternalBeginFrame(args);
    // Ensure that Display will receive the BeginFrame (as a missed one), even
    // if it doesn't currently need it. This way, we ensure that
    // OnDisplayDidFinishFrame will be called for this BeginFrame.
    data->display->SetNeedsOneBeginFrame();
  } else {
    DLOG(WARNING) << "IssueExternalBeginFrame called for compositor without "
                     "ExternalBeginFrameController";
    // Still send an ack back to unblock the client.
    compositor->OnDisplayDidFinishFrame(
        viz::BeginFrameAck(args.source_id, args.sequence_number, false));
  }
}

void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
                                                   bool secure) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  data->output_is_secure = secure;
  if (data->display)
    data->display->SetOutputIsSecure(secure);
}

const viz::ResourceSettings& GpuProcessTransportFactory::GetResourceSettings()
    const {
  return renderer_settings_.resource_settings;
}

void GpuProcessTransportFactory::AddObserver(
    ui::ContextFactoryObserver* observer) {
  observer_list_.AddObserver(observer);
}

void GpuProcessTransportFactory::RemoveObserver(
    ui::ContextFactoryObserver* observer) {
  observer_list_.RemoveObserver(observer);
}

viz::FrameSinkManagerImpl* GpuProcessTransportFactory::GetFrameSinkManager() {
  return BrowserMainLoop::GetInstance()->GetFrameSinkManager();
}

viz::GLHelper* GpuProcessTransportFactory::GetGLHelper() {
  if (!gl_helper_ && !per_compositor_data_.empty()) {
    scoped_refptr<ContextProvider> provider = SharedMainThreadContextProvider();
    if (provider.get())
      gl_helper_.reset(
          new viz::GLHelper(provider->ContextGL(), provider->ContextSupport()));
  }
  return gl_helper_.get();
}

#if defined(OS_MACOSX)
void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
    ui::Compositor* compositor,
    bool suspended) {
  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
  if (it == per_compositor_data_.end())
    return;
  PerCompositorData* data = it->second.get();
  DCHECK(data);
  if (data->display_output_surface)
    data->display_output_surface->SetSurfaceSuspendedForRecycle(suspended);
}
#endif

scoped_refptr<ContextProvider>
GpuProcessTransportFactory::SharedMainThreadContextProvider() {
  if (is_gpu_compositing_disabled_)
    return nullptr;

  if (shared_main_thread_contexts_)
    return shared_main_thread_contexts_;

  scoped_refptr<gpu::GpuChannelHost> gpu_channel_host =
      gpu_channel_factory_->EstablishGpuChannelSync(nullptr);
  if (!gpu_channel_host ||
      gpu_channel_host->gpu_feature_info()
              .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
          gpu::kGpuFeatureStatusEnabled) {
    DisableGpuCompositing(nullptr);
    if (gpu_channel_host)
      gpu_channel_host->DestroyChannel();
    return nullptr;
  }

  // We need a separate context from the compositor's so that skia and gl_helper
  // don't step on each other.
  bool need_alpha_channel = false;
  bool support_locking = false;
  shared_main_thread_contexts_ = CreateContextCommon(
      std::move(gpu_channel_host), gpu::kNullSurfaceHandle, need_alpha_channel,
      false, support_locking, nullptr,
      ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT);
  shared_main_thread_contexts_->AddObserver(this);
  auto result = shared_main_thread_contexts_->BindToCurrentThread();
  if (result != gpu::ContextResult::kSuccess) {
    shared_main_thread_contexts_->RemoveObserver(this);
    shared_main_thread_contexts_ = nullptr;
  }
  return shared_main_thread_contexts_;
}

GpuProcessTransportFactory::PerCompositorData*
GpuProcessTransportFactory::CreatePerCompositorData(
    ui::Compositor* compositor) {
  DCHECK(!per_compositor_data_[compositor]);

  gfx::AcceleratedWidget widget = compositor->widget();

  auto data = std::make_unique<PerCompositorData>();
  if (widget == gfx::kNullAcceleratedWidget) {
    data->surface_handle = gpu::kNullSurfaceHandle;
  } else {
#if defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
    data->surface_handle = widget;
#else
    gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get();
    data->surface_handle = tracker->AddSurfaceForNativeWidget(
        gpu::GpuSurfaceTracker::SurfaceRecord(widget));
#endif
  }

  PerCompositorData* return_ptr = data.get();
  per_compositor_data_[compositor] = std::move(data);
  return return_ptr;
}

void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
  LOG(ERROR) << "Lost UI shared context.";

  // Keep old resources around while we call the observers, but ensure that
  // new resources are created if needed.
  // Kill shared contexts for both threads in tandem so they are always in
  // the same share group.
  if (shared_main_thread_contexts_)
    shared_main_thread_contexts_->RemoveObserver(this);
  scoped_refptr<ContextProvider> lost_shared_main_thread_contexts =
      shared_main_thread_contexts_;
  shared_main_thread_contexts_ = nullptr;

  std::unique_ptr<viz::GLHelper> lost_gl_helper = std::move(gl_helper_);

  for (auto& observer : observer_list_)
    observer.OnLostResources();

  // Kill things that use the shared context before killing the shared context.
  lost_gl_helper.reset();
  lost_shared_main_thread_contexts = nullptr;
}

scoped_refptr<viz::VulkanInProcessContextProvider>
GpuProcessTransportFactory::SharedVulkanContextProvider() {
  if (!shared_vulkan_context_provider_initialized_) {
    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableVulkan)) {
      shared_vulkan_context_provider_ =
          viz::VulkanInProcessContextProvider::Create();
    }

    shared_vulkan_context_provider_initialized_ = true;
  }
  return shared_vulkan_context_provider_;
}

void GpuProcessTransportFactory::OnContextLost() {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
                     callback_factory_.GetWeakPtr()));
}

scoped_refptr<ui::ContextProviderCommandBuffer>
GpuProcessTransportFactory::CreateContextCommon(
    scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
    gpu::SurfaceHandle surface_handle,
    bool need_alpha_channel,
    bool need_stencil_bits,
    bool support_locking,
    ui::ContextProviderCommandBuffer* shared_context_provider,
    ui::command_buffer_metrics::ContextType type) {
  DCHECK(gpu_channel_host);
  DCHECK(!is_gpu_compositing_disabled_);

  // All browser contexts get the same stream id because we don't use sync
  // tokens for browser surfaces.
  int32_t stream_id = content::kGpuStreamIdDefault;
  gpu::SchedulingPriority stream_priority = content::kGpuStreamPriorityUI;

  // This is called from a few places to create different contexts:
  // - The shared main thread context (offscreen).
  // - The compositor context, which is used by the browser compositor
  //   (offscreen) for synchronization mostly, and by the display compositor
  //   (onscreen, except for with mus) for actual GL drawing.
  // - The compositor worker context (offscreen) used for GPU raster.
  // So ask for capabilities needed by any of these cases (we can optimize by
  // branching on |surface_handle| being null if these needs diverge).
  //
  // The default framebuffer for an offscreen context is not used, so it does
  // not need alpha, stencil, depth, antialiasing. The display compositor does
  // not use these things either (except for alpha when using mus for
  // non-opaque ui that overlaps the system's window borders or stencil bits
  // for overdraw feedback), so we can request only that when needed.
  gpu::gles2::ContextCreationAttribHelper attributes;
  attributes.alpha_size = need_alpha_channel ? 8 : -1;
  attributes.depth_size = 0;
  attributes.stencil_size = need_stencil_bits ? 8 : 0;
  attributes.samples = 0;
  attributes.sample_buffers = 0;
  attributes.bind_generates_resource = false;
  attributes.lose_context_when_out_of_memory = true;
  attributes.buffer_preserved = false;

  constexpr bool automatic_flushes = false;

  GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
  return base::MakeRefCounted<ui::ContextProviderCommandBuffer>(
      std::move(gpu_channel_host), stream_id, stream_priority, surface_handle,
      url, automatic_flushes, support_locking, gpu::SharedMemoryLimits(),
      attributes, shared_context_provider, type);
}

}  // namespace content
