kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "components/exo/vsync_timing_manager.h" |
| 6 | |
| 7 | #include "base/stl_util.h" |
| 8 | #include "base/threading/thread_task_runner_handle.h" |
| 9 | |
| 10 | namespace exo { |
| 11 | |
| 12 | VSyncTimingManager::VSyncTimingManager(Delegate* delegate) |
| 13 | : delegate_(delegate) {} |
| 14 | |
| 15 | VSyncTimingManager::~VSyncTimingManager() = default; |
| 16 | |
| 17 | void VSyncTimingManager::AddObserver(Observer* obs) { |
| 18 | DCHECK(obs); |
| 19 | |
| 20 | // This is adding the first observer so start receiving IPCs. |
| 21 | if (observers_.empty()) |
| 22 | InitializeConnection(); |
| 23 | |
| 24 | observers_.push_back(obs); |
| 25 | } |
| 26 | |
| 27 | void VSyncTimingManager::RemoveObserver(Observer* obs) { |
| 28 | DCHECK(obs); |
| 29 | |
| 30 | base::Erase(observers_, obs); |
| 31 | |
| 32 | // There are no more observers so stop receiving IPCs. |
| 33 | if (observers_.empty()) |
Mario Sanchez Prada | 90d2f46 | 2019-10-28 20:36:35 | [diff] [blame] | 34 | receiver_.reset(); |
kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | void VSyncTimingManager::OnUpdateVSyncParameters(base::TimeTicks timebase, |
| 38 | base::TimeDelta interval) { |
| 39 | for (auto* observer : observers_) |
| 40 | observer->OnUpdateVSyncParameters(timebase, interval); |
| 41 | } |
| 42 | |
| 43 | void VSyncTimingManager::InitializeConnection() { |
Mario Sanchez Prada | 90d2f46 | 2019-10-28 20:36:35 | [diff] [blame] | 44 | mojo::PendingRemote<viz::mojom::VSyncParameterObserver> remote = |
| 45 | receiver_.BindNewPipeAndPassRemote(); |
kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 46 | |
Mario Sanchez Prada | 90d2f46 | 2019-10-28 20:36:35 | [diff] [blame] | 47 | // Unretained is safe because |this| owns |receiver_| and will outlive it. |
| 48 | receiver_.set_disconnect_handler(base::BindOnce( |
kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 49 | &VSyncTimingManager::OnConnectionError, base::Unretained(this))); |
| 50 | |
Mario Sanchez Prada | 90d2f46 | 2019-10-28 20:36:35 | [diff] [blame] | 51 | delegate_->AddVSyncParameterObserver(std::move(remote)); |
kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | void VSyncTimingManager::MaybeInitializeConnection() { |
| 55 | // The last observer might have been unregistered between when there was a |
| 56 | // connection error, in which case we don't need to reconnect. Alternatively, |
| 57 | // the last observer might have been unregistered and then a new observer |
| 58 | // registered, in which case we already reconnected. |
Mario Sanchez Prada | 90d2f46 | 2019-10-28 20:36:35 | [diff] [blame] | 59 | if (!observers_.empty() || receiver_.is_bound()) |
kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 60 | InitializeConnection(); |
| 61 | } |
| 62 | |
| 63 | void VSyncTimingManager::OnConnectionError() { |
Mario Sanchez Prada | 90d2f46 | 2019-10-28 20:36:35 | [diff] [blame] | 64 | receiver_.reset(); |
kylechar | 536117135 | 2019-04-26 18:23:12 | [diff] [blame] | 65 | |
| 66 | // Try to add a new observer after a short delay. If adding a new observer |
| 67 | // fails we'll retry again until successful. The delay avoids spamming |
| 68 | // retries. |
| 69 | base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 70 | FROM_HERE, |
| 71 | base::BindOnce(&VSyncTimingManager::MaybeInitializeConnection, |
| 72 | weak_ptr_factory_.GetWeakPtr()), |
| 73 | base::TimeDelta::FromMilliseconds(250)); |
| 74 | } |
| 75 | |
| 76 | } // namespace exo |