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