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