// Copyright 2016 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 MAPPED_BATCH_H
#define MAPPED_BATCH_H

#include <lib/magma/platform/platform_bus_mapper.h>
#include <lib/magma/platform/platform_semaphore.h>

#include "device_id.h"
#include "gpu_mapping.h"
#include "msd_intel_buffer.h"
#include "sequencer.h"

class MsdIntelContext;

class MappedBatch {
 public:
  enum BatchType {
    UNKNOWN,
    SIMPLE_BATCH,
    COMMAND_BUFFER,
    MAPPING_RELEASE_BATCH,
    PIPELINE_FENCE_BATCH,
    INDIRECT_CONTEXT_BATCH,
  };

  explicit MappedBatch(BatchType type = UNKNOWN) : type_(type) {}

  virtual ~MappedBatch() {}

  virtual std::weak_ptr<MsdIntelContext> GetContext() = 0;
  virtual bool GetGpuAddress(gpu_addr_t* gpu_addr_out) = 0;
  virtual void SetSequenceNumber(uint32_t sequence_number) = 0;
  virtual uint64_t GetBatchBufferId() { return 0; }
  virtual uint32_t GetPipeControlFlags() { return 0; }
  virtual BatchType GetType() { return type_; }
  virtual const GpuMappingView* GetBatchMapping() = 0;

  void scheduled() { scheduled_ = true; }
  bool was_scheduled() { return scheduled_; }

  void set_command_streamer(EngineCommandStreamerId command_streamer) {
    command_streamer_ = command_streamer;
  }

  EngineCommandStreamerId get_command_streamer() { return command_streamer_; }

 private:
  BatchType type_;
  bool scheduled_ = false;
  EngineCommandStreamerId command_streamer_ = RENDER_COMMAND_STREAMER;
};

class SimpleMappedBatch : public MappedBatch {
 public:
  SimpleMappedBatch(std::shared_ptr<MsdIntelContext> context,
                    std::unique_ptr<GpuMapping> batch_buffer_mapping)
      : MappedBatch(SIMPLE_BATCH),
        context_(std::move(context)),
        batch_buffer_mapping_(std::move(batch_buffer_mapping)) {}

  std::weak_ptr<MsdIntelContext> GetContext() override { return context_; }

  bool GetGpuAddress(gpu_addr_t* gpu_addr_out) override {
    *gpu_addr_out = batch_buffer_mapping_->gpu_addr();
    return true;
  }

  void SetSequenceNumber(uint32_t sequence_number) override { sequence_number_ = sequence_number; }

  const GpuMappingView* GetBatchMapping() override { return batch_buffer_mapping_.get(); }

 private:
  std::shared_ptr<MsdIntelContext> context_;
  std::unique_ptr<GpuMapping> batch_buffer_mapping_;
  uint32_t sequence_number_ = Sequencer::kInvalidSequenceNumber;
};

// Has no batch.
class NullBatch : public MappedBatch {
 public:
  explicit NullBatch(BatchType type) : MappedBatch(type) {}

  bool GetGpuAddress(gpu_addr_t* gpu_addr_out) override { return false; }
  void SetSequenceNumber(uint32_t sequence_number) override {}
  const GpuMappingView* GetBatchMapping() override { return nullptr; }
};

// Releases the list of bus mappings when destroyed.
class MappingReleaseBatch : public NullBatch {
 public:
  struct BusMappingsWrapper {
    std::vector<std::unique_ptr<magma::PlatformBusMapper::BusMapping>> bus_mappings;
  };

  explicit MappingReleaseBatch(std::shared_ptr<BusMappingsWrapper> wrapper)
      : NullBatch(MAPPING_RELEASE_BATCH), wrapper_(std::move(wrapper)) {}

  void SetContext(std::shared_ptr<MsdIntelContext> context) { context_ = std::move(context); }

  std::weak_ptr<MsdIntelContext> GetContext() override { return context_; }

  BusMappingsWrapper* wrapper() { return wrapper_.get(); }

 private:
  std::shared_ptr<MsdIntelContext> context_;
  std::shared_ptr<BusMappingsWrapper> wrapper_;
};

// Signals an event upon completion.
class PipelineFenceBatch : public NullBatch {
 public:
  explicit PipelineFenceBatch(std::shared_ptr<MsdIntelContext> context,
                              std::shared_ptr<magma::PlatformSemaphore> event)
      : NullBatch(PIPELINE_FENCE_BATCH), context_(std::move(context)), event_(std::move(event)) {}

  ~PipelineFenceBatch() override { event_->Signal(); }

  std::weak_ptr<MsdIntelContext> GetContext() override { return context_; }

 private:
  std::shared_ptr<MsdIntelContext> context_;
  std::shared_ptr<magma::PlatformSemaphore> event_;
};

// The "indirect context" batch is intended to execute on all context switches.
class IndirectContextBatch : public MappedBatch {
 public:
  IndirectContextBatch(std::unique_ptr<GpuMapping> batch_buffer_mapping, uint32_t length)
      : MappedBatch(INDIRECT_CONTEXT_BATCH),
        batch_buffer_mapping_(std::move(batch_buffer_mapping)),
        length_(length) {
    // Length must be cache line aligned.
    DASSERT(length % DeviceId::cache_line_size() == 0);
  }

  uint32_t length() const { return length_; }

  std::weak_ptr<MsdIntelContext> GetContext() override { return {}; }

  bool GetGpuAddress(gpu_addr_t* gpu_addr_out) override {
    *gpu_addr_out = batch_buffer_mapping_->gpu_addr();
    return true;
  }

  void SetSequenceNumber(uint32_t sequence_number) override { DASSERT(false); }

  const GpuMappingView* GetBatchMapping() override { return batch_buffer_mapping_.get(); }

 private:
  std::unique_ptr<GpuMapping> batch_buffer_mapping_;
  uint32_t length_;
};

#endif  // MAPPED_BATCH_H
