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

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

Issue 2087333002: mus::GpuService: Support establish GpuChannel asynchronously. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix the unittests 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/demo/mus_demo.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/mus/common/gpu_service.h" 5 #include "components/mus/common/gpu_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/memory/singleton.h" 8 #include "base/memory/singleton.h"
9 #include "base/threading/thread_task_runner_handle.h" 9 #include "base/threading/thread_task_runner_handle.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
11 #include "components/mus/common/gpu_type_converters.h" 11 #include "components/mus/common/gpu_type_converters.h"
12 #include "components/mus/common/mojo_gpu_memory_buffer_manager.h"
13 #include "components/mus/common/switches.h" 12 #include "components/mus/common/switches.h"
14 #include "components/mus/public/interfaces/gpu_service.mojom.h" 13 #include "components/mus/public/interfaces/gpu_service.mojom.h"
15 #include "mojo/public/cpp/bindings/sync_call_restrictions.h" 14 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
16 #include "mojo/public/cpp/system/platform_handle.h" 15 #include "mojo/public/cpp/system/platform_handle.h"
17 #include "services/shell/public/cpp/connector.h" 16 #include "services/shell/public/cpp/connector.h"
18 17
19 namespace mus { 18 namespace mus {
20 19
21 GpuService::GpuService() 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)
22 : main_task_runner_(base::ThreadTaskRunnerHandle::Get()), 32 : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
33 connector_(connector),
23 shutdown_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, 34 shutdown_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
24 base::WaitableEvent::InitialState::NOT_SIGNALED), 35 base::WaitableEvent::InitialState::NOT_SIGNALED),
25 io_thread_("GPUIOThread"), 36 io_thread_("GPUIOThread"),
26 gpu_memory_buffer_manager_(new MojoGpuMemoryBufferManager) { 37 gpu_memory_buffer_manager_(new MojoGpuMemoryBufferManager),
38 is_establishing_(false),
39 establishing_condition_(&lock_) {
40 DCHECK(main_task_runner_);
41 DCHECK(connector_);
27 base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); 42 base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
28 thread_options.priority = base::ThreadPriority::NORMAL; 43 thread_options.priority = base::ThreadPriority::NORMAL;
29 CHECK(io_thread_.StartWithOptions(thread_options)); 44 CHECK(io_thread_.StartWithOptions(thread_options));
30 } 45 }
31 46
32 GpuService::~GpuService() {} 47 GpuService::~GpuService() {
48 DCHECK(IsMainThread());
49 if (gpu_channel_)
50 gpu_channel_->DestroyChannel();
51 }
33 52
34 // static 53 // static
35 bool GpuService::UseChromeGpuCommandBuffer() { 54 bool GpuService::UseChromeGpuCommandBuffer() {
36 // TODO(penghuang): Kludge: Running with Chrome GPU command buffer by default 55 // TODO(penghuang): Kludge: Running with Chrome GPU command buffer by default
37 // breaks unit tests on Windows 56 // breaks unit tests on Windows
38 #if defined(OS_WIN) 57 #if defined(OS_WIN)
39 return false; 58 return false;
40 #else 59 #else
41 return !base::CommandLine::ForCurrentProcess()->HasSwitch( 60 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
42 switches::kUseMojoGpuCommandBufferInMus); 61 switches::kUseMojoGpuCommandBufferInMus);
43 #endif 62 #endif
44 } 63 }
45 64
46 // static 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
47 GpuService* GpuService::GetInstance() { 79 GpuService* GpuService::GetInstance() {
48 return base::Singleton<GpuService, 80 DCHECK(g_gpu_service);
49 base::LeakySingletonTraits<GpuService>>::get(); 81 return g_gpu_service;
50 } 82 }
51 83
52 scoped_refptr<gpu::GpuChannelHost> GpuService::EstablishGpuChannel( 84 void GpuService::EstablishGpuChannel(const base::Closure& callback) {
53 shell::Connector* connector) {
54 base::AutoLock auto_lock(lock_); 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() {
55 if (gpu_channel_ && gpu_channel_->IsLost()) { 136 if (gpu_channel_ && gpu_channel_->IsLost()) {
56 gpu_channel_->DestroyChannel(); 137 main_task_runner_->PostTask(
138 FROM_HERE,
139 base::Bind(&gpu::GpuChannelHost::DestroyChannel, gpu_channel_));
57 gpu_channel_ = nullptr; 140 gpu_channel_ = nullptr;
58 } 141 }
142 return gpu_channel_;
143 }
59 144
60 if (gpu_channel_) 145 void GpuService::EstablishGpuChannelOnMainThread() {
61 return gpu_channel_; 146 base::AutoLock auto_lock(lock_);
147 DCHECK(IsMainThread());
62 148
63 mus::mojom::GpuServicePtr gpu_service; 149 // In GpuService::EstablishGpuChannelOnMainThreadSyncLocked(), we use the sync
64 connector->ConnectToInterface("mojo:mus", &gpu_service); 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_);
65 178
66 int client_id = 0; 179 int client_id = 0;
67 mojom::ChannelHandlePtr channel_handle; 180 mojom::ChannelHandlePtr channel_handle;
68 mojom::GpuInfoPtr gpu_info; 181 mojom::GpuInfoPtr gpu_info;
182 connector_->ConnectToInterface("mojo:mus", &gpu_service_);
69 { 183 {
70 // TODO(penghuang): Remove the ScopedAllowSyncCall when HW rendering is 184 base::AutoUnlock auto_unlock(lock_);
71 // enabled in mus chrome.
72 mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; 185 mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call;
73 if (!gpu_service->EstablishGpuChannel(&client_id, &channel_handle, 186 if (!gpu_service_->EstablishGpuChannel(&client_id, &channel_handle,
74 &gpu_info)) { 187 &gpu_info)) {
75 DLOG(WARNING) 188 DLOG(WARNING)
76 << "Channel encountered error while establishing gpu channel."; 189 << "Channel encountered error while establishing gpu channel.";
77 return nullptr; 190 return;
78 } 191 }
79 } 192 }
193 const bool locked = true;
194 EstablishGpuChannelOnMainThreadDone(
195 locked, client_id, std::move(channel_handle), std::move(gpu_info));
196 }
80 197
81 // TODO(penghuang): Get the real gpu info from mus. 198 void GpuService::EstablishGpuChannelOnMainThreadDone(
82 gpu_channel_ = gpu::GpuChannelHost::Create( 199 bool locked,
83 this, client_id, gpu::GPUInfo(), channel_handle.To<IPC::ChannelHandle>(), 200 int client_id,
84 &shutdown_event_, gpu_memory_buffer_manager_.get()); 201 mojom::ChannelHandlePtr channel_handle,
85 return gpu_channel_; 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();
86 } 226 }
87 227
88 bool GpuService::IsMainThread() { 228 bool GpuService::IsMainThread() {
89 return main_task_runner_->BelongsToCurrentThread(); 229 return main_task_runner_->BelongsToCurrentThread();
90 } 230 }
91 231
92 scoped_refptr<base::SingleThreadTaskRunner> 232 scoped_refptr<base::SingleThreadTaskRunner>
93 GpuService::GetIOThreadTaskRunner() { 233 GpuService::GetIOThreadTaskRunner() {
94 return io_thread_.task_runner(); 234 return io_thread_.task_runner();
95 } 235 }
(...skipping 11 matching lines...) Expand all
107 MojoResult result = mojo::UnwrapSharedMemoryHandle( 247 MojoResult result = mojo::UnwrapSharedMemoryHandle(
108 std::move(handle), &platform_handle, &shared_memory_size, &readonly); 248 std::move(handle), &platform_handle, &shared_memory_size, &readonly);
109 if (result != MOJO_RESULT_OK) 249 if (result != MOJO_RESULT_OK)
110 return nullptr; 250 return nullptr;
111 DCHECK_EQ(shared_memory_size, size); 251 DCHECK_EQ(shared_memory_size, size);
112 252
113 return base::MakeUnique<base::SharedMemory>(platform_handle, readonly); 253 return base::MakeUnique<base::SharedMemory>(platform_handle, readonly);
114 } 254 }
115 255
116 } // namespace mus 256 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/common/gpu_service.h ('k') | components/mus/demo/mus_demo.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698