summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 00:25:07 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 00:25:07 +0000
commit68780860e0e5ff26d9d2a8af6dc97539985062f9 (patch)
treebcaa4f918eee05a30487d88f1244a907bfc08310
parentd52e1c81558d878c86fee741297df58309089c01 (diff)
downloadchromium_src-68780860e0e5ff26d9d2a8af6dc97539985062f9.zip
chromium_src-68780860e0e5ff26d9d2a8af6dc97539985062f9.tar.gz
chromium_src-68780860e0e5ff26d9d2a8af6dc97539985062f9.tar.bz2
Implement gpu::CommandBuffer over mojo IPCs and have mojo::gles2 use that.
This implementation is not complete yet, but is enough to get all the samples working. There is one major hack which is how to pass shared memory handles across mojo IPC. We will need to add the right capability and/or rework the command buffer protocol to work on top of mojo primitives. BUG=333157 R=darin@chromium.org, jamesr@chromium.org Review URL: https://codereview.chromium.org/149333004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249556 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--mojo/gles2/DEPS1
-rw-r--r--mojo/gles2/command_buffer_client_impl.cc293
-rw-r--r--mojo/gles2/command_buffer_client_impl.h130
-rw-r--r--mojo/gles2/gles2_client_impl.cc68
-rw-r--r--mojo/gles2/gles2_client_impl.h59
-rw-r--r--mojo/gles2/gles2_context.cc69
-rw-r--r--mojo/gles2/gles2_context.h63
-rw-r--r--mojo/gles2/gles2_support_impl.cc24
-rw-r--r--mojo/mojo.gyp10
-rw-r--r--mojo/mojo_services.gypi9
-rw-r--r--mojo/services/gles2/DEPS3
-rw-r--r--mojo/services/gles2/command_buffer.mojom57
-rw-r--r--mojo/services/gles2/command_buffer_impl.cc173
-rw-r--r--mojo/services/gles2/command_buffer_impl.h73
-rw-r--r--mojo/services/gles2/command_buffer_type_conversions.cc65
-rw-r--r--mojo/services/gles2/command_buffer_type_conversions.h36
-rw-r--r--mojo/services/gles2/gles2.mojom28
-rw-r--r--mojo/services/gles2/gles2_impl.cc68
-rw-r--r--mojo/services/gles2/gles2_impl.h51
-rw-r--r--mojo/services/native_viewport/native_viewport_service.cc46
20 files changed, 1008 insertions, 318 deletions
diff --git a/mojo/gles2/DEPS b/mojo/gles2/DEPS
index 08992c3..a0e373e 100644
--- a/mojo/gles2/DEPS
+++ b/mojo/gles2/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+gpu/command_buffer/client",
+ "+gpu/command_buffer/common",
]
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc
new file mode 100644
index 0000000..1e87c1d
--- /dev/null
+++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -0,0 +1,293 @@
+// Copyright 2014 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.
+
+#include "mojo/gles2/command_buffer_client_impl.h"
+
+#include <limits>
+
+#include "base/logging.h"
+#include "base/process/process_handle.h"
+#include "mojo/public/bindings/allocation_scope.h"
+#include "mojo/public/bindings/sync_dispatcher.h"
+#include "mojo/services/gles2/command_buffer_type_conversions.h"
+
+namespace mojo {
+namespace gles2 {
+
+CommandBufferDelegate::~CommandBufferDelegate() {}
+
+void CommandBufferDelegate::ContextLost() {}
+void CommandBufferDelegate::DrawAnimationFrame() {}
+
+CommandBufferClientImpl::CommandBufferClientImpl(
+ CommandBufferDelegate* delegate,
+ MojoAsyncWaiter* async_waiter,
+ ScopedMessagePipeHandle command_buffer)
+ : delegate_(delegate),
+ command_buffer_(command_buffer.Pass(), this, this, async_waiter),
+ last_put_offset_(-1),
+ next_transfer_buffer_id_(0),
+ initialize_result_(false) {}
+
+CommandBufferClientImpl::~CommandBufferClientImpl() {}
+
+bool CommandBufferClientImpl::Initialize() {
+ shared_state_shm_.reset(new base::SharedMemory);
+ if (!shared_state_shm_->CreateAndMapAnonymous(
+ sizeof(gpu::CommandBufferSharedState)))
+ return false;
+
+ base::SharedMemoryHandle handle;
+ shared_state_shm_->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
+ if (!base::SharedMemory::IsHandleValid(handle))
+ return false;
+
+ shared_state()->Initialize();
+
+ MessagePipe sync_pipe;
+ sync_dispatcher_.reset(new SyncDispatcher<CommandBufferSyncClient>(
+ sync_pipe.handle1.Pass(), this));
+ AllocationScope scope;
+ command_buffer_->Initialize(sync_pipe.handle0.Pass(), handle);
+ // Wait for DidInitialize to come on the sync client pipe.
+ if (!sync_dispatcher_->WaitAndDispatchOneMessage()) {
+ VLOG(1) << "Channel encountered error while creating command buffer";
+ return false;
+ }
+ return initialize_result_;
+}
+
+gpu::CommandBuffer::State CommandBufferClientImpl::GetState() {
+ MakeProgressAndUpdateState();
+ return last_state_;
+}
+
+gpu::CommandBuffer::State CommandBufferClientImpl::GetLastState() {
+ return last_state_;
+}
+
+int32 CommandBufferClientImpl::GetLastToken() {
+ TryUpdateState();
+ return last_state_.token;
+}
+
+void CommandBufferClientImpl::Flush(int32 put_offset) {
+ if (last_put_offset_ == put_offset)
+ return;
+
+ last_put_offset_ = put_offset;
+ command_buffer_->Flush(put_offset);
+}
+
+gpu::CommandBuffer::State CommandBufferClientImpl::FlushSync(
+ int32 put_offset,
+ int32 last_known_get) {
+ Flush(put_offset);
+ TryUpdateState();
+ if (last_known_get == last_state_.get_offset)
+ MakeProgressAndUpdateState();
+
+ return last_state_;
+}
+
+void CommandBufferClientImpl::SetGetBuffer(int32 shm_id) {
+ command_buffer_->SetGetBuffer(shm_id);
+ last_put_offset_ = -1;
+}
+
+void CommandBufferClientImpl::SetGetOffset(int32 get_offset) {
+ // Not implemented in proxy.
+ NOTREACHED();
+}
+
+gpu::Buffer CommandBufferClientImpl::CreateTransferBuffer(size_t size,
+ int32* id) {
+ gpu::Buffer buffer;
+ if (size >= std::numeric_limits<uint32_t>::max())
+ return buffer;
+
+ scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
+ if (!shared_memory->CreateAndMapAnonymous(size))
+ return buffer;
+
+ base::SharedMemoryHandle handle;
+ shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
+ if (!base::SharedMemory::IsHandleValid(handle))
+ return buffer;
+
+ *id = ++next_transfer_buffer_id_;
+ DCHECK(transfer_buffers_.find(*id) == transfer_buffers_.end());
+
+ AllocationScope scope;
+ command_buffer_->RegisterTransferBuffer(
+ *id, handle, static_cast<uint32_t>(size));
+
+ buffer.ptr = shared_memory->memory();
+ buffer.size = size;
+ buffer.shared_memory = shared_memory.release();
+ transfer_buffers_[*id] = buffer;
+
+ return buffer;
+}
+
+void CommandBufferClientImpl::DestroyTransferBuffer(int32 id) {
+ TransferBufferMap::iterator it = transfer_buffers_.find(id);
+ if (it != transfer_buffers_.end()) {
+ delete it->second.shared_memory;
+ transfer_buffers_.erase(it);
+ }
+ command_buffer_->DestroyTransferBuffer(id);
+}
+
+gpu::Buffer CommandBufferClientImpl::GetTransferBuffer(int32 id) {
+ TransferBufferMap::iterator it = transfer_buffers_.find(id);
+ if (it != transfer_buffers_.end()) {
+ return it->second;
+ } else {
+ return gpu::Buffer();
+ }
+}
+
+void CommandBufferClientImpl::SetToken(int32 token) {
+ // Not implemented in proxy.
+ NOTREACHED();
+}
+
+void CommandBufferClientImpl::SetParseError(gpu::error::Error error) {
+ // Not implemented in proxy.
+ NOTREACHED();
+}
+
+void CommandBufferClientImpl::SetContextLostReason(
+ gpu::error::ContextLostReason reason) {
+ // Not implemented in proxy.
+ NOTREACHED();
+}
+
+gpu::Capabilities CommandBufferClientImpl::GetCapabilities() {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+ return gpu::Capabilities();
+}
+
+gfx::GpuMemoryBuffer* CommandBufferClientImpl::CreateGpuMemoryBuffer(
+ size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
+void CommandBufferClientImpl::DestroyGpuMemoryBuffer(int32 id) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+}
+
+bool CommandBufferClientImpl::GenerateMailboxNames(
+ unsigned num,
+ std::vector<gpu::Mailbox>* names) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+ return false;
+}
+
+uint32 CommandBufferClientImpl::InsertSyncPoint() {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+void CommandBufferClientImpl::SignalSyncPoint(uint32 sync_point,
+ const base::Closure& callback) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+}
+
+void CommandBufferClientImpl::SignalQuery(uint32 query,
+ const base::Closure& callback) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+}
+
+void CommandBufferClientImpl::SetSurfaceVisible(bool visible) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+}
+
+void CommandBufferClientImpl::SendManagedMemoryStats(
+ const gpu::ManagedMemoryStats& stats) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+}
+
+void CommandBufferClientImpl::Echo(const base::Closure& callback) {
+ echo_closures_.push(callback);
+ command_buffer_->Echo();
+}
+
+uint32 CommandBufferClientImpl::CreateStreamTexture(uint32 texture_id) {
+ // TODO(piman)
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+void CommandBufferClientImpl::RequestAnimationFrames() {
+ command_buffer_->RequestAnimationFrames();
+}
+
+void CommandBufferClientImpl::CancelAnimationFrames() {
+ command_buffer_->CancelAnimationFrames();
+}
+
+void CommandBufferClientImpl::DidInitialize(bool success) {
+ initialize_result_ = success;
+}
+
+void CommandBufferClientImpl::DidMakeProgress(const CommandBufferState& state) {
+ if (state.generation() - last_state_.generation < 0x80000000U)
+ last_state_ = state;
+}
+
+void CommandBufferClientImpl::DidDestroy() {
+ LostContext(gpu::error::kUnknown);
+}
+
+void CommandBufferClientImpl::EchoAck() {
+ base::Closure closure = echo_closures_.front();
+ echo_closures_.pop();
+ closure.Run();
+}
+
+void CommandBufferClientImpl::LostContext(int32_t lost_reason) {
+ last_state_.error = gpu::error::kLostContext;
+ last_state_.context_lost_reason =
+ static_cast<gpu::error::ContextLostReason>(lost_reason);
+ delegate_->ContextLost();
+}
+
+void CommandBufferClientImpl::OnError() { LostContext(gpu::error::kUnknown); }
+
+void CommandBufferClientImpl::TryUpdateState() {
+ if (last_state_.error == gpu::error::kNoError)
+ shared_state()->Read(&last_state_);
+}
+
+void CommandBufferClientImpl::MakeProgressAndUpdateState() {
+ command_buffer_->MakeProgress(last_state_.get_offset);
+ if (!sync_dispatcher_->WaitAndDispatchOneMessage()) {
+ VLOG(1) << "Channel encountered error while waiting for command buffer";
+ // TODO(piman): is it ok for this to re-enter?
+ DidDestroy();
+ return;
+ }
+}
+
+void CommandBufferClientImpl::DrawAnimationFrame() {
+ delegate_->DrawAnimationFrame();
+}
+
+} // namespace gles2
+} // namespace mojo
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h
new file mode 100644
index 0000000..a0367d8
--- /dev/null
+++ b/mojo/gles2/command_buffer_client_impl.h
@@ -0,0 +1,130 @@
+// Copyright 2014 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 MOJO_GLES2_COMMAND_BUFFER_CLIENT_IMPL_H_
+#define MOJO_GLES2_COMMAND_BUFFER_CLIENT_IMPL_H_
+
+#include <map>
+#include <queue>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/shared_memory.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/common/command_buffer_shared.h"
+#include "gpu/command_buffer/common/gpu_control.h"
+
+#include "mojo/public/bindings/error_handler.h"
+#include "mojo/public/bindings/remote_ptr.h"
+#include "mojom/command_buffer.h"
+
+namespace base {
+class RunLoop;
+}
+
+namespace mojo {
+template <typename S>
+class SyncDispatcher;
+
+namespace gles2 {
+class CommandBufferClientImpl;
+
+class CommandBufferDelegate {
+ public:
+ virtual ~CommandBufferDelegate();
+ virtual void ContextLost();
+ virtual void DrawAnimationFrame();
+};
+
+class CommandBufferClientImpl : public CommandBufferClient,
+ public CommandBufferSyncClient,
+ public ErrorHandler,
+ public gpu::CommandBuffer,
+ public gpu::GpuControl {
+ public:
+ explicit CommandBufferClientImpl(CommandBufferDelegate* delegate,
+ MojoAsyncWaiter* async_waiter,
+ ScopedMessagePipeHandle command_buffer);
+ virtual ~CommandBufferClientImpl();
+
+ // CommandBuffer implementation:
+ virtual bool Initialize() OVERRIDE;
+ virtual State GetState() OVERRIDE;
+ virtual State GetLastState() OVERRIDE;
+ virtual int32 GetLastToken() OVERRIDE;
+ virtual void Flush(int32 put_offset) OVERRIDE;
+ virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE;
+ virtual void SetGetBuffer(int32 shm_id) OVERRIDE;
+ virtual void SetGetOffset(int32 get_offset) OVERRIDE;
+ virtual gpu::Buffer CreateTransferBuffer(size_t size, int32* id) OVERRIDE;
+ virtual void DestroyTransferBuffer(int32 id) OVERRIDE;
+ virtual gpu::Buffer GetTransferBuffer(int32 id) OVERRIDE;
+ virtual void SetToken(int32 token) OVERRIDE;
+ virtual void SetParseError(gpu::error::Error error) OVERRIDE;
+ virtual void SetContextLostReason(gpu::error::ContextLostReason reason)
+ OVERRIDE;
+
+ // gpu::GpuControl implementation:
+ virtual gpu::Capabilities GetCapabilities() OVERRIDE;
+ virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) OVERRIDE;
+ virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+ virtual bool GenerateMailboxNames(unsigned num,
+ std::vector<gpu::Mailbox>* names) OVERRIDE;
+ virtual uint32 InsertSyncPoint() OVERRIDE;
+ virtual void SignalSyncPoint(uint32 sync_point,
+ const base::Closure& callback) OVERRIDE;
+ virtual void SignalQuery(uint32 query,
+ const base::Closure& callback) OVERRIDE;
+ virtual void SetSurfaceVisible(bool visible) OVERRIDE;
+ virtual void SendManagedMemoryStats(const gpu::ManagedMemoryStats& stats)
+ OVERRIDE;
+ virtual void Echo(const base::Closure& callback) OVERRIDE;
+ virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;
+
+ void RequestAnimationFrames();
+ void CancelAnimationFrames();
+
+ private:
+ typedef std::map<int32, gpu::Buffer> TransferBufferMap;
+
+ // CommandBufferClient implementation:
+ virtual void DidInitialize(bool success) MOJO_OVERRIDE;
+ virtual void DidMakeProgress(const CommandBufferState& state) MOJO_OVERRIDE;
+ virtual void DidDestroy() MOJO_OVERRIDE;
+ virtual void EchoAck() MOJO_OVERRIDE;
+ virtual void LostContext(int32_t lost_reason) MOJO_OVERRIDE;
+
+ // ErrorHandler implementation:
+ virtual void OnError() MOJO_OVERRIDE;
+
+ virtual void DrawAnimationFrame() MOJO_OVERRIDE;
+
+ void TryUpdateState();
+ void MakeProgressAndUpdateState();
+
+ gpu::CommandBufferSharedState* shared_state() const {
+ return reinterpret_cast<gpu::CommandBufferSharedState*>(
+ shared_state_shm_->memory());
+ }
+
+ CommandBufferDelegate* delegate_;
+ RemotePtr<mojo::CommandBuffer> command_buffer_;
+ scoped_ptr<SyncDispatcher<CommandBufferSyncClient> > sync_dispatcher_;
+
+ State last_state_;
+ scoped_ptr<base::SharedMemory> shared_state_shm_;
+ TransferBufferMap transfer_buffers_;
+ int32 last_put_offset_;
+ int32 next_transfer_buffer_id_;
+ std::queue<base::Closure> echo_closures_;
+
+ bool initialize_result_;
+};
+
+} // gles2
+} // mojo
+
+#endif // MOJO_GLES2_COMMAND_BUFFER_CLIENT_IMPL_H_
diff --git a/mojo/gles2/gles2_client_impl.cc b/mojo/gles2/gles2_client_impl.cc
deleted file mode 100644
index f776d8e..0000000
--- a/mojo/gles2/gles2_client_impl.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 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.
-
-#include "mojo/gles2/gles2_client_impl.h"
-
-#include "mojo/public/bindings/sync_dispatcher.h"
-#include "mojo/public/gles2/gles2.h"
-#include "mojo/public/system/core_cpp.h"
-
-namespace mojo {
-namespace gles2 {
-
-GLES2ClientImpl::GLES2ClientImpl(MojoAsyncWaiter* async_waiter,
- ScopedMessagePipeHandle pipe,
- MojoGLES2ContextLost lost_callback,
- MojoGLES2DrawAnimationFrame animation_callback,
- void* closure)
- : service_(pipe.Pass(), this, NULL, async_waiter),
- implementation_(NULL),
- lost_callback_(lost_callback),
- animation_callback_(animation_callback),
- closure_(closure) {
-}
-
-GLES2ClientImpl::~GLES2ClientImpl() {
- service_->Destroy();
-}
-
-bool GLES2ClientImpl::Initialize() {
- MessagePipe sync_pipe;
- sync_dispatcher_.reset(
- new SyncDispatcher<GLES2SyncClient>(sync_pipe.handle1.Pass(), this));
- service_->Initialize(sync_pipe.handle0.Pass());
- // Wait for DidCreateContext to come on the sync client pipe.
- if (!sync_dispatcher_->WaitAndDispatchOneMessage())
- return false;
- return !!implementation_;
-}
-
-void GLES2ClientImpl::RequestAnimationFrames() {
- service_->RequestAnimationFrames();
-}
-
-void GLES2ClientImpl::CancelAnimationFrames() {
- service_->CancelAnimationFrames();
-}
-
-void GLES2ClientImpl::DidCreateContext(uint64_t encoded) {
- // Ack, Hans! It's the giant hack.
- // TODO(abarth): Replace this hack with something more disciplined. Most
- // likley, we should receive a MojoHandle that we use to wire up the
- // client side of an out-of-process command buffer. Given that we're
- // still in-process, we just reinterpret_cast the value into a GL interface.
- implementation_ = reinterpret_cast<gpu::gles2::GLES2Implementation*>(
- static_cast<uintptr_t>(encoded));
-}
-
-void GLES2ClientImpl::ContextLost() {
- lost_callback_(closure_);
-}
-
-void GLES2ClientImpl::DrawAnimationFrame() {
- animation_callback_(closure_);
-}
-
-} // namespace gles2
-} // namespace mojo
diff --git a/mojo/gles2/gles2_client_impl.h b/mojo/gles2/gles2_client_impl.h
deleted file mode 100644
index 45a0f0d..0000000
--- a/mojo/gles2/gles2_client_impl.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2014 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 MOJO_GLES2_GLES2_CLIENT_IMPL_H_
-#define MOJO_GLES2_GLES2_CLIENT_IMPL_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "mojo/public/bindings/remote_ptr.h"
-#include "mojo/public/gles2/gles2.h"
-#include "mojom/gles2.h"
-
-struct MojoGLES2ContextPrivate {};
-
-namespace mojo {
-
-template<typename S> class SyncDispatcher;
-
-namespace gles2 {
-
-class GLES2ClientImpl : public GLES2Client,
- public GLES2SyncClient,
- public MojoGLES2ContextPrivate {
- public:
- explicit GLES2ClientImpl(MojoAsyncWaiter* async_waiter,
- ScopedMessagePipeHandle pipe,
- MojoGLES2ContextLost lost_callback,
- MojoGLES2DrawAnimationFrame animation_callback,
- void* closure);
- virtual ~GLES2ClientImpl();
- bool Initialize();
-
- gpu::gles2::GLES2Interface* interface() const { return implementation_; }
- gpu::ContextSupport* context_support() const { return implementation_; }
- void RequestAnimationFrames();
- void CancelAnimationFrames();
-
- private:
- virtual void DidCreateContext(uint64_t encoded) MOJO_OVERRIDE;
- virtual void ContextLost() MOJO_OVERRIDE;
- virtual void DrawAnimationFrame() MOJO_OVERRIDE;
-
- bool WaitForSyncMessageAndDispatch();
-
- RemotePtr<GLES2> service_;
- scoped_ptr<SyncDispatcher<GLES2SyncClient> > sync_dispatcher_;
- gpu::gles2::GLES2Implementation* implementation_;
- MojoGLES2ContextLost lost_callback_;
- MojoGLES2DrawAnimationFrame animation_callback_;
- void* closure_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2ClientImpl);
-};
-
-} // namespace gles2
-} // namespace mojo
-
-#endif // MOJO_GLES2_GLES2_CLIENT_IMPL_H_
diff --git a/mojo/gles2/gles2_context.cc b/mojo/gles2/gles2_context.cc
new file mode 100644
index 0000000..126a513
--- /dev/null
+++ b/mojo/gles2/gles2_context.cc
@@ -0,0 +1,69 @@
+// Copyright 2014 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.
+
+#include "mojo/gles2/gles2_context.h"
+
+#include "gpu/command_buffer/client/gles2_cmd_helper.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
+#include "mojo/public/gles2/gles2.h"
+#include "mojo/public/system/core_cpp.h"
+
+namespace mojo {
+namespace gles2 {
+
+namespace {
+const size_t kDefaultCommandBufferSize = 1024 * 1024;
+const size_t kDefaultStartTransferBufferSize = 1 * 1024 * 1024;
+const size_t kDefaultMinTransferBufferSize = 1 * 256 * 1024;
+const size_t kDefaultMaxTransferBufferSize = 16 * 1024 * 1024;
+}
+
+GLES2Context::GLES2Context(MojoAsyncWaiter* async_waiter,
+ ScopedMessagePipeHandle pipe,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure)
+ : command_buffer_(this, async_waiter, pipe.Pass()),
+ lost_callback_(lost_callback),
+ animation_callback_(animation_callback),
+ closure_(closure) {}
+
+GLES2Context::~GLES2Context() {}
+
+bool GLES2Context::Initialize() {
+ if (!command_buffer_.Initialize())
+ return false;
+ gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(&command_buffer_));
+ if (!gles2_helper_->Initialize(kDefaultCommandBufferSize))
+ return false;
+ gles2_helper_->SetAutomaticFlushes(false);
+ transfer_buffer_.reset(new gpu::TransferBuffer(gles2_helper_.get()));
+ implementation_.reset(
+ new gpu::gles2::GLES2Implementation(gles2_helper_.get(),
+ NULL,
+ transfer_buffer_.get(),
+ true,
+ true,
+ &command_buffer_));
+ return implementation_->Initialize(kDefaultStartTransferBufferSize,
+ kDefaultMinTransferBufferSize,
+ kDefaultMaxTransferBufferSize,
+ gpu::gles2::GLES2Implementation::kNoLimit);
+}
+
+void GLES2Context::RequestAnimationFrames() {
+ command_buffer_.RequestAnimationFrames();
+}
+
+void GLES2Context::CancelAnimationFrames() {
+ command_buffer_.CancelAnimationFrames();
+}
+
+void GLES2Context::ContextLost() { lost_callback_(closure_); }
+
+void GLES2Context::DrawAnimationFrame() { animation_callback_(closure_); }
+
+} // namespace gles2
+} // namespace mojo
diff --git a/mojo/gles2/gles2_context.h b/mojo/gles2/gles2_context.h
new file mode 100644
index 0000000..430825d
--- /dev/null
+++ b/mojo/gles2/gles2_context.h
@@ -0,0 +1,63 @@
+// Copyright 2014 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 MOJO_GLES2_GLES2_CONTEXT_H_
+#define MOJO_GLES2_GLES2_CONTEXT_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "mojo/gles2/command_buffer_client_impl.h"
+#include "mojo/public/bindings/remote_ptr.h"
+#include "mojo/public/gles2/gles2.h"
+
+struct MojoGLES2ContextPrivate {};
+
+namespace gpu {
+class TransferBuffer;
+namespace gles2 {
+class GLES2CmdHelper;
+class GLES2Implementation;
+}
+}
+
+namespace mojo {
+namespace gles2 {
+
+class GLES2Context : public CommandBufferDelegate,
+ public MojoGLES2ContextPrivate {
+ public:
+ explicit GLES2Context(MojoAsyncWaiter* async_waiter,
+ ScopedMessagePipeHandle pipe,
+ MojoGLES2ContextLost lost_callback,
+ MojoGLES2DrawAnimationFrame animation_callback,
+ void* closure);
+ virtual ~GLES2Context();
+ bool Initialize();
+
+ gpu::gles2::GLES2Interface* interface() const {
+ return implementation_.get();
+ }
+ gpu::ContextSupport* context_support() const { return implementation_.get(); }
+ void RequestAnimationFrames();
+ void CancelAnimationFrames();
+
+ private:
+ virtual void ContextLost() MOJO_OVERRIDE;
+ virtual void DrawAnimationFrame() MOJO_OVERRIDE;
+
+ CommandBufferClientImpl command_buffer_;
+ scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
+ scoped_ptr<gpu::gles2::GLES2Implementation> implementation_;
+ MojoGLES2ContextLost lost_callback_;
+ MojoGLES2DrawAnimationFrame animation_callback_;
+ void* closure_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(GLES2Context);
+};
+
+} // namespace gles2
+} // namespace mojo
+
+#endif // MOJO_GLES2_GLES2_CONTEXT_H_
diff --git a/mojo/gles2/gles2_support_impl.cc b/mojo/gles2/gles2_support_impl.cc
index 9a90a09..d976065 100644
--- a/mojo/gles2/gles2_support_impl.cc
+++ b/mojo/gles2/gles2_support_impl.cc
@@ -6,7 +6,7 @@
#include "base/lazy_instance.h"
#include "gpu/command_buffer/client/gles2_interface.h"
-#include "mojo/gles2/gles2_client_impl.h"
+#include "mojo/gles2/gles2_context.h"
#include "mojo/public/gles2/gles2_interface.h"
#include "mojo/public/gles2/gles2_private.h"
@@ -65,24 +65,24 @@ MojoGLES2Context GLES2SupportImpl::CreateContext(
void* closure) {
mojo::ScopedMessagePipeHandle scoped_handle =
mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handle));
- scoped_ptr<GLES2ClientImpl> client(new GLES2ClientImpl(async_waiter_,
- scoped_handle.Pass(),
- lost_callback,
- animation_callback,
- closure));
+ scoped_ptr<GLES2Context> client(new GLES2Context(async_waiter_,
+ scoped_handle.Pass(),
+ lost_callback,
+ animation_callback,
+ closure));
if (!client->Initialize())
client.reset();
return client.release();
}
void GLES2SupportImpl::DestroyContext(MojoGLES2Context context) {
- delete static_cast<GLES2ClientImpl*>(context);
+ delete static_cast<GLES2Context*>(context);
}
void GLES2SupportImpl::MakeCurrent(MojoGLES2Context context) {
gpu::gles2::GLES2Interface* interface = NULL;
if (context) {
- GLES2ClientImpl* client = static_cast<GLES2ClientImpl*>(context);
+ GLES2Context* client = static_cast<GLES2Context*>(context);
interface = client->interface();
DCHECK(interface);
}
@@ -94,19 +94,19 @@ void GLES2SupportImpl::SwapBuffers() {
}
void GLES2SupportImpl::RequestAnimationFrames(MojoGLES2Context context) {
- static_cast<GLES2ClientImpl*>(context)->RequestAnimationFrames();
+ static_cast<GLES2Context*>(context)->RequestAnimationFrames();
}
void GLES2SupportImpl::CancelAnimationFrames(MojoGLES2Context context) {
- static_cast<GLES2ClientImpl*>(context)->CancelAnimationFrames();
+ static_cast<GLES2Context*>(context)->CancelAnimationFrames();
}
void* GLES2SupportImpl::GetGLES2Interface(MojoGLES2Context context) {
- return static_cast<GLES2ClientImpl*>(context)->interface();
+ return static_cast<GLES2Context*>(context)->interface();
}
void* GLES2SupportImpl::GetContextSupport(MojoGLES2Context context) {
- return static_cast<GLES2ClientImpl*>(context)->context_support();
+ return static_cast<GLES2Context*>(context)->context_support();
}
GLES2Interface* GLES2SupportImpl::GetGLES2InterfaceForCurrentContext() {
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index ef01a46..524c85c 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -189,6 +189,10 @@
'dependencies': [
'../base/base.gyp:base',
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ '../gpu/gpu.gyp:command_buffer_client',
+ '../gpu/gpu.gyp:command_buffer_common',
+ '../gpu/gpu.gyp:gles2_cmd_helper',
+ '../gpu/gpu.gyp:gles2_implementation',
'mojo_gles2',
'mojo_gles2_bindings',
'mojo_environment_chromium',
@@ -197,11 +201,13 @@
'MOJO_GLES2_IMPL_IMPLEMENTATION',
],
'sources': [
+ 'gles2/command_buffer_client_impl.cc',
+ 'gles2/command_buffer_client_impl.h',
'gles2/gles2_impl_export.h',
'gles2/gles2_support_impl.cc',
'gles2/gles2_support_impl.h',
- 'gles2/gles2_client_impl.cc',
- 'gles2/gles2_client_impl.h',
+ 'gles2/gles2_context.cc',
+ 'gles2/gles2_context.h',
],
},
{
diff --git a/mojo/mojo_services.gypi b/mojo/mojo_services.gypi
index 9204dcb..07a9a67 100644
--- a/mojo/mojo_services.gypi
+++ b/mojo/mojo_services.gypi
@@ -4,7 +4,9 @@
'target_name': 'mojo_gles2_bindings',
'type': 'static_library',
'sources': [
- 'services/gles2/gles2.mojom',
+ 'services/gles2/command_buffer.mojom',
+ 'services/gles2/command_buffer_type_conversions.cc',
+ 'services/gles2/command_buffer_type_conversions.h',
],
'includes': [ 'public/bindings/mojom_bindings_generator.gypi' ],
'export_dependent_settings': [
@@ -18,7 +20,6 @@
'dependencies': [
'../base/base.gyp:base',
'../gpu/gpu.gyp:command_buffer_service',
- '../gpu/gpu.gyp:gles2_implementation',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gl/gl.gyp:gl',
@@ -28,8 +29,8 @@
'mojo_gles2_bindings',
],
'sources': [
- 'services/gles2/gles2_impl.cc',
- 'services/gles2/gles2_impl.h',
+ 'services/gles2/command_buffer_impl.cc',
+ 'services/gles2/command_buffer_impl.h',
],
},
{
diff --git a/mojo/services/gles2/DEPS b/mojo/services/gles2/DEPS
index 93a965e..acd992d 100644
--- a/mojo/services/gles2/DEPS
+++ b/mojo/services/gles2/DEPS
@@ -1,4 +1,5 @@
include_rules = [
- "+gpu/command_buffer/client",
+ "+gpu/command_buffer",
"+ui/gfx",
+ "+ui/gl",
]
diff --git a/mojo/services/gles2/command_buffer.mojom b/mojo/services/gles2/command_buffer.mojom
new file mode 100644
index 0000000..1193027
--- /dev/null
+++ b/mojo/services/gles2/command_buffer.mojom
@@ -0,0 +1,57 @@
+// Copyright 2014 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.
+
+module mojo {
+
+struct CommandBufferState {
+ int32 num_entries;
+ int32 get_offset;
+ int32 put_offset;
+ int32 token;
+ int32 error; // TODO(piman): enum
+ int32 context_lost_reason; // TODO(piman): enum
+ uint32 generation;
+};
+
+// TODO(piman): we need to support proper SHM handles, or refactor command
+// buffers to sit on top of mojo primitives (e.g. DataPipe, etc.).
+struct ShmHandle {
+ uint64 handle_hack;
+};
+
+[Peer=CommandBufferClient]
+interface CommandBuffer {
+ void Initialize(handle<message_pipe> sync_client,
+ ShmHandle shared_state);
+ void SetGetBuffer(int32 buffer);
+ void Flush(int32 put_offset);
+ void MakeProgress(int32 last_get_offset);
+ void RegisterTransferBuffer(int32 id, ShmHandle transfer_buffer, uint32 size);
+ void DestroyTransferBuffer(int32 id);
+ void Echo();
+
+ // TODO(piman): move to somewhere else (native_viewport?).
+ void RequestAnimationFrames();
+ void CancelAnimationFrames();
+
+ // TODO(piman): sync points
+};
+
+[Peer=CommandBuffer]
+interface CommandBufferClient {
+ void DidDestroy();
+ void EchoAck();
+ void LostContext(int32 lost_reason); // TODO(piman): enum
+
+ // TODO(piman): move to somewhere else (native_viewport?).
+ void DrawAnimationFrame();
+};
+
+interface CommandBufferSyncClient {
+ void DidInitialize(bool success);
+ void DidMakeProgress(CommandBufferState state);
+};
+
+}
+
diff --git a/mojo/services/gles2/command_buffer_impl.cc b/mojo/services/gles2/command_buffer_impl.cc
new file mode 100644
index 0000000..dcbee5d
--- /dev/null
+++ b/mojo/services/gles2/command_buffer_impl.cc
@@ -0,0 +1,173 @@
+// Copyright 2013 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.
+
+#include "mojo/services/gles2/command_buffer_impl.h"
+
+#include "base/bind.h"
+#include "base/memory/shared_memory.h"
+
+#include "gpu/command_buffer/common/constants.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gpu_control_service.h"
+#include "gpu/command_buffer/service/gpu_scheduler.h"
+#include "gpu/command_buffer/service/image_manager.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/memory_tracking.h"
+#include "mojo/public/bindings/allocation_scope.h"
+#include "mojo/services/gles2/command_buffer_type_conversions.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_surface.h"
+
+namespace mojo {
+namespace services {
+
+namespace {
+
+class MemoryTrackerStub : public gpu::gles2::MemoryTracker {
+ public:
+ MemoryTrackerStub() {}
+
+ virtual void TrackMemoryAllocatedChange(size_t old_size,
+ size_t new_size,
+ gpu::gles2::MemoryTracker::Pool pool)
+ OVERRIDE {}
+
+ virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE {
+ return true;
+ };
+
+ private:
+ virtual ~MemoryTrackerStub() {}
+
+ DISALLOW_COPY_AND_ASSIGN(MemoryTrackerStub);
+};
+
+} // anonymous namespace
+
+CommandBufferImpl::CommandBufferImpl(ScopedMessagePipeHandle client,
+ gfx::AcceleratedWidget widget,
+ const gfx::Size& size)
+ : client_(client.Pass(), this), widget_(widget), size_(size) {}
+
+CommandBufferImpl::~CommandBufferImpl() { client_->DidDestroy(); }
+
+void CommandBufferImpl::Initialize(ScopedMessagePipeHandle sync_client,
+ const ShmHandle& shared_state) {
+ sync_client_ = RemotePtr<CommandBufferSyncClient>(sync_client.Pass());
+ sync_client_->DidInitialize(DoInitialize(shared_state));
+}
+
+bool CommandBufferImpl::DoInitialize(const ShmHandle& shared_state) {
+ // TODO(piman): offscreen surface.
+ scoped_refptr<gfx::GLSurface> surface =
+ gfx::GLSurface::CreateViewGLSurface(widget_);
+ if (!surface.get())
+ return false;
+
+ // TODO(piman): context sharing, virtual contexts, gpu preference.
+ scoped_refptr<gfx::GLContext> context = gfx::GLContext::CreateGLContext(
+ NULL, surface.get(), gfx::PreferIntegratedGpu);
+ if (!context.get())
+ return false;
+
+ if (!context->MakeCurrent(surface.get()))
+ return false;
+
+ scoped_refptr<gpu::gles2::ContextGroup> context_group =
+ new gpu::gles2::ContextGroup(
+ NULL, NULL, new MemoryTrackerStub(), NULL, true);
+ command_buffer_.reset(
+ new gpu::CommandBufferService(context_group->transfer_buffer_manager()));
+ bool result = command_buffer_->Initialize();
+ DCHECK(result);
+
+ decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group.get()));
+ scheduler_.reset(new gpu::GpuScheduler(
+ command_buffer_.get(), decoder_.get(), decoder_.get()));
+ decoder_->set_engine(scheduler_.get());
+
+ gpu::gles2::DisallowedFeatures disallowed_features;
+
+ // TODO(piman): attributes.
+ std::vector<int32> attrib_vector;
+ if (!decoder_->Initialize(surface,
+ context,
+ false /* offscreen */,
+ size_,
+ disallowed_features,
+ attrib_vector))
+ return false;
+
+ gpu_control_.reset(
+ new gpu::GpuControlService(context_group->image_manager(),
+ NULL,
+ context_group->mailbox_manager(),
+ NULL,
+ decoder_->GetCapabilities()));
+
+ command_buffer_->SetPutOffsetChangeCallback(base::Bind(
+ &gpu::GpuScheduler::PutChanged, base::Unretained(scheduler_.get())));
+ command_buffer_->SetGetBufferChangeCallback(base::Bind(
+ &gpu::GpuScheduler::SetGetBuffer, base::Unretained(scheduler_.get())));
+ command_buffer_->SetParseErrorCallback(
+ base::Bind(&CommandBufferImpl::OnParseError, base::Unretained(this)));
+
+ // TODO(piman): other callbacks
+
+ scoped_ptr<base::SharedMemory> shared_state_shm(
+ new base::SharedMemory(shared_state, false));
+ if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass()))
+ return false;
+
+ return true;
+}
+
+void CommandBufferImpl::SetGetBuffer(int32_t buffer) {
+ command_buffer_->SetGetBuffer(buffer);
+}
+
+void CommandBufferImpl::Flush(int32_t put_offset) {
+ command_buffer_->Flush(put_offset);
+}
+
+void CommandBufferImpl::MakeProgress(int32_t last_get_offset) {
+ // TODO(piman): handle out-of-order.
+ AllocationScope scope;
+ sync_client_->DidMakeProgress(command_buffer_->GetState());
+}
+
+void CommandBufferImpl::RegisterTransferBuffer(int32_t id,
+ const ShmHandle& transfer_buffer,
+ uint32_t size) {
+ bool read_only = false;
+ base::SharedMemory shared_memory(transfer_buffer, read_only);
+ command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
+}
+
+void CommandBufferImpl::DestroyTransferBuffer(int32_t id) {
+ command_buffer_->DestroyTransferBuffer(id);
+}
+
+void CommandBufferImpl::Echo() { client_->EchoAck(); }
+
+void CommandBufferImpl::RequestAnimationFrames() {
+ timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(16),
+ this,
+ &CommandBufferImpl::DrawAnimationFrame);
+}
+
+void CommandBufferImpl::CancelAnimationFrames() { timer_.Stop(); }
+
+void CommandBufferImpl::OnParseError() {
+ gpu::CommandBuffer::State state = command_buffer_->GetState();
+ client_->LostContext(state.context_lost_reason);
+}
+
+void CommandBufferImpl::DrawAnimationFrame() { client_->DrawAnimationFrame(); }
+
+} // namespace services
+} // namespace mojo
diff --git a/mojo/services/gles2/command_buffer_impl.h b/mojo/services/gles2/command_buffer_impl.h
new file mode 100644
index 0000000..30b85cf
--- /dev/null
+++ b/mojo/services/gles2/command_buffer_impl.h
@@ -0,0 +1,73 @@
+// Copyright 2013 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 MOJO_SERVICES_GLES2_COMMAND_BUFFER_IMPL_H_
+#define MOJO_SERVICES_GLES2_COMMAND_BUFFER_IMPL_H_
+
+#include "base/memory/scoped_ptr.h"
+#include "base/timer/timer.h"
+#include "mojo/public/bindings/remote_ptr.h"
+#include "mojo/public/system/core_cpp.h"
+#include "mojom/command_buffer.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/size.h"
+
+namespace gpu {
+class CommandBufferService;
+class GpuScheduler;
+class GpuControlService;
+namespace gles2 {
+class GLES2Decoder;
+}
+}
+
+namespace mojo {
+namespace services {
+
+class CommandBufferImpl : public CommandBuffer {
+ public:
+ CommandBufferImpl(ScopedMessagePipeHandle client,
+ gfx::AcceleratedWidget widget,
+ const gfx::Size& size);
+ virtual ~CommandBufferImpl();
+
+ virtual void Initialize(ScopedMessagePipeHandle sync_client,
+ const ShmHandle& shared_state) OVERRIDE;
+ virtual void SetGetBuffer(int32_t buffer) OVERRIDE;
+ virtual void Flush(int32_t put_offset) OVERRIDE;
+ virtual void MakeProgress(int32_t last_get_offset) OVERRIDE;
+ virtual void RegisterTransferBuffer(int32_t id,
+ const ShmHandle& transfer_buffer,
+ uint32_t size) OVERRIDE;
+ virtual void DestroyTransferBuffer(int32_t id) OVERRIDE;
+ virtual void Echo() OVERRIDE;
+
+ virtual void RequestAnimationFrames() OVERRIDE;
+ virtual void CancelAnimationFrames() OVERRIDE;
+
+ private:
+ bool DoInitialize(const ShmHandle& shared_state);
+
+ void OnParseError();
+
+ void DrawAnimationFrame();
+
+ RemotePtr<CommandBufferClient> client_;
+ RemotePtr<CommandBufferSyncClient> sync_client_;
+
+ gfx::AcceleratedWidget widget_;
+ gfx::Size size_;
+ scoped_ptr<gpu::CommandBufferService> command_buffer_;
+ scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
+ scoped_ptr<gpu::GpuScheduler> scheduler_;
+ scoped_ptr<gpu::GpuControlService> gpu_control_;
+ base::RepeatingTimer<CommandBufferImpl> timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(CommandBufferImpl);
+};
+
+} // namespace services
+} // namespace mojo
+
+#endif // MOJO_SERVICES_GLES2_COMMAND_BUFFER_IMPL_H_
diff --git a/mojo/services/gles2/command_buffer_type_conversions.cc b/mojo/services/gles2/command_buffer_type_conversions.cc
new file mode 100644
index 0000000..a39feb5
--- /dev/null
+++ b/mojo/services/gles2/command_buffer_type_conversions.cc
@@ -0,0 +1,65 @@
+// Copyright 2014 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.
+
+#include "mojo/services/gles2/command_buffer_type_conversions.h"
+
+#include <string.h>
+
+#include "mojom/command_buffer.h"
+
+namespace mojo {
+
+COMPILE_ASSERT(sizeof(base::SharedMemoryHandle) <= sizeof(uint64_t),
+ mojo_ShmHandle_too_small_for_base_SharedMemoryHandle);
+
+ShmHandle TypeConverter<ShmHandle, base::SharedMemoryHandle>::ConvertFrom(
+ const base::SharedMemoryHandle& input,
+ Buffer* buffer) {
+ ShmHandle::Builder result(buffer);
+ uint64_t handle = 0;
+ memcpy(&handle, &input, sizeof(input));
+ result.set_handle_hack(handle);
+ return result.Finish();
+}
+
+base::SharedMemoryHandle
+TypeConverter<ShmHandle, base::SharedMemoryHandle>::ConvertTo(
+ const ShmHandle& input) {
+ base::SharedMemoryHandle output;
+ uint64_t handle = input.handle_hack();
+ memcpy(&output, &handle, sizeof(output));
+ return output;
+}
+
+CommandBufferState
+TypeConverter<CommandBufferState, gpu::CommandBuffer::State>::ConvertFrom(
+ const gpu::CommandBuffer::State& input,
+ Buffer* buffer) {
+ CommandBufferState::Builder result(buffer);
+ result.set_num_entries(input.num_entries);
+ result.set_get_offset(input.get_offset);
+ result.set_put_offset(input.put_offset);
+ result.set_token(input.token);
+ result.set_error(input.error);
+ result.set_context_lost_reason(input.context_lost_reason);
+ result.set_generation(input.generation);
+ return result.Finish();
+}
+
+gpu::CommandBuffer::State
+TypeConverter<CommandBufferState, gpu::CommandBuffer::State>::ConvertTo(
+ const CommandBufferState& input) {
+ gpu::CommandBuffer::State state;
+ state.num_entries = input.num_entries();
+ state.get_offset = input.get_offset();
+ state.put_offset = input.put_offset();
+ state.token = input.token();
+ state.error = static_cast<gpu::error::Error>(input.error());
+ state.context_lost_reason =
+ static_cast<gpu::error::ContextLostReason>(input.context_lost_reason());
+ state.generation = input.generation();
+ return state;
+}
+
+} // namespace mojo
diff --git a/mojo/services/gles2/command_buffer_type_conversions.h b/mojo/services/gles2/command_buffer_type_conversions.h
new file mode 100644
index 0000000..911bd70
--- /dev/null
+++ b/mojo/services/gles2/command_buffer_type_conversions.h
@@ -0,0 +1,36 @@
+// Copyright 2014 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 MOJO_SERVICES_GLES2_COMMAND_BUFFER_TYPE_CONVERSIONS_H_
+#define MOJO_SERVICES_GLES2_COMMAND_BUFFER_TYPE_CONVERSIONS_H_
+
+#include "base/memory/shared_memory.h"
+#include "gpu/command_buffer/common/command_buffer.h"
+#include "mojo/public/bindings/type_converter.h"
+
+namespace mojo {
+
+class ShmHandle;
+class CommandBufferState;
+class Buffer;
+
+template <>
+class TypeConverter<ShmHandle, base::SharedMemoryHandle> {
+ public:
+ static ShmHandle ConvertFrom(const base::SharedMemoryHandle& input,
+ Buffer* buffer);
+ static base::SharedMemoryHandle ConvertTo(const ShmHandle& input);
+};
+
+template <>
+class TypeConverter<CommandBufferState, gpu::CommandBuffer::State> {
+ public:
+ static CommandBufferState ConvertFrom(const gpu::CommandBuffer::State& input,
+ Buffer* buffer);
+ static gpu::CommandBuffer::State ConvertTo(const CommandBufferState& input);
+};
+
+} // namespace mojo
+
+#endif // MOJO_SERVICES_GLES2_COMMAND_BUFFER_TYPE_CONVERSIONS_H_
diff --git a/mojo/services/gles2/gles2.mojom b/mojo/services/gles2/gles2.mojom
deleted file mode 100644
index d7199d7..0000000
--- a/mojo/services/gles2/gles2.mojom
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 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.
-
-module mojo {
-
-[Peer=GLES2Client]
-interface GLES2 {
- void Initialize(handle<message_pipe> gles2_sync_client);
- void RequestAnimationFrames();
- void CancelAnimationFrames();
- void Destroy();
-};
-
-[Peer=GLES2]
-interface GLES2Client {
- void ContextLost();
- void DrawAnimationFrame();
-};
-
-// TODO(piman): I don't want to have a peer but generator crashes if I don't
-// have one. https://crbug.com/320086
-[Peer=GLES2]
-interface GLES2SyncClient {
- void DidCreateContext(uint64 encoded);
-};
-
-}
diff --git a/mojo/services/gles2/gles2_impl.cc b/mojo/services/gles2/gles2_impl.cc
deleted file mode 100644
index 1a16a25..0000000
--- a/mojo/services/gles2/gles2_impl.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2013 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.
-
-#include "mojo/services/gles2/gles2_impl.h"
-
-#include <stdio.h>
-#include "base/bind.h"
-#include "gpu/command_buffer/client/gl_in_process_context.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-
-namespace mojo {
-namespace services {
-
-GLES2Impl::GLES2Impl(ScopedMessagePipeHandle client)
- : client_(client.Pass(), this) {
-}
-
-GLES2Impl::~GLES2Impl() {
-}
-
-void GLES2Impl::Initialize(ScopedMessagePipeHandle sync_client_handle) {
- sync_client_.reset(sync_client_handle.Pass());
- SendDidCreateContextIfNeeded();
-}
-
-void GLES2Impl::RequestAnimationFrames() {
- timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(16),
- this, &GLES2Impl::DrawAnimationFrame);
-}
-
-void GLES2Impl::CancelAnimationFrames() {
- timer_.Stop();
-}
-
-void GLES2Impl::Destroy() {
- gl_context_.reset();
-}
-
-void GLES2Impl::CreateContext(gfx::AcceleratedWidget widget,
- const gfx::Size& size) {
- gpu::GLInProcessContextAttribs attribs;
- gl_context_.reset(gpu::GLInProcessContext::CreateContext(
- false, widget, size, false, attribs, gfx::PreferDiscreteGpu));
- gl_context_->SetContextLostCallback(base::Bind(
- &GLES2Impl::OnGLContextLost, base::Unretained(this)));
- SendDidCreateContextIfNeeded();
-}
-
-void GLES2Impl::SendDidCreateContextIfNeeded() {
- if (sync_client_.is_null() || !gl_context_.get())
- return;
- gpu::gles2::GLES2Interface* gl = gl_context_->GetImplementation();
- uint64_t encoded_gl = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(gl));
-
- sync_client_->DidCreateContext(encoded_gl);
-}
-
-void GLES2Impl::OnGLContextLost() {
- client_->ContextLost();
-}
-
-void GLES2Impl::DrawAnimationFrame() {
- client_->DrawAnimationFrame();
-}
-
-} // namespace services
-} // namespace mojo
diff --git a/mojo/services/gles2/gles2_impl.h b/mojo/services/gles2/gles2_impl.h
deleted file mode 100644
index 0bdd5c9..0000000
--- a/mojo/services/gles2/gles2_impl.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2013 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 MOJO_SERVICES_GLES2_GLES2_IMPL_H_
-#define MOJO_SERVICES_GLES2_GLES2_IMPL_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/timer/timer.h"
-#include "mojo/public/bindings/remote_ptr.h"
-#include "mojo/public/system/core_cpp.h"
-#include "mojom/gles2.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gfx/size.h"
-
-namespace gpu {
-class GLInProcessContext;
-}
-
-namespace mojo {
-namespace services {
-
-class GLES2Impl : public GLES2 {
- public:
- explicit GLES2Impl(ScopedMessagePipeHandle client);
- virtual ~GLES2Impl();
-
- void CreateContext(gfx::AcceleratedWidget widget, const gfx::Size& size);
-
- private:
- virtual void Initialize(ScopedMessagePipeHandle sync_client_handle) OVERRIDE;
- virtual void RequestAnimationFrames() OVERRIDE;
- virtual void CancelAnimationFrames() OVERRIDE;
- virtual void Destroy() OVERRIDE;
-
- void SendDidCreateContextIfNeeded();
- void OnGLContextLost();
- void DrawAnimationFrame();
-
- base::RepeatingTimer<GLES2Impl> timer_;
- scoped_ptr<gpu::GLInProcessContext> gl_context_;
- RemotePtr<GLES2Client> client_;
- RemotePtr<GLES2SyncClient> sync_client_;
-
- DISALLOW_COPY_AND_ASSIGN(GLES2Impl);
-};
-
-} // namespace services
-} // namespace mojo
-
-#endif // MOJO_SERVICES_GLES2_GLES2_IMPL_H_
diff --git a/mojo/services/native_viewport/native_viewport_service.cc b/mojo/services/native_viewport/native_viewport_service.cc
index 7f485df..ec8068f 100644
--- a/mojo/services/native_viewport/native_viewport_service.cc
+++ b/mojo/services/native_viewport/native_viewport_service.cc
@@ -6,7 +6,7 @@
#include "base/time/time.h"
#include "mojo/public/bindings/allocation_scope.h"
#include "mojo/public/shell/service.h"
-#include "mojo/services/gles2/gles2_impl.h"
+#include "mojo/services/gles2/command_buffer_impl.h"
#include "mojo/services/native_viewport/geometry_conversions.h"
#include "mojo/services/native_viewport/native_viewport.h"
#include "mojo/services/native_viewport/native_viewport_export.h"
@@ -32,9 +32,7 @@ class NativeViewportImpl
NativeViewportImpl()
: widget_(gfx::kNullAcceleratedWidget),
waiting_for_event_ack_(false),
- pending_event_timestamp_(0),
- created_context_(false) {
- }
+ pending_event_timestamp_(0) {}
virtual ~NativeViewportImpl() {}
virtual void Create(const Rect& bounds) MOJO_OVERRIDE {
@@ -53,7 +51,7 @@ class NativeViewportImpl
}
virtual void Close() MOJO_OVERRIDE {
- gles2_.reset();
+ command_buffer_.reset();
DCHECK(native_viewport_);
native_viewport_->Close();
}
@@ -66,8 +64,13 @@ class NativeViewportImpl
virtual void CreateGLES2Context(ScopedMessagePipeHandle client_handle)
MOJO_OVERRIDE {
- gles2_.reset(new GLES2Impl(client_handle.Pass()));
- CreateGLES2ContextIfNeeded();
+ if (command_buffer_ || command_buffer_handle_.is_valid()) {
+ LOG(ERROR) << "Can't create multiple contexts on a NativeViewport";
+ return;
+ }
+
+ command_buffer_handle_ = client_handle.Pass();
+ CreateCommandBufferIfNeeded();
}
virtual void AckEvent(const Event& event) MOJO_OVERRIDE {
@@ -75,16 +78,17 @@ class NativeViewportImpl
waiting_for_event_ack_ = false;
}
- void CreateGLES2ContextIfNeeded() {
- if (created_context_)
+ void CreateCommandBufferIfNeeded() {
+ if (!command_buffer_handle_.is_valid())
return;
- if (widget_ == gfx::kNullAcceleratedWidget || !gles2_)
+ DCHECK(!command_buffer_.get());
+ if (widget_ == gfx::kNullAcceleratedWidget)
return;
gfx::Size size = native_viewport_->GetSize();
if (size.IsEmpty())
return;
- gles2_->CreateContext(widget_, size);
- created_context_ = true;
+ command_buffer_.reset(new CommandBufferImpl(
+ command_buffer_handle_.Pass(), widget_, native_viewport_->GetSize()));
}
virtual bool OnEvent(ui::Event* ui_event) MOJO_OVERRIDE {
@@ -143,25 +147,17 @@ class NativeViewportImpl
virtual void OnAcceleratedWidgetAvailable(
gfx::AcceleratedWidget widget) MOJO_OVERRIDE {
widget_ = widget;
- CreateGLES2ContextIfNeeded();
+ CreateCommandBufferIfNeeded();
}
virtual void OnBoundsChanged(const gfx::Rect& bounds) MOJO_OVERRIDE {
- CreateGLES2ContextIfNeeded();
+ CreateCommandBufferIfNeeded();
AllocationScope scope;
client()->OnBoundsChanged(bounds);
}
virtual void OnDestroyed() MOJO_OVERRIDE {
- // TODO(beng):
- // Destroying |gles2_| on the shell thread here hits thread checker
- // asserts. All code must stop touching the AcceleratedWidget at this
- // point as it is dead after this call stack. jamesr said we probably
- // should make our own GLSurface and simply tell it to stop touching the
- // AcceleratedWidget via Destroy() but we have no good way of doing that
- // right now given our current threading model so james' recommendation
- // was just to wait until after we move the gl service out of process.
- // gles2_.reset();
+ command_buffer_.reset();
client()->OnDestroyed();
base::MessageLoop::current()->Quit();
}
@@ -169,10 +165,10 @@ class NativeViewportImpl
private:
gfx::AcceleratedWidget widget_;
scoped_ptr<services::NativeViewport> native_viewport_;
- scoped_ptr<GLES2Impl> gles2_;
+ ScopedMessagePipeHandle command_buffer_handle_;
+ scoped_ptr<CommandBufferImpl> command_buffer_;
bool waiting_for_event_ack_;
int64 pending_event_timestamp_;
- bool created_context_;
};
} // namespace services