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