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