// 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 GPU_BLINK_WEBGRAPHICSCONTEXT3D_IN_PROCESS_COMMAND_BUFFER_IMPL_H_
#define GPU_BLINK_WEBGRAPHICSCONTEXT3D_IN_PROCESS_COMMAND_BUFFER_IMPL_H_

#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "gpu/blink/gpu_blink_export.h"
#include "gpu/blink/webgraphicscontext3d_impl.h"
#include "gpu/command_buffer/client/gl_in_process_context.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "ui/gfx/native_widget_types.h"

namespace gpu {
class ContextSupport;
class GLInProcessContext;

namespace gles2 {
class GLES2Interface;
class GLES2Implementation;
struct ContextCreationAttribHelper;
}
}

namespace gpu_blink {

class GPU_BLINK_EXPORT WebGraphicsContext3DInProcessCommandBufferImpl
    : public WebGraphicsContext3DImpl {
 public:
  enum MappedMemoryReclaimLimit {
    kNoLimit = 0,
  };

  static scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>
      CreateViewContext(
          const blink::WebGraphicsContext3D::Attributes& attributes,
          bool lose_context_when_out_of_memory,
          gfx::AcceleratedWidget window);

  static scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>
      CreateOffscreenContext(
          const blink::WebGraphicsContext3D::Attributes& attributes,
          bool lose_context_when_out_of_memory);

  static scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>
      WrapContext(
          scoped_ptr< ::gpu::GLInProcessContext> context,
          const blink::WebGraphicsContext3D::Attributes& attributes);

  virtual ~WebGraphicsContext3DInProcessCommandBufferImpl();

  size_t GetMappedMemoryLimit();

  bool InitializeOnCurrentThread();

  //----------------------------------------------------------------------
  // WebGraphicsContext3D methods
  virtual bool isContextLost();

  virtual WGC3Denum getGraphicsResetStatusARB();

  ::gpu::ContextSupport* GetContextSupport();

  ::gpu::gles2::GLES2Implementation* GetImplementation() {
    return real_gl_;
  }

 private:
  WebGraphicsContext3DInProcessCommandBufferImpl(
      scoped_ptr< ::gpu::GLInProcessContext> context,
      const blink::WebGraphicsContext3D::Attributes& attributes,
      bool lose_context_when_out_of_memory,
      bool is_offscreen,
      gfx::AcceleratedWidget window);

  void OnContextLost();

  bool MaybeInitializeGL();

  // Used to try to find bugs in code that calls gl directly through the gl api
  // instead of going through WebGraphicsContext3D.
  void ClearContext();

  ::gpu::gles2::ContextCreationAttribHelper attribs_;
  bool share_resources_;
  bool webgl_context_;

  bool is_offscreen_;
  // Only used when not offscreen.
  gfx::AcceleratedWidget window_;

  // The context we use for OpenGL rendering.
  scoped_ptr< ::gpu::GLInProcessContext> context_;
  // The GLES2Implementation we use for OpenGL rendering.
  ::gpu::gles2::GLES2Implementation* real_gl_;
};

}  // namespace gpu_blink

#endif  // GPU_BLINK_WEBGRAPHICSCONTEXT3D_IN_PROCESS_COMMAND_BUFFER_IMPL_H_
