OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/wallpaper/wallpaper_color_calculator.h" | 5 #include "components/wallpaper/wallpaper_color_calculator.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "base/task_runner.h" | 12 #include "base/task_runner.h" |
13 #include "base/task_runner_util.h" | 13 #include "base/task_runner_util.h" |
14 #include "components/wallpaper/wallpaper_color_calculator_observer.h" | 14 #include "components/wallpaper/wallpaper_color_calculator_observer.h" |
| 15 #include "components/wallpaper/wallpaper_color_extraction_result.h" |
| 16 #include "ui/gfx/color_analysis.h" |
| 17 #include "ui/gfx/image/image_skia.h" |
| 18 |
| 19 using LumaRange = color_utils::LumaRange; |
| 20 using SaturationRange = color_utils::SaturationRange; |
15 | 21 |
16 namespace wallpaper { | 22 namespace wallpaper { |
17 | 23 |
18 namespace { | 24 namespace { |
19 | 25 |
20 // The largest image size, in pixels, to synchronously calculate the prominent | 26 // The largest image size, in pixels, to synchronously calculate the prominent |
21 // color. This is a simple heuristic optimization because extraction on images | 27 // color. This is a simple heuristic optimization because extraction on images |
22 // smaller than this should run very quickly, and offloading the task to another | 28 // smaller than this should run very quickly, and offloading the task to another |
23 // thread would actually take longer. | 29 // thread would actually take longer. |
24 const int kMaxPixelsForSynchronousCalculation = 100; | 30 const int kMaxPixelsForSynchronousCalculation = 100; |
25 | 31 |
26 // Wrapper for color_utils::CalculateProminentColorOfBitmap() that records | 32 // Wrapper for color_utils::CalculateProminentColorsOfBitmap() that records |
27 // wallpaper specific metrics. | 33 // wallpaper specific metrics. |
28 // | 34 // |
29 // NOTE: |image| is intentionally a copy to ensure it exists for the duration of | 35 // NOTE: |image| is intentionally a copy to ensure it exists for the duration of |
30 // the calculation. | 36 // the calculation. |
31 SkColor CalculateWallpaperColor(const gfx::ImageSkia image, | 37 std::vector<SkColor> CalculateWallpaperColor( |
32 color_utils::LumaRange luma, | 38 const gfx::ImageSkia image, |
33 color_utils::SaturationRange saturation) { | 39 const std::vector<color_utils::ColorProfile> color_profiles) { |
34 base::TimeTicks start_time = base::TimeTicks::Now(); | 40 base::TimeTicks start_time = base::TimeTicks::Now(); |
35 const SkColor prominent_color = color_utils::CalculateProminentColorOfBitmap( | 41 const std::vector<SkColor> prominent_colors = |
36 *image.bitmap(), luma, saturation); | 42 color_utils::CalculateProminentColorsOfBitmap(*image.bitmap(), |
| 43 color_profiles); |
37 | 44 |
38 UMA_HISTOGRAM_TIMES("Ash.Wallpaper.ColorExtraction.Durations", | 45 UMA_HISTOGRAM_TIMES("Ash.Wallpaper.ColorExtraction.Durations", |
39 base::TimeTicks::Now() - start_time); | 46 base::TimeTicks::Now() - start_time); |
40 UMA_HISTOGRAM_BOOLEAN("Ash.Wallpaper.ColorExtractionResult", | 47 WallpaperColorExtractionResult result = NUM_COLOR_EXTRACTION_RESULTS; |
41 prominent_color != SK_ColorTRANSPARENT); | 48 for (size_t i = 0; i < color_profiles.size(); ++i) { |
| 49 bool is_result_transparent = prominent_colors[i] == SK_ColorTRANSPARENT; |
| 50 if (color_profiles[i].saturation == SaturationRange::VIBRANT) { |
| 51 switch (color_profiles[i].luma) { |
| 52 case LumaRange::DARK: |
| 53 result = is_result_transparent ? RESULT_DARK_VIBRANT_TRANSPARENT |
| 54 : RESULT_DARK_VIBRANT_OPAQUE; |
| 55 break; |
| 56 case LumaRange::NORMAL: |
| 57 result = is_result_transparent ? RESULT_NORMAL_VIBRANT_TRANSPARENT |
| 58 : RESULT_NORMAL_VIBRANT_OPAQUE; |
| 59 break; |
| 60 case LumaRange::LIGHT: |
| 61 result = is_result_transparent ? RESULT_LIGHT_VIBRANT_TRANSPARENT |
| 62 : RESULT_LIGHT_VIBRANT_OPAQUE; |
| 63 break; |
| 64 } |
| 65 } else { |
| 66 switch (color_profiles[i].luma) { |
| 67 case LumaRange::DARK: |
| 68 result = is_result_transparent ? RESULT_DARK_MUTED_TRANSPARENT |
| 69 : RESULT_DARK_MUTED_OPAQUE; |
| 70 break; |
| 71 case LumaRange::NORMAL: |
| 72 result = is_result_transparent ? RESULT_NORMAL_MUTED_TRANSPARENT |
| 73 : RESULT_NORMAL_MUTED_OPAQUE; |
| 74 break; |
| 75 case LumaRange::LIGHT: |
| 76 result = is_result_transparent ? RESULT_LIGHT_MUTED_TRANSPARENT |
| 77 : RESULT_LIGHT_MUTED_OPAQUE; |
| 78 break; |
| 79 } |
| 80 } |
| 81 } |
| 82 DCHECK_NE(NUM_COLOR_EXTRACTION_RESULTS, result); |
| 83 UMA_HISTOGRAM_ENUMERATION("Ash.Wallpaper.ColorExtractionResult2", result, |
| 84 NUM_COLOR_EXTRACTION_RESULTS); |
42 | 85 |
43 return prominent_color; | 86 return prominent_colors; |
44 } | 87 } |
45 | 88 |
46 bool ShouldCalculateSync(const gfx::ImageSkia& image) { | 89 bool ShouldCalculateSync(const gfx::ImageSkia& image) { |
47 return image.width() * image.height() <= kMaxPixelsForSynchronousCalculation; | 90 return image.width() * image.height() <= kMaxPixelsForSynchronousCalculation; |
48 } | 91 } |
49 | 92 |
50 } // namespace | 93 } // namespace |
51 | 94 |
52 WallpaperColorCalculator::WallpaperColorCalculator( | 95 WallpaperColorCalculator::WallpaperColorCalculator( |
53 const gfx::ImageSkia& image, | 96 const gfx::ImageSkia& image, |
54 color_utils::LumaRange luma, | 97 const std::vector<color_utils::ColorProfile>& color_profiles, |
55 color_utils::SaturationRange saturation, | |
56 scoped_refptr<base::TaskRunner> task_runner) | 98 scoped_refptr<base::TaskRunner> task_runner) |
57 : image_(image), | 99 : image_(image), |
58 luma_(luma), | 100 color_profiles_(color_profiles), |
59 saturation_(saturation), | |
60 task_runner_(std::move(task_runner)), | 101 task_runner_(std::move(task_runner)), |
61 weak_ptr_factory_(this) {} | 102 weak_ptr_factory_(this) { |
| 103 prominent_colors_ = |
| 104 std::vector<SkColor>(color_profiles_.size(), SK_ColorTRANSPARENT); |
| 105 } |
62 | 106 |
63 WallpaperColorCalculator::~WallpaperColorCalculator() {} | 107 WallpaperColorCalculator::~WallpaperColorCalculator() = default; |
64 | 108 |
65 void WallpaperColorCalculator::AddObserver( | 109 void WallpaperColorCalculator::AddObserver( |
66 WallpaperColorCalculatorObserver* observer) { | 110 WallpaperColorCalculatorObserver* observer) { |
67 observers_.AddObserver(observer); | 111 observers_.AddObserver(observer); |
68 } | 112 } |
69 | 113 |
70 void WallpaperColorCalculator::RemoveObserver( | 114 void WallpaperColorCalculator::RemoveObserver( |
71 WallpaperColorCalculatorObserver* observer) { | 115 WallpaperColorCalculatorObserver* observer) { |
72 observers_.RemoveObserver(observer); | 116 observers_.RemoveObserver(observer); |
73 } | 117 } |
74 | 118 |
75 bool WallpaperColorCalculator::StartCalculation() { | 119 bool WallpaperColorCalculator::StartCalculation() { |
76 if (ShouldCalculateSync(image_)) { | 120 if (ShouldCalculateSync(image_)) { |
77 const SkColor prominent_color = | 121 const std::vector<SkColor> prominent_colors = |
78 CalculateWallpaperColor(image_, luma_, saturation_); | 122 CalculateWallpaperColor(image_, color_profiles_); |
79 NotifyCalculationComplete(prominent_color); | 123 NotifyCalculationComplete(prominent_colors); |
80 return true; | 124 return true; |
81 } | 125 } |
82 | 126 |
83 image_.MakeThreadSafe(); | 127 image_.MakeThreadSafe(); |
84 if (base::PostTaskAndReplyWithResult( | 128 if (base::PostTaskAndReplyWithResult( |
85 task_runner_.get(), FROM_HERE, | 129 task_runner_.get(), FROM_HERE, |
86 base::Bind(&CalculateWallpaperColor, image_, luma_, saturation_), | 130 base::Bind(&CalculateWallpaperColor, image_, color_profiles_), |
87 base::Bind(&WallpaperColorCalculator::OnAsyncCalculationComplete, | 131 base::Bind(&WallpaperColorCalculator::OnAsyncCalculationComplete, |
88 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()))) { | 132 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()))) { |
89 return true; | 133 return true; |
90 } | 134 } |
91 | 135 |
92 LOG(WARNING) << "PostSequencedWorkerTask failed. " | 136 LOG(WARNING) << "PostSequencedWorkerTask failed. " |
93 << "Wallpaper promiment color may not be calculated."; | 137 << "Wallpaper prominent colors may not be calculated."; |
94 | 138 |
95 prominent_color_ = SK_ColorTRANSPARENT; | 139 prominent_colors_ = |
| 140 std::vector<SkColor>(color_profiles_.size(), SK_ColorTRANSPARENT); |
96 return false; | 141 return false; |
97 } | 142 } |
98 | 143 |
99 void WallpaperColorCalculator::SetTaskRunnerForTest( | 144 void WallpaperColorCalculator::SetTaskRunnerForTest( |
100 scoped_refptr<base::TaskRunner> task_runner) { | 145 scoped_refptr<base::TaskRunner> task_runner) { |
101 task_runner_ = task_runner; | 146 task_runner_ = task_runner; |
102 } | 147 } |
103 | 148 |
104 void WallpaperColorCalculator::OnAsyncCalculationComplete( | 149 void WallpaperColorCalculator::OnAsyncCalculationComplete( |
105 base::TimeTicks async_start_time, | 150 base::TimeTicks async_start_time, |
106 SkColor prominent_color) { | 151 const std::vector<SkColor>& prominent_colors) { |
107 UMA_HISTOGRAM_TIMES("Ash.Wallpaper.ColorExtraction.UserDelay", | 152 UMA_HISTOGRAM_TIMES("Ash.Wallpaper.ColorExtraction.UserDelay", |
108 base::TimeTicks::Now() - async_start_time); | 153 base::TimeTicks::Now() - async_start_time); |
109 NotifyCalculationComplete(prominent_color); | 154 NotifyCalculationComplete(prominent_colors); |
110 } | 155 } |
111 | 156 |
112 void WallpaperColorCalculator::NotifyCalculationComplete( | 157 void WallpaperColorCalculator::NotifyCalculationComplete( |
113 SkColor prominent_color) { | 158 const std::vector<SkColor>& prominent_colors) { |
114 prominent_color_ = prominent_color; | 159 prominent_colors_ = prominent_colors; |
115 for (auto& observer : observers_) | 160 for (auto& observer : observers_) |
116 observer.OnColorCalculationComplete(); | 161 observer.OnColorCalculationComplete(); |
117 | 162 |
118 // This could be deleted! | 163 // This could be deleted! |
119 } | 164 } |
120 | 165 |
121 } // namespace wallpaper | 166 } // namespace wallpaper |
OLD | NEW |