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