chromium/android_webview/browser/gfx/viz_compositor_thread_runner_webview.h

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ANDROID_WEBVIEW_BROWSER_GFX_VIZ_COMPOSITOR_THREAD_RUNNER_WEBVIEW_H_
#define ANDROID_WEBVIEW_BROWSER_GFX_VIZ_COMPOSITOR_THREAD_RUNNER_WEBVIEW_H_

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/no_destructor.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "components/viz/service/main/viz_compositor_thread_runner.h"

namespace base {
class Location;
}  // namespace base

namespace viz {
class FrameSinkManagerImpl;
class ServerSharedBitmapManager;
class SharedImageInterfaceProvider;
}  // namespace viz

namespace android_webview {

// This class overrides VizCompositorThreadRunner largely so that
// FrameSinkManagerImpl and other viz classes are connected to their mojo end
// points using the same code path (through VizMainImpl) as other chromium
// platforms. The benefit of this include:
// * code path sharing
// * keep illusion in content and below that webview does not assume
//   in-process gpu
// * no need to introduce more "if webview" conditions in shared code
// However these viz classes actually do not talk to the gpu service
// in VizMainImpl, which may cause confusion for developers. If this proves to
// be common, then an alternative is assume viz runs in the browser process
// and directly connect viz classes to mojo end points in the browser.
//
// Lifetime: Singleton
class VizCompositorThreadRunnerWebView : public viz::VizCompositorThreadRunner {
 public:
  static VizCompositorThreadRunnerWebView* GetInstance();

  VizCompositorThreadRunnerWebView(const VizCompositorThreadRunnerWebView&) =
      delete;
  VizCompositorThreadRunnerWebView& operator=(
      const VizCompositorThreadRunnerWebView&) = delete;

  viz::FrameSinkManagerImpl* GetFrameSinkManager();

  // Must be called on Viz thread.
  base::flat_set<base::PlatformThreadId> GetThreadIds() const;

  // Must be called from the TaskQueueWebView thread. |task| is allowed to call
  // TaskQueueWebView::ScheduleTask.
  void ScheduleOnVizAndBlock(base::OnceClosure task);

  // Can be called from any thread, and blocks the caller until the task
  // finishes executing.
  void PostTaskAndBlock(const base::Location& from_here,
                        base::OnceClosure task);

  viz::GpuServiceImpl* GetGpuService();

  // viz::VizCompositorThreadRunner overrides.
  base::SingleThreadTaskRunner* task_runner() override;
  bool CreateHintSessionFactory(
      base::flat_set<base::PlatformThreadId> thread_ids,
      base::RepeatingClosure* wake_up_closure) override;
  void SetIOThreadId(base::PlatformThreadId io_thread_id) override;
  void CreateFrameSinkManager(viz::mojom::FrameSinkManagerParamsPtr params,
                              viz::GpuServiceImpl* gpu_service) override;

 private:
  friend class base::NoDestructor<VizCompositorThreadRunnerWebView>;

  VizCompositorThreadRunnerWebView();
  ~VizCompositorThreadRunnerWebView() override;

  void InitFrameSinkManagerOnViz();
  void BindFrameSinkManagerOnViz(viz::mojom::FrameSinkManagerParamsPtr params,
                                 viz::GpuServiceImpl* gpu_service_impl);
  void SetIOThreadIdOnViz(base::PlatformThreadId io_thread_id,
                          base::WaitableEvent* event);

  base::Thread viz_thread_;
  scoped_refptr<base::SingleThreadTaskRunner> viz_task_runner_;

  std::unique_ptr<viz::SharedImageInterfaceProvider>
      shared_image_interface_provider_;

  // Only accessed on |viz_task_runner_|.
  THREAD_CHECKER(viz_thread_checker_);
  std::unique_ptr<viz::ServerSharedBitmapManager> server_shared_bitmap_manager_;
  std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_;
  raw_ptr<viz::GpuServiceImpl> gpu_service_impl_ = nullptr;
  base::flat_set<base::PlatformThreadId> thread_ids_;
};

}  // namespace android_webview

#endif  // ANDROID_WEBVIEW_BROWSER_GFX_VIZ_COMPOSITOR_THREAD_RUNNER_WEBVIEW_H_