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

Side by Side Diff: chrome/browser/image_decoder.cc

Issue 1028543002: Turn the utility process image decoder into a Mojo service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and remove ref counting. Created 5 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/image_decoder.h" 5 #include "chrome/browser/image_decoder.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/common/chrome_switches.h"
11 #include "chrome/common/chrome_utility_messages.h" 12 #include "chrome/common/chrome_utility_messages.h"
12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/utility_process_host.h" 14 #include "content/public/browser/utility_process_host.h"
15 #include "content/public/common/service_registry.h"
16 #include "services/image_decoder/public/interfaces/image_decoder.mojom.h"
17 #include "skia/public/type_converters.h"
14 18
15 using content::BrowserThread; 19 using content::BrowserThread;
16 using content::UtilityProcessHost; 20 using content::UtilityProcessHost;
17 21
18 namespace { 22 namespace {
19 23
20 // static, Leaky to allow access from any thread. 24 // static, Leaky to allow access from any thread.
21 base::LazyInstance<ImageDecoder>::Leaky g_decoder = LAZY_INSTANCE_INITIALIZER; 25 base::LazyInstance<ImageDecoder>::Leaky g_decoder = LAZY_INSTANCE_INITIALIZER;
22 26
23 // How long to wait after the last request has been received before ending 27 // How long to wait after the last request has been received before ending
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 212 }
209 213
210 last_request_ = base::TimeTicks::Now(); 214 last_request_ = base::TimeTicks::Now();
211 { 215 {
212 base::AutoLock lock(map_lock_); 216 base::AutoLock lock(map_lock_);
213 auto it = image_request_id_map_.find(request_id); 217 auto it = image_request_id_map_.find(request_id);
214 if (it != image_request_id_map_.end()) 218 if (it != image_request_id_map_.end())
215 it->second->SetStarted(); 219 it->second->SetStarted();
216 } 220 }
217 221
218 switch (image_codec) { 222 if (switches::MojoUtilityServicesEnabled()) {
219 case ROBUST_JPEG_CODEC: 223 decoder_->DecodeImage(mojo::Array<uint8_t>::From(image_data),
220 utility_process_host_->Send( 224 image_codec == ROBUST_JPEG_CODEC ?
221 new ChromeUtilityMsg_RobustJPEGDecodeImage(image_data, request_id)); 225 services::IMAGE_CODEC_ROBUST_JPEG :
222 break; 226 services::IMAGE_CODEC_DEFAULT,
223 case DEFAULT_CODEC: 227 shrink_to_fit,
224 utility_process_host_->Send(new ChromeUtilityMsg_DecodeImage( 228 base::Bind(&ImageDecoder::OnDecodeImageDone,
225 image_data, shrink_to_fit, request_id)); 229 this,
226 break; 230 request_id));
231 } else {
232 switch (image_codec) {
233 case ROBUST_JPEG_CODEC:
234 utility_process_host_->Send(new ChromeUtilityMsg_RobustJPEGDecodeImage(
235 image_data, request_id));
236 break;
237 case DEFAULT_CODEC:
238 utility_process_host_->Send(new ChromeUtilityMsg_DecodeImage(
239 image_data, shrink_to_fit, request_id));
240 break;
241 }
227 } 242 }
228 } 243 }
229 244
230 void ImageDecoder::CancelImpl(ImageRequest* image_request) { 245 void ImageDecoder::CancelImpl(ImageRequest* image_request) {
231 std::set<scoped_refptr<Job>> jobs; 246 std::set<scoped_refptr<Job>> jobs;
232 247
233 { 248 {
234 base::AutoLock lock(map_lock_); 249 base::AutoLock lock(map_lock_);
235 for (const auto& request : image_request_id_map_) { 250 for (const auto& request : image_request_id_map_) {
236 if (request.second->image_request() == image_request) { 251 if (request.second->image_request() == image_request) {
237 jobs.insert(request.second); 252 jobs.insert(request.second);
238 // Don't erase the job from the map here, but let Job::Cancel do it 253 // Don't erase the job from the map here, but let Job::Cancel do it
239 // instead. This is mainly to maintain consistency with how decode 254 // instead. This is mainly to maintain consistency with how decode
240 // success/fail are handled. 255 // success/fail are handled.
241 } 256 }
242 } 257 }
243 } 258 }
244 259
245 // Will block if |OnImageDecoded| or |OnDecodeImageFailed| is running. 260 // Will block if |OnImageDecoded| or |OnDecodeImageFailed| is running.
246 for (auto& job : jobs) 261 for (auto& job : jobs)
247 job->Cancel(); 262 job->Cancel();
248 } 263 }
249 264
250 void ImageDecoder::StartBatchMode() { 265 void ImageDecoder::StartBatchMode() {
251 DCHECK_CURRENTLY_ON(BrowserThread::IO); 266 DCHECK_CURRENTLY_ON(BrowserThread::IO);
252 utility_process_host_ = 267 utility_process_host_ =
253 UtilityProcessHost::Create(this, base::MessageLoopProxy::current().get()) 268 UtilityProcessHost::Create(this, base::MessageLoopProxy::current().get())
254 ->AsWeakPtr(); 269 ->AsWeakPtr();
255 if (!utility_process_host_->StartBatchMode()) { 270 if (switches::MojoUtilityServicesEnabled()) {
256 utility_process_host_.reset(); 271 decoder_.reset();
257 return; 272 if (!utility_process_host_->StartMojoMode()) {
273 utility_process_host_.reset();
Sam McNally 2015/04/08 08:09:00 3 space indent?
Anand Mistry (off Chromium) 2015/04/09 05:25:03 Done.
274 return;
275 }
276 content::ServiceRegistry* service_registry =
277 utility_process_host_->GetServiceRegistry();
278 service_registry->ConnectToRemoteService(&decoder_);
279 } else {
280 if (!utility_process_host_->StartBatchMode()) {
281 utility_process_host_.reset();
282 return;
283 }
258 } 284 }
259 batch_mode_timer_.Start( 285 batch_mode_timer_.Start(
260 FROM_HERE, base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds), 286 FROM_HERE, base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds),
261 this, &ImageDecoder::StopBatchMode); 287 this, &ImageDecoder::StopBatchMode);
262 } 288 }
263 289
264 void ImageDecoder::StopBatchMode() { 290 void ImageDecoder::StopBatchMode() {
265 DCHECK_CURRENTLY_ON(BrowserThread::IO); 291 DCHECK_CURRENTLY_ON(BrowserThread::IO);
266 if ((base::TimeTicks::Now() - last_request_) 292 if ((base::TimeTicks::Now() - last_request_)
267 < base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds)) { 293 < base::TimeDelta::FromSeconds(kBatchModeTimeoutSeconds)) {
268 return; 294 return;
269 } 295 }
270 296
271 if (utility_process_host_) { 297 if (utility_process_host_) {
272 utility_process_host_->EndBatchMode(); 298 if (!switches::MojoUtilityServicesEnabled())
299 utility_process_host_->EndBatchMode();
273 utility_process_host_.reset(); 300 utility_process_host_.reset();
301 decoder_.reset();
274 } 302 }
275 batch_mode_timer_.Stop(); 303 batch_mode_timer_.Stop();
276 304
277 // There could be outstanding request that are taking too long. Fail these so 305 // There could be outstanding request that are taking too long. Fail these so
278 // that there aren't any dangling requests. 306 // that there aren't any dangling requests.
279 FailAllSentRequests(); 307 FailAllSentRequests();
280 } 308 }
281 309
282 void ImageDecoder::FailAllSentRequests() { 310 void ImageDecoder::FailAllSentRequests() {
283 RequestMap requests; 311 RequestMap requests;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 base::AutoLock lock(map_lock_); 375 base::AutoLock lock(map_lock_);
348 auto it = image_request_id_map_.find(request_id); 376 auto it = image_request_id_map_.find(request_id);
349 if (it != image_request_id_map_.end()) { 377 if (it != image_request_id_map_.end()) {
350 job = it->second; 378 job = it->second;
351 } 379 }
352 } 380 }
353 if (job) 381 if (job)
354 job->NotifyDecodeFailed(); 382 job->NotifyDecodeFailed();
355 } 383 }
356 384
385 void ImageDecoder::OnDecodeImageDone(int request_id, skia::BitmapPtr image) {
386 DCHECK_CURRENTLY_ON(BrowserThread::IO);
387 if (image) {
388 SkBitmap bitmap = image.To<SkBitmap>();
389 if (!bitmap.empty()) {
390 OnDecodeImageSucceeded(bitmap, request_id);
391 return;
392 }
393 }
394 OnDecodeImageFailed(request_id);
395 }
396
357 void ImageDecoder::RemoveJob(const scoped_refptr<Job>& job) { 397 void ImageDecoder::RemoveJob(const scoped_refptr<Job>& job) {
358 base::AutoLock lock(map_lock_); 398 base::AutoLock lock(map_lock_);
359 for (auto it = image_request_id_map_.begin(); 399 for (auto it = image_request_id_map_.begin();
360 it != image_request_id_map_.end();) { 400 it != image_request_id_map_.end();) {
361 if (it->second == job) { 401 if (it->second == job) {
362 image_request_id_map_.erase(it++); 402 image_request_id_map_.erase(it++);
363 break; 403 break;
364 } else { 404 } else {
365 ++it; 405 ++it;
366 } 406 }
367 } 407 }
368 } 408 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698