1 /*
2  * Copyright (c) 2021-2023 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 #ifndef VSYNC_VSYNC_RECEIVER_H
17 #define VSYNC_VSYNC_RECEIVER_H
18 
19 #include <refbase.h>
20 #include "ivsync_connection.h"
21 #include "file_descriptor_listener.h"
22 
23 #include <atomic>
24 #include <functional>
25 #include <memory>
26 #include <mutex>
27 #include <stdint.h>
28 #include <string>
29 #include <vector>
30 
31 namespace OHOS {
32 namespace Rosen {
33 class VSyncCallBackListener : public OHOS::AppExecFwk::FileDescriptorListener {
34 public:
35     using VSyncCallback = std::function<void(int64_t, void*)>;
36     using VSyncCallbackWithId = std::function<void(int64_t, int64_t, void*)>;
37     struct FrameCallback {
38         void *userData_;
39         VSyncCallback callback_;
40         VSyncCallbackWithId callbackWithId_;
41     };
VSyncCallBackListener()42     VSyncCallBackListener()
43         : vsyncCallbacks_(nullptr), vsyncCallbacksWithId_(nullptr), userData_(nullptr)
44     {}
45 
~VSyncCallBackListener()46     ~VSyncCallBackListener()
47     {
48     }
SetCallback(FrameCallback cb)49     void SetCallback(FrameCallback cb)
50     {
51         std::lock_guard<std::mutex> locker(mtx_);
52         userData_ = cb.userData_;
53         vsyncCallbacks_ = cb.callback_;
54         vsyncCallbacksWithId_ = cb.callbackWithId_;
55     }
SetName(std::string &name)56     void SetName(std::string &name)
57     {
58         std::lock_guard<std::mutex> locker(mtx_);
59         name_ = name;
60     }
SetRNVFlag(bool RNVFlag)61     void SetRNVFlag(bool RNVFlag)
62     {
63         std::lock_guard<std::mutex> locker(mtx_);
64         RNVFlag_ = RNVFlag;
65     }
GetRNVFlag()66     bool GetRNVFlag()
67     {
68         std::lock_guard<std::mutex> locker(mtx_);
69         return RNVFlag_;
70     }
71 
GetPeriod()72     int64_t GetPeriod()
73     {
74         std::lock_guard<std::mutex> locker(mtx_);
75         return period_;
76     }
77 
GetTimeStamp()78     int64_t GetTimeStamp()
79     {
80         std::lock_guard<std::mutex> locker(mtx_);
81         return timeStamp_;
82     }
83 
GetPeriodShared()84     int64_t GetPeriodShared()
85     {
86         std::lock_guard<std::mutex> locker(mtx_);
87         return periodShared_;
88     }
89 
GetTimeStampShared()90     int64_t GetTimeStampShared()
91     {
92         std::lock_guard<std::mutex> locker(mtx_);
93         return timeStampShared_;
94     }
95 
AddCallback(FrameCallback cb)96     void AddCallback(FrameCallback cb)
97     {
98         std::lock_guard<std::mutex> locker(mtx_);
99         frameCallbacks_.push_back(cb);
100     }
101 
102     void CloseFd(int32_t fd);
103 
104 private:
105     void OnReadable(int32_t fileDescriptor) override;
106     int64_t CalculateExpectedEndLocked(int64_t now);
107     void HandleVsyncCallbacks(int64_t data[], ssize_t dataCount);
108     VsyncError ReadFdInternal(int32_t fd, int64_t (&data)[3], ssize_t &dataCount);
109     VSyncCallback vsyncCallbacks_;
110     VSyncCallbackWithId vsyncCallbacksWithId_;
111     void *userData_;
112     std::mutex mtx_;
113     std::string name_;
114     bool RNVFlag_ = false;
115     int64_t period_ = 0;
116     int64_t timeStamp_ = 0;
117     thread_local static inline int64_t periodShared_ = 0;
118     thread_local static inline int64_t timeStampShared_ = 0;
119     std::vector<FrameCallback> frameCallbacks_ = {};
120     std::mutex fdMutex_;
121     bool fdClosed_ = false;
122 };
123 
124 #ifdef __OHOS__
125 class VSyncReceiver : public RefBase {
126 public:
127     // check
128     using FrameCallback = VSyncCallBackListener::FrameCallback;
129 
130     VSyncReceiver(const sptr<IVSyncConnection>& conn,
131         const sptr<IRemoteObject>& token = nullptr,
132         const std::shared_ptr<OHOS::AppExecFwk::EventHandler>& looper = nullptr,
133         const std::string& name = "Uninitialized");
134     ~VSyncReceiver();
135     // nocopyable
136     VSyncReceiver(const VSyncReceiver &) = delete;
137     VSyncReceiver &operator=(const VSyncReceiver &) = delete;
138 
139     virtual VsyncError Init();
140     void ThreadCreateNotify();
141     virtual VsyncError RequestNextVSync(FrameCallback callback);
142     virtual VsyncError SetVSyncRate(FrameCallback callback, int32_t rate);
143     virtual VsyncError GetVSyncPeriod(int64_t &period);
144     virtual VsyncError GetVSyncPeriodAndLastTimeStamp(int64_t &period, int64_t &timeStamp,
145                                                         bool isThreadShared = false);
GetFd()146     int32_t GetFd() { return fd_; }
147 
148     /* transfer the FD to other process(want to use the FD),
149       the current process does not use the FD, so close FD, but not close vsync connection
150     */
151     void CloseVsyncReceiverFd();
152     virtual VsyncError RequestNextVSync(FrameCallback callback, const std::string &fromWhom,
153                                         int64_t lastVSyncTS);
154     virtual bool IsRequestedNextVSync();
155     virtual VsyncError SetVsyncCallBackForEveryFrame(FrameCallback callback, bool isOpen);
156     virtual VsyncError SetUiDvsyncSwitch(bool dvsyncSwitch);
157     virtual VsyncError SetUiDvsyncConfig(int32_t bufferCount);
158     virtual VsyncError RequestNextVSyncWithMultiCallback(FrameCallback callback);
159     virtual VsyncError SetNativeDVSyncSwitch(bool dvsyncSwitch);
160 private:
161     VsyncError Destroy();
162     sptr<IVSyncConnection> connection_;
163     sptr<IRemoteObject> token_;
164     std::shared_ptr<OHOS::AppExecFwk::EventHandler> looper_;
165     std::shared_ptr<VSyncCallBackListener> listener_;
166 
167     std::mutex initMutex_;
168     bool init_;
169     int32_t fd_;
170     std::string name_;
171 };
172 #else
173 class VSyncReceiver {
174 public:
175     using FrameCallback = VSyncCallBackListener::FrameCallback;
176 
177     VSyncReceiver() = default;
178     virtual ~VSyncReceiver() = default;
179     VSyncReceiver(const VSyncReceiver &) = delete;
180     VSyncReceiver &operator=(const VSyncReceiver &) = delete;
181 
182     virtual VsyncError Init() = 0;
183     virtual VsyncError RequestNextVSync(FrameCallback callback) = 0;
184     virtual VsyncError SetVSyncRate(FrameCallback callback, int32_t rate) = 0;
185 };
186 #endif
187 } // namespace Rosen
188 } // namespace OHOS
189 
190 #endif
191