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 <cstring>
24 #include <securec.h>
25 #include <mutex>
26 #include "v1_2/include/idisplay_composer_interface.h"
27
28 #define CHECK_DEVICE_NULL(sptrDevice) \
29 do { \
30 if ((sptrDevice) == nullptr) { \
31 HLOGE("[%{public}s]: HdiDevice is nullptr.", __func__); \
32 return GRAPHIC_DISPLAY_NULL_PTR; \
33 } \
34 } while (0)
35
36 namespace OHOS {
37 namespace Rosen {
38 using namespace OHOS::HDI::Display::Composer::V1_0;
39 using namespace OHOS::HDI::Display::Composer::V1_1;
40 using namespace OHOS::HDI::Display::Composer::V1_2;
41 constexpr size_t MATRIX_SIZE = 9;
42 const std::string GENERIC_METADATA_KEY_DISPLAY_LINEAR_MATRIX = "DisplayLinearMatrix";
43
CreateHdiScreen(uint32_t screenId)44 std::unique_ptr<HdiScreen> HdiScreen::CreateHdiScreen(uint32_t screenId)
45 {
46 return std::make_unique<HdiScreen>(screenId);
47 }
48
HdiScreen(uint32_t screenId)49 HdiScreen::HdiScreen(uint32_t screenId) : screenId_(screenId)
50 {
51 HLOGI("Create screen, screenId is %{public}d", screenId);
52 }
53
~HdiScreen()54 HdiScreen::~HdiScreen()
55 {
56 HLOGI("Destroy screen, screenId is %{public}d", screenId_);
57 }
58
OnVsync(uint32_t sequence,uint64_t ns,void * data)59 void HdiScreen::OnVsync(uint32_t sequence, uint64_t ns, void *data)
60 {
61 (void)data;
62 ScopedBytrace onVsyncTrace("HdiScreen::OnVsync_" + std::to_string((ns)));
63 if (ns == 0) {
64 HLOGW("Vsync ns is 0, drop this callback");
65 return;
66 }
67
68 // trigger vsync
69 // if the sampler->GetHardwareVSyncStatus() is false, this OnVsync callback will be disable
70 // we need to add this process
71 auto sampler = CreateVSyncSampler();
72 if (sampler->GetHardwareVSyncStatus()) {
73 bool enable = sampler->AddSample(ns);
74 sampler->SetHardwareVSyncStatus(enable);
75 }
76 }
77
Init()78 bool HdiScreen::Init()
79 {
80 if (device_ != nullptr) {
81 HLOGI("HdiScreen has been initialized");
82 return true;
83 }
84
85 device_ = HdiDevice::GetInstance();
86 if (device_ == nullptr) {
87 HLOGE("[%{public}s]: HdiDevice is nullptr.", __func__);
88 return false;
89 }
90
91 int32_t ret = device_->RegScreenVBlankCallback(screenId_, HdiScreen::OnVsync, this);
92 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
93 HLOGE("RegScreenVBlankCallback failed, ret is %{public}d", ret);
94 return false;
95 }
96
97 HLOGI("Init hdiScreen succeed");
98 return true;
99 }
100
SetHdiDevice(HdiDevice * device)101 bool HdiScreen::SetHdiDevice(HdiDevice* device)
102 {
103 if (device_ != nullptr) {
104 return true;
105 }
106
107 if (device == nullptr) {
108 HLOGE("Input HdiDevice is null");
109 return false;
110 }
111
112 device_ = device;
113 return true;
114 }
115
GetScreenCapability(GraphicDisplayCapability & dcap) const116 int32_t HdiScreen::GetScreenCapability(GraphicDisplayCapability &dcap) const
117 {
118 CHECK_DEVICE_NULL(device_);
119 return device_->GetScreenCapability(screenId_, dcap);
120 }
121
GetScreenSupportedModes(std::vector<GraphicDisplayModeInfo> & modes) const122 int32_t HdiScreen::GetScreenSupportedModes(std::vector<GraphicDisplayModeInfo> &modes) const
123 {
124 CHECK_DEVICE_NULL(device_);
125 return device_->GetScreenSupportedModes(screenId_, modes);
126 }
127
GetScreenMode(uint32_t & modeId)128 int32_t HdiScreen::GetScreenMode(uint32_t &modeId)
129 {
130 std::unique_lock<std::mutex> locker(mutex_);
131 CHECK_DEVICE_NULL(device_);
132 if (modeId_ != UINT32_MAX) {
133 modeId = modeId_;
134 return HDF_SUCCESS;
135 }
136 int32_t ret = device_->GetScreenMode(screenId_, modeId);
137 if (ret == HDF_SUCCESS) {
138 modeId_ = modeId;
139 }
140 return ret;
141 }
142
SetScreenMode(uint32_t modeId)143 int32_t HdiScreen::SetScreenMode(uint32_t modeId)
144 {
145 std::unique_lock<std::mutex> locker(mutex_);
146 CHECK_DEVICE_NULL(device_);
147 int32_t ret = device_->SetScreenMode(screenId_, modeId);
148 if (ret == HDF_SUCCESS) {
149 modeId_ = modeId;
150 } else {
151 modeId_ = UINT32_MAX;
152 }
153 return ret;
154 }
155
SetScreenActiveRect(const GraphicIRect & activeRect)156 int32_t HdiScreen::SetScreenActiveRect(const GraphicIRect& activeRect)
157 {
158 std::unique_lock<std::mutex> locker(mutex_);
159 CHECK_DEVICE_NULL(device_);
160 return device_->SetScreenActiveRect(screenId_, activeRect);
161 }
162
SetScreenOverlayResolution(uint32_t width,uint32_t height) const163 int32_t HdiScreen::SetScreenOverlayResolution(uint32_t width, uint32_t height) const
164 {
165 CHECK_DEVICE_NULL(device_);
166 return device_->SetScreenOverlayResolution(screenId_, width, height);
167 }
168
GetScreenPowerStatus(GraphicDispPowerStatus & status) const169 int32_t HdiScreen::GetScreenPowerStatus(GraphicDispPowerStatus &status) const
170 {
171 CHECK_DEVICE_NULL(device_);
172 return device_->GetScreenPowerStatus(screenId_, status);
173 }
174
SetScreenPowerStatus(GraphicDispPowerStatus status) const175 int32_t HdiScreen::SetScreenPowerStatus(GraphicDispPowerStatus status) const
176 {
177 CHECK_DEVICE_NULL(device_);
178 return device_->SetScreenPowerStatus(screenId_, status);
179 }
180
GetScreenBacklight(uint32_t & level) const181 int32_t HdiScreen::GetScreenBacklight(uint32_t &level) const
182 {
183 CHECK_DEVICE_NULL(device_);
184 return device_->GetScreenBacklight(screenId_, level);
185 }
186
SetScreenBacklight(uint32_t level) const187 int32_t HdiScreen::SetScreenBacklight(uint32_t level) const
188 {
189 CHECK_DEVICE_NULL(device_);
190 return device_->SetScreenBacklight(screenId_, level);
191 }
192
SetScreenVsyncEnabled(bool enabled) const193 int32_t HdiScreen::SetScreenVsyncEnabled(bool enabled) const
194 {
195 CHECK_DEVICE_NULL(device_);
196 int32_t ret = device_->SetScreenVsyncEnabled(screenId_, enabled);
197 if (ret != HDF_SUCCESS) {
198 HLOGE("SetScreenVsyncEnabled Failed, screenId:%{public}u, enabled:%{public}d, ret:%{public}d",
199 screenId_, enabled, ret);
200 RS_TRACE_NAME_FMT("SetScreenVsyncEnabled Failed, screenId:%u, enabled:%d, ret:%d", screenId_, enabled, ret);
201 }
202 return ret;
203 }
204
GetScreenSupportedColorGamuts(std::vector<GraphicColorGamut> & gamuts) const205 int32_t HdiScreen::GetScreenSupportedColorGamuts(std::vector<GraphicColorGamut> &gamuts) const
206 {
207 CHECK_DEVICE_NULL(device_);
208 return device_->GetScreenSupportedColorGamuts(screenId_, gamuts);
209 }
210
SetScreenColorGamut(GraphicColorGamut gamut) const211 int32_t HdiScreen::SetScreenColorGamut(GraphicColorGamut gamut) const
212 {
213 CHECK_DEVICE_NULL(device_);
214 return device_->SetScreenColorGamut(screenId_, gamut);
215 }
216
GetScreenColorGamut(GraphicColorGamut & gamut) const217 int32_t HdiScreen::GetScreenColorGamut(GraphicColorGamut &gamut) const
218 {
219 CHECK_DEVICE_NULL(device_);
220 return device_->GetScreenColorGamut(screenId_, gamut);
221 }
222
SetScreenGamutMap(GraphicGamutMap gamutMap) const223 int32_t HdiScreen::SetScreenGamutMap(GraphicGamutMap gamutMap) const
224 {
225 CHECK_DEVICE_NULL(device_);
226 return device_->SetScreenGamutMap(screenId_, gamutMap);
227 }
228
GetScreenGamutMap(GraphicGamutMap & gamutMap) const229 int32_t HdiScreen::GetScreenGamutMap(GraphicGamutMap &gamutMap) const
230 {
231 CHECK_DEVICE_NULL(device_);
232 return device_->GetScreenGamutMap(screenId_, gamutMap);
233 }
234
SetScreenColorTransform(const std::vector<float> & matrix) const235 int32_t HdiScreen::SetScreenColorTransform(const std::vector<float>& matrix) const
236 {
237 CHECK_DEVICE_NULL(device_);
238 return device_->SetScreenColorTransform(screenId_, matrix);
239 }
240
SetScreenLinearMatrix(const std::vector<float> & matrix) const241 int32_t HdiScreen::SetScreenLinearMatrix(const std::vector<float> &matrix) const
242 {
243 CHECK_DEVICE_NULL(device_);
244 std::vector<int8_t> valueBlob(MATRIX_SIZE * sizeof(float));
245 if (memcpy_s(valueBlob.data(), valueBlob.size(), matrix.data(),
246 MATRIX_SIZE * sizeof(float)) != EOK) {
247 return -1;
248 }
249 return device_->SetDisplayPerFrameParameterSmq(
250 screenId_, GENERIC_METADATA_KEY_DISPLAY_LINEAR_MATRIX, valueBlob);
251 }
252
GetHDRCapabilityInfos(GraphicHDRCapability & info) const253 int32_t HdiScreen::GetHDRCapabilityInfos(GraphicHDRCapability &info) const
254 {
255 CHECK_DEVICE_NULL(device_);
256 return device_->GetHDRCapabilityInfos(screenId_, info);
257 }
258
GetSupportedMetaDataKey(std::vector<GraphicHDRMetadataKey> & keys) const259 int32_t HdiScreen::GetSupportedMetaDataKey(std::vector<GraphicHDRMetadataKey> &keys) const
260 {
261 CHECK_DEVICE_NULL(device_);
262 return device_->GetSupportedMetaDataKey(screenId_, keys);
263 }
264
SetScreenConstraint(uint64_t frameId,uint64_t timestamp,uint32_t type)265 int32_t HdiScreen::SetScreenConstraint(uint64_t frameId, uint64_t timestamp, uint32_t type)
266 {
267 CHECK_DEVICE_NULL(device_);
268 return device_->SetScreenConstraint(screenId_, frameId, timestamp, type);
269 }
270
GetDisplayPropertyForHardCursor(uint32_t screenId)271 bool HdiScreen::GetDisplayPropertyForHardCursor(uint32_t screenId)
272 {
273 if (device_ == nullptr) {
274 HLOGE("[%{public}s]: HdiDevice is nullptr.", __func__);
275 return false;
276 }
277 uint64_t propertyValue = 0;
278 if (device_->GetDisplayProperty(screenId,
279 HDI::Display::Composer::V1_2::DISPLAY_CAPBILITY_HARDWARE_CURSOR, propertyValue)
280 != HDI::Display::Composer::V1_2::DISPLAY_SUCCESS) {
281 return false;
282 }
283 if (propertyValue) {
284 return true;
285 }
286 return false;
287 }
288
GetDisplayIdentificationData(uint8_t & outPort,std::vector<uint8_t> & edidData) const289 int32_t HdiScreen::GetDisplayIdentificationData(uint8_t& outPort, std::vector<uint8_t>& edidData) const
290 {
291 CHECK_DEVICE_NULL(device_);
292 return device_->GetDisplayIdentificationData(screenId_, outPort, edidData);
293 }
294 } // namespace Rosen
295 } // namespace OHOS
296