// 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.

#ifndef UI_COMPOSITOR_COMPOSITOR_H_
#define UI_COMPOSITOR_COMPOSITOR_H_

#include <stdint.h>

#include <memory>
#include <string>

#include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "cc/paint/element_id.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/host/host_frame_sink_client.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom-forward.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkMatrix44.h"
#include "ui/compositor/compositor_animation_observer.h"
#include "ui/compositor/compositor_export.h"
#include "ui/compositor/compositor_lock.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/layer_animator_collection.h"
#include "ui/compositor/throughput_tracker.h"
#include "ui/compositor/throughput_tracker_host.h"
#include "ui/gfx/display_color_spaces.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/overlay_transform.h"

namespace base {
class SingleThreadTaskRunner;
}

namespace cc {
class AnimationHost;
class AnimationTimeline;
class Layer;
class LayerTreeDebugState;
class LayerTreeFrameSink;
class TaskGraphRunner;
}

namespace gfx {
struct PresentationFeedback;
class Rect;
class ScrollOffset;
class Size;
}

namespace gpu {
class GpuMemoryBufferManager;
}

namespace viz {
namespace mojom {
class DisplayPrivate;
class ExternalBeginFrameController;
class DelegatedInkPointRenderer;
}  // namespace mojom
class ContextProvider;
class HostFrameSinkManager;
class LocalSurfaceId;
class RasterContextProvider;
}

namespace ui {
class Compositor;
class Layer;
class ScopedAnimationDurationScaleMode;
class ScrollInputHandler;
class ThroughputTracker;
struct PendingBeginFrameArgs;

constexpr int kCompositorLockTimeoutMs = 67;

// This class abstracts the creation of the 3D context for the compositor. It is
// a global object.
class COMPOSITOR_EXPORT ContextFactory {
 public:
  virtual ~ContextFactory() {}

  // Creates an output surface for the given compositor. The factory may keep
  // per-compositor data (e.g. a shared context), that needs to be cleaned up
  // by calling RemoveCompositor when the compositor gets destroyed.
  virtual void CreateLayerTreeFrameSink(
      base::WeakPtr<Compositor> compositor) = 0;

  // Return a reference to a shared offscreen context provider usable from the
  // main thread.
  virtual scoped_refptr<viz::ContextProvider>
  SharedMainThreadContextProvider() = 0;

  // Return a reference to a shared offscreen context provider usable from the
  // main thread.
  virtual scoped_refptr<viz::RasterContextProvider>
  SharedMainThreadRasterContextProvider() = 0;

  // Destroys per-compositor data.
  virtual void RemoveCompositor(Compositor* compositor) = 0;

  // Gets the GPU memory buffer manager.
  virtual gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() = 0;

  // Gets the task graph runner.
  virtual cc::TaskGraphRunner* GetTaskGraphRunner() = 0;

  // Allocate a new client ID for the display compositor.
  virtual viz::FrameSinkId AllocateFrameSinkId() = 0;

