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 "hdi_output.h"
17
18 namespace OHOS {
19 namespace Rosen {
20
CreateHdiOutput(uint32_t screenId)21 std::shared_ptr<HdiOutput> HdiOutput::CreateHdiOutput(uint32_t screenId)
22 {
23 return std::make_shared<HdiOutput>(screenId);
24 }
25
HdiOutput(uint32_t screenId)26 HdiOutput::HdiOutput(uint32_t screenId) : screenId_(screenId)
27 {
28 }
29
~HdiOutput()30 HdiOutput::~HdiOutput()
31 {
32 }
33
Init()34 RosenError HdiOutput::Init()
35 {
36 if (fbSurface_ != nullptr) {
37 return ROSEN_ERROR_OK;
38 }
39
40 fbSurface_ = HdiFramebufferSurface::CreateFramebufferSurface();
41 if (fbSurface_ == nullptr) {
42 HLOGE("Create framebuffer surface failed");
43 return ROSEN_ERROR_NOT_INIT;
44 }
45
46 return ROSEN_ERROR_OK;
47 }
48
SetLayerInfo(const std::vector<LayerInfoPtr> & layerInfos)49 void HdiOutput::SetLayerInfo(const std::vector<LayerInfoPtr> &layerInfos)
50 {
51 for (auto &layerInfo : layerInfos) {
52 if (layerInfo == nullptr || layerInfo->GetSurface() == nullptr) {
53 HLOGE("current layerInfo or layerInfo's cSurface is null");
54 continue;
55 }
56 uint64_t surfaceId = layerInfo->GetSurface()->GetUniqueId();
57 auto iter = surfaceIdMap_.find(surfaceId);
58 if (iter != surfaceIdMap_.end()) {
59 const LayerPtr &layer = iter->second;
60 const LayerInfoPtr &info = layer->GetLayerInfo();
61 if (info->GetLayerSize().w == layerInfo->GetLayerSize().w &&
62 info->GetLayerSize().h == layerInfo->GetLayerSize().h)
63 {
64 layer->UpdateLayerInfo(layerInfo);
65 continue;
66 }
67 }
68
69 int32_t ret = CreateLayer(surfaceId, layerInfo);
70 if (ret != DISPLAY_SUCCESS) {
71 return;
72 }
73 }
74
75 DeletePrevLayers();
76 ResetLayerStatus();
77 }
78
DeletePrevLayers()79 void HdiOutput::DeletePrevLayers()
80 {
81 auto surfaceIter = surfaceIdMap_.begin();
82 while (surfaceIter != surfaceIdMap_.end()) {
83 const LayerPtr &layer = surfaceIter->second;
84 if (!layer->GetLayerStatus()) {
85 surfaceIdMap_.erase(surfaceIter++);
86 } else {
87 ++surfaceIter;
88 }
89 }
90
91 auto layerIter = layerIdMap_.begin();
92 while (layerIter != layerIdMap_.end()) {
93 const LayerPtr &layer = layerIter->second;
94 if (!layer->GetLayerStatus()) {
95 layerIdMap_.erase(layerIter++);
96 } else {
97 ++layerIter;
98 }
99 }
100 }
101
ResetLayerStatus()102 void HdiOutput::ResetLayerStatus()
103 {
104 for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); ++iter) {
105 iter->second->SetLayerStatus(false);
106 }
107 }
108
CreateLayer(uint64_t surfaceId,const LayerInfoPtr & layerInfo)109 int32_t HdiOutput::CreateLayer(uint64_t surfaceId, const LayerInfoPtr &layerInfo)
110 {
111 LayerPtr layer = HdiLayer::CreateHdiLayer(screenId_);
112 if (!layer->Init(layerInfo)) {
113 HLOGE("Init hdiLayer failed");
114 return DISPLAY_FAILURE;
115 }
116
117 layer->UpdateLayerInfo(layerInfo);
118 uint32_t layerId = layer->GetLayerId();
119 layerIdMap_[layerId] = layer;
120 surfaceIdMap_[surfaceId] = layer;
121
122 return DISPLAY_SUCCESS;
123 }
124
SetOutputDamage(uint32_t num,const IRect & outputDamage)125 void HdiOutput::SetOutputDamage(uint32_t num, const IRect &outputDamage)
126 {
127 outputDamageNum_ = num;
128 outputDamage_ = outputDamage;
129 }
130
GetOutputDamage()131 /* const */ IRect& HdiOutput::GetOutputDamage()
132 {
133 return outputDamage_;
134 }
135
GetOutputDamageNum() const136 uint32_t HdiOutput::GetOutputDamageNum() const
137 {
138 return outputDamageNum_;
139 }
140
GetLayers()141 const std::unordered_map<uint32_t, std::shared_ptr<HdiLayer>>& HdiOutput::GetLayers()
142 {
143 return layerIdMap_;
144 }
145
UpdatePrevLayerInfo()146 void HdiOutput::UpdatePrevLayerInfo()
147 {
148 for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); iter++) {
149 LayerPtr layer = iter->second;
150 layer->SavePrevLayerInfo();
151 }
152 }
153
GetScreenId() const154 uint32_t HdiOutput::GetScreenId() const
155 {
156 return screenId_;
157 }
158
SetLayerCompCapacity(uint32_t layerCompositionCapacity)159 void HdiOutput::SetLayerCompCapacity(uint32_t layerCompositionCapacity)
160 {
161 layerCompCapacity_ = layerCompositionCapacity;
162 }
163
GetLayerCompCapacity() const164 uint32_t HdiOutput::GetLayerCompCapacity() const
165 {
166 return layerCompCapacity_;
167 }
168
GetFrameBufferSurface()169 sptr<Surface> HdiOutput::GetFrameBufferSurface()
170 {
171 if (!CheckFbSurface()) {
172 return nullptr;
173 }
174
175 return fbSurface_->GetSurface();
176 }
177
GetFramebuffer()178 std::unique_ptr<FrameBufferEntry> HdiOutput::GetFramebuffer()
179 {
180 if (!CheckFbSurface()) {
181 return nullptr;
182 }
183
184 return fbSurface_->GetFramebuffer();
185 }
186
ReleaseFramebuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & releaseFence)187 int32_t HdiOutput::ReleaseFramebuffer(
188 sptr<SurfaceBuffer> &buffer,
189 const sptr<SyncFence>& releaseFence)
190 {
191 if (!CheckFbSurface()) {
192 return -1;
193 }
194
195 return fbSurface_->ReleaseFramebuffer(buffer, releaseFence);
196 }
197
CheckFbSurface()198 bool HdiOutput::CheckFbSurface()
199 {
200 if (fbSurface_ == nullptr) {
201 HLOGE("fbSurface is nullptr");
202 return false;
203 }
204
205 return true;
206 }
207
RecordCompositionTime(int64_t timeStamp)208 void HdiOutput::RecordCompositionTime(int64_t timeStamp)
209 {
210 compositionTimeRecords_[compTimeRcdIndex_] = timeStamp;
211 compTimeRcdIndex_ = (compTimeRcdIndex_ + 1) % COMPOSITION_RECORDS_NUM;
212 }
213
SetDirectClientCompEnableStatus(bool enableStatus)214 void HdiOutput::SetDirectClientCompEnableStatus(bool enableStatus)
215 {
216 directClientCompositionEnabled_ = enableStatus;
217 }
218
GetDirectClientCompEnableStatus() const219 bool HdiOutput::GetDirectClientCompEnableStatus() const
220 {
221 return directClientCompositionEnabled_;
222 }
223
Dump(std::string & result) const224 void HdiOutput::Dump(std::string &result) const
225 {
226 std::vector<LayerDumpInfo> dumpLayerInfos;
227 ReorderLayerInfo(dumpLayerInfos);
228
229 result.append("\n");
230 result.append("-- LayerInfo\n");
231
232 for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
233 const LayerPtr &layer = layerInfo.layer;
234 if (layer == nullptr || layer->GetLayerInfo() == nullptr ||
235 layer->GetLayerInfo()->GetSurface() == nullptr) {
236 continue;
237 }
238 const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
239 const LayerInfoPtr &info = layer->GetLayerInfo();
240 result += "\n surface [" + name + "] NodeId[" + std::to_string(layerInfo.surfaceId) + "]";
241 result += " LayerId[" + std::to_string(layer->GetLayerId()) + "]:\n";
242 info->Dump(result);
243 }
244
245 if (fbSurface_ != nullptr) {
246 result += "\n";
247 result += "FrameBufferSurface\n";
248 fbSurface_->Dump(result);
249 }
250 }
251
DumpFps(std::string & result,const std::string & arg) const252 void HdiOutput::DumpFps(std::string &result, const std::string &arg) const
253 {
254 std::vector<LayerDumpInfo> dumpLayerInfos;
255 ReorderLayerInfo(dumpLayerInfos);
256
257 result.append("\n");
258 if (arg == "composer") {
259 result += "The fps of screen [Id:" + std::to_string(screenId_) + "] is:\n";
260 const int32_t offset = compTimeRcdIndex_;
261 for (uint32_t i = 0; i < COMPOSITION_RECORDS_NUM; i++) {
262 uint32_t order = (offset + i) % COMPOSITION_RECORDS_NUM;
263 result += std::to_string(compositionTimeRecords_[order]) + "\n";
264 }
265 return;
266 }
267
268 for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
269 const LayerPtr &layer = layerInfo.layer;
270 const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
271 if (name == arg) {
272 result += "\n surface [" + name + "] Id[" + std::to_string(layerInfo.surfaceId) + "]:\n";
273 layer->Dump(result);
274 }
275 }
276 }
277
ClearFpsDump(std::string & result,const std::string & arg)278 void HdiOutput::ClearFpsDump(std::string &result, const std::string &arg)
279 {
280 std::vector<LayerDumpInfo> dumpLayerInfos;
281 ReorderLayerInfo(dumpLayerInfos);
282
283 result.append("\n");
284 if (arg == "composer") {
285 result += "The fps info of screen [Id:" + std::to_string(screenId_) + "] is cleared.\n";
286 compositionTimeRecords_.fill(0);
287 return;
288 }
289
290 for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
291 const LayerPtr &layer = layerInfo.layer;
292 const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
293 if (name == arg) {
294 result += "\n The fps info of surface [" + name + "] Id["
295 + std::to_string(layerInfo.surfaceId) + "] is cleared.\n";
296 layer->ClearDump();
297 }
298 }
299 }
300
301
Cmp(const LayerDumpInfo & layer1,const LayerDumpInfo & layer2)302 static inline bool Cmp(const LayerDumpInfo &layer1, const LayerDumpInfo &layer2)
303 {
304 return layer1.layer->GetLayerInfo()->GetZorder() < layer2.layer->GetLayerInfo()->GetZorder();
305 }
306
ReorderLayerInfo(std::vector<LayerDumpInfo> & dumpLayerInfos) const307 void HdiOutput::ReorderLayerInfo(std::vector<LayerDumpInfo> &dumpLayerInfos) const
308 {
309 for (auto iter = surfaceIdMap_.begin(); iter != surfaceIdMap_.end(); ++iter) {
310 struct LayerDumpInfo layerInfo = {
311 .surfaceId = iter->first,
312 .layer = iter->second,
313 };
314 dumpLayerInfos.emplace_back(layerInfo);
315 }
316
317 std::sort(dumpLayerInfos.begin(), dumpLayerInfos.end(), Cmp);
318 }
319 } // namespace Rosen
320 } // namespace OHOS
321