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