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