• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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