OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "components/mus/gles2/command_buffer_impl.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/macros.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "components/mus/common/gpu_type_converters.h" | |
11 #include "components/mus/gles2/command_buffer_driver.h" | |
12 #include "components/mus/gles2/gpu_state.h" | |
13 #include "gpu/command_buffer/service/sync_point_manager.h" | |
14 | |
15 namespace mus { | |
16 | |
17 namespace { | |
18 | |
19 uint64_t g_next_command_buffer_id = 0; | |
20 | |
21 void RunInitializeCallback( | |
22 const mojom::CommandBuffer::InitializeCallback& callback, | |
23 mojom::CommandBufferInitializeResultPtr result) { | |
24 callback.Run(std::move(result)); | |
25 } | |
26 | |
27 void RunMakeProgressCallback( | |
28 const mojom::CommandBuffer::MakeProgressCallback& callback, | |
29 const gpu::CommandBuffer::State& state) { | |
30 callback.Run(state); | |
31 } | |
32 | |
33 } // namespace | |
34 | |
35 CommandBufferImpl::CommandBufferImpl( | |
36 mojo::InterfaceRequest<mus::mojom::CommandBuffer> request, | |
37 scoped_refptr<GpuState> gpu_state) | |
38 : gpu_state_(gpu_state) { | |
39 // Bind |CommandBufferImpl| to the |request| in the GPU control thread. | |
40 gpu_state_->control_task_runner()->PostTask( | |
41 FROM_HERE, | |
42 base::Bind(&CommandBufferImpl::BindToRequest, | |
43 base::Unretained(this), base::Passed(&request))); | |
44 } | |
45 | |
46 void CommandBufferImpl::DidLoseContext(uint32_t reason) { | |
47 driver_->set_client(nullptr); | |
48 client_->Destroyed(reason, gpu::error::kLostContext); | |
49 } | |
50 | |
51 void CommandBufferImpl::UpdateVSyncParameters(const base::TimeTicks& timebase, | |
52 const base::TimeDelta& interval) { | |
53 } | |
54 | |
55 void CommandBufferImpl::OnGpuCompletedSwapBuffers(gfx::SwapResult result) {} | |
56 | |
57 CommandBufferImpl::~CommandBufferImpl() { | |
58 } | |
59 | |
60 void CommandBufferImpl::Initialize( | |
61 mus::mojom::CommandBufferClientPtr client, | |
62 mojo::ScopedSharedBufferHandle shared_state, | |
63 mojo::Array<int32_t> attribs, | |
64 const mojom::CommandBuffer::InitializeCallback& callback) { | |
65 gpu_state_->command_buffer_task_runner()->task_runner()->PostTask( | |
66 FROM_HERE, | |
67 base::Bind(&CommandBufferImpl::InitializeOnGpuThread, | |
68 base::Unretained(this), base::Passed(&client), | |
69 base::Passed(&shared_state), base::Passed(&attribs), | |
70 base::Bind(&RunInitializeCallback, callback))); | |
71 } | |
72 | |
73 void CommandBufferImpl::SetGetBuffer(int32_t buffer) { | |
74 gpu_state_->command_buffer_task_runner()->PostTask( | |
75 driver_.get(), base::Bind(&CommandBufferImpl::SetGetBufferOnGpuThread, | |
76 base::Unretained(this), buffer)); | |
77 } | |
78 | |
79 void CommandBufferImpl::Flush(int32_t put_offset) { | |
80 gpu::SyncPointManager* sync_point_manager = gpu_state_->sync_point_manager(); | |
81 const uint32_t order_num = driver_->sync_point_order_data() | |
82 ->GenerateUnprocessedOrderNumber(sync_point_manager); | |
83 gpu_state_->command_buffer_task_runner()->PostTask( | |
84 driver_.get(), base::Bind(&CommandBufferImpl::FlushOnGpuThread, | |
85 base::Unretained(this), put_offset, order_num)); | |
86 } | |
87 | |
88 void CommandBufferImpl::MakeProgress( | |
89 int32_t last_get_offset, | |
90 const mojom::CommandBuffer::MakeProgressCallback& callback) { | |
91 gpu_state_->command_buffer_task_runner()->PostTask( | |
92 driver_.get(), base::Bind(&CommandBufferImpl::MakeProgressOnGpuThread, | |
93 base::Unretained(this), last_get_offset, | |
94 base::Bind(&RunMakeProgressCallback, | |
95 callback))); | |
96 } | |
97 | |
98 void CommandBufferImpl::RegisterTransferBuffer( | |
99 int32_t id, | |
100 mojo::ScopedSharedBufferHandle transfer_buffer, | |
101 uint32_t size) { | |
102 gpu_state_->command_buffer_task_runner()->PostTask( | |
103 driver_.get(), | |
104 base::Bind(&CommandBufferImpl::RegisterTransferBufferOnGpuThread, | |
105 base::Unretained(this), id, base::Passed(&transfer_buffer), | |
106 size)); | |
107 } | |
108 | |
109 void CommandBufferImpl::DestroyTransferBuffer(int32_t id) { | |
110 gpu_state_->command_buffer_task_runner()->PostTask( | |
111 driver_.get(), | |
112 base::Bind(&CommandBufferImpl::DestroyTransferBufferOnGpuThread, | |
113 base::Unretained(this), id)); | |
114 } | |
115 | |
116 void CommandBufferImpl::CreateImage(int32_t id, | |
117 mojo::ScopedHandle memory_handle, | |
118 int32_t type, | |
119 const gfx::Size& size, | |
120 int32_t format, | |
121 int32_t internal_format) { | |
122 gpu_state_->command_buffer_task_runner()->PostTask( | |
123 driver_.get(), | |
124 base::Bind(&CommandBufferImpl::CreateImageOnGpuThread, | |
125 base::Unretained(this), id, base::Passed(&memory_handle), type, | |
126 size, format, internal_format)); | |
127 } | |
128 | |
129 void CommandBufferImpl::DestroyImage(int32_t id) { | |
130 gpu_state_->command_buffer_task_runner()->PostTask( | |
131 driver_.get(), base::Bind(&CommandBufferImpl::DestroyImageOnGpuThread, | |
132 base::Unretained(this), id)); | |
133 } | |
134 | |
135 void CommandBufferImpl::CreateStreamTexture( | |
136 uint32_t client_texture_id, | |
137 const mojom::CommandBuffer::CreateStreamTextureCallback& callback) { | |
138 NOTIMPLEMENTED(); | |
139 } | |
140 | |
141 void CommandBufferImpl::TakeFrontBuffer(const gpu::Mailbox& mailbox) { | |
142 NOTIMPLEMENTED(); | |
143 } | |
144 | |
145 void CommandBufferImpl::ReturnFrontBuffer(const gpu::Mailbox& mailbox, | |
146 bool is_lost) { | |
147 NOTIMPLEMENTED(); | |
148 } | |
149 | |
150 void CommandBufferImpl::SignalQuery(uint32_t query, uint32_t signal_id) { | |
151 NOTIMPLEMENTED(); | |
152 } | |
153 | |
154 void CommandBufferImpl::SignalSyncToken(const gpu::SyncToken& sync_token, | |
155 uint32_t signal_id) { | |
156 NOTIMPLEMENTED(); | |
157 } | |
158 | |
159 void CommandBufferImpl::WaitForGetOffsetInRange( | |
160 int32_t start, int32_t end, | |
161 const mojom::CommandBuffer::WaitForGetOffsetInRangeCallback& callback) { | |
162 NOTIMPLEMENTED(); | |
163 } | |
164 | |
165 void CommandBufferImpl::WaitForTokenInRange( | |
166 int32_t start, int32_t end, | |
167 const mojom::CommandBuffer::WaitForGetOffsetInRangeCallback& callback) { | |
168 NOTIMPLEMENTED(); | |
169 } | |
170 | |
171 void CommandBufferImpl::BindToRequest( | |
172 mojo::InterfaceRequest<mus::mojom::CommandBuffer> request) { | |
173 binding_.reset( | |
174 new mojo::Binding<mus::mojom::CommandBuffer>(this, std::move(request))); | |
175 binding_->set_connection_error_handler( | |
176 base::Bind(&CommandBufferImpl::OnConnectionError, | |
177 base::Unretained(this))); | |
178 } | |
179 | |
180 void CommandBufferImpl::InitializeOnGpuThread( | |
181 mojom::CommandBufferClientPtr client, | |
182 mojo::ScopedSharedBufferHandle shared_state, | |
183 mojo::Array<int32_t> attribs, | |
184 const base::Callback< | |
185 void(mojom::CommandBufferInitializeResultPtr)>& callback) { | |
186 DCHECK(!driver_); | |
187 driver_.reset(new CommandBufferDriver( | |
188 gpu::CommandBufferNamespace::MOJO, | |
189 gpu::CommandBufferId::FromUnsafeValue(++g_next_command_buffer_id), | |
190 gfx::kNullAcceleratedWidget, gpu_state_)); | |
191 driver_->set_client(this); | |
192 client_ = mojo::MakeProxy(client.PassInterface()); | |
193 bool result = | |
194 driver_->Initialize(std::move(shared_state), std::move(attribs)); | |
195 mojom::CommandBufferInitializeResultPtr initialize_result; | |
196 if (result) { | |
197 initialize_result = mojom::CommandBufferInitializeResult::New(); | |
198 initialize_result->command_buffer_namespace = driver_->GetNamespaceID(); | |
199 initialize_result->command_buffer_id = | |
200 driver_->GetCommandBufferID().GetUnsafeValue(); | |
201 initialize_result->capabilities = driver_->GetCapabilities(); | |
202 } | |
203 gpu_state_->control_task_runner()->PostTask( | |
204 FROM_HERE, base::Bind(callback, base::Passed(&initialize_result))); | |
205 } | |
206 | |
207 bool CommandBufferImpl::SetGetBufferOnGpuThread(int32_t buffer) { | |
208 DCHECK(driver_->IsScheduled()); | |
209 driver_->SetGetBuffer(buffer); | |
210 return true; | |
211 } | |
212 | |
213 bool CommandBufferImpl::FlushOnGpuThread(int32_t put_offset, | |
214 uint32_t order_num) { | |
215 DCHECK(driver_->IsScheduled()); | |
216 driver_->sync_point_order_data()->BeginProcessingOrderNumber(order_num); | |
217 driver_->Flush(put_offset); | |
218 | |
219 // Return false if the Flush is not finished, so the CommandBufferTaskRunner | |
220 // will not remove this task from the task queue. | |
221 const bool complete = !driver_->HasUnprocessedCommands(); | |
222 if (!complete) | |
223 driver_->sync_point_order_data()->PauseProcessingOrderNumber(order_num); | |
224 else | |
225 driver_->sync_point_order_data()->FinishProcessingOrderNumber(order_num); | |
226 return complete; | |
227 } | |
228 | |
229 bool CommandBufferImpl::MakeProgressOnGpuThread( | |
230 int32_t last_get_offset, | |
231 const base::Callback<void(const gpu::CommandBuffer::State&)>& callback) { | |
232 DCHECK(driver_->IsScheduled()); | |
233 gpu_state_->control_task_runner()->PostTask( | |
234 FROM_HERE, base::Bind(callback, driver_->GetLastState())); | |
235 return true; | |
236 } | |
237 | |
238 bool CommandBufferImpl::RegisterTransferBufferOnGpuThread( | |
239 int32_t id, | |
240 mojo::ScopedSharedBufferHandle transfer_buffer, | |
241 uint32_t size) { | |
242 DCHECK(driver_->IsScheduled()); | |
243 driver_->RegisterTransferBuffer(id, std::move(transfer_buffer), size); | |
244 return true; | |
245 } | |
246 | |
247 bool CommandBufferImpl::DestroyTransferBufferOnGpuThread(int32_t id) { | |
248 DCHECK(driver_->IsScheduled()); | |
249 driver_->DestroyTransferBuffer(id); | |
250 return true; | |
251 } | |
252 | |
253 bool CommandBufferImpl::CreateImageOnGpuThread(int32_t id, | |
254 mojo::ScopedHandle memory_handle, | |
255 int32_t type, | |
256 const gfx::Size& size, | |
257 int32_t format, | |
258 int32_t internal_format) { | |
259 DCHECK(driver_->IsScheduled()); | |
260 driver_->CreateImage(id, std::move(memory_handle), type, std::move(size), | |
261 format, internal_format); | |
262 return true; | |
263 } | |
264 | |
265 bool CommandBufferImpl::DestroyImageOnGpuThread(int32_t id) { | |
266 DCHECK(driver_->IsScheduled()); | |
267 driver_->DestroyImage(id); | |
268 return true; | |
269 } | |
270 | |
271 void CommandBufferImpl::OnConnectionError() { | |
272 // OnConnectionError() is called on the control thread |control_task_runner|. | |
273 | |
274 // Before deleting, we need to delete |binding_| because it is bound to the | |
275 // current thread (|control_task_runner|). | |
276 binding_.reset(); | |
277 | |
278 // Objects we own (such as CommandBufferDriver) need to be destroyed on the | |
279 // thread we were created on. It's entirely possible we haven't or are in the | |
280 // process of creating |driver_|. | |
281 if (driver_) { | |
282 gpu_state_->command_buffer_task_runner()->PostTask( | |
283 driver_.get(), base::Bind(&CommandBufferImpl::DeleteOnGpuThread, | |
284 base::Unretained(this))); | |
285 } else { | |
286 gpu_state_->command_buffer_task_runner()->task_runner()->PostTask( | |
287 FROM_HERE, base::Bind(&CommandBufferImpl::DeleteOnGpuThread2, | |
288 base::Unretained(this))); | |
289 } | |
290 } | |
291 | |
292 bool CommandBufferImpl::DeleteOnGpuThread() { | |
293 delete this; | |
294 return true; | |
295 } | |
296 | |
297 void CommandBufferImpl::DeleteOnGpuThread2() { | |
298 delete this; | |
299 } | |
300 | |
301 } // namespace mus | |
OLD | NEW |