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 "fb_display.h"
17 #include <sys/ioctl.h>
18 #include <sys/mman.h>
19 #include <sys/ioctl.h>
20 #include <cerrno>
21 #include <securec.h>
22 #include <linux/fb.h>
23 #include "display_common.h"
24 #include "hdi_gfx_composition.h"
25 #include "fb_composition.h"
26 #include "vsync/sorft_vsync.h"
27 #include "hdi_gles_composition.h"
28 #include "hdi_gfx_composition.h"
29 #include "display_adapter.h"
30
31 namespace OHOS {
32 namespace HDI {
33 namespace DISPLAY {
CreateHdiLayer(LayerType type)34 std::unique_ptr<HdiLayer> FbDisplay::CreateHdiLayer(LayerType type)
35 {
36 DISPLAY_LOGD();
37 auto layer = HdiDisplay::CreateHdiLayer(type);
38 layer->SetReleaseFence(-1); // the fd display will return the current buffer fence.
39 return layer;
40 }
41
FbDisplay(std::vector<int> & fds)42 FbDisplay::FbDisplay(std::vector<int> &fds)
43 {
44 DISPLAY_LOGD();
45 deviceFds_ = fds;
46 }
47
~FbDisplay()48 FbDisplay::~FbDisplay()
49 {
50 DISPLAY_LOGD();
51 }
52
GetPreComposition(uint32_t w,uint32_t h)53 std::unique_ptr<HdiComposition> FbDisplay::GetPreComposition(uint32_t w, uint32_t h)
54 {
55 int ret;
56 #ifdef ENABLE_GLES_COMPOSITION
57 auto preComp = std::make_unique<HdiGlesComposition>();
58 DISPLAY_CHK_RETURN((preComp == nullptr), nullptr,
59 DISPLAY_LOGE("can not new HdiGlesComposition errno %{public}d", errno));
60 ret = preComp->Init(w, h);
61 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_LOGE("can not init HdiGfxComposition"));
62 #else
63 auto preComp = std::make_unique<HdiGfxComposition>();
64 DISPLAY_CHK_RETURN((preComp == nullptr), nullptr,
65 DISPLAY_LOGE("can not new HdiGfxComposition errno %{public}d", errno));
66 ret = preComp->Init();
67 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_LOGE("can not init HdiGfxComposition"));
68 #endif // ENABLE_GLES_COMPOSITION
69 return preComp;
70 }
Init()71 int32_t FbDisplay::Init()
72 {
73 int ret;
74 int deviceFd = deviceFds_[0];
75 struct fb_var_screeninfo varInfo;
76 const uint32_t defaultFreshRate = 60 * 1000;
77 ret = HdiDisplay::Init();
78 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("init failed"));
79 ret = DisplayAdapter::GetInstance()->Ioctl(deviceFd, FBIOGET_VSCREENINFO, &varInfo);
80 DISPLAY_CHK_RETURN((ret < 0), DISPLAY_FAILURE, DISPLAY_LOGE("failed to get screen information"));
81 DisplayModeInfo mode;
82 mode.freshRate = defaultFreshRate;
83 mode.width = varInfo.xres;
84 mode.height = varInfo.yres;
85 mode.id = 0;
86 modes_.push_back(mode);
87 DISPLAY_LOGD("xres : %{public}d yres : %{public}d fps : %{public}d", varInfo.xres, varInfo.yres, mode.freshRate);
88
89 displayCapability_.phyWidth = varInfo.xres;
90 displayCapability_.phyHeight = varInfo.yres;
91 displayCapability_.type = DISP_INTF_PANEL;
92 mActiveModeId = 0;
93
94 auto preComp = GetPreComposition(mode.width, mode.height);
95
96 auto postComp = std::make_unique<FbComposition>(deviceFds_);
97 DISPLAY_CHK_RETURN((postComp == nullptr), DISPLAY_FAILURE,
98 DISPLAY_LOGE("can not new HdiDrmComposition errno %{public}d", errno));
99 ret = postComp->Init();
100 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not init HdiDrmComposition"));
101 mComposer = std::make_unique<HdiComposer>(std::move(preComp), std::move(postComp));
102 mClientLayer->SetReleaseFence(-1);
103 return DISPLAY_SUCCESS;
104 }
105
GetDisplayCapability(DisplayCapability * info)106 int32_t FbDisplay::GetDisplayCapability(DisplayCapability *info)
107 {
108 DISPLAY_LOGD();
109 DISPLAY_CHK_RETURN((info == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("inof is nullptr"));
110 *info = displayCapability_;
111 return DISPLAY_SUCCESS;
112 }
113
GetDisplaySupportedModes(uint32_t * num,DisplayModeInfo * modes)114 int32_t FbDisplay::GetDisplaySupportedModes(uint32_t *num, DisplayModeInfo *modes)
115 {
116 DISPLAY_LOGD();
117 DISPLAY_CHK_RETURN((num == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("num and modes is nullptr"));
118 DISPLAY_CHK_RETURN((*num < 0), DISPLAY_FAILURE, DISPLAY_LOGE("the num is invalid"));
119 if (modes == NULL) {
120 *num = modes_.size();
121 return DISPLAY_SUCCESS;
122 }
123 if (*num > modes_.size()) {
124 *num = modes_.size();
125 }
126 memcpy_s(modes, sizeof(DisplayModeInfo) * (*num), modes_.data(), sizeof(DisplayModeInfo) * (*num));
127 return DISPLAY_SUCCESS;
128 }
129
GetDisplayMode(uint32_t * modeId)130 int32_t FbDisplay::GetDisplayMode(uint32_t *modeId)
131 {
132 DISPLAY_LOGD();
133 *modeId = mActiveModeId;
134 if (mActiveModeId == static_cast<uint32_t>(INVALID_MODE_ID)) {
135 DISPLAY_LOGE("now has not active mode");
136 return DISPLAY_FAILURE;
137 }
138 return DISPLAY_SUCCESS;
139 }
140
SetDisplayMode(uint32_t modeId)141 int32_t FbDisplay::SetDisplayMode(uint32_t modeId)
142 {
143 DISPLAY_LOGD();
144 if (modeId < modes_.size()) {
145 mActiveModeId = modeId;
146 } else {
147 DISPLAY_LOGE("the modeId is invalid");
148 }
149 return DISPLAY_SUCCESS;
150 }
151
GetDisplayPowerStatus(DispPowerStatus * status)152 int32_t FbDisplay::GetDisplayPowerStatus(DispPowerStatus *status)
153 {
154 DISPLAY_LOGD();
155 DISPLAY_CHK_RETURN((status == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the status is nullptr"));
156 *status = mPowerstatus;
157 return DISPLAY_SUCCESS;
158 }
159
SetDisplayPowerStatus(DispPowerStatus status)160 int32_t FbDisplay::SetDisplayPowerStatus(DispPowerStatus status)
161 {
162 DISPLAY_LOGD();
163 mPowerstatus = status;
164 return DISPLAY_SUCCESS;
165 }
166
GetDisplayBacklight(uint32_t * value)167 int32_t FbDisplay::GetDisplayBacklight(uint32_t *value)
168 {
169 DISPLAY_LOGD();
170 return DISPLAY_NOT_SUPPORT;
171 }
172
SetDisplayBacklight(uint32_t value)173 int32_t FbDisplay::SetDisplayBacklight(uint32_t value)
174 {
175 DISPLAY_LOGD();
176 return DISPLAY_NOT_SUPPORT;
177 }
178
RegDisplayVBlankCallback(VBlankCallback cb,void * data)179 int32_t FbDisplay::RegDisplayVBlankCallback(VBlankCallback cb, void *data)
180 {
181 DISPLAY_LOGD("the VBlankCallback %{public}p ", cb);
182 std::shared_ptr<VsyncCallBack> vsyncCb = std::make_shared<VsyncCallBack>(cb, nullptr);
183 SorftVsync::GetInstance().ReqesterVBlankCb(vsyncCb);
184 return DISPLAY_SUCCESS;
185 }
186
IsConnected()187 bool FbDisplay::IsConnected()
188 {
189 DISPLAY_LOGD();
190 return true;
191 }
192
SetDisplayVsyncEnabled(bool enabled)193 int32_t FbDisplay::SetDisplayVsyncEnabled(bool enabled)
194 {
195 DISPLAY_LOGD("enable %{public}d", enabled);
196 SorftVsync::GetInstance().EnableVsync(enabled);
197 return DISPLAY_SUCCESS;
198 }
199 } // namespace OHOS
200 } // namespace HDI
201 } // namespace DISPLAY
202