1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/client/gl_in_process_context.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
728390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch#include <set>
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <utility>
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <vector>
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <GLES2/gl2.h>
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef GL_GLEXT_PROTOTYPES
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define GL_GLEXT_PROTOTYPES 1
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <GLES2/gl2ext.h>
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <GLES2/gl2extchromium.h>
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/bind_helpers.h"
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/lazy_instance.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_ptr.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/weak_ptr.h"
249ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/client/gles2_implementation.h"
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/client/transfer_buffer.h"
2728390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch#include "gpu/command_buffer/common/command_buffer.h"
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/common/constants.h"
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/gfx/size.h"
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/gl/gl_image.h"
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_ANDROID)
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gl/android/surface_texture.h"
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace gpu {
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const int32 kDefaultCommandBufferSize = 1024 * 1024;
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const unsigned int kDefaultStartTransferBufferSize = 4 * 1024 * 1024;
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const unsigned int kDefaultMinTransferBufferSize = 1 * 256 * 1024;
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const unsigned int kDefaultMaxTransferBufferSize = 16 * 1024 * 1024;
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass GLInProcessContextImpl
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : public GLInProcessContext,
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      public base::SupportsWeakPtr<GLInProcessContextImpl> {
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public:
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  explicit GLInProcessContextImpl(
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      const GLInProcessContextSharedMemoryLimits& mem_limits);
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual ~GLInProcessContextImpl();
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool Initialize(
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_refptr<gfx::GLSurface> surface,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool is_offscreen,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool use_global_share_group,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GLInProcessContext* share_context,
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::AcceleratedWidget window,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const gfx::Size& size,
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const gpu::gles2::ContextCreationAttribHelper& attribs,
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::GpuPreference gpu_preference,
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<InProcessCommandBuffer::Service>& service);
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // GLInProcessContext implementation:
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  virtual void SetContextLostCallback(const base::Closure& callback) OVERRIDE;
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE;
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual size_t GetMappedMemoryLimit() OVERRIDE;
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_ANDROID)
70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual scoped_refptr<gfx::SurfaceTexture> GetSurfaceTexture(
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      uint32 stream_id) OVERRIDE;
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private:
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Destroy();
76bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void OnContextLost();
7728390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  void OnSignalSyncPoint(const base::Closure& callback);
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_;
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<TransferBuffer> transfer_buffer_;
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<gles2::GLES2Implementation> gles2_implementation_;
8228390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  scoped_ptr<InProcessCommandBuffer> command_buffer_;
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const GLInProcessContextSharedMemoryLimits mem_limits_;
8528390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  bool context_lost_;
86bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::Closure context_lost_callback_;
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl);
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
9128390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdochbase::LazyInstance<base::Lock> g_all_shared_contexts_lock =
9228390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    LAZY_INSTANCE_INITIALIZER;
9328390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdochbase::LazyInstance<std::set<GLInProcessContextImpl*> > g_all_shared_contexts =
9428390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    LAZY_INSTANCE_INITIALIZER;
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)GLInProcessContextImpl::GLInProcessContextImpl(
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const GLInProcessContextSharedMemoryLimits& mem_limits)
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : mem_limits_(mem_limits), context_lost_(false) {
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochGLInProcessContextImpl::~GLInProcessContextImpl() {
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  {
10328390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    base::AutoLock lock(g_all_shared_contexts_lock.Get());
10428390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    g_all_shared_contexts.Get().erase(this);
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
10628390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  Destroy();
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochgles2::GLES2Implementation* GLInProcessContextImpl::GetImplementation() {
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return gles2_implementation_.get();
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)size_t GLInProcessContextImpl::GetMappedMemoryLimit() {
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return mem_limits_.mapped_memory_reclaim_limit;
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid GLInProcessContextImpl::SetContextLostCallback(
118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    const base::Closure& callback) {
119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  context_lost_callback_ = callback;
120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
121bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
122bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid GLInProcessContextImpl::OnContextLost() {
12328390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  context_lost_ = true;
124bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!context_lost_callback_.is_null()) {
125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    context_lost_callback_.Run();
126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
12728390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch}
12828390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch
129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool GLInProcessContextImpl::Initialize(
130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_refptr<gfx::GLSurface> surface,
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    bool is_offscreen,
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool use_global_share_group,
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLInProcessContext* share_context,
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    gfx::AcceleratedWidget window,
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const gfx::Size& size,
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const gles2::ContextCreationAttribHelper& attribs,
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::GpuPreference gpu_preference,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<InProcessCommandBuffer::Service>& service) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!use_global_share_group || !share_context);
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(size.width() >= 0 && size.height() >= 0);
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
142bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::vector<int32> attrib_vector;
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  attribs.Serialize(&attrib_vector);
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
14528390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  base::Closure wrapped_callback =
146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      base::Bind(&GLInProcessContextImpl::OnContextLost, AsWeakPtr());
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  command_buffer_.reset(new InProcessCommandBuffer(service));
14828390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch
14928390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  scoped_ptr<base::AutoLock> scoped_shared_context_lock;
15028390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  scoped_refptr<gles2::ShareGroup> share_group;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InProcessCommandBuffer* share_command_buffer = NULL;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (use_global_share_group) {
15328390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    scoped_shared_context_lock.reset(
15428390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch        new base::AutoLock(g_all_shared_contexts_lock.Get()));
15528390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    for (std::set<GLInProcessContextImpl*>::const_iterator it =
15628390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch             g_all_shared_contexts.Get().begin();
15728390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch         it != g_all_shared_contexts.Get().end();
15828390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch         it++) {
15928390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch      const GLInProcessContextImpl* context = *it;
16028390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch      if (!context->context_lost_) {
16128390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch        share_group = context->gles2_implementation_->share_group();
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        share_command_buffer = context->command_buffer_.get();
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        DCHECK(share_group.get());
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        DCHECK(share_command_buffer);
16528390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch        break;
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (share_context) {
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLInProcessContextImpl* impl =
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<GLInProcessContextImpl*>(share_context);
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    share_group = impl->gles2_implementation_->share_group();
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    share_command_buffer = impl->command_buffer_.get();
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(share_group.get());
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(share_command_buffer);
17528390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  }
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
177bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!command_buffer_->Initialize(surface,
178bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   is_offscreen,
179bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   window,
180bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   size,
181bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   attrib_vector,
182bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   gpu_preference,
183bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   wrapped_callback,
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   share_command_buffer)) {
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(ERROR) << "Failed to initialize InProcessCommmandBuffer";
18628390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    return false;
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Create the GLES2 helper, which writes the command buffer protocol.
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gles2_helper_.reset(new gles2::GLES2CmdHelper(command_buffer_.get()));
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!gles2_helper_->Initialize(mem_limits_.command_buffer_size)) {
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    LOG(ERROR) << "Failed to initialize GLES2CmdHelper";
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    Destroy();
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Create a transfer buffer.
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  transfer_buffer_.reset(new TransferBuffer(gles2_helper_.get()));
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Check for consistency.
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(!attribs.bind_generates_resource);
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool bind_generates_resource = false;
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Create the object exposing the OpenGL API.
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gles2_implementation_.reset(
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new gles2::GLES2Implementation(gles2_helper_.get(),
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     share_group.get(),
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     transfer_buffer_.get(),
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     bind_generates_resource,
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     attribs.lose_context_when_out_of_memory,
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     command_buffer_.get()));
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (use_global_share_group) {
21428390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    g_all_shared_contexts.Get().insert(this);
21528390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch    scoped_shared_context_lock.reset();
21628390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch  }
21728390f6bb8dc6eb59bac1e0576f95a7740a9bd61Ben Murdoch
218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!gles2_implementation_->Initialize(
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          mem_limits_.start_transfer_buffer_size,
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          mem_limits_.min_transfer_buffer_size,
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          mem_limits_.max_transfer_buffer_size,
22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          mem_limits_.mapped_memory_reclaim_limit)) {
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return true;
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid GLInProcessContextImpl::Destroy() {
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (gles2_implementation_) {
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // First flush the context to ensure that any pending frees of resources
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // are completed. Otherwise, if this context is part of a share group,
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // those resources might leak. Also, any remaining side effects of commands
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // issued on this context might not be visible to other contexts in the
235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // share group.
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    gles2_implementation_->Flush();
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    gles2_implementation_.reset();
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  transfer_buffer_.reset();
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  gles2_helper_.reset();
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  command_buffer_.reset();
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_ANDROID)
247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_refptr<gfx::SurfaceTexture>
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)GLInProcessContextImpl::GetSurfaceTexture(uint32 stream_id) {
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return command_buffer_->GetSurfaceTexture(stream_id);
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // anonymous namespace
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)GLInProcessContextSharedMemoryLimits::GLInProcessContextSharedMemoryLimits()
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : command_buffer_size(kDefaultCommandBufferSize),
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      start_transfer_buffer_size(kDefaultStartTransferBufferSize),
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      min_transfer_buffer_size(kDefaultMinTransferBufferSize),
25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      max_transfer_buffer_size(kDefaultMaxTransferBufferSize),
26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      mapped_memory_reclaim_limit(gles2::GLES2Implementation::kNoLimit) {
26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// static
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GLInProcessContext* GLInProcessContext::Create(
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_refptr<gfx::GLSurface> surface,
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool is_offscreen,
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gfx::AcceleratedWidget window,
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const gfx::Size& size,
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLInProcessContext* share_context,
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool use_global_share_group,
2726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const ::gpu::gles2::ContextCreationAttribHelper& attribs,
27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    gfx::GpuPreference gpu_preference,
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const GLInProcessContextSharedMemoryLimits& memory_limits) {
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!use_global_share_group || !share_context);
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (surface.get()) {
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(surface->IsOffscreen(), is_offscreen);
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(surface->GetSize() == size);
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(gfx::kNullAcceleratedWidget, window);
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<GLInProcessContextImpl> context(
28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new GLInProcessContextImpl(memory_limits));
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!context->Initialize(surface,
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           is_offscreen,
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           use_global_share_group,
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           share_context,
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           window,
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           size,
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           attribs,
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           gpu_preference,
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           service))
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return NULL;
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return context.release();
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace gpu
299