blob: db1f677388375a2fe500fe3cd917fdb88d9ce5e4 [file] [log] [blame]
Adam Barth116f6fe2014-11-18 09:30:34 -08001// Copyright 2014 The Chromium Authors. All rights reserved.
James Robinson646469d2014-10-03 15:33:28 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
James Robinsonc9b163e2014-12-03 13:31:32 -08005#include "services/gles2/command_buffer_impl.h"
James Robinson646469d2014-10-03 15:33:28 -07006
Vardhan Mudunuruc3575c42016-02-11 15:08:21 -08007#include <utility>
8
Adam Barthb087f9a2014-11-20 12:26:29 -08009#include "base/bind.h"
Adam Barth1658f112014-11-19 20:09:14 -080010#include "base/message_loop/message_loop.h"
Adam Barthb087f9a2014-11-20 12:26:29 -080011#include "gpu/command_buffer/service/sync_point_manager.h"
James Robinsonc9b163e2014-12-03 13:31:32 -080012#include "services/gles2/command_buffer_driver.h"
James Robinson646469d2014-10-03 15:33:28 -070013
James Robinsonc3704cd2014-12-05 11:10:47 -080014namespace gles2 {
Adam Barth1658f112014-11-19 20:09:14 -080015namespace {
16void DestroyDriver(scoped_ptr<CommandBufferDriver> driver) {
17 // Just let ~scoped_ptr run.
18}
James Robinson646469d2014-10-03 15:33:28 -070019
James Robinsonc3704cd2014-12-05 11:10:47 -080020void RunCallback(const mojo::Callback<void()>& callback) {
Adam Barth1658f112014-11-19 20:09:14 -080021 callback.Run();
22}
Adam Barth68487312014-11-25 12:14:20 -080023
24class 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 Barth68487312014-11-25 12:14:20 -080033 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 Robinsonfb327162015-01-30 13:12:13 -080040 void DidLoseContext() override {
Etienne Membrives6d38eec2015-06-04 11:48:59 +020041 command_buffer_->DidLoseContext();
Adam Barth68487312014-11-25 12:14:20 -080042 }
43
44 base::WeakPtr<CommandBufferImpl> command_buffer_;
45 scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_;
46};
Vardhan Mudunuruc3575c42016-02-11 15:08:21 -080047} // namespace
Adam Barth1658f112014-11-19 20:09:14 -080048
49CommandBufferImpl::CommandBufferImpl(
James Robinsonc3704cd2014-12-05 11:10:47 -080050 mojo::InterfaceRequest<mojo::CommandBuffer> request,
51 mojo::ViewportParameterListenerPtr listener,
Adam Barth1658f112014-11-19 20:09:14 -080052 scoped_refptr<base::SingleThreadTaskRunner> control_task_runner,
Adam Barthb087f9a2014-11-20 12:26:29 -080053 gpu::SyncPointManager* sync_point_manager,
Adam Barth1658f112014-11-19 20:09:14 -080054 scoped_ptr<CommandBufferDriver> driver)
Adam Barthb087f9a2014-11-20 12:26:29 -080055 : sync_point_manager_(sync_point_manager),
Etienne Membrives6d38eec2015-06-04 11:48:59 +020056 control_task_runner_(control_task_runner),
Adam Barthb087f9a2014-11-20 12:26:29 -080057 driver_task_runner_(base::MessageLoop::current()->task_runner()),
Adam Barth1658f112014-11-19 20:09:14 -080058 driver_(driver.Pass()),
Adam Barth68487312014-11-25 12:14:20 -080059 viewport_parameter_listener_(listener.Pass()),
Adam Barth1658f112014-11-19 20:09:14 -080060 binding_(this),
Colin Blundella3b4ddb2015-05-11 17:26:34 +020061 observer_(nullptr),
Adam Barth1658f112014-11-19 20:09:14 -080062 weak_factory_(this) {
James Robinsonfb327162015-01-30 13:12:13 -080063 driver_->set_client(make_scoped_ptr(new CommandBufferDriverClientImpl(
64 weak_factory_.GetWeakPtr(), control_task_runner)));
Adam Barth1658f112014-11-19 20:09:14 -080065
Etienne Membrives6d38eec2015-06-04 11:48:59 +020066 control_task_runner_->PostTask(
Adam Barth1658f112014-11-19 20:09:14 -080067 FROM_HERE, base::Bind(&CommandBufferImpl::BindToRequest,
68 base::Unretained(this), base::Passed(&request)));
James Robinson646469d2014-10-03 15:33:28 -070069}
70
71CommandBufferImpl::~CommandBufferImpl() {
Adam Barth1658f112014-11-19 20:09:14 -080072 driver_task_runner_->PostTask(
73 FROM_HERE, base::Bind(&DestroyDriver, base::Passed(&driver_)));
James Robinson646469d2014-10-03 15:33:28 -070074}
75
Adam Barthb087f9a2014-11-20 12:26:29 -080076void CommandBufferImpl::Initialize(
Vardhan Mudunuruc3575c42016-02-11 15:08:21 -080077 mojo::InterfaceHandle<mojo::CommandBufferSyncClient> sync_client,
78 mojo::InterfaceHandle<mojo::CommandBufferSyncPointClient> sync_point_client,
79 mojo::InterfaceHandle<mojo::CommandBufferLostContextObserver> loss_observer,
James Robinsonc3704cd2014-12-05 11:10:47 -080080 mojo::ScopedSharedBufferHandle shared_state) {
Vardhan Mudunuruc3575c42016-02-11 15:08:21 -080081 sync_point_client_ = mojo::CommandBufferSyncPointClientPtr::Create(
82 std::move(sync_point_client));
Adam Barth1658f112014-11-19 20:09:14 -080083 driver_task_runner_->PostTask(
84 FROM_HERE,
85 base::Bind(&CommandBufferDriver::Initialize,
86 base::Unretained(driver_.get()), base::Passed(&sync_client),
James Robinsonfb327162015-01-30 13:12:13 -080087 base::Passed(&loss_observer),
Adam Barth1658f112014-11-19 20:09:14 -080088 base::Passed(&shared_state)));
James Robinson646469d2014-10-03 15:33:28 -070089}
90
91void CommandBufferImpl::SetGetBuffer(int32_t buffer) {
Adam Barth1658f112014-11-19 20:09:14 -080092 driver_task_runner_->PostTask(
93 FROM_HERE, base::Bind(&CommandBufferDriver::SetGetBuffer,
94 base::Unretained(driver_.get()), buffer));
James Robinson646469d2014-10-03 15:33:28 -070095}
96
97void CommandBufferImpl::Flush(int32_t put_offset) {
Adam Barth1658f112014-11-19 20:09:14 -080098 driver_task_runner_->PostTask(
99 FROM_HERE, base::Bind(&CommandBufferDriver::Flush,
100 base::Unretained(driver_.get()), put_offset));
James Robinson646469d2014-10-03 15:33:28 -0700101}
102
103void CommandBufferImpl::MakeProgress(int32_t last_get_offset) {
Adam Barth1658f112014-11-19 20:09:14 -0800104 driver_task_runner_->PostTask(
105 FROM_HERE, base::Bind(&CommandBufferDriver::MakeProgress,
106 base::Unretained(driver_.get()), last_get_offset));
James Robinson646469d2014-10-03 15:33:28 -0700107}
108
109void CommandBufferImpl::RegisterTransferBuffer(
110 int32_t id,
James Robinsonc3704cd2014-12-05 11:10:47 -0800111 mojo::ScopedSharedBufferHandle transfer_buffer,
James Robinson646469d2014-10-03 15:33:28 -0700112 uint32_t size) {
Adam Barth1658f112014-11-19 20:09:14 -0800113 driver_task_runner_->PostTask(
114 FROM_HERE, base::Bind(&CommandBufferDriver::RegisterTransferBuffer,
115 base::Unretained(driver_.get()), id,
116 base::Passed(&transfer_buffer), size));
James Robinson646469d2014-10-03 15:33:28 -0700117}
118
119void CommandBufferImpl::DestroyTransferBuffer(int32_t id) {
Adam Barth1658f112014-11-19 20:09:14 -0800120 driver_task_runner_->PostTask(
121 FROM_HERE, base::Bind(&CommandBufferDriver::DestroyTransferBuffer,
122 base::Unretained(driver_.get()), id));
James Robinson646469d2014-10-03 15:33:28 -0700123}
124
James Robinsone24b0242014-11-21 11:04:09 -0800125void CommandBufferImpl::InsertSyncPoint(bool retire) {
Adam Barthb087f9a2014-11-20 12:26:29 -0800126 uint32_t sync_point = sync_point_manager_->GenerateSyncPoint();
127 sync_point_client_->DidInsertSyncPoint(sync_point);
James Robinsone24b0242014-11-21 11:04:09 -0800128 if (retire) {
129 driver_task_runner_->PostTask(
cdotstout63532252015-09-17 23:02:57 -0700130 FROM_HERE, base::Bind(&CommandBufferDriver::RetireSyncPointOnGpuThread,
131 base::Unretained(driver_.get()), sync_point));
James Robinsone24b0242014-11-21 11:04:09 -0800132 }
133}
134
135void CommandBufferImpl::RetireSyncPoint(uint32_t sync_point) {
Adam Barthb087f9a2014-11-20 12:26:29 -0800136 driver_task_runner_->PostTask(
cdotstout63532252015-09-17 23:02:57 -0700137 FROM_HERE, base::Bind(&CommandBufferDriver::RetireSyncPointOnGpuThread,
138 base::Unretained(driver_.get()), sync_point));
Adam Barthb087f9a2014-11-20 12:26:29 -0800139}
140
James Robinsonc3704cd2014-12-05 11:10:47 -0800141void CommandBufferImpl::Echo(const mojo::Callback<void()>& callback) {
Adam Barth1658f112014-11-19 20:09:14 -0800142 driver_task_runner_->PostTaskAndReply(FROM_HERE, base::Bind(&base::DoNothing),
143 base::Bind(&RunCallback, callback));
144}
145
Viet-Trung Luu017c7ac2015-07-08 12:46:25 -0700146void CommandBufferImpl::DidLoseContext() {
147 NotifyAndDestroy();
148}
149
150void 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 Robinsonc3704cd2014-12-05 11:10:47 -0800158void CommandBufferImpl::BindToRequest(
159 mojo::InterfaceRequest<mojo::CommandBuffer> request) {
Adam Barth1658f112014-11-19 20:09:14 -0800160 binding_.Bind(request.Pass());
Viet-Trung Luu017c7ac2015-07-08 12:46:25 -0700161 binding_.set_connection_error_handler([this]() { OnConnectionError(); });
Etienne Membrives6d38eec2015-06-04 11:48:59 +0200162}
163
164void 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
173void 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
184void CommandBufferImpl::Destroy() {
185 delete this;
James Robinson646469d2014-10-03 15:33:28 -0700186}
187
James Robinsonc3704cd2014-12-05 11:10:47 -0800188} // namespace gles2