// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file contains the command buffer helper class.

#ifndef GPU_COMMAND_BUFFER_CLIENT_CMD_BUFFER_HELPER_H_
#define GPU_COMMAND_BUFFER_CLIENT_CMD_BUFFER_HELPER_H_

#include <stddef.h>
#include <stdint.h>
#include <string.h>

#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/functional/function_ref.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/trace_event/memory_dump_provider.h"
#include "build/build_config.h"
#include "gpu/command_buffer/client/gpu_command_buffer_client_export.h"
#include "gpu/command_buffer/common/cmd_buffer_common.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/context_result.h"

namespace gpu {

class Buffer;

#if !BUILDFLAG(IS_ANDROID)
#define CMD_HELPER_PERIODIC_FLUSH_CHECK
const int kCommandsPerFlushCheck = 100;
const int kPeriodicFlushDelayInMicroseconds = 500;
#endif

const int kAutoFlushSmall = 16;  // 1/16 of the buffer
const int kAutoFlushBig = 2;     // 1/2 of the buffer

// Command buffer helper class. This class simplifies ring buffer management:
// it will allocate the buffer, give it to the buffer interface, and let the
// user add commands to it, while taking care of the synchronization (put and
// get). It also provides a way to ensure commands have been executed, through
// the token mechanism:
//
// helper.AddCommand(...);
// helper.AddCommand(...);
// int32_t token = helper.InsertToken();
// helper.AddCommand(...);
// helper.AddCommand(...);
// [...]
//
// helper.WaitForToken(token);  // this doesn't return until the first two
//                              // commands have been executed.
class GPU_COMMAND_BUFFER_CLIENT_EXPORT CommandBufferHelper {
 public:
  explicit CommandBufferHelper(CommandBuffer* command_buffer);

  CommandBufferHelper(const CommandBufferHelper&) = delete;
  CommandBufferHelper& operator=(const CommandBufferHelper&) = delete;

  virtual ~CommandBufferHelper();

  // Initializes the CommandBufferHelper.
  // Parameters:
  //   ring_buffer_size: The size of the ring buffer portion of the command
  //       buffer.
  gpu::ContextResult Initialize(uint32_t ring_buffer_size);

  // Sets whether the command buffer should automatically flush periodically
  // to try to increase performance. Defaults to true.
  void SetAutomaticFlushes(bool enabled);

  // True if the context is lost.
  bool IsContextLost();

  // Asynchronously flushes the commands, setting the put pointer to let the
  // buffer interface know that new commands have been added. After a flush
  // returns, the command buffer service is aware of all pending commands.
  void Flush();

  // Flushes if the put pointer has changed since the last flush.
  void FlushLazy();

  // Ensures that commands up to the put pointer will be processed in the
  // command buffer service before any future commands on other command buffers
  // sharing a channel.
  void OrderingBarrier();

  // Waits until all the commands have been executed. Returns whether it
  // was successful. The function will fail if the command buffer service has
  // disconnected.
  bool Finish();

  // Waits until a given number of available entries are available.
  // Parameters:
  //   count: number of entries needed. This value must be at most
  //     the size of the buffer minus one.
  void WaitForAvailableEntries(int32_t count);

  // Inserts a new token into the command buffer. This token either has a value
  // different from previously inserted tokens, or ensures that previously
  // inserted tokens with that value have already passed through the command
  // stream.
  // Returns:
  //   the value of the new token or -1 if the command buffer reader has
  //   shutdown.
  int32_t InsertToken();

  // Returns true if the token has passed.  This combines RefreshCachedToken
  // and HasCachedTokenPassed.  Don't call this function if you have to call
  // it repeatedly, and instead use those alternative functions.
  // Parameters:
  //   the value of the token to check whether it has passed
  bool HasTokenPassed(int32_t token);

  // Returns true if the token has passed, but doesn't take a lock and check
  // for what the latest token state is.
  bool HasCachedTokenPassed(int32_t token);

  // Update the state of the latest passed token.
  void RefreshCachedToken();

  // Waits until the token of a particular value has passed through the command
  // stream (i.e. commands inserted before that token have been executed).
  // NOTE: This will call Flush if it needs to block.
  // Parameters:
  //   the value of the token to wait for.
  void WaitForToken(int32_t token);

  // Called prior to each command being issued. Waits for a certain amount of
  // space to be available. Returns address of space.
  void* GetSpace(int32_t entries) {
#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK)
    // Allow this command buffer to be pre-empted by another if a "reasonable"
    // amount of work has been done. On highend machines, this reduces the
    // latency of GPU commands. However, on Android, this can cause the
    // kernel to thrash between generating GPU commands and executing them.
    ++commands_issued_;
    if (flush_automatically_ &&
        (commands_issued_ % kCommandsPerFlushCheck == 0)) {
      PeriodicFlushCheck();
    }
#endif

    // Test for immediate entries.
    if (entries > immediate_entry_count_) {
      WaitForAvailableEntries(entries);
      if (entries > immediate_entry_count_)
        return nullptr;
    }

    DCHECK_LE(entries, immediate_entry_count_);

    // Allocate space and advance put_.
    CommandBufferEntry* space = UNSAFE_TODO(&entries_[put_]);
    put_ += entries;
    immediate_entry_count_ -= entries;

    DCHECK_LE(put_, total_entry_count_);
    return space;
  }

  // Typed version of GetSpace. Gets enough room for the given type and returns
  // a reference to it.
  template <typename T>
  T* GetCmdSpace() {
    static_assert(T::kArgFlags == cmd::kFixed,
                  "T::kArgFlags should equal cmd::kFixed");
    int32_t space_needed = ComputeNumEntries(sizeof(T));
    T* data = static_cast<T*>(GetSpace(space_needed));
    return data;
  }

  // Typed version of GetSpace for immediate commands.
  template <typename T>
  T* GetImmediateCmdSpace(size_t data_space) {
    static_assert(T::kArgFlags == cmd::kAtLeastN,
                  "T::kArgFlags should equal cmd::kAtLeastN");
    int32_t space_needed = ComputeNumEntries(sizeof(T) + data_space);
    T* data = static_cast<T*>(GetSpace(space_needed));
    return data;
  }

  // Typed version of GetSpace for immediate commands.
  template <typename T>
  T* GetImmediateCmdSpaceTotalSize(size_t total_space) {
    static_assert(T::kArgFlags == cmd::kAtLeastN,
                  "T::kArgFlags should equal cmd::kAtLeastN");
    int32_t space_needed = ComputeNumEntries(total_space);
    T* data = static_cast<T*>(GetSpace(space_needed));
    return data;
  }

  // Common Commands
  void Noop(uint32_t skip_count) {
    cmd::Noop* cmd = GetImmediateCmdSpace<cmd::Noop>(
        (skip_count - 1) * sizeof(CommandBufferEntry));
    if (cmd) {
      cmd->Init(skip_count);
    }
  }

  void SetToken(uint32_t token) {
    cmd::SetToken* cmd = GetCmdSpace<cmd::SetToken>();
    if (cmd) {
      cmd->Init(token);
    }
  }

  void SetBucketSize(uint32_t bucket_id, uint32_t size) {
    cmd::SetBucketSize* cmd = GetCmdSpace<cmd::SetBucketSize>();
    if (cmd) {
      cmd->Init(bucket_id, size);
    }
  }

  void SetBucketData(uint32_t bucket_id,
                     uint32_t offset,
                     uint32_t size,
                     uint32_t shared_memory_id,
                     uint32_t shared_memory_offset) {
    cmd::SetBucketData* cmd = GetCmdSpace<cmd::SetBucketData>();
    if (cmd) {
      cmd->Init(bucket_id, offset, size, shared_memory_id,
                shared_memory_offset);
    }
  }

  void SetBucketDataImmediate(uint32_t bucket_id,
                              uint32_t offset,
                              const void* data,
                              uint32_t size) {
    cmd::SetBucketDataImmediate* cmd =
        GetImmediateCmdSpace<cmd::SetBucketDataImmediate>(size);
    if (cmd) {
      cmd->Init(bucket_id, offset, size);
      UNSAFE_TODO(memcpy(ImmediateDataAddress(cmd), data, size));
    }
  }

  void GetBucketStart(uint32_t bucket_id,
                      uint32_t result_memory_id,
                      uint32_t result_memory_offset,
                      uint32_t data_memory_size,
                      uint32_t data_memory_id,
                      uint32_t data_memory_offset) {
    cmd::GetBucketStart* cmd = GetCmdSpace<cmd::GetBucketStart>();
    if (cmd) {
      cmd->Init(bucket_id, result_memory_id, result_memory_offset,
                data_memory_size, data_memory_id, data_memory_offset);
    }
  }

  void GetBucketData(uint32_t bucket_id,
                     uint32_t offset,
                     uint32_t size,
                     uint32_t shared_memory_id,
                     uint32_t shared_memory_offset) {
    cmd::GetBucketData* cmd = GetCmdSpace<cmd::GetBucketData>();
    if (cmd) {
      cmd->Init(bucket_id, offset, size, shared_memory_id,
                shared_memory_offset);
    }
  }

  uint64_t InsertFenceSync(base::FunctionRef<uint64_t()> sync_token_generator) {
    cmd::InsertFenceSync* cmd = GetCmdSpace<cmd::InsertFenceSync>();

    // Please note that it is important to generate the sync token after
    // GetCmdSpace().
    // 1) If InsertFenceSync command `cmd` is not successfully allocated, a sync
    //    token shouldn't be created either. Otherwise, it results in waiting
    //    for a fence sync that is never released.
    // 2) Even if `cmd` is successfully allocated, we still need to generate the
    //    sync token afterwards: The GetCmdSpace() call may result in a flush of
    //    the command buffer. On the other hand, command buffer implementations
    //    (such as CommandBufferProxyImpl) may assume that when a flush happens,
    //    the commands releasing the previously-generated sync tokens are
    //    already in the buffer and thus all flushed.
    if (cmd) {
      uint64_t release_count = sync_token_generator();
      cmd->Init(release_count);
      return release_count;
    }

    return 0;
  }

  CommandBuffer* command_buffer() const { return command_buffer_; }

  scoped_refptr<Buffer> get_ring_buffer() const { return ring_buffer_; }
  int32_t get_ring_buffer_id() const { return ring_buffer_id_; }

  uint32_t flush_generation() const { return flush_generation_; }

  void FreeRingBuffer();

  bool HaveRingBuffer() const {
    bool have_ring_buffer = !!ring_buffer_;
    DCHECK(usable() || !have_ring_buffer);
    return have_ring_buffer;
  }

  bool usable() const { return usable_; }

  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                    base::trace_event::ProcessMemoryDump* pmd);

  int32_t GetPutOffsetForTest() const { return put_; }

 private:
  void CalcImmediateEntries(int waiting_count);
  bool AllocateRingBuffer();
  void SetGetBuffer(int32_t id, scoped_refptr<Buffer> buffer);

  // Waits for the get offset to be in a specific range, inclusive. Returns
  // false if there was an error.
  bool WaitForGetOffsetInRange(int32_t start, int32_t end);

#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK)
  // Calls Flush if automatic flush conditions are met.
  void PeriodicFlushCheck();
#endif

  int32_t GetTotalFreeEntriesNoWaiting() const;

  // Updates |cached_get_offset_|, |cached_last_token_read_| and |context_lost_|
  // from given command buffer state.
  void UpdateCachedState(const CommandBuffer::State& state);

  const raw_ptr<CommandBuffer> command_buffer_;
  int32_t ring_buffer_id_ = -1;
  uint32_t ring_buffer_size_ = 0;
  scoped_refptr<gpu::Buffer> ring_buffer_;
  raw_ptr<CommandBufferEntry, AllowPtrArithmetic> entries_ = nullptr;
  int32_t total_entry_count_ = 0;  // the total number of entries
  int32_t immediate_entry_count_ = 0;
  int32_t token_ = 0;
  int32_t put_ = 0;
  int32_t cached_last_token_read_ = 0;
  int32_t cached_get_offset_ = 0;
  uint32_t set_get_buffer_count_ = 0;
  bool service_on_old_buffer_ = false;

#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK)
  int commands_issued_ = 0;
#endif

  bool usable_ = true;
  bool context_lost_ = false;
  bool flush_automatically_ = true;

  // We track last put offset to avoid redundant automatic flushes. We track
  // both flush and ordering barrier put offsets so that an automatic flush
  // after an ordering barrier forces a flush. Automatic flushes are enabled on
  // desktop, and are also used to flush before waiting for free space in the
  // command buffer. If the auto flush logic is wrong, we might call
  // WaitForGetOffsetInRange without flushing, causing the service to go idle,
  // and the client to hang. See https://crbug.com/798400 for details.
  int32_t last_flush_put_ = 0;
  int32_t last_ordering_barrier_put_ = 0;

  base::TimeTicks last_flush_time_;

  // Incremented every time the helper flushes the command buffer.
  // Can be used to track when prior commands have been flushed.
  uint32_t flush_generation_ = 0;

  friend class CommandBufferHelperTest;
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_CMD_BUFFER_HELPER_H_
