1 /* 2 * Copyright (c) 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 #ifndef OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H 17 #define OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H 18 19 #include "v1_1/display_command/display_cmd_requester.h" 20 #include "v1_2/display_command/display_cmd_utils.h" 21 #include "v1_2/display_composer_type.h" 22 #include "v1_2/idisplay_composer.h" 23 24 namespace OHOS { 25 namespace HDI { 26 namespace Display { 27 namespace Composer { 28 namespace V1_2 { 29 using namespace OHOS::HDI::Base; 30 31 template <typename Transfer, typename CompHdi> 32 class DisplayCmdRequester : public V1_1::DisplayCmdRequester<Transfer, CompHdi> { 33 public: DisplayCmdRequester(sptr<CompHdi> hdi)34 DisplayCmdRequester(sptr<CompHdi> hdi) : BaseType1_1(hdi), hdi_1_2_(hdi) {} 35 Create(sptr<CompHdi> hdi)36 static std::unique_ptr<DisplayCmdRequester> Create(sptr<CompHdi> hdi) 37 { 38 DISPLAY_CHK_RETURN(hdi == nullptr, nullptr, HDF_LOGE("%{public}s: hdi is nullptr", __func__)); 39 auto requester = std::make_unique<DisplayCmdRequester>(hdi); 40 DISPLAY_CHK_RETURN(requester == nullptr, nullptr, 41 HDF_LOGE("%{public}s: CmdRequester is nullptr", __func__)); 42 auto ret = requester->Init(CmdUtils::INIT_ELEMENT_COUNT); 43 if (ret != HDF_SUCCESS) { 44 HDF_LOGE("DisplayCmdRequester init failed"); 45 return nullptr; 46 } 47 return requester; 48 } 49 CommitAndGetReleaseFence(uint32_t devId,int32_t & fence,bool isSupportSkipValidate,int32_t & skipState,bool & needFlush,std::vector<uint32_t> & layers,std::vector<int32_t> & fences,bool isValidated)50 int32_t CommitAndGetReleaseFence(uint32_t devId, int32_t& fence, bool isSupportSkipValidate, int32_t& skipState, 51 bool& needFlush, std::vector<uint32_t>& layers, std::vector<int32_t>& fences, bool isValidated) 52 { 53 uint32_t replyEleCnt = 0; 54 std::vector<HdifdInfo> outFds; 55 56 int32_t ret = CmdUtils::StartSection(REQUEST_CMD_COMMIT_AND_GET_RELEASE_FENCE, requestPacker_); 57 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 58 59 ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 60 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 61 62 ret = requestPacker_.WriteBool(isSupportSkipValidate) ? HDF_SUCCESS : HDF_FAILURE; 63 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 64 65 ret = requestPacker_.WriteBool(isValidated) ? HDF_SUCCESS : HDF_FAILURE; 66 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 67 68 ret = CmdUtils::EndSection(requestPacker_); 69 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 70 71 ret = CmdUtils::EndPack(requestPacker_); 72 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 73 74 ret = DoRequest(replyEleCnt, outFds); 75 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 76 77 ret = DoReplyResults(replyEleCnt, outFds, [&](void *data) -> int32_t { 78 FenceData *fenceData = reinterpret_cast<struct FenceData *>(data); 79 if (fenceData == nullptr) { 80 fence = -1; 81 skipState = -1; 82 needFlush = false; 83 layers.clear(); 84 fences.clear(); 85 return HDF_FAILURE; 86 } 87 fence = fenceData->fence_; 88 skipState = fenceData->skipValidateState_; 89 needFlush = fenceData->needFlush_; 90 layers = fenceData->layers; 91 fences = fenceData->fences; 92 return HDF_SUCCESS; 93 }); 94 if (ret != HDF_SUCCESS) { 95 HDF_LOGE("DoReplyResults failure, ret=%{public}d", ret); 96 } 97 98 EXIT: 99 return PeriodDataReset() == HDF_SUCCESS ? ret : HDF_FAILURE; 100 } 101 OnReplySkipStateFailed(CommandDataUnpacker & replyUnpacker,bool & needFlush)102 int32_t OnReplySkipStateFailed(CommandDataUnpacker& replyUnpacker, bool &needFlush) 103 { 104 uint32_t devId = 0; 105 int32_t retBool = replyUnpacker.ReadUint32(devId); 106 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read devId failed", __func__)); 107 108 retBool = replyUnpacker.ReadBool(needFlush); 109 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read needFlush failed", __func__)); 110 111 // unpack layers vector 112 uint32_t vectSize = 0; 113 retBool = replyUnpacker.ReadUint32(vectSize); 114 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 115 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 116 117 if (vectSize > CmdUtils::MAX_MEMORY) { 118 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize); 119 return HDF_FAILURE; 120 } 121 compChangeLayers_[devId].resize(vectSize); 122 for (uint32_t i = 0; i < vectSize; i++) { 123 DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(compChangeLayers_[devId][i]) == false, HDF_FAILURE, 124 HDF_LOGE("%{public}s: HDI 1.2 read layer vector failed", __func__)); 125 } 126 // unpack types vector 127 vectSize = 0; 128 retBool = replyUnpacker.ReadUint32(vectSize); 129 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 130 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 131 132 if (vectSize > CmdUtils::MAX_MEMORY) { 133 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize); 134 return HDF_FAILURE; 135 } 136 compChangeTypes_[devId].resize(vectSize); 137 for (uint32_t i = 0; i < vectSize; i++) { 138 DISPLAY_CHK_RETURN(replyUnpacker.ReadInt32(compChangeTypes_[devId][i]) == false, HDF_FAILURE, 139 HDF_LOGE("%{public}s: HDI 1.2 read composition type vector failed", __func__)); 140 } 141 return HDF_SUCCESS; 142 } 143 OnReplyCommitAndGetReleaseFence(CommandDataUnpacker & replyUnpacker,std::vector<HdifdInfo> & replyFds,int32_t & fenceFd,int32_t & skipState,bool & needFlush,std::vector<uint32_t> & layers,std::vector<int32_t> & fences)144 int32_t OnReplyCommitAndGetReleaseFence(CommandDataUnpacker& replyUnpacker, 145 std::vector<HdifdInfo>& replyFds, int32_t& fenceFd, int32_t& skipState, 146 bool& needFlush, std::vector<uint32_t>& layers, std::vector<int32_t>& fences) 147 { 148 int32_t ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fenceFd); 149 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 150 HDF_LOGE("%{public}s: FileDescriptorUnpack failed", __func__)); 151 152 int32_t retBool = replyUnpacker.ReadInt32(skipState); 153 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 154 HDF_LOGE("%{public}s: read skipValidateState failed", __func__)); 155 156 if (skipState != HDF_SUCCESS) { 157 return OnReplySkipStateFailed(replyUnpacker, needFlush); 158 } else { 159 // unpack layers vector 160 uint32_t vectSize = 0; 161 DISPLAY_CHK_RETURN(true != replyUnpacker.ReadUint32(vectSize), HDF_FAILURE, 162 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 163 164 if (vectSize > CmdUtils::MAX_MEMORY) { 165 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize); 166 return HDF_FAILURE; 167 } 168 layers.resize(vectSize); 169 for (uint32_t i = 0; i < vectSize; i++) { 170 DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(layers[i]) == false, HDF_FAILURE, 171 HDF_LOGE("%{public}s: HDI 1.2 read layer vector failed", __func__)); 172 } 173 174 // unpack fences vector 175 vectSize = 0; 176 DISPLAY_CHK_RETURN(true != replyUnpacker.ReadUint32(vectSize), HDF_FAILURE, 177 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 178 179 if (vectSize > CmdUtils::MAX_MEMORY) { 180 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize); 181 return HDF_FAILURE; 182 } 183 fences.resize(vectSize); 184 for (uint32_t i = 0; i < vectSize; i++) { 185 ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fences[i]); 186 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 187 HDF_LOGE("%{public}s: HDI 1.2 FileDescriptorUnpack failed", __func__)); 188 } 189 } 190 return HDF_SUCCESS; 191 } 192 ProcessUnpackCmd(CommandDataUnpacker & replyUnpacker,int32_t unpackCmd,std::vector<HdifdInfo> & replyFds,std::function<int32_t (void *)> fn)193 int32_t ProcessUnpackCmd(CommandDataUnpacker& replyUnpacker, int32_t unpackCmd, 194 std::vector<HdifdInfo>& replyFds, std::function<int32_t(void *)> fn) 195 { 196 int32_t ret = HDF_SUCCESS; 197 while (replyUnpacker.NextSection()) { 198 bool retBool = replyUnpacker.BeginSection(unpackCmd); 199 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 200 HDF_LOGE("%{public}s: BeginSection failed", __func__)); 201 202 FenceData fenceData; 203 204 std::unordered_map<int32_t, int32_t> errMaps; 205 switch (unpackCmd) { 206 case REPLY_CMD_COMMIT_AND_GET_RELEASE_FENCE: 207 ret = OnReplyCommitAndGetReleaseFence(replyUnpacker, replyFds, fenceData.fence_, 208 fenceData.skipValidateState_, fenceData.needFlush_, fenceData.layers, fenceData.fences); 209 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 210 HDF_LOGE("%{public}s: OnReplyCommit failed unpackCmd=%{public}s", 211 __func__, CmdUtils::CommandToString(unpackCmd))); 212 213 ret = fn(&fenceData); 214 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 215 HDF_LOGE("%{public}s: return fence fd error, unpackCmd=%{public}s", 216 __func__, CmdUtils::CommandToString(unpackCmd))); 217 break; 218 default: 219 HDF_LOGE("Unpack command failure, unpackCmd=%{public}d", unpackCmd); 220 return HDF_FAILURE; 221 } 222 } 223 return HDF_SUCCESS; 224 } 225 DoReplyResults(uint32_t replyEleCnt,std::vector<HdifdInfo> & replyFds,std::function<int32_t (void *)> fn)226 int32_t DoReplyResults(uint32_t replyEleCnt, std::vector<HdifdInfo>& replyFds, std::function<int32_t(void *)> fn) 227 { 228 CommandDataUnpacker replyUnpacker; 229 replyUnpacker.Init(replyData_.get(), replyEleCnt << CmdUtils::MOVE_SIZE); 230 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA 231 replyUnpacker.Dump(); 232 #endif // DEBUG_DISPLAY_CMD_RAW_DATA 233 int32_t unpackCmd = -1; 234 bool retBool = replyUnpacker.PackBegin(unpackCmd); 235 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 236 HDF_LOGE("%{public}s: PackBegin failed", __func__)); 237 if (unpackCmd != CONTROL_CMD_REPLY_BEGIN) { 238 HDF_LOGE("%{public}s: PackBegin cmd not match, unpackCmd=%{public}d", __func__, unpackCmd); 239 request_->Reset(); 240 reply_->Reset(); 241 return HDF_FAILURE; 242 } 243 if (ProcessUnpackCmd(replyUnpacker, unpackCmd, replyFds, fn) != HDF_SUCCESS) { 244 HDF_LOGE("%{public}s: ProcessUnpackCmd failed, unpackCmd=%{public}d", __func__, unpackCmd); 245 request_->Reset(); 246 reply_->Reset(); 247 return HDF_FAILURE; 248 } 249 250 retBool = replyUnpacker.PackEnd(unpackCmd); 251 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 252 HDF_LOGE("%{public}s: PackEnd failed", __func__)); 253 254 DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_END, HDF_FAILURE, 255 HDF_LOGE("%{public}s: PackEnd failed, endCmd = %{public}s", 256 __func__, CmdUtils::CommandToString(unpackCmd))); 257 258 return HDF_SUCCESS; 259 } 260 261 // LTPO新增接口 SetDisplayConstraint(uint32_t devId,uint64_t frameID,uint64_t ns,uint32_t type)262 int32_t SetDisplayConstraint(uint32_t devId, uint64_t frameID, uint64_t ns, uint32_t type) 263 { 264 int32_t ret = 0; 265 bool retBool = false; 266 size_t writePos = requestPacker_.ValidSize(); 267 268 do { 269 ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CONSTRAINT, requestPacker_); 270 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 271 HDF_LOGE("%{public}s: StartSection failed", __func__)); 272 273 retBool = requestPacker_.WriteUint32(devId); 274 DISPLAY_CHK_BREAK(retBool == false, 275 HDF_LOGE("%{public}s: write devId failed", __func__)); 276 277 retBool = requestPacker_.WriteUint64(frameID); 278 DISPLAY_CHK_BREAK(retBool == false, 279 HDF_LOGE("%{public}s: write frameID failed", __func__)); 280 281 retBool = requestPacker_.WriteUint64(ns); 282 DISPLAY_CHK_BREAK(retBool == false, 283 HDF_LOGE("%{public}s: write ns failed", __func__)); 284 285 retBool = requestPacker_.WriteUint32(type); 286 DISPLAY_CHK_BREAK(retBool == false, 287 HDF_LOGE("%{public}s: write type failed", __func__)); 288 289 ret = CmdUtils::EndSection(requestPacker_); 290 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 291 HDF_LOGE("%{public}s: EndSection failed", __func__)); 292 } while (0); 293 294 if (retBool == false || ret != HDF_SUCCESS) { 295 requestPacker_.RollBack(writePos); 296 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 297 return HDF_FAILURE; 298 } 299 return HDF_SUCCESS; 300 } 301 SetLayerPerFrameParameterSmq(uint32_t devId,uint32_t layerId,const std::string & key,const std::vector<int8_t> & value)302 int32_t SetLayerPerFrameParameterSmq(uint32_t devId, uint32_t layerId, const std::string& key, 303 const std::vector<int8_t>& value) 304 { 305 int32_t ret = 0; 306 bool retBool = false; 307 size_t writePos = requestPacker_.ValidSize(); 308 309 do { 310 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_PERFRAME_PARAM, requestPacker_); 311 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 312 HDF_LOGE("%{public}s: StartSection failed", __func__)); 313 314 retBool = requestPacker_.WriteUint32(devId); 315 DISPLAY_CHK_BREAK(retBool == false, 316 HDF_LOGE("%{public}s: write devId failed", __func__)); 317 318 retBool = requestPacker_.WriteUint32(layerId); 319 DISPLAY_CHK_BREAK(retBool == false, 320 HDF_LOGE("%{public}s: write layerId failed", __func__)); 321 322 uint32_t vectStrSize = key.size(); 323 retBool = requestPacker_.WriteUint32(vectStrSize); 324 if (vectStrSize > CmdUtils::MAX_MEMORY) { 325 DISPLAY_CHK_BREAK(retBool == false, 326 HDF_LOGE("%{public}s: write vectStr failed", __func__)); 327 } 328 for (uint32_t i = 0; i < vectStrSize; i++) { 329 retBool = requestPacker_.WriteInt32(static_cast<int32_t>(key[i])); 330 DISPLAY_CHK_BREAK(retBool == false, 331 HDF_LOGE("%{public}s: write vectStr failed", __func__)); 332 } 333 334 uint32_t vectSize = value.size(); 335 retBool = requestPacker_.WriteUint32(vectSize); 336 if (vectSize > CmdUtils::MAX_MEMORY) { 337 DISPLAY_CHK_BREAK(retBool == false, 338 HDF_LOGE("%{public}s: write vect failed", __func__)); 339 } 340 for (uint32_t i = 0; i < vectSize; i++) { 341 retBool = requestPacker_.WriteUint8(static_cast<uint8_t>(value[i])); 342 DISPLAY_CHK_BREAK(retBool == false, 343 HDF_LOGE("%{public}s: write vect failed", __func__)); 344 } 345 346 ret = CmdUtils::EndSection(requestPacker_); 347 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 348 HDF_LOGE("%{public}s: EndSection failed", __func__)); 349 } while (0); 350 351 if (retBool == false || ret != HDF_SUCCESS) { 352 requestPacker_.RollBack(writePos); 353 HDF_LOGE("SetLayerPerFrameParameterSmq writePos_ rollback %{public}s, %{public}d, %{public}d", 354 key.c_str(), devId, layerId); 355 356 return HDF_FAILURE; 357 } 358 return HDF_SUCCESS; 359 } 360 SetDisplayPerFrameParameterSmq(uint32_t devId,const std::string & key,const std::vector<int8_t> & value)361 int32_t SetDisplayPerFrameParameterSmq(uint32_t devId, const std::string& key, 362 const std::vector<int8_t>& value) 363 { 364 int32_t ret = 0; 365 bool retBool = false; 366 size_t writePos = requestPacker_.ValidSize(); 367 368 do { 369 ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_PERFRAME_PARAM, requestPacker_); 370 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 371 HDF_LOGE("%{public}s: StartSection failed", __func__)); 372 373 retBool = requestPacker_.WriteUint32(devId); 374 DISPLAY_CHK_BREAK(retBool == false, 375 HDF_LOGE("%{public}s: write devId failed", __func__)); 376 377 uint32_t vectStrSize = key.size(); 378 retBool = requestPacker_.WriteUint32(vectStrSize); 379 if (vectStrSize > CmdUtils::MAX_MEMORY) { 380 DISPLAY_CHK_BREAK(retBool == false, 381 HDF_LOGE("%{public}s: write vectStr failed", __func__)); 382 } 383 for (uint32_t i = 0; i < vectStrSize; i++) { 384 retBool = requestPacker_.WriteInt32(static_cast<int32_t>(key[i])); 385 DISPLAY_CHK_BREAK(retBool == false, 386 HDF_LOGE("%{public}s: write vectStr failed", __func__)); 387 } 388 389 uint32_t vectSize = value.size(); 390 retBool = requestPacker_.WriteUint32(vectSize); 391 if (vectSize > CmdUtils::MAX_MEMORY) { 392 DISPLAY_CHK_BREAK(retBool == false, 393 HDF_LOGE("%{public}s: write vect failed", __func__)); 394 } 395 for (uint32_t i = 0; i < vectSize; i++) { 396 retBool = requestPacker_.WriteUint8(static_cast<uint8_t>(value[i])); 397 DISPLAY_CHK_BREAK(retBool == false, 398 HDF_LOGE("%{public}s: write vect failed", __func__)); 399 } 400 401 ret = CmdUtils::EndSection(requestPacker_); 402 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 403 HDF_LOGE("%{public}s: EndSection failed", __func__)); 404 } while (0); 405 406 if (retBool == false || ret != HDF_SUCCESS) { 407 requestPacker_.RollBack(writePos); 408 HDF_LOGE("SetDisplayPerFrameParameterSmq writePos_ rollback %{public}s, %{public}d", 409 key.c_str(), devId); 410 411 return HDF_FAILURE; 412 } 413 return HDF_SUCCESS; 414 } 415 416 protected: 417 sptr<CompHdi> hdi_1_2_; 418 private: 419 using BaseType1_1 = V1_1::DisplayCmdRequester<Transfer, CompHdi>; 420 using BaseType1_1::request_; 421 using BaseType1_1::reply_; 422 using BaseType1_1::requestPacker_; 423 using BaseType1_1::replyData_; 424 using BaseType1_1::DoRequest; 425 using BaseType1_1::PeriodDataReset; 426 427 // Composition layers/types changed 428 using BaseType1_1::compChangeLayers_; 429 using BaseType1_1::compChangeTypes_; 430 // CommitAndGetReleaseFence 431 struct FenceData { 432 int32_t fence_ = -1; 433 int32_t skipValidateState_ = -1; 434 bool needFlush_ = false; 435 std::vector<uint32_t> layers; 436 std::vector<int32_t> fences; 437 }; 438 }; 439 using HdiDisplayCmdRequester = V1_2::DisplayCmdRequester<SharedMemQueue<int32_t>, V1_2::IDisplayComposer>; 440 } // namespace V1_2 441 } // namespace Composer 442 } // namespace Display 443 } // namespace HDI 444 } // namespace OHOS 445 #endif // OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H 446