• 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_display.h"
17 #include <vector>
18 #include "display_common.h"
19 
20 namespace OHOS {
21     namespace HDI {
22         namespace DISPLAY {
23             uint32_t HdiDisplay::mIdleId = 0;
24             std::unordered_set<uint32_t> HdiDisplay::mIdSets;
25 
GetIdleId()26             uint32_t HdiDisplay::GetIdleId()
27             {
28                 const uint32_t oldIdleId = mIdleId;
29                 uint32_t id = INVALIDE_DISPLAY_ID;
30                 // ensure the mIdleId not INVALIDE_DISPLAY_ID
31                 mIdleId = mIdleId % INVALIDE_DISPLAY_ID;
32                 do {
33                     auto iter = mIdSets.find(mIdleId);
34                     if (iter == mIdSets.end()) {
35                         id = mIdleId;
36                         break;
37                     }
38                     mIdleId = (mIdleId + 1) % INVALIDE_DISPLAY_ID;
39                 } while (oldIdleId != mIdleId);
40                 mIdSets.emplace(id);
41                 mIdleId++;
42                 return id;
43             }
44 
Init()45             int32_t HdiDisplay::Init()
46             {
47                 DISPLAY_DEBUGLOG();
48                 uint32_t id = GetIdleId();
49                 DISPLAY_CHK_RETURN((id == INVALIDE_DISPLAY_ID), DISPLAY_FAILURE, DISPLAY_LOGE("have no id to used"));
50                 mId = id;
51                 auto layer = CreateHdiLayer(LAYER_TYPE_GRAPHIC);
52                 DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE,
53                                    DISPLAY_LOGE("can not create hdi layer for client"));
54                 mClientLayer = std::move(layer);
55                 DISPLAY_DEBUGLOG("the id is %{public}d", id);
56                 return DISPLAY_SUCCESS;
57             }
58 
~HdiDisplay()59             HdiDisplay::~HdiDisplay()
60             {
61                 mIdSets.erase(mId);
62             }
63 
SetLayerZorder(uint32_t layerId,uint32_t zorder)64             int32_t HdiDisplay::SetLayerZorder(uint32_t layerId, uint32_t zorder)
65             {
66                 DISPLAY_DEBUGLOG("layerId : %{public}d", layerId);
67                 auto iter = mLayersMap.find(layerId);
68                 DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
69                                    DISPLAY_LOGE("can not find the layer %{public}d", layerId));
70                 auto layer = mLayersMap[layerId].get();
71                 if (layer->GetZorder() == zorder) {
72                     DISPLAY_DEBUGLOG("zorder no change layerId %{public}d, zorder %{public}d", layerId, zorder);
73                     return DISPLAY_SUCCESS;
74                 }
75                 // reset to sort
76                 auto zRange = mLayers.equal_range(layer);
77                 DISPLAY_DEBUGLOG("zorder range : zRange.first %{public}p  zRange.second %{public}p", *zRange.first,
78                                  *zRange.second);
79                 for (auto c = zRange.first; c != zRange.second; c++) {
80                     if (*c == layer) {
81                         mLayers.erase(c);
82                         break;
83                     }
84                 }
85                 layer->SetLayerZorder(zorder);
86                 mLayers.emplace(layer);
87                 return DISPLAY_SUCCESS;
88             }
89 
CreateLayer(const LayerInfo * layerInfo,uint32_t * layerId)90             int32_t HdiDisplay::CreateLayer(const LayerInfo *layerInfo, uint32_t *layerId)
91             {
92                 DISPLAY_DEBUGLOG();
93                 int ret;
94                 DISPLAY_CHK_RETURN((layerInfo == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("LayerInfo is null"));
95                 DISPLAY_CHK_RETURN((layerId == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("layerId is null"));
96                 auto layer = CreateHdiLayer(layerInfo->type);
97                 DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create hdi layer"));
98                 ret = layer->Init();
99                 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Layer Init failed"));
100                 *layerId = layer->GetId();
101                 mLayers.insert(layer.get());
102                 mLayersMap.emplace(layer->GetId(), std::move(layer));
103                 DISPLAY_DEBUGLOG("mLayers size %{public}zu", mLayers.size());
104                 DISPLAY_DEBUGLOG("mLayerMap size %{public}zu", mLayersMap.size());
105                 return DISPLAY_SUCCESS;
106             }
107 
CreateHdiLayer(LayerType type)108             std::unique_ptr<HdiLayer> HdiDisplay::CreateHdiLayer(LayerType type)
109             {
110                 DISPLAY_DEBUGLOG();
111                 return std::make_unique<HdiLayer>(type);
112             }
113 
CloseLayer(uint32_t layerId)114             int32_t HdiDisplay::CloseLayer(uint32_t layerId)
115             {
116                 DISPLAY_DEBUGLOG("layerId %{public}d", layerId);
117                 auto iter = mLayersMap.find(layerId);
118                 DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
119                                    DISPLAY_LOGE("can not find the layer id %{public}d", layerId));
120                 mLayers.erase(iter->second.get());
121                 mLayersMap.erase(layerId);
122                 return DISPLAY_SUCCESS;
123             }
124 
GetDisplayCompChange(uint32_t * num,uint32_t * layers,int32_t * type)125             int32_t HdiDisplay::GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type)
126             {
127                 DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
128                 *num = mChangeLayers.size();
129                 if ((layers == nullptr) && (type == nullptr)) {
130                     return DISPLAY_SUCCESS;
131                 }
132                 DISPLAY_DEBUGLOG("set the layers and type");
133                 for (uint32_t i = 0; i < mChangeLayers.size(); i++) {
134                     HdiLayer *layer = mChangeLayers[i];
135                     if (layers != nullptr) {
136                         *(layers + i) = layer->GetId();
137                     }
138                     if (type != nullptr) {
139                         *(type + i) = layer->GetCompositionType();
140                     }
141                 }
142                 return DISPLAY_SUCCESS;
143             }
144 
GetDisplayReleaseFence(uint32_t * num,uint32_t * layers,int32_t * fences)145             int32_t HdiDisplay::GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences)
146             {
147                 DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
148                 *num = mLayers.size();
149                 if ((layers == nullptr) && (fences == nullptr)) {
150                     return DISPLAY_SUCCESS;
151                 }
152                 DISPLAY_DEBUGLOG("set the layer fences");
153                 int i = 0;
154                 for (auto layer : mLayers) {
155                     if (layers != nullptr) {
156                         *(layers + i) = layer->GetId();
157                     }
158                     if (fences != nullptr) {
159                         *(fences + i) = dup(layer->GetReleaseFenceFd());
160                     }
161                     DISPLAY_DEBUGLOG("layer id %{public}d fencefd %{public}d", layer->GetId(),
162                                      layer->GetReleaseFenceFd());
163                     i++;
164                 }
165                 return DISPLAY_SUCCESS;
166             }
167 
PrepareDisplayLayers(bool * needFlushFb)168             int32_t HdiDisplay::PrepareDisplayLayers(bool *needFlushFb)
169             {
170                 DISPLAY_DEBUGLOG();
171                 mChangeLayers.clear();
172                 std::vector<HdiLayer *> layers;
173                 uint32_t topZpos = 3;
174                 for (auto c : mLayers) {
175                     layers.push_back(c);
176                 }
177                 DISPLAY_DEBUGLOG(" mLayers  size %{public}zu layers size %{public}zu", mLayers.size(), layers.size());
178 
179                 /* Set the target layer to the top.
180                  *  It would not by cover by other layer.
181                  */
182                 mClientLayer->SetLayerZorder(topZpos);
183 
184                 mComposer->Prepare(layers, *mClientLayer);
185                 // get the change layers
186                 for (auto &layer : layers) {
187                     if (layer->GetDeviceSelect() != layer->GetCompositionType()) {
188                         DISPLAY_DEBUGLOG("layer change");
189                         layer->SetLayerCompositionType(layer->GetDeviceSelect());
190                     }
191                     mChangeLayers.push_back(layer);
192                 }
193                 *needFlushFb = true;
194                 return DISPLAY_SUCCESS;
195             }
196 
Commit(int32_t * fence)197             int32_t HdiDisplay::Commit(int32_t *fence)
198             {
199                 DISPLAY_DEBUGLOG();
200                 mComposer->Commit(false);
201                 *fence = dup(mClientLayer->GetReleaseFenceFd());
202                 DISPLAY_DEBUGLOG("the release fence is %{public}d", *fence);
203                 return DISPLAY_SUCCESS;
204             }
205 
SetDisplayClientBuffer(const BufferHandle * buffer,int32_t fence)206             int32_t HdiDisplay::SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence)
207             {
208                 mClientLayer->SetLayerBuffer(buffer, fence);
209                 return DISPLAY_SUCCESS;
210             }
211 
GetHdiLayer(uint32_t id)212             HdiLayer *HdiDisplay::GetHdiLayer(uint32_t id)
213             {
214                 DISPLAY_DEBUGLOG("id : %{public}d", id);
215                 auto iter = mLayersMap.find(id);
216                 DISPLAY_CHK_RETURN((iter == mLayersMap.end()), nullptr,
217                                    DISPLAY_LOGE("can not find the layer %{public}d", id));
218                 return iter->second.get();
219             }
220 
VsyncCallBack(VBlankCallback cb,void * data,uint32_t displayId)221             VsyncCallBack::VsyncCallBack(VBlankCallback cb, void *data, uint32_t displayId)
222                 : mVBlankCb(cb), mData(data), mPipe(displayId)
223             {
224                 DISPLAY_DEBUGLOG("VsyncCallBack %{public}p", cb);
225             }
226 
Vsync(unsigned int sequence,uint64_t ns)227             void VsyncCallBack::Vsync(unsigned int sequence, uint64_t ns)
228             {
229                 DISPLAY_CHK_RETURN_NOT_VALUE((mVBlankCb == nullptr), DISPLAY_LOGE("the callback is nullptr"));
230                 mVBlankCb(sequence, ns, mData);
231             }
232         }
233     }
234 }
235