// Copyright (c) 2012 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 PPAPI_PROXY_PPB_GRAPHICS_3D_PROXY_H_
#define PPAPI_PROXY_PPB_GRAPHICS_3D_PROXY_H_

#include <vector>

#include "base/memory/shared_memory.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "ppapi/c/pp_graphics_3d.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/interface_proxy.h"
#include "ppapi/proxy/proxy_completion_callback_factory.h"
#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/utility/completion_callback_factory.h"

namespace ppapi {

class HostResource;

namespace proxy {

class SerializedHandle;
class PpapiCommandBufferProxy;

class Graphics3D : public PPB_Graphics3D_Shared {
 public:
  explicit Graphics3D(const HostResource& resource);
  virtual ~Graphics3D();

  bool Init(gpu::gles2::GLES2Implementation* share_gles2);

  // Graphics3DTrusted API. These are not implemented in the proxy.
  virtual PP_Bool SetGetBuffer(int32_t shm_id) OVERRIDE;
  virtual gpu::CommandBuffer::State GetState() OVERRIDE;
  virtual PP_Bool Flush(int32_t put_offset) OVERRIDE;
  virtual gpu::CommandBuffer::State FlushSync(int32_t put_offset) OVERRIDE;
  virtual int32_t CreateTransferBuffer(uint32_t size) OVERRIDE;
  virtual PP_Bool DestroyTransferBuffer(int32_t id) OVERRIDE;
  virtual PP_Bool GetTransferBuffer(int32_t id,
                                    int* shm_handle,
                                    uint32_t* shm_size) OVERRIDE;
  virtual gpu::CommandBuffer::State FlushSyncFast(
      int32_t put_offset,
      int32_t last_known_get) OVERRIDE;
  virtual uint32_t InsertSyncPoint() OVERRIDE;

 private:
  // PPB_Graphics3D_Shared overrides.
  virtual gpu::CommandBuffer* GetCommandBuffer() OVERRIDE;
  virtual gpu::GpuControl* GetGpuControl() OVERRIDE;
  virtual int32 DoSwapBuffers() OVERRIDE;

  scoped_ptr<PpapiCommandBufferProxy> command_buffer_;

  DISALLOW_COPY_AND_ASSIGN(Graphics3D);
};

class PPB_Graphics3D_Proxy : public InterfaceProxy {
 public:
  PPB_Graphics3D_Proxy(Dispatcher* dispatcher);
  virtual ~PPB_Graphics3D_Proxy();

  static PP_Resource CreateProxyResource(
      PP_Instance instance,
      PP_Resource share_context,
      const int32_t* attrib_list);

  // InterfaceProxy implementation.
  virtual bool OnMessageReceived(const IPC::Message& msg);

  static const ApiID kApiID = API_ID_PPB_GRAPHICS_3D;

 private:
  void OnMsgCreate(PP_Instance instance,
                   HostResource share_context,
                   const std::vector<int32_t>& attribs,
                   HostResource* result);
  void OnMsgSetGetBuffer(const HostResource& context,
                         int32 id);
  void OnMsgGetState(const HostResource& context,
                     gpu::CommandBuffer::State* state,
                     bool* success);
  void OnMsgFlush(const HostResource& context,
                  int32 put_offset,
                  int32 last_known_get,
                  gpu::CommandBuffer::State* state,
                  bool* success);
  void OnMsgAsyncFlush(const HostResource& context,
                       int32 put_offset);
  void OnMsgCreateTransferBuffer(const HostResource& context,
                                 uint32 size,
                                 int32* id);
  void OnMsgDestroyTransferBuffer(const HostResource& context,
                                  int32 id);
  void OnMsgGetTransferBuffer(const HostResource& context,
                              int32 id,
                              ppapi::proxy::SerializedHandle* transfer_buffer);
  void OnMsgSwapBuffers(const HostResource& context);
  void OnMsgInsertSyncPoint(const HostResource& context, uint32* sync_point);
  // Renderer->plugin message handlers.
  void OnMsgSwapBuffersACK(const HostResource& context,
                           int32_t pp_error);

  void SendSwapBuffersACKToPlugin(int32_t result,
                                  const HostResource& context);

  ProxyCompletionCallbackFactory<PPB_Graphics3D_Proxy> callback_factory_;

  DISALLOW_COPY_AND_ASSIGN(PPB_Graphics3D_Proxy);
};

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_PPB_GRAPHICS_3D_PROXY_H_

