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