// Copyright 2018 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_IMPLEMENTATION_BASE_H_
#define GPU_COMMAND_BUFFER_CLIENT_IMPLEMENTATION_BASE_H_

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

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/trace_event/memory_dump_provider.h"
#include "gpu/command_buffer/client/client_transfer_cache.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_impl_export.h"
#include "gpu/command_buffer/client/gpu_control_client.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/capabilities.h"
#include "gpu/command_buffer/common/context_result.h"

namespace gpu {

namespace gles2 {
class QueryTracker;
}

class CommandBufferHelper;
class GpuControl;
class MappedMemoryManager;
struct SharedMemoryLimits;

// Base class with functionality shared between GLES2Implementation and
// RasterImplementation.
class GLES2_IMPL_EXPORT ImplementationBase
    : public base::trace_event::MemoryDumpProvider,
      public ContextSupport,
      public GpuControlClient {
 public:
  // The maximum result size from simple GL get commands.
  static const uint32_t kMaxSizeOfSimpleResult =
      16 * sizeof(uint32_t);  // NOLINT.

  // used for testing only. If more things are reseved add them here.
  static const uint32_t kStartingOffset = kMaxSizeOfSimpleResult;

  // Alignment of allocations.
  static const unsigned int kAlignment = 16;

  // The bucket used for results. Public for testing only.
  static const uint32_t kResultBucketId = 1;

  ImplementationBase(CommandBufferHelper* helper,
                     TransferBufferInterface* transfer_buffer,
                     GpuControl* gpu_control);
  ~ImplementationBase() override;

  void FreeUnusedSharedMemory();
  void FreeEverything();

  // TODO(danakj): Move to ContextSupport once ContextProvider doesn't need to
  // intercept it.
  void SetLostContextCallback(base::OnceClosure callback);

  const Capabilities& capabilities() const { return capabilities_; }

  // ContextSupport implementation.
  void FlushPendingWork() override;
  void SignalSyncToken(const gpu::SyncToken& sync_token,
                       base::OnceClosure callback) override;
  bool IsSyncTokenSignaled(const gpu::SyncToken& sync_token) override;
  void SignalQuery(uint32_t query, base::OnceClosure callback) override;
  void GetGpuFence(uint32_t gpu_fence_id,
                   base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>
                       callback) override;
  void SetGrContext(GrContext* gr) override;
  bool HasGrContextSupport() const override;
  void WillCallGLFromSkia() override;
  void DidCallGLFromSkia() override;
  void SetDisplayTransform(gfx::OverlayTransform transform) override;

  // base::trace_event::MemoryDumpProvider implementation.
  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                    base::trace_event::ProcessMemoryDump* pmd) override;

  // Used by child classes to implement gpu::InterfaceBase
  void GenSyncToken(GLbyte* sync_token);
  void GenUnverifiedSyncToken(GLbyte* sync_token);
  void VerifySyncTokens(GLbyte** sync_tokens, GLsizei count);
  void WaitSyncToken(const GLbyte* sync_token);

 protected:
  gpu::ContextResult Initialize(const SharedMemoryLimits& limits);

  // Waits for all commands to execute.
  void WaitForCmd();

  // Gets the value of the result.
  template <typename T>
  ScopedResultPtr<T> GetResultAs() {
    return ScopedResultPtr<T>(transfer_buffer_);
  }

  int32_t GetResultShmId();

  // TODO(gman): These bucket functions really seem like they belong in
  // CommandBufferHelper (or maybe BucketHelper?). Unfortunately they need
  // a transfer buffer to function which is currently managed by this class.

  // Gets the contents of a bucket.
  bool GetBucketContents(uint32_t bucket_id, std::vector<int8_t>* data);

  // Sets the contents of a bucket.
  void SetBucketContents(uint32_t bucket_id, const void* data, uint32_t size);

  // Sets the contents of a bucket as a string.
  void SetBucketAsCString(uint32_t bucket_id, const char* str);

  // Gets the contents of a bucket as a string. Returns false if there is no
  // string available which is a separate case from the empty string.
  bool GetBucketAsString(uint32_t bucket_id, std::string* str);

  // Sets the contents of a bucket as a string.
  void SetBucketAsString(uint32_t bucket_id, const std::string& str);

  bool GetVerifiedSyncTokenForIPC(const SyncToken& sync_token,
                                  SyncToken* verified_sync_token);

  void RunIfContextNotLost(base::OnceClosure callback);

  TransferBufferInterface* transfer_buffer_;

  std::unique_ptr<MappedMemoryManager> mapped_memory_;

  std::unique_ptr<gles2::QueryTracker> query_tracker_;

  base::OnceClosure lost_context_callback_;
  bool lost_context_callback_run_ = false;

  GpuControl* const gpu_control_;

  Capabilities capabilities_;

 private:
  virtual void IssueShallowFlush() = 0;
  virtual void SetGLError(GLenum error,
                          const char* function_name,
                          const char* msg) = 0;

  CommandBufferHelper* helper_;

  base::WeakPtrFactory<ImplementationBase> weak_ptr_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(ImplementationBase);
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_IMPLEMENTATION_BASE_H_
