• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 <vsync_receiver.h>
17 #include "transaction/rs_interfaces.h"
18 #include "feature/hyper_graphic_manager/rs_frame_rate_linker.h"
19 #include "vsync_log.h"
20 #include "native_vsync.h"
21 
22 using namespace OHOS;
23 
24 namespace {
25 struct NativeVSync {
26     std::shared_ptr<OHOS::Rosen::VSyncReceiver> receiver_;
27     std::shared_ptr<OHOS::Rosen::RSFrameRateLinker> frameRateLinker_;
28 };
29 }
OH_NativeVSync_OHNativeVSyncToNativeVSync(OH_NativeVSync * ohNativeVSync)30 static NativeVSync* OH_NativeVSync_OHNativeVSyncToNativeVSync(OH_NativeVSync* ohNativeVSync)
31 {
32     return reinterpret_cast<NativeVSync*>(ohNativeVSync);
33 }
34 
OH_NativeVSync_NativeVSyncToOHNativeVSync(NativeVSync * nativeVSync)35 static OH_NativeVSync* OH_NativeVSync_NativeVSyncToOHNativeVSync(NativeVSync* nativeVSync)
36 {
37     return reinterpret_cast<OH_NativeVSync*>(nativeVSync);
38 }
39 
CreateAndInitVSyncReceiver(const std::string & vsyncName,NativeVSync * nativeVSync,uint64_t windowID=0,bool isAssociatedWindow=false)40 std::shared_ptr<OHOS::Rosen::VSyncReceiver> CreateAndInitVSyncReceiver(
41     const std::string& vsyncName,
42     NativeVSync* nativeVSync,
43     uint64_t windowID = 0,
44     bool isAssociatedWindow = false)
45 {
46     auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance();
47     std::shared_ptr<OHOS::Rosen::VSyncReceiver> receiver;
48     if (nativeVSync == nullptr || nativeVSync->frameRateLinker_ == nullptr) {
49         return nullptr;
50     }
51     receiver = rsClient.CreateVSyncReceiver(
52         vsyncName, nativeVSync->frameRateLinker_->GetId(), nullptr, windowID, isAssociatedWindow);
53     if (receiver == nullptr) {
54         VLOGE("Create VSyncReceiver failed");
55         return nullptr;
56     }
57     int ret = receiver->Init();
58     if (ret != 0) {
59         VLOGE("VSyncReceiver Init failed, ret:%{public}d", ret);
60         return nullptr;
61     }
62     return receiver;
63 }
64 
OH_NativeVSync_Create(const char * name,unsigned int length)65 OH_NativeVSync* OH_NativeVSync_Create(const char* name, unsigned int length)
66 {
67     if (name == nullptr) {
68         VLOGE("name is nullptr, please check");
69         return nullptr;
70     }
71     std::string vsyncName(name, length);
72     NativeVSync* nativeVSync = new NativeVSync;
73     if (nativeVSync == nullptr) {
74         VLOGE("nativeVSync create fail");
75         return nullptr;
76     }
77     nativeVSync->frameRateLinker_ = OHOS::Rosen::RSFrameRateLinker::Create();
78     if (nativeVSync->frameRateLinker_ == nullptr) {
79         VLOGE("frameRateLinker_ create fail");
80         delete nativeVSync;
81         return nullptr;
82     }
83     nativeVSync->frameRateLinker_->SetEnable(true);
84     auto receiver = CreateAndInitVSyncReceiver(vsyncName, nativeVSync);
85     if (receiver == nullptr) {
86         VLOGE("receiver is nullptr, please check");
87         delete nativeVSync;
88         return nullptr;
89     }
90     nativeVSync->receiver_ = receiver;
91     return OH_NativeVSync_NativeVSyncToOHNativeVSync(nativeVSync);
92 }
93 
OH_NativeVSync_Create_ForAssociatedWindow(uint64_t windowID,const char * name,unsigned int length)94 OH_NativeVSync* OH_NativeVSync_Create_ForAssociatedWindow(uint64_t windowID, const char* name, unsigned int length)
95 {
96     if (name == nullptr) {
97         VLOGE("name is nullptr, please check");
98         return nullptr;
99     }
100     std::string vsyncName(name, length);
101     NativeVSync* nativeVSync = new NativeVSync;
102     if (nativeVSync == nullptr) {
103         VLOGE("nativeVSync create fail");
104         return nullptr;
105     }
106     nativeVSync->frameRateLinker_ = OHOS::Rosen::RSFrameRateLinker::Create();
107     auto receiver = CreateAndInitVSyncReceiver(vsyncName, nativeVSync, windowID, true);
108     if (receiver == nullptr) {
109         VLOGE("receiver is nullptr, please check");
110         delete nativeVSync;
111         return nullptr;
112     }
113     nativeVSync->receiver_ = receiver;
114     return OH_NativeVSync_NativeVSyncToOHNativeVSync(nativeVSync);
115 }
116 
OH_NativeVSync_Destroy(OH_NativeVSync * nativeVSync)117 void OH_NativeVSync_Destroy(OH_NativeVSync *nativeVSync)
118 {
119     if (nativeVSync == nullptr) {
120         VLOGE("parameter is nullptr, please check");
121         return;
122     }
123 
124     delete OH_NativeVSync_OHNativeVSyncToNativeVSync(nativeVSync);
125     nativeVSync = nullptr;
126 }
127 
OH_NativeVSync_RequestFrame(OH_NativeVSync * ohNativeVSync,OH_NativeVSync_FrameCallback callback,void * data)128 int OH_NativeVSync_RequestFrame(OH_NativeVSync *ohNativeVSync, OH_NativeVSync_FrameCallback callback, void* data)
129 {
130     NativeVSync* nativeVSync = OH_NativeVSync_OHNativeVSyncToNativeVSync(ohNativeVSync);
131     if (nativeVSync == nullptr || nativeVSync->receiver_ == nullptr || callback == nullptr) {
132         VLOGE("parameter is nullptr, please check");
133         return VSYNC_ERROR_INVALID_ARGUMENTS;
134     }
135     OHOS::Rosen::VSyncReceiver::FrameCallback frameCallback = {
136         .userData_ = data,
137         .callback_ = callback,
138     };
139     return nativeVSync->receiver_->RequestNextVSync(frameCallback);
140 }
141 
OH_NativeVSync_RequestFrameWithMultiCallback(OH_NativeVSync * ohNativeVSync,OH_NativeVSync_FrameCallback callback,void * data)142 int OH_NativeVSync_RequestFrameWithMultiCallback(
143     OH_NativeVSync *ohNativeVSync, OH_NativeVSync_FrameCallback callback, void* data)
144 {
145     NativeVSync* nativeVSync = OH_NativeVSync_OHNativeVSyncToNativeVSync(ohNativeVSync);
146     if (nativeVSync == nullptr || nativeVSync->receiver_ == nullptr || callback == nullptr) {
147         VLOGE("parameter is nullptr, please check");
148         return VSYNC_ERROR_INVALID_ARGUMENTS;
149     }
150     OHOS::Rosen::VSyncReceiver::FrameCallback frameCallback = {
151         .userData_ = data,
152         .callback_ = callback,
153     };
154     return nativeVSync->receiver_->RequestNextVSyncWithMultiCallback(frameCallback);
155 }
156 
OH_NativeVSync_GetPeriod(OH_NativeVSync * nativeVsync,long long * period)157 int OH_NativeVSync_GetPeriod(OH_NativeVSync* nativeVsync, long long* period)
158 {
159     NativeVSync* nativeVSync = OH_NativeVSync_OHNativeVSyncToNativeVSync(nativeVsync);
160     if (nativeVSync == nullptr || nativeVSync->receiver_ == nullptr || period == nullptr) {
161         VLOGE("parameter is nullptr, please check");
162         return VSYNC_ERROR_INVALID_ARGUMENTS;
163     }
164     return nativeVSync->receiver_->GetVSyncPeriod(*reinterpret_cast<int64_t*>(period));
165 }
166 
OH_NativeVSync_DVSyncSwitch(OH_NativeVSync * ohNativeVSync,bool enable)167 int OH_NativeVSync_DVSyncSwitch(OH_NativeVSync* ohNativeVSync, bool enable)
168 {
169     NativeVSync* nativeVSync = OH_NativeVSync_OHNativeVSyncToNativeVSync(ohNativeVSync);
170     if (nativeVSync == nullptr || nativeVSync->receiver_ == nullptr) {
171         VLOGE("parameter is nullptr, please check");
172         return VSYNC_ERROR_INVALID_ARGUMENTS;
173     }
174     return nativeVSync->receiver_->SetNativeDVSyncSwitch(enable);
175 }
176 
177 namespace {
IsInputRateRangeValid(OH_NativeVSync_ExpectedRateRange * range)178 bool IsInputRateRangeValid(OH_NativeVSync_ExpectedRateRange* range)
179 {
180     if (range == nullptr) {
181         VLOGE("input range is nullptr, please check");
182         return false;
183     }
184     return range->min <= range->expected && range->expected <= range->max &&
185         range->min >= 0 && range->max <= RANGE_MAX_REFRESHRATE;
186 }
187 }
188 
OH_NativeVSync_SetExpectedFrameRateRange(OH_NativeVSync * nativeVsync,OH_NativeVSync_ExpectedRateRange * range)189 int OH_NativeVSync_SetExpectedFrameRateRange(OH_NativeVSync* nativeVsync, OH_NativeVSync_ExpectedRateRange* range)
190 {
191     NativeVSync* nativeVSync = OH_NativeVSync_OHNativeVSyncToNativeVSync(nativeVsync);
192     if (nativeVSync == nullptr || range == nullptr) {
193         VLOGE("parameter is nullptr, please check");
194         return VSYNC_ERROR_INVALID_ARGUMENTS;
195     }
196     if (!IsInputRateRangeValid(range)) {
197         VLOGE("ExpectedRateRange Error, please check.");
198         return VSYNC_ERROR_INVALID_ARGUMENTS;
199     }
200     if (nativeVSync->frameRateLinker_ == nullptr) {
201         VLOGE("FrameRateLinker is nullptr, please check.");
202         return VSYNC_ERROR_NOT_SUPPORT;
203     }
204     OHOS::Rosen::FrameRateRange frameRateRange(range->min, range->max, range->expected,
205         OHOS::Rosen::NATIVE_VSYNC_FRAME_RATE_TYPE);
206     VLOGI("NativeVsyncExpectedRateRange:{%{public}d, %{public}d, %{public}d}",
207         range->min, range->max, range->expected);
208     if (nativeVSync->frameRateLinker_->IsEnable()) {
209         nativeVSync->frameRateLinker_->UpdateFrameRateRangeImme(frameRateRange);
210     }
211     return VSYNC_ERROR_OK;
212 }
213