Adam Barth | 116f6fe | 2014-11-18 09:30:34 -0800 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
James Robinson | c9b163e | 2014-12-03 13:31:32 -0800 | [diff] [blame] | 5 | #include "services/gles2/command_buffer_impl.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 6 | |
Vardhan Mudunuru | c3575c4 | 2016-02-11 15:08:21 -0800 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 9 | #include "base/bind.h" |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 10 | #include "base/message_loop/message_loop.h" |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 11 | #include "gpu/command_buffer/service/sync_point_manager.h" |
James Robinson | c9b163e | 2014-12-03 13:31:32 -0800 | [diff] [blame] | 12 | #include "services/gles2/command_buffer_driver.h" |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 13 | |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 14 | namespace gles2 { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 15 | namespace { |
| 16 | void DestroyDriver(scoped_ptr<CommandBufferDriver> driver) { |
| 17 | // Just let ~scoped_ptr run. |
| 18 | } |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 19 | |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 20 | void RunCallback(const mojo::Callback<void()>& callback) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 21 | callback.Run(); |
| 22 | } |
Adam Barth | 6848731 | 2014-11-25 12:14:20 -0800 | [diff] [blame] | 23 | |
| 24 | class CommandBufferDriverClientImpl : public CommandBufferDriver::Client { |
| 25 | public: |
| 26 | CommandBufferDriverClientImpl( |
| 27 | base::WeakPtr<CommandBufferImpl> command_buffer, |
| 28 | scoped_refptr<base::SingleThreadTaskRunner> control_task_runner) |
| 29 | : command_buffer_(command_buffer), |
| 30 | control_task_runner_(control_task_runner) {} |
| 31 | |
| 32 | private: |
Adam Barth | 6848731 | 2014-11-25 12:14:20 -0800 | [diff] [blame] | 33 | void UpdateVSyncParameters(base::TimeTicks timebase, |
| 34 | base::TimeDelta interval) override { |
| 35 | control_task_runner_->PostTask( |
| 36 | FROM_HERE, base::Bind(&CommandBufferImpl::UpdateVSyncParameters, |
| 37 | command_buffer_, timebase, interval)); |
| 38 | } |
| 39 | |
James Robinson | fb32716 | 2015-01-30 13:12:13 -0800 | [diff] [blame] | 40 | void DidLoseContext() override { |
Etienne Membrives | 6d38eec | 2015-06-04 11:48:59 +0200 | [diff] [blame] | 41 | command_buffer_->DidLoseContext(); |
Adam Barth | 6848731 | 2014-11-25 12:14:20 -0800 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | base::WeakPtr<CommandBufferImpl> command_buffer_; |
| 45 | scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_; |
| 46 | }; |
Vardhan Mudunuru | c3575c4 | 2016-02-11 15:08:21 -0800 | [diff] [blame] | 47 | } // namespace |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 48 | |
| 49 | CommandBufferImpl::CommandBufferImpl( |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 50 | mojo::InterfaceRequest<mojo::CommandBuffer> request, |
| 51 | mojo::ViewportParameterListenerPtr listener, |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 52 | scoped_refptr<base::SingleThreadTaskRunner> control_task_runner, |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 53 | gpu::SyncPointManager* sync_point_manager, |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 54 | scoped_ptr<CommandBufferDriver> driver) |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 55 | : sync_point_manager_(sync_point_manager), |
Etienne Membrives | 6d38eec | 2015-06-04 11:48:59 +0200 | [diff] [blame] | 56 | control_task_runner_(control_task_runner), |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 57 | driver_task_runner_(base::MessageLoop::current()->task_runner()), |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 58 | driver_(driver.Pass()), |
Adam Barth | 6848731 | 2014-11-25 12:14:20 -0800 | [diff] [blame] | 59 | viewport_parameter_listener_(listener.Pass()), |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 60 | binding_(this), |
Colin Blundell | a3b4ddb | 2015-05-11 17:26:34 +0200 | [diff] [blame] | 61 | observer_(nullptr), |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 62 | weak_factory_(this) { |
James Robinson | fb32716 | 2015-01-30 13:12:13 -0800 | [diff] [blame] | 63 | driver_->set_client(make_scoped_ptr(new CommandBufferDriverClientImpl( |
| 64 | weak_factory_.GetWeakPtr(), control_task_runner))); |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 65 | |
Etienne Membrives | 6d38eec | 2015-06-04 11:48:59 +0200 | [diff] [blame] | 66 | control_task_runner_->PostTask( |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 67 | FROM_HERE, base::Bind(&CommandBufferImpl::BindToRequest, |
| 68 | base::Unretained(this), base::Passed(&request))); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 69 | } |
| 70 | |
| 71 | CommandBufferImpl::~CommandBufferImpl() { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 72 | driver_task_runner_->PostTask( |
| 73 | FROM_HERE, base::Bind(&DestroyDriver, base::Passed(&driver_))); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 74 | } |
| 75 | |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 76 | void CommandBufferImpl::Initialize( |
Vardhan Mudunuru | c3575c4 | 2016-02-11 15:08:21 -0800 | [diff] [blame] | 77 | mojo::InterfaceHandle<mojo::CommandBufferSyncClient> sync_client, |
| 78 | mojo::InterfaceHandle<mojo::CommandBufferSyncPointClient> sync_point_client, |
| 79 | mojo::InterfaceHandle<mojo::CommandBufferLostContextObserver> loss_observer, |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 80 | mojo::ScopedSharedBufferHandle shared_state) { |
Vardhan Mudunuru | c3575c4 | 2016-02-11 15:08:21 -0800 | [diff] [blame] | 81 | sync_point_client_ = mojo::CommandBufferSyncPointClientPtr::Create( |
| 82 | std::move(sync_point_client)); |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 83 | driver_task_runner_->PostTask( |
| 84 | FROM_HERE, |
| 85 | base::Bind(&CommandBufferDriver::Initialize, |
| 86 | base::Unretained(driver_.get()), base::Passed(&sync_client), |
James Robinson | fb32716 | 2015-01-30 13:12:13 -0800 | [diff] [blame] | 87 | base::Passed(&loss_observer), |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 88 | base::Passed(&shared_state))); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | void CommandBufferImpl::SetGetBuffer(int32_t buffer) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 92 | driver_task_runner_->PostTask( |
| 93 | FROM_HERE, base::Bind(&CommandBufferDriver::SetGetBuffer, |
| 94 | base::Unretained(driver_.get()), buffer)); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 95 | } |
| 96 | |
| 97 | void CommandBufferImpl::Flush(int32_t put_offset) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 98 | driver_task_runner_->PostTask( |
| 99 | FROM_HERE, base::Bind(&CommandBufferDriver::Flush, |
| 100 | base::Unretained(driver_.get()), put_offset)); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | void CommandBufferImpl::MakeProgress(int32_t last_get_offset) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 104 | driver_task_runner_->PostTask( |
| 105 | FROM_HERE, base::Bind(&CommandBufferDriver::MakeProgress, |
| 106 | base::Unretained(driver_.get()), last_get_offset)); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | void CommandBufferImpl::RegisterTransferBuffer( |
| 110 | int32_t id, |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 111 | mojo::ScopedSharedBufferHandle transfer_buffer, |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 112 | uint32_t size) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 113 | driver_task_runner_->PostTask( |
| 114 | FROM_HERE, base::Bind(&CommandBufferDriver::RegisterTransferBuffer, |
| 115 | base::Unretained(driver_.get()), id, |
| 116 | base::Passed(&transfer_buffer), size)); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | void CommandBufferImpl::DestroyTransferBuffer(int32_t id) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 120 | driver_task_runner_->PostTask( |
| 121 | FROM_HERE, base::Bind(&CommandBufferDriver::DestroyTransferBuffer, |
| 122 | base::Unretained(driver_.get()), id)); |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 123 | } |
| 124 | |
James Robinson | e24b024 | 2014-11-21 11:04:09 -0800 | [diff] [blame] | 125 | void CommandBufferImpl::InsertSyncPoint(bool retire) { |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 126 | uint32_t sync_point = sync_point_manager_->GenerateSyncPoint(); |
| 127 | sync_point_client_->DidInsertSyncPoint(sync_point); |
James Robinson | e24b024 | 2014-11-21 11:04:09 -0800 | [diff] [blame] | 128 | if (retire) { |
| 129 | driver_task_runner_->PostTask( |
cdotstout | 6353225 | 2015-09-17 23:02:57 -0700 | [diff] [blame] | 130 | FROM_HERE, base::Bind(&CommandBufferDriver::RetireSyncPointOnGpuThread, |
| 131 | base::Unretained(driver_.get()), sync_point)); |
James Robinson | e24b024 | 2014-11-21 11:04:09 -0800 | [diff] [blame] | 132 | } |
| 133 | } |
| 134 | |
| 135 | void CommandBufferImpl::RetireSyncPoint(uint32_t sync_point) { |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 136 | driver_task_runner_->PostTask( |
cdotstout | 6353225 | 2015-09-17 23:02:57 -0700 | [diff] [blame] | 137 | FROM_HERE, base::Bind(&CommandBufferDriver::RetireSyncPointOnGpuThread, |
| 138 | base::Unretained(driver_.get()), sync_point)); |
Adam Barth | b087f9a | 2014-11-20 12:26:29 -0800 | [diff] [blame] | 139 | } |
| 140 | |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 141 | void CommandBufferImpl::Echo(const mojo::Callback<void()>& callback) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 142 | driver_task_runner_->PostTaskAndReply(FROM_HERE, base::Bind(&base::DoNothing), |
| 143 | base::Bind(&RunCallback, callback)); |
| 144 | } |
| 145 | |
Viet-Trung Luu | 017c7ac | 2015-07-08 12:46:25 -0700 | [diff] [blame] | 146 | void CommandBufferImpl::DidLoseContext() { |
| 147 | NotifyAndDestroy(); |
| 148 | } |
| 149 | |
| 150 | void CommandBufferImpl::UpdateVSyncParameters(base::TimeTicks timebase, |
| 151 | base::TimeDelta interval) { |
| 152 | if (!viewport_parameter_listener_) |
| 153 | return; |
| 154 | viewport_parameter_listener_->OnVSyncParametersUpdated( |
| 155 | timebase.ToInternalValue(), interval.ToInternalValue()); |
| 156 | } |
| 157 | |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 158 | void CommandBufferImpl::BindToRequest( |
| 159 | mojo::InterfaceRequest<mojo::CommandBuffer> request) { |
Adam Barth | 1658f11 | 2014-11-19 20:09:14 -0800 | [diff] [blame] | 160 | binding_.Bind(request.Pass()); |
Viet-Trung Luu | 017c7ac | 2015-07-08 12:46:25 -0700 | [diff] [blame] | 161 | binding_.set_connection_error_handler([this]() { OnConnectionError(); }); |
Etienne Membrives | 6d38eec | 2015-06-04 11:48:59 +0200 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | void CommandBufferImpl::OnConnectionError() { |
| 165 | // Called from the control_task_runner thread as we bound to the message pipe |
| 166 | // handle on that thread. However, the observer have to be notified on the |
| 167 | // thread that created this object, so we post on driver_task_runner. |
| 168 | driver_task_runner_->PostTask( |
| 169 | FROM_HERE, |
| 170 | base::Bind(&CommandBufferImpl::NotifyAndDestroy, base::Unretained(this))); |
| 171 | } |
| 172 | |
| 173 | void CommandBufferImpl::NotifyAndDestroy() { |
| 174 | if (observer_) { |
| 175 | observer_->OnCommandBufferImplDestroyed(); |
| 176 | } |
| 177 | // We have notified the observer on the right thread. However, destruction of |
| 178 | // this object must happen on control_task_runner_ |
| 179 | control_task_runner_->PostTask( |
| 180 | FROM_HERE, |
| 181 | base::Bind(&CommandBufferImpl::Destroy, base::Unretained(this))); |
| 182 | } |
| 183 | |
| 184 | void CommandBufferImpl::Destroy() { |
| 185 | delete this; |
James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 186 | } |
| 187 | |
James Robinson | c3704cd | 2014-12-05 11:10:47 -0800 | [diff] [blame] | 188 | } // namespace gles2 |