Bluetooth: add Device events, and cleanup JS API
[chromium-blink-merge.git] / mojo / gles2 / command_buffer_client_impl.cc
blob60fa366ab0574f5bd156f7b0e8a894003b02e7f7
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/gles2/command_buffer_client_impl.h"
7 #include <limits>
9 #include "base/logging.h"
10 #include "base/process/process_handle.h"
11 #include "mojo/public/bindings/allocation_scope.h"
12 #include "mojo/public/bindings/sync_dispatcher.h"
13 #include "mojo/services/gles2/command_buffer_type_conversions.h"
15 namespace mojo {
16 namespace gles2 {
18 CommandBufferDelegate::~CommandBufferDelegate() {}
20 void CommandBufferDelegate::ContextLost() {}
21 void CommandBufferDelegate::DrawAnimationFrame() {}
23 CommandBufferClientImpl::CommandBufferClientImpl(
24 CommandBufferDelegate* delegate,
25 MojoAsyncWaiter* async_waiter,
26 ScopedCommandBufferHandle command_buffer_handle)
27 : delegate_(delegate),
28 command_buffer_(command_buffer_handle.Pass(), this, this, async_waiter),
29 last_put_offset_(-1),
30 next_transfer_buffer_id_(0),
31 initialize_result_(false) {}
33 CommandBufferClientImpl::~CommandBufferClientImpl() {}
35 bool CommandBufferClientImpl::Initialize() {
36 shared_state_shm_.reset(new base::SharedMemory);
37 if (!shared_state_shm_->CreateAndMapAnonymous(
38 sizeof(gpu::CommandBufferSharedState)))
39 return false;
41 base::SharedMemoryHandle handle;
42 shared_state_shm_->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
43 if (!base::SharedMemory::IsHandleValid(handle))
44 return false;
46 shared_state()->Initialize();
48 InterfacePipe<CommandBufferSyncClient, NoInterface> sync_pipe;
49 sync_dispatcher_.reset(new SyncDispatcher<CommandBufferSyncClient>(
50 sync_pipe.handle_to_peer.Pass(), this));
51 AllocationScope scope;
52 command_buffer_->Initialize(sync_pipe.handle_to_self.Pass(), handle);
53 // Wait for DidInitialize to come on the sync client pipe.
54 if (!sync_dispatcher_->WaitAndDispatchOneMessage()) {
55 VLOG(1) << "Channel encountered error while creating command buffer";
56 return false;
58 return initialize_result_;
61 gpu::CommandBuffer::State CommandBufferClientImpl::GetState() {
62 MakeProgressAndUpdateState();
63 return last_state_;
66 gpu::CommandBuffer::State CommandBufferClientImpl::GetLastState() {
67 return last_state_;
70 int32 CommandBufferClientImpl::GetLastToken() {
71 TryUpdateState();
72 return last_state_.token;
75 void CommandBufferClientImpl::Flush(int32 put_offset) {
76 if (last_put_offset_ == put_offset)
77 return;
79 last_put_offset_ = put_offset;
80 command_buffer_->Flush(put_offset);
83 gpu::CommandBuffer::State CommandBufferClientImpl::FlushSync(
84 int32 put_offset,
85 int32 last_known_get) {
86 Flush(put_offset);
87 TryUpdateState();
88 if (last_known_get == last_state_.get_offset)
89 MakeProgressAndUpdateState();
91 return last_state_;
94 void CommandBufferClientImpl::SetGetBuffer(int32 shm_id) {
95 command_buffer_->SetGetBuffer(shm_id);
96 last_put_offset_ = -1;
99 void CommandBufferClientImpl::SetGetOffset(int32 get_offset) {
100 // Not implemented in proxy.
101 NOTREACHED();
104 gpu::Buffer CommandBufferClientImpl::CreateTransferBuffer(size_t size,
105 int32* id) {
106 gpu::Buffer buffer;
107 if (size >= std::numeric_limits<uint32_t>::max())
108 return buffer;
110 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
111 if (!shared_memory->CreateAndMapAnonymous(size))
112 return buffer;
114 base::SharedMemoryHandle handle;
115 shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), &handle);
116 if (!base::SharedMemory::IsHandleValid(handle))
117 return buffer;
119 *id = ++next_transfer_buffer_id_;
120 DCHECK(transfer_buffers_.find(*id) == transfer_buffers_.end());
122 AllocationScope scope;
123 command_buffer_->RegisterTransferBuffer(
124 *id, handle, static_cast<uint32_t>(size));
126 buffer.ptr = shared_memory->memory();
127 buffer.size = size;
128 buffer.shared_memory = shared_memory.release();
129 transfer_buffers_[*id] = buffer;
131 return buffer;
134 void CommandBufferClientImpl::DestroyTransferBuffer(int32 id) {
135 TransferBufferMap::iterator it = transfer_buffers_.find(id);
136 if (it != transfer_buffers_.end()) {
137 delete it->second.shared_memory;
138 transfer_buffers_.erase(it);
140 command_buffer_->DestroyTransferBuffer(id);
143 gpu::Buffer CommandBufferClientImpl::GetTransferBuffer(int32 id) {
144 TransferBufferMap::iterator it = transfer_buffers_.find(id);
145 if (it != transfer_buffers_.end()) {
146 return it->second;
147 } else {
148 return gpu::Buffer();
152 void CommandBufferClientImpl::SetToken(int32 token) {
153 // Not implemented in proxy.
154 NOTREACHED();
157 void CommandBufferClientImpl::SetParseError(gpu::error::Error error) {
158 // Not implemented in proxy.
159 NOTREACHED();
162 void CommandBufferClientImpl::SetContextLostReason(
163 gpu::error::ContextLostReason reason) {
164 // Not implemented in proxy.
165 NOTREACHED();
168 gpu::Capabilities CommandBufferClientImpl::GetCapabilities() {
169 // TODO(piman)
170 NOTIMPLEMENTED();
171 return gpu::Capabilities();
174 gfx::GpuMemoryBuffer* CommandBufferClientImpl::CreateGpuMemoryBuffer(
175 size_t width,
176 size_t height,
177 unsigned internalformat,
178 int32* id) {
179 // TODO(piman)
180 NOTIMPLEMENTED();
181 return NULL;
184 void CommandBufferClientImpl::DestroyGpuMemoryBuffer(int32 id) {
185 // TODO(piman)
186 NOTIMPLEMENTED();
189 uint32 CommandBufferClientImpl::InsertSyncPoint() {
190 // TODO(piman)
191 NOTIMPLEMENTED();
192 return 0;
195 void CommandBufferClientImpl::SignalSyncPoint(uint32 sync_point,
196 const base::Closure& callback) {
197 // TODO(piman)
198 NOTIMPLEMENTED();
201 void CommandBufferClientImpl::SignalQuery(uint32 query,
202 const base::Closure& callback) {
203 // TODO(piman)
204 NOTIMPLEMENTED();
207 void CommandBufferClientImpl::SetSurfaceVisible(bool visible) {
208 // TODO(piman)
209 NOTIMPLEMENTED();
212 void CommandBufferClientImpl::SendManagedMemoryStats(
213 const gpu::ManagedMemoryStats& stats) {
214 // TODO(piman)
215 NOTIMPLEMENTED();
218 void CommandBufferClientImpl::Echo(const base::Closure& callback) {
219 echo_closures_.push(callback);
220 command_buffer_->Echo();
223 uint32 CommandBufferClientImpl::CreateStreamTexture(uint32 texture_id) {
224 // TODO(piman)
225 NOTIMPLEMENTED();
226 return 0;
229 void CommandBufferClientImpl::RequestAnimationFrames() {
230 command_buffer_->RequestAnimationFrames();
233 void CommandBufferClientImpl::CancelAnimationFrames() {
234 command_buffer_->CancelAnimationFrames();
237 void CommandBufferClientImpl::DidInitialize(bool success) {
238 initialize_result_ = success;
241 void CommandBufferClientImpl::DidMakeProgress(const CommandBufferState& state) {
242 if (state.generation() - last_state_.generation < 0x80000000U)
243 last_state_ = state;
246 void CommandBufferClientImpl::DidDestroy() {
247 LostContext(gpu::error::kUnknown);
250 void CommandBufferClientImpl::EchoAck() {
251 base::Closure closure = echo_closures_.front();
252 echo_closures_.pop();
253 closure.Run();
256 void CommandBufferClientImpl::LostContext(int32_t lost_reason) {
257 last_state_.error = gpu::error::kLostContext;
258 last_state_.context_lost_reason =
259 static_cast<gpu::error::ContextLostReason>(lost_reason);
260 delegate_->ContextLost();
263 void CommandBufferClientImpl::OnError() { LostContext(gpu::error::kUnknown); }
265 void CommandBufferClientImpl::TryUpdateState() {
266 if (last_state_.error == gpu::error::kNoError)
267 shared_state()->Read(&last_state_);
270 void CommandBufferClientImpl::MakeProgressAndUpdateState() {
271 command_buffer_->MakeProgress(last_state_.get_offset);
272 if (!sync_dispatcher_->WaitAndDispatchOneMessage()) {
273 VLOG(1) << "Channel encountered error while waiting for command buffer";
274 // TODO(piman): is it ok for this to re-enter?
275 DidDestroy();
276 return;
280 void CommandBufferClientImpl::DrawAnimationFrame() {
281 delegate_->DrawAnimationFrame();
284 } // namespace gles2
285 } // namespace mojo