// Copyright 2013 The Flutter 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 FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
#define FLUTTER_IMPELLER_RENDERER_PIPELINE_H_

#include <future>

#include "compute_pipeline_descriptor.h"
#include "impeller/renderer/compute_pipeline_builder.h"
#include "impeller/renderer/compute_pipeline_descriptor.h"
#include "impeller/renderer/context.h"
#include "impeller/renderer/pipeline_builder.h"
#include "impeller/renderer/pipeline_descriptor.h"

namespace impeller {

class PipelineLibrary;
template <typename PipelineDescriptor_>
class Pipeline;

template <typename T>
struct PipelineFuture {
  std::optional<T> descriptor;
  std::shared_future<std::shared_ptr<Pipeline<T>>> future;

  const std::shared_ptr<Pipeline<T>> Get() const { return future.get(); }

  bool IsValid() const { return future.valid(); }
};

//------------------------------------------------------------------------------
/// @brief      Describes the fixed function and programmable aspects of
///             rendering and compute operations performed by commands submitted
///             to the GPU via a command buffer.
///
///             A pipeline handle must be allocated upfront and kept alive for
///             as long as possible. Do not create a pipeline object within a
///             frame workload.
///
///             This pipeline object is almost never used directly as it is
///             untyped. Use reflected shader information generated by the
///             Impeller offline shader compiler to generate a typed pipeline
///             object.
///
template <typename T>
class Pipeline {
 public:
  virtual ~Pipeline();

  virtual bool IsValid() const = 0;

  //----------------------------------------------------------------------------
  /// @brief      Get the descriptor that was responsible for creating this
  ///             pipeline. It may be copied and modified to create a pipeline
  ///             variant.
  ///
  /// @return     The descriptor.
  ///
  const T& GetDescriptor() const;

  PipelineFuture<T> CreateVariant(
      std::function<void(T& desc)> descriptor_callback) const;

 protected:
  const std::weak_ptr<PipelineLibrary> library_;

  const T desc_;

  Pipeline(std::weak_ptr<PipelineLibrary> library, T desc);

 private:
  Pipeline(const Pipeline&) = delete;

  Pipeline& operator=(const Pipeline&) = delete;
};

extern template class Pipeline<PipelineDescriptor>;
extern template class Pipeline<ComputePipelineDescriptor>;

PipelineFuture<PipelineDescriptor> CreatePipelineFuture(
    const Context& context,
    std::optional<PipelineDescriptor> desc);

PipelineFuture<ComputePipelineDescriptor> CreatePipelineFuture(
    const Context& context,
    std::optional<ComputePipelineDescriptor> desc);

template <class VertexShader_, class FragmentShader_>
class RenderPipelineT {
 public:
  using VertexShader = VertexShader_;
  using FragmentShader = FragmentShader_;
  using Builder = PipelineBuilder<VertexShader, FragmentShader>;

  explicit RenderPipelineT(const Context& context)
      : RenderPipelineT(CreatePipelineFuture(
            context,
            Builder::MakeDefaultPipelineDescriptor(context))) {}

  explicit RenderPipelineT(const Context& context,
                           std::optional<PipelineDescriptor> desc)
      : RenderPipelineT(CreatePipelineFuture(context, desc)) {}

  explicit RenderPipelineT(PipelineFuture<PipelineDescriptor> future)
      : pipeline_future_(std::move(future)) {}

  std::shared_ptr<Pipeline<PipelineDescriptor>> WaitAndGet() {
    if (did_wait_) {
      return pipeline_;
    }
    did_wait_ = true;
    if (pipeline_future_.IsValid()) {
      pipeline_ = pipeline_future_.Get();
    }
    return pipeline_;
  }

  std::optional<PipelineDescriptor> GetDescriptor() const {
    return pipeline_future_.descriptor;
  }

 private:
  PipelineFuture<PipelineDescriptor> pipeline_future_;
  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_;
  bool did_wait_ = false;

  RenderPipelineT(const RenderPipelineT&) = delete;

  RenderPipelineT& operator=(const RenderPipelineT&) = delete;
};

template <class ComputeShader_>
class ComputePipelineT {
 public:
  using ComputeShader = ComputeShader_;
  using Builder = ComputePipelineBuilder<ComputeShader>;

  explicit ComputePipelineT(const Context& context)
      : ComputePipelineT(CreatePipelineFuture(
            context,
            Builder::MakeDefaultPipelineDescriptor(context))) {}

  explicit ComputePipelineT(
      const Context& context,
      std::optional<ComputePipelineDescriptor> compute_desc)
      : ComputePipelineT(CreatePipelineFuture(context, compute_desc)) {}

  explicit ComputePipelineT(PipelineFuture<ComputePipelineDescriptor> future)
      : pipeline_future_(std::move(future)) {}

  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> WaitAndGet() {
    if (did_wait_) {
      return pipeline_;
    }
    did_wait_ = true;
    if (pipeline_future_.IsValid()) {
      pipeline_ = pipeline_future_.Get();
    }
    return pipeline_;
  }

 private:
  PipelineFuture<ComputePipelineDescriptor> pipeline_future_;
  std::shared_ptr<Pipeline<ComputePipelineDescriptor>> pipeline_;
  bool did_wait_ = false;

  ComputePipelineT(const ComputePipelineT&) = delete;

  ComputePipelineT& operator=(const ComputePipelineT&) = delete;
};

}  // namespace impeller

#endif  // FLUTTER_IMPELLER_RENDERER_PIPELINE_H_
