• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         if (vectSize > CmdUtils::MAX_MEMORY) {
119             HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize);
120             return HDF_FAILURE;
121         }
122         compChangeLayers_[devId].resize(vectSize);
123         for (uint32_t i = 0; i < vectSize; i++) {
124             DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(compChangeLayers_[devId][i]) == false, HDF_FAILURE,
125                 HDF_LOGE("%{public}s: HDI 1.2 read layer vector failed", __func__));
126         }
127         // unpack types vector
128         vectSize = 0;
129         retBool = replyUnpacker.ReadUint32(vectSize);
130         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
131             HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__));
132 
133         if (vectSize > CmdUtils::MAX_MEMORY) {
134             HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize);
135             return HDF_FAILURE;
136         }
137         compChangeTypes_[devId].resize(vectSize);
138         for (uint32_t i = 0; i < vectSize; i++) {
139             DISPLAY_CHK_RETURN(replyUnpacker.ReadInt32(compChangeTypes_[devId][i]) == false, HDF_FAILURE,
140                 HDF_LOGE("%{public}s: HDI 1.2 read composition type vector failed", __func__));
141         }
142         return HDF_SUCCESS;
143     }
144 
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)145     int32_t OnReplyCommitAndGetReleaseFence(CommandDataUnpacker& replyUnpacker,
146         std::vector<HdifdInfo>& replyFds, int32_t& fenceFd, int32_t& skipState,
147         bool& needFlush, std::vector<uint32_t>& layers, std::vector<int32_t>& fences)
148     {
149         int32_t ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fenceFd);
150         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
151             HDF_LOGE("%{public}s: FileDescriptorUnpack failed", __func__));
152 
153         int32_t retBool = replyUnpacker.ReadInt32(skipState);
154         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
155             HDF_LOGE("%{public}s: read skipValidateState failed", __func__));
156 
157         if (skipState != HDF_SUCCESS) {
158             return OnReplySkipStateFailed(replyUnpacker, needFlush);
159         } else {
160             // unpack layers vector
161             uint32_t vectSize = 0;
162             DISPLAY_CHK_RETURN(true != replyUnpacker.ReadUint32(vectSize), HDF_FAILURE,
163                 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__));
164 
165             if (vectSize > CmdUtils::MAX_MEMORY) {
166                 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize);
167                 return HDF_FAILURE;
168             }
169             layers.resize(vectSize);
170             for (uint32_t i = 0; i < vectSize; i++) {
171                 DISPLAY_CHK_RETURN(replyUnpacker.ReadUint32(layers[i]) == false, HDF_FAILURE,
172                     HDF_LOGE("%{public}s: HDI 1.2 read layer vector failed", __func__));
173             }
174 
175             // unpack fences vector
176             vectSize = 0;
177             DISPLAY_CHK_RETURN(true != replyUnpacker.ReadUint32(vectSize), HDF_FAILURE,
178                 HDF_LOGE("%{public}s: HDI 1.2 read vect size failed", __func__));
179 
180             if (vectSize > CmdUtils::MAX_MEMORY) {
181                 HDF_LOGE("%{public}s: layers vectSize:%{public}u is too large", __func__, vectSize);
182                 return HDF_FAILURE;
183             }
184             fences.resize(vectSize);
185             for (uint32_t i = 0; i < vectSize; i++) {
186                 ret = CmdUtils::FileDescriptorUnpack(replyUnpacker, replyFds, fences[i]);
187                 DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
188                     HDF_LOGE("%{public}s: HDI 1.2 FileDescriptorUnpack failed", __func__));
189             }
190         }
191 
192         return HDF_SUCCESS;
193     }
194 
ProcessUnpackCmd(CommandDataUnpacker & replyUnpacker,int32_t unpackCmd,std::vector<HdifdInfo> & replyFds,std::function<int32_t (void *)> fn)195     int32_t ProcessUnpackCmd(CommandDataUnpacker& replyUnpacker, int32_t unpackCmd,
196         std::vector<HdifdInfo>& replyFds, std::function<int32_t(void *)> fn)
197     {
198         int32_t ret = HDF_SUCCESS;
199         while (replyUnpacker.NextSection()) {
200             bool retBool = replyUnpacker.BeginSection(unpackCmd);
201             DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
202                 HDF_LOGE("%{public}s: BeginSection failed", __func__));
203 
204             FenceData fenceData;
205 
206             std::unordered_map<int32_t, int32_t> errMaps;
207             switch (unpackCmd) {
208                 case REPLY_CMD_COMMIT_AND_GET_RELEASE_FENCE:
209                     ret = OnReplyCommitAndGetReleaseFence(replyUnpacker, replyFds, fenceData.fence_,
210                         fenceData.skipValidateState_, fenceData.needFlush_, fenceData.layers, fenceData.fences);
211                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
212                         HDF_LOGE("%{public}s: OnReplyCommit failed unpackCmd=%{public}s",
213                         __func__, CmdUtils::CommandToString(unpackCmd)));
214 
215                     ret = fn(&fenceData);
216                     DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
217                         HDF_LOGE("%{public}s: return fence fd error, unpackCmd=%{public}s",
218                         __func__, CmdUtils::CommandToString(unpackCmd)));
219                     break;
220                 default:
221                     HDF_LOGE("Unpack command failure");
222                     return HDF_FAILURE;
223             }
224         }
225         return HDF_SUCCESS;
226     }
227 
DoReplyResults(uint32_t replyEleCnt,std::vector<HdifdInfo> & replyFds,std::shared_ptr<char> replyData,std::function<int32_t (void *)> fn)228     int32_t DoReplyResults(uint32_t replyEleCnt, std::vector<HdifdInfo>& replyFds, std::shared_ptr<char> replyData,
229         std::function<int32_t(void *)> fn)
230     {
231         CommandDataUnpacker replyUnpacker;
232         replyUnpacker.Init(replyData.get(), replyEleCnt << CmdUtils::MOVE_SIZE);
233 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
234         replyUnpacker.Dump();
235 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
236         int32_t unpackCmd = -1;
237         bool retBool = replyUnpacker.PackBegin(unpackCmd);
238         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
239             HDF_LOGE("%{public}s: PackBegin failed", __func__));
240         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_BEGIN, HDF_FAILURE,
241             HDF_LOGE("%{public}s: PackBegin cmd not match, unpackCmd=%{public}d", __func__, unpackCmd));
242         if (ProcessUnpackCmd(replyUnpacker, unpackCmd, replyFds, fn) != HDF_SUCCESS) {
243             return HDF_FAILURE;
244         }
245 
246         retBool = replyUnpacker.PackEnd(unpackCmd);
247         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
248             HDF_LOGE("%{public}s: PackEnd failed", __func__));
249 
250         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REPLY_END, HDF_FAILURE,
251             HDF_LOGE("%{public}s: PackEnd failed, endCmd = %{public}s",
252             __func__, CmdUtils::CommandToString(unpackCmd)));
253 
254         return HDF_SUCCESS;
255     }
256 
257     // LTPO新增接口
SetDisplayConstraint(uint32_t devId,uint64_t frameID,uint64_t ns,uint32_t type)258     int32_t SetDisplayConstraint(uint32_t devId, uint64_t frameID, uint64_t ns, uint32_t type)
259     {
260         int32_t ret = 0;
261         bool retBool = false;
262         size_t writePos = requestPacker_.ValidSize();
263 
264         do {
265             ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_CONSTRAINT, requestPacker_);
266             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
267                 HDF_LOGE("%{public}s: StartSection failed", __func__));
268 
269             retBool = requestPacker_.WriteUint32(devId);
270             DISPLAY_CHK_BREAK(retBool == false,
271                 HDF_LOGE("%{public}s: write devId failed", __func__));
272 
273             retBool = requestPacker_.WriteUint64(frameID);
274             DISPLAY_CHK_BREAK(retBool == false,
275                 HDF_LOGE("%{public}s: write frameID failed", __func__));
276 
277             retBool = requestPacker_.WriteUint64(ns);
278             DISPLAY_CHK_BREAK(retBool == false,
279                 HDF_LOGE("%{public}s: write ns failed", __func__));
280 
281             retBool = requestPacker_.WriteUint32(type);
282             DISPLAY_CHK_BREAK(retBool == false,
283                 HDF_LOGE("%{public}s: write type failed", __func__));
284 
285             ret = CmdUtils::EndSection(requestPacker_);
286             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
287                 HDF_LOGE("%{public}s: EndSection failed", __func__));
288         } while (0);
289 
290         if (retBool == false || ret != HDF_SUCCESS) {
291             requestPacker_.RollBack(writePos);
292             HDF_LOGE("%{public}s: writePos_ rollback", __func__);
293             return HDF_FAILURE;
294         }
295         return HDF_SUCCESS;
296     }
297 
SetLayerPerFrameParameterSmq(uint32_t devId,uint32_t layerId,const std::string & key,const std::vector<int8_t> & value)298     int32_t SetLayerPerFrameParameterSmq(uint32_t devId, uint32_t layerId, const std::string& key,
299         const std::vector<int8_t>& value)
300     {
301         int32_t ret = 0;
302         bool retBool = false;
303         size_t writePos = requestPacker_.ValidSize();
304 
305         do {
306             ret = CmdUtils::StartSection(REQUEST_CMD_SET_LAYER_PERFRAME_PARAM, requestPacker_);
307             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
308                 HDF_LOGE("%{public}s: StartSection failed", __func__));
309 
310             retBool = requestPacker_.WriteUint32(devId);
311             DISPLAY_CHK_BREAK(retBool == false,
312                 HDF_LOGE("%{public}s: write devId failed", __func__));
313 
314             retBool = requestPacker_.WriteUint32(layerId);
315             DISPLAY_CHK_BREAK(retBool == false,
316                 HDF_LOGE("%{public}s: write layerId failed", __func__));
317 
318             uint32_t vectStrSize = key.size();
319             retBool = requestPacker_.WriteUint32(vectStrSize);
320             if (vectStrSize > CmdUtils::MAX_MEMORY) {
321                 DISPLAY_CHK_BREAK(retBool == false,
322                     HDF_LOGE("%{public}s: write vectStr failed", __func__));
323             }
324             for (uint32_t i = 0; i < vectStrSize; i++) {
325                 retBool = requestPacker_.WriteInt32(static_cast<int32_t>(key[i]));
326                 DISPLAY_CHK_BREAK(retBool == false,
327                     HDF_LOGE("%{public}s: write vectStr failed", __func__));
328             }
329 
330             uint32_t vectSize = value.size();
331             retBool = requestPacker_.WriteUint32(vectSize);
332             if (vectSize > CmdUtils::MAX_MEMORY) {
333                 DISPLAY_CHK_BREAK(retBool == false,
334                     HDF_LOGE("%{public}s: write vect failed", __func__));
335             }
336             for (uint32_t i = 0; i < vectSize; i++) {
337                 retBool = requestPacker_.WriteUint8(static_cast<uint8_t>(value[i]));
338                 DISPLAY_CHK_BREAK(retBool == false,
339                     HDF_LOGE("%{public}s: write vect failed", __func__));
340             }
341 
342             ret = CmdUtils::EndSection(requestPacker_);
343             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
344                 HDF_LOGE("%{public}s: EndSection failed", __func__));
345         } while (0);
346 
347         if (retBool == false || ret != HDF_SUCCESS) {
348             requestPacker_.RollBack(writePos);
349             HDF_LOGE("SetLayerPerFrameParameterSmq writePos_ rollback %{public}s, %{public}d, %{public}d",
350                 key.c_str(), devId, layerId);
351 
352             return HDF_FAILURE;
353         }
354         return HDF_SUCCESS;
355     }
356 
SetDisplayPerFrameParameterSmq(uint32_t devId,const std::string & key,const std::vector<int8_t> & value)357     int32_t SetDisplayPerFrameParameterSmq(uint32_t devId, const std::string& key,
358         const std::vector<int8_t>& value)
359     {
360         int32_t ret = 0;
361         bool retBool = false;
362         size_t writePos = requestPacker_.ValidSize();
363 
364         do {
365             ret = CmdUtils::StartSection(REQUEST_CMD_SET_DISPLAY_PERFRAME_PARAM, requestPacker_);
366             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
367                 HDF_LOGE("%{public}s: StartSection failed", __func__));
368 
369             retBool = requestPacker_.WriteUint32(devId);
370             DISPLAY_CHK_BREAK(retBool == false,
371                 HDF_LOGE("%{public}s: write devId failed", __func__));
372 
373             uint32_t vectStrSize = key.size();
374             retBool = requestPacker_.WriteUint32(vectStrSize);
375             if (vectStrSize > CmdUtils::MAX_MEMORY) {
376                 DISPLAY_CHK_BREAK(retBool == false,
377                     HDF_LOGE("%{public}s: write vectStr failed", __func__));
378             }
379             for (uint32_t i = 0; i < vectStrSize; i++) {
380                 retBool = requestPacker_.WriteInt32(static_cast<int32_t>(key[i]));
381                 DISPLAY_CHK_BREAK(retBool == false,
382                     HDF_LOGE("%{public}s: write vectStr failed", __func__));
383             }
384 
385             uint32_t vectSize = value.size();
386             retBool = requestPacker_.WriteUint32(vectSize);
387             if (vectSize > CmdUtils::MAX_MEMORY) {
388                 DISPLAY_CHK_BREAK(retBool == false,
389                     HDF_LOGE("%{public}s: write vect failed", __func__));
390             }
391             for (uint32_t i = 0; i < vectSize; i++) {
392                 retBool = requestPacker_.WriteUint8(static_cast<uint8_t>(value[i]));
393                 DISPLAY_CHK_BREAK(retBool == false,
394                     HDF_LOGE("%{public}s: write vect failed", __func__));
395             }
396 
397             ret = CmdUtils::EndSection(requestPacker_);
398             DISPLAY_CHK_BREAK(ret != HDF_SUCCESS,
399                 HDF_LOGE("%{public}s: EndSection failed", __func__));
400         } while (0);
401 
402         if (retBool == false || ret != HDF_SUCCESS) {
403             requestPacker_.RollBack(writePos);
404             HDF_LOGE("SetDisplayPerFrameParameterSmq writePos_ rollback %{public}s, %{public}d",
405                 key.c_str(), devId);
406 
407             return HDF_FAILURE;
408         }
409         return HDF_SUCCESS;
410     }
411 
412 protected:
413     sptr<CompHdi> hdi_1_2_;
414 private:
415     using BaseType1_1 = V1_1::DisplayCmdRequester<Transfer, CompHdi>;
416     using BaseType1_1::requestPacker_;
417     using BaseType1_1::DoRequest;
418     using BaseType1_1::PeriodDataReset;
419     using BaseType1_1::DoReplyResults;
420 
421     // Composition layers/types changed
422     using BaseType1_1::compChangeLayers_;
423     using BaseType1_1::compChangeTypes_;
424     // CommitAndGetReleaseFence
425     struct FenceData {
426         int32_t fence_ = -1;
427         int32_t skipValidateState_ = -1;
428         bool needFlush_ = false;
429         std::vector<uint32_t> layers;
430         std::vector<int32_t> fences;
431     };
432 };
433 using HdiDisplayCmdRequester = V1_2::DisplayCmdRequester<SharedMemQueue<int32_t>, V1_2::IDisplayComposer>;
434 } // namespace V1_2
435 } // namespace Composer
436 } // namespace Display
437 } // namespace HDI
438 } // namespace OHOS
439 #endif // OHOS_HDI_DISPLAY_V1_2_DISPLAY_CMD_REQUESTER_H
440