1 // Copyright 2013 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/services/gles2/command_buffer_impl.h"
8 #include "base/memory/shared_memory.h"
10 #include "gpu/command_buffer/common/constants.h"
11 #include "gpu/command_buffer/service/command_buffer_service.h"
12 #include "gpu/command_buffer/service/context_group.h"
13 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
14 #include "gpu/command_buffer/service/gpu_control_service.h"
15 #include "gpu/command_buffer/service/gpu_scheduler.h"
16 #include "gpu/command_buffer/service/image_manager.h"
17 #include "gpu/command_buffer/service/mailbox_manager.h"
18 #include "gpu/command_buffer/service/memory_tracking.h"
19 #include "mojo/public/bindings/allocation_scope.h"
20 #include "mojo/services/gles2/command_buffer_type_conversions.h"
21 #include "ui/gl/gl_context.h"
22 #include "ui/gl/gl_surface.h"
29 class MemoryTrackerStub : public gpu::gles2::MemoryTracker {
31 MemoryTrackerStub() {}
33 virtual void TrackMemoryAllocatedChange(size_t old_size,
35 gpu::gles2::MemoryTracker::Pool pool)
38 virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE {
43 virtual ~MemoryTrackerStub() {}
45 DISALLOW_COPY_AND_ASSIGN(MemoryTrackerStub);
48 } // anonymous namespace
50 CommandBufferImpl::CommandBufferImpl(ScopedCommandBufferClientHandle client,
51 gfx::AcceleratedWidget widget,
52 const gfx::Size& size)
53 : client_(client.Pass(), this), widget_(widget), size_(size) {}
55 CommandBufferImpl::~CommandBufferImpl() { client_->DidDestroy(); }
57 void CommandBufferImpl::Initialize(
58 ScopedCommandBufferSyncClientHandle sync_client,
59 const ShmHandle& shared_state) {
60 sync_client_.reset(sync_client.Pass());
61 sync_client_->DidInitialize(DoInitialize(shared_state));
64 bool CommandBufferImpl::DoInitialize(const ShmHandle& shared_state) {
65 // TODO(piman): offscreen surface.
66 scoped_refptr<gfx::GLSurface> surface =
67 gfx::GLSurface::CreateViewGLSurface(widget_);
71 // TODO(piman): context sharing, virtual contexts, gpu preference.
72 scoped_refptr<gfx::GLContext> context = gfx::GLContext::CreateGLContext(
73 NULL, surface.get(), gfx::PreferIntegratedGpu);
77 if (!context->MakeCurrent(surface.get()))
80 scoped_refptr<gpu::gles2::ContextGroup> context_group =
81 new gpu::gles2::ContextGroup(
82 NULL, NULL, new MemoryTrackerStub(), NULL, true);
83 command_buffer_.reset(
84 new gpu::CommandBufferService(context_group->transfer_buffer_manager()));
85 bool result = command_buffer_->Initialize();
88 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group.get()));
89 scheduler_.reset(new gpu::GpuScheduler(
90 command_buffer_.get(), decoder_.get(), decoder_.get()));
91 decoder_->set_engine(scheduler_.get());
93 gpu::gles2::DisallowedFeatures disallowed_features;
95 // TODO(piman): attributes.
96 std::vector<int32> attrib_vector;
97 if (!decoder_->Initialize(surface,
99 false /* offscreen */,
106 new gpu::GpuControlService(context_group->image_manager(),
108 context_group->mailbox_manager(),
110 decoder_->GetCapabilities()));
112 command_buffer_->SetPutOffsetChangeCallback(base::Bind(
113 &gpu::GpuScheduler::PutChanged, base::Unretained(scheduler_.get())));
114 command_buffer_->SetGetBufferChangeCallback(base::Bind(
115 &gpu::GpuScheduler::SetGetBuffer, base::Unretained(scheduler_.get())));
116 command_buffer_->SetParseErrorCallback(
117 base::Bind(&CommandBufferImpl::OnParseError, base::Unretained(this)));
119 // TODO(piman): other callbacks
121 scoped_ptr<base::SharedMemory> shared_state_shm(
122 new base::SharedMemory(shared_state, false));
123 if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass()))
129 void CommandBufferImpl::SetGetBuffer(int32_t buffer) {
130 command_buffer_->SetGetBuffer(buffer);
133 void CommandBufferImpl::Flush(int32_t put_offset) {
134 command_buffer_->Flush(put_offset);
137 void CommandBufferImpl::MakeProgress(int32_t last_get_offset) {
138 // TODO(piman): handle out-of-order.
139 AllocationScope scope;
140 sync_client_->DidMakeProgress(command_buffer_->GetState());
143 void CommandBufferImpl::RegisterTransferBuffer(int32_t id,
144 const ShmHandle& transfer_buffer,
146 bool read_only = false;
147 base::SharedMemory shared_memory(transfer_buffer, read_only);
148 command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
151 void CommandBufferImpl::DestroyTransferBuffer(int32_t id) {
152 command_buffer_->DestroyTransferBuffer(id);
155 void CommandBufferImpl::Echo() { client_->EchoAck(); }
157 void CommandBufferImpl::RequestAnimationFrames() {
158 timer_.Start(FROM_HERE,
159 base::TimeDelta::FromMilliseconds(16),
161 &CommandBufferImpl::DrawAnimationFrame);
164 void CommandBufferImpl::CancelAnimationFrames() { timer_.Stop(); }
166 void CommandBufferImpl::OnParseError() {
167 gpu::CommandBuffer::State state = command_buffer_->GetState();
168 client_->LostContext(state.context_lost_reason);
171 void CommandBufferImpl::DrawAnimationFrame() { client_->DrawAnimationFrame(); }
173 } // namespace services