1/* 2 * Copyright (c) 2023-2024 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_test_display.h" 17#include "unistd.h" 18#include "display_test_utils.h" 19#include "hdi_test_device.h" 20namespace OHOS { 21namespace HDI { 22namespace Display { 23namespace TEST { 24using namespace OHOS::HDI::Display::Composer::V1_1; 25HdiTestDisplay::HdiTestDisplay(uint32_t id, sptr<Composer::V1_2::IDisplayComposerInterface> device) 26 : id_(id), device_(device), currentFb_(nullptr) 27{ 28} 29 30int32_t HdiTestDisplay::Init() 31{ 32 DISPLAY_TEST_LOGE(); 33 int ret = device_->GetDisplayCapability(id_, cap_); 34 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get cap")); 35 DISPLAY_TEST_LOGE("the capablility name %s type : %{public}d phyWidth : %{public}d phyHeight : %{public}d", 36 cap_.name.c_str(), cap_.type, cap_.phyWidth, cap_.phyHeight); 37 // get the modes 38 ret = device_->GetDisplaySupportedModes(id_, modes_); 39 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get modes")); 40 DISPLAY_TEST_LOGE("the modes size() %{public}zu", modes_.size()); 41 42 ret = device_->GetDisplayMode(id_, activeModeId_); 43 DISPLAY_TEST_CHK_RETURN( 44 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the mode id is : %{public}u", activeModeId_)); 45 46 ret = GetModeInfoFromId(activeModeId_, currentMode_); 47 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, 48 DISPLAY_TEST_LOGE("can not get the mode of id : %{public}u", activeModeId_)); 49 50 ret = device_->SetDisplayPowerStatus(id_, Composer::V1_0::DispPowerStatus::POWER_STATUS_ON); 51 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, 52 DISPLAY_TEST_LOGE("SetDisplayPowerStatus failed, id_ : %{public}u", id_)); 53 54 ret = device_->SetDisplayMode(id_, currentMode_.id); 55 DISPLAY_TEST_CHK_RETURN( 56 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("SetDisplayMode failed, id_ : %{public}u", id_)); 57 58 LayerInfo layerinfo = {0}; 59 layerinfo.width = currentMode_.width; 60 layerinfo.height = currentMode_.height; 61 layerinfo.pixFormat = Composer::V1_0::PIXEL_FMT_BGRA_8888; 62 const uint32_t CLIENT_LAYER_ID = 0xffffffff; // invalid id 63 clientLayer_ = std::make_unique<HdiTestLayer>(layerinfo, CLIENT_LAYER_ID, id_); 64 ret = clientLayer_->Init(); 65 DISPLAY_TEST_CHK_RETURN( 66 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("the client layer can not be created")); 67 68 ret = device_->SetClientBufferCacheCount(id_, clientLayer_->GetLayerBuffercount()); 69 DISPLAY_TEST_CHK_RETURN( 70 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("setClientBufferCount error")); 71 return DISPLAY_SUCCESS; 72} 73 74int32_t HdiTestDisplay::GetModeInfoFromId(int32_t id, DisplayModeInfo& modeInfo) const 75{ 76 DISPLAY_TEST_LOGE(); 77 auto iter = std::find_if (std::begin(modes_), std::end(modes_), [id](const auto& mode) { 78 return mode.id == id; 79 }); 80 if (iter != std::end(modes_)) { 81 modeInfo = *iter; 82 DISPLAY_TEST_LOGE("the mode width: %{public}d height : %{public}d freshRate : %{public}u id: %{public}d", 83 iter->width, iter->height, iter->freshRate, iter->id); 84 return DISPLAY_SUCCESS; 85 } 86 DISPLAY_TEST_LOGE("can not find the modeinfo id : %{public}d", id); 87 return DISPLAY_FAILURE; 88} 89 90std::shared_ptr<HdiTestLayer> HdiTestDisplay::CreateHdiTestLayer(LayerInfo& info) 91{ 92 DISPLAY_TEST_LOGE(); 93 uint32_t layerId = 0; 94 int ret = device_->CreateLayer(id_, info, HdiTestLayer::MAX_BUFFER_COUNT, layerId); 95 DISPLAY_TEST_LOGE("CreateLayer layerId %{public}u", layerId); 96 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_TEST_LOGE("layer creat failed")); 97 auto layer = std::make_shared<HdiTestLayer>(info, layerId, id_); 98 ret = layer->Init(); 99 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), nullptr, DISPLAY_TEST_LOGE("layer init failed")); 100 layerMaps_.emplace(layerId, layer); 101 return layer; 102} 103 104std::shared_ptr<HdiTestLayer> HdiTestDisplay::CreateHdiTestLayer(uint32_t w, uint32_t h) 105{ 106 const int32_t BPP = 32; 107 108 LayerInfo info = {w, h, LAYER_TYPE_GRAPHIC, BPP, Composer::V1_0::PIXEL_FMT_RGBA_8888}; 109 return CreateHdiTestLayer(info); 110} 111 112int32_t HdiTestDisplay::RefreshLayersCompType() 113{ 114 int ret; 115 std::vector<uint32_t> layers; 116 std::vector<int32_t> types; 117 ret = device_->GetDisplayCompChange(id_, layers, types); 118 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, 119 DISPLAY_TEST_LOGE("GetDisplayCompChange get layers and types failed")); 120 DISPLAY_TEST_LOGE("the change numbers %{public}zu, layers size %{public}zu", layers.size(), layers.size()); 121 for (uint32_t i = 0; i < layers.size(); i++) { 122 DISPLAY_TEST_LOGE(" the layer id %{public}u ", layers[i]); 123 std::shared_ptr<HdiTestLayer> layer = GetLayerFromId(layers[i]); 124 layer->SetCompType(static_cast<Composer::V1_0::CompositionType>(types[i])); 125 } 126 return DISPLAY_SUCCESS; 127} 128 129int32_t HdiTestDisplay::GetLayersReleaseFence() 130{ 131 int ret; 132 std::vector<uint32_t> layers; 133 std::vector<int32_t> fences; 134 135 ret = device_->GetDisplayReleaseFence(id_, layers, fences); 136 DISPLAY_TEST_CHK_RETURN((ret != 0), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("GetDisplayReleaseFence get data failed")); 137 DISPLAY_TEST_LOGE("the release fence numbers %{public}zu, layers size %{public}zu", layers.size(), layers.size()); 138 for (uint32_t i = 0; i < layers.size(); i++) { 139 DISPLAY_TEST_LOGE(" the layer id %{public}u, fence: 0x%x", layers[i], fences[i]); 140 std::shared_ptr<HdiTestLayer> layer = GetLayerFromId(layers[i]); 141 layer->SetReleaseFence(fences[i]); 142 } 143 return DISPLAY_SUCCESS; 144} 145 146int32_t HdiTestDisplay::PrepareDisplayLayers() 147{ 148 int ret; 149 needFlushFb_ = false; 150 DISPLAY_TEST_LOGE("id : %{public}u layer size %{public}zu", id_, layerMaps_.size()); 151 for (const auto& layerMap : layerMaps_) { 152 ret = layerMap.second->PreparePresent(); 153 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, 154 DISPLAY_TEST_LOGE("layer %{public}d Prepare failed", layerMap.first)); 155 } 156 ret = device_->PrepareDisplayLayers(id_, needFlushFb_); 157 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, 158 DISPLAY_TEST_LOGE("PrepareDisplayLayers failed display id %{public}u", id_)); 159 ret = RefreshLayersCompType(); 160 DISPLAY_TEST_CHK_RETURN( 161 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("RefreshLayersCompType failed")); 162 return DISPLAY_SUCCESS; 163} 164 165int32_t HdiTestDisplay::Commit() 166{ 167 int32_t fenceFd; 168 int ret; 169 HdiGrallocBuffer* buffer = nullptr; 170 if (needFlushFb_) { 171 ret = clientLayer_->SwapFrontToBackQ(); 172 DISPLAY_TEST_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, 173 DISPLAY_TEST_LOGE("has no front buffer display id %{public}u", id_)); 174 175 buffer = clientLayer_->GetBackBuffer(); 176 DISPLAY_TEST_CHK_RETURN((buffer == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("can not get back buffer")); 177 BufferHandle* handle = buffer->Get(); 178 DISPLAY_TEST_CHK_RETURN((handle == nullptr), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("BufferHandle is null")); 179 ClearColor(*handle, 0); // need clear the fb first 180 181 ret = buffer->SetGraphicBuffer([&](const BufferHandle* buffer, uint32_t seqNo) -> int32_t { 182 int32_t result = device_->SetDisplayClientBuffer(id_, buffer, seqNo, -1); 183 DISPLAY_TEST_CHK_RETURN( 184 (result != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set client buffer handle failed")); 185 return DISPLAY_SUCCESS; 186 }); 187 currentFb_ = handle; 188 DISPLAY_TEST_CHK_RETURN( 189 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("set client buffer handle failed")); 190 } 191 192 ret = device_->Commit(id_, fenceFd); 193 DISPLAY_TEST_CHK_RETURN( 194 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("commit failed display id %{public}u", id_)); 195 ret = GetLayersReleaseFence(); 196 DISPLAY_TEST_CHK_RETURN( 197 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("GetLayersReleaseFence failed %{public}u", id_)); 198 199 if (needFlushFb_) { 200 DISPLAY_TEST_LOGE("commit out client buffer fence: %{public}d", fenceFd); 201 buffer->SetReleaseFence(fenceFd); 202 ret = clientLayer_->SwapBackToFrontQ(); 203 } 204 DISPLAY_TEST_CHK_RETURN( 205 (ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_TEST_LOGE("has no back buffer display id %{public}u", id_)); 206 return DISPLAY_SUCCESS; 207} 208 209int32_t HdiTestDisplay::RegDisplayVBlankCallback(VBlankCallback cb, void* data) const 210{ 211 int ret = device_->RegDisplayVBlankCallback(id_, cb, data); 212 return ret; 213} 214 215int32_t HdiTestDisplay::SetDisplayVsyncEnabled(bool enabled) const 216{ 217 int ret = device_->SetDisplayVsyncEnabled(id_, enabled); 218 return ret; 219} 220 221std::shared_ptr<HdiTestLayer> HdiTestDisplay::GetLayerFromId(uint32_t id) 222{ 223 auto layerMap = layerMaps_.find(id); 224 DISPLAY_TEST_CHK_RETURN( 225 (layerMap == layerMaps_.end()), nullptr, DISPLAY_TEST_LOGE("can not find the layer id : %{public}u", id)); 226 return layerMap->second; 227} 228 229void HdiTestDisplay::Clear() 230{ 231 DISPLAY_TEST_LOGE(); 232 for (auto const& iter : layerMaps_) { 233 uint32_t layerId = iter.first; 234 device_->DestroyLayer(id_, layerId); 235 } 236 layerMaps_.clear(); 237 DISPLAY_TEST_LOGE("layerMaps_ size %{public}zu", layerMaps_.size()); 238} 239} // namespace TEST 240} // namespace Display 241} // namespace HDI 242} // namespace OHOS 243