  // Gets the frame sink manager host instance.
  virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0;
};

// Compositor object to take care of GPU painting.
// A Browser compositor object is responsible for generating the final
// displayable form of pixels comprising a single widget's contents. It draws an
// appropriately transformed texture for each transformed view in the widget's
// view hierarchy.
class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
                                     public cc::LayerTreeHostSingleThreadClient,
                                     public viz::HostFrameSinkClient,
                                     public ThroughputTrackerHost {
 public:
  Compositor(const viz::FrameSinkId& frame_sink_id,
             ui::ContextFactory* context_factory,
             scoped_refptr<base::SingleThreadTaskRunner> task_runner,
             bool enable_pixel_canvas,
             bool use_external_begin_frame_control = false,
             bool force_software_compositor = false);
  ~Compositor() override;

  ui::ContextFactory* context_factory() { return context_factory_; }

  void AddChildFrameSink(const viz::FrameSinkId& frame_sink_id);
  void RemoveChildFrameSink(const viz::FrameSinkId& frame_sink_id);

  void SetLayerTreeFrameSink(std::unique_ptr<cc::LayerTreeFrameSink> surface,
                             viz::mojom::DisplayPrivate* display_private);
  void SetExternalBeginFrameController(viz::mojom::ExternalBeginFrameController*
                                           external_begin_frame_controller);

  // Called when a child surface is about to resize.
  void OnChildResizing();

  // Schedules a redraw of the layer tree associated with this compositor.
  void ScheduleDraw();

  // Sets the root of the layer tree drawn by this Compositor. The root layer
  // must have no parent. The compositor's root layer is reset if the root layer
  // is destroyed. NULL can be passed to reset the root layer, in which case the
  // compositor will stop drawing anything.
  // The Compositor does not own the root layer.
  const Layer* root_layer() const { return root_layer_; }
  Layer* root_layer() { return root_layer_; }
  void SetRootLayer(Layer* root_layer);

  cc::AnimationTimeline* GetAnimationTimeline() const;

  // The scale factor of the device that this compositor is
  // compositing layers on.
  float device_scale_factor() const { return device_scale_factor_; }

  // Gets and sets the color matrix used to transform the output colors of what
  // this compositor renders.
  const SkMatrix44& display_color_matrix() const {
    return display_color_matrix_;
  }
  void SetDisplayColorMatrix(const SkMatrix44& matrix);

  // Where possible, draws are scissored to a damage region calculated from
  // changes to layer properties.  This bypasses that and indicates that
  // the whole frame needs to be drawn.
  void ScheduleFullRedraw();

  // Schedule redraw and append damage_rect to the damage region calculated
  // from changes to layer properties.
  void ScheduleRedrawRect(const gfx::Rect& damage_rect);

#if defined(OS_WIN)
  // Until this is called with |should| true then both DisableSwapUntilResize()
  // and ReenableSwap() do nothing.
  void SetShouldDisableSwapUntilResize(bool should);

  // Attempts to immediately swap a frame with the current size if possible,
  // then disables swapping on this surface until it is resized.
  void DisableSwapUntilResize();
  void ReenableSwap();
#endif

  // Sets the compositor's device scale factor and size.
  void SetScaleAndSize(float scale,
                       const gfx::Size& size_in_pixel,
                       const viz::LocalSurfaceId& local_surface_id);

  // Set the output color profile into which this compositor should render. Also
  // sets the SDR white level (in nits) used to scale HDR color space primaries.
  void SetDisplayColorSpaces(
      const gfx::DisplayColorSpaces& display_color_spaces);

  // Set the transform/rotation info for the display output surface.
  void SetDisplayTransformHint(gfx::OverlayTransform hint);
  gfx::OverlayTransform display_transform_hint() const {
    return host_->display_transform_hint();
  }

  // Returns the size of the widget that is being drawn to in pixel coordinates.
  const gfx::Size& size() const { return size_; }

  // Sets the background color used for areas that aren't covered by
  // the |root_layer|.
  void SetBackgroundColor(SkColor color);

  // Inform the display corresponding to this compositor if it is visible. When
  // false it does not need to produce any frames. Visibility is reset for each
  // call to CreateLayerTreeFrameSink.
  void SetVisible(bool visible);

  // Gets the visibility of the underlying compositor.
  bool IsVisible();

  // Gets or sets the scroll offset for the given layer in step with the
  // cc::InputHandler. Returns true if the layer is active on the impl side.
  bool GetScrollOffsetForLayer(cc::ElementId element_id,
                               gfx::ScrollOffset* offset) const;
  bool ScrollLayerTo(cc::ElementId element_id, const gfx::ScrollOffset& offset);

  // Mac path for transporting vsync parameters to the display. Other platforms
  // update it via the BrowserCompositorLayerTreeFrameSink directly.
  void SetDisplayVSyncParameters(base::TimeTicks timebase,
                                 base::TimeDelta interval);
  void AddVSyncParameterObserver(
      mojo::PendingRemote<viz::mojom::VSyncParameterObserver> observer);

  // Sets the widget for the compositor to render into.
  void SetAcceleratedWidget(gfx::AcceleratedWidget widget);
  // Releases the widget previously set through SetAcceleratedWidget().
  // After returning it will not be used for rendering anymore.
  // The compositor must be set to invisible when taking away a widget.
  gfx::AcceleratedWidget ReleaseAcceleratedWidget();
  gfx::AcceleratedWidget widget() const;

  // This flag is used to force a compositor into software compositing even tho
  // in general chrome is using gpu compositing. This allows the compositor to
  // be created without a gpu context, and does not go through the gpu path at
  // all. This flag can not be used with a compositor that embeds any external
  // content via a SurfaceLayer, as they would not agree on what compositing
  // mode to use for resources, but may be used eg for tooltip windows.
  bool force_software_compositor() { return force_software_compositor_; }

  // Returns the main thread task runner this compositor uses. Users of the
  // compositor generally shouldn't use this.
  scoped_refptr<base::SingleThreadTaskRunner> task_runner() const {
    return task_runner_;
  }

  // Compositor does not own observers. It is the responsibility of the
  // observer to remove itself when it is done observing.
  void AddObserver(CompositorObserver* observer);
  void RemoveObserver(CompositorObserver* observer);
  bool HasObserver(const CompositorObserver* observer) const;

  void AddAnimationObserver(CompositorAnimationObserver* observer);
  void RemoveAnimationObserver(CompositorAnimationObserver* observer);
  bool HasAnimationObserver(const CompositorAnimationObserver* observer) const;

  // Creates a compositor lock. Returns NULL if it is not possible to lock at
  // this time (i.e. we're waiting to complete a previous unlock). If the
  // timeout is null, then no timeout is used.
  std::unique_ptr<CompositorLock> GetCompositorLock(
      CompositorLockClient* client,
      base::TimeDelta timeout =
          base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)) {
    return lock_manager_.GetCompositorLock(client, timeout,
                                           host_->DeferMainFrameUpdate());
  }

