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

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: Refactoring: extract Session inner class. 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
« no previous file with comments | « components/favicon/core/large_icon_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
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
16 LargeIconService::LargeIconService(FaviconService* favicon_service) 31 LargeIconService::LargeIconService(FaviconService* favicon_service)
17 : favicon_service_(favicon_service) { 32 : favicon_service_(favicon_service) {
18 large_icon_types_.push_back(favicon_base::IconType::FAVICON); 33 large_icon_types_.push_back(favicon_base::IconType::FAVICON);
19 large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON); 34 large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
20 large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON); 35 large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
21 } 36 }
22 37
23 LargeIconService::~LargeIconService() { 38 LargeIconService::~LargeIconService() {
24 } 39 }
25 40
41 // Main entry point, runs on the UI thread.
beaudoin 2015/05/05 19:44:40 NIT: must run on the UI thread. That comment shoul
huangs 2015/05/05 20:07:23 Done.
26 base::CancelableTaskTracker::TaskId 42 base::CancelableTaskTracker::TaskId
27 LargeIconService::GetLargeIconOrFallbackStyle( 43 LargeIconService::GetLargeIconOrFallbackStyle(
28 const GURL& page_url, 44 const GURL& page_url,
29 int desired_size_in_pixel, 45 int desired_size_in_pixel,
30 const favicon_base::LargeIconCallback& callback, 46 const favicon_base::LargeIconCallback& callback,
31 base::CancelableTaskTracker* tracker) { 47 base::CancelableTaskTracker* tracker) {
48 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
beaudoin 2015/05/05 19:44:40 This is typically a DCHECK in Chrome, any reason t
huangs 2015/05/05 20:07:23 Because I'm testing with release build. Changed t
49 scoped_refptr<LargeIconService::Session> session =
50 new LargeIconService::Session();
51 session->desired_size_in_pixel = desired_size_in_pixel;
52 session->callback = callback;
53 session->tracker = tracker;
54
32 // TODO(beaudoin): For now this is just a wrapper around 55 // TODO(beaudoin): For now this is just a wrapper around
33 // GetLargestRawFaviconForPageURL. Add the logic required to select the best 56 // GetLargestRawFaviconForPageURL. Add the logic required to select the best
34 // possible large icon. Also add logic to fetch-on-demand when the URL of 57 // 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. 58 // a large icon is known but its bitmap is not available.
36 return favicon_service_->GetLargestRawFaviconForPageURL( 59 return favicon_service_->GetLargestRawFaviconForPageURL(
37 page_url, 60 page_url,
38 large_icon_types_, 61 large_icon_types_,
39 desired_size_in_pixel, 62 desired_size_in_pixel,
40 base::Bind(&LargeIconService::RunLargeIconCallback, 63 base::Bind(&LargeIconService::OnIconLookupComplete,
41 base::Unretained(this), callback, desired_size_in_pixel), 64 base::Unretained(this),
65 session),
42 tracker); 66 tracker);
43 } 67 }
44 68
69 // static
70 // Resizes |bitmap_result| to |desired_size_in_pixel|x|desired_size_in_pixel|.
71 // Stores the resized bitmap data in |resized_bitmap_result| and returns true
72 // if successful. This runs on a background thread.
beaudoin 2015/05/05 19:44:40 The method comment should be in the .h, except //
huangs 2015/05/05 20:07:23 I briefly made this local, forgot to remove when I
45 bool LargeIconService::ResizeLargeIconIfValid( 73 bool LargeIconService::ResizeLargeIconIfValid(
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) {
77 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
beaudoin 2015/05/05 19:44:40 DCHECK?
huangs 2015/05/05 20:07:23 Done.
49 // Require bitmap to be valid and square. 78 // Require bitmap to be valid and square.
50 if (!bitmap_result.is_valid() || 79 if (!bitmap_result.is_valid() ||
51 bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height()) 80 bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height())
52 return false; 81 return false;
53 82
54 // Require bitmap to be large enough. It's square, so just check width. 83 // Require bitmap to be large enough. It's square, so just check width.
55 if (bitmap_result.pixel_size.width() < desired_size_in_pixel) { 84 if (bitmap_result.pixel_size.width() < desired_size_in_pixel) {
56 // TODO(beaudoin): Potentially relax this, and allow icon to be scaled up. 85 // TODO(beaudoin): Potentially relax this, and allow icon to be scaled up.
57 return false; 86 return false;
58 } 87 }
59 88
60 *resized_bitmap_result = bitmap_result; 89 *resized_bitmap_result = bitmap_result;
61
62 // Special case: Can use |resized_bitmap_result| as is. 90 // Special case: Can use |resized_bitmap_result| as is.
63 if (bitmap_result.pixel_size.width() == desired_size_in_pixel) 91 if (bitmap_result.pixel_size.width() == desired_size_in_pixel)
64 return true; 92 return true;
65 93
66 // Resize bitmap: decode PNG, resize, and re-encode PNG. 94 // Resize bitmap: decode PNG, resize, and re-encode PNG.
67 SkBitmap decoded_bitmap; 95 SkBitmap decoded_bitmap;
68 if (!gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), 96 if (!gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
69 bitmap_result.bitmap_data->size(), &decoded_bitmap)) 97 bitmap_result.bitmap_data->size(), &decoded_bitmap))
70 return false; 98 return false;
71 99
72 SkBitmap resized_bitmap = skia::ImageOperations::Resize( 100 SkBitmap resized_bitmap = skia::ImageOperations::Resize(
73 decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, 101 decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
74 desired_size_in_pixel, desired_size_in_pixel); 102 desired_size_in_pixel, desired_size_in_pixel);
75 103
76 std::vector<unsigned char> bitmap_data; 104 std::vector<unsigned char> bitmap_data;
77 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data)) 105 if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data))
78 return false; 106 return false;
79 107
80 resized_bitmap_result->pixel_size = 108 resized_bitmap_result->pixel_size =
81 gfx::Size(desired_size_in_pixel, desired_size_in_pixel); 109 gfx::Size(desired_size_in_pixel, desired_size_in_pixel);
82 resized_bitmap_result->bitmap_data = 110 resized_bitmap_result->bitmap_data =
83 base::RefCountedBytes::TakeVector(&bitmap_data); 111 base::RefCountedBytes::TakeVector(&bitmap_data);
84 return true; 112 return true;
85 } 113 }
86 114
87 void LargeIconService::RunLargeIconCallback( 115 // Runs on the UI thread.
88 const favicon_base::LargeIconCallback& callback, 116 void LargeIconService::OnIconLookupComplete(
89 int desired_size_in_pixel, 117 scoped_refptr<LargeIconService::Session> session,
90 const favicon_base::FaviconRawBitmapResult& bitmap_result) { 118 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
119 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
120 session->bitmap_result = bitmap_result;
121 session->tracker->PostTask(
122 GetBackgroundTaskRunner().get(),
123 FROM_HERE,
124 base::Bind(&LargeIconService::ProcessIconOnBackgroundThread,
125 base::Unretained(this),
126 session));
127 }
128
129 // Runs on a background thread.
130 void LargeIconService::ProcessIconOnBackgroundThread(
131 scoped_refptr<LargeIconService::Session> session) {
132 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
91 favicon_base::FaviconRawBitmapResult resized_bitmap_result; 133 favicon_base::FaviconRawBitmapResult resized_bitmap_result;
92 if (ResizeLargeIconIfValid(desired_size_in_pixel, bitmap_result, 134 if (ResizeLargeIconIfValid(session->desired_size_in_pixel,
93 &resized_bitmap_result)) { 135 session->bitmap_result, &resized_bitmap_result)) {
beaudoin 2015/05/05 19:44:40 Indentation looks wrong.
huangs 2015/05/05 20:07:23 Ran "git cl format", let's see how this changes th
94 callback.Run(favicon_base::LargeIconResult(resized_bitmap_result)); 136 session->result.reset(
95 return; 137 new favicon_base::LargeIconResult(resized_bitmap_result));
138 } else {
139 // Failed to resize |bitmap_result|, so compute fallback icon style.
140 scoped_ptr<favicon_base::FallbackIconStyle> fallback_icon_style(
141 new favicon_base::FallbackIconStyle());
142 if (session->bitmap_result.is_valid()) {
143 favicon_base::SetDominantColorAsBackground(
144 session->bitmap_result.bitmap_data, fallback_icon_style.get());
145 }
146 session->result.reset(
147 new favicon_base::LargeIconResult(fallback_icon_style.release()));
96 } 148 }
97 149
98 // Failed to resize |bitmap_result|, so compute fallback icon style. 150 content::BrowserThread::PostTask(
99 favicon_base::LargeIconResult result(new favicon_base::FallbackIconStyle()); 151 content::BrowserThread::UI,
100 if (bitmap_result.is_valid()) { 152 FROM_HERE,
101 favicon_base::SetDominantColorAsBackground( 153 base::Bind(&LargeIconService::OnIconProcessingComplete,
102 bitmap_result.bitmap_data, result.fallback_icon_style.get()); 154 base::Unretained(this),
103 } 155 session));
beaudoin 2015/05/05 19:44:40 Would it be possible to skip the intermediate func
huangs 2015/05/05 20:07:23 Yes but I think it's cleaner this way.
104 callback.Run(result); 156 }
157
158 // Runs on the UI thread.
159 void LargeIconService::OnIconProcessingComplete(
160 scoped_refptr<LargeIconService::Session> session) {
161 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
162 session->callback.Run(*session->result);
105 } 163 }
106 164
107 } // namespace favicon 165 } // namespace favicon
OLDNEW
« no previous file with comments | « 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