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 <unordered_map> 20 #include "base/hdi_smq.h" 21 #include "command_pack/command_data_packer.h" 22 #include "command_pack/command_data_unpacker.h" 23 #include "common/include/display_interface_utils.h" 24 #include "display_cmd_utils.h" 25 #include "hdifd_parcelable.h" 26 #include "hdf_log.h" 27 #include "v1_0/display_composer_type.h" 28 #include "v1_0/idisplay_composer.h" 29 30 namespace OHOS { 31 namespace HDI { 32 namespace Display { 33 namespace Composer { 34 namespace V1_0 { 35 using namespace OHOS::HDI::Base; 36 using namespace OHOS::HDI::Display::Composer::V1_0; 37 38 template <typename Transfer, typename CompHdi> 39 class DisplayCmdRequester { 40 public: DisplayCmdRequester(sptr<CompHdi> hdi)41 DisplayCmdRequester(sptr<CompHdi> hdi) 42 : initFlag_(false), 43 hdi_(hdi), 44 request_(nullptr), 45 reply_(nullptr) 46 { 47 } 48 Create(sptr<CompHdi> hdi)49 static std::unique_ptr<DisplayCmdRequester> Create(sptr<CompHdi> hdi) 50 { 51 DISPLAY_CHK_RETURN(hdi == nullptr, nullptr, HDF_LOGE("%{public}s: hdi is nullptr", __func__)); 52 auto requester = std::make_unique<DisplayCmdRequester>(hdi); 53 DISPLAY_CHK_RETURN(requester == nullptr, nullptr, 54 HDF_LOGE("%{public}s: CmdRequester is nullptr", __func__)); 55 auto ret = requester->Init(CmdUtils::INIT_ELEMENT_COUNT); 56 if (ret != HDF_SUCCESS) { 57 HDF_LOGE("DisplayCmdRequester init failed"); 58 return nullptr; 59 } 60 return requester; 61 } 62 Init(uint32_t eleCnt)63 int32_t Init(uint32_t eleCnt) 64 { 65 request_ = std::make_shared<Transfer>(eleCnt, SmqType::SYNCED_SMQ); 66 DISPLAY_CHK_RETURN(request_ == nullptr, HDF_FAILURE, 67 HDF_LOGE("%{public}s: request_ is nullptr", __func__)); 68 69 DISPLAY_CHK_RETURN(hdi_ == nullptr, HDF_FAILURE, 70 HDF_LOGE("%{public}s: hdi_ is nullptr", __func__)); 71 72 int32_t ret = hdi_->InitCmdRequest(request_); 73 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 74 HDF_LOGE("%{public}s: InitCmdRequest failure, ret=%{public}d", __func__, ret)); 75 76 if (requestPacker_.Init(request_->GetSize() << CmdUtils::MOVE_SIZE) == false) { 77 HDF_LOGE("%{public}s: requestPacker init failed", __func__); 78 return HDF_FAILURE; 79 } 80 81 ret = hdi_->GetCmdReply(reply_); 82 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 83 HDF_LOGE("%{public}s: GetCmdReply failure, ret=%{public}d", __func__, ret)); 84 initFlag_ = true; 85 86 ret = CmdUtils::StartPack(CONTROL_CMD_REQUEST_BEGIN, requestPacker_); 87 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 88 HDF_LOGE("%{public}s: StartPack failed", __func__)); 89 90 return HDF_SUCCESS; 91 } 92 PrepareDisplayLayers(uint32_t devId,bool & needFlushFb)93 int32_t PrepareDisplayLayers(uint32_t devId, bool &needFlushFb) 94 { 95 uint32_t replyEleCnt; 96 std::vector<HdifdInfo> outFds; 97 std::shared_ptr<char> replyData; 98 99 int32_t ret = CmdUtils::StartSection(REQUEST_CMD_PREPARE_DISPLAY_LAYERS, requestPacker_); 100 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 101 102 ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 103 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 104 105 ret = CmdUtils::EndSection(requestPacker_); 106 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 107 108 ret = CmdUtils::EndPack(requestPacker_); 109 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 110 111 ret = DoRequest(replyEleCnt, outFds, replyData); 112 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 113 114 ret = DoReplyResults(replyEleCnt, outFds, replyData, [&](void *data) -> int32_t { 115 needFlushFb = *(reinterpret_cast<bool *>(data)); 116 return HDF_SUCCESS; 117 }); 118 if (ret != HDF_SUCCESS) { 119 HDF_LOGE("DoReplyResults failure, ret=%{public}d", ret); 120 } 121 122 EXIT: 123 return PeriodDataReset() == HDF_SUCCESS ? ret : HDF_FAILURE; 124 } 125 SetDisplayClientBuffer(uint32_t devId,const BufferHandle * buffer,uint32_t seqNo,int32_t fence)126 int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle* buffer, uint32_t seqNo, 127 int32_t fence) 128 { 129 int32_t ret = 0; 130 bool retBool = false; 131 int32_t writePos = requestPacker_.ValidSize(); 132 133 do { 134 ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, requestPacker_); 135 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 136 HDF_LOGE("%{public}s: StartSection failed", __func__)); 137 138 retBool = requestPacker_.WriteUint32(devId); 139 DISPLAY_CHK_BREAK(retBool == false, 140 HDF_LOGE("%{public}s: write devId failed", __func__)); 141 142 ret = CmdUtils::BufferHandlePack(buffer, requestPacker_, requestHdiFds_); 143 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 144 HDF_LOGE("%{public}s: BufferHandlePack failed", __func__)); 145 146 retBool = requestPacker_.WriteUint32(seqNo); 147 DISPLAY_CHK_BREAK(retBool == false, 148 HDF_LOGE("%{public}s: write seqNo failed", __func__)); 149 150 ret = CmdUtils::FileDescriptorPack(fence, requestPacker_, requestHdiFds_); 151 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 152 HDF_LOGE("%{public}s: FileDescriptorPack failed", __func__)); 153 154 ret = CmdUtils::EndSection(requestPacker_); 155 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 156 HDF_LOGE("%{public}s: EndSection failed", __func__)); 157 } while (0); 158 159 if (retBool == false || ret != HDF_SUCCESS) { 160 requestPacker_.RollBack(writePos); 161 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 162 return HDF_FAILURE; 163 } 164 return HDF_SUCCESS; 165 } 166 SetDisplayClientDamage(uint32_t devId,std::vector<IRect> & rects)167 int32_t SetDisplayClientDamage(uint32_t devId, std::vector<IRect> &rects) 168 { 169 int32_t ret = 0; 170 bool retBool = false; 171 int32_t writePos = requestPacker_.ValidSize(); 172 173 do { 174 ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE, requestPacker_); 175 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 176 HDF_LOGE("%{public}s: StartSection failed", __func__)); 177 178 ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 179 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 180 HDF_LOGE("%{public}s: write devId failed", __func__)); 181 182 uint32_t vectSize = static_cast<uint32_t>(rects.size()); 183 retBool = requestPacker_.WriteUint32(vectSize); 184 DISPLAY_CHK_BREAK(retBool == false, 185 HDF_LOGE("%{public}s: write damage vector size failed", __func__)); 186 187 for (uint32_t i = 0; i < vectSize; i++) { 188 ret = CmdUtils::RectPack(rects[i], requestPacker_); 189 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 190 HDF_LOGE("%{public}s: RectPack failed", __func__)); 191 } 192 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 193 HDF_LOGE("%{public}s: RectPack failed, break!", __func__)); 194 195 ret = CmdUtils::EndSection(requestPacker_); 196 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 197 HDF_LOGE("%{public}s: EndSection failed", __func__)); 198 } while (0); 199 200 if (retBool == false || ret != HDF_SUCCESS) { 201 requestPacker_.RollBack(writePos); 202 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 203 return HDF_FAILURE; 204 } 205 return HDF_SUCCESS; 206 } 207 Commit(uint32_t devId,int32_t & fence)208 int32_t Commit(uint32_t devId, int32_t &fence) 209 { 210 uint32_t replyEleCnt = 0; 211 std::vector<HdifdInfo> outFds; 212 std::shared_ptr<char> replyData; 213 214 int32_t ret = CmdUtils::StartSection(REQUEST_CMD_COMMIT, requestPacker_); 215 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 216 217 ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 218 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 219 220 ret = CmdUtils::EndSection(requestPacker_); 221 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 222 223 ret = CmdUtils::EndPack(requestPacker_); 224 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 225 226 ret = DoRequest(replyEleCnt, outFds, replyData); 227 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 228 229 ret = DoReplyResults(replyEleCnt, outFds, replyData, [&](void *data) -> int32_t { 230 fence = *(reinterpret_cast<int32_t *>(data)); 231 return HDF_SUCCESS; 232 }); 233 if (ret != HDF_SUCCESS) { 234 HDF_LOGE("DoReplyResults failure, ret=%{public}d", ret); 235 } 236 237 EXIT: 238 return PeriodDataReset() == HDF_SUCCESS ? ret : HDF_FAILURE; 239 } 240 SetLayerAlpha(uint32_t devId,uint32_t layerId,const LayerAlpha & alpha)241 int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, const LayerAlpha &alpha) 242 { 243 int32_t ret = 0; 244 bool retBool = false; 245 int32_t writePos = requestPacker_.ValidSize(); 246 247 do { 248 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_ALPHA, requestPacker_); 249 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 250 HDF_LOGE("%{public}s: StartSection failed", __func__)); 251 252 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 253 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 254 HDF_LOGE("%{public}s: write devId failed", __func__)); 255 256 retBool = requestPacker_.WriteBool(alpha.enGlobalAlpha); 257 DISPLAY_CHK_BREAK(retBool == false, 258 HDF_LOGE("%{public}s: write enGlobalAlpha failed", __func__)); 259 260 retBool = requestPacker_.WriteBool(alpha.enPixelAlpha); 261 DISPLAY_CHK_BREAK(retBool == false, 262 HDF_LOGE("%{public}s: write enPixelAlpha failed", __func__)); 263 264 retBool = requestPacker_.WriteUint8(alpha.alpha0); 265 DISPLAY_CHK_BREAK(retBool == false, 266 HDF_LOGE("%{public}s: write alpha0 failed", __func__)); 267 268 retBool = requestPacker_.WriteUint8(alpha.alpha1); 269 DISPLAY_CHK_BREAK(retBool == false, 270 HDF_LOGE("%{public}s: write alpha1 failed", __func__)); 271 272 retBool = requestPacker_.WriteUint8(alpha.gAlpha); 273 DISPLAY_CHK_BREAK(retBool == false, 274 HDF_LOGE("%{public}s: write gAlpha failed", __func__)); 275 276 ret = CmdUtils::EndSection(requestPacker_); 277 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 278 HDF_LOGE("%{public}s: EndSection failed", __func__)); 279 } while (0); 280 281 if (retBool == false || ret != HDF_SUCCESS) { 282 requestPacker_.RollBack(writePos); 283 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 284 return HDF_FAILURE; 285 } 286 return HDF_SUCCESS; 287 } 288 SetLayerRegion(uint32_t devId,uint32_t layerId,const IRect & rect)289 int32_t SetLayerRegion(uint32_t devId, uint32_t layerId, const IRect &rect) 290 { 291 int32_t ret = 0; 292 int32_t writePos = requestPacker_.ValidSize(); 293 294 do { 295 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_REGION, requestPacker_); 296 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 297 HDF_LOGE("%{public}s: StartSection failed", __func__)); 298 299 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 300 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 301 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 302 303 ret = CmdUtils::RectPack(rect, requestPacker_); 304 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 305 HDF_LOGE("%{public}s: RectPack failed", __func__)); 306 307 ret = CmdUtils::EndSection(requestPacker_); 308 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 309 HDF_LOGE("%{public}s: EndSection failed", __func__)); 310 } while (0); 311 312 if (ret != HDF_SUCCESS) { 313 requestPacker_.RollBack(writePos); 314 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 315 return HDF_FAILURE; 316 } 317 return HDF_SUCCESS; 318 } 319 SetLayerCrop(uint32_t devId,uint32_t layerId,const IRect & rect)320 int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, const IRect &rect) 321 { 322 int32_t ret = 0; 323 int32_t writePos = requestPacker_.ValidSize(); 324 325 do { 326 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_CROP, requestPacker_); 327 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 328 HDF_LOGE("%{public}s: StartSection failed", __func__)); 329 330 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 331 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 332 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 333 334 ret = CmdUtils::RectPack(rect, requestPacker_); 335 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 336 HDF_LOGE("%{public}s: RectPack failed", __func__)); 337 338 ret = CmdUtils::EndSection(requestPacker_); 339 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 340 HDF_LOGE("%{public}s: EndSection failed", __func__)); 341 } while (0); 342 343 if (ret != HDF_SUCCESS) { 344 requestPacker_.RollBack(writePos); 345 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 346 return HDF_FAILURE; 347 } 348 return HDF_SUCCESS; 349 } 350 SetLayerZorder(uint32_t devId,uint32_t layerId,uint32_t zorder)351 int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder) 352 { 353 int32_t ret = 0; 354 bool retBool = false; 355 int32_t writePos = requestPacker_.ValidSize(); 356 357 do { 358 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_ZORDER, requestPacker_); 359 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 360 HDF_LOGE("%{public}s: StartSection failed", __func__)); 361 362 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 363 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 364 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 365 366 retBool = requestPacker_.WriteUint32(zorder); 367 DISPLAY_CHK_BREAK(retBool == false, 368 HDF_LOGE("%{public}s: write zorder failed", __func__)); 369 370 ret = CmdUtils::EndSection(requestPacker_); 371 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 372 HDF_LOGE("%{public}s: EndSection failed", __func__)); 373 } while (0); 374 375 if (retBool == false || ret != HDF_SUCCESS) { 376 requestPacker_.RollBack(writePos); 377 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 378 return HDF_FAILURE; 379 } 380 return HDF_SUCCESS; 381 } 382 SetLayerPreMulti(uint32_t devId,uint32_t layerId,bool preMul)383 int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul) 384 { 385 int32_t ret = 0; 386 bool retBool = false; 387 int32_t writePos = requestPacker_.ValidSize(); 388 389 do { 390 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_PREMULTI, requestPacker_); 391 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 392 HDF_LOGE("%{public}s: StartSection failed", __func__)); 393 394 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 395 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 396 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 397 398 retBool = requestPacker_.WriteBool(preMul); 399 DISPLAY_CHK_BREAK(retBool == false, 400 HDF_LOGE("%{public}s: write preMul failed", __func__)); 401 402 ret = CmdUtils::EndSection(requestPacker_); 403 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 404 HDF_LOGE("%{public}s: EndSection failed", __func__)); 405 } while (0); 406 407 if (retBool == false || ret != HDF_SUCCESS) { 408 requestPacker_.RollBack(writePos); 409 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 410 return HDF_FAILURE; 411 } 412 413 return HDF_SUCCESS; 414 } 415 SetLayerTransformMode(uint32_t devId,uint32_t layerId,TransformType type)416 int32_t SetLayerTransformMode(uint32_t devId, uint32_t layerId, TransformType type) 417 { 418 int32_t ret = 0; 419 bool retBool = false; 420 int32_t writePos = requestPacker_.ValidSize(); 421 422 do { 423 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE, requestPacker_); 424 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 425 HDF_LOGE("%{public}s: StartSection failed", __func__)); 426 427 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 428 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 429 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 430 431 retBool = requestPacker_.WriteInt32(type); 432 DISPLAY_CHK_BREAK(retBool == false, 433 HDF_LOGE("%{public}s: write transform-type failed", __func__)); 434 435 ret = CmdUtils::EndSection(requestPacker_); 436 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 437 HDF_LOGE("%{public}s: EndSection failed", __func__)); 438 } while (0); 439 440 if (retBool == false || ret != HDF_SUCCESS) { 441 requestPacker_.RollBack(writePos); 442 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 443 return HDF_FAILURE; 444 } 445 return HDF_SUCCESS; 446 } 447 SetLayerDirtyRegion(uint32_t devId,uint32_t layerId,const std::vector<IRect> & rects)448 int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, const std::vector<IRect> &rects) 449 { 450 int32_t ret = 0; 451 bool retBool = false; 452 int32_t writePos = requestPacker_.ValidSize(); 453 454 do { 455 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_DIRTY_REGION, requestPacker_); 456 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 457 HDF_LOGE("%{public}s: StartSection failed", __func__)); 458 459 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 460 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 461 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 462 463 uint32_t vSize = rects.size(); 464 retBool = requestPacker_.WriteUint32(vSize); 465 DISPLAY_CHK_BREAK(retBool == false, 466 HDF_LOGE("%{public}s: write vSize failed", __func__)); 467 for (uint32_t i = 0; i < vSize; i++) { 468 ret = CmdUtils::RectPack(rects[i], requestPacker_); 469 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 470 HDF_LOGE("%{public}s: RectPack failed", __func__)); 471 } 472 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 473 HDF_LOGE("%{public}s: RectPack failed, break", __func__)); 474 475 ret = CmdUtils::EndSection(requestPacker_); 476 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 477 HDF_LOGE("%{public}s: EndSection failed", __func__)); 478 } while (0); 479 480 if (retBool == false || ret != HDF_SUCCESS) { 481 requestPacker_.RollBack(writePos); 482 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 483 return HDF_FAILURE; 484 } 485 return HDF_SUCCESS; 486 } 487 SetLayerVisibleRegion(uint32_t devId,uint32_t layerId,std::vector<IRect> & rects)488 int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, std::vector<IRect> &rects) 489 { 490 int32_t ret = 0; 491 bool retBool = false; 492 int32_t writePos = requestPacker_.ValidSize(); 493 494 do { 495 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_VISIBLE_REGION, requestPacker_); 496 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 497 HDF_LOGE("%{public}s: StartSection failed", __func__)); 498 499 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 500 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 501 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 502 503 uint32_t vSize = rects.size(); 504 retBool = requestPacker_.WriteUint32(vSize); 505 DISPLAY_CHK_BREAK(retBool == false, 506 HDF_LOGE("%{public}s: write vSize failed", __func__)); 507 for (uint32_t i = 0; i < vSize; i++) { 508 ret = CmdUtils::RectPack(rects[i], requestPacker_); 509 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 510 HDF_LOGE("%{public}s: RectPack failed", __func__)); 511 } 512 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 513 HDF_LOGE("%{public}s: RectPack failed, break", __func__)); 514 515 ret = CmdUtils::EndSection(requestPacker_); 516 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 517 HDF_LOGE("%{public}s: EndSection failed", __func__)); 518 } while (0); 519 520 if (retBool == false || ret != HDF_SUCCESS) { 521 requestPacker_.RollBack(writePos); 522 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 523 return HDF_FAILURE; 524 } 525 return HDF_SUCCESS; 526 } 527 SetLayerBuffer(uint32_t devId,uint32_t layerId,const BufferHandle * buffer,uint32_t seqNo,int32_t fence,const std::vector<uint32_t> & deletingList)528 int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle* buffer, uint32_t seqNo, 529 int32_t fence, const std::vector<uint32_t>& deletingList) 530 { 531 int32_t ret = 0; 532 bool retBool = false; 533 bool result = false; 534 int32_t writePos = requestPacker_.ValidSize(); 535 536 do { 537 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_BUFFER, requestPacker_); 538 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 539 HDF_LOGE("%{public}s: StartSection failed", __func__)); 540 541 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 542 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 543 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 544 545 ret = CmdUtils::BufferHandlePack(buffer, requestPacker_, requestHdiFds_); 546 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 547 HDF_LOGE("%{public}s: BufferHandlePack failed", __func__)); 548 549 result = requestPacker_.WriteUint32(seqNo); 550 DISPLAY_CHK_BREAK(result == false, 551 HDF_LOGE("%{public}s: write seqNo failed", __func__)); 552 553 ret = CmdUtils::FileDescriptorPack(fence, requestPacker_, requestHdiFds_); 554 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 555 HDF_LOGE("%{public}s: FileDescriptorPack failed", __func__)); 556 // write deletingList 557 uint32_t vectSize = static_cast<uint32_t>(deletingList.size()); 558 retBool = requestPacker_.WriteUint32(vectSize); 559 DISPLAY_CHK_BREAK(retBool == false, 560 HDF_LOGE("%{public}s: write vector size failed", __func__)); 561 562 for (uint32_t i = 0; i < vectSize; i++) { 563 bool result = requestPacker_.WriteUint32(deletingList[i]); 564 DISPLAY_CHK_BREAK(result == false, 565 HDF_LOGE("%{public}s: write deletingList failed", __func__)); 566 } 567 DISPLAY_CHK_BREAK(result == false, 568 HDF_LOGE("%{public}s: write deletingList failed, break!", __func__)); 569 570 ret = CmdUtils::EndSection(requestPacker_); 571 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 572 HDF_LOGE("%{public}s: EndSection failed", __func__)); 573 } while (0); 574 575 if (retBool == false || result == false || ret != HDF_SUCCESS) { 576 requestPacker_.RollBack(writePos); 577 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 578 return HDF_FAILURE; 579 } 580 return HDF_SUCCESS; 581 } 582 SetLayerCompositionType(uint32_t devId,uint32_t layerId,CompositionType type)583 int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type) 584 { 585 int32_t ret = 0; 586 bool retBool = false; 587 int32_t writePos = requestPacker_.ValidSize(); 588 589 do { 590 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE, requestPacker_); 591 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 592 HDF_LOGE("%{public}s: StartSection failed", __func__)); 593 594 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 595 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 596 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 597 598 retBool = requestPacker_.WriteInt32(type); 599 DISPLAY_CHK_BREAK(retBool == false, 600 HDF_LOGE("%{public}s: write composition type failed", __func__)); 601 602 ret = CmdUtils::EndSection(requestPacker_); 603 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 604 HDF_LOGE("%{public}s: EndSection failed", __func__)); 605 } while (0); 606 607 if (retBool == false || ret != HDF_SUCCESS) { 608 requestPacker_.RollBack(writePos); 609 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 610 return HDF_FAILURE; 611 } 612 return HDF_SUCCESS; 613 } 614 SetLayerBlendType(uint32_t devId,uint32_t layerId,BlendType type)615 int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type) 616 { 617 int32_t ret = 0; 618 bool retBool = false; 619 int32_t writePos = requestPacker_.ValidSize(); 620 621 do { 622 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_BLEND_TYPE, requestPacker_); 623 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 624 HDF_LOGE("%{public}s: StartSection failed", __func__)); 625 626 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 627 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 628 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 629 630 retBool = requestPacker_.WriteInt32(type); 631 DISPLAY_CHK_BREAK(retBool == false, 632 HDF_LOGE("%{public}s: write blend type failed", __func__)); 633 634 ret = CmdUtils::EndSection(requestPacker_); 635 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 636 HDF_LOGE("%{public}s: EndSection failed", __func__)); 637 } while (0); 638 639 if (retBool == false || ret != HDF_SUCCESS) { 640 requestPacker_.RollBack(writePos); 641 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 642 return HDF_FAILURE; 643 } 644 return HDF_SUCCESS; 645 } 646 SetLayerMaskInfo(uint32_t devId,uint32_t layerId,const MaskInfo maskInfo)647 int32_t SetLayerMaskInfo(uint32_t devId, uint32_t layerId, const MaskInfo maskInfo) 648 { 649 int32_t ret = 0; 650 bool retBool = false; 651 int32_t writePos = requestPacker_.ValidSize(); 652 653 do { 654 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_MASK_INFO, requestPacker_); 655 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 656 HDF_LOGE("%{public}s: StartSection failed", __func__)); 657 658 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 659 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 660 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 661 662 retBool = requestPacker_.WriteUint32(maskInfo); 663 DISPLAY_CHK_BREAK(retBool == false, 664 HDF_LOGE("%{public}s: write maskInfo failed", __func__)); 665 666 ret = CmdUtils::EndSection(requestPacker_); 667 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 668 HDF_LOGE("%{public}s: EndSection failed", __func__)); 669 } while (0); 670 671 if (retBool == false || ret != HDF_SUCCESS) { 672 requestPacker_.RollBack(writePos); 673 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 674 return HDF_FAILURE; 675 } 676 return HDF_SUCCESS; 677 } 678 SetLayerColor(uint32_t devId,uint32_t layerId,const LayerColor & layerColor)679 int32_t SetLayerColor(uint32_t devId, uint32_t layerId, const LayerColor& layerColor) 680 { 681 int32_t ret = 0; 682 int32_t writePos = requestPacker_.ValidSize(); 683 684 do { 685 ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_COLOR, requestPacker_); 686 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 687 HDF_LOGE("%{public}s: StartSection failed", __func__)); 688 689 ret = CmdUtils::SetupDevice(devId, layerId, requestPacker_); 690 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 691 HDF_LOGE("%{public}s: SetupDevice failed", __func__)); 692 693 ret = CmdUtils::LayerColorPack(layerColor, requestPacker_); 694 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 695 HDF_LOGE("%{public}s: RectPack failed", __func__)); 696 697 ret = CmdUtils::EndSection(requestPacker_); 698 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 699 HDF_LOGE("%{public}s: EndSection failed", __func__)); 700 } while (0); 701 702 if (ret != HDF_SUCCESS) { 703 requestPacker_.RollBack(writePos); 704 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 705 return HDF_FAILURE; 706 } 707 return HDF_SUCCESS; 708 } 709 GetDisplayCompChange(uint32_t devId,std::vector<uint32_t> & layers,std::vector<int32_t> & types)710 int32_t GetDisplayCompChange(uint32_t devId, std::vector<uint32_t>& layers, std::vector<int32_t>& types) 711 { 712 layers = compChangeLayers_[devId]; 713 types = compChangeTypes_[devId]; 714 compChangeLayers_.erase(devId); 715 compChangeTypes_.erase(devId); 716 return HDF_SUCCESS; 717 } 718 protected: OnReplySetError(CommandDataUnpacker & replyUnpacker,std::unordered_map<int32_t,int32_t> & errMaps)719 int32_t OnReplySetError(CommandDataUnpacker& replyUnpacker, std::unordered_map<int32_t, int32_t> &errMaps) 720 { 721 uint32_t errCnt = 0; 722 bool retBool = replyUnpacker.ReadUint32(errCnt); 723 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 724 HDF_LOGE("%{public}s: read err cnt failed", __func__)); 725 726 int32_t errCmd = -1; 727 int32_t errCode = -1; 728 for (; errCnt > 0; errCnt--) { 729 retBool = replyUnpacker.ReadInt32(errCmd); 730 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 731 HDF_LOGE("%{public}s: read err cmd failed", __func__)); 732 retBool = replyUnpacker.ReadInt32(errCode); 733 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 734 HDF_LOGE("%{public}s: read err code failed", __func__)); 735 errMaps.emplace(errCmd, errCode); 736 } 737 738 return HDF_SUCCESS; 739 } 740 OnReplyPrepareDisplayLayers(CommandDataUnpacker & replyUnpacker,bool & needFlushFb)741 int32_t OnReplyPrepareDisplayLayers(CommandDataUnpacker& replyUnpacker, bool &needFlushFb) 742 { 743 uint32_t devId = 0; 744 int32_t retBool = replyUnpacker.ReadUint32(devId); 745 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read devId failed", __func__)); 746 747 retBool = replyUnpacker.ReadBool(needFlushFb); 748 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read needFlushFb failed", __func__)); 749 // unpack layers vector 750 uint32_t vectSize = 0; 751 retBool = replyUnpacker.ReadUint32(vectSize); 752 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read vect size failed", __func__)); 753 if (vectSize > CmdUtils::MAX_MEMORY) { 754 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize); 755 return HDF_FAILURE; 756 } 757 758 compChangeLayers_[devId].resize(vectSize); 759 for (uint32_t i = 0; i < vectSize; i++) { 760 DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(compChangeLayers_[devId][i]) == false, HDF_FAILURE, 761 HDF_LOGE("%{public}s: read layer vector failed", __func__)); 762 } 763 // unpack types vector 764 vectSize = 0; 765 retBool = replyUnpacker.ReadUint32(vectSize); 766 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read vect size failed", __func__)); 767 if (vectSize > CmdUtils::MAX_MEMORY) { 768 HDF_LOGE("%{public}s: types vectSize:%{public}u is too large", __func__, vectSize); 769 return HDF_FAILURE; 770 } 771 772 compChangeTypes_[devId].resize(vectSize); 773 for (uint32_t i = 0; i < vectSize; i++) { 774 DISPLAY_CHK_RETURN(replyUnpacker.ReadInt32(compChangeTypes_[devId][i]) == false, HDF_FAILURE, 775 HDF_LOGE("%{public}s: read composition type vector failed", __func__)); 776 } 777 778 return HDF_SUCCESS; 779 } 780 OnReplyCommit(CommandDataUnpacker & replyUnpacker,std::vector<HdifdInfo> & replyFds,int32_t & fenceFd)781 int32_t OnReplyCommit( 782 CommandDataUnpacker& replyUnpacker, std::vector<HdifdInfo>& replyFds, int32_t &fenceFd) 783 { 784 int32_t ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fenceFd); 785 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 786 HDF_LOGE("%{public}s: FileDescriptorUnpack failed", __func__)); 787 return HDF_SUCCESS; 788 } 789 ProcessUnpackCmd(CommandDataUnpacker & replyUnpacker,int32_t unpackCmd,std::vector<HdifdInfo> & replyFds,std::function<int32_t (void *)> fn)790 int32_t ProcessUnpackCmd(CommandDataUnpacker& replyUnpacker, int32_t unpackCmd, 791 std::vector<HdifdInfo>& replyFds, std::function<int32_t(void *)> fn) 792 { 793 int32_t ret = HDF_SUCCESS; 794 while (replyUnpacker.NextSection()) { 795 bool retBool = replyUnpacker.BeginSection(unpackCmd); 796 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 797 HDF_LOGE("%{public}s: BeginSection failed", __func__)); 798 799 bool needFlushFb; 800 int32_t fenceFd = -1; 801 std::unordered_map<int32_t, int32_t> errMaps; 802 switch (unpackCmd) { 803 case REPLY_CMD_PREPARE_DISPLAY_LAYERS: 804 ret = OnReplyPrepareDisplayLayers(replyUnpacker, needFlushFb); 805 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 806 HDF_LOGE("%{public}s: OnReplyPrepareDisplayLayers failed", __func__)); 807 808 ret = fn(&needFlushFb); 809 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 810 HDF_LOGE("%{public}s: ReadBool failed, unpackCmd=%{public}s", 811 __func__, CmdUtils::CommandToString(unpackCmd))); 812 break; 813 case REPLY_CMD_COMMIT: 814 ret = OnReplyCommit(replyUnpacker, replyFds, fenceFd); 815 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 816 HDF_LOGE("%{public}s: OnReplyCommit failed unpackCmd=%{public}s", 817 __func__, CmdUtils::CommandToString(unpackCmd))); 818 819 ret = fn(&fenceFd); 820 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 821 HDF_LOGE("%{public}s: return fence fd error, unpackCmd=%{public}s", 822 __func__, CmdUtils::CommandToString(unpackCmd))); 823 break; 824 case REPLY_CMD_SET_ERROR: 825 ret = OnReplySetError(replyUnpacker, errMaps); 826 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 827 HDF_LOGE("%{public}s: OnReplySetError failed", __func__)); 828 DISPLAY_CHK_RETURN(errMaps.size() > 0, HDF_FAILURE, 829 HDF_LOGE("error: server return errs, size=%{public}zu", errMaps.size())); 830 break; 831 default: 832 HDF_LOGE("Unpack command failure"); 833 return HDF_FAILURE; 834 } 835 } 836 return HDF_SUCCESS; 837 } 838 DoReplyResults(uint32_t replyEleCnt,std::vector<HdifdInfo> & replyFds,std::shared_ptr<char> replyData,std::function<int32_t (void *)> fn)839 int32_t DoReplyResults(uint32_t replyEleCnt, std::vector<HdifdInfo>& replyFds, std::shared_ptr<char> replyData, 840 std::function<int32_t(void *)> fn) 841 { 842 CommandDataUnpacker replyUnpacker; 843 replyUnpacker.Init(replyData.get(), replyEleCnt << CmdUtils::MOVE_SIZE); 844 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA 845 replyUnpacker.Dump(); 846 #endif // DEBUG_DISPLAY_CMD_RAW_DATA 847 int32_t unpackCmd = -1; 848 bool retBool = replyUnpacker.PackBegin(unpackCmd); 849 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 850 HDF_LOGE("%{public}s: PackBegin failed", __func__)); 851 DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_BEGIN, HDF_FAILURE, 852 HDF_LOGE("%{public}s: PackBegin cmd not match, unpackCmd=%{public}d", __func__, unpackCmd)); 853 if (ProcessUnpackCmd(replyUnpacker, unpackCmd, replyFds, fn) != HDF_SUCCESS) { 854 return HDF_FAILURE; 855 } 856 857 retBool = replyUnpacker.PackEnd(unpackCmd); 858 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 859 HDF_LOGE("%{public}s: PackEnd failed", __func__)); 860 861 DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_END, HDF_FAILURE, 862 HDF_LOGE("%{public}s: PackEnd failed, endCmd = %{public}s", 863 __func__, CmdUtils::CommandToString(unpackCmd))); 864 865 return HDF_SUCCESS; 866 } 867 DoRequest(uint32_t & replyEleCnt,std::vector<HdifdInfo> & outFds,std::shared_ptr<char> & replyData)868 int32_t DoRequest(uint32_t &replyEleCnt, std::vector<HdifdInfo> &outFds, std::shared_ptr<char> &replyData) 869 { 870 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA 871 requestPacker_.Dump(); 872 #endif // DEBUG_DISPLAY_CMD_RAW_DATA 873 uint32_t eleCnt = requestPacker_.ValidSize() >> CmdUtils::MOVE_SIZE; 874 int32_t ret = request_->Write( 875 reinterpret_cast<int32_t *>(requestPacker_.GetDataPtr()), eleCnt, CmdUtils::TRANSFER_WAIT_TIME); 876 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 877 HDF_LOGE("%{public}s: CmdRequest write failed", __func__)); 878 879 ret = hdi_->CmdRequest(eleCnt, requestHdiFds_, replyEleCnt, outFds); 880 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 881 HDF_LOGE("%{public}s: CmdRequest failed", __func__)); 882 883 if (replyEleCnt != 0) { 884 replyData.reset(new char[replyEleCnt << CmdUtils::MOVE_SIZE], std::default_delete<char[]>()); 885 DISPLAY_CHK_RETURN(replyData == nullptr, HDF_FAILURE, 886 HDF_LOGE("%{public}s: get replyData failed", __func__)); 887 ret = reply_->Read(reinterpret_cast<int32_t *>(replyData.get()), replyEleCnt, CmdUtils::TRANSFER_WAIT_TIME); 888 if (ret != HDF_SUCCESS) { 889 HDF_LOGE("reply read data failure, ret=%{public}d", ret); 890 } 891 } 892 893 return ret; 894 } 895 PeriodDataReset()896 int32_t PeriodDataReset() 897 { 898 for (uint32_t i = 0; i < requestHdiFds_.size(); ++i) { 899 int32_t fd = requestHdiFds_[i].hdiFd->Move(); 900 if (fd != -1) { 901 close(fd); 902 } 903 } 904 requestHdiFds_.clear(); 905 int32_t ret = CmdUtils::StartPack(CONTROL_CMD_REQUEST_BEGIN, requestPacker_); 906 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 907 HDF_LOGE("%{public}s: StartPack failed", __func__)); 908 909 return HDF_SUCCESS; 910 } 911 912 protected: 913 bool initFlag_; 914 sptr<CompHdi> hdi_; 915 std::shared_ptr<Transfer> request_; 916 std::shared_ptr<Transfer> reply_; 917 // Period data 918 CommandDataPacker requestPacker_; 919 std::vector<HdifdInfo> requestHdiFds_; 920 // Composition layers/types changed 921 std::unordered_map<uint32_t, std::vector<uint32_t>> compChangeLayers_; 922 std::unordered_map<uint32_t, std::vector<int32_t>> compChangeTypes_; 923 }; 924 using HdiDisplayCmdRequester = DisplayCmdRequester<SharedMemQueue<int32_t>, IDisplayComposer>; 925 } // namespace V1_0 926 } // namespace Composer 927 } // namespace Display 928 } // namespace HDI 929 } // namespace OHOS 930 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H 931