 Chromium Code Reviews
 Chromium Code Reviews Issue 2870073002:
  [Sensors] Decouple sensor readings update from rAF  (Closed)
    
  
    Issue 2870073002:
  [Sensors] Decouple sensor readings update from rAF  (Closed) 
  | Index: third_party/WebKit/Source/modules/sensor/Sensor.cpp | 
| diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp | 
| index 7581a9ea08c7715856e5d5ca6e19d2d35f460ec9..0a741555db8aae4a05300be94dc322a0bedef35c 100644 | 
| --- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp | 
| +++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp | 
| @@ -18,6 +18,13 @@ using namespace device::mojom::blink; | 
| namespace blink { | 
| +namespace { | 
| + | 
| +constexpr double kMinWaitingInterval = | 
| + 1 / device::mojom::blink::SensorConfiguration::kMaxAllowedFrequency; | 
| + | 
| +} // namespace | 
| + | 
| Sensor::Sensor(ExecutionContext* execution_context, | 
| const SensorOptions& sensor_options, | 
| ExceptionState& exception_state, | 
| @@ -26,7 +33,8 @@ Sensor::Sensor(ExecutionContext* execution_context, | 
| sensor_options_(sensor_options), | 
| type_(type), | 
| state_(SensorState::kIdle), | 
| - last_update_timestamp_(0.0) { | 
| + last_update_timestamp_(0.0), | 
| + pending_reading_update_(false) { | 
| // Check secure context. | 
| String error_message; | 
| if (!execution_context->IsSecureContext(error_message)) { | 
| @@ -89,7 +97,7 @@ DOMHighResTimeStamp Sensor::timestamp(ScriptState* script_state, | 
| is_null = false; | 
| return performance->MonotonicTimeToDOMHighResTimeStamp( | 
| - sensor_proxy_->Reading().timestamp); | 
| + sensor_proxy_->reading().timestamp); | 
| } | 
| DEFINE_TRACE(Sensor) { | 
| @@ -133,7 +141,7 @@ double Sensor::ReadingValue(int index, bool& is_null) const { | 
| double Sensor::ReadingValueUnchecked(int index) const { | 
| DCHECK(sensor_proxy_); | 
| DCHECK(index >= 0 && index < device::SensorReading::kValuesCount); | 
| - return sensor_proxy_->Reading().values[index]; | 
| + return sensor_proxy_->reading().values[index]; | 
| } | 
| void Sensor::InitSensorProxyIfNeeded() { | 
| @@ -162,16 +170,35 @@ void Sensor::OnSensorInitialized() { | 
| RequestAddConfiguration(); | 
| } | 
| -void Sensor::NotifySensorChanged(double timestamp) { | 
| +void Sensor::OnSensorReadingChanged(double timestamp) { | 
| if (state_ != Sensor::SensorState::kActivated) | 
| return; | 
| - DCHECK_GT(configuration_->frequency, 0.0); | 
| - double period = 1 / configuration_->frequency; | 
| + // Return if reading update is already scheduled or the cached | 
| + // reading is up-to-date. | 
| + if (pending_reading_update_ || | 
| + sensor_proxy_->reading().timestamp == reading_.timestamp) | 
| + return; | 
| + | 
| + pending_reading_update_ = true; | 
| + | 
| + double elapsedTime = timestamp - last_update_timestamp_; | 
| - if (timestamp - last_update_timestamp_ >= period) { | 
| - last_update_timestamp_ = timestamp; | 
| - NotifySensorReadingChanged(); | 
| + DCHECK_GT(configuration_->frequency, 0.0); | 
| + double waitingTime = 1 / configuration_->frequency - elapsedTime; | 
| + | 
| + // Negative or zero 'waitingTime' means that polling period has elapsed. | 
| + // We also avoid scheduling if the elapsed time is slightly behind the | 
| + // polling period. | 
| + auto sensor_reading_changed = | 
| + WTF::Bind(&Sensor::UpdateReading, WrapWeakPersistent(this)); | 
| + if (waitingTime < kMinWaitingInterval) { | 
| + TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) | 
| + ->PostTask(BLINK_FROM_HERE, std::move(sensor_reading_changed)); | 
| 
Reilly Grant (use Gerrit)
2017/05/10 14:53:28
Why not call UpdateReading directly here?
 
Mikhail
2017/05/11 10:46:20
It would synchronously invoke JS callbacks that mi
 
Reilly Grant (use Gerrit)
2017/05/11 18:28:12
Can you add a comment explaining that here? I wish
 
Mikhail
2017/05/12 08:42:13
Done.
 | 
| + } else { | 
| + TaskRunnerHelper::Get(TaskType::kSensor, GetExecutionContext()) | 
| + ->PostDelayedTask(BLINK_FROM_HERE, std::move(sensor_reading_changed), | 
| + waitingTime * 1000); | 
| } | 
| } | 
| @@ -273,13 +300,11 @@ void Sensor::HandleError(ExceptionCode code, | 
| } | 
| } | 
| -void Sensor::NotifySensorReadingChanged() { | 
| - DCHECK(sensor_proxy_); | 
| - | 
| - if (sensor_proxy_->Reading().timestamp != stored_data_.timestamp) { | 
| - stored_data_ = sensor_proxy_->Reading(); | 
| - DispatchEvent(Event::Create(EventTypeNames::change)); | 
| - } | 
| +void Sensor::UpdateReading() { | 
| + last_update_timestamp_ = WTF::MonotonicallyIncreasingTime(); | 
| + reading_ = sensor_proxy_->reading(); | 
| + pending_reading_update_ = false; | 
| + DispatchEvent(Event::Create(EventTypeNames::change)); | 
| } | 
| void Sensor::NotifyOnActivate() { | 
| @@ -295,7 +320,7 @@ bool Sensor::CanReturnReadings() const { | 
| if (!IsActivated()) | 
| return false; | 
| DCHECK(sensor_proxy_); | 
| - return sensor_proxy_->Reading().timestamp != 0.0; | 
| + return sensor_proxy_->reading().timestamp != 0.0; | 
| } | 
| } // namespace blink |