1 /* 2 * Copyright (c) 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 #ifndef OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H 17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H 18 19 #include <fstream> 20 #include <poll.h> 21 #include <securec.h> 22 #include <sstream> 23 #include <string> 24 #include <sys/time.h> 25 #include <unistd.h> 26 #include <unordered_map> 27 28 #include "base/hdi_smq.h" 29 #include "buffer_handle_utils.h" 30 #include "command_pack/command_data_packer.h" 31 #include "command_pack/command_data_unpacker.h" 32 #include "display_cmd_utils.h" 33 #include "hdf_base.h" 34 #include "hdf_trace.h" 35 #include "hdifd_parcelable.h" 36 #include "hilog/log.h" 37 #include "idisplay_composer_vdi.h" 38 #include "parameter.h" 39 #include "v1_0/display_composer_type.h" 40 #include "v1_0/mapper_stub.h" 41 42 #define DISPLAY_TRACE HdfTrace trace(__func__, "HDI:DISP:") 43 44 namespace OHOS { 45 namespace HDI { 46 namespace Display { 47 namespace Composer { 48 namespace V1_0 { 49 using namespace OHOS::HDI::Base; 50 using namespace OHOS::HDI::Display::Composer::V1_0; 51 using namespace OHOS::HDI::Display::Buffer::V1_0; 52 using HdifdSet = std::vector<std::shared_ptr<HdifdParcelable>>; 53 54 static constexpr uint32_t TIME_BUFFER_MAX_LEN = 15; 55 56 static sptr<IMapper> g_bufferServiceImpl = nullptr; 57 58 template <typename Transfer, typename VdiImpl> 59 class DisplayCmdResponser { 60 public: Create(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)61 static std::unique_ptr<DisplayCmdResponser> Create(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr) 62 { 63 DISPLAY_CHK_RETURN(impl == nullptr, nullptr, 64 HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__)); 65 DISPLAY_CHK_RETURN(cacheMgr == nullptr, nullptr, 66 HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__)); 67 return std::make_unique<DisplayCmdResponser>(impl, cacheMgr); 68 } 69 DisplayCmdResponser(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)70 DisplayCmdResponser(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr) 71 : impl_(impl), 72 cacheMgr_(cacheMgr), 73 request_(nullptr), 74 isReplyUpdated_(false), 75 reply_(nullptr), 76 replyCommandCnt_(0), 77 replyPacker_(nullptr) {} 78 ~DisplayCmdResponser()79 ~DisplayCmdResponser() {} 80 InitCmdRequest(const std::shared_ptr<Transfer> & request)81 int32_t InitCmdRequest(const std::shared_ptr<Transfer>& request) 82 { 83 DISPLAY_CHK_RETURN(request == nullptr, HDF_FAILURE, 84 HDF_LOGE("%{public}s: error, request is nullptr", __func__)); 85 if (request_ != nullptr) { 86 request_.reset(); 87 } 88 request_ = request; 89 90 return HDF_SUCCESS; 91 } 92 GetCmdReply(std::shared_ptr<Transfer> & reply)93 int32_t GetCmdReply(std::shared_ptr<Transfer>& reply) 94 { 95 int32_t ret = HDF_SUCCESS; 96 if (isReplyUpdated_ == false) { 97 ret = InitReply(CmdUtils::INIT_ELEMENT_COUNT); 98 } 99 if (ret == HDF_SUCCESS) { 100 if (reply_ != nullptr) { 101 reply = reply_; 102 } else { 103 ret = HDF_FAILURE; 104 } 105 } 106 isReplyUpdated_ = false; 107 if (ret != HDF_SUCCESS) { 108 HDF_LOGE("error: GetCmdReply failure"); 109 } 110 111 return ret; 112 } 113 ProcessRequestCmd(std::shared_ptr<CommandDataUnpacker> unpacker,int32_t cmd,const std::vector<HdifdInfo> & inFds,std::vector<HdifdInfo> & outFds)114 int32_t ProcessRequestCmd(std::shared_ptr<CommandDataUnpacker> unpacker, int32_t cmd, 115 const std::vector<HdifdInfo>& inFds, std::vector<HdifdInfo>& outFds) 116 { 117 int32_t ret = HDF_SUCCESS; 118 HDF_LOGD("%{public}s: PackSection, cmd-[%{public}d] = %{public}s", 119 __func__, cmd, CmdUtils::CommandToString(cmd)); 120 switch (cmd) { 121 case REQUEST_CMD_PREPARE_DISPLAY_LAYERS: 122 OnPrepareDisplayLayers(unpacker); 123 break; 124 case REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER: 125 OnSetDisplayClientBuffer(unpacker, inFds); 126 break; 127 case REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE: 128 OnSetDisplayClientDamage(unpacker); 129 break; 130 case REQUEST_CMD_COMMIT: 131 OnCommit(unpacker, outFds); 132 break; 133 case REQUEST_CMD_SET_LAYER_ALPHA: 134 OnSetLayerAlpha(unpacker); 135 break; 136 case REQUEST_CMD_SET_LAYER_REGION: 137 OnSetLayerRegion(unpacker); 138 break; 139 case REQUEST_CMD_SET_LAYER_CROP: 140 OnSetLayerCrop(unpacker); 141 break; 142 case REQUEST_CMD_SET_LAYER_ZORDER: 143 OnSetLayerZorder(unpacker); 144 break; 145 case REQUEST_CMD_SET_LAYER_PREMULTI: 146 OnSetLayerPreMulti(unpacker); 147 break; 148 case REQUEST_CMD_SET_LAYER_TRANSFORM_MODE: 149 OnSetLayerTransformMode(unpacker); 150 break; 151 case REQUEST_CMD_SET_LAYER_DIRTY_REGION: 152 OnSetLayerDirtyRegion(unpacker); 153 break; 154 case REQUEST_CMD_SET_LAYER_VISIBLE_REGION: 155 OnSetLayerVisibleRegion(unpacker); 156 break; 157 case REQUEST_CMD_SET_LAYER_BUFFER: 158 OnSetLayerBuffer(unpacker, inFds); 159 break; 160 case REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE: 161 OnSetLayerCompositionType(unpacker); 162 break; 163 case REQUEST_CMD_SET_LAYER_BLEND_TYPE: 164 OnSetLayerBlendType(unpacker); 165 break; 166 case REQUEST_CMD_SET_LAYER_MASK_INFO: 167 OnSetLayerMaskInfo(unpacker); 168 break; 169 case CONTROL_CMD_REQUEST_END: 170 ret = OnRequestEnd(unpacker); 171 break; 172 case REQUEST_CMD_SET_LAYER_COLOR: 173 OnSetLayerColor(unpacker); 174 break; 175 default: 176 HDF_LOGE("%{public}s: not support this cmd, unpacked cmd = %{public}d", __func__, cmd); 177 ret = HDF_FAILURE; 178 break; 179 } 180 return ret; 181 } 182 CmdRequest(uint32_t inEleCnt,const std::vector<HdifdInfo> & inFds,uint32_t & outEleCnt,std::vector<HdifdInfo> & outFds)183 int32_t CmdRequest(uint32_t inEleCnt, const std::vector<HdifdInfo>& inFds, uint32_t& outEleCnt, 184 std::vector<HdifdInfo>& outFds) 185 { 186 std::shared_ptr<char> requestData(new char[inEleCnt * CmdUtils::ELEMENT_SIZE], std::default_delete<char[]>()); 187 int32_t ret = request_->Read(reinterpret_cast<int32_t *>(requestData.get()), inEleCnt, 188 CmdUtils::TRANSFER_WAIT_TIME); 189 190 std::shared_ptr<CommandDataUnpacker> unpacker = std::make_shared<CommandDataUnpacker>(); 191 DISPLAY_CHK_RETURN(unpacker == nullptr, HDF_FAILURE, 192 HDF_LOGE("%{public}s: unpacker construct failed", __func__)); 193 194 unpacker->Init(requestData.get(), inEleCnt * CmdUtils::ELEMENT_SIZE); 195 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA 196 unpacker->Dump(); 197 #endif // DEBUG_DISPLAY_CMD_RAW_DATA 198 199 int32_t unpackCmd = -1; 200 bool retBool = unpacker->PackBegin(unpackCmd); 201 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 202 HDF_LOGE("%{public}s: error: Check RequestBegin failed", __func__)); 203 DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REQUEST_BEGIN, HDF_FAILURE, 204 HDF_LOGI("error: unpacker PackBegin cmd not match, cmd(%{public}d)=%{public}s.", unpackCmd, 205 CmdUtils::CommandToString(unpackCmd))); 206 207 while (ret == HDF_SUCCESS && unpacker->NextSection()) { 208 if (!unpacker->BeginSection(unpackCmd)) { 209 HDF_LOGE("error: PackSection failed, unpackCmd=%{public}s.", 210 CmdUtils::CommandToString(unpackCmd)); 211 ret = HDF_FAILURE; 212 } 213 ret = ProcessRequestCmd(unpacker, unpackCmd, inFds, outFds); 214 } 215 216 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 217 HDF_LOGE("%{public}s: ProcessRequestCmd failed", __func__)); 218 /* pack request end commands */ 219 replyPacker_->PackEnd(CONTROL_CMD_REPLY_END); 220 221 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA 222 /* just for debug */ 223 replyPacker_->Dump(); 224 HDF_LOGI("CmdReply command cnt=%{public}d", replyCommandCnt_); 225 #endif // DEBUG_DISPLAY_CMD_RAW_DATA 226 227 /* Write reply pack */ 228 outEleCnt = replyPacker_->ValidSize() / CmdUtils::ELEMENT_SIZE; 229 ret = reply_->Write(reinterpret_cast<int32_t *>(replyPacker_->GetDataPtr()), outEleCnt, 230 CmdUtils::TRANSFER_WAIT_TIME); 231 if (ret != HDF_SUCCESS) { 232 HDF_LOGE("Reply write failure, ret=%{public}d", ret); 233 outEleCnt = 0; 234 } 235 int32_t ec = PeriodDataReset(); 236 return (ret == HDF_SUCCESS ? ec : ret); 237 } 238 239 private: InitReply(uint32_t size)240 int32_t InitReply(uint32_t size) 241 { 242 reply_ = std::make_shared<Transfer>(size, SmqType::SYNCED_SMQ); 243 DISPLAY_CHK_RETURN(reply_ == nullptr, HDF_FAILURE, 244 HDF_LOGE("%{public}s: reply_ construct failed", __func__)); 245 246 replyPacker_ = std::make_shared<CommandDataPacker>(); 247 DISPLAY_CHK_RETURN(replyPacker_ == nullptr, HDF_FAILURE, 248 HDF_LOGE("%{public}s: replyPacker_ construct failed", __func__)); 249 250 bool retBool = replyPacker_->Init(reply_->GetSize() * CmdUtils::ELEMENT_SIZE); 251 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 252 HDF_LOGE("%{public}s: replyPacker_ init failed", __func__)); 253 254 return CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_); 255 } 256 OnRequestEnd(std::shared_ptr<CommandDataUnpacker> unpacker)257 int32_t OnRequestEnd(std::shared_ptr<CommandDataUnpacker> unpacker) 258 { 259 DISPLAY_TRACE; 260 261 size_t errCnt = errMaps_.size(); 262 if (errCnt >= 0) { 263 int32_t ret = CmdUtils::StartSection(REPLY_CMD_SET_ERROR, replyPacker_); 264 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 265 HDF_LOGE("%{public}s: StartSection failed", __func__)); 266 267 bool result = replyPacker_->WriteUint32(errCnt); 268 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE, 269 HDF_LOGE("%{public}s: write errCnt failed", __func__)); 270 for (auto it = errMaps_.begin(); it != errMaps_.end(); ++it) { 271 result = replyPacker_->WriteInt32(it->first); 272 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE, 273 HDF_LOGE("%{public}s: write err-cmd failed, cmdId:%{public}s", 274 __func__, CmdUtils::CommandToString(it->first))); 275 276 result = replyPacker_->WriteInt32(it->second); 277 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE, 278 HDF_LOGE("%{public}s: write errNo failed, errNo:%{public}d", __func__, it->second)); 279 } 280 result = CmdUtils::EndSection(replyPacker_); 281 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE, 282 HDF_LOGE("%{public}s: write replyPacker_ EndSection failed", __func__)); 283 replyCommandCnt_++; 284 } 285 return HDF_SUCCESS; 286 } 287 OnPrepareDisplayLayers(std::shared_ptr<CommandDataUnpacker> unpacker)288 void OnPrepareDisplayLayers(std::shared_ptr<CommandDataUnpacker> unpacker) 289 { 290 DISPLAY_TRACE; 291 292 uint32_t devId = 0; 293 bool needFlush = false; 294 uint32_t vectSize = 0; 295 std::vector<uint32_t> layers; 296 std::vector<int32_t> types; 297 298 int32_t ret = unpacker->ReadUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 299 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 300 301 ret = impl_->PrepareDisplayLayers(devId, needFlush); 302 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 303 304 ret = impl_->GetDisplayCompChange(devId, layers, types); 305 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 306 307 ret = CmdUtils::StartSection(REPLY_CMD_PREPARE_DISPLAY_LAYERS, replyPacker_); 308 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 309 310 DISPLAY_CHECK(replyPacker_->WriteUint32(devId) == false, goto EXIT); 311 312 DISPLAY_CHECK(replyPacker_->WriteBool(needFlush) == false, goto EXIT); 313 // Write layers vector 314 vectSize = static_cast<uint32_t>(layers.size()); 315 DISPLAY_CHECK(replyPacker_->WriteUint32(vectSize) == false, goto EXIT); 316 317 for (uint32_t i = 0; i < vectSize; i++) { 318 DISPLAY_CHECK(replyPacker_->WriteUint32(layers[i]) == false, goto EXIT); 319 } 320 // Write composer types vector 321 vectSize = static_cast<uint32_t>(types.size()); 322 DISPLAY_CHECK(replyPacker_->WriteUint32(vectSize) == false, goto EXIT); 323 324 for (uint32_t i = 0; i < vectSize; i++) { 325 DISPLAY_CHECK(replyPacker_->WriteUint32(types[i]) == false, goto EXIT); 326 } 327 // End this cmd section 328 ret = CmdUtils::EndSection(replyPacker_); 329 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 330 replyCommandCnt_++; 331 EXIT: 332 if (ret != HDF_SUCCESS) { 333 errMaps_.emplace(REQUEST_CMD_PREPARE_DISPLAY_LAYERS, ret); 334 } 335 return; 336 } 337 OnSetDisplayClientBuffer(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & inFds)338 void OnSetDisplayClientBuffer(std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo>& inFds) 339 { 340 DISPLAY_TRACE; 341 342 uint32_t devId = 0; 343 int32_t ret = unpacker->ReadUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 344 345 BufferHandle *buffer = nullptr; 346 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::BufferHandleUnpack(unpacker, inFds, buffer), 347 HDF_LOGE("%{public}s, read buffer handle error", __func__)); 348 bool isValidBuffer = (ret == HDF_SUCCESS ? true : false); 349 350 uint32_t seqNo = -1; 351 bool result = true; 352 DISPLAY_CHK_CONDITION(result, ret == HDF_SUCCESS, unpacker->ReadUint32(seqNo), 353 HDF_LOGE("%{public}s, read seqNo error", __func__)); 354 ret = result ? HDF_SUCCESS : HDF_FAILURE; 355 356 int32_t fence = -1; 357 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorUnpack(unpacker, inFds, fence), 358 HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__)); 359 HdifdParcelable fdParcel(fence); 360 { 361 DISPLAY_CHECK(cacheMgr_ == nullptr, goto EXIT); 362 std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex()); 363 DeviceCache* devCache = cacheMgr_->DeviceCacheInstance(devId); 364 DISPLAY_CHECK(devCache == nullptr, goto EXIT); 365 366 ret = devCache->SetDisplayClientBuffer(buffer, seqNo, [&](const BufferHandle& handle)->int32_t { 367 int rc = impl_->SetDisplayClientBuffer(devId, handle, fdParcel.GetFd()); 368 DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail")); 369 return HDF_SUCCESS; 370 }); 371 } 372 #ifndef DISPLAY_COMMUNITY 373 fdParcel.Move(); 374 #endif // DISPLAY_COMMUNITY 375 EXIT: 376 if (ret != HDF_SUCCESS) { 377 HDF_LOGE("%{public}s, SetDisplayClientBuffer error", __func__); 378 if (isValidBuffer != HDF_SUCCESS) { 379 FreeBufferHandle(buffer); 380 } 381 errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret); 382 } 383 384 return; 385 } 386 OnSetDisplayClientDamage(std::shared_ptr<CommandDataUnpacker> unpacker)387 void OnSetDisplayClientDamage(std::shared_ptr<CommandDataUnpacker> unpacker) 388 { 389 DISPLAY_TRACE; 390 391 uint32_t devId = 0; 392 uint32_t vectSize = 0; 393 bool retBool = true; 394 DISPLAY_CHK_CONDITION(retBool, true, unpacker->ReadUint32(devId), 395 HDF_LOGE("%{public}s, read devId error", __func__)); 396 397 DISPLAY_CHK_CONDITION(retBool, true, unpacker->ReadUint32(vectSize), 398 HDF_LOGE("%{public}s, read vectSize error", __func__)); 399 400 int32_t ret = (retBool ? HDF_SUCCESS : HDF_FAILURE); 401 std::vector<IRect> rects(vectSize); 402 if (ret == HDF_SUCCESS) { 403 for (uint32_t i = 0; i < vectSize; i++) { 404 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]), 405 HDF_LOGE("%{public}s, read vect error at i = %{public}d", __func__, i)); 406 if (ret != HDF_SUCCESS) { 407 break; 408 } 409 } 410 } 411 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, impl_->SetDisplayClientDamage(devId, rects), 412 HDF_LOGE("%{public}s, SetDisplayClientDamage error", __func__)); 413 414 if (ret != HDF_SUCCESS) { 415 errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE, ret); 416 } 417 return; 418 } 419 OnCommit(std::shared_ptr<CommandDataUnpacker> unpacker,std::vector<HdifdInfo> & outFds)420 void OnCommit(std::shared_ptr<CommandDataUnpacker> unpacker, std::vector<HdifdInfo>& outFds) 421 { 422 DISPLAY_TRACE; 423 424 uint32_t devId = 0; 425 int32_t fence = -1; 426 427 const std::string SWITCH_ON = "on"; 428 const uint32_t DUMP_CACHE_SWITCH_LEN = 4; 429 char dumpSwitch[DUMP_CACHE_SWITCH_LEN] = {0}; 430 GetParameter("hdi.composer.dumpcache", "off", dumpSwitch, DUMP_CACHE_SWITCH_LEN); 431 432 if (SWITCH_ON.compare(dumpSwitch) == 0) { 433 cacheMgr_->Dump(); 434 } 435 436 bool retBool = true; 437 DISPLAY_CHK_CONDITION(retBool, true, unpacker->ReadUint32(devId), 438 HDF_LOGE("%{public}s, read devId error", __func__)); 439 440 int32_t ret = (retBool ? HDF_SUCCESS : HDF_FAILURE); 441 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, impl_->Commit(devId, fence), 442 HDF_LOGE("%{public}s, commit error", __func__)); 443 444 HdifdParcelable fdParcel(fence); 445 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::StartSection(REPLY_CMD_COMMIT, replyPacker_), 446 HDF_LOGE("%{public}s, StartSection error", __func__)); 447 448 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorPack(fdParcel.GetFd(), replyPacker_, outFds), 449 HDF_LOGE("%{public}s, FileDescriptorPack error", __func__)); 450 451 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::EndSection(replyPacker_), 452 HDF_LOGE("%{public}s, EndSection error", __func__)); 453 454 replyCommandCnt_++; 455 456 #ifndef DISPLAY_COMMUNITY 457 fdParcel.Move(); 458 #endif // DISPLAY_COMMUNITY 459 460 if (ret != HDF_SUCCESS) { 461 errMaps_.emplace(REQUEST_CMD_COMMIT, ret); 462 } 463 464 return; 465 } 466 OnSetLayerAlpha(std::shared_ptr<CommandDataUnpacker> unpacker)467 void OnSetLayerAlpha(std::shared_ptr<CommandDataUnpacker> unpacker) 468 { 469 DISPLAY_TRACE; 470 471 uint32_t devId = 0; 472 uint32_t layerId = 0; 473 LayerAlpha alpha = {0}; 474 bool retBool = true; 475 476 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 477 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 478 479 retBool = unpacker->ReadBool(alpha.enGlobalAlpha); 480 DISPLAY_CHECK(retBool == false, goto EXIT); 481 482 retBool = unpacker->ReadBool(alpha.enPixelAlpha); 483 DISPLAY_CHECK(retBool == false, goto EXIT); 484 485 retBool = unpacker->ReadUint8(alpha.alpha0); 486 DISPLAY_CHECK(retBool == false, goto EXIT); 487 488 retBool = unpacker->ReadUint8(alpha.alpha1); 489 DISPLAY_CHECK(retBool == false, goto EXIT); 490 491 retBool = unpacker->ReadUint8(alpha.gAlpha); 492 DISPLAY_CHECK(retBool == false, goto EXIT); 493 494 ret = impl_->SetLayerAlpha(devId, layerId, alpha); 495 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 496 497 EXIT: 498 if (ret != HDF_SUCCESS || retBool == false) { 499 errMaps_.emplace(REQUEST_CMD_SET_LAYER_ALPHA, ret); 500 } 501 return; 502 } 503 OnSetLayerRegion(std::shared_ptr<CommandDataUnpacker> unpacker)504 void OnSetLayerRegion(std::shared_ptr<CommandDataUnpacker> unpacker) 505 { 506 DISPLAY_TRACE; 507 508 uint32_t devId = 0; 509 uint32_t layerId = 0; 510 IRect rect = {0}; 511 512 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 513 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 514 515 ret = CmdUtils::RectUnpack(unpacker, rect); 516 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 517 518 ret = impl_->SetLayerRegion(devId, layerId, rect); 519 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 520 EXIT: 521 if (ret != HDF_SUCCESS) { 522 errMaps_.emplace(REQUEST_CMD_SET_LAYER_REGION, ret); 523 } 524 return; 525 } 526 OnSetLayerCrop(std::shared_ptr<CommandDataUnpacker> unpacker)527 void OnSetLayerCrop(std::shared_ptr<CommandDataUnpacker> unpacker) 528 { 529 DISPLAY_TRACE; 530 531 uint32_t devId = 0; 532 uint32_t layerId = 0; 533 IRect rect = {0}; 534 535 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 536 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 537 538 ret = CmdUtils::RectUnpack(unpacker, rect); 539 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 540 541 ret = impl_->SetLayerCrop(devId, layerId, rect); 542 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 543 EXIT: 544 if (ret != HDF_SUCCESS) { 545 errMaps_.emplace(REQUEST_CMD_SET_LAYER_CROP, ret); 546 } 547 return; 548 } 549 OnSetLayerZorder(std::shared_ptr<CommandDataUnpacker> unpacker)550 void OnSetLayerZorder(std::shared_ptr<CommandDataUnpacker> unpacker) 551 { 552 DISPLAY_TRACE; 553 554 uint32_t devId = 0; 555 uint32_t layerId = 0; 556 uint32_t zorder = 0; 557 558 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 559 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 560 561 ret = unpacker->ReadUint32(zorder) ? HDF_SUCCESS : HDF_FAILURE; 562 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 563 564 ret = impl_->SetLayerZorder(devId, layerId, zorder); 565 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 566 EXIT: 567 if (ret != HDF_SUCCESS) { 568 errMaps_.emplace(REQUEST_CMD_SET_LAYER_ZORDER, ret); 569 } 570 return; 571 } 572 OnSetLayerPreMulti(std::shared_ptr<CommandDataUnpacker> unpacker)573 void OnSetLayerPreMulti(std::shared_ptr<CommandDataUnpacker> unpacker) 574 { 575 DISPLAY_TRACE; 576 577 uint32_t devId = 0; 578 uint32_t layerId = 0; 579 bool preMulti = false; 580 581 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 582 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 583 584 ret = unpacker->ReadBool(preMulti) ? HDF_SUCCESS : HDF_FAILURE; 585 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 586 587 ret = impl_->SetLayerPreMulti(devId, layerId, preMulti); 588 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 589 EXIT: 590 if (ret != HDF_SUCCESS) { 591 errMaps_.emplace(REQUEST_CMD_SET_LAYER_PREMULTI, ret); 592 } 593 return; 594 } 595 OnSetLayerTransformMode(std::shared_ptr<CommandDataUnpacker> unpacker)596 void OnSetLayerTransformMode(std::shared_ptr<CommandDataUnpacker> unpacker) 597 { 598 DISPLAY_TRACE; 599 600 uint32_t devId = 0; 601 uint32_t layerId = 0; 602 int32_t type = 0; 603 604 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 605 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 606 607 ret = unpacker->ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE; 608 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 609 610 ret = impl_->SetLayerTransformMode(devId, layerId, static_cast<TransformType>(type)); 611 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 612 EXIT: 613 if (ret != HDF_SUCCESS) { 614 errMaps_.emplace(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE, ret); 615 } 616 return; 617 } 618 OnSetLayerDirtyRegion(std::shared_ptr<CommandDataUnpacker> unpacker)619 void OnSetLayerDirtyRegion(std::shared_ptr<CommandDataUnpacker> unpacker) 620 { 621 DISPLAY_TRACE; 622 623 uint32_t devId = 0; 624 uint32_t layerId = 0; 625 uint32_t vectSize = 0; 626 int32_t ret = HDF_SUCCESS; 627 628 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId), 629 HDF_LOGE("%{public}s, read devId error", __func__)); 630 631 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker->ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE, 632 HDF_LOGE("%{public}s, read vectSize error", __func__)); 633 634 std::vector<IRect> rects(vectSize); 635 if (ret == HDF_SUCCESS) { 636 for (uint32_t i = 0; i < vectSize; i++) { 637 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]), 638 HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i)); 639 if (ret != HDF_SUCCESS) { 640 break; 641 } 642 } 643 } 644 645 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, impl_->SetLayerDirtyRegion(devId, layerId, rects), 646 HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__)); 647 648 if (ret != HDF_SUCCESS) { 649 errMaps_.emplace(REQUEST_CMD_SET_LAYER_DIRTY_REGION, ret); 650 } 651 return; 652 } 653 OnSetLayerVisibleRegion(std::shared_ptr<CommandDataUnpacker> unpacker)654 void OnSetLayerVisibleRegion(std::shared_ptr<CommandDataUnpacker> unpacker) 655 { 656 DISPLAY_TRACE; 657 658 uint32_t devId = 0; 659 uint32_t layerId = 0; 660 uint32_t vectSize = 0; 661 int32_t ret = HDF_SUCCESS; 662 663 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId), 664 HDF_LOGE("%{public}s, read devId error", __func__)); 665 666 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker->ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE, 667 HDF_LOGE("%{public}s, read vectSize error", __func__)); 668 669 std::vector<IRect> rects(vectSize); 670 if (ret == HDF_SUCCESS) { 671 for (uint32_t i = 0; i < vectSize; i++) { 672 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]), 673 HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i)); 674 if (ret != HDF_SUCCESS) { 675 break; 676 } 677 } 678 } 679 680 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, impl_->SetLayerVisibleRegion(devId, layerId, rects), 681 HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__)); 682 683 if (ret != HDF_SUCCESS) { 684 errMaps_.emplace(REQUEST_CMD_SET_LAYER_VISIBLE_REGION, ret); 685 } 686 return; 687 } 688 OnSetLayerBuffer(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & inFds)689 void OnSetLayerBuffer(std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo>& inFds) 690 { 691 DISPLAY_TRACE; 692 693 uint32_t devId = 0; 694 uint32_t layerId = 0; 695 BufferHandle *buffer = nullptr; 696 int32_t ret = HDF_SUCCESS; 697 698 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId), 699 HDF_LOGE("%{public}s, read devId error", __func__)); 700 701 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::BufferHandleUnpack(unpacker, inFds, buffer), 702 HDF_LOGE("%{public}s, read BufferHandleUnpack error", __func__)); 703 bool isValidBuffer = (ret == HDF_SUCCESS ? true : false); 704 705 uint32_t seqNo = 0; 706 bool result = true; 707 DISPLAY_CHK_CONDITION(result, ret == HDF_SUCCESS, unpacker->ReadUint32(seqNo), 708 HDF_LOGE("%{public}s, read seqNo error", __func__)); 709 ret = result ? HDF_SUCCESS : HDF_FAILURE; 710 711 int32_t fence = -1; 712 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorUnpack(unpacker, inFds, fence), 713 HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__)); 714 715 HdifdParcelable fdParcel(fence); 716 717 // unpack deletingList 718 uint32_t vectSize = 0; 719 DISPLAY_CHK_CONDITION(result, ret == HDF_SUCCESS, unpacker->ReadUint32(vectSize), 720 HDF_LOGE("%{public}s, read vectSize error", __func__)); 721 722 std::vector<uint32_t> deletingList(vectSize); 723 for (uint32_t i = 0; i < vectSize; i++) { 724 DISPLAY_CHK_CONDITION(result, true, unpacker->ReadUint32(deletingList[i]), 725 HDF_LOGE("%{public}s, read seqNo error, at i = %{public}d", __func__, i)); 726 if (result != true) { 727 break; 728 } 729 } 730 ret = result ? HDF_SUCCESS : HDF_FAILURE; 731 { 732 DISPLAY_CHECK(cacheMgr_ == nullptr, goto EXIT); 733 std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex()); 734 DeviceCache* devCache = nullptr; 735 LayerCache* layerCache = nullptr; 736 devCache = cacheMgr_->DeviceCacheInstance(devId); 737 DISPLAY_CHECK(devCache == nullptr, goto EXIT); 738 layerCache = devCache->LayerCacheInstance(layerId); 739 DISPLAY_CHECK(layerCache == nullptr, goto EXIT); 740 741 ret = layerCache->SetLayerBuffer(buffer, seqNo, deletingList, [&](const BufferHandle& handle)->int32_t { 742 DumpLayerBuffer(devId, layerId, fence, handle); 743 744 int rc = impl_->SetLayerBuffer(devId, layerId, handle, fdParcel.GetFd()); 745 DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail")); 746 return HDF_SUCCESS; 747 }); 748 } 749 #ifndef DISPLAY_COMMUNITY 750 fdParcel.Move(); 751 #endif // DISPLAY_COMMUNITY 752 EXIT: 753 if (ret != HDF_SUCCESS) { 754 HDF_LOGE("%{public}s, SetLayerBuffer error", __func__); 755 if (isValidBuffer != HDF_SUCCESS) { 756 FreeBufferHandle(buffer); 757 } 758 errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret); 759 } 760 761 return; 762 } 763 OnSetLayerCompositionType(std::shared_ptr<CommandDataUnpacker> unpacker)764 void OnSetLayerCompositionType(std::shared_ptr<CommandDataUnpacker> unpacker) 765 { 766 DISPLAY_TRACE; 767 768 uint32_t devId = 0; 769 uint32_t layerId = 0; 770 int32_t type; 771 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 772 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 773 774 ret = unpacker->ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE; 775 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 776 777 ret = impl_->SetLayerCompositionType(devId, layerId, static_cast<CompositionType>(type)); 778 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 779 EXIT: 780 if (ret != HDF_SUCCESS) { 781 errMaps_.emplace(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE, ret); 782 } 783 return; 784 } 785 OnSetLayerBlendType(std::shared_ptr<CommandDataUnpacker> unpacker)786 void OnSetLayerBlendType(std::shared_ptr<CommandDataUnpacker> unpacker) 787 { 788 DISPLAY_TRACE; 789 790 uint32_t devId = 0; 791 uint32_t layerId = 0; 792 int32_t type; 793 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 794 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 795 796 ret = unpacker->ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE; 797 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 798 799 ret = impl_->SetLayerBlendType(devId, layerId, static_cast<BlendType>(type)); 800 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 801 EXIT: 802 if (ret != HDF_SUCCESS) { 803 errMaps_.emplace(REQUEST_CMD_SET_LAYER_BLEND_TYPE, ret); 804 } 805 return; 806 } 807 OnSetLayerMaskInfo(std::shared_ptr<CommandDataUnpacker> unpacker)808 void OnSetLayerMaskInfo(std::shared_ptr<CommandDataUnpacker> unpacker) 809 { 810 DISPLAY_TRACE; 811 812 uint32_t devId = 0; 813 uint32_t layerId = 0; 814 uint32_t maskInfo = 0; 815 816 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 817 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 818 819 ret = unpacker->ReadUint32(maskInfo) ? HDF_SUCCESS : HDF_FAILURE; 820 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 821 822 ret = impl_->SetLayerMaskInfo(devId, layerId, static_cast<MaskInfo>(maskInfo)); 823 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 824 EXIT: 825 if (ret != HDF_SUCCESS) { 826 errMaps_.emplace(REQUEST_CMD_SET_LAYER_MASK_INFO, ret); 827 } 828 return; 829 } 830 OnSetLayerColor(std::shared_ptr<CommandDataUnpacker> unpacker)831 void OnSetLayerColor(std::shared_ptr<CommandDataUnpacker> unpacker) 832 { 833 DISPLAY_TRACE; 834 835 uint32_t devId = 0; 836 uint32_t layerId = 0; 837 LayerColor layerColor = {0}; 838 839 int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId); 840 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 841 842 ret = CmdUtils::LayerColorUnpack(unpacker, layerColor); 843 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 844 845 ret = impl_->SetLayerColor(devId, layerId, layerColor); 846 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 847 EXIT: 848 if (ret != HDF_SUCCESS) { 849 errMaps_.emplace(REQUEST_CMD_SET_LAYER_COLOR, ret); 850 } 851 return; 852 } 853 PeriodDataReset()854 int32_t PeriodDataReset() 855 { 856 replyCommandCnt_ = 0; 857 errMaps_.clear(); 858 859 int32_t ret = CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_); 860 if (ret != HDF_SUCCESS) { 861 HDF_LOGE("PackBegin failure, ret=%{public}d", ret); 862 } 863 return ret; 864 } 865 GetFileName(uint32_t devId,uint32_t layerId,const BufferHandle & buffer)866 static std::string GetFileName(uint32_t devId, uint32_t layerId, const BufferHandle& buffer) 867 { 868 struct timeval tv; 869 char nowStr[TIME_BUFFER_MAX_LEN] = {0}; 870 871 gettimeofday(&tv, nullptr); 872 if (strftime(nowStr, sizeof(nowStr), "%m-%d-%H-%M-%S", localtime(&tv.tv_sec)) == 0) { 873 HDF_LOGE("strftime failed"); 874 return ""; 875 }; 876 877 std::ostringstream strStream; 878 strStream << "hdi_layer_" << devId << "_" << layerId << "_" << buffer.width << "x" << buffer.height << "_" << 879 nowStr << "-" << tv.tv_usec; 880 return strStream.str(); 881 } 882 DumpLayerBuffer(uint32_t devId,uint32_t layerId,int32_t fence,const BufferHandle & buffer)883 static void DumpLayerBuffer(uint32_t devId, uint32_t layerId, int32_t fence, const BufferHandle& buffer) 884 { 885 const std::string SWITCH_ON = "on"; 886 const uint32_t DUMP_BUFFER_SWITCH_LEN = 4; 887 char dumpSwitch[DUMP_BUFFER_SWITCH_LEN] = {0}; 888 GetParameter("hdi.composer.dumpbuffer", "off", dumpSwitch, DUMP_BUFFER_SWITCH_LEN); 889 890 if (SWITCH_ON.compare(dumpSwitch) != 0) { 891 return; 892 } 893 894 const uint32_t FENCE_TIMEOUT = 3000; 895 int32_t retCode = WaitFence(fence, FENCE_TIMEOUT); 896 if (retCode != HDF_SUCCESS) { 897 return; 898 } 899 900 if (g_bufferServiceImpl == nullptr) { 901 g_bufferServiceImpl = IMapper::Get(true); 902 DISPLAY_CHECK((g_bufferServiceImpl == nullptr), HDF_LOGE("get IMapper failed")); 903 } 904 905 std::string fileName = GetFileName(devId, layerId, buffer); 906 DISPLAY_CHECK((fileName == ""), HDF_LOGE("GetFileName failed")); 907 HDF_LOGI("fileName = %{public}s", fileName.c_str()); 908 909 const std::string PATH_PREFIX = "/data/local/traces/"; 910 std::stringstream filePath; 911 filePath << PATH_PREFIX << fileName; 912 std::ofstream rawDataFile(filePath.str(), std::ofstream::binary); 913 DISPLAY_CHECK((!rawDataFile.good()), HDF_LOGE("open file failed, %{public}s", 914 std::strerror(errno))); 915 916 sptr<NativeBuffer> hdiBuffer = new NativeBuffer(); 917 hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&buffer)); 918 919 int32_t ret = 0; 920 ret = g_bufferServiceImpl->Mmap(hdiBuffer); 921 DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Mmap buffer failed")); 922 923 std::chrono::milliseconds time_before = std::chrono::duration_cast<std::chrono::milliseconds> ( 924 std::chrono::system_clock::now().time_since_epoch() 925 ); 926 rawDataFile.write(static_cast<const char *>(buffer.virAddr), buffer.size); 927 std::chrono::milliseconds time_after = std::chrono::duration_cast<std::chrono::milliseconds> ( 928 std::chrono::system_clock::now().time_since_epoch() 929 ); 930 HDF_LOGI("wirte file take time %{public}lld", time_after.count() - time_before.count()); 931 rawDataFile.close(); 932 933 ret = g_bufferServiceImpl->Unmap(hdiBuffer); 934 DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Unmap buffer failed")); 935 } 936 WaitFence(int32_t fence,uint32_t timeout)937 static int32_t WaitFence(int32_t fence, uint32_t timeout) 938 { 939 int retCode = -1; 940 if (fence < 0) { 941 HDF_LOGE("The fence id is invalid."); 942 return retCode; 943 } 944 945 struct pollfd pollfds = {0}; 946 pollfds.fd = fence; 947 pollfds.events = POLLIN; 948 949 do { 950 retCode = poll(&pollfds, 1, timeout); 951 } while (retCode == -1 && (errno == EINTR || errno == EAGAIN)); 952 953 if (retCode == 0) { 954 retCode = -1; 955 errno = ETIME; 956 } else if (retCode > 0) { 957 retCode = 0; 958 if (pollfds.revents & (POLLERR | POLLNVAL)) { 959 retCode = -1; 960 errno = EINVAL; 961 } 962 } 963 964 return retCode < 0 ? -errno : HDF_SUCCESS; 965 } 966 967 private: 968 VdiImpl* impl_ = nullptr; 969 std::shared_ptr<DeviceCacheManager> cacheMgr_; 970 std::shared_ptr<Transfer> request_; 971 bool isReplyUpdated_; 972 std::shared_ptr<Transfer> reply_; 973 /* period data */ 974 uint32_t replyCommandCnt_; 975 std::shared_ptr<CommandDataPacker> replyPacker_; 976 std::unordered_map<int32_t, int32_t> errMaps_; 977 }; 978 using HdiDisplayCmdResponser = DisplayCmdResponser<SharedMemQueue<int32_t>, IDisplayComposerVdi>; 979 } // namespace V1_0 980 } // namespace Composer 981 } // namespace Display 982 } // namespace HDI 983 } // namespace OHOS 984 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H 985