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

Side by Side Diff: components/favicon/core/favicon_service.cc

Issue 2313563002: Reduce jank from favicon downscaling. (Closed)
Patch Set: Add description comment in header Created 4 years, 3 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 | « no previous file | components/favicon_base/favicon_util.h » ('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 (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 "components/favicon/core/favicon_service.h" 5 #include "components/favicon/core/favicon_service.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <cmath> 8 #include <cmath>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/hash.h" 11 #include "base/hash.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
14 #include "base/trace_event/trace_event.h"
14 #include "components/favicon/core/favicon_client.h" 15 #include "components/favicon/core/favicon_client.h"
15 #include "components/favicon_base/favicon_util.h" 16 #include "components/favicon_base/favicon_util.h"
16 #include "components/favicon_base/select_favicon_frames.h" 17 #include "components/favicon_base/select_favicon_frames.h"
17 #include "components/history/core/browser/history_service.h" 18 #include "components/history/core/browser/history_service.h"
18 #include "third_party/skia/include/core/SkBitmap.h" 19 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/gfx/codec/png_codec.h" 20 #include "ui/gfx/codec/png_codec.h"
20 #include "ui/gfx/favicon_size.h" 21 #include "ui/gfx/favicon_size.h"
21 #include "ui/gfx/image/image_skia.h" 22 #include "ui/gfx/image/image_skia.h"
22 #include "url/gurl.h" 23 #include "url/gurl.h"
23 24
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 void FaviconService::FaviconResultsCallbackRunner( 63 void FaviconService::FaviconResultsCallbackRunner(
63 const favicon_base::FaviconResultsCallback& callback, 64 const favicon_base::FaviconResultsCallback& callback,
64 const std::vector<favicon_base::FaviconRawBitmapResult>* results) { 65 const std::vector<favicon_base::FaviconRawBitmapResult>* results) {
65 callback.Run(*results); 66 callback.Run(*results);
66 } 67 }
67 68
68 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage( 69 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImage(
69 const GURL& icon_url, 70 const GURL& icon_url,
70 const favicon_base::FaviconImageCallback& callback, 71 const favicon_base::FaviconImageCallback& callback,
71 base::CancelableTaskTracker* tracker) { 72 base::CancelableTaskTracker* tracker) {
73 TRACE_EVENT0("browser", "FaviconService::GetFaviconImage");
72 favicon_base::FaviconResultsCallback callback_runner = 74 favicon_base::FaviconResultsCallback callback_runner =
73 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, 75 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
74 base::Unretained(this), callback, gfx::kFaviconSize); 76 base::Unretained(this), callback, gfx::kFaviconSize);
75 if (history_service_) { 77 if (history_service_) {
76 std::vector<GURL> icon_urls; 78 std::vector<GURL> icon_urls;
77 icon_urls.push_back(icon_url); 79 icon_urls.push_back(icon_url);
78 return history_service_->GetFavicons( 80 return history_service_->GetFavicons(
79 icon_urls, 81 icon_urls,
80 favicon_base::FAVICON, 82 favicon_base::FAVICON,
81 GetPixelSizesForFaviconScales(gfx::kFaviconSize), 83 GetPixelSizesForFaviconScales(gfx::kFaviconSize),
82 callback_runner, 84 callback_runner,
83 tracker); 85 tracker);
84 } 86 }
85 return RunWithEmptyResultAsync(callback_runner, tracker); 87 return RunWithEmptyResultAsync(callback_runner, tracker);
86 } 88 }
87 89
88 base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon( 90 base::CancelableTaskTracker::TaskId FaviconService::GetRawFavicon(
89 const GURL& icon_url, 91 const GURL& icon_url,
90 favicon_base::IconType icon_type, 92 favicon_base::IconType icon_type,
91 int desired_size_in_pixel, 93 int desired_size_in_pixel,
92 const favicon_base::FaviconRawBitmapCallback& callback, 94 const favicon_base::FaviconRawBitmapCallback& callback,
93 base::CancelableTaskTracker* tracker) { 95 base::CancelableTaskTracker* tracker) {
96 TRACE_EVENT0("browser", "FaviconService::GetRawFavicon");
94 favicon_base::FaviconResultsCallback callback_runner = 97 favicon_base::FaviconResultsCallback callback_runner =
95 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, 98 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
96 base::Unretained(this), callback, desired_size_in_pixel); 99 base::Unretained(this), callback, desired_size_in_pixel);
97 100
98 if (history_service_) { 101 if (history_service_) {
99 std::vector<GURL> icon_urls; 102 std::vector<GURL> icon_urls;
100 icon_urls.push_back(icon_url); 103 icon_urls.push_back(icon_url);
101 std::vector<int> desired_sizes_in_pixel; 104 std::vector<int> desired_sizes_in_pixel;
102 desired_sizes_in_pixel.push_back(desired_size_in_pixel); 105 desired_sizes_in_pixel.push_back(desired_size_in_pixel);
103 106
104 return history_service_->GetFavicons( 107 return history_service_->GetFavicons(
105 icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker); 108 icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker);
106 } 109 }
107 return RunWithEmptyResultAsync(callback_runner, tracker); 110 return RunWithEmptyResultAsync(callback_runner, tracker);
108 } 111 }
109 112
110 base::CancelableTaskTracker::TaskId FaviconService::GetFavicon( 113 base::CancelableTaskTracker::TaskId FaviconService::GetFavicon(
111 const GURL& icon_url, 114 const GURL& icon_url,
112 favicon_base::IconType icon_type, 115 favicon_base::IconType icon_type,
113 int desired_size_in_dip, 116 int desired_size_in_dip,
114 const favicon_base::FaviconResultsCallback& callback, 117 const favicon_base::FaviconResultsCallback& callback,
115 base::CancelableTaskTracker* tracker) { 118 base::CancelableTaskTracker* tracker) {
119 TRACE_EVENT0("browser", "FaviconService::GetFavicon");
116 if (history_service_) { 120 if (history_service_) {
117 std::vector<GURL> icon_urls; 121 std::vector<GURL> icon_urls;
118 icon_urls.push_back(icon_url); 122 icon_urls.push_back(icon_url);
119 return history_service_->GetFavicons( 123 return history_service_->GetFavicons(
120 icon_urls, 124 icon_urls,
121 icon_type, 125 icon_type,
122 GetPixelSizesForFaviconScales(desired_size_in_dip), 126 GetPixelSizesForFaviconScales(desired_size_in_dip),
123 callback, 127 callback,
124 tracker); 128 tracker);
125 } 129 }
126 return RunWithEmptyResultAsync(callback, tracker); 130 return RunWithEmptyResultAsync(callback, tracker);
127 } 131 }
128 132
129 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForPageURL( 133 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconImageForPageURL(
130 const GURL& page_url, 134 const GURL& page_url,
131 const favicon_base::FaviconImageCallback& callback, 135 const favicon_base::FaviconImageCallback& callback,
132 base::CancelableTaskTracker* tracker) { 136 base::CancelableTaskTracker* tracker) {
137 TRACE_EVENT0("browser", "FaviconService::GetFaviconImageForPageURL");
133 return GetFaviconForPageURLImpl( 138 return GetFaviconForPageURLImpl(
134 page_url, favicon_base::FAVICON, 139 page_url, favicon_base::FAVICON,
135 GetPixelSizesForFaviconScales(gfx::kFaviconSize), 140 GetPixelSizesForFaviconScales(gfx::kFaviconSize),
136 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults, 141 base::Bind(&FaviconService::RunFaviconImageCallbackWithBitmapResults,
137 base::Unretained(this), callback, gfx::kFaviconSize), 142 base::Unretained(this), callback, gfx::kFaviconSize),
138 tracker); 143 tracker);
139 } 144 }
140 145
141 base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForPageURL( 146 base::CancelableTaskTracker::TaskId FaviconService::GetRawFaviconForPageURL(
142 const GURL& page_url, 147 const GURL& page_url,
143 int icon_types, 148 int icon_types,
144 int desired_size_in_pixel, 149 int desired_size_in_pixel,
145 const favicon_base::FaviconRawBitmapCallback& callback, 150 const favicon_base::FaviconRawBitmapCallback& callback,
146 base::CancelableTaskTracker* tracker) { 151 base::CancelableTaskTracker* tracker) {
152 TRACE_EVENT0("browser", "FaviconService::GetRawFaviconForPageURL");
147 std::vector<int> desired_sizes_in_pixel; 153 std::vector<int> desired_sizes_in_pixel;
148 desired_sizes_in_pixel.push_back(desired_size_in_pixel); 154 desired_sizes_in_pixel.push_back(desired_size_in_pixel);
149 return GetFaviconForPageURLImpl( 155 return GetFaviconForPageURLImpl(
150 page_url, icon_types, desired_sizes_in_pixel, 156 page_url, icon_types, desired_sizes_in_pixel,
151 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, 157 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
152 base::Unretained(this), callback, desired_size_in_pixel), 158 base::Unretained(this), callback, desired_size_in_pixel),
153 tracker); 159 tracker);
154 } 160 }
155 161
156 base::CancelableTaskTracker::TaskId 162 base::CancelableTaskTracker::TaskId
157 FaviconService::GetLargestRawFaviconForPageURL( 163 FaviconService::GetLargestRawFaviconForPageURL(
158 const GURL& page_url, 164 const GURL& page_url,
159 const std::vector<int>& icon_types, 165 const std::vector<int>& icon_types,
160 int minimum_size_in_pixels, 166 int minimum_size_in_pixels,
161 const favicon_base::FaviconRawBitmapCallback& callback, 167 const favicon_base::FaviconRawBitmapCallback& callback,
162 base::CancelableTaskTracker* tracker) { 168 base::CancelableTaskTracker* tracker) {
169 TRACE_EVENT0("browser", "FaviconService::GetLargestRawFaviconForPageURL");
163 favicon_base::FaviconResultsCallback favicon_results_callback = 170 favicon_base::FaviconResultsCallback favicon_results_callback =
164 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, 171 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
165 base::Unretained(this), callback, 0); 172 base::Unretained(this), callback, 0);
166 if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) { 173 if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) {
167 std::vector<int> desired_sizes_in_pixel; 174 std::vector<int> desired_sizes_in_pixel;
168 desired_sizes_in_pixel.push_back(0); 175 desired_sizes_in_pixel.push_back(0);
169 return favicon_client_->GetFaviconForNativeApplicationURL( 176 return favicon_client_->GetFaviconForNativeApplicationURL(
170 page_url, desired_sizes_in_pixel, favicon_results_callback, tracker); 177 page_url, desired_sizes_in_pixel, favicon_results_callback, tracker);
171 } 178 }
172 if (history_service_) { 179 if (history_service_) {
173 return history_service_->GetLargestFaviconForURL(page_url, icon_types, 180 return history_service_->GetLargestFaviconForURL(page_url, icon_types,
174 minimum_size_in_pixels, callback, tracker); 181 minimum_size_in_pixels, callback, tracker);
175 } 182 }
176 return RunWithEmptyResultAsync(favicon_results_callback, tracker); 183 return RunWithEmptyResultAsync(favicon_results_callback, tracker);
177 } 184 }
178 185
179 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL( 186 base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL(
180 const GURL& page_url, 187 const GURL& page_url,
181 int icon_types, 188 int icon_types,
182 int desired_size_in_dip, 189 int desired_size_in_dip,
183 const favicon_base::FaviconResultsCallback& callback, 190 const favicon_base::FaviconResultsCallback& callback,
184 base::CancelableTaskTracker* tracker) { 191 base::CancelableTaskTracker* tracker) {
192 TRACE_EVENT0("browser", "FaviconService::GetFaviconForPageURL");
185 return GetFaviconForPageURLImpl( 193 return GetFaviconForPageURLImpl(
186 page_url, 194 page_url,
187 icon_types, 195 icon_types,
188 GetPixelSizesForFaviconScales(desired_size_in_dip), 196 GetPixelSizesForFaviconScales(desired_size_in_dip),
189 callback, 197 callback,
190 tracker); 198 tracker);
191 } 199 }
192 200
193 base::CancelableTaskTracker::TaskId 201 base::CancelableTaskTracker::TaskId
194 FaviconService::UpdateFaviconMappingsAndFetch( 202 FaviconService::UpdateFaviconMappingsAndFetch(
(...skipping 12 matching lines...) Expand all
207 callback, 215 callback,
208 tracker); 216 tracker);
209 } 217 }
210 return RunWithEmptyResultAsync(callback, tracker); 218 return RunWithEmptyResultAsync(callback, tracker);
211 } 219 }
212 220
213 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID( 221 base::CancelableTaskTracker::TaskId FaviconService::GetLargestRawFaviconForID(
214 favicon_base::FaviconID favicon_id, 222 favicon_base::FaviconID favicon_id,
215 const favicon_base::FaviconRawBitmapCallback& callback, 223 const favicon_base::FaviconRawBitmapCallback& callback,
216 base::CancelableTaskTracker* tracker) { 224 base::CancelableTaskTracker* tracker) {
225 TRACE_EVENT0("browser", "FaviconService::GetLargestRawFaviconForID");
217 // Use 0 as |desired_size| to get the largest bitmap for |favicon_id| without 226 // Use 0 as |desired_size| to get the largest bitmap for |favicon_id| without
218 // any resizing. 227 // any resizing.
219 int desired_size = 0; 228 int desired_size = 0;
220 favicon_base::FaviconResultsCallback callback_runner = 229 favicon_base::FaviconResultsCallback callback_runner =
221 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults, 230 base::Bind(&FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults,
222 base::Unretained(this), callback, desired_size); 231 base::Unretained(this), callback, desired_size);
223 232
224 if (history_service_) { 233 if (history_service_) {
225 return history_service_->GetFaviconForID( 234 return history_service_->GetFaviconForID(
226 favicon_id, desired_size, callback_runner, tracker); 235 favicon_id, desired_size, callback_runner, tracker);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 tracker); 316 tracker);
308 } 317 }
309 return RunWithEmptyResultAsync(callback, tracker); 318 return RunWithEmptyResultAsync(callback, tracker);
310 } 319 }
311 320
312 void FaviconService::RunFaviconImageCallbackWithBitmapResults( 321 void FaviconService::RunFaviconImageCallbackWithBitmapResults(
313 const favicon_base::FaviconImageCallback& callback, 322 const favicon_base::FaviconImageCallback& callback,
314 int desired_size_in_dip, 323 int desired_size_in_dip,
315 const std::vector<favicon_base::FaviconRawBitmapResult>& 324 const std::vector<favicon_base::FaviconRawBitmapResult>&
316 favicon_bitmap_results) { 325 favicon_bitmap_results) {
326 TRACE_EVENT0("browser",
327 "FaviconService::RunFaviconImageCallbackWithBitmapResults");
317 favicon_base::FaviconImageResult image_result; 328 favicon_base::FaviconImageResult image_result;
318 image_result.image = favicon_base::SelectFaviconFramesFromPNGs( 329 image_result.image = favicon_base::SelectFaviconFramesFromPNGs(
319 favicon_bitmap_results, 330 favicon_bitmap_results,
320 favicon_base::GetFaviconScales(), 331 favicon_base::GetFaviconScales(),
321 desired_size_in_dip); 332 desired_size_in_dip);
322 favicon_base::SetFaviconColorSpace(&image_result.image); 333 favicon_base::SetFaviconColorSpace(&image_result.image);
323 334
324 image_result.icon_url = image_result.image.IsEmpty() ? 335 image_result.icon_url = image_result.image.IsEmpty() ?
325 GURL() : favicon_bitmap_results[0].icon_url; 336 GURL() : favicon_bitmap_results[0].icon_url;
326 callback.Run(image_result); 337 callback.Run(image_result);
327 } 338 }
328 339
329 void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults( 340 void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults(
330 const favicon_base::FaviconRawBitmapCallback& callback, 341 const favicon_base::FaviconRawBitmapCallback& callback,
331 int desired_size_in_pixel, 342 int desired_size_in_pixel,
332 const std::vector<favicon_base::FaviconRawBitmapResult>& 343 const std::vector<favicon_base::FaviconRawBitmapResult>&
333 favicon_bitmap_results) { 344 favicon_bitmap_results) {
334 if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid()) { 345 TRACE_EVENT0("browser",
335 callback.Run(favicon_base::FaviconRawBitmapResult()); 346 "FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults");
336 return; 347 callback.Run(
337 } 348 ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel));
338
339 favicon_base::FaviconRawBitmapResult bitmap_result =
340 favicon_bitmap_results[0];
341
342 // If the desired size is 0, SelectFaviconFrames() will return the largest
343 // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap
344 // data for a single bitmap, return it and avoid an unnecessary decode.
345 if (desired_size_in_pixel == 0) {
346 callback.Run(bitmap_result);
347 return;
348 }
349
350 // If history bitmap is already desired pixel size, return early.
351 if (bitmap_result.pixel_size.width() == desired_size_in_pixel &&
352 bitmap_result.pixel_size.height() == desired_size_in_pixel) {
353 callback.Run(bitmap_result);
354 return;
355 }
356
357 // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then
358 // convert back.
359 std::vector<float> desired_favicon_scales;
360 desired_favicon_scales.push_back(1.0f);
361 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
362 favicon_bitmap_results, desired_favicon_scales, desired_size_in_pixel);
363
364 std::vector<unsigned char> resized_bitmap_data;
365 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false,
366 &resized_bitmap_data)) {
367 callback.Run(favicon_base::FaviconRawBitmapResult());
368 return;
369 }
370
371 bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector(
372 &resized_bitmap_data);
373 callback.Run(bitmap_result);
374 } 349 }
375 350
376 } // namespace favicon 351 } // namespace favicon
OLDNEW
« no previous file with comments | « no previous file | components/favicon_base/favicon_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698