OLD | NEW |
---|---|
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 "content/renderer/pepper/plugin_instance_throttler_impl.h" | 5 #include "content/renderer/pepper/plugin_instance_throttler_impl.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/time/time.h" | 8 #include "base/time/time.h" |
9 #include "content/public/common/content_constants.h" | 9 #include "content/public/common/content_constants.h" |
10 #include "content/public/renderer/render_thread.h" | 10 #include "content/public/renderer/render_thread.h" |
11 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 11 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
12 #include "content/renderer/pepper/pepper_webplugin_impl.h" | |
13 #include "content/renderer/render_frame_impl.h" | 12 #include "content/renderer/render_frame_impl.h" |
14 #include "ppapi/shared_impl/ppapi_constants.h" | 13 #include "ppapi/shared_impl/ppapi_constants.h" |
15 #include "ppapi/shared_impl/scoped_pp_var.h" | 14 #include "ppapi/shared_impl/scoped_pp_var.h" |
16 #include "ppapi/shared_impl/var.h" | 15 #include "ppapi/shared_impl/var.h" |
17 #include "third_party/WebKit/public/platform/WebRect.h" | 16 #include "third_party/WebKit/public/platform/WebRect.h" |
18 #include "third_party/WebKit/public/web/WebInputEvent.h" | 17 #include "third_party/WebKit/public/web/WebInputEvent.h" |
19 #include "third_party/WebKit/public/web/WebPluginParams.h" | 18 #include "third_party/WebKit/public/web/WebPluginParams.h" |
20 #include "ui/gfx/color_utils.h" | 19 #include "ui/gfx/color_utils.h" |
21 #include "url/gurl.h" | 20 #include "url/gurl.h" |
22 | 21 |
23 namespace content { | 22 namespace content { |
24 | 23 |
25 namespace { | 24 namespace { |
26 | 25 |
27 // Threshold for 'boring' score to accept a frame as good enough to be a | 26 // Threshold for 'boring' score to accept a frame as good enough to be a |
28 // representative keyframe. Units are the ratio of all pixels that are within | 27 // representative keyframe. Units are the ratio of all pixels that are within |
29 // the most common luma bin. The same threshold is used for history thumbnails. | 28 // the most common luma bin. The same threshold is used for history thumbnails. |
30 const double kAcceptableFrameMaximumBoringness = 0.94; | 29 const double kAcceptableFrameMaximumBoringness = 0.94; |
31 | 30 |
32 const int kMinimumConsecutiveInterestingFrames = 4; | 31 const int kMinimumConsecutiveInterestingFrames = 4; |
33 | 32 |
34 // When plugin audio is throttled, the plugin will sometimes stop generating | 33 // When plugin audio is throttled, the plugin will sometimes stop generating |
35 // video frames. We use this timeout to prevent waiting forever for a good | 34 // video frames. We use this timeout to prevent waiting forever for a good |
36 // poster image. Chosen arbitrarily. | 35 // poster image. Chosen arbitrarily. |
37 const int kAudioThrottledFrameTimeoutMilliseconds = 500; | 36 const int kAudioThrottledFrameTimeoutMilliseconds = 500; |
38 | 37 |
38 class PowerSaverTestPluginDelegate : public PluginInstanceThrottler::Observer { | |
39 public: | |
40 explicit PowerSaverTestPluginDelegate( | |
41 const PluginInstanceThrottlerImpl* throttler) | |
42 : throttler_(throttler) {} | |
43 | |
44 virtual ~PowerSaverTestPluginDelegate() {} | |
45 | |
46 private: | |
47 void OnThrottleStateChange() override { | |
48 if (throttler_->GetWebPlugin() && throttler_->GetWebPlugin()->instance()) { | |
49 throttler_->GetWebPlugin()->instance()->HandleMessage(ppapi::ScopedPPVar( | |
50 ppapi::ScopedPPVar::PassRef(), | |
51 ppapi::StringVar::StringToPPVar("throttleStatusChange"))); | |
52 } | |
53 } | |
54 | |
55 void OnPeripheralStateChange() override { | |
56 if (throttler_->GetWebPlugin() && throttler_->GetWebPlugin()->instance()) { | |
57 throttler_->GetWebPlugin()->instance()->HandleMessage(ppapi::ScopedPPVar( | |
58 ppapi::ScopedPPVar::PassRef(), | |
59 ppapi::StringVar::StringToPPVar("peripheralStatusChange"))); | |
60 } | |
61 } | |
62 | |
63 void OnThrottlerDestroyed() override { delete this; } | |
64 | |
65 // Non-owning pointer. | |
66 const PluginInstanceThrottlerImpl* const throttler_; | |
67 }; | |
68 | |
39 } // namespace | 69 } // namespace |
40 | 70 |
41 // static | 71 // static |
42 const int PluginInstanceThrottlerImpl::kMaximumFramesToExamine = 150; | 72 const int PluginInstanceThrottlerImpl::kMaximumFramesToExamine = 150; |
43 | 73 |
44 // static | 74 // static |
45 scoped_ptr<PluginInstanceThrottler> PluginInstanceThrottler::Create() { | 75 scoped_ptr<PluginInstanceThrottler> PluginInstanceThrottler::Create() { |
46 return make_scoped_ptr(new PluginInstanceThrottlerImpl); | 76 return make_scoped_ptr(new PluginInstanceThrottlerImpl); |
47 } | 77 } |
48 | 78 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 | 124 |
95 void PluginInstanceThrottlerImpl::MarkPluginEssential( | 125 void PluginInstanceThrottlerImpl::MarkPluginEssential( |
96 PowerSaverUnthrottleMethod method) { | 126 PowerSaverUnthrottleMethod method) { |
97 if (state_ == THROTTLER_STATE_MARKED_ESSENTIAL) | 127 if (state_ == THROTTLER_STATE_MARKED_ESSENTIAL) |
98 return; | 128 return; |
99 | 129 |
100 bool was_throttled = IsThrottled(); | 130 bool was_throttled = IsThrottled(); |
101 state_ = THROTTLER_STATE_MARKED_ESSENTIAL; | 131 state_ = THROTTLER_STATE_MARKED_ESSENTIAL; |
102 RecordUnthrottleMethodMetric(method); | 132 RecordUnthrottleMethodMetric(method); |
103 | 133 |
134 FOR_EACH_OBSERVER(Observer, observer_list_, OnPeripheralStateChange()); | |
135 | |
104 if (was_throttled) | 136 if (was_throttled) |
105 FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); | 137 FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); |
106 | |
107 // Notify the Power Saver test plugin of a peripheral status change. | |
108 if (web_plugin_ && web_plugin_->instance() && | |
109 plugin_module_name_ == ppapi::kPowerSaverTestPluginName) { | |
110 web_plugin_->instance()->HandleMessage(ppapi::ScopedPPVar( | |
111 ppapi::ScopedPPVar::PassRef(), | |
112 ppapi::StringVar::StringToPPVar("peripheralStatusChange"))); | |
113 } | |
114 } | 138 } |
115 | 139 |
116 void PluginInstanceThrottlerImpl::SetHiddenForPlaceholder(bool hidden) { | 140 void PluginInstanceThrottlerImpl::SetHiddenForPlaceholder(bool hidden) { |
117 is_hidden_for_placeholder_ = hidden; | 141 is_hidden_for_placeholder_ = hidden; |
118 FOR_EACH_OBSERVER(Observer, observer_list_, OnHiddenForPlaceholder(hidden)); | 142 FOR_EACH_OBSERVER(Observer, observer_list_, OnHiddenForPlaceholder(hidden)); |
119 } | 143 } |
120 | 144 |
121 blink::WebPlugin* PluginInstanceThrottlerImpl::GetWebPlugin() const { | 145 PepperWebPluginImpl* PluginInstanceThrottlerImpl::GetWebPlugin() const { |
122 DCHECK(web_plugin_); | 146 DCHECK(web_plugin_); |
123 return web_plugin_; | 147 return web_plugin_; |
124 } | 148 } |
125 | 149 |
126 const gfx::Size& PluginInstanceThrottlerImpl::GetSize() const { | 150 const gfx::Size& PluginInstanceThrottlerImpl::GetSize() const { |
127 return unobscured_size_; | 151 return unobscured_size_; |
128 } | 152 } |
129 | 153 |
130 void PluginInstanceThrottlerImpl::NotifyAudioThrottled() { | 154 void PluginInstanceThrottlerImpl::NotifyAudioThrottled() { |
131 audio_throttled_ = true; | 155 audio_throttled_ = true; |
132 audio_throttled_frame_timeout_.Reset(); | 156 audio_throttled_frame_timeout_.Reset(); |
133 } | 157 } |
134 | 158 |
135 void PluginInstanceThrottlerImpl::SetWebPlugin( | 159 void PluginInstanceThrottlerImpl::SetWebPlugin( |
136 PepperWebPluginImpl* web_plugin) { | 160 PepperWebPluginImpl* web_plugin) { |
137 DCHECK(!web_plugin_); | 161 DCHECK(!web_plugin_); |
138 web_plugin_ = web_plugin; | 162 web_plugin_ = web_plugin; |
139 } | 163 } |
140 | 164 |
141 void PluginInstanceThrottlerImpl::Initialize( | 165 void PluginInstanceThrottlerImpl::Initialize( |
142 RenderFrameImpl* frame, | 166 RenderFrameImpl* frame, |
143 const GURL& content_origin, | 167 const GURL& content_origin, |
144 const std::string& plugin_module_name, | 168 const std::string& plugin_module_name, |
145 const gfx::Size& unobscured_size) { | 169 const gfx::Size& unobscured_size) { |
146 plugin_module_name_ = plugin_module_name; | |
147 unobscured_size_ = unobscured_size; | 170 unobscured_size_ = unobscured_size; |
148 | 171 |
149 // |frame| may be nullptr in tests. | 172 // |frame| may be nullptr in tests. |
150 if (frame) { | 173 if (frame) { |
151 PluginPowerSaverHelper* helper = frame->plugin_power_saver_helper(); | 174 PluginPowerSaverHelper* helper = frame->plugin_power_saver_helper(); |
152 bool cross_origin_main_content = false; | 175 bool cross_origin_main_content = false; |
153 if (!helper->ShouldThrottleContent(content_origin, plugin_module_name, | 176 if (!helper->ShouldThrottleContent(content_origin, plugin_module_name, |
154 unobscured_size.width(), | 177 unobscured_size.width(), |
155 unobscured_size.height(), | 178 unobscured_size.height(), |
156 &cross_origin_main_content)) { | 179 &cross_origin_main_content)) { |
157 state_ = THROTTLER_STATE_MARKED_ESSENTIAL; | 180 state_ = THROTTLER_STATE_MARKED_ESSENTIAL; |
158 | 181 |
159 if (cross_origin_main_content) | 182 if (cross_origin_main_content) |
160 helper->WhitelistContentOrigin(content_origin); | 183 helper->WhitelistContentOrigin(content_origin); |
161 | 184 |
162 return; | 185 return; |
163 } | 186 } |
164 | 187 |
188 if (plugin_module_name == ppapi::kPowerSaverTestPluginName) { | |
189 // Delegate manages its own lifetime. | |
190 new PowerSaverTestPluginDelegate(this); | |
191 } | |
raymes
2015/04/30 00:42:07
It still feels a bit nasty to have the observer ad
tommycli
2015/04/30 01:27:10
That's a good idea. Will do that!
| |
192 | |
165 // To collect UMAs, register peripheral content even if power saver mode | 193 // To collect UMAs, register peripheral content even if power saver mode |
166 // is disabled. | 194 // is disabled. |
167 helper->RegisterPeripheralPlugin( | 195 helper->RegisterPeripheralPlugin( |
168 content_origin, | 196 content_origin, |
169 base::Bind(&PluginInstanceThrottlerImpl::MarkPluginEssential, | 197 base::Bind(&PluginInstanceThrottlerImpl::MarkPluginEssential, |
170 weak_factory_.GetWeakPtr(), UNTHROTTLE_METHOD_BY_WHITELIST)); | 198 weak_factory_.GetWeakPtr(), UNTHROTTLE_METHOD_BY_WHITELIST)); |
171 } | 199 } |
172 } | 200 } |
173 | 201 |
174 void PluginInstanceThrottlerImpl::OnImageFlush(const SkBitmap* bitmap) { | 202 void PluginInstanceThrottlerImpl::OnImageFlush(const SkBitmap* bitmap) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 | 254 |
227 // Release our reference to the underlying pixel data. | 255 // Release our reference to the underlying pixel data. |
228 last_received_frame_.reset(); | 256 last_received_frame_.reset(); |
229 } | 257 } |
230 | 258 |
231 state_ = THROTTLER_STATE_PLUGIN_THROTTLED; | 259 state_ = THROTTLER_STATE_PLUGIN_THROTTLED; |
232 FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); | 260 FOR_EACH_OBSERVER(Observer, observer_list_, OnThrottleStateChange()); |
233 } | 261 } |
234 | 262 |
235 } // namespace content | 263 } // namespace content |
OLD | NEW |