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