• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "unistd.h"
18 #include "display_test_utils.h"
19 #include "hdi_test_device.h"
20 namespace OHOS {
21 namespace HDI {
22 namespace Display {
23 namespace TEST {
24 using namespace OHOS::HDI::Display::Composer::V1_1;
HdiTestDisplay(uint32_t id,sptr<Composer::V1_1::IDisplayComposerInterface> device)25 HdiTestDisplay::HdiTestDisplay(uint32_t id, sptr<Composer::V1_1::IDisplayComposerInterface> device)
26     : id_(id), device_(device), currentFb_(nullptr)
27 {
28 }
29 
Init()30 int32_t HdiTestDisplay::Init()
31 {
32     DISPLAY_TEST_LOGE();
33     int ret = device_->GetDisplayCapability(id_, cap_);
34     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get cap"));
35     DISPLAY_TEST_LOGE("the capablility name %s type : %{public}d phyWidth : %{public}d phyHeight : %{public}d",
36         cap_.name.c_str(), cap_.type, cap_.phyWidth, cap_.phyHeight);
37     // get the modes
38     ret = device_->GetDisplaySupportedModes(id_, modes_);
39     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get modes"));
40     DISPLAY_TEST_LOGE("the modes size() %{public}zu", modes_.size());
41 
42     ret = device_->GetDisplayMode(id_, activeModeId_);
43     DISPLAY_TEST_CHK_RETURN(
44         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the mode id is : %{public}u", activeModeId_));
45 
46     ret = GetModeInfoFromId(activeModeId_, currentMode_);
47     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
48         DISPLAY_TEST_LOGE("can not get the mode of id : %{public}u", activeModeId_));
49 
50     ret = device_->SetDisplayPowerStatus(id_, Composer::V1_0::DispPowerStatus::POWER_STATUS_ON);
51     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
52         DISPLAY_TEST_LOGE("SetDisplayPowerStatus failed, id_ : %{public}u", id_));
53 
54     ret = device_->SetDisplayMode(id_, currentMode_.id);
55     DISPLAY_TEST_CHK_RETURN(
56         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("SetDisplayMode failed, id_ : %{public}u", id_));
57 
58     LayerInfo layerinfo = {0};
59     layerinfo.width = currentMode_.width;
60     layerinfo.height = currentMode_.height;
61     layerinfo.pixFormat = Composer::V1_0::PIXEL_FMT_BGRA_8888;
62     const uint32_t CLIENT_LAYER_ID = 0xffffffff; // invalid id
63     clientLayer_ = std::make_unique<HdiTestLayer>(layerinfo, CLIENT_LAYER_ID, id_);
64     ret = clientLayer_->Init();
65     DISPLAY_TEST_CHK_RETURN(
66         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the client layer can not be created"));
67 
68     ret = device_->SetClientBufferCacheCount(id_, clientLayer_->GetLayerBuffercount());
69     DISPLAY_TEST_CHK_RETURN(
70         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("setClientBufferCount error"));
71     return DISPLAY_SUCCESS;
72 }
73 
GetModeInfoFromId(int32_t id,DisplayModeInfo & modeInfo) const74 int32_t HdiTestDisplay::GetModeInfoFromId(int32_t id, DisplayModeInfo& modeInfo) const
75 {
76     DISPLAY_TEST_LOGE();
77     auto iter = std::find_if (std::begin(modes_), std::end(modes_), [id](const auto& mode) {
78         return mode.id == id;
79     });
80     if (iter != std::end(modes_)) {
81         modeInfo = *iter;
82         DISPLAY_TEST_LOGE("the mode width: %{public}d height : %{public}d freshRate : %{public}u id: %{public}d",
83             iter->width, iter->height, iter->freshRate, iter->id);
84         return DISPLAY_SUCCESS;
85     }
86     DISPLAY_TEST_LOGE("can not find the modeinfo id : %{public}d", id);
87     return DISPLAY_FAILURE;
88 }
89 
CreateHdiTestLayer(LayerInfo & info)90 std::shared_ptr<HdiTestLayer> HdiTestDisplay::CreateHdiTestLayer(LayerInfo& info)
91 {
92     DISPLAY_TEST_LOGE();
93     uint32_t layerId = 0;
94     int ret = device_->CreateLayer(id_, info, HdiTestLayer::MAX_BUFFER_COUNT, layerId);
95     DISPLAY_TEST_LOGE("CreateLayer layerId %{public}u", layerId);
96     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_TEST_LOGE("layer creat failed"));
97     auto layer = std::make_shared<HdiTestLayer>(info, layerId, id_);
98     ret = layer->Init();
99     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_TEST_LOGE("layer init failed"));
100     layerMaps_.emplace(layerId, layer);
101     return layer;
102 }
103 
CreateHdiTestLayer(uint32_t w,uint32_t h)104 std::shared_ptr<HdiTestLayer> HdiTestDisplay::CreateHdiTestLayer(uint32_t w, uint32_t h)
105 {
106     const int32_t BPP = 32;
107 
108     LayerInfo info = {w, h, LAYER_TYPE_GRAPHIC, BPP, Composer::V1_0::PIXEL_FMT_RGBA_8888};
109     return CreateHdiTestLayer(info);
110 }
111 
RefreshLayersCompType()112 int32_t HdiTestDisplay::RefreshLayersCompType()
113 {
114     int ret;
115     std::vector<uint32_t> layers;
116     std::vector<int32_t> types;
117     ret = device_->GetDisplayCompChange(id_, layers, types);
118     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
119         DISPLAY_TEST_LOGE("GetDisplayCompChange get layers and types failed"));
120     DISPLAY_TEST_LOGE("the change numbers %{public}zu, layers size %{public}zu", layers.size(), layers.size());
121     for (uint32_t i = 0; i < layers.size(); i++) {
122         DISPLAY_TEST_LOGE(" the layer id %{public}u ", layers[i]);
123         std::shared_ptr<HdiTestLayer> layer = GetLayerFromId(layers[i]);
124         layer->SetCompType(static_cast<Composer::V1_0::CompositionType>(types[i]));
125     }
126     return DISPLAY_SUCCESS;
127 }
128 
GetLayersReleaseFence()129 int32_t HdiTestDisplay::GetLayersReleaseFence()
130 {
131     int ret;
132     std::vector<uint32_t> layers;
133     std::vector<int32_t> fences;
134 
135     ret = device_->GetDisplayReleaseFence(id_, layers, fences);
136     DISPLAY_TEST_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("GetDisplayReleaseFence get data failed"));
137     DISPLAY_TEST_LOGE("the release fence numbers %{public}zu, layers size %{public}zu", layers.size(), layers.size());
138     for (uint32_t i = 0; i < layers.size(); i++) {
139         DISPLAY_TEST_LOGE(" the layer id %{public}u, fence: 0x%x", layers[i], fences[i]);
140         std::shared_ptr<HdiTestLayer> layer = GetLayerFromId(layers[i]);
141         layer->SetReleaseFence(fences[i]);
142     }
143     return DISPLAY_SUCCESS;
144 }
145 
PrepareDisplayLayers()146 int32_t HdiTestDisplay::PrepareDisplayLayers()
147 {
148     int ret;
149     needFlushFb_ = false;
150     DISPLAY_TEST_LOGE("id : %{public}u  layer size %{public}zu", id_, layerMaps_.size());
151     for (const auto& layerMap : layerMaps_) {
152         ret = layerMap.second->PreparePresent();
153         DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
154             DISPLAY_TEST_LOGE("layer %{public}d Prepare failed", layerMap.first));
155     }
156     ret = device_->PrepareDisplayLayers(id_, needFlushFb_);
157     DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
158         DISPLAY_TEST_LOGE("PrepareDisplayLayers failed display id %{public}u", id_));
159     ret = RefreshLayersCompType();
160     DISPLAY_TEST_CHK_RETURN(
161         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("RefreshLayersCompType failed"));
162     return DISPLAY_SUCCESS;
163 }
164 
Commit()165 int32_t HdiTestDisplay::Commit()
166 {
167     int32_t fenceFd;
168     int ret;
169     HdiGrallocBuffer* buffer = nullptr;
170     if (needFlushFb_) {
171         ret = clientLayer_->SwapFrontToBackQ();
172         DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
173             DISPLAY_TEST_LOGE("has no front buffer display id %{public}u", id_));
174 
175         buffer = clientLayer_->GetBackBuffer();
176         DISPLAY_TEST_CHK_RETURN((buffer == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get back buffer"));
177         BufferHandle* handle = buffer->Get();
178         DISPLAY_TEST_CHK_RETURN((handle == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("BufferHandle is null"));
179         ClearColor(*handle, 0); // need clear the fb first
180 
181         ret = buffer->SetGraphicBuffer([&](const BufferHandle* buffer, uint32_t seqNo) -> int32_t {
182             int32_t result = device_->SetDisplayClientBuffer(id_, buffer, seqNo, -1);
183             DISPLAY_TEST_CHK_RETURN(
184                 (result != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set client buffer handle failed"));
185             return DISPLAY_SUCCESS;
186         });
187         currentFb_ = handle;
188         DISPLAY_TEST_CHK_RETURN(
189             (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set client buffer handle failed"));
190     }
191 
192     ret = device_->Commit(id_, fenceFd);
193     DISPLAY_TEST_CHK_RETURN(
194         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("commit failed display id %{public}u", id_));
195     ret = GetLayersReleaseFence();
196     DISPLAY_TEST_CHK_RETURN(
197         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("GetLayersReleaseFence failed %{public}u", id_));
198 
199     if (needFlushFb_) {
200         DISPLAY_TEST_LOGE("commit out client buffer fence: %{public}d", fenceFd);
201         buffer->SetReleaseFence(fenceFd);
202         ret = clientLayer_->SwapBackToFrontQ();
203     }
204     DISPLAY_TEST_CHK_RETURN(
205         (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("has no back buffer display id %{public}u", id_));
206     return DISPLAY_SUCCESS;
207 }
208 
RegDisplayVBlankCallback(VBlankCallback cb,void * data) const209 int32_t HdiTestDisplay::RegDisplayVBlankCallback(VBlankCallback cb, void* data) const
210 {
211     int ret = device_->RegDisplayVBlankCallback(id_, cb, data);
212     return ret;
213 }
214 
SetDisplayVsyncEnabled(bool enabled) const215 int32_t HdiTestDisplay::SetDisplayVsyncEnabled(bool enabled) const
216 {
217     int ret = device_->SetDisplayVsyncEnabled(id_, enabled);
218     return ret;
219 }
220 
GetLayerFromId(uint32_t id)221 std::shared_ptr<HdiTestLayer> HdiTestDisplay::GetLayerFromId(uint32_t id)
222 {
223     auto layerMap = layerMaps_.find(id);
224     DISPLAY_TEST_CHK_RETURN(
225         (layerMap == layerMaps_.end()), nullptr, DISPLAY_TEST_LOGE("can not find the layer id : %{public}u", id));
226     return layerMap->second;
227 }
228 
Clear()229 void HdiTestDisplay::Clear()
230 {
231     DISPLAY_TEST_LOGE();
232     for (auto const& iter : layerMaps_) {
233         uint32_t layerId = iter.first;
234         device_->DestroyLayer(id_, layerId);
235     }
236     layerMaps_.clear();
237     DISPLAY_TEST_LOGE("layerMaps_ size %{public}zu", layerMaps_.size());
238 }
239 } // namespace TEST
240 } // namespace Display
241 } // namespace HDI
242 } // namespace OHOS
243