// Copyright (c) 2017 The Chromium 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 GPU_COMMAND_BUFFER_CLIENT_CLIENT_TRANSFER_CACHE_H_
#define GPU_COMMAND_BUFFER_CLIENT_CLIENT_TRANSFER_CACHE_H_

#include <map>

#include "base/callback.h"
#include "base/optional.h"
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/client/client_discardable_manager.h"
#include "gpu/command_buffer/client/gles2_impl_export.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/mapped_memory.h"
#include "gpu/command_buffer/client/transfer_buffer.h"

namespace gpu {
class MappedMemoryManager;

// ClientTransferCache allows for ClientTransferCacheEntries to be inserted
// into the cache, which will send them to the ServiceTransferCache, making
// them available for consumption in the GPU process. Typical usage is:
//   1) Create a new ClientTransferCacheEntry.
//   2) Map a memory allocation for the entry using either MapEntry() or
//      MapTransferBufferEntry().
//   3) Write the entry data to the mapped allocation using
//      ClientTransferCacheEntry::Serialize().
//   4) Unmap the allocation using UnmapAndCreateEntry(). This will ensure that
//      the entry starts locked and will trigger the creation of the
//      service-side cache entry.
//   5) Use the new entry's ID in one or more commands.
//   6) Unlock the entry via UnlockEntries() after dependent commands have been
//      issued.
//
// If an entry is needed again:
//   7) Attempt to lock the entry via LockEntry().
//      7a) If this fails, DeleteEntry() then go to (1).
//      7b) If this succeeds, go to (5).
//
// If an entry is no longer needed:
//   8) DeleteEntry().
//
// If the client wants to send the cache entry without using the |client| passed
// to the constructor, it should replace steps (2)-(4) with a call to
// StartTransferCacheEntry() and send the information needed to create the cache
// entry on the service side using some external mechanism, e.g., an IPC
// message.
//
// NOTE: The presence of locking on this class does not make it threadsafe.
// The underlying locking *only* allows calling LockTransferCacheEntry
// without holding the GL context lock. All other calls still require that
// the context lock be held.
class GLES2_IMPL_EXPORT ClientTransferCache {
 public:
  class Client {
   public:
    virtual void IssueCreateTransferCacheEntry(GLuint entry_type,
                                               GLuint entry_id,
                                               GLuint handle_shm_id,
                                               GLuint handle_shm_offset,
                                               GLuint data_shm_id,
                                               GLuint data_shm_offset,
                                               GLuint data_size) = 0;
    virtual void IssueDeleteTransferCacheEntry(GLuint entry_type,
                                               GLuint entry_id) = 0;
    virtual void IssueUnlockTransferCacheEntry(GLuint entry_type,
                                               GLuint entry_id) = 0;
    virtual CommandBufferHelper* cmd_buffer_helper() = 0;
    virtual CommandBuffer* command_buffer() const = 0;
  };

  explicit ClientTransferCache(Client* client);
  ~ClientTransferCache();

  // Adds a transfer cache entry with previously written memory.
  void AddTransferCacheEntry(uint32_t type,
                             uint32_t id,
                             uint32_t shm_id,
                             uint32_t shm_offset,
                             uint32_t size);

  // Similar to AddTransferCacheEntry() but doesn't use |client_| to trigger the
  // creation of the service-side cache entry. Instead, it calls
  // |create_entry_cb| passing a ClientDiscardableHandle which
  // |create_entry_cb| can use to trigger the creation of an initially locked
  // service-side cache entry using some external mechanism, e.g., an IPC
  // message. This external mechanism should guarantee that it is safe for
  // command buffer commands to reference the cache entry after
  // |create_entry_cb| returns. Note that this function calls |create_entry_cb|
  // before returning. |create_entry_cb| is not called if the
  // ClientDiscardableHandle could not be created.
  void StartTransferCacheEntry(
      uint32_t type,
      uint32_t id,
      base::OnceCallback<void(ClientDiscardableHandle)> create_entry_cb);

  // Map(of either type) must always be followed by an Unmap.
  void* MapEntry(MappedMemoryManager* mapped_memory, uint32_t size);
  void* MapTransferBufferEntry(TransferBufferInterface* transfer_buffer,
                               uint32_t size);
  void UnmapAndCreateEntry(uint32_t type, uint32_t id);
  bool LockEntry(uint32_t type, uint32_t id);
  void UnlockEntries(const std::vector<std::pair<uint32_t, uint32_t>>& entries);
  void DeleteEntry(uint32_t type, uint32_t id);

 private:
  using EntryKey = std::pair<uint32_t, uint32_t>;
  ClientDiscardableHandle::Id FindDiscardableHandleId(const EntryKey& key);
  ClientDiscardableHandle CreateDiscardableHandle(const EntryKey& key);

  Client* const client_;  // not owned --- client_ outlives this

  base::Optional<ScopedMappedMemoryPtr> mapped_ptr_;
  base::Optional<ScopedTransferBufferPtr> transfer_buffer_ptr_;

  // Access to other members must always be done with |lock_| held.
  base::Lock lock_;
  ClientDiscardableManager discardable_manager_;
  std::map<EntryKey, ClientDiscardableHandle::Id> discardable_handle_id_map_;

  DISALLOW_COPY_AND_ASSIGN(ClientTransferCache);
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_CLIENT_TRANSFER_CACHE_H_
