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

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

Issue 1122103003: [Large Icon Service] Move icon resizing into worker thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make Session a class; make using callback chain functions static. Created 5 years, 7 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 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 "components/favicon/core/large_icon_service.h" 5 #include "components/favicon/core/large_icon_service.h"
6 6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/task_runner.h"
10 #include "base/threading/sequenced_worker_pool.h"
7 #include "components/favicon/core/favicon_service.h" 11 #include "components/favicon/core/favicon_service.h"
8 #include "components/favicon_base/fallback_icon_style.h" 12 #include "components/favicon_base/fallback_icon_style.h"
9 #include "components/favicon_base/favicon_types.h" 13 #include "content/public/browser/browser_thread.h"
10 #include "skia/ext/image_operations.h" 14 #include "skia/ext/image_operations.h"
11 #include "ui/gfx/codec/png_codec.h" 15 #include "ui/gfx/codec/png_codec.h"
12 #include "ui/gfx/geometry/size.h" 16 #include "ui/gfx/geometry/size.h"
13 17
18 namespace {
19
20 // Return a TaskRunner used to execute background task.
pkotwicz 2015/05/07 14:52:14 Nit: "Return TaskRunner" (no "a")
huangs 2015/05/07 21:01:58 Done, also using "Returns".
21 scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() {
22 return content::BrowserThread::GetBlockingPool()
23 ->GetTaskRunnerWithShutdownBehavior(
24 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
25 }
26
27 } // namespace
28
14 namespace favicon { 29 namespace favicon {
15 30
31 LargeIconService::Session::Session()
32 : desired_size_in_pixel(0),
33 tracker(nullptr) {
34 }
35
36 LargeIconService::Session::~Session() {
37 }
38
16 LargeIconService::LargeIconService(FaviconService* favicon_service) 39 LargeIconService::LargeIconService(FaviconService* favicon_service)
17 : favicon_service_(favicon_service) { 40 : favicon_service_(favicon_service) {
18 large_icon_types_.push_back(favicon_base::IconType::FAVICON); 41 large_icon_types_.push_back(favicon_base::IconType::FAVICON);
19 large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON); 42 large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
20 large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON); 43 large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
21 } 44 }
22 45
23 LargeIconService::~LargeIconService() { 46 LargeIconService::~LargeIconService() {
24 } 47 }
25 48
26 base::CancelableTaskTracker::TaskId 49 base::CancelableTaskTracker::TaskId
27 LargeIconService::GetLargeIconOrFallbackStyle( 50 LargeIconService::GetLargeIconOrFallbackStyle(
28 const GURL& page_url, 51 const GURL& page_url,
29 int desired_size_in_pixel, 52 int desired_size_in_pixel,
30 const favicon_base::LargeIconCallback& callback, 53 const favicon_base::LargeIconCallback& callback,
31 base::CancelableTaskTracker* tracker) { 54 base::CancelableTaskTracker* tracker) {
55 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
56 scoped_refptr<LargeIconService::Session> session =
57 new LargeIconService::Session();
58 session->desired_size_in_pixel = desired_size_in_pixel;
59 session->callback = callback;
60 session->tracker = tracker;
61
32 // TODO(beaudoin): For now this is just a wrapper around 62 // TODO(beaudoin): For now this is just a wrapper around
33 // GetLargestRawFaviconForPageURL. Add the logic required to select the best 63 // GetLargestRawFaviconForPageURL. Add the logic required to select the best
34 // possible large icon. Also add logic to fetch-on-demand when the URL of 64 // possible large icon. Also add logic to fetch-on-demand when the URL of
35 // a large icon is known but its bitmap is not available. 65 // a large icon is known but its bitmap is not available.
36 return favicon_service_->GetLargestRawFaviconForPageURL( 66 return favicon_service_->GetLargestRawFaviconForPageURL(
37 page_url, 67 page_url, large_icon_types_, desired_size_in_pixel,
38 large_icon_types_, 68 base::Bind(&LargeIconService::OnIconLookupComplete, session),
39 desired_size_in_pixel,
40 base::Bind(&LargeIconService::RunLargeIconCallback,
41 base::Unretained(this), callback, desired_size_in_pixel),
42 tracker); 69 tracker);
43 } 70 }
44 71
72 // static
45 bool LargeIconService::ResizeLargeIconIfValid( 73 bool LargeIconService::ResizeLargeIconIfValid(
pkotwicz 2015/05/07 14:52:14 Can you please add the "OnBackgroundThread" suffix
huangs 2015/05/07 21:01:58 Done, but "IfValid" wins as suffix.
46 int desired_size_in_pixel, 74 int desired_size_in_pixel,
47 const favicon_base::FaviconRawBitmapResult& bitmap_result, 75 const favicon_base::FaviconRawBitmapResult& bitmap_result,
48 favicon_base::FaviconRawBitmapResult* resized_bitmap_result) { 76 favicon_base::FaviconRawBitmapResult* resized_bitmap_result) {
49 // Require bitmap to be valid and square. 77 // Require bitmap to be valid and square.
50 if (!bitmap_result.is_valid() || 78 if (!bitmap_result.is_valid() ||
51 bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height()) 79 bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height())
52 return false; 80 return false;
53 81
54 // Require bitmap to be large enough. It's square, so just check width. 82 // Require bitmap to be large enough. It's square, so just check width.
55 if (bitmap_result.pixel_size.width() < desired_size_in_pixel) { 83 if (bitmap_result.pixel_size.width() < desired_size_in_pixel) {
56 // TODO(beaudoin): Potentially relax this, and allow icon to be scaled up. 84 // TODO(beaudoin): Potentially relax this, and allow icon to be scaled up.
57 return false; 85 return false;
58 } 86 }
59 87
60 *resized_bitmap_result = bitmap_result; 88 *resized_bitmap_result = bitmap_result;
61
62 // Special case: Can use |resized_bitmap_result| as is. 89 // Special case: Can use |resized_bitmap_result| as is.
63 if (bitmap_result.pixel_size.width() == desired_size_in_pixel) 90 if (bitmap_result.pixel_size.width() == desired_size_in_pixel)
64 return true; 91 return true;
65 92
66 // Resize bitmap: decode PNG, resize, and re-encode PNG. 93 // Resize bitmap: decode PNG, resize, and re-encode PNG.
67 SkBitmap decoded_bitmap; 94 SkBitmap decoded_bitmap;
68 if (!gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), 95 if (!gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
69 bitmap_result.bitmap_data->size(), &decoded_bitmap)) 96 bitmap_result.bitmap_data->size(), &decoded_bitmap))
70 return false; 97 return false;
71 98
72 SkBitmap resized_bitmap = skia::ImageOperations::Resize( 99 SkBitmap resized_bitmap = skia::ImageOperations::Resize(
73 decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, 100 decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
74 desired_size_in_pixel, desired_size_in_pixel); 101 desired_size_in_pixel, desired_size_in_pixel);
75 102
76 std::vector<unsigned char> bitmap_data; 103 std::vector<unsigned char> bitmap_data;
77 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data)) 104 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data))
78 return false; 105 return false;
79 106
80 resized_bitmap_result->pixel_size = 107 resized_bitmap_result->pixel_size =
81 gfx::Size(desired_size_in_pixel, desired_size_in_pixel); 108 gfx::Size(desired_size_in_pixel, desired_size_in_pixel);
82 resized_bitmap_result->bitmap_data = 109 resized_bitmap_result->bitmap_data =
83 base::RefCountedBytes::TakeVector(&bitmap_data); 110 base::RefCountedBytes::TakeVector(&bitmap_data);
84 return true; 111 return true;
85 } 112 }
86 113
87 void LargeIconService::RunLargeIconCallback( 114 // static
88 const favicon_base::LargeIconCallback& callback, 115 void LargeIconService::OnIconLookupComplete(
89 int desired_size_in_pixel, 116 scoped_refptr<LargeIconService::Session> session,
90 const favicon_base::FaviconRawBitmapResult& bitmap_result) { 117 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
118 session->bitmap_result = bitmap_result;
119 session->tracker->PostTask(
120 GetBackgroundTaskRunner().get(), FROM_HERE,
121 base::Bind(&LargeIconService::ProcessIconOnBackgroundThread, session));
122 }
123
124 // static
125 void LargeIconService::ProcessIconOnBackgroundThread(
126 scoped_refptr<LargeIconService::Session> session) {
127 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
91 favicon_base::FaviconRawBitmapResult resized_bitmap_result; 128 favicon_base::FaviconRawBitmapResult resized_bitmap_result;
92 if (ResizeLargeIconIfValid(desired_size_in_pixel, bitmap_result, 129 if (ResizeLargeIconIfValid(session->desired_size_in_pixel,
93 &resized_bitmap_result)) { 130 session->bitmap_result, &resized_bitmap_result)) {
94 callback.Run(favicon_base::LargeIconResult(resized_bitmap_result)); 131 session->result.reset(
95 return; 132 new favicon_base::LargeIconResult(resized_bitmap_result));
133 } else {
134 // Failed to resize |bitmap_result|, so compute fallback icon style.
135 scoped_ptr<favicon_base::FallbackIconStyle> fallback_icon_style(
136 new favicon_base::FallbackIconStyle());
137 if (session->bitmap_result.is_valid()) {
138 favicon_base::SetDominantColorAsBackground(
139 session->bitmap_result.bitmap_data, fallback_icon_style.get());
140 }
141 session->result.reset(
142 new favicon_base::LargeIconResult(fallback_icon_style.release()));
96 } 143 }
97 144
98 // Failed to resize |bitmap_result|, so compute fallback icon style. 145 content::BrowserThread::PostTask(
99 favicon_base::LargeIconResult result(new favicon_base::FallbackIconStyle()); 146 content::BrowserThread::UI, FROM_HERE,
100 if (bitmap_result.is_valid()) { 147 base::Bind(&LargeIconService::OnIconProcessingComplete, session));
pkotwicz 2015/05/07 14:52:14 Is there a reason that you pass the session object
huangs 2015/05/07 21:01:58 Using session->callback and session->result. And
101 favicon_base::SetDominantColorAsBackground( 148 }
102 bitmap_result.bitmap_data, result.fallback_icon_style.get()); 149
103 } 150 // static
104 callback.Run(result); 151 void LargeIconService::OnIconProcessingComplete(
152 scoped_refptr<LargeIconService::Session> session) {
153 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
154 session->callback.Run(*session->result);
105 } 155 }
106 156
107 } // namespace favicon 157 } // namespace favicon
OLDNEW
« components/favicon/core/large_icon_service.h ('K') | « components/favicon/core/large_icon_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698