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