• 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 
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 zorder:%{public}d size:%{public}zu", layerId, zorder, mLayers.size());
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             DISPLAY_LOGD("erase layer:%{public}p", layer);
82             mLayers.erase(c);
83             break;
84         }
85     }
86     layer->SetLayerZorder(zorder);
87     mLayers.emplace(layer);
88     DISPLAY_LOGD("SetLayerZorder size:%{public}zu", mLayers.size());
89     return DISPLAY_SUCCESS;
90 }
91 
CreateLayer(const LayerInfo * layerInfo,uint32_t * layerId)92 int32_t HdiDisplay::CreateLayer(const LayerInfo *layerInfo, uint32_t *layerId)
93 {
94     DISPLAY_LOGD();
95     int ret;
96     DISPLAY_CHK_RETURN((layerInfo == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("LayerInfo is null"));
97     DISPLAY_CHK_RETURN((layerId == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("layerId is null"));
98     auto layer = CreateHdiLayer(layerInfo->type);
99     DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create hdi layer"));
100     ret = layer->Init();
101     DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Layer Init failed"));
102     *layerId = layer->GetId();
103     mLayers.insert(layer.get());
104     mLayersMap.emplace(layer->GetId(), std::move(layer));
105     DISPLAY_LOGD("mLayers size %{public}zu", mLayers.size());
106     DISPLAY_LOGD("mLayerMap size %{public}zu", mLayersMap.size());
107     return DISPLAY_SUCCESS;
108 }
109 
CreateHdiLayer(LayerType type)110 std::unique_ptr<HdiLayer> HdiDisplay::CreateHdiLayer(LayerType type)
111 {
112     DISPLAY_LOGD();
113     return std::make_unique<HdiLayer>(type);
114 }
115 
116 
CloseLayer(uint32_t layerId)117 int32_t HdiDisplay::CloseLayer(uint32_t layerId)
118 {
119     DISPLAY_LOGD("layerId %{public}d", layerId);
120     auto iter = mLayersMap.find(layerId);
121     DISPLAY_CHK_RETURN((iter == mLayersMap.end()), DISPLAY_FAILURE,
122         DISPLAY_LOGE("can not find the layer id %{public}d", layerId));
123     auto layer = iter->second.get();
124     auto zRange = mLayers.equal_range(layer);
125     DISPLAY_LOGD("zorder range:zRange.first %{public}p, zRange.second %{public}p", *zRange.first, *zRange.second);
126     for (auto c = zRange.first; c != zRange.second; c++) {
127         if (*c == layer) {
128             DISPLAY_LOGD("erase layer:%{public}p", layer);
129             mLayers.erase(c);
130             break;
131         }
132     }
133     mLayersMap.erase(layerId);
134     return DISPLAY_SUCCESS;
135 }
136 
GetDisplayCompChange(uint32_t * num,uint32_t * layers,int32_t * type)137 int32_t HdiDisplay::GetDisplayCompChange(uint32_t *num, uint32_t *layers, int32_t *type)
138 {
139     DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
140     *num = mChangeLayers.size();
141     if ((layers == nullptr) && (type == nullptr)) {
142         return DISPLAY_SUCCESS;
143     }
144     DISPLAY_LOGD("set the layers and type");
145     for (uint32_t i = 0; i < mChangeLayers.size(); i++) {
146         HdiLayer *layer = mChangeLayers[i];
147         if (layers != nullptr) {
148             *(layers + i) = layer->GetId();
149         }
150         if (type != nullptr) {
151             *(type + i) = layer->GetCompositionType();
152         }
153     }
154     return DISPLAY_SUCCESS;
155 }
156 
GetDisplayReleaseFence(uint32_t * num,uint32_t * layers,int32_t * fences)157 int32_t HdiDisplay::GetDisplayReleaseFence(uint32_t *num, uint32_t *layers, int32_t *fences)
158 {
159     DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the num is nullptr"));
160     *num = mLayers.size();
161     if ((layers == nullptr) && (fences == nullptr)) {
162         return DISPLAY_SUCCESS;
163     }
164     DISPLAY_LOGD("set the layer fences");
165     int i = 0;
166     for (auto layer : mLayers) {
167         if (layers != nullptr) {
168             *(layers + i) = layer->GetId();
169         }
170         if (fences != nullptr) {
171             *(fences + i) = dup(layer->GetReleaseFenceFd());
172         }
173         DISPLAY_LOGD("layer id %{public}d fencefd %{public}d", layer->GetId(), layer->GetReleaseFenceFd());
174         i++;
175     }
176     return DISPLAY_SUCCESS;
177 }
178 
PrepareDisplayLayers(bool * needFlushFb)179 int32_t HdiDisplay::PrepareDisplayLayers(bool *needFlushFb)
180 {
181     DISPLAY_LOGD();
182     mChangeLayers.clear();
183     std::vector<HdiLayer *> layers;
184     for (auto c : mLayers) {
185         if (c->IsVisible()) {
186             layers.push_back(c);
187         }
188     }
189     DISPLAY_LOGD(" mLayers  size %{public}zu layers size %{public}zu", mLayers.size(), layers.size());
190 
191     mComposer->Prepare(layers, *mClientLayer);
192     // get the change layers
193     for (auto &layer : layers) {
194         if (layer->GetDeviceSelect() != layer->GetCompositionType()) {
195             DISPLAY_LOGD("layer change");
196             layer->SetLayerCompositionType(layer->GetDeviceSelect());
197         }
198         mChangeLayers.push_back(layer);
199     }
200     *needFlushFb = true;
201     return DISPLAY_SUCCESS;
202 }
203 
Commit(int32_t * fence)204 int32_t HdiDisplay::Commit(int32_t *fence)
205 {
206     DISPLAY_LOGD();
207     mComposer->Commit(false);
208     *fence = dup(mClientLayer->GetReleaseFenceFd());
209     DISPLAY_LOGD("the release fence is %{public}d", *fence);
210     return DISPLAY_SUCCESS;
211 }
212 
SetDisplayClientBuffer(const BufferHandle * buffer,int32_t fence)213 int32_t HdiDisplay::SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence)
214 {
215     DISPLAY_LOGD();
216     mClientLayer->SetLayerBuffer(buffer, fence);
217     return DISPLAY_SUCCESS;
218 }
219 
GetHdiLayer(uint32_t id)220 HdiLayer *HdiDisplay::GetHdiLayer(uint32_t id)
221 {
222     DISPLAY_LOGD("id : %{public}d", id);
223     auto iter = mLayersMap.find(id);
224     DISPLAY_CHK_RETURN((iter == mLayersMap.end()), nullptr, DISPLAY_LOGE("can not find the layer %{public}d", id));
225     return iter->second.get();
226 }
227 
VsyncCallBack(VBlankCallback cb,void * data)228 VsyncCallBack::VsyncCallBack(VBlankCallback cb, void *data) : mVBlankCb(cb), mData(data)
229 {
230     DISPLAY_LOGD("VsyncCallBack %{public}p", cb);
231 }
232 
Vsync(unsigned int sequence,uint64_t ns)233 void VsyncCallBack::Vsync(unsigned int sequence, uint64_t ns)
234 {
235     DISPLAY_CHK_RETURN_NOT_VALUE((mVBlankCb == nullptr), DISPLAY_LOGE("the callback is nullptr"));
236     mVBlankCb(sequence, ns, mData);
237 }
238 }
239 }
240 }
241