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 "services/ui/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 "gpu/command_buffer/service/sync_point_manager.h" |
| 11 #include "services/ui/common/gpu_type_converters.h" |
| 12 #include "services/ui/gles2/command_buffer_driver.h" |
| 13 #include "services/ui/gles2/gpu_state.h" |
| 14 |
| 15 namespace ui { |
| 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<ui::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 ui::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<ui::mojom::CommandBuffer> request) { |
| 173 binding_.reset( |
| 174 new mojo::Binding<ui::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 ui |
OLD | NEW |