• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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