1/*
2 * Copyright (c) 2021-2023 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
20namespace OHOS {
21namespace HDI {
22namespace DISPLAY {
23uint32_t HdiDisplay::mIdleId = 0;
24std::unordered_set<uint32_t> HdiDisplay::mIdSets;
25
26uint32_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
46int32_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
60HdiDisplay::~HdiDisplay()
61{
62    mIdSets.erase(mId);
63}
64
65int32_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    for (auto c = zRange.first; c != zRange.second; c++) {
79        if (*c == layer) {
80            mLayers.erase(c);
81            break;
82        }
83    }
84    layer->SetLayerZorder(zorder);
85    mLayers.emplace(layer);
86    return DISPLAY_SUCCESS;
87}
88
89int32_t HdiDisplay::CreateLayer(const LayerInfo *layerInfo, uint32_t *layerId)
90{
91    DISPLAY_LOGD();
92    int ret;
93    DISPLAY_CHK_RETURN((layerInfo == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("LayerInfo is null"));
94    DISPLAY_CHK_RETURN((layerId == nullptr), DISPLAY_PARAM_ERR, DISPLAY_LOGE("layerId is null"));
95    auto layer = CreateHdiLayer(layerInfo->type);
96    DISPLAY_CHK_RETURN((layer.get() == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not create hdi layer"));
97    ret = layer->Init();
98    DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("Layer Init failed"));
99    *layerId = layer->GetId();
100    mLayers.insert(layer.get());
101    mLayersMap.emplace(layer->GetId(), std::move(layer));
102    DISPLAY_LOGD("mLayers size %{public}zu", mLayers.size());
103    DISPLAY_LOGD("mLayerMap size %{public}zu", mLayersMap.size());
104    return DISPLAY_SUCCESS;
105}
106
107std::unique_ptr<HdiLayer> HdiDisplay::CreateHdiLayer(LayerType type)
108{
109    DISPLAY_LOGD();
110    return std::make_unique<HdiLayer>(type);
111}
112
113
114int32_t HdiDisplay::DestroyLayer(uint32_t layerId)
115{
116    DISPLAY_LOGD("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
125int32_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_LOGD("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
145int32_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_LOGD("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_LOGD("layer id %{public}d fencefd %{public}d", layer->GetId(), layer->GetReleaseFenceFd());
162        i++;
163    }
164    return DISPLAY_SUCCESS;
165}
166
167int32_t HdiDisplay::PrepareDisplayLayers(bool *needFlushFb)
168{
169    DISPLAY_LOGD();
170    mChangeLayers.clear();
171    std::vector<HdiLayer *> layers;
172    uint32_t topZpos = 3;
173    for (auto c : mLayers) {
174        layers.push_back(c);
175    }
176    DISPLAY_LOGD(" mLayers  size %{public}zu layers size %{public}zu", mLayers.size(), layers.size());
177
178    /* Set the target layer to the top.
179     *  It would not by cover by other layer.
180     */
181    mClientLayer->SetLayerZorder(topZpos);
182
183    mComposer->Prepare(layers, *mClientLayer);
184    // get the change layers
185    for (auto &layer : layers) {
186        if (layer->GetDeviceSelect() != layer->GetCompositionType()) {
187            DISPLAY_LOGD("layer change");
188            layer->SetLayerCompositionType(layer->GetDeviceSelect());
189        }
190        mChangeLayers.push_back(layer);
191    }
192    *needFlushFb = true;
193    return DISPLAY_SUCCESS;
194}
195
196int32_t HdiDisplay::Commit(int32_t *fence)
197{
198    DISPLAY_LOGD();
199    mComposer->Commit(false);
200    *fence = dup(mClientLayer->GetReleaseFenceFd());
201    DISPLAY_LOGD("the release fence is %{public}d", *fence);
202    return DISPLAY_SUCCESS;
203}
204
205int32_t HdiDisplay::SetDisplayClientBuffer(const BufferHandle *buffer, int32_t fence)
206{
207    mClientLayer->SetLayerBuffer(buffer, fence);
208    return DISPLAY_SUCCESS;
209}
210
211HdiLayer *HdiDisplay::GetHdiLayer(uint32_t id)
212{
213    DISPLAY_LOGD("id : %{public}d", id);
214    auto iter = mLayersMap.find(id);
215    DISPLAY_CHK_RETURN((iter == mLayersMap.end()), nullptr, DISPLAY_LOGE("can not find the layer %{public}d", id));
216    return iter->second.get();
217}
218
219VsyncCallBack::VsyncCallBack(VBlankCallback cb, void *data, uint32_t displayId) : mVBlankCb(cb),
220    mData(data), mPipe(displayId)
221{
222}
223
224void VsyncCallBack::Vsync(unsigned int sequence, uint64_t ns)
225{
226    DISPLAY_CHK_RETURN_NOT_VALUE((mVBlankCb == nullptr), DISPLAY_LOGE("the callback is nullptr"));
227    mVBlankCb(sequence, ns, mData);
228}
229}
230}
231}
232