1 /* 2 * Copyright (c) 2024 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 #ifndef RENDER_SERVICE_CLIENT_CORE_UI_RS_UI_DISPLAY_SOLOIST_H 16 #define RENDER_SERVICE_CLIENT_CORE_UI_RS_UI_DISPLAY_SOLOIST_H 17 18 #include <atomic> 19 #include <functional> 20 #include <mutex> 21 22 #include "command/rs_animation_command.h" 23 #include "common/rs_common_def.h" 24 #include "feature/hyper_graphic_manager/rs_frame_rate_linker.h" 25 #include "transaction/rs_interfaces.h" 26 #include "vsync_receiver.h" 27 28 namespace OHOS { 29 namespace Rosen { 30 31 using SoloistIdType = uint32_t; 32 using TimestampType = int64_t; 33 using DisplaySoloistOnFrameCallback = std::function<void(long long, long long, void*)>; 34 35 const std::string TIME_OUT_TASK = "vsync_time_out_task_"; 36 constexpr int64_t TIME_OUT_MILLISECONDS = 600; 37 static const std::vector<int32_t> REFRESH_RATE_LIST{ 90, 120, 144 }; 38 static std::vector<int32_t> REFRESH_RATE_FACTORS; 39 static std::unordered_map<int32_t, std::vector<int32_t>> RATE_TO_FACTORS; 40 static std::once_flag COMPUTE_FACTORS_FLAG; 41 constexpr float SECOND_IN_NANO = 1000000000.0f; 42 constexpr int32_t FRAME_RATE_0 = 0; 43 constexpr int32_t SOLOIST_ERROR = -1; 44 constexpr int32_t EXEC_SUCCESS = 0; 45 46 enum class ActiveStatus : int32_t { 47 INACTIVE = 0, 48 ACTIVE = 1, 49 NEED_REMOVE = 2, 50 }; 51 52 class RSC_EXPORT SoloistId { 53 public: 54 SoloistId(); 55 ~SoloistId(); 56 57 SoloistIdType GetId() const; 58 static std::shared_ptr<SoloistId> Create(); 59 private: 60 static SoloistIdType GenerateId(); 61 const SoloistIdType id_; 62 }; 63 64 class RSC_EXPORT RSDisplaySoloist { 65 public: 66 RSDisplaySoloist() = default; 67 RSDisplaySoloist(SoloistIdType instanceId); ~RSDisplaySoloist()68 ~RSDisplaySoloist() 69 { 70 std::lock_guard<std::mutex> lock(mtx_); 71 destroyed_ = true; 72 } 73 74 bool JudgeWhetherSkip(TimestampType timestamp); 75 void RequestNextVSync(); 76 void SetSubFrameRateLinkerEnable(bool enabled); 77 void TriggerCallback(); 78 void SetCallback(DisplaySoloistOnFrameCallback cb, void* params); 79 static void OnVsync(TimestampType timestamp, void* client); 80 void VsyncCallbackInner(TimestampType timestamp); 81 82 enum ActiveStatus subStatus_ = ActiveStatus::INACTIVE; 83 bool useExclusiveThread_ = false; 84 FrameRateRange frameRateRange_; 85 private: 86 void Init(); 87 bool IsCommonDivisor(int32_t expectedRate, int32_t vsyncRate); 88 std::vector<int32_t> FindRefreshRateFactors(int32_t refreshRate); 89 void FindAllRefreshRateFactors(); 90 int32_t FindMatchedRefreshRate(int32_t vsyncRate, int32_t targetRate); 91 int32_t FindAccurateRefreshRate(int32_t approximateRate); 92 int32_t SearchMatchedRate(const FrameRateRange& frameRateRange, int32_t vsyncRate, 93 int32_t iterCount = 1); 94 95 void FlushFrameRate(int32_t rate); 96 int64_t GetVSyncPeriod(); 97 bool SetVSyncRate(int32_t vsyncRate); 98 int32_t GetVSyncRate(); 99 100 std::shared_ptr<AppExecFwk::EventHandler> subVsyncHandler_ = nullptr; 101 std::shared_ptr<OHOS::Rosen::VSyncReceiver> subReceiver_ = nullptr; 102 VSyncReceiver::FrameCallback subFrameCallback_ = { 103 .userData_ = this, 104 .callback_ = OnVsync, 105 }; 106 #ifdef RS_ENABLE_GPU 107 bool hasInitVsyncReceiver_ = false; 108 #endif 109 110 int32_t sourceVsyncRate_ = 0; 111 int32_t drawFPS_ = 0; 112 int32_t currRate_ = 0; 113 int32_t currCnt_ = 0; 114 TimestampType timestamp_ = 0; 115 TimestampType targetTimestamp_ = 0; 116 117 SoloistIdType instanceId_ = 0; 118 std::shared_ptr<RSFrameRateLinker> frameRateLinker_; 119 120 void OnVsyncTimeOut(); 121 std::mutex mtx_; 122 bool hasRequestedVsync_ = false; 123 bool destroyed_ = false; 124 std::string vsyncTimeoutTaskName_ = ""; 125 #ifdef RS_ENABLE_GPU 126 AppExecFwk::EventHandler::Callback vsyncTimeoutCallback_ = 127 [this] { this->OnVsyncTimeOut(); }; 128 #endif 129 130 std::mutex callbackMutex_; 131 std::pair<DisplaySoloistOnFrameCallback, void*> callback_; 132 }; 133 134 using IdToSoloistMapType = std::unordered_map<SoloistIdType, std::shared_ptr<RSDisplaySoloist>>; 135 136 class RSC_EXPORT RSDisplaySoloistManager { 137 public: 138 static RSDisplaySoloistManager& GetInstance() noexcept; 139 void RequestNextVSync(); 140 141 void Start(SoloistIdType id); 142 void Stop(SoloistIdType id); 143 144 void InsertOnVsyncCallback(SoloistIdType id, DisplaySoloistOnFrameCallback cb, void* data); 145 void InsertFrameRateRange(SoloistIdType id, FrameRateRange frameRateRange); 146 void InsertUseExclusiveThreadFlag(SoloistIdType id, bool useExclusiveThread); 147 void RemoveSoloist(SoloistIdType id); 148 149 void FlushFrameRate(int32_t rate); 150 void SetMainFrameRateLinkerEnable(bool enabled); 151 152 FrameRateRange GetFrameRateRange(); 153 IdToSoloistMapType GetIdToSoloistMap(); 154 std::shared_ptr<RSFrameRateLinker> GetFrameRateLinker(); 155 enum ActiveStatus GetManagerStatus(); 156 157 int64_t GetVSyncPeriod() const; 158 bool SetVSyncRate(int32_t vsyncRate); 159 int32_t GetVSyncRate() const; 160 161 private: 162 RSDisplaySoloistManager() = default; 163 ~RSDisplaySoloistManager() noexcept; 164 RSDisplaySoloistManager(const RSDisplaySoloistManager&) = delete; 165 RSDisplaySoloistManager(const RSDisplaySoloistManager&&) = delete; 166 RSDisplaySoloistManager& operator=(const RSDisplaySoloistManager&) = delete; 167 RSDisplaySoloistManager& operator=(const RSDisplaySoloistManager&&) = delete; 168 void InitVsyncReceiver(); 169 170 std::shared_ptr<AppExecFwk::EventHandler> vsyncHandler_ = nullptr; 171 std::shared_ptr<OHOS::Rosen::VSyncReceiver> receiver_ = nullptr; 172 static void OnVsync(TimestampType timestamp, void* client); 173 void VsyncCallbackInner(TimestampType timestamp); 174 void DispatchSoloistCallback(TimestampType timestamp); 175 VSyncReceiver::FrameCallback managerFrameCallback_ = { 176 .userData_ = this, 177 .callback_ = OnVsync, 178 }; 179 180 enum ActiveStatus managerStatus_ = ActiveStatus::INACTIVE; 181 int32_t sourceVsyncRate_ = 0; 182 183 FrameRateRange frameRateRange_; 184 std::shared_ptr<RSFrameRateLinker> frameRateLinker_; 185 IdToSoloistMapType idToSoloistMap_; 186 187 void OnVsyncTimeOut(); 188 std::mutex mtx_; 189 std::mutex dataUpdateMtx_; 190 std::string vsyncTimeoutTaskName_ = "soloist_manager_time_out_task"; 191 #ifdef RS_ENABLE_GPU 192 AppExecFwk::EventHandler::Callback vsyncTimeoutCallback_ = 193 [this] { this->OnVsyncTimeOut(); }; 194 #endif 195 }; 196 197 } // namespace Rosen 198 } // namespace OHOS 199 200 #endif // RENDER_SERVICE_CLIENT_CORE_UI_RS_UI_DISPLAY_SOLOIST_H 201