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