1 /*
2 * Copyright (c) 2021-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 "hdi_test_display.h"
17 #include "display_test_utils.h"
18 #include "hdi_test_device.h"
19 namespace OHOS {
20 namespace HDI {
21 namespace DISPLAY {
22 namespace TEST {
HdiTestDisplay(const uint32_t id,const DeviceFuncs & deviceFunc)23 HdiTestDisplay::HdiTestDisplay(const uint32_t id, const DeviceFuncs &deviceFunc) : mId(id), mDeviceFunc(deviceFunc) {}
24
Init()25 int32_t HdiTestDisplay::Init()
26 {
27 DISPLAY_TEST_LOGI();
28 int ret = mDeviceFunc.GetDisplayCapability(mId, &mCap);
29 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get cap"));
30 DISPLAY_TEST_LOGI("the capablility name %s type : %d phyWidth : %d phyHeight : %d", mCap.name, mCap.type,
31 mCap.phyWidth, mCap.phyHeight);
32 // get the modes
33 uint32_t num = 0;
34 ret = mDeviceFunc.GetDisplaySupportedModes(mId, &num, nullptr);
35 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get modes num"));
36 DISPLAY_TEST_CHK_RETURN((num == 0), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the mode num is %d", num));
37 mModes.resize(num);
38 ret = mDeviceFunc.GetDisplaySupportedModes(mId, &num, mModes.data());
39 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get modes"));
40 DISPLAY_TEST_LOGI("the modes size() %zd", mModes.size());
41
42 ret = mDeviceFunc.GetDisplayMode(mId, &mActiveModeId);
43 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
44 DISPLAY_TEST_LOGE("the mode id is : %d", mActiveModeId));
45
46 ret = GetModeInfoFromId(mActiveModeId, mCurrentMode);
47 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
48 DISPLAY_TEST_LOGE("can not get the mode of id : %d", mActiveModeId));
49
50 LayerInfo layerinfo = { 0 };
51 layerinfo.width = mCurrentMode.width;
52 layerinfo.height = mCurrentMode.height;
53 layerinfo.pixFormat = PIXEL_FMT_BGRA_8888;
54 const uint32_t clientLayerId = 0xffffffff; // invalid id
55 mClientLayer = std::make_unique<HdiTestLayer>(layerinfo, clientLayerId, mId);
56 ret = mClientLayer->Init();
57 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
58 DISPLAY_TEST_LOGE("the client layer can not be created"));
59 return DISPLAY_SUCCESS;
60 }
61
GetModeInfoFromId(int32_t id,DisplayModeInfo & modeInfo) const62 int32_t HdiTestDisplay::GetModeInfoFromId(int32_t id, DisplayModeInfo &modeInfo) const
63 {
64 DISPLAY_TEST_LOGI();
65 for (const auto &mode : mModes) {
66 if (mode.id == id) {
67 modeInfo = mode;
68 DISPLAY_TEST_LOGI("the mode width: %d height : %d freshRate : %u id: %d", mode.width, mode.height,
69 mode.freshRate, mode.id);
70 return DISPLAY_SUCCESS;
71 }
72 }
73 DISPLAY_TEST_LOGE("can not find the modeinfo id : %d", id);
74 return DISPLAY_FAILURE;
75 }
76
CreateHdiTestLayer(LayerInfo & info)77 std::shared_ptr<HdiTestLayer> HdiTestDisplay::CreateHdiTestLayer(LayerInfo &info)
78 {
79 DISPLAY_TEST_LOGI();
80 uint32_t layerId = 0;
81 LayerFuncs &layerFuncs = HdiTestDevice::GetInstance().GetLayerFuncs();
82 int ret = layerFuncs.CreateLayer(mId, &info, &layerId);
83 DISPLAY_TEST_LOGI(" layerId %d", layerId);
84 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_TEST_LOGE("layer create failed"));
85 auto layer = std::make_shared<HdiTestLayer>(info, layerId, mId);
86 ret = layer->Init();
87 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_TEST_LOGE("layer init failed"));
88 mLayerMaps.emplace(layerId, layer);
89 return layer;
90 }
91
CreateHdiTestLayer(uint32_t w,uint32_t h)92 std::shared_ptr<HdiTestLayer> HdiTestDisplay::CreateHdiTestLayer(uint32_t w, uint32_t h)
93 {
94 const int32_t bpp = 32;
95
96 LayerInfo info = { w, h, LAYER_TYPE_GRAPHIC, bpp, PIXEL_FMT_RGBA_8888 };
97 return CreateHdiTestLayer(info);
98 }
99
RefreshLayersCompType()100 int32_t HdiTestDisplay::RefreshLayersCompType()
101 {
102 uint32_t num;
103 int ret;
104 std::vector<uint32_t> layers;
105 std::vector<int32_t> types;
106 ret = GetDeviceFuncs().GetDisplayCompChange(mId, &num, nullptr, nullptr);
107 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
108 DISPLAY_TEST_LOGE("GetDisplayCompChange get number failed"));
109 DISPLAY_TEST_LOGI("the change numbers %d", num);
110 layers.resize(num);
111 types.resize(num);
112 ret = GetDeviceFuncs().GetDisplayCompChange(mId, &num, layers.data(), types.data());
113 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
114 DISPLAY_TEST_LOGE("GetDisplayCompChange get layers and types failed"));
115 for (uint32_t i = 0; i < layers.size(); i++) {
116 DISPLAY_TEST_LOGI(" the layer id %d ", layers[i]);
117 std::shared_ptr<HdiTestLayer> layer = GetLayerFromId(layers[i]);
118 layer->SetCompType(static_cast<CompositionType>(types[i]));
119 }
120 return DISPLAY_SUCCESS;
121 }
122
GetLayersReleaseFence()123 int32_t HdiTestDisplay::GetLayersReleaseFence()
124 {
125 uint32_t num;
126 int ret;
127 std::vector<uint32_t> layers;
128 std::vector<int32_t> fences;
129
130 ret = HdiTestDevice::GetInstance().GetDeviceFuncs().GetDisplayReleaseFence(mId, &num, nullptr, nullptr);
131 DISPLAY_TEST_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("GetDisplayReleaseFence failed"));
132 DISPLAY_TEST_CHK_RETURN((num == 0), DISPLAY_SUCCESS, DISPLAY_TEST_LOGE("has no layers fence data"));
133 layers.resize(num);
134 fences.resize(num);
135 ret = HdiTestDevice::GetInstance().GetDeviceFuncs().GetDisplayReleaseFence(mId, &num, layers.data(), fences.data());
136 DISPLAY_TEST_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("GetDisplayReleaseFence get data failed"));
137 for (uint32_t i = 0; i < layers.size(); i++) {
138 DISPLAY_TEST_LOGI(" the layer id %d ", layers[i]);
139 std::shared_ptr<HdiTestLayer> layer = GetLayerFromId(layers[i]);
140 layer->SetReleaseFence(fences[i]);
141 }
142 return DISPLAY_SUCCESS;
143 }
144
PrepareDisplayLayers()145 int32_t HdiTestDisplay::PrepareDisplayLayers()
146 {
147 int ret;
148 mNeedFlushFb = false;
149 DISPLAY_TEST_LOGI("id : %d layer size %zd", mId, mLayerMaps.size());
150 for (const auto &layerMap : mLayerMaps) {
151 ret = layerMap.second->PreparePresent();
152 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
153 DISPLAY_TEST_LOGE("layer %d Prepare failed", layerMap.first));
154 }
155 ret = GetDeviceFuncs().PrepareDisplayLayers(mId, &mNeedFlushFb);
156 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
157 DISPLAY_TEST_LOGE("PrepareDisplayLayers failed display id %d", mId));
158 ret = RefreshLayersCompType();
159 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
160 DISPLAY_TEST_LOGE("RefreshLayersCompType failed"));
161 return DISPLAY_SUCCESS;
162 }
163
Commit()164 int32_t HdiTestDisplay::Commit()
165 {
166 int32_t fenceFd;
167 int ret;
168 HdiGrallocBuffer *buffer = nullptr;
169 if (mNeedFlushFb) {
170 ret = mClientLayer->SwapFrontToBackQ();
171 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
172 DISPLAY_TEST_LOGE("has no front buffer display id %d", mId));
173
174 buffer = mClientLayer->GetBackBuffer();
175 DISPLAY_TEST_CHK_RETURN((buffer == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get back buffer"));
176 BufferHandle *handle = buffer->Get();
177 DISPLAY_TEST_CHK_RETURN((handle == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("BufferHandle is null"));
178 ClearColor(*handle, 0); // need clear the fb first
179 ret = HdiTestDevice::GetInstance().GetDeviceFuncs().SetDisplayClientBuffer(mId, handle, -1);
180 mCurrentFb = handle;
181 DISPLAY_TEST_LOGI("client fb phyaddr %" PRIx64 " virtual addr %p", handle->phyAddr, handle->virAddr);
182 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
183 DISPLAY_TEST_LOGE("set client buffer handle failed"));
184 }
185
186 ret = HdiTestDevice::GetInstance().GetDeviceFuncs().Commit(mId, &fenceFd);
187 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
188 DISPLAY_TEST_LOGE("commit failed display id %d", mId));
189 ret = GetLayersReleaseFence();
190 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
191 DISPLAY_TEST_LOGE("GetLayersReleaseFence failed %d", mId));
192 buffer->SetReleaseFence(fenceFd);
193 if (mNeedFlushFb) {
194 ret = mClientLayer->SwapBackToFrontQ();
195 }
196 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
197 DISPLAY_TEST_LOGE("has no back buffer display id %d", mId));
198 return DISPLAY_SUCCESS;
199 }
200
RegDisplayVBlankCallback(VBlankCallback cb,void * data)201 int32_t HdiTestDisplay::RegDisplayVBlankCallback(VBlankCallback cb, void *data)
202 {
203 int ret = HdiTestDevice::GetInstance().GetDeviceFuncs().RegDisplayVBlankCallback(mId, cb, data);
204 return ret;
205 }
206
SetDisplayVsyncEnabled(bool enabled)207 int32_t HdiTestDisplay::SetDisplayVsyncEnabled(bool enabled)
208 {
209 int ret = HdiTestDevice::GetInstance().GetDeviceFuncs().SetDisplayVsyncEnabled(mId, enabled);
210 return ret;
211 }
212
GetLayerFromId(uint32_t id)213 std::shared_ptr<HdiTestLayer> HdiTestDisplay::GetLayerFromId(uint32_t id)
214 {
215 auto layerMap = mLayerMaps.find(id);
216 DISPLAY_TEST_CHK_RETURN((layerMap == mLayerMaps.end()), nullptr,
217 DISPLAY_TEST_LOGE("can not find the layer id : %d", id));
218 return layerMap->second;
219 }
220
Clear()221 void HdiTestDisplay::Clear()
222 {
223 DISPLAY_TEST_LOGI();
224 for (auto const & iter : mLayerMaps) {
225 uint32_t layerId = iter.first;
226 HdiTestDevice::GetInstance().GetLayerFuncs().CloseLayer(mId, layerId);
227 }
228 mLayerMaps.clear();
229 DISPLAY_TEST_LOGI("mLayerMaps size %zd", mLayerMaps.size());
230 }
231 } // OHOS
232 } // HDI
233 } // DISPLAY
234 } // TEST
235