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

Side by Side Diff: components/favicon_base/favicon_util.cc

Issue 2313563002: Reduce jank from favicon downscaling. (Closed)
Patch Set: Rename to ResizeFaviconBitmapResult 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_base/favicon_util.h" 5 #include "components/favicon_base/favicon_util.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
11 11
12 #include "base/trace_event/trace_event.h"
12 #include "build/build_config.h" 13 #include "build/build_config.h"
13 #include "components/favicon_base/favicon_types.h" 14 #include "components/favicon_base/favicon_types.h"
14 #include "components/favicon_base/select_favicon_frames.h" 15 #include "components/favicon_base/select_favicon_frames.h"
15 #include "skia/ext/image_operations.h" 16 #include "skia/ext/image_operations.h"
16 #include "third_party/skia/include/core/SkBitmap.h" 17 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "third_party/skia/include/core/SkCanvas.h" 18 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "ui/base/layout.h" 19 #include "ui/base/layout.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/geometry/size.h" 22 #include "ui/gfx/geometry/size.h"
22 #include "ui/gfx/image/image_png_rep.h" 23 #include "ui/gfx/image/image_png_rep.h"
23 #include "ui/gfx/image/image_skia.h" 24 #include "ui/gfx/image/image_skia.h"
24 25
25 #if defined(OS_MACOSX) && !defined(OS_IOS) 26 #if defined(OS_MACOSX) && !defined(OS_IOS)
26 #include "base/mac/mac_util.h" 27 #include "base/mac/mac_util.h"
27 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 28 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
28 29
29 namespace favicon_base { 30 namespace favicon_base {
30 namespace { 31 namespace {
31 32
32 // Creates image reps of DIP size |favicon_size| for the subset of 33 // Creates image reps of DIP size |favicon_size| for the subset of
33 // |favicon_scales| for which the image reps can be created without resizing 34 // |favicon_scales| for which the image reps can be created without resizing
34 // or decoding the bitmap data. 35 // or decoding the bitmap data.
35 std::vector<gfx::ImagePNGRep> SelectFaviconFramesFromPNGsWithoutResizing( 36 std::vector<gfx::ImagePNGRep> SelectFaviconFramesFromPNGsWithoutResizing(
36 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data, 37 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data,
37 const std::vector<float>& favicon_scales, 38 const std::vector<float>& favicon_scales,
38 int favicon_size) { 39 int favicon_size) {
40 TRACE_EVENT0("browser",
41 "FaviconUtil::SelectFaviconFramesFromPNGsWithoutResizing");
39 std::vector<gfx::ImagePNGRep> png_reps; 42 std::vector<gfx::ImagePNGRep> png_reps;
40 if (png_data.empty()) 43 if (png_data.empty())
41 return png_reps; 44 return png_reps;
42 45
43 // A |favicon_size| of 0 indicates that the largest frame is desired. 46 // A |favicon_size| of 0 indicates that the largest frame is desired.
44 if (favicon_size == 0) { 47 if (favicon_size == 0) {
45 int maximum_area = 0; 48 int maximum_area = 0;
46 scoped_refptr<base::RefCountedMemory> best_candidate; 49 scoped_refptr<base::RefCountedMemory> best_candidate;
47 for (size_t i = 0; i < png_data.size(); ++i) { 50 for (size_t i = 0; i < png_data.size(); ++i) {
48 int area = png_data[i].pixel_size.GetArea(); 51 int area = png_data[i].pixel_size.GetArea();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 void SetFaviconColorSpace(gfx::Image* image) { 162 void SetFaviconColorSpace(gfx::Image* image) {
160 #if defined(OS_MACOSX) && !defined(OS_IOS) 163 #if defined(OS_MACOSX) && !defined(OS_IOS)
161 image->SetSourceColorSpace(base::mac::GetSystemColorSpace()); 164 image->SetSourceColorSpace(base::mac::GetSystemColorSpace());
162 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 165 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
163 } 166 }
164 167
165 gfx::Image SelectFaviconFramesFromPNGs( 168 gfx::Image SelectFaviconFramesFromPNGs(
166 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data, 169 const std::vector<favicon_base::FaviconRawBitmapResult>& png_data,
167 const std::vector<float>& favicon_scales, 170 const std::vector<float>& favicon_scales,
168 int favicon_size) { 171 int favicon_size) {
172 TRACE_EVENT0("browser", "FaviconUtil::SelectFaviconFramesFromPNGs");
173
169 // Create image reps for as many scales as possible without resizing 174 // Create image reps for as many scales as possible without resizing
170 // the bitmap data or decoding it. FaviconHandler stores already resized 175 // the bitmap data or decoding it. FaviconHandler stores already resized
171 // favicons into history so no additional resizing should be needed in the 176 // favicons into history so no additional resizing should be needed in the
172 // common case. 177 // common case.
173 // Creating the gfx::Image from |png_data| without resizing or decoding if 178 // Creating the gfx::Image from |png_data| without resizing or decoding if
174 // possible is important because: 179 // possible is important because:
175 // - Sync does a byte-to-byte comparison of gfx::Image::As1xPNGBytes() to 180 // - Sync does a byte-to-byte comparison of gfx::Image::As1xPNGBytes() to
176 // the data it put into the database in order to determine whether any 181 // the data it put into the database in order to determine whether any
177 // updates should be pushed to sync. 182 // updates should be pushed to sync.
178 // - The decoding occurs on the UI thread and the decoding can be a 183 // - The decoding occurs on the UI thread and the decoding can be a
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 false, 243 false,
239 &png_bytes->data())) { 244 &png_bytes->data())) {
240 png_reps.push_back( 245 png_reps.push_back(
241 gfx::ImagePNGRep(png_bytes, resized_image_skia_reps[i].scale())); 246 gfx::ImagePNGRep(png_bytes, resized_image_skia_reps[i].scale()));
242 } 247 }
243 } 248 }
244 249
245 return gfx::Image(png_reps); 250 return gfx::Image(png_reps);
246 } 251 }
247 252
253 favicon_base::FaviconRawBitmapResult ResizeFaviconBitmapResult(
254 const std::vector<favicon_base::FaviconRawBitmapResult>&
255 favicon_bitmap_results,
256 int desired_size_in_pixel) {
257 TRACE_EVENT0("browser", "FaviconUtil::ResizeFaviconBitmapResult");
258
259 if (favicon_bitmap_results.empty() || !favicon_bitmap_results[0].is_valid())
260 return favicon_base::FaviconRawBitmapResult();
261
262 favicon_base::FaviconRawBitmapResult bitmap_result =
263 favicon_bitmap_results[0];
264
265 // If the desired size is 0, SelectFaviconFrames() will return the largest
266 // bitmap without doing any resizing. As |favicon_bitmap_results| has bitmap
267 // data for a single bitmap, return it and avoid an unnecessary decode.
268 if (desired_size_in_pixel == 0)
269 return bitmap_result;
270
271 // If history bitmap is already desired pixel size, return early.
272 if (bitmap_result.pixel_size.width() == desired_size_in_pixel &&
273 bitmap_result.pixel_size.height() == desired_size_in_pixel)
274 return bitmap_result;
275
276 // Convert raw bytes to SkBitmap, resize via SelectFaviconFrames(), then
277 // convert back.
278 std::vector<float> desired_favicon_scales;
279 desired_favicon_scales.push_back(1.0f);
280
281 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
282 favicon_bitmap_results, desired_favicon_scales, desired_size_in_pixel);
283
284 std::vector<unsigned char> resized_bitmap_data;
285 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_image.AsBitmap(), false,
286 &resized_bitmap_data)) {
287 return favicon_base::FaviconRawBitmapResult();
288 }
289
290 bitmap_result.bitmap_data = base::RefCountedBytes::TakeVector(
291 &resized_bitmap_data);
292 bitmap_result.pixel_size =
293 gfx::Size(desired_size_in_pixel, desired_size_in_pixel);
294
295 return bitmap_result;
296 }
297
248 } // namespace favicon_base 298 } // namespace favicon_base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698