1 /* 2 * Copyright (c) 2024 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_2_DISPLAY_CMD_REQUESTER_H 17 #define OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H 18 19 #include "v1_1/display_command/display_cmd_requester.h" 20 #include "v1_2/display_command/display_cmd_utils.h" 21 #include "v1_2/display_composer_type.h" 22 #include "v1_2/idisplay_composer.h" 23 24 namespace OHOS { 25 namespace HDI { 26 namespace Display { 27 namespace Composer { 28 namespace V1_2 { 29 using namespace OHOS::HDI::Base; 30 31 template <typename Transfer, typename CompHdi> 32 class DisplayCmdRequester : public V1_1::DisplayCmdRequester<Transfer, CompHdi> { 33 public: DisplayCmdRequester(sptr<CompHdi> hdi)34 DisplayCmdRequester(sptr<CompHdi> hdi) : BaseType1_1(hdi), hdi_1_2_(hdi) {} 35 Create(sptr<CompHdi> hdi)36 static std::unique_ptr<DisplayCmdRequester> Create(sptr<CompHdi> hdi) 37 { 38 DISPLAY_CHK_RETURN(hdi == nullptr, nullptr, HDF_LOGE("%{public}s: hdi is nullptr", __func__)); 39 auto requester = std::make_unique<DisplayCmdRequester>(hdi); 40 DISPLAY_CHK_RETURN(requester == nullptr, nullptr, 41 HDF_LOGE("%{public}s: CmdRequester is nullptr", __func__)); 42 auto ret = requester->Init(CmdUtils::INIT_ELEMENT_COUNT); 43 if (ret != HDF_SUCCESS) { 44 HDF_LOGE("DisplayCmdRequester init failed"); 45 return nullptr; 46 } 47 return requester; 48 } 49 CommitAndGetReleaseFence(uint32_t devId,int32_t & fence,bool isSupportSkipValidate,int32_t & skipState,bool & needFlush,std::vector<uint32_t> & layers,std::vector<int32_t> & fences,bool isValidated)50 int32_t CommitAndGetReleaseFence(uint32_t devId, int32_t& fence, bool isSupportSkipValidate, int32_t& skipState, 51 bool& needFlush, std::vector<uint32_t>& layers, std::vector<int32_t>& fences, bool isValidated) 52 { 53 uint32_t replyEleCnt = 0; 54 std::vector<HdifdInfo> outFds; 55 std::shared_ptr<char> replyData; 56 57 int32_t ret = CmdUtils::StartSection(REQUEST_CMD_COMMIT_AND_GET_RELEASE_FENCE, requestPacker_); 58 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 59 60 ret = requestPacker_.WriteUint32(devId) ? HDF_SUCCESS : HDF_FAILURE; 61 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 62 63 ret = requestPacker_.WriteBool(isSupportSkipValidate) ? HDF_SUCCESS : HDF_FAILURE; 64 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 65 66 ret = requestPacker_.WriteBool(isValidated) ? HDF_SUCCESS : HDF_FAILURE; 67 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 68 69 ret = CmdUtils::EndSection(requestPacker_); 70 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 71 72 ret = CmdUtils::EndPack(requestPacker_); 73 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 74 75 ret = DoRequest(replyEleCnt, outFds, replyData); 76 DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT); 77 78 ret = DoReplyResults(replyEleCnt, outFds, replyData, [&](void *data) -> int32_t { 79 FenceData *fenceData = reinterpret_cast<struct FenceData *>(data); 80 if (fenceData == nullptr) { 81 fence = -1; 82 skipState = -1; 83 needFlush = false; 84 layers.clear(); 85 fences.clear(); 86 return HDF_FAILURE; 87 } 88 fence = fenceData->fence_; 89 skipState = fenceData->skipValidateState_; 90 needFlush = fenceData->needFlush_; 91 layers = fenceData->layers; 92 fences = fenceData->fences; 93 return HDF_SUCCESS; 94 }); 95 if (ret != HDF_SUCCESS) { 96 HDF_LOGE("DoReplyResults failure, ret=%{public}d", ret); 97 } 98 99 EXIT: 100 return PeriodDataReset() == HDF_SUCCESS ? ret : HDF_FAILURE; 101 } 102 OnReplySkipStateFailed(CommandDataUnpacker & replyUnpacker,bool & needFlush)103 int32_t OnReplySkipStateFailed(CommandDataUnpacker& replyUnpacker, bool &needFlush) 104 { 105 uint32_t devId = 0; 106 int32_t retBool = replyUnpacker.ReadUint32(devId); 107 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read devId failed", __func__)); 108 109 retBool = replyUnpacker.ReadBool(needFlush); 110 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, HDF_LOGE("%{public}s: read needFlush failed", __func__)); 111 112 // unpack layers vector 113 uint32_t vectSize = 0; 114 retBool = replyUnpacker.ReadUint32(vectSize); 115 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 116 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 117 118 compChangeLayers_[devId].resize(vectSize); 119 for (uint32_t i = 0; i < vectSize; i++) { 120 DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(compChangeLayers_[devId][i]) == false, HDF_FAILURE, 121 HDF_LOGE("%{public}s: HDI 1.2 read layer vector failed", __func__)); 122 } 123 // unpack types vector 124 vectSize = 0; 125 retBool = replyUnpacker.ReadUint32(vectSize); 126 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 127 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 128 129 compChangeTypes_[devId].resize(vectSize); 130 for (uint32_t i = 0; i < vectSize; i++) { 131 DISPLAY_CHK_RETURN(replyUnpacker.ReadInt32(compChangeTypes_[devId][i]) == false, HDF_FAILURE, 132 HDF_LOGE("%{public}s: HDI 1.2 read composition type vector failed", __func__)); 133 } 134 return HDF_SUCCESS; 135 } 136 OnReplyCommitAndGetReleaseFence(CommandDataUnpacker & replyUnpacker,std::vector<HdifdInfo> & replyFds,int32_t & fenceFd,int32_t & skipState,bool & needFlush,std::vector<uint32_t> & layers,std::vector<int32_t> & fences)137 int32_t OnReplyCommitAndGetReleaseFence(CommandDataUnpacker& replyUnpacker, 138 std::vector<HdifdInfo>& replyFds, int32_t& fenceFd, int32_t& skipState, 139 bool& needFlush, std::vector<uint32_t>& layers, std::vector<int32_t>& fences) 140 { 141 int32_t ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fenceFd); 142 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 143 HDF_LOGE("%{public}s: FileDescriptorUnpack failed", __func__)); 144 145 int32_t retBool = replyUnpacker.ReadInt32(skipState); 146 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 147 HDF_LOGE("%{public}s: read skipValidateState failed", __func__)); 148 149 if (skipState != HDF_SUCCESS) { 150 return OnReplySkipStateFailed(replyUnpacker, needFlush); 151 } else { 152 // unpack layers vector 153 uint32_t vectSize = 0; 154 DISPLAY_CHK_RETURN(true != replyUnpacker.ReadUint32(vectSize), HDF_FAILURE, 155 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 156 157 layers.resize(vectSize); 158 for (uint32_t i = 0; i < vectSize; i++) { 159 DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(layers[i]) == false, HDF_FAILURE, 160 HDF_LOGE("%{public}s: HDI 1.2 read layer vector failed", __func__)); 161 } 162 163 // unpack fences vector 164 vectSize = 0; 165 DISPLAY_CHK_RETURN(true != replyUnpacker.ReadUint32(vectSize), HDF_FAILURE, 166 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__)); 167 168 fences.resize(vectSize); 169 for (uint32_t i = 0; i < vectSize; i++) { 170 ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fences[i]); 171 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 172 HDF_LOGE("%{public}s: HDI 1.2 FileDescriptorUnpack failed", __func__)); 173 } 174 } 175 176 return HDF_SUCCESS; 177 } 178 ProcessUnpackCmd(CommandDataUnpacker & replyUnpacker,int32_t unpackCmd,std::vector<HdifdInfo> & replyFds,std::function<int32_t (void *)> fn)179 int32_t ProcessUnpackCmd(CommandDataUnpacker& replyUnpacker, int32_t unpackCmd, 180 std::vector<HdifdInfo>& replyFds, std::function<int32_t(void *)> fn) 181 { 182 int32_t ret = HDF_SUCCESS; 183 while (replyUnpacker.NextSection()) { 184 bool retBool = replyUnpacker.BeginSection(unpackCmd); 185 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 186 HDF_LOGE("%{public}s: BeginSection failed", __func__)); 187 188 FenceData fenceData; 189 190 std::unordered_map<int32_t, int32_t> errMaps; 191 switch (unpackCmd) { 192 case REPLY_CMD_COMMIT_AND_GET_RELEASE_FENCE: 193 ret = OnReplyCommitAndGetReleaseFence(replyUnpacker, replyFds, fenceData.fence_, 194 fenceData.skipValidateState_, fenceData.needFlush_, fenceData.layers, fenceData.fences); 195 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 196 HDF_LOGE("%{public}s: OnReplyCommit failed unpackCmd=%{public}s", 197 __func__, CmdUtils::CommandToString(unpackCmd))); 198 199 ret = fn(&fenceData); 200 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, 201 HDF_LOGE("%{public}s: return fence fd error, unpackCmd=%{public}s", 202 __func__, CmdUtils::CommandToString(unpackCmd))); 203 break; 204 default: 205 HDF_LOGE("Unpack command failure"); 206 return HDF_FAILURE; 207 } 208 } 209 return HDF_SUCCESS; 210 } 211 DoReplyResults(uint32_t replyEleCnt,std::vector<HdifdInfo> & replyFds,std::shared_ptr<char> replyData,std::function<int32_t (void *)> fn)212 int32_t DoReplyResults(uint32_t replyEleCnt, std::vector<HdifdInfo>& replyFds, std::shared_ptr<char> replyData, 213 std::function<int32_t(void *)> fn) 214 { 215 CommandDataUnpacker replyUnpacker; 216 replyUnpacker.Init(replyData.get(), replyEleCnt << CmdUtils::MOVE_SIZE); 217 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA 218 replyUnpacker.Dump(); 219 #endif // DEBUG_DISPLAY_CMD_RAW_DATA 220 int32_t unpackCmd = -1; 221 bool retBool = replyUnpacker.PackBegin(unpackCmd); 222 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 223 HDF_LOGE("%{public}s: PackBegin failed", __func__)); 224 DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_BEGIN, HDF_FAILURE, 225 HDF_LOGE("%{public}s: PackBegin cmd not match, unpackCmd=%{public}d", __func__, unpackCmd)); 226 if (ProcessUnpackCmd(replyUnpacker, unpackCmd, replyFds, fn) != HDF_SUCCESS) { 227 return HDF_FAILURE; 228 } 229 230 retBool = replyUnpacker.PackEnd(unpackCmd); 231 DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE, 232 HDF_LOGE("%{public}s: PackEnd failed", __func__)); 233 234 DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_END, HDF_FAILURE, 235 HDF_LOGE("%{public}s: PackEnd failed, endCmd = %{public}s", 236 __func__, CmdUtils::CommandToString(unpackCmd))); 237 238 return HDF_SUCCESS; 239 } 240 241 // LTPO新增接口 SetDisplayConstraint(uint32_t devId,uint64_t frameID,uint64_t ns,uint32_t type)242 int32_t SetDisplayConstraint(uint32_t devId, uint64_t frameID, uint64_t ns, uint32_t type) 243 { 244 int32_t ret = 0; 245 bool retBool = false; 246 int32_t writePos = requestPacker_.ValidSize(); 247 248 do { 249 ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CONSTRAINT, requestPacker_); 250 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 251 HDF_LOGE("%{public}s: StartSection failed", __func__)); 252 253 retBool = requestPacker_.WriteUint32(devId); 254 DISPLAY_CHK_BREAK(retBool == false, 255 HDF_LOGE("%{public}s: write devId failed", __func__)); 256 257 retBool = requestPacker_.WriteUint64(frameID); 258 DISPLAY_CHK_BREAK(retBool == false, 259 HDF_LOGE("%{public}s: write frameID failed", __func__)); 260 261 retBool = requestPacker_.WriteUint64(ns); 262 DISPLAY_CHK_BREAK(retBool == false, 263 HDF_LOGE("%{public}s: write ns failed", __func__)); 264 265 retBool = requestPacker_.WriteUint32(type); 266 DISPLAY_CHK_BREAK(retBool == false, 267 HDF_LOGE("%{public}s: write type failed", __func__)); 268 269 ret = CmdUtils::EndSection(requestPacker_); 270 DISPLAY_CHK_BREAK(ret != HDF_SUCCESS, 271 HDF_LOGE("%{public}s: EndSection failed", __func__)); 272 } while (0); 273 274 if (retBool == false || ret != HDF_SUCCESS) { 275 requestPacker_.RollBack(writePos); 276 HDF_LOGE("%{public}s: writePos_ rollback", __func__); 277 return HDF_FAILURE; 278 } 279 return HDF_SUCCESS; 280 } 281 282 protected: 283 sptr<CompHdi> hdi_1_2_; 284 private: 285 using BaseType1_1 = V1_1::DisplayCmdRequester<Transfer, CompHdi>; 286 using BaseType1_1::requestPacker_; 287 using BaseType1_1::DoRequest; 288 using BaseType1_1::PeriodDataReset; 289 using BaseType1_1::DoReplyResults; 290 291 // Composition layers/types changed 292 using BaseType1_1::compChangeLayers_; 293 using BaseType1_1::compChangeTypes_; 294 // CommitAndGetReleaseFence 295 struct FenceData { 296 int32_t fence_ = -1; 297 int32_t skipValidateState_ = -1; 298 bool needFlush_ = false; 299 std::vector<uint32_t> layers; 300 std::vector<int32_t> fences; 301 }; 302 }; 303 using HdiDisplayCmdRequester = V1_2::DisplayCmdRequester<SharedMemQueue<int32_t>, V1_2::IDisplayComposer>; 304 } // namespace V1_2 305 } // namespace Composer 306 } // namespace Display 307 } // namespace HDI 308 } // namespace OHOS 309 #endif // OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H 310