// Copyright 2018 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_GRAPHICS_DISPLAY_DRIVERS_SIMPLE_SIMPLE_DISPLAY_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_SIMPLE_SIMPLE_DISPLAY_H_

#include <lib/ddk/driver.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>

#include <fbl/mutex.h>

#include "src/graphics/display/lib/api-types-cpp/config-stamp.h"
#include "src/graphics/display/lib/api-types-cpp/driver-buffer-collection-id.h"

#if __cplusplus

#include <fidl/fuchsia.hardware.sysmem/cpp/wire.h>
#include <fidl/fuchsia.images2/cpp/wire.h>
#include <fidl/fuchsia.sysmem/cpp/wire.h>
#include <fidl/fuchsia.sysmem2/cpp/wire.h>
#include <fuchsia/hardware/display/controller/cpp/banjo.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/cpp/wire/server.h>
#include <lib/fit/function.h>
#include <lib/mmio/mmio.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/clock.h>
#include <lib/zx/vmo.h>

#include <atomic>
#include <memory>

#include <ddktl/device.h>

class SimpleDisplay;
using DeviceType = ddk::Device<SimpleDisplay>;
using HeapServer = fidl::WireServer<fuchsia_hardware_sysmem::Heap>;
using BufferKey = std::pair<uint64_t, uint32_t>;
class SimpleDisplay : public DeviceType,
                      public HeapServer,
                      public ddk::DisplayControllerImplProtocol<SimpleDisplay, ddk::base_protocol> {
 public:
  SimpleDisplay(zx_device_t* parent,
                fidl::WireSyncClient<fuchsia_hardware_sysmem::Sysmem> hardware_sysmem,
                fidl::WireSyncClient<fuchsia_sysmem2::Allocator> sysmem,
                fdf::MmioBuffer framebuffer_mmio, uint32_t width, uint32_t height, uint32_t stride,
                fuchsia_images2::wire::PixelFormat format);
  ~SimpleDisplay() = default;

  void DdkRelease();
  zx_status_t Bind(const char* name, std::unique_ptr<SimpleDisplay>* controller_ptr);

  void AllocateVmo(AllocateVmoRequestView request, AllocateVmoCompleter::Sync& completer) override;
  void DeleteVmo(DeleteVmoRequestView request, DeleteVmoCompleter::Sync& completer) override;

  void DisplayControllerImplSetDisplayControllerInterface(
      const display_controller_interface_protocol_t* intf);
  void DisplayControllerImplResetDisplayControllerInterface();
  zx_status_t DisplayControllerImplImportBufferCollection(
      uint64_t banjo_driver_buffer_collection_id, zx::channel collection_token);
  zx_status_t DisplayControllerImplReleaseBufferCollection(
      uint64_t banjo_driver_buffer_collection_id);
  zx_status_t DisplayControllerImplImportImage(const image_metadata_t* image_metadata,
                                               uint64_t banjo_driver_buffer_collection_id,
                                               uint32_t index, uint64_t* out_image_handle);
  zx_status_t DisplayControllerImplImportImageForCapture(uint64_t banjo_driver_buffer_collection_id,
                                                         uint32_t index,
                                                         uint64_t* out_capture_handle) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  void DisplayControllerImplReleaseImage(uint64_t image_handle);
  config_check_result_t DisplayControllerImplCheckConfiguration(
      const display_config_t* display_configs, size_t display_count,
      client_composition_opcode_t* out_client_composition_opcodes_list,
      size_t client_composition_opcodes_count, size_t* out_client_composition_opcodes_actual);
  void DisplayControllerImplApplyConfiguration(const display_config_t* display_config,
                                               size_t display_count,
                                               const config_stamp_t* banjo_config_stamp);
  void DisplayControllerImplSetEld(uint64_t display_id, const uint8_t* raw_eld_list,
                                   size_t raw_eld_count) {}  // No ELD required for non-HDA systems.
  zx_status_t DisplayControllerImplSetBufferCollectionConstraints(
      const image_buffer_usage_t* usage, uint64_t banjo_driver_buffer_collection_id);
  zx_status_t DisplayControllerImplSetDisplayPower(uint64_t display_id, bool power_on) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  bool DisplayControllerImplIsCaptureSupported() { return false; }
  zx_status_t DisplayControllerImplStartCapture(uint64_t capture_handle) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t DisplayControllerImplReleaseCapture(uint64_t capture_handle) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  bool DisplayControllerImplIsCaptureCompleted() { return false; }
  zx_status_t DisplayControllerImplSetMinimumRgb(uint8_t minimum_rgb) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  const std::unordered_map<display::DriverBufferCollectionId,
                           fidl::WireSyncClient<fuchsia_sysmem2::BufferCollection>>&
  GetBufferCollectionsForTesting() const {
    return buffer_collections_;
  }

 private:
  void OnPeriodicVSync();

  fidl::WireSyncClient<fuchsia_hardware_sysmem::Sysmem> hardware_sysmem_;

  // The sysmem allocator client used to bind incoming buffer collection tokens.
  fidl::WireSyncClient<fuchsia_sysmem2::Allocator> sysmem_;

  // Imported sysmem buffer collections.
  std::unordered_map<display::DriverBufferCollectionId,
                     fidl::WireSyncClient<fuchsia_sysmem2::BufferCollection>>
      buffer_collections_;

  async::Loop loop_;

  // protects only framebuffer_key_
  fbl::Mutex framebuffer_key_mtx_;
  std::optional<BufferKey> framebuffer_key_ TA_GUARDED(framebuffer_key_mtx_);

  static_assert(std::atomic<bool>::is_always_lock_free);
  std::atomic<bool> has_image_;

  // A lock is required to ensure the atomicity when setting |config_stamp| in
  // |ApplyConfiguration()| and passing |&config_stamp_| to |OnDisplayVsync()|.
  fbl::Mutex mtx_;
  display::ConfigStamp config_stamp_ TA_GUARDED(mtx_) = display::kInvalidConfigStamp;

  const fdf::MmioBuffer framebuffer_mmio_;
  const uint32_t width_;
  const uint32_t height_;
  const uint32_t stride_;
  const fuchsia_images2::wire::PixelFormat format_;

  const fuchsia_images2::wire::PixelFormatModifier kFormatModifier =
      fuchsia_images2::wire::PixelFormatModifier::kLinear;

  // Only used on the vsync thread.
  zx::time next_vsync_time_;
  ddk::DisplayControllerInterfaceProtocolClient intf_;
};

#endif  // __cplusplus

__BEGIN_CDECLS
zx_status_t bind_simple_pci_display(zx_device_t* dev, const char* name, uint32_t bar,
                                    uint32_t width, uint32_t height, uint32_t stride,
                                    fuchsia_images2::wire::PixelFormat format);

zx_status_t bind_simple_fidl_pci_display(zx_device_t* dev, const char* name, uint32_t bar,
                                         uint32_t width, uint32_t height, uint32_t stride,
                                         fuchsia_images2::wire::PixelFormat format);

zx_status_t bind_simple_pci_display_bootloader(zx_device_t* dev, const char* name, uint32_t bar,
                                               bool use_fidl);
__END_CDECLS

#endif  // SRC_GRAPHICS_DISPLAY_DRIVERS_SIMPLE_SIMPLE_DISPLAY_H_
