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