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