  // Registers a callback that is run when the next frame successfully makes it
  // to the screen (it's entirely possible some frames may be dropped between
  // the time this is called and the callback is run).
  // See ui/gfx/presentation_feedback.h for details on the args (TimeTicks is
  // always non-zero).
  using PresentationTimeCallback =
      base::OnceCallback<void(const gfx::PresentationFeedback&)>;
  void RequestPresentationTimeForNextFrame(PresentationTimeCallback callback);

  void IssueExternalBeginFrame(
      const viz::BeginFrameArgs& args,
      bool force,
      base::OnceCallback<void(const viz::BeginFrameAck&)> callback);

  // Creates a ThroughputTracker for tracking this Compositor.
  ThroughputTracker RequestNewThroughputTracker();

  // LayerTreeHostClient implementation.
  void WillBeginMainFrame() override {}
  void DidBeginMainFrame() override {}
  void OnDeferMainFrameUpdatesChanged(bool) override {}
  void OnDeferCommitsChanged(bool) override {}
  void WillUpdateLayers() override {}
  void DidUpdateLayers() override;
  void BeginMainFrame(const viz::BeginFrameArgs& args) override;
  void BeginMainFrameNotExpectedSoon() override;
  void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override;
  void UpdateLayerTreeHost() override;
  void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override {
  }
  void UpdateCompositorScrollState(
      const cc::CompositorCommitData& commit_data) override {}
  void RequestNewLayerTreeFrameSink() override;
  void DidInitializeLayerTreeFrameSink() override {}
  void DidFailToInitializeLayerTreeFrameSink() override;
  void WillCommit() override {}
  void DidCommit(base::TimeTicks) override;
  void DidCommitAndDrawFrame() override {}
  void DidReceiveCompositorFrameAck() override;
  void DidCompletePageScaleAnimation() override {}
  void DidPresentCompositorFrame(
      uint32_t frame_token,
      const gfx::PresentationFeedback& feedback) override;
  void RecordStartOfFrameMetrics() override {}
  void RecordEndOfFrameMetrics(
      base::TimeTicks frame_begin_time,
      cc::ActiveFrameSequenceTrackers trackers) override {}
  std::unique_ptr<cc::BeginMainFrameMetrics> GetBeginMainFrameMetrics()
      override;
  std::unique_ptr<cc::WebVitalMetrics> GetWebVitalMetrics() override;
  void NotifyThroughputTrackerResults(
      cc::CustomTrackerResults results) override;
  void DidObserveFirstScrollDelay(
      base::TimeDelta first_scroll_delay,
      base::TimeTicks first_scroll_timestamp) override {}

  // cc::LayerTreeHostSingleThreadClient implementation.
  void DidSubmitCompositorFrame() override;
  void DidLoseLayerTreeFrameSink() override {}
  void FrameIntervalUpdated(base::TimeDelta interval) override;

  // viz::HostFrameSinkClient implementation.
  void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
  void OnFrameTokenChanged(uint32_t frame_token) override;

  // ThroughputTrackerHost implementation.
  void StartThroughputTracker(
      TrackerId tracker_id,
      ThroughputTrackerHost::ReportCallback callback) override;
  void StopThroughtputTracker(TrackerId tracker_id) override;
  void CancelThroughtputTracker(TrackerId tracker_id) override;

// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
// of lacros-chrome is complete.
#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
  void OnCompleteSwapWithNewSize(const gfx::Size& size);
#endif

  bool IsLocked() { return lock_manager_.IsLocked(); }

  void SetOutputIsSecure(bool output_is_secure);

  const cc::LayerTreeDebugState& GetLayerTreeDebugState() const;
  void SetLayerTreeDebugState(const cc::LayerTreeDebugState& debug_state);

  LayerAnimatorCollection* layer_animator_collection() {
    return &layer_animator_collection_;
  }

  const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }
  int activated_frame_count() const { return activated_frame_count_; }
  float refresh_rate() const { return refresh_rate_; }

  bool use_external_begin_frame_control() const {
    return use_external_begin_frame_control_;
  }

  void SetAllowLocksToExtendTimeout(bool allowed) {
    lock_manager_.set_allow_locks_to_extend_timeout(allowed);
  }

  // If true, all paint commands are recorded at pixel size instead of DIP.
  bool is_pixel_canvas() const { return is_pixel_canvas_; }

  ScrollInputHandler* scroll_input_handler() const {
    return scroll_input_handler_.get();
  }

  virtual void SetDelegatedInkPointRenderer(
      mojo::PendingReceiver<viz::mojom::DelegatedInkPointRenderer> receiver);

 private:
  friend class base::RefCounted<Compositor>;
  friend class TotalAnimationThroughputReporter;

  // Called when collected metrics for the tracker of |tracker_id| is ready.
  void ReportMetricsForTracker(
      int tracker_id,
      const cc::FrameSequenceMetrics::CustomReportData& data);

  gfx::Size size_;

  ui::ContextFactory* context_factory_;

  // |display_private_| can be null for:
  // 1. Tests that don't set |display_private_|.
  // 2. Intermittently on creation or if there is some kind of error (GPU crash,
  //    GL context loss, etc.) that triggers reinitializing message pipes to the
  //    GPU process RootCompositorFrameSinkImpl.
  // Therefore, it should always be null checked for safety before use.
  //
  // These pointers are owned by |context_factory_|, and must be reset before
  // calling RemoveCompositor();
  viz::mojom::DisplayPrivate* display_private_ = nullptr;
  viz::mojom::ExternalBeginFrameController* external_begin_frame_controller_ =
      nullptr;

  std::unique_ptr<PendingBeginFrameArgs> pending_begin_frame_args_;

  // The root of the Layer tree drawn by this compositor.
  Layer* root_layer_ = nullptr;

  base::ObserverList<CompositorObserver, true>::Unchecked observer_list_;
  base::ObserverList<CompositorAnimationObserver>::Unchecked
      animation_observer_list_;

  gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
  // A sequence number of a current compositor frame for use with metrics.
  int activated_frame_count_ = 0;

  // Current vsync refresh rate per second. Initialized to 60hz as a reasonable
  // value until first begin frame arrives with the real refresh rate.
  float refresh_rate_ = 60.f;

  // A map from child id to parent id.
  std::unordered_set<viz::FrameSinkId, viz::FrameSinkIdHash> child_frame_sinks_;
  bool widget_valid_ = false;
  bool layer_tree_frame_sink_requested_ = false;
  const viz::FrameSinkId frame_sink_id_;
  scoped_refptr<cc::Layer> root_web_layer_;
  std::unique_ptr<cc::AnimationHost> animation_host_;
  std::unique_ptr<cc::LayerTreeHost> host_;
  base::WeakPtr<cc::InputHandler> input_handler_weak_;
  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;

  // Snapshot of last set vsync parameters, to avoid redundant IPCs.
  base::TimeTicks vsync_timebase_;
  base::TimeDelta vsync_interval_ = viz::BeginFrameArgs::DefaultInterval();
  bool has_vsync_params_ = false;

  const bool use_external_begin_frame_control_;
  const bool force_software_compositor_;

  // The device scale factor of the monitor that this compositor is compositing
  // layers on.
  float device_scale_factor_ = 0.f;

  LayerAnimatorCollection layer_animator_collection_;
  scoped_refptr<cc::AnimationTimeline> animation_timeline_;
  std::unique_ptr<ScopedAnimationDurationScaleMode> slow_animations_;

  SkMatrix44 display_color_matrix_;
  gfx::DisplayColorSpaces display_color_spaces_;

  bool output_is_secure_ = false;

  // If true, all paint commands are recorded at pixel size instead of DIP.
  const bool is_pixel_canvas_;

  CompositorLockManager lock_manager_;

  std::unique_ptr<ScrollInputHandler> scroll_input_handler_;

#if defined(OS_WIN)
  bool should_disable_swap_until_resize_ = false;
#endif

  // Set in DisableSwapUntilResize and reset when a resize happens.
  bool disabled_swap_until_resize_ = false;

  TrackerId next_throughput_tracker_id_ = 1u;
  using ThroughputTrackerMap =
      base::flat_map<TrackerId, ThroughputTrackerHost::ReportCallback>;
  ThroughputTrackerMap throughput_tracker_map_;

  base::WeakPtrFactory<Compositor> context_creation_weak_ptr_factory_{this};
  base::WeakPtrFactory<Compositor> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(Compositor);
};

}  // namespace ui

#endif  // UI_COMPOSITOR_COMPOSITOR_H_
