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 "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(SoloistIdType instanceId);
~RSDisplaySoloist()67     ~RSDisplaySoloist()
68     {
69         std::lock_guard<std::mutex> lock(mtx_);
70         destroyed_ = true;
71     }
72 
73     void Init();
74     bool JudgeWhetherSkip(TimestampType timestamp);
75     void RequestNextVSync();
76 
77     void FlushFrameRate(int32_t rate);
78     void SetSubFrameRateLinkerEnable(bool enabled);
79 
80     int64_t GetVSyncPeriod();
81     bool SetVSyncRate(int32_t vsyncRate);
82     int32_t GetVSyncRate();
83 
84     RSDisplaySoloist() = default;
85 
86     bool IsCommonDivisor(int32_t expectedRate, int32_t vsyncRate);
87     std::vector<int32_t> FindRefreshRateFactors(int32_t refreshRate);
88     void FindAllRefreshRateFactors();
89     int32_t FindMatchedRefreshRate(int32_t vsyncRate, int32_t targetRate);
90     int32_t FindAccurateRefreshRate(int32_t approximateRate);
91     int32_t SearchMatchedRate(const FrameRateRange& frameRateRange, int32_t vsyncRate,
92                               int32_t iterCount = 1);
93 
94     std::shared_ptr<AppExecFwk::EventHandler> subVsyncHandler_ = nullptr;
95     std::shared_ptr<OHOS::Rosen::VSyncReceiver> subReceiver_ = nullptr;
96     std::pair<DisplaySoloistOnFrameCallback, void*> callback_;
97     static void OnVsync(TimestampType timestamp, void* client);
98     void VsyncCallbackInner(TimestampType timestamp);
99     VSyncReceiver::FrameCallback subFrameCallback_ = {
100         .userData_ = this,
101         .callback_ = OnVsync,
102     };
103     enum ActiveStatus subStatus_ = ActiveStatus::INACTIVE;
104     bool hasInitVsyncReceiver_ = false;
105 
106     int32_t sourceVsyncRate_ = 0;
107     int32_t drawFPS_ = 0;
108     int32_t currRate_ = 0;
109     int32_t currCnt_ = 0;
110     TimestampType timestamp_ = 0;
111     TimestampType targetTimestamp_ = 0;
112 
113     SoloistIdType instanceId_ = 0;
114     bool useExclusiveThread_ = false;
115     FrameRateRange frameRateRange_;
116     std::shared_ptr<RSFrameRateLinker> frameRateLinker_;
117 
118     void OnVsyncTimeOut();
119     std::mutex mtx_;
120     bool hasRequestedVsync_ = false;
121     bool destroyed_ = false;
122     std::string vsyncTimeoutTaskName_ = "";
123     AppExecFwk::EventHandler::Callback vsyncTimeoutCallback_ =
124         [this] { this->OnVsyncTimeOut(); };
125 };
126 
127 using IdToSoloistMapType = std::unordered_map<SoloistIdType, std::shared_ptr<RSDisplaySoloist>>;
128 
129 class RSC_EXPORT RSDisplaySoloistManager {
130 public:
131     static RSDisplaySoloistManager& GetInstance() noexcept;
132     bool InitVsyncReceiver();
133     void RequestNextVSync();
134 
135     void Start(SoloistIdType id);
136     void Stop(SoloistIdType id);
137 
138     void InsertOnVsyncCallback(SoloistIdType id, DisplaySoloistOnFrameCallback cb, void* data);
139     void InsertFrameRateRange(SoloistIdType id, FrameRateRange frameRateRange);
140     void InsertUseExclusiveThreadFlag(SoloistIdType id, bool useExclusiveThread);
141     void RemoveSoloist(SoloistIdType id);
142 
143     void FlushFrameRate(int32_t rate);
144     void SetMainFrameRateLinkerEnable(bool enabled);
145 
146     FrameRateRange GetFrameRateRange();
147     IdToSoloistMapType GetIdToSoloistMap();
148     std::shared_ptr<RSFrameRateLinker> GetFrameRateLinker();
149     enum ActiveStatus GetManagerStatus();
150 
151     int64_t GetVSyncPeriod() const;
152     bool SetVSyncRate(int32_t vsyncRate);
153     int32_t GetVSyncRate() const;
154 
155 private:
156     RSDisplaySoloistManager() = default;
157     ~RSDisplaySoloistManager() noexcept;
158     RSDisplaySoloistManager(const RSDisplaySoloistManager&) = delete;
159     RSDisplaySoloistManager(const RSDisplaySoloistManager&&) = delete;
160     RSDisplaySoloistManager& operator=(const RSDisplaySoloistManager&) = delete;
161     RSDisplaySoloistManager& operator=(const RSDisplaySoloistManager&&) = delete;
162 
163     std::shared_ptr<AppExecFwk::EventHandler> vsyncHandler_ = nullptr;
164     std::shared_ptr<OHOS::Rosen::VSyncReceiver> receiver_ = nullptr;
165     static void OnVsync(TimestampType timestamp, void* client);
166     void VsyncCallbackInner(TimestampType timestamp);
167     void DispatchSoloistCallback(TimestampType timestamp);
168     VSyncReceiver::FrameCallback managerFrameCallback_ = {
169         .userData_ = this,
170         .callback_ = OnVsync,
171     };
172 
173     enum ActiveStatus managerStatus_ = ActiveStatus::INACTIVE;
174     bool hasInitVsyncReceiver_ = false;
175     int32_t sourceVsyncRate_ = 0;
176 
177     FrameRateRange frameRateRange_;
178     std::shared_ptr<RSFrameRateLinker> frameRateLinker_;
179     IdToSoloistMapType idToSoloistMap_;
180 
181     void OnVsyncTimeOut();
182     std::mutex mtx_;
183     std::mutex dataUpdateMtx_;
184     std::string vsyncTimeoutTaskName_ = "soloist_manager_time_out_task";
185     AppExecFwk::EventHandler::Callback vsyncTimeoutCallback_ =
186         [this] { this->OnVsyncTimeOut(); };
187 };
188 
189 } // namespace Rosen
190 } // namespace OHOS
191 
192 #endif // RENDER_SERVICE_CLIENT_CORE_UI_RS_UI_DISPLAY_SOLOIST_H
193