1 /*
2 * Copyright (c) 2022 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 #include <chrono>
17 #include <mutex>
18 #include <sys/time.h>
19 #include "display_common.h"
20 #include "sorft_vsync.h"
21
22 namespace OHOS {
23 namespace HDI {
24 namespace DISPLAY {
SorftVsync()25 SorftVsync::SorftVsync() {}
26
Init()27 int32_t SorftVsync::Init()
28 {
29 thread_ = std::make_unique<std::thread>([this]() { WorkThread(); });
30 DISPLAY_CHK_RETURN((thread_ == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create thread"));
31 running_ = true;
32 return DISPLAY_SUCCESS;
33 }
34
GetInstance()35 SorftVsync &SorftVsync::GetInstance()
36 {
37 static SorftVsync instance;
38 static std::once_flag once;
39 std::call_once(once, [&]() {
40 int ret = instance.Init();
41 if (ret != DISPLAY_SUCCESS) {
42 DISPLAY_LOGE("Vsync Worker Init failed");
43 }
44 });
45 return instance;
46 }
47
~SorftVsync()48 SorftVsync::~SorftVsync()
49 {
50 DISPLAY_LOGD();
51 {
52 std::lock_guard<std::mutex> lg(mutext_);
53 running_ = false;
54 }
55 condition_.notify_one();
56 if (thread_ != nullptr) {
57 thread_->join();
58 }
59 }
60
CheckRuning()61 bool SorftVsync::CheckRuning()
62 {
63 std::unique_lock<std::mutex> ul(mutext_);
64 condition_.wait(ul, [this]() { return (enable_ || !running_); });
65 return running_;
66 }
67
EnableVsync(bool enable)68 void SorftVsync::EnableVsync(bool enable)
69 {
70 DISPLAY_LOGD();
71 {
72 std::lock_guard<std::mutex> lg(mutext_);
73 enable_ = enable;
74 }
75 condition_.notify_one();
76 }
77
WorkThread()78 void SorftVsync::WorkThread()
79 {
80 DISPLAY_LOGD();
81 unsigned int seq = 0;
82 uint64_t time = 0;
83 const int SIXTY_HZ_OF_TIME = 16666;
84 struct timespec ts;
85 while (CheckRuning()) {
86 // wait the vblank
87 usleep(SIXTY_HZ_OF_TIME);
88 seq++;
89 if (callback_ != nullptr) {
90 clock_gettime(CLOCK_MONOTONIC, &ts);
91 time = ts.tv_nsec;
92 callback_->Vsync(seq, time);
93 } else {
94 DISPLAY_LOGE("the callbac is nullptr");
95 }
96 }
97 }
98
ReqesterVBlankCb(std::shared_ptr<VsyncCallBack> & cb)99 void SorftVsync::ReqesterVBlankCb(std::shared_ptr<VsyncCallBack> &cb)
100 {
101 DISPLAY_LOGD();
102 DISPLAY_CHK_RETURN_NOT_VALUE((cb == nullptr), DISPLAY_LOGE("the VBlankCallback is nullptr "));
103 callback_ = cb;
104 }
105 } // namespace OHOS
106 } // namespace HDI
107 } // namespace DISPLAY
108