1 /*
2  * Copyright (c) 2021 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 <scoped_bytrace.h>
17 #include "hdi_screen.h"
18 #include <chrono>
19 #include "hdi_log.h"
20 #include "vsync_sampler.h"
21 #include <hdf_base.h>
22 #include <rs_trace.h>
23 #include <mutex>
24 #include "v1_2/include/idisplay_composer_interface.h"
25 
26 #define CHECK_DEVICE_NULL(sptrDevice)                                \
27     do {                                                             \
28         if ((sptrDevice) == nullptr) {                               \
29             HLOGE("[%{public}s]: HdiDevice is nullptr.", __func__);  \
30             return GRAPHIC_DISPLAY_NULL_PTR;                         \
31         }                                                            \
32     } while (0)
33 
34 namespace OHOS {
35 namespace Rosen {
36 using namespace OHOS::HDI::Display::Composer::V1_0;
37 using namespace OHOS::HDI::Display::Composer::V1_1;
38 using namespace OHOS::HDI::Display::Composer::V1_2;
39 
CreateHdiScreen(uint32_t screenId)40 std::unique_ptr<HdiScreen> HdiScreen::CreateHdiScreen(uint32_t screenId)
41 {
42     return std::make_unique<HdiScreen>(screenId);
43 }
44 
HdiScreen(uint32_t screenId)45 HdiScreen::HdiScreen(uint32_t screenId) : screenId_(screenId)
46 {
47     HLOGI("Create screen, screenId is %{public}d", screenId);
48 }
49 
~HdiScreen()50 HdiScreen::~HdiScreen()
51 {
52     HLOGI("Destroy screen, screenId is %{public}d", screenId_);
53 }
54 
OnVsync(uint32_t sequence,uint64_t ns,void * data)55 void HdiScreen::OnVsync(uint32_t sequence, uint64_t ns, void *data)
56 {
57     (void)data;
58     ScopedBytrace onVsyncTrace("HdiScreen::OnVsync_" + std::to_string((ns)));
59     if (ns == 0) {
60         HLOGW("Vsync ns is 0, drop this callback");
61         return;
62     }
63 
64     // trigger vsync
65     // if the sampler->GetHardwareVSyncStatus() is false, this OnVsync callback will be disable
66     // we need to add this process
67     auto sampler = CreateVSyncSampler();
68     if (sampler->GetHardwareVSyncStatus()) {
69         bool enable = sampler->AddSample(ns);
70         sampler->SetHardwareVSyncStatus(enable);
71     }
72 }
73 
Init()74 bool HdiScreen::Init()
75 {
76     if (device_ != nullptr) {
77         HLOGI("HdiScreen has been initialized");
78         return true;
79     }
80 
81     device_ = HdiDevice::GetInstance();
82     if (device_ == nullptr) {
83         HLOGE("[%{public}s]: HdiDevice is nullptr.", __func__);
84         return false;
85     }
86 
87     int32_t ret = device_->RegScreenVBlankCallback(screenId_, HdiScreen::OnVsync, this);
88     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
89         HLOGE("RegScreenVBlankCallback failed, ret is %{public}d", ret);
90         return false;
91     }
92 
93     ret = device_->SetScreenVsyncEnabled(screenId_, true);
94     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
95         HLOGE("SetScreenVsyncEnabled failed, ret is %{public}d", ret);
96         return false;
97     }
98 
99     HLOGI("Init hdiScreen succeed");
100 
101     return true;
102 }
103 
SetHdiDevice(HdiDevice * device)104 bool HdiScreen::SetHdiDevice(HdiDevice* device)
105 {
106     if (device_ != nullptr) {
107         return true;
108     }
109 
110     if (device == nullptr) {
111         HLOGE("Input HdiDevice is null");
112         return false;
113     }
114 
115     device_ = device;
116     return true;
117 }
118 
GetScreenCapability(GraphicDisplayCapability & dcap) const119 int32_t HdiScreen::GetScreenCapability(GraphicDisplayCapability &dcap) const
120 {
121     CHECK_DEVICE_NULL(device_);
122     return device_->GetScreenCapability(screenId_, dcap);
123 }
124 
GetScreenSupportedModes(std::vector<GraphicDisplayModeInfo> & modes) const125 int32_t HdiScreen::GetScreenSupportedModes(std::vector<GraphicDisplayModeInfo> &modes) const
126 {
127     CHECK_DEVICE_NULL(device_);
128     return device_->GetScreenSupportedModes(screenId_, modes);
129 }
130 
GetScreenMode(uint32_t & modeId)131 int32_t HdiScreen::GetScreenMode(uint32_t &modeId)
132 {
133     std::unique_lock<std::mutex> locker(mutex_);
134     CHECK_DEVICE_NULL(device_);
135     if (modeId_ != UINT32_MAX) {
136         modeId = modeId_;
137         return HDF_SUCCESS;
138     }
139     int32_t ret = device_->GetScreenMode(screenId_, modeId);
140     if (ret == HDF_SUCCESS) {
141         modeId_ = modeId;
142     }
143     return ret;
144 }
145 
SetScreenMode(uint32_t modeId)146 int32_t HdiScreen::SetScreenMode(uint32_t modeId)
147 {
148     std::unique_lock<std::mutex> locker(mutex_);
149     CHECK_DEVICE_NULL(device_);
150     int32_t ret = device_->SetScreenMode(screenId_, modeId);
151     if (ret == HDF_SUCCESS) {
152         modeId_ = modeId;
153     } else {
154         modeId_ = UINT32_MAX;
155     }
156     return ret;
157 }
158 
SetScreenOverlayResolution(uint32_t width,uint32_t height) const159 int32_t HdiScreen::SetScreenOverlayResolution(uint32_t width, uint32_t height) const
160 {
161     CHECK_DEVICE_NULL(device_);
162     return device_->SetScreenOverlayResolution(screenId_, width, height);
163 }
164 
GetScreenPowerStatus(GraphicDispPowerStatus & status) const165 int32_t HdiScreen::GetScreenPowerStatus(GraphicDispPowerStatus &status) const
166 {
167     CHECK_DEVICE_NULL(device_);
168     return device_->GetScreenPowerStatus(screenId_, status);
169 }
170 
SetScreenPowerStatus(GraphicDispPowerStatus status) const171 int32_t HdiScreen::SetScreenPowerStatus(GraphicDispPowerStatus status) const
172 {
173     CHECK_DEVICE_NULL(device_);
174     return device_->SetScreenPowerStatus(screenId_, status);
175 }
176 
GetScreenBacklight(uint32_t & level) const177 int32_t HdiScreen::GetScreenBacklight(uint32_t &level) const
178 {
179     CHECK_DEVICE_NULL(device_);
180     return device_->GetScreenBacklight(screenId_, level);
181 }
182 
SetScreenBacklight(uint32_t level) const183 int32_t HdiScreen::SetScreenBacklight(uint32_t level) const
184 {
185     CHECK_DEVICE_NULL(device_);
186     return device_->SetScreenBacklight(screenId_, level);
187 }
188 
SetScreenVsyncEnabled(bool enabled) const189 int32_t HdiScreen::SetScreenVsyncEnabled(bool enabled) const
190 {
191     CHECK_DEVICE_NULL(device_);
192     int32_t ret = device_->SetScreenVsyncEnabled(screenId_, enabled);
193     if (ret != HDF_SUCCESS) {
194         HLOGE("SetScreenVsyncEnabled Failed, screenId:%{public}u, enabled:%{public}d, ret:%{public}d",
195             screenId_, enabled, ret);
196         RS_TRACE_NAME_FMT("SetScreenVsyncEnabled Failed, screenId:%u, enabled:%d, ret:%d", screenId_, enabled, ret);
197     }
198     return ret;
199 }
200 
GetScreenSupportedColorGamuts(std::vector<GraphicColorGamut> & gamuts) const201 int32_t HdiScreen::GetScreenSupportedColorGamuts(std::vector<GraphicColorGamut> &gamuts) const
202 {
203     CHECK_DEVICE_NULL(device_);
204     return device_->GetScreenSupportedColorGamuts(screenId_, gamuts);
205 }
206 
SetScreenColorGamut(GraphicColorGamut gamut) const207 int32_t HdiScreen::SetScreenColorGamut(GraphicColorGamut gamut) const
208 {
209     CHECK_DEVICE_NULL(device_);
210     return device_->SetScreenColorGamut(screenId_, gamut);
211 }
212 
GetScreenColorGamut(GraphicColorGamut & gamut) const213 int32_t HdiScreen::GetScreenColorGamut(GraphicColorGamut &gamut) const
214 {
215     CHECK_DEVICE_NULL(device_);
216     return device_->GetScreenColorGamut(screenId_, gamut);
217 }
218 
SetScreenGamutMap(GraphicGamutMap gamutMap) const219 int32_t HdiScreen::SetScreenGamutMap(GraphicGamutMap gamutMap) const
220 {
221     CHECK_DEVICE_NULL(device_);
222     return device_->SetScreenGamutMap(screenId_, gamutMap);
223 }
224 
GetScreenGamutMap(GraphicGamutMap & gamutMap) const225 int32_t HdiScreen::GetScreenGamutMap(GraphicGamutMap &gamutMap) const
226 {
227     CHECK_DEVICE_NULL(device_);
228     return device_->GetScreenGamutMap(screenId_, gamutMap);
229 }
230 
SetScreenColorTransform(const std::vector<float> & matrix) const231 int32_t HdiScreen::SetScreenColorTransform(const std::vector<float>& matrix) const
232 {
233     CHECK_DEVICE_NULL(device_);
234     return device_->SetScreenColorTransform(screenId_, matrix);
235 }
236 
GetHDRCapabilityInfos(GraphicHDRCapability & info) const237 int32_t HdiScreen::GetHDRCapabilityInfos(GraphicHDRCapability &info) const
238 {
239     CHECK_DEVICE_NULL(device_);
240     return device_->GetHDRCapabilityInfos(screenId_, info);
241 }
242 
GetSupportedMetaDataKey(std::vector<GraphicHDRMetadataKey> & keys) const243 int32_t HdiScreen::GetSupportedMetaDataKey(std::vector<GraphicHDRMetadataKey> &keys) const
244 {
245     CHECK_DEVICE_NULL(device_);
246     return device_->GetSupportedMetaDataKey(screenId_, keys);
247 }
248 
SetScreenConstraint(uint64_t frameId,uint64_t timestamp,uint32_t type)249 int32_t HdiScreen::SetScreenConstraint(uint64_t frameId, uint64_t timestamp, uint32_t type)
250 {
251     CHECK_DEVICE_NULL(device_);
252     return device_->SetScreenConstraint(screenId_, frameId, timestamp, type);
253 }
254 
GetDisplayPropertyForHardCursor(uint32_t screenId)255 bool HdiScreen::GetDisplayPropertyForHardCursor(uint32_t screenId)
256 {
257     if (device_ == nullptr) {
258         HLOGE("[%{public}s]: HdiDevice is nullptr.", __func__);
259         return false;
260     }
261     uint64_t propertyValue = 0;
262     if (device_->GetDisplayProperty(screenId,
263         HDI::Display::Composer::V1_2::DISPLAY_CAPBILITY_HARDWARE_CURSOR, propertyValue)
264         != HDI::Display::Composer::V1_2::DISPLAY_SUCCESS) {
265         return false;
266     }
267     if (propertyValue) {
268         return true;
269     }
270     return false;
271 }
272 } // namespace Rosen
273 } // namespace OHOS
274