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_log.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
45
Init()46 int32_t HdiDisplay::Init()
47 {
48 DISPLAY_LOGD();
49 uint32_t id = GetIdleId();
50 DISPLAY_CHK_RETURN((id == INVALIDE_DISPLAY_ID), DISPLAY_FAILURE, DISPLAY_LOGE("have no id to used"));
51 mId = id;
52 auto layer = CreateHdiLayer(LAYER_TYPE_GRAPHIC);
53 DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create hdi layer for client"));
54 mClientLayer = std::move(layer);
55 DISPLAY_LOGD("the id is %{public}d", id);
56 return DISPLAY_SUCCESS;
57 }
58
59
~HdiDisplay()60 HdiDisplay::~HdiDisplay()
61 {
62 mIdSets.erase(mId);
63 }
64
SetLayerZorder(uint32_t layerId,uint32_t zorder)65 int32_t HdiDisplay::SetLayerZorder(uint32_t layerId, uint32_t zorder)
66 {
67 DISPLAY_LOGD("layerId : %{public}d", layerId);
68 auto iter = mLayersMap.find(layerId);
69 DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
70 DISPLAY_LOGE("can not find the layer %{public}d", layerId));
71 auto layer = mLayersMap[layerId].get();
72 if (layer->GetZorder() == zorder) {
73 DISPLAY_LOGD("zorder no change layerId %{public}d, zorder %{public}d", layerId, zorder);
74 return DISPLAY_SUCCESS;
75 }
76 // reset to sort
77 auto zRange = mLayers.equal_range(layer);
78 DISPLAY_LOGD("zorder range : zRange.first %{public}p zRange.second %{public}p", *zRange.first, *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_LOGD();
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_LOGD("mLayers size %{public}zu", mLayers.size());
104 DISPLAY_LOGD("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_LOGD();
111 return std::make_unique<HdiLayer>(type);
112 }
113
114
DestroyLayer(uint32_t layerId)115 int32_t HdiDisplay::DestroyLayer(uint32_t layerId)
116 {
117 DISPLAY_LOGD("layerId %{public}d", layerId);
118 auto iter = mLayersMap.find(layerId);
119 DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
120 DISPLAY_LOGE("can not find the layer id %{public}d", layerId));
121 mLayers.erase(iter->second.get());
122 mLayersMap.erase(layerId);
123 return DISPLAY_SUCCESS;
124 }
125
GetDisplayCompChange(uint32_t * num,uint32_t * layers,int32_t * type)126 int32_t HdiDisplay::GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type)
127 {
128 DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
129 *num = mChangeLayers.size();
130 if ((layers == nullptr) && (type == nullptr)) {
131 return DISPLAY_SUCCESS;
132 }
133 DISPLAY_LOGD("set the layers and type");
134 for (uint32_t i = 0; i < mChangeLayers.size(); i++) {
135 HdiLayer *layer = mChangeLayers[i];
136 if (layers != nullptr) {
137 *(layers + i) = layer->GetId();
138 }
139 if (type != nullptr) {
140 *(type + i) = layer->GetCompositionType();
141 }
142 }
143 return DISPLAY_SUCCESS;
144 }
145
GetDisplayReleaseFence(uint32_t * num,uint32_t * layers,int32_t * fences)146 int32_t HdiDisplay::GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences)
147 {
148 DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
149 *num = mLayers.size();
150 if ((layers == nullptr) && (fences == nullptr)) {
151 return DISPLAY_SUCCESS;
152 }
153 DISPLAY_LOGD("set the layer fences");
154 int i = 0;
155 for (auto layer : mLayers) {
156 if (layers != nullptr) {
157 *(layers + i) = layer->GetId();
158 }
159 if (fences != nullptr) {
160 *(fences + i) = dup(layer->GetReleaseFenceFd());
161 }
162 DISPLAY_LOGD("layer id %{public}d fencefd %{public}d", layer->GetId(), layer->GetReleaseFenceFd());
163 i++;
164 }
165 return DISPLAY_SUCCESS;
166 }
167
PrepareDisplayLayers(bool * needFlushFb)168 int32_t HdiDisplay::PrepareDisplayLayers(bool *needFlushFb)
169 {
170 DISPLAY_LOGD();
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_LOGD(" 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_LOGD("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_LOGD();
200 mComposer->Commit(false);
201 *fence = dup(mClientLayer->GetReleaseFenceFd());
202 DISPLAY_LOGD("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_LOGD("id : %{public}d", id);
215 auto iter = mLayersMap.find(id);
216 DISPLAY_CHK_RETURN((iter == mLayersMap.end()), nullptr, DISPLAY_LOGE("can not find the layer %{public}d", id));
217 return iter->second.get();
218 }
219
VsyncCallBack(VBlankCallback cb,void * data,uint32_t displayId)220 VsyncCallBack::VsyncCallBack(VBlankCallback cb, void *data, uint32_t displayId) : mVBlankCb(cb),
221 mData(data), mPipe(displayId)
222 {
223 DISPLAY_LOGD("VsyncCallBack %{public}p", cb);
224 }
225
Vsync(unsigned int sequence,uint64_t ns)226 void VsyncCallBack::Vsync(unsigned int sequence, uint64_t ns)
227 {
228 DISPLAY_CHK_RETURN_NOT_VALUE((mVBlankCb == nullptr), DISPLAY_LOGE("the callback is nullptr"));
229 mVBlankCb(sequence, ns, mData);
230 }
231 }
232 }
233 }
234