OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "media/gpu/ipc/service/gpu_jpeg_decode_accelerator.h" | 5 #include "media/gpu/ipc/service/gpu_jpeg_decode_accelerator.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/containers/hash_tables.h" | 13 #include "base/containers/hash_tables.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/ptr_util.h" | |
15 #include "base/memory/shared_memory.h" | 16 #include "base/memory/shared_memory.h" |
16 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
17 #include "base/stl_util.h" | |
18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
19 #include "base/trace_event/trace_event.h" | 19 #include "base/trace_event/trace_event.h" |
20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
21 #include "gpu/ipc/service/gpu_channel.h" | 21 #include "gpu/ipc/service/gpu_channel.h" |
22 #include "ipc/ipc_message_macros.h" | 22 #include "ipc/ipc_message_macros.h" |
23 #include "ipc/message_filter.h" | 23 #include "ipc/message_filter.h" |
24 #include "media/filters/jpeg_parser.h" | 24 #include "media/filters/jpeg_parser.h" |
25 #include "media/gpu/ipc/common/media_messages.h" | 25 #include "media/gpu/ipc/common/media_messages.h" |
26 #include "ui/gfx/geometry/size.h" | 26 #include "ui/gfx/geometry/size.h" |
27 | 27 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 } | 151 } |
152 return sender_->Send(message); | 152 return sender_->Send(message); |
153 } | 153 } |
154 | 154 |
155 void AddClientOnIOThread(int32_t route_id, | 155 void AddClientOnIOThread(int32_t route_id, |
156 Client* client, | 156 Client* client, |
157 base::Callback<void(bool)> response) { | 157 base::Callback<void(bool)> response) { |
158 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 158 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
159 DCHECK(client_map_.count(route_id) == 0); | 159 DCHECK(client_map_.count(route_id) == 0); |
160 | 160 |
161 client_map_[route_id] = client; | 161 // See the comment on GpuJpegDecodeAccelerator::AddClient. |
162 client_map_[route_id] = base::WrapUnique(client); | |
162 response.Run(true); | 163 response.Run(true); |
163 } | 164 } |
164 | 165 |
165 void OnDestroyOnIOThread(const int32_t* route_id) { | 166 void OnDestroyOnIOThread(const int32_t* route_id) { |
166 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 167 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
167 const auto& it = client_map_.find(*route_id); | 168 const auto& it = client_map_.find(*route_id); |
168 DCHECK(it != client_map_.end()); | 169 DCHECK(it != client_map_.end()); |
169 Client* client = it->second; | 170 std::unique_ptr<Client> client = std::move(it->second); |
170 DCHECK(client); | 171 DCHECK(client); |
171 client_map_.erase(it); | 172 client_map_.erase(it); |
172 | 173 |
173 child_task_runner_->PostTask( | 174 child_task_runner_->PostTask( |
174 FROM_HERE, base::Bind(&MessageFilter::DestroyClient, this, client)); | 175 FROM_HERE, |
176 base::Bind(&MessageFilter::DestroyClient, this, base::Passed(&client))); | |
175 } | 177 } |
176 | 178 |
177 void DestroyClient(Client* client) { | 179 void DestroyClient(std::unique_ptr<Client> client) { |
178 DCHECK(child_task_runner_->BelongsToCurrentThread()); | 180 DCHECK(child_task_runner_->BelongsToCurrentThread()); |
179 delete client; | |
180 if (owner_) | 181 if (owner_) |
wolenetz
2016/09/27 22:01:12
nit: include a comment here like on l.273, too?
Avi (use Gerrit)
2016/09/28 15:41:46
Done.
| |
181 owner_->ClientRemoved(); | 182 owner_->ClientRemoved(); |
182 } | 183 } |
183 | 184 |
184 void NotifyDecodeStatusOnIOThread(int32_t route_id, | 185 void NotifyDecodeStatusOnIOThread(int32_t route_id, |
185 int32_t buffer_id, | 186 int32_t buffer_id, |
186 JpegDecodeAccelerator::Error error) { | 187 JpegDecodeAccelerator::Error error) { |
187 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 188 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
188 SendOnIOThread(new AcceleratedJpegDecoderHostMsg_DecodeAck( | 189 SendOnIOThread(new AcceleratedJpegDecoderHostMsg_DecodeAck( |
189 route_id, buffer_id, error)); | 190 route_id, buffer_id, error)); |
190 } | 191 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 << params.input_buffer.id(); | 235 << params.input_buffer.id(); |
235 NotifyDecodeStatusOnIOThread(*route_id, params.input_buffer.id(), | 236 NotifyDecodeStatusOnIOThread(*route_id, params.input_buffer.id(), |
236 JpegDecodeAccelerator::PLATFORM_FAILURE); | 237 JpegDecodeAccelerator::PLATFORM_FAILURE); |
237 base::SharedMemory::CloseHandle(params.input_buffer.handle()); | 238 base::SharedMemory::CloseHandle(params.input_buffer.handle()); |
238 return; | 239 return; |
239 } | 240 } |
240 frame->AddDestructionObserver( | 241 frame->AddDestructionObserver( |
241 base::Bind(DecodeFinished, base::Passed(&output_shm))); | 242 base::Bind(DecodeFinished, base::Passed(&output_shm))); |
242 | 243 |
243 DCHECK_GT(client_map_.count(*route_id), 0u); | 244 DCHECK_GT(client_map_.count(*route_id), 0u); |
244 Client* client = client_map_[*route_id]; | 245 Client* client = client_map_[*route_id].get(); |
245 client->Decode(params.input_buffer, frame); | 246 client->Decode(params.input_buffer, frame); |
246 } | 247 } |
247 | 248 |
248 protected: | 249 protected: |
249 ~MessageFilter() override { | 250 ~MessageFilter() override { |
250 if (client_map_.empty()) | 251 if (client_map_.empty()) |
251 return; | 252 return; |
252 | 253 |
253 if (child_task_runner_->BelongsToCurrentThread()) { | 254 if (child_task_runner_->BelongsToCurrentThread()) { |
254 base::STLDeleteValues(&client_map_); | 255 client_map_.clear(); |
255 } else { | 256 } else { |
256 // Make sure |Client| are deleted on child thread. | 257 // Make sure |Client| are deleted on child thread. |
257 std::unique_ptr<ClientMap> client_map(new ClientMap); | 258 std::unique_ptr<ClientMap> client_map(new ClientMap); |
258 client_map->swap(client_map_); | 259 client_map->swap(client_map_); |
259 | 260 |
260 child_task_runner_->PostTask( | 261 child_task_runner_->PostTask( |
261 FROM_HERE, | 262 FROM_HERE, |
262 base::Bind(&DeleteClientMapOnChildThread, base::Passed(&client_map))); | 263 base::Bind(&DeleteClientMapOnChildThread, base::Passed(&client_map))); |
263 } | 264 } |
264 } | 265 } |
265 | 266 |
266 private: | 267 private: |
267 using ClientMap = base::hash_map<int32_t, Client*>; | 268 using ClientMap = base::hash_map<int32_t, std::unique_ptr<Client>>; |
268 | 269 |
269 // Must be static because this method runs after destructor. | 270 // Must be static because this method runs after destructor. |
270 static void DeleteClientMapOnChildThread( | 271 static void DeleteClientMapOnChildThread( |
271 std::unique_ptr<ClientMap> client_map) { | 272 std::unique_ptr<ClientMap> client_map) { |
272 base::STLDeleteValues(client_map.get()); | 273 // |client_map| is cleared when the scope of this function is left. |
273 } | 274 } |
274 | 275 |
275 base::WeakPtr<GpuJpegDecodeAccelerator> owner_; | 276 base::WeakPtr<GpuJpegDecodeAccelerator> owner_; |
276 | 277 |
277 // GPU child task runner. | 278 // GPU child task runner. |
278 scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; | 279 scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; |
279 | 280 |
280 // GPU IO task runner. | 281 // GPU IO task runner. |
281 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; | 282 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; |
282 | 283 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 // This should be before AddClientOnIOThread. | 342 // This should be before AddClientOnIOThread. |
342 channel_->AddFilter(filter_.get()); | 343 channel_->AddFilter(filter_.get()); |
343 } | 344 } |
344 client_number_++; | 345 client_number_++; |
345 | 346 |
346 // In this PostTask, |client| may leak if |io_task_runner_| is destroyed | 347 // In this PostTask, |client| may leak if |io_task_runner_| is destroyed |
347 // before |client| reached AddClientOnIOThread. However we cannot use scoper | 348 // before |client| reached AddClientOnIOThread. However we cannot use scoper |
348 // to protect it because |client| can only be deleted on child thread. The IO | 349 // to protect it because |client| can only be deleted on child thread. The IO |
349 // thread is destroyed at termination, at which point it's ok to leak since | 350 // thread is destroyed at termination, at which point it's ok to leak since |
350 // we're going to tear down the process anyway. So we just crossed fingers | 351 // we're going to tear down the process anyway. So we just crossed fingers |
351 // here instead of making the code unnecessary complicated. | 352 // here instead of making the code unnecessary complicated. |
wolenetz
2016/09/27 22:01:12
drive-by nit: s/unnecessary/unnecessarily/
Avi (use Gerrit)
2016/09/28 15:41:46
I'll spell-check the whole file while I'm at it, t
| |
352 io_task_runner_->PostTask( | 353 io_task_runner_->PostTask( |
353 FROM_HERE, base::Bind(&MessageFilter::AddClientOnIOThread, filter_, | 354 FROM_HERE, base::Bind(&MessageFilter::AddClientOnIOThread, filter_, |
354 route_id, client.release(), response)); | 355 route_id, client.release(), response)); |
355 } | 356 } |
356 | 357 |
357 void GpuJpegDecodeAccelerator::NotifyDecodeStatus( | 358 void GpuJpegDecodeAccelerator::NotifyDecodeStatus( |
358 int32_t route_id, | 359 int32_t route_id, |
359 int32_t buffer_id, | 360 int32_t buffer_id, |
360 JpegDecodeAccelerator::Error error) { | 361 JpegDecodeAccelerator::Error error) { |
361 DCHECK(CalledOnValidThread()); | 362 DCHECK(CalledOnValidThread()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 for (const auto& create_jda_function : create_jda_fps) { | 410 for (const auto& create_jda_function : create_jda_fps) { |
410 std::unique_ptr<JpegDecodeAccelerator> accelerator = | 411 std::unique_ptr<JpegDecodeAccelerator> accelerator = |
411 (*create_jda_function)(base::ThreadTaskRunnerHandle::Get()); | 412 (*create_jda_function)(base::ThreadTaskRunnerHandle::Get()); |
412 if (accelerator && accelerator->IsSupported()) | 413 if (accelerator && accelerator->IsSupported()) |
413 return true; | 414 return true; |
414 } | 415 } |
415 return false; | 416 return false; |
416 } | 417 } |
417 | 418 |
418 } // namespace media | 419 } // namespace media |
OLD | NEW |