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

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

Issue 931993002: Make image_decoder a Leaky LazyInstance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename instance_ to image_decoder_instance_ for mac linker Created 5 years, 9 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 "base/bind.h" 7 #include "base/bind.h"
8 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/browser_process.h"
9 #include "chrome/common/chrome_utility_messages.h" 9 #include "chrome/common/chrome_utility_messages.h"
10 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/utility_process_host.h" 11 #include "content/public/browser/utility_process_host.h"
12 12
13 using content::BrowserThread; 13 using content::BrowserThread;
14 using content::UtilityProcessHost; 14 using content::UtilityProcessHost;
15 15
16 ImageDecoder::ImageDecoder(Delegate* delegate, 16
17 const std::string& image_data, 17 // static, Leaky to allow access from any thread.
18 ImageCodec image_codec) 18 base::LazyInstance<ImageDecoder>::Leaky image_decoder_instance_ =
19 : delegate_(delegate), 19 LAZY_INSTANCE_INITIALIZER;
20 image_data_(image_data.begin(), image_data.end()), 20
21 image_codec_(image_codec), 21 // static
22 task_runner_(NULL), 22 ImageDecoder* ImageDecoder::GetInstance() {
23 shrink_to_fit_(false) { 23 return image_decoder_instance_.Pointer();
24 } 24 }
25 25
26 ImageDecoder::ImageDecoder(Delegate* delegate, 26 ImageDecoder::ImageDecoder() {
27 const std::vector<char>& image_data, 27 image_decoder_impl_ = new ImageDecoderImpl();
dcheng 2015/02/27 16:47:17 It might be better to put this in the initializer.
dcheng 2015/02/27 16:47:17 It might be better to put this in the initializer.
Theresa 2015/03/04 03:10:06 Done.
Theresa 2015/03/04 03:10:06 Done.
28 ImageCodec image_codec)
29 : delegate_(delegate),
30 image_data_(image_data.begin(), image_data.end()),
31 image_codec_(image_codec),
32 task_runner_(NULL),
33 shrink_to_fit_(false) {
34 } 28 }
35 29
36 ImageDecoder::~ImageDecoder() {} 30 ImageDecoder::~ImageDecoder() {
37
38 void ImageDecoder::Start(scoped_refptr<base::SequencedTaskRunner> task_runner) {
39 task_runner_ = task_runner;
40 BrowserThread::PostTask(
41 BrowserThread::IO, FROM_HERE,
42 base::Bind(&ImageDecoder::DecodeImageInSandbox, this, image_data_));
43 } 31 }
44 32
45 bool ImageDecoder::OnMessageReceived(const IPC::Message& message) { 33 void ImageDecoder::Start(Delegate* delegate,
34 const std::string& image_data,
35 ImageCodec image_codec,
36 scoped_refptr<base::SequencedTaskRunner> task_runner,
37 bool shrink_to_fit) {
38 image_decoder_impl_->Start(delegate, image_data, image_codec,
39 task_runner, shrink_to_fit);
40 }
41
42 // ImageDecoder::ImageDecoderImpl Methods
43
44 ImageDecoder::ImageDecoderImpl::ImageDecoderImpl(){
dcheng 2015/02/27 16:47:17 clang-format should catch these random missing spa
Theresa 2015/03/04 03:10:06 Done.
45 }
46
47 ImageDecoder::ImageDecoderImpl::~ImageDecoderImpl(){
48 }
49
50 void ImageDecoder::ImageDecoderImpl::Start(
51 Delegate* delegate,
52 const std::string& image_data,
53 ImageCodec image_codec,
54 scoped_refptr<base::SequencedTaskRunner> task_runner,
55 bool shrink_to_fit) {
56 // If the task runner is null, we can't post tasks back to it when the
57 // image is decoded. Notify the delegate if possible and return.
58 if (!task_runner) {
dcheng 2015/02/27 16:47:17 This seems like a programming error that we should
Theresa 2015/03/04 03:10:06 Done.
59 if (delegate) {
dcheng 2015/02/27 16:47:17 IMO, |delegate| should probably be required too.
Theresa 2015/03/04 03:10:06 Done.
60 delegate->OnDecodeImageFailed();
61 }
62 return;
63 }
64
65 if (!batch_mode_started_) {
66 task_runner_at_start_ = task_runner;
67 BrowserThread::PostTask(
68 BrowserThread::IO, FROM_HERE,
69 base::Bind(
70 &ImageDecoder::ImageDecoderImpl::StartBatchMode,
71 this,
72 delegate,
73 image_data,
74 image_codec,
75 shrink_to_fit));
76 return;
77 }
78
79 last_request_ = time(0);
80 delegate_map_[delegate_id_counter_] = delegate;
dcheng 2015/02/27 16:47:17 I'd recommend using IDMap here. Also, it's probabl
Theresa 2015/03/04 03:10:06 I changed it to one map instead of two parallel ma
81 task_runner_map_[delegate_id_counter_] = task_runner;
82
83 BrowserThread::PostTask(
84 BrowserThread::IO, FROM_HERE,
85 base::Bind(
86 &ImageDecoder::ImageDecoderImpl::DecodeImageInSandbox,
87 this,
88 delegate,
89 std::vector<unsigned char>(image_data.begin(), image_data.end()),
90 image_codec,
91 shrink_to_fit,
92 delegate_id_counter_));
93
94 ++delegate_id_counter_;
95 }
96
97 void ImageDecoder::ImageDecoderImpl::StartBatchMode(
98 Delegate* delegate,
99 const std::string& image_data,
100 ImageCodec image_codec,
101 bool shrink_to_fit) {
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
103 utility_process_host_ = UtilityProcessHost::Create(
104 this, base::MessageLoopProxy::current().get())->AsWeakPtr();
105 utility_process_host_->StartBatchMode();
106 batch_mode_started_ = true;
107 PostDelayedStopBatchModeTask();
108 Start(delegate, image_data, image_codec, task_runner_at_start_,
109 shrink_to_fit);
110 }
111
112 void ImageDecoder::ImageDecoderImpl::PostDelayedStopBatchModeTask() {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
114 BrowserThread::PostDelayedTask(
115 BrowserThread::IO, FROM_HERE,
116 base::Bind(&ImageDecoder::ImageDecoderImpl::StopBatchMode,
117 this),
118 base::TimeDelta::FromSeconds(batch_mode_timeout_seconds_));
119 }
120
121 void ImageDecoder::ImageDecoderImpl::StopBatchMode() {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
123 if ((time(0) - last_request_) < batch_mode_timeout_seconds_) {
dcheng 2015/02/27 16:47:17 I think we can use base::DelayTimer here to simpli
Theresa 2015/03/04 03:10:06 The timer api's aren't thread safe, so they won't
Theresa 2015/03/05 16:53:05 I rethought this and spent some time playing aroun
124 PostDelayedStopBatchModeTask();
125 return;
126 }
127
128 if (utility_process_host_.get()) {
129 utility_process_host_->EndBatchMode();
130 utility_process_host_.reset();
131 }
132 batch_mode_started_ = false;
133 }
134
135 bool ImageDecoder::ImageDecoderImpl::OnMessageReceived(
136 const IPC::Message& message) {
46 bool handled = true; 137 bool handled = true;
47 IPC_BEGIN_MESSAGE_MAP(ImageDecoder, message) 138 IPC_BEGIN_MESSAGE_MAP(ImageDecoder::ImageDecoderImpl, message)
48 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded, 139 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded,
49 OnDecodeImageSucceeded) 140 OnDecodeImageSucceeded)
50 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed, 141 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed,
51 OnDecodeImageFailed) 142 OnDecodeImageFailed)
52 IPC_MESSAGE_UNHANDLED(handled = false) 143 IPC_MESSAGE_UNHANDLED(handled = false)
53 IPC_END_MESSAGE_MAP() 144 IPC_END_MESSAGE_MAP()
54 return handled; 145 return handled;
55 } 146 }
56 147
57 void ImageDecoder::OnDecodeImageSucceeded(const SkBitmap& decoded_image) { 148 void ImageDecoder::ImageDecoderImpl::OnDecodeImageSucceeded(
58 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 149 const SkBitmap& decoded_image,
59 if (delegate_) 150 int id) {
60 delegate_->OnImageDecoded(this, decoded_image); 151 if (delegate_map_.find(id) != delegate_map_.end()
152 && task_runner_map_.find(id) != task_runner_map_.end()) {
153 task_runner_map_[id]->PostTask(
154 FROM_HERE,
155 base::Bind(
156 &ImageDecoder::ImageDecoderImpl::NotifyDelegateDecodeSucceeded,
157 this,
158 decoded_image,
159 delegate_map_[id]));
160
161 delegate_map_.erase(id);
162 task_runner_map_.erase(id);
163 }
61 } 164 }
62 165
63 void ImageDecoder::OnDecodeImageFailed() { 166 void ImageDecoder::ImageDecoderImpl::OnDecodeImageFailed(int id) {
64 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 167 if (delegate_map_.find(id) != delegate_map_.end()
65 if (delegate_) 168 && task_runner_map_.find(id) != task_runner_map_.end()) {
66 delegate_->OnDecodeImageFailed(this); 169 task_runner_map_[id]->PostTask(
170 FROM_HERE,
171 base::Bind(
172 &ImageDecoder::ImageDecoderImpl::NotifyDelegateDecodeFailed,
173 this,
174 delegate_map_[id]));
175
176 delegate_map_.erase(id);
177 task_runner_map_.erase(id);
178 }
67 } 179 }
68 180
69 void ImageDecoder::DecodeImageInSandbox( 181 void ImageDecoder::ImageDecoderImpl::NotifyDelegateDecodeSucceeded(
70 const std::vector<unsigned char>& image_data) { 182 const SkBitmap& decoded_image, Delegate* delegate) {
183 delegate->OnImageDecoded(decoded_image);
184 }
185
186 void ImageDecoder::ImageDecoderImpl::NotifyDelegateDecodeFailed(
187 Delegate* delegate) {
188 delegate->OnDecodeImageFailed();
189 }
190
191 void ImageDecoder::ImageDecoderImpl::DecodeImageInSandbox(
192 Delegate* delegate,
193 const std::vector<unsigned char>& image_data,
194 ImageCodec image_codec,
195 bool shrink_to_fit,
196 int delegate_id) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
72 UtilityProcessHost* utility_process_host; 198 if (image_codec == ROBUST_JPEG_CODEC) {
73 utility_process_host = UtilityProcessHost::Create(this, task_runner_.get()); 199 utility_process_host_->Send(
74 if (image_codec_ == ROBUST_JPEG_CODEC) { 200 new ChromeUtilityMsg_RobustJPEGDecodeImage(image_data,
75 utility_process_host->Send( 201 delegate_id));
76 new ChromeUtilityMsg_RobustJPEGDecodeImage(image_data));
77 } else { 202 } else {
78 utility_process_host->Send( 203 utility_process_host_->Send(
79 new ChromeUtilityMsg_DecodeImage(image_data, shrink_to_fit_)); 204 new ChromeUtilityMsg_DecodeImage(image_data, shrink_to_fit,
205 delegate_id));
80 } 206 }
81 } 207 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698