Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / services / gles2 / command_buffer_impl.cc
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.
4
5 #include "mojo/services/gles2/command_buffer_impl.h"
6
7 #include "base/bind.h"
8 #include "base/memory/shared_memory.h"
9
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"
23
24 namespace mojo {
25 namespace services {
26
27 namespace {
28
29 class MemoryTrackerStub : public gpu::gles2::MemoryTracker {
30  public:
31   MemoryTrackerStub() {}
32
33   virtual void TrackMemoryAllocatedChange(size_t old_size,
34                                           size_t new_size,
35                                           gpu::gles2::MemoryTracker::Pool pool)
36       OVERRIDE {}
37
38   virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE {
39     return true;
40   };
41
42  private:
43   virtual ~MemoryTrackerStub() {}
44
45   DISALLOW_COPY_AND_ASSIGN(MemoryTrackerStub);
46 };
47
48 }  // anonymous namespace
49
50 CommandBufferImpl::CommandBufferImpl(ScopedCommandBufferClientHandle client,
51                                      gfx::AcceleratedWidget widget,
52                                      const gfx::Size& size)
53     : client_(client.Pass(), this), widget_(widget), size_(size) {}
54
55 CommandBufferImpl::~CommandBufferImpl() { client_->DidDestroy(); }
56
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));
62 }
63
64 bool CommandBufferImpl::DoInitialize(const ShmHandle& shared_state) {
65   // TODO(piman): offscreen surface.
66   scoped_refptr<gfx::GLSurface> surface =
67       gfx::GLSurface::CreateViewGLSurface(widget_);
68   if (!surface.get())
69     return false;
70
71   // TODO(piman): context sharing, virtual contexts, gpu preference.
72   scoped_refptr<gfx::GLContext> context = gfx::GLContext::CreateGLContext(
73       NULL, surface.get(), gfx::PreferIntegratedGpu);
74   if (!context.get())
75     return false;
76
77   if (!context->MakeCurrent(surface.get()))
78     return false;
79
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();
86   DCHECK(result);
87
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());
92
93   gpu::gles2::DisallowedFeatures disallowed_features;
94
95   // TODO(piman): attributes.
96   std::vector<int32> attrib_vector;
97   if (!decoder_->Initialize(surface,
98                             context,
99                             false /* offscreen */,
100                             size_,
101                             disallowed_features,
102                             attrib_vector))
103     return false;
104
105   gpu_control_.reset(
106       new gpu::GpuControlService(context_group->image_manager(),
107                                  NULL,
108                                  context_group->mailbox_manager(),
109                                  NULL,
110                                  decoder_->GetCapabilities()));
111
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)));
118
119   // TODO(piman): other callbacks
120
121   scoped_ptr<base::SharedMemory> shared_state_shm(
122       new base::SharedMemory(shared_state, false));
123   if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass()))
124     return false;
125
126   return true;
127 }
128
129 void CommandBufferImpl::SetGetBuffer(int32_t buffer) {
130   command_buffer_->SetGetBuffer(buffer);
131 }
132
133 void CommandBufferImpl::Flush(int32_t put_offset) {
134   command_buffer_->Flush(put_offset);
135 }
136
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());
141 }
142
143 void CommandBufferImpl::RegisterTransferBuffer(int32_t id,
144                                                const ShmHandle& transfer_buffer,
145                                                uint32_t size) {
146   bool read_only = false;
147   base::SharedMemory shared_memory(transfer_buffer, read_only);
148   command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
149 }
150
151 void CommandBufferImpl::DestroyTransferBuffer(int32_t id) {
152   command_buffer_->DestroyTransferBuffer(id);
153 }
154
155 void CommandBufferImpl::Echo() { client_->EchoAck(); }
156
157 void CommandBufferImpl::RequestAnimationFrames() {
158   timer_.Start(FROM_HERE,
159                base::TimeDelta::FromMilliseconds(16),
160                this,
161                &CommandBufferImpl::DrawAnimationFrame);
162 }
163
164 void CommandBufferImpl::CancelAnimationFrames() { timer_.Stop(); }
165
166 void CommandBufferImpl::OnParseError() {
167   gpu::CommandBuffer::State state = command_buffer_->GetState();
168   client_->LostContext(state.context_lost_reason);
169 }
170
171 void CommandBufferImpl::DrawAnimationFrame() { client_->DrawAnimationFrame(); }
172
173 }  // namespace services
174 }  // namespace mojo