1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 17 #ifndef VSYNC_VSYNC_DISTRIBUTOR_H 18 #define VSYNC_VSYNC_DISTRIBUTOR_H 19 20 #include <refbase.h> 21 22 #include <mutex> 23 #include <vector> 24 #include <thread> 25 #include <condition_variable> 26 27 #include "local_socketpair.h" 28 #include "vsync_controller.h" 29 #include "vsync_connection_stub.h" 30 31 #include "vsync_system_ability_listener.h" 32 33 #if defined(RS_ENABLE_DVSYNC) 34 #include "dvsync.h" 35 #endif 36 37 namespace OHOS { 38 namespace Rosen { 39 class VSyncDistributor; 40 struct ConnectionInfo { 41 std::string name_; 42 uint64_t postVSyncCount_; ConnectionInfoConnectionInfo43 ConnectionInfo(std::string name): postVSyncCount_(0) 44 { 45 this->name_ = name; 46 } 47 }; 48 typedef void (*GCNotifyTask)(bool); 49 50 class VSyncConnection : public VSyncConnectionStub { 51 public: 52 // id for LTPO, windowNodeId for vsync rate control 53 VSyncConnection(const sptr<VSyncDistributor>& distributor, std::string name, 54 const sptr<IRemoteObject>& token = nullptr, uint64_t id = 0, uint64_t windowNodeId = 0); 55 ~VSyncConnection(); 56 57 virtual VsyncError RequestNextVSync() override; 58 virtual VsyncError RequestNextVSync(const std::string &fromWhom, int64_t lastVSyncTS) override; 59 virtual VsyncError GetReceiveFd(int32_t &fd) override; 60 virtual VsyncError SetVSyncRate(int32_t rate) override; 61 virtual VsyncError Destroy() override; 62 virtual VsyncError SetUiDvsyncSwitch(bool vsyncSwitch) override; 63 virtual VsyncError SetUiDvsyncConfig(int32_t bufferCount) override; 64 int32_t PostEvent(int64_t now, int64_t period, int64_t vsyncCount); SetGCNotifyTask(GCNotifyTask hook)65 inline void SetGCNotifyTask(GCNotifyTask hook) 66 { 67 gcNotifyTask_ = hook; 68 } 69 70 int32_t rate_; // used for LTPS 71 int32_t highPriorityRate_ = -1; 72 bool highPriorityState_ = false; 73 ConnectionInfo info_; 74 bool triggerThisTime_ = false; // used for LTPO 75 uint64_t id_ = 0; 76 uint64_t windowNodeId_ = 0; 77 uint32_t vsyncPulseFreq_ = 1; 78 int64_t referencePulseCount_ = 0; 79 uint32_t refreshRate_ = 0; 80 int32_t proxyPid_; 81 bool rnvTrigger_ = false; 82 private: 83 VsyncError CleanAllLocked(); 84 class VSyncConnectionDeathRecipient : public IRemoteObject::DeathRecipient { 85 public: 86 explicit VSyncConnectionDeathRecipient(wptr<VSyncConnection> conn); 87 virtual ~VSyncConnectionDeathRecipient() = default; 88 89 void OnRemoteDied(const wptr<IRemoteObject>& token) override; 90 91 private: 92 wptr<VSyncConnection> conn_; 93 }; 94 GCNotifyTask gcNotifyTask_ = nullptr; 95 sptr<VSyncConnectionDeathRecipient> vsyncConnDeathRecipient_ = nullptr; 96 sptr<IRemoteObject> token_ = nullptr; 97 // Circular reference, need check 98 wptr<VSyncDistributor> distributor_; 99 sptr<LocalSocketPair> socketPair_; 100 bool isDead_; 101 std::mutex mutex_; 102 bool isFirstRequestVsync_ = true; 103 bool isFirstSendVsync_ = true; 104 }; 105 106 class VSyncDistributor : public RefBase, public VSyncController::Callback { 107 public: 108 109 VSyncDistributor(sptr<VSyncController> controller, std::string name); 110 ~VSyncDistributor(); 111 // nocopyable 112 VSyncDistributor(const VSyncDistributor &) = delete; 113 VSyncDistributor &operator=(const VSyncDistributor &) = delete; 114 115 VsyncError AddConnection(const sptr<VSyncConnection>& connection, uint64_t windowNodeId = 0); 116 VsyncError RemoveConnection(const sptr<VSyncConnection> &connection); 117 118 // fromWhom indicates whether the source is animate or non-animate 119 // lastVSyncTS indicates last vsync time, 0 when non-animate 120 VsyncError RequestNextVSync(const sptr<VSyncConnection> &connection, const std::string &fromWhom = "unknown", 121 int64_t lastVSyncTS = 0); 122 VsyncError SetVSyncRate(int32_t rate, const sptr<VSyncConnection>& connection); 123 VsyncError SetHighPriorityVSyncRate(int32_t highPriorityRate, const sptr<VSyncConnection>& connection); 124 VsyncError SetQosVSyncRate(uint64_t windowNodeId, int32_t rate, bool isSystemAnimateScene = false); 125 126 // used by DVSync 127 bool IsDVsyncOn(); 128 void SetFrameIsRender(bool isRender); 129 void MarkRSAnimate(); 130 void UnmarkRSAnimate(); 131 bool HasPendingUIRNV(); 132 uint32_t GetRefreshRate(); 133 void RecordVsyncModeChange(uint32_t refreshRate, int64_t period); 134 bool IsUiDvsyncOn(); 135 VsyncError SetUiDvsyncSwitch(bool dvsyncSwitch, const sptr<VSyncConnection>& connection); 136 VsyncError SetUiDvsyncConfig(int32_t bufferCount); 137 int64_t GetUiCommandDelayTime(); 138 void UpdatePendingReferenceTime(int64_t &timeStamp); 139 void SetHardwareTaskNum(uint32_t num); 140 141 private: 142 143 // check, add more info 144 struct VSyncEvent { 145 int64_t timestamp; 146 int64_t vsyncCount; // used for LTPS 147 int64_t period; 148 int64_t vsyncPulseCount; // used for LTPO 149 uint32_t refreshRate; 150 }; 151 void ThreadMain(); 152 void EnableVSync(); 153 void DisableVSync(); 154 void OnVSyncEvent(int64_t now, int64_t period, uint32_t refreshRate, VSyncMode vsyncMode); 155 void CollectConnections(bool &waitForVSync, int64_t timestamp, 156 std::vector<sptr<VSyncConnection>> &conns, int64_t vsyncCount, bool isDvsyncThread = false); 157 VsyncError QosGetPidByName(const std::string& name, uint32_t& pid); 158 constexpr pid_t ExtractPid(uint64_t id); 159 void PostVSyncEvent(const std::vector<sptr<VSyncConnection>> &conns, int64_t timestamp, bool isDvsyncThread); 160 void ChangeConnsRateLocked(); 161 void CollectConnectionsLTPO(bool &waitForVSync, int64_t timestamp, 162 std::vector<sptr<VSyncConnection>> &conns, int64_t vsyncCount, bool isDvsyncThread = false); 163 /* std::pair<id, refresh rate> */ 164 void OnConnsRefreshRateChanged(const std::vector<std::pair<uint64_t, uint32_t>> &refreshRates); 165 VsyncError SetQosVSyncRateByPid(uint32_t pid, int32_t rate, bool isSystemAnimateScene = false); 166 167 #ifdef COMPOSER_SCHED_ENABLE 168 void SubScribeSystemAbility(const std::string& threadName); 169 #endif 170 void WaitForVsyncOrRequest(std::unique_lock<std::mutex> &locker); 171 void WaitForVsyncOrTimeOut(std::unique_lock<std::mutex> &locker); 172 void CollectConns(bool &waitForVSync, int64_t ×tamp, 173 std::vector<sptr<VSyncConnection>> &conns, bool isDvsyncThread); 174 bool PostVSyncEventPreProcess(int64_t ×tamp, std::vector<sptr<VSyncConnection>> &conns); 175 void CheckNeedDisableDvsync(int64_t now, int64_t period); 176 void OnVSyncTrigger(int64_t now, int64_t period, uint32_t refreshRate, VSyncMode vsyncMode); 177 178 sptr<VSyncSystemAbilityListener> saStatusChangeListener_ = nullptr; 179 std::thread threadLoop_; 180 sptr<VSyncController> controller_; 181 std::mutex mutex_; 182 std::condition_variable con_; 183 std::vector<sptr<VSyncConnection> > connections_; 184 std::map<uint64_t, std::vector<sptr<VSyncConnection>>> connectionsMap_; 185 VSyncEvent event_; 186 bool vsyncEnabled_; 187 std::string name_; 188 bool vsyncThreadRunning_ = false; 189 std::vector<std::pair<uint64_t, uint32_t>> changingConnsRefreshRates_; // std::pair<id, refresh rate> 190 VSyncMode vsyncMode_ = VSYNC_MODE_LTPS; // default LTPS 191 std::mutex changingConnsRefreshRatesMtx_; 192 uint32_t generatorRefreshRate_ = 0; 193 std::unordered_map<int32_t, int32_t> connectionCounter_; 194 uint32_t countTraceValue_ = 0; 195 #if defined(RS_ENABLE_DVSYNC) 196 int32_t GetUIDVsyncPid(); 197 void SendConnectionsToVSyncWindow(int64_t now, int64_t period, uint32_t refreshRate, VSyncMode vsyncMode, 198 std::unique_lock<std::mutex> &locker); 199 void OnDVSyncTrigger(int64_t now, int64_t period, uint32_t refreshRate, VSyncMode vsyncMode); 200 sptr<DVsync> dvsync_ = nullptr; 201 bool pendingRNVInVsync_ = false; // for vsync switch to dvsync 202 std::atomic<int64_t> lastDVsyncTS_ = 0; // for dvsync switch to vsync 203 #endif 204 bool isRs_ = false; 205 std::atomic<bool> hasVsync_ = false; 206 }; 207 } // namespace Rosen 208 } // namespace OHOS 209 210 #endif 211