// Copyright 2020 The Fuchsia 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 SRC_UI_SCENIC_LIB_FLATLAND_ENGINE_ENGINE_H_
#define SRC_UI_SCENIC_LIB_FLATLAND_ENGINE_ENGINE_H_

#include "src/ui/scenic/lib/display/util.h"
#include "src/ui/scenic/lib/flatland/buffers/buffer_collection_importer.h"
#include "src/ui/scenic/lib/flatland/engine/engine_types.h"

namespace flatland {

// The engine is responsible for compositing Flatland render data onto the display(s).
// It accomplishes this either by direct hardware compositing via the display controller
// interface, or rendering on the GPU via a custom renderer API. It also handles the
// registration of sysmem buffer collections and importation of images to both the
// display controller and the renderer via the BufferCollectionImporter interface. The
// BufferCollectionImporter interface is how Flatland instances communicate with the
// Engine, providing it with the necessary data to render without exposing to Flatland
// the DisplayController or other dependencies.
class Engine final : public BufferCollectionImporter {
 public:
  // TODO(fxbug.dev/66807): The engine has multiple parts of its code where usage of the display
  // controller is protected by locks, because of the multithreaded environment of flatland.
  // Ideally, we'd want the engine to have sole ownership of the display controller - meaning that
  // it would require a unique_ptr instead of a shared_ptr. But since access to the real
  // display controller is provided to clients via a shared_ptr, we take in a shared_ptr as
  // a parameter here. However, this could cause problems with our locking mechanisms, as
  // other display-controller clients could be accessing the same functions and/or state at
  // the same time as the engine without making use of locks.
  Engine(std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> display_controller,
         const std::shared_ptr<Renderer>& renderer, RenderDataFunc render_data_func);

  ~Engine() override;

  // |BufferCollectionImporter|
  bool ImportBufferCollection(
      sysmem_util::GlobalBufferCollectionId collection_id,
      fuchsia::sysmem::Allocator_Sync* sysmem_allocator,
      fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> token) override;

  // |BufferCollectionImporter|
  void ReleaseBufferCollection(sysmem_util::GlobalBufferCollectionId collection_id) override;

  // |BufferCollectionImporter|
  bool ImportBufferImage(const ImageMetadata& metadata) override;

  // |BufferCollectionImporter|
  void ReleaseBufferImage(sysmem_util::GlobalImageId image_id) override;

  // TODO(fxbug.dev/59646): Add in parameters for scheduling, etc. Right now we're just making sure
  // the data is processed correctly.
  void RenderFrame();

  // Register a new display to the engine, which also generates the render targets to be presented
  // on the display when compositing on the GPU. If num_vmos is 0, this function will not create
  // any render targets for GPU composition for that display. Returns the ID for the buffer
  // collection of the render targets. The buffer collection info is also returned back to the
  // caller via an output parameter.
  // TODO(fxbug.dev/59646): We need to figure out exactly how we want the display to anchor
  // to the Flatland hierarchy.
  sysmem_util::GlobalBufferCollectionId AddDisplay(
      uint64_t display_id, DisplayInfo info, fuchsia::sysmem::Allocator_Sync* sysmem_allocator,
      uint32_t num_vmos, fuchsia::sysmem::BufferCollectionInfo_2* collection_info = nullptr);

 private:
  struct DisplayConfigResponse {
    // Whether or not the config can be successfully applied or not.
    fuchsia::hardware::display::ConfigResult result;
    // If the config is invalid, this vector will list all the operations
    // that need to be performed to make the config valid again.
    std::vector<fuchsia::hardware::display::ClientCompositionOp> ops;
  };

  struct FrameEventData {
    scenic_impl::DisplayEventId wait_id;
    scenic_impl::DisplayEventId signal_id;
    zx::event wait_event;
    zx::event signal_event;
  };

  struct DisplayEngineData {
    // The hardware layers we've created to use on this display.
    std::vector<uint64_t> layers;

    // The number of vmos we are using in the case of software composition
    // (1 for each render target).
    uint32_t vmo_count = 0;

    // The current target that is being rendererd to by the software renderer.
    uint32_t curr_vmo = 0;

    // The information used to create images for each render target from the vmo data.
    std::vector<ImageMetadata> targets;

    // Used to synchronize buffer rendering with setting the buffer on the display.
    std::vector<FrameEventData> frame_event_datas;
  };

  // Generates a new FrameEventData struct to be used with a render target on a display.
  FrameEventData NewFrameEventData();

  // Generates a hardware layer for direct compositing on the display. Returns the ID used
  // to reference that layer in the display controller API.
  uint64_t CreateDisplayLayer();

  // Does all the setup for applying the render data, which includes images and rectangles,
  // onto the display via the display controller interface. Returns false if this cannot
  // be completed.
  bool SetRenderDataOnDisplay(const RenderData& data);

  // Sets the provided layers onto the display referenced by the given display_id.
  void SetDisplayLayers(uint64_t display_id, const std::vector<uint64_t>& layers);

  // Takes an image and directly composites it to a hardware layer on the display.
  void ApplyLayerImage(uint32_t layer_id, escher::Rectangle2D rectangle, ImageMetadata image,
                       scenic_impl::DisplayEventId wait_id, scenic_impl::DisplayEventId signal_id);

  // Checks if the display controller is capable of applying the configuration settings that
  // have been set up until that point
  DisplayConfigResponse CheckConfig();

  // Erases the configuration that has been set on the display controller.
  void DiscardConfig();

  // Applies the config to the display controller. This should only be called after CheckConfig
  // has verified that the config is okay, since ApplyConfig does not return any errors.
  void ApplyConfig();

  // Returns the image id used by the display controller.
  uint64_t InternalImageId(sysmem_util::GlobalImageId image_id) const;

  // This mutex protects access to |display_controller_| and |image_id_map_|.
  //
  // TODO(fxbug.dev/44335): Convert this to a lock-free structure. This is a unique
  // case since we are talking to a FIDL interface (display_controller_) through a lock.
  // We either need lock-free threadsafe FIDL bindings, multiple channels to the display
  // controller, or something else.
  mutable std::mutex lock_;

  // Handle to the display controller interface.
  std::shared_ptr<fuchsia::hardware::display::ControllerSyncPtr> display_controller_;

  // Maps the flatland global image id to the image id used by the display controller.
  std::unordered_map<sysmem_util::GlobalImageId, uint64_t> image_id_map_;

  // Software renderer used when render data cannot be directly composited to the display.
  std::shared_ptr<Renderer> renderer_;

  // Function used to get render data.
  RenderDataFunc render_data_func_;

  // Maps a display ID to the the DisplayInfo struct. This is kept separate from the
  // display_engine_data_map_ since this only this data is needed for the render_data_func_.
  std::unordered_map<uint64_t, DisplayInfo> display_info_map_;

  // Maps a display ID to a struct of all the information needed to properly render to
  // that display in both the hardware and software composition paths.
  std::unordered_map<uint64_t, DisplayEngineData> display_engine_data_map_;
};

}  // namespace flatland

#endif  // SRC_UI_SCENIC_LIB_FLATLAND_ENGINE_ENGINE_H_
