Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: components/mus/common/gpu_service.cc

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/mus/common/gpu_service.h ('k') | components/mus/common/gpu_type_converters.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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/common/gpu_service.h"
6
7 #include "base/command_line.h"
8 #include "base/memory/singleton.h"
9 #include "base/threading/thread_task_runner_handle.h"
10 #include "build/build_config.h"
11 #include "components/mus/common/gpu_type_converters.h"
12 #include "components/mus/common/switches.h"
13 #include "components/mus/public/interfaces/gpu_service.mojom.h"
14 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
15 #include "mojo/public/cpp/system/platform_handle.h"
16 #include "services/shell/public/cpp/connector.h"
17
18 namespace mus {
19
20 namespace {
21
22 void PostTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
23 const tracked_objects::Location& from_here,
24 const base::Closure& callback) {
25 runner->PostTask(from_here, callback);
26 }
27
28 GpuService* g_gpu_service = nullptr;
29 }
30
31 GpuService::GpuService(shell::Connector* connector)
32 : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
33 connector_(connector),
34 shutdown_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
35 base::WaitableEvent::InitialState::NOT_SIGNALED),
36 io_thread_("GPUIOThread"),
37 gpu_memory_buffer_manager_(new MojoGpuMemoryBufferManager),
38 is_establishing_(false),
39 establishing_condition_(&lock_) {
40 DCHECK(main_task_runner_);
41 DCHECK(connector_);
42 base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
43 thread_options.priority = base::ThreadPriority::NORMAL;
44 CHECK(io_thread_.StartWithOptions(thread_options));
45 }
46
47 GpuService::~GpuService() {
48 DCHECK(IsMainThread());
49 if (gpu_channel_)
50 gpu_channel_->DestroyChannel();
51 }
52
53 // static
54 bool GpuService::UseChromeGpuCommandBuffer() {
55 // TODO(penghuang): Kludge: Running with Chrome GPU command buffer by default
56 // breaks unit tests on Windows
57 #if defined(OS_WIN)
58 return false;
59 #else
60 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
61 switches::kUseMojoGpuCommandBufferInMus);
62 #endif
63 }
64
65 // static
66 void GpuService::Initialize(shell::Connector* connector) {
67 DCHECK(!g_gpu_service);
68 g_gpu_service = new GpuService(connector);
69 }
70
71 // static
72 void GpuService::Terminate() {
73 DCHECK(g_gpu_service);
74 delete g_gpu_service;
75 g_gpu_service = nullptr;
76 }
77
78 // static
79 GpuService* GpuService::GetInstance() {
80 DCHECK(g_gpu_service);
81 return g_gpu_service;
82 }
83
84 void GpuService::EstablishGpuChannel(const base::Closure& callback) {
85 base::AutoLock auto_lock(lock_);
86 auto runner = base::ThreadTaskRunnerHandle::Get();
87 if (GetGpuChannelLocked()) {
88 runner->PostTask(FROM_HERE, callback);
89 return;
90 }
91
92 base::Closure wrapper_callback =
93 IsMainThread() ? callback
94 : base::Bind(PostTask, runner, FROM_HERE, callback);
95 establish_callbacks_.push_back(wrapper_callback);
96
97 if (!is_establishing_) {
98 is_establishing_ = true;
99 main_task_runner_->PostTask(
100 FROM_HERE, base::Bind(&GpuService::EstablishGpuChannelOnMainThread,
101 base::Unretained(this)));
102 }
103 }
104
105 scoped_refptr<gpu::GpuChannelHost> GpuService::EstablishGpuChannelSync() {
106 base::AutoLock auto_lock(lock_);
107 if (GetGpuChannelLocked())
108 return gpu_channel_;
109
110 if (IsMainThread()) {
111 is_establishing_ = true;
112 EstablishGpuChannelOnMainThreadSyncLocked();
113 } else {
114 if (!is_establishing_) {
115 // Create an establishing gpu channel task, if there isn't one.
116 is_establishing_ = true;
117 main_task_runner_->PostTask(
118 FROM_HERE, base::Bind(&GpuService::EstablishGpuChannelOnMainThread,
119 base::Unretained(this)));
120 }
121
122 // Wait until the pending establishing task is finished.
123 do {
124 establishing_condition_.Wait();
125 } while (is_establishing_);
126 }
127 return gpu_channel_;
128 }
129
130 scoped_refptr<gpu::GpuChannelHost> GpuService::GetGpuChannel() {
131 base::AutoLock auto_lock(lock_);
132 return GetGpuChannelLocked();
133 }
134
135 scoped_refptr<gpu::GpuChannelHost> GpuService::GetGpuChannelLocked() {
136 if (gpu_channel_ && gpu_channel_->IsLost()) {
137 main_task_runner_->PostTask(
138 FROM_HERE,
139 base::Bind(&gpu::GpuChannelHost::DestroyChannel, gpu_channel_));
140 gpu_channel_ = nullptr;
141 }
142 return gpu_channel_;
143 }
144
145 void GpuService::EstablishGpuChannelOnMainThread() {
146 base::AutoLock auto_lock(lock_);
147 DCHECK(IsMainThread());
148
149 // In GpuService::EstablishGpuChannelOnMainThreadSyncLocked(), we use the sync
150 // mojo EstablishGpuChannel call, after that call the gpu_service_ will be
151 // reset immediatelly. So gpu_service_ should be always null here.
152 DCHECK(!gpu_service_);
153
154 // is_establishing_ is false, it means GpuService::EstablishGpuChannelSync()
155 // has been used, and we don't need try to establish a new GPU channel
156 // anymore.
157 if (!is_establishing_)
158 return;
159
160 connector_->ConnectToInterface("mojo:mus", &gpu_service_);
161 const bool locked = false;
162 gpu_service_->EstablishGpuChannel(
163 base::Bind(&GpuService::EstablishGpuChannelOnMainThreadDone,
164 base::Unretained(this), locked));
165 }
166
167 void GpuService::EstablishGpuChannelOnMainThreadSyncLocked() {
168 DCHECK(IsMainThread());
169 DCHECK(is_establishing_);
170
171 // In browser process, EstablishGpuChannelSync() is only used by testing &
172 // GpuProcessTransportFactory::GetGLHelper(). For GetGLHelper(), it expects
173 // the gpu channel has been established, so it should not reach here.
174 // For testing, the asyc method should not be used.
175 // In renderer process, we only use EstablishGpuChannelSync().
176 // So the gpu_service_ should be null here.
177 DCHECK(!gpu_service_);
178
179 int client_id = 0;
180 mojom::ChannelHandlePtr channel_handle;
181 mojom::GpuInfoPtr gpu_info;
182 connector_->ConnectToInterface("mojo:mus", &gpu_service_);
183 {
184 base::AutoUnlock auto_unlock(lock_);
185 mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
186 if (!gpu_service_->EstablishGpuChannel(&client_id, &channel_handle,
187 &gpu_info)) {
188 DLOG(WARNING)
189 << "Channel encountered error while establishing gpu channel.";
190 return;
191 }
192 }
193 const bool locked = true;
194 EstablishGpuChannelOnMainThreadDone(
195 locked, client_id, std::move(channel_handle), std::move(gpu_info));
196 }
197
198 void GpuService::EstablishGpuChannelOnMainThreadDone(
199 bool locked,
200 int client_id,
201 mojom::ChannelHandlePtr channel_handle,
202 mojom::GpuInfoPtr gpu_info) {
203 DCHECK(IsMainThread());
204 scoped_refptr<gpu::GpuChannelHost> gpu_channel;
205 if (client_id) {
206 // TODO(penghuang): Get the real gpu info from mus.
207 gpu_channel = gpu::GpuChannelHost::Create(
208 this, client_id, gpu::GPUInfo(),
209 channel_handle.To<IPC::ChannelHandle>(), &shutdown_event_,
210 gpu_memory_buffer_manager_.get());
211 }
212
213 auto auto_lock = base::WrapUnique<base::AutoLock>(
214 locked ? nullptr : new base::AutoLock(lock_));
215 DCHECK(is_establishing_);
216 DCHECK(!gpu_channel_);
217
218 is_establishing_ = false;
219 gpu_channel_ = gpu_channel;
220 establishing_condition_.Broadcast();
221
222 for (const auto& i : establish_callbacks_)
223 i.Run();
224 establish_callbacks_.clear();
225 gpu_service_.reset();
226 }
227
228 bool GpuService::IsMainThread() {
229 return main_task_runner_->BelongsToCurrentThread();
230 }
231
232 scoped_refptr<base::SingleThreadTaskRunner>
233 GpuService::GetIOThreadTaskRunner() {
234 return io_thread_.task_runner();
235 }
236
237 std::unique_ptr<base::SharedMemory> GpuService::AllocateSharedMemory(
238 size_t size) {
239 mojo::ScopedSharedBufferHandle handle =
240 mojo::SharedBufferHandle::Create(size);
241 if (!handle.is_valid())
242 return nullptr;
243
244 base::SharedMemoryHandle platform_handle;
245 size_t shared_memory_size;
246 bool readonly;
247 MojoResult result = mojo::UnwrapSharedMemoryHandle(
248 std::move(handle), &platform_handle, &shared_memory_size, &readonly);
249 if (result != MOJO_RESULT_OK)
250 return nullptr;
251 DCHECK_EQ(shared_memory_size, size);
252
253 return base::MakeUnique<base::SharedMemory>(platform_handle, readonly);
254 }
255
256 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/common/gpu_service.h ('k') | components/mus/common/gpu_type_converters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698