• 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 <fstream>
20 #include <poll.h>
21 #include <securec.h>
22 #include <sstream>
23 #include <string>
24 #include <sys/time.h>
25 #include <unistd.h>
26 #include <unordered_map>
27 #include <queue>
28 
29 #include "base/hdi_smq.h"
30 #include "buffer_handle_utils.h"
31 #include "command_pack/command_data_packer.h"
32 #include "command_pack/command_data_unpacker.h"
33 #include "display_cmd_utils.h"
34 #include "hdf_base.h"
35 #include "hdf_trace.h"
36 #include "hdifd_parcelable.h"
37 #include "hilog/log.h"
38 #include "idisplay_composer_vdi.h"
39 #include "parameter.h"
40 #include "v1_0/display_composer_type.h"
41 #include "v1_0/mapper_stub.h"
42 #include "common/include/display_vdi_adapter_interface.h"
43 
44 #define DISPLAY_TRACE HdfTrace trace(__func__, "HDI:DISP:")
45 
46 namespace OHOS {
47 namespace HDI {
48 namespace Display {
49 namespace Composer {
50 namespace V1_0 {
51 using namespace OHOS::HDI::Base;
52 using namespace OHOS::HDI::Display::Composer::V1_0;
53 using namespace OHOS::HDI::Display::Buffer::V1_0;
54 using HdifdSet = std::vector<std::shared_ptr<HdifdParcelable>>;
55 
56 static constexpr uint32_t TIME_BUFFER_MAX_LEN = 15;
57 static constexpr uint32_t BUFFER_QUEUE_MAX_SIZE = 6;
58 static constexpr unsigned int REDUCE_COUNT = 50;
59 static constexpr int32_t ERROR_FENCE_COUNT = 500;
60 static sptr<IMapper> g_bufferServiceImpl = nullptr;
61 
62 static constexpr uint32_t COMMIT_PRINT_INTERVAL = 1200;
63 
64 template <typename Transfer, typename VdiImpl>
65 class DisplayCmdResponser {
66 public:
Create(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)67     static std::unique_ptr<DisplayCmdResponser> Create(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
68     {
69         DISPLAY_CHK_RETURN(impl == nullptr, nullptr,
70             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
71         DISPLAY_CHK_RETURN(cacheMgr == nullptr, nullptr,
72             HDF_LOGE("%{public}s: error, VdiImpl is nullptr", __func__));
73         return std::make_unique<DisplayCmdResponser>(impl, cacheMgr);
74     }
75 
DisplayCmdResponser(VdiImpl * impl,std::shared_ptr<DeviceCacheManager> cacheMgr)76     DisplayCmdResponser(VdiImpl* impl, std::shared_ptr<DeviceCacheManager> cacheMgr)
77         : impl_(impl),
78         cacheMgr_(cacheMgr),
79         request_(nullptr),
80         isReplyUpdated_(false),
81         reply_(nullptr),
82         replyCommandCnt_(0) {}
83 
~DisplayCmdResponser()84     virtual ~DisplayCmdResponser()
85     {
86         while (delayFreeQueue_.size() > 0) {
87             BufferHandle *temp = delayFreeQueue_.front();
88             delayFreeQueue_.pop();
89             FreeBufferHandle(temp);
90             temp = nullptr;
91         }
92     }
93 
InitCmdRequest(const std::shared_ptr<Transfer> & request)94     int32_t InitCmdRequest(const std::shared_ptr<Transfer>& request)
95     {
96         DISPLAY_CHK_RETURN(request == nullptr, HDF_FAILURE,
97             HDF_LOGE("%{public}s: error, request is nullptr", __func__));
98         std::lock_guard<std::mutex> lock(requestMutex_);
99         if (request_ != nullptr) {
100             request_.reset();
101         }
102         request_ = request;
103 
104         return HDF_SUCCESS;
105     }
106 
GetCmdReply(std::shared_ptr<Transfer> & reply)107     int32_t GetCmdReply(std::shared_ptr<Transfer>& reply)
108     {
109         std::lock_guard<std::mutex> lock(replyMutex_);
110         int32_t ret = HDF_SUCCESS;
111         if (isReplyUpdated_ == false) {
112             ret = InitReply(CmdUtils::INIT_ELEMENT_COUNT);
113         }
114         if (ret == HDF_SUCCESS) {
115             if (reply_ != nullptr) {
116                 reply = reply_;
117             } else {
118                 ret = HDF_FAILURE;
119             }
120         }
121         isReplyUpdated_ = false;
122         if (ret != HDF_SUCCESS) {
123             HDF_LOGE("error: GetCmdReply failure");
124         }
125 
126         return ret;
127     }
128 
ProcessRequestCmd(CommandDataUnpacker & unpacker,int32_t cmd,const std::vector<HdifdInfo> & inFds,std::vector<HdifdInfo> & outFds)129     int32_t ProcessRequestCmd(CommandDataUnpacker& unpacker, int32_t cmd,
130         const std::vector<HdifdInfo>& inFds, std::vector<HdifdInfo>& outFds)
131     {
132         int32_t ret = HDF_SUCCESS;
133         switch (cmd) {
134             case REQUEST_CMD_PREPARE_DISPLAY_LAYERS: OnPrepareDisplayLayers(unpacker); break;
135             case REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER: OnSetDisplayClientBuffer(unpacker, inFds); break;
136             case REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE: OnSetDisplayClientDamage(unpacker); break;
137             case REQUEST_CMD_COMMIT: OnCommit(unpacker, outFds); break;
138             case REQUEST_CMD_SET_LAYER_ALPHA: OnSetLayerAlpha(unpacker); break;
139             case REQUEST_CMD_SET_LAYER_REGION: OnSetLayerRegion(unpacker); break;
140             case REQUEST_CMD_SET_LAYER_CROP: OnSetLayerCrop(unpacker); break;
141             case REQUEST_CMD_SET_LAYER_ZORDER: OnSetLayerZorder(unpacker); break;
142             case REQUEST_CMD_SET_LAYER_PREMULTI: OnSetLayerPreMulti(unpacker); break;
143             case REQUEST_CMD_SET_LAYER_TRANSFORM_MODE: OnSetLayerTransformMode(unpacker); break;
144             case REQUEST_CMD_SET_LAYER_DIRTY_REGION: OnSetLayerDirtyRegion(unpacker); break;
145             case REQUEST_CMD_SET_LAYER_VISIBLE_REGION: OnSetLayerVisibleRegion(unpacker); break;
146             case REQUEST_CMD_SET_LAYER_BUFFER: OnSetLayerBuffer(unpacker, inFds); break;
147             case REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE: OnSetLayerCompositionType(unpacker); break;
148             case REQUEST_CMD_SET_LAYER_BLEND_TYPE: OnSetLayerBlendType(unpacker); break;
149             case REQUEST_CMD_SET_LAYER_MASK_INFO: OnSetLayerMaskInfo(unpacker); break;
150             case CONTROL_CMD_REQUEST_END: ret = OnRequestEnd(unpacker); break;
151             case REQUEST_CMD_SET_LAYER_COLOR: OnSetLayerColor(unpacker); break;
152             default:
153                 HDF_LOGE("%{public}s: not support this cmd, unpacked cmd = %{public}d", __func__, cmd);
154                 ret = HDF_FAILURE;
155                 break;
156         }
157         return ret;
158     }
159 
CmdRequest(uint32_t inEleCnt,const std::vector<HdifdInfo> & inFds,uint32_t & outEleCnt,std::vector<HdifdInfo> & outFds)160     int32_t CmdRequest(uint32_t inEleCnt, const std::vector<HdifdInfo>& inFds, uint32_t& outEleCnt,
161         std::vector<HdifdInfo>& outFds)
162     {
163         if (inEleCnt > CmdUtils::MAX_ELE_COUNT) {
164             HDF_LOGE("%{public}s: inEleCnt:%{public}u is too large", __func__, inEleCnt);
165             return HDF_FAILURE;
166         }
167         std::shared_ptr<char> requestData(new char[inEleCnt * CmdUtils::ELEMENT_SIZE], std::default_delete<char[]>());
168         int32_t ret = HDF_SUCCESS;
169         {
170             std::lock_guard<std::mutex> lock(requestMutex_);
171             ret = request_->Read(reinterpret_cast<int32_t *>(requestData.get()), inEleCnt,
172                 CmdUtils::TRANSFER_WAIT_TIME);
173         }
174         CommandDataUnpacker unpacker;
175         unpacker.Init(requestData.get(), inEleCnt << CmdUtils::MOVE_SIZE);
176 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
177         unpacker.Dump();
178 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
179 
180         int32_t unpackCmd = -1;
181         bool retBool = unpacker.PackBegin(unpackCmd);
182         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
183             HDF_LOGE("%{public}s: error: Check RequestBegin failed", __func__));
184         DISPLAY_CHK_RETURN(unpackCmd != CONTROL_CMD_REQUEST_BEGIN, HDF_FAILURE,
185             HDF_LOGI("error: unpacker PackBegin cmd not match, cmd(%{public}d)=%{public}s.", unpackCmd,
186             CmdUtils::CommandToString(unpackCmd)));
187 
188         while (ret == HDF_SUCCESS && unpacker.NextSection()) {
189             if (!unpacker.BeginSection(unpackCmd)) {
190                 HDF_LOGE("error: PackSection failed, unpackCmd=%{public}s.", CmdUtils::CommandToString(unpackCmd));
191                 return HDF_FAILURE;
192             }
193             ret = ProcessRequestCmd(unpacker, unpackCmd, inFds, outFds);
194         }
195 
196         DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret, HDF_LOGE("%{public}s:ProcessRequestCmd failed", __func__));
197         /* pack request end commands */
198         replyPacker_.PackEnd(CONTROL_CMD_REPLY_END);
199 
200 #ifdef DEBUG_DISPLAY_CMD_RAW_DATA
201         /* just for debug */
202         replyPacker_.Dump();
203         HDF_LOGI("CmdReply command cnt=%{public}d", replyCommandCnt_);
204 #endif // DEBUG_DISPLAY_CMD_RAW_DATA
205 
206         /*  Write reply pack */
207         outEleCnt = replyPacker_.ValidSize() >> CmdUtils::MOVE_SIZE;
208         {
209             std::lock_guard<std::mutex> lock(replyMutex_);
210             ret = reply_->Write(reinterpret_cast<int32_t *>(replyPacker_.GetDataPtr()), outEleCnt,
211                 CmdUtils::TRANSFER_WAIT_TIME);
212         }
213         if (ret != HDF_SUCCESS) {
214             HDF_LOGE("Reply write failure, ret=%{public}d", ret);
215             outEleCnt = 0;
216         }
217         int32_t ec = PeriodDataReset();
218         return (ret == HDF_SUCCESS ? ec : ret);
219     }
220 
221 protected:
InitReply(uint32_t size)222     int32_t InitReply(uint32_t size)
223     {
224         if (size > CmdUtils::MAX_MEMORY) {
225             HDF_LOGE("%{public}s: size:%{public}u is too large", __func__, size);
226             return HDF_FAILURE;
227         }
228         reply_ = std::make_shared<Transfer>(size, SmqType::SYNCED_SMQ);
229         DISPLAY_CHK_RETURN(reply_ == nullptr, HDF_FAILURE,
230             HDF_LOGE("%{public}s: reply_ construct failed", __func__));
231 
232         bool retBool = replyPacker_.Init(reply_->GetSize() << CmdUtils::MOVE_SIZE);
233         DISPLAY_CHK_RETURN(retBool == false, HDF_FAILURE,
234             HDF_LOGE("%{public}s: replyPacker_ init failed", __func__));
235 
236         return CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_);
237     }
238 
OnRequestEnd(CommandDataUnpacker & unpacker)239     int32_t OnRequestEnd(CommandDataUnpacker& unpacker)
240     {
241         DISPLAY_TRACE;
242 
243         size_t errCnt = errMaps_.size();
244         if (errCnt >= 0) {
245             int32_t ret = CmdUtils::StartSection(REPLY_CMD_SET_ERROR, replyPacker_);
246             DISPLAY_CHK_RETURN(ret != HDF_SUCCESS, ret,
247                 HDF_LOGE("%{public}s: StartSection failed", __func__));
248 
249             bool result = replyPacker_.WriteUint32(errCnt);
250             DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
251                 HDF_LOGE("%{public}s: write errCnt failed", __func__));
252             for (auto it = errMaps_.begin(); it != errMaps_.end(); ++it) {
253                 result = replyPacker_.WriteInt32(it->first);
254                 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
255                     HDF_LOGE("%{public}s: write err-cmd failed, cmdId:%{public}s",
256                     __func__, CmdUtils::CommandToString(it->first)));
257 
258                 result = replyPacker_.WriteInt32(it->second);
259                 DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
260                     HDF_LOGE("%{public}s: write errNo failed, errNo:%{public}d", __func__, it->second));
261             }
262             result = CmdUtils::EndSection(replyPacker_);
263             DISPLAY_CHK_RETURN(result == false, HDF_FAILURE,
264                 HDF_LOGE("%{public}s: write replyPacker_ EndSection failed", __func__));
265             replyCommandCnt_++;
266         }
267         return HDF_SUCCESS;
268     }
269 
OnPrepareDisplayLayers(CommandDataUnpacker & unpacker)270     void OnPrepareDisplayLayers(CommandDataUnpacker& unpacker)
271     {
272         DISPLAY_TRACE;
273 
274         uint32_t devId = 0;
275         bool needFlush = false;
276         uint32_t vectSize = 0;
277         std::vector<uint32_t> layers;
278         std::vector<int32_t> types;
279 
280         int32_t ret = unpacker.ReadUint32(devId) ? HDF_SUCCESS : HDF_FAILURE;
281         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
282         {
283             HdfTrace traceVdi("PrepareDisplayLayers", "HDI:DISP:HARDWARE");
284             ret = impl_->PrepareDisplayLayers(devId, needFlush);
285         }
286 
287         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
288         {
289             HdfTrace traceVdi("GetDisplayCompChange", "HDI:DISP:HARDWARE");
290             ret = impl_->GetDisplayCompChange(devId, layers, types);
291         }
292 
293         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
294 
295         ret = CmdUtils::StartSection(REPLY_CMD_PREPARE_DISPLAY_LAYERS, replyPacker_);
296         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
297 
298         DISPLAY_CHECK(replyPacker_.WriteUint32(devId) == false, goto EXIT);
299 
300         DISPLAY_CHECK(replyPacker_.WriteBool(needFlush) == false, goto EXIT);
301         // Write layers vector
302         vectSize = static_cast<uint32_t>(layers.size());
303         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false, goto EXIT);
304 
305         for (uint32_t i = 0; i < vectSize; i++) {
306             DISPLAY_CHECK(replyPacker_.WriteUint32(layers[i]) == false, goto EXIT);
307         }
308         // Write composer types vector
309         vectSize = static_cast<uint32_t>(types.size());
310         DISPLAY_CHECK(replyPacker_.WriteUint32(vectSize) == false, goto EXIT);
311 
312         for (uint32_t i = 0; i < vectSize; i++) {
313             DISPLAY_CHECK(replyPacker_.WriteUint32(types[i]) == false, goto EXIT);
314         }
315         // End this cmd section
316         ret = CmdUtils::EndSection(replyPacker_);
317         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
318         replyCommandCnt_++;
319 EXIT:
320         if (ret != HDF_SUCCESS) {
321             errMaps_.emplace(REQUEST_CMD_PREPARE_DISPLAY_LAYERS, ret);
322         }
323         return;
324     }
325 
326     typedef struct ClientBufferData {
327         uint32_t devId;
328         uint32_t seqNo;
329         int32_t fence;
330         BufferHandle *buffer;
331         bool isValidBuffer;
332     } ClientBufferData;
333 
UnpackDisplayClientBufferInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds,ClientBufferData & data)334     int32_t UnpackDisplayClientBufferInfo(CommandDataUnpacker& unpacker,
335         const std::vector<HdifdInfo>& inFds, ClientBufferData& data)
336     {
337         if (!unpacker.ReadUint32(data.devId)) {
338             return HDF_FAILURE;
339         }
340 
341         if (CmdUtils::BufferHandleUnpack(unpacker, inFds, data.buffer) != HDF_SUCCESS) {
342             data.isValidBuffer = false;
343             HDF_LOGE("%{public}s, read buffer handle error", __func__);
344             return HDF_FAILURE;
345         }
346         data.isValidBuffer = true;
347 
348         if (!unpacker.ReadUint32(data.seqNo)) {
349             HDF_LOGE("%{public}s, read seqNo error", __func__);
350             return HDF_FAILURE;
351         }
352 
353         if (CmdUtils::FileDescriptorUnpack(unpacker, inFds, data.fence) != HDF_SUCCESS) {
354             HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__);
355             return HDF_FAILURE;
356         }
357 
358         return HDF_SUCCESS;
359     }
360 
SetDisplayClientBuffer(ClientBufferData & data,bool & needFreeBuffer,bool & needMoveFd,int fd)361     int32_t SetDisplayClientBuffer(ClientBufferData& data, bool &needFreeBuffer, bool &needMoveFd, int fd)
362     {
363         if (cacheMgr_ == nullptr) {
364             HDF_LOGE("%{public}s, get cache manager error", __func__);
365             return HDF_FAILURE;
366         }
367         std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex());
368 
369         DeviceCache* devCache = cacheMgr_->DeviceCacheInstance(data.devId);
370         if (devCache == nullptr) {
371             HDF_LOGE("%{public}s, get device cache error", __func__);
372             return HDF_FAILURE;
373         }
374 
375         int32_t ret = devCache->SetDisplayClientBuffer(data.buffer, data.seqNo, needFreeBuffer,
376             [&data, &needMoveFd, &fd, this](const BufferHandle& handle)->int32_t {
377 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
378             DumpLayerBuffer(data.devId, data.seqNo, data.fence, handle, "client_");
379 #endif
380             if (data.fence > ERROR_FENCE_COUNT) {
381                 HDF_LOGW("SetDisplayClientBuffer:%{public}s data.devId:%{public}d, data.buffer->fd:%{public}d, "
382                          "data.seqNo:%{public}d, fd:%{public}d",
383                     data.buffer == nullptr ? "data.buffer is nullptr!" : "",
384                     data.devId,
385                     data.buffer == nullptr ? -1 : data.buffer->fd,
386                     data.seqNo,
387                     fd);
388             }
389             needMoveFd = true;
390             HITRACE_METER_FMT(HITRACE_TAG_HDF,
391                 "SetDisplayClientBuffer:%s data.devId:%d, data.buffer->fd:%d, data.seqNo:%d, fd:%d",
392                 data.buffer == nullptr ? "data.buffer is nullptr!" : "",
393                 data.devId,
394                 data.buffer == nullptr ? -1 : data.buffer->fd,
395                 data.seqNo,
396                 fd);
397             int rc = impl_->SetDisplayClientBuffer(data.devId, handle, fd);
398             DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail"));
399             return HDF_SUCCESS;
400         });
401         return ret;
402     }
403 
OnSetDisplayClientBuffer(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds)404     void OnSetDisplayClientBuffer(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds)
405     {
406         DISPLAY_TRACE;
407 
408         ClientBufferData data = {0};
409         data.fence = -1;
410         bool needFreeBuffer = false;
411         bool needMoveFd = false;
412         int32_t ret = UnpackDisplayClientBufferInfo(unpacker, inFds, data);
413         HdifdParcelable fdParcel(data.fence);
414         if (ret == HDF_SUCCESS) {
415             ret = SetDisplayClientBuffer(data, needFreeBuffer, needMoveFd, fdParcel.GetFd());
416         }
417 #ifndef DISPLAY_COMMUNITY
418         // fix fd leak
419         if (data.buffer != nullptr && needFreeBuffer) {
420             FreeBufferWithDelay(data.buffer);
421             data.buffer = nullptr;
422             data.isValidBuffer = false;
423         }
424         if (needMoveFd) {
425             fdParcel.Move();
426         }
427 #endif // DISPLAY_COMMUNITY
428         if (ret != HDF_SUCCESS) {
429             HDF_LOGE("%{public}s, SetDisplayClientBuffer error", __func__);
430             if (data.isValidBuffer && data.buffer != nullptr) {
431                 FreeBufferHandle(data.buffer);
432                 data.buffer = nullptr;
433             }
434             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret);
435         }
436     }
437 
OnSetDisplayClientDamage(CommandDataUnpacker & unpacker)438     void OnSetDisplayClientDamage(CommandDataUnpacker& unpacker)
439     {
440         DISPLAY_TRACE;
441 
442         uint32_t devId = 0;
443         uint32_t vectSize = 0;
444         bool retBool = true;
445         DISPLAY_CHK_CONDITION(retBool, true, unpacker.ReadUint32(devId),
446             HDF_LOGE("%{public}s, read devId error", __func__));
447 
448         DISPLAY_CHK_CONDITION(retBool, true, unpacker.ReadUint32(vectSize),
449             HDF_LOGE("%{public}s, read vectSize error", __func__));
450 
451         int32_t ret = (retBool ? HDF_SUCCESS : HDF_FAILURE);
452         std::vector<IRect> rects(vectSize);
453         if (ret == HDF_SUCCESS) {
454             for (uint32_t i = 0; i < vectSize; i++) {
455                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
456                     HDF_LOGE("%{public}s, read vect error at i = %{public}d", __func__, i));
457                 if (ret != HDF_SUCCESS) {
458                     break;
459                 }
460             }
461         }
462         if (ret == HDF_SUCCESS) {
463             HdfTrace traceVdi("SetDisplayClientDamage", "HDI:DISP:HARDWARE");
464             impl_->SetDisplayClientDamage(devId, rects);
465         } else {
466             HDF_LOGE("%{public}s, SetDisplayClientDamage error", __func__);
467             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE, ret);
468         }
469         return;
470     }
471 
OnCommit(CommandDataUnpacker & unpacker,std::vector<HdifdInfo> & outFds)472     void OnCommit(CommandDataUnpacker& unpacker, std::vector<HdifdInfo>& outFds)
473     {
474         DISPLAY_TRACE;
475 
476         uint32_t devId = 0;
477         int32_t fence = -1;
478 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
479         const std::string SWITCH_ON = "on";
480         const uint32_t DUMP_CACHE_SWITCH_LEN = 4;
481         char dumpSwitch[DUMP_CACHE_SWITCH_LEN] = {0};
482         GetParameter("hdi.composer.dumpcache", "off", dumpSwitch, DUMP_CACHE_SWITCH_LEN);
483 
484         if (SWITCH_ON.compare(dumpSwitch) == 0) {
485             cacheMgr_->Dump();
486         }
487 #endif
488         int32_t ret = HDF_SUCCESS;
489         if (!unpacker.ReadUint32(devId)) {
490             HDF_LOGE("%{public}s, read devId error", __func__);
491             ret = HDF_FAILURE;
492             goto REPLY;
493         }
494 
495         {
496             HdfTrace traceVdi("Commit", "HDI:DISP:HARDWARE");
497             ret = impl_->Commit(devId, fence);
498         }
499         static unsigned int count = 0;
500         if (ret == HDF_SUCCESS) {
501             count = 0;
502         } else {
503             if (++count > REDUCE_COUNT) {
504                 HDF_LOGE("%{public}s, commit failed with ret = %{public}d", __func__, ret);
505                 count = 0;
506             }
507         }
508 
509 REPLY:
510         HdifdParcelable fdParcel(fence);
511         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::StartSection(REPLY_CMD_COMMIT, replyPacker_),
512             HDF_LOGE("%{public}s, StartSection error", __func__));
513 
514         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::FileDescriptorPack(fdParcel.GetFd(), replyPacker_, outFds),
515             HDF_LOGE("%{public}s, FileDescriptorPack error", __func__));
516 
517         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::EndSection(replyPacker_),
518             HDF_LOGE("%{public}s, EndSection error", __func__));
519 
520         replyCommandCnt_++;
521 
522 #ifndef DISPLAY_COMMUNITY
523         fdParcel.Move();
524 #endif // DISPLAY_COMMUNITY
525 
526         if (ret != HDF_SUCCESS) {
527             errMaps_.emplace(REQUEST_CMD_COMMIT, ret);
528         }
529 
530         return;
531     }
532 
OnSetLayerAlpha(CommandDataUnpacker & unpacker)533     void OnSetLayerAlpha(CommandDataUnpacker& unpacker)
534     {
535         DISPLAY_TRACE;
536 
537         uint32_t devId = 0;
538         uint32_t layerId = 0;
539         LayerAlpha alpha = {0};
540         bool retBool = true;
541 
542         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
543         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
544 
545         retBool = unpacker.ReadBool(alpha.enGlobalAlpha);
546         DISPLAY_CHECK(retBool == false, goto EXIT);
547 
548         retBool = unpacker.ReadBool(alpha.enPixelAlpha);
549         DISPLAY_CHECK(retBool == false, goto EXIT);
550 
551         retBool = unpacker.ReadUint8(alpha.alpha0);
552         DISPLAY_CHECK(retBool == false, goto EXIT);
553 
554         retBool = unpacker.ReadUint8(alpha.alpha1);
555         DISPLAY_CHECK(retBool == false, goto EXIT);
556 
557         retBool = unpacker.ReadUint8(alpha.gAlpha);
558         DISPLAY_CHECK(retBool == false, goto EXIT);
559 
560         {
561             HdfTrace traceVdi("SetLayerAlpha", "HDI:DISP:HARDWARE");
562             ret = impl_->SetLayerAlpha(devId, layerId, alpha);
563         }
564         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
565 
566 EXIT:
567         if (ret != HDF_SUCCESS || retBool == false) {
568             errMaps_.emplace(REQUEST_CMD_SET_LAYER_ALPHA, ret);
569         }
570         return;
571     }
572 
OnSetLayerRegion(CommandDataUnpacker & unpacker)573     void OnSetLayerRegion(CommandDataUnpacker& unpacker)
574     {
575         DISPLAY_TRACE;
576 
577         uint32_t devId = 0;
578         uint32_t layerId = 0;
579         IRect rect = {0};
580 
581         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
582         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
583 
584         ret = CmdUtils::RectUnpack(unpacker, rect);
585         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
586 
587         {
588             HdfTrace traceVdi("SetLayerRegion", "HDI:DISP:HARDWARE");
589             ret = impl_->SetLayerRegion(devId, layerId, rect);
590         }
591         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
592 EXIT:
593         if (ret != HDF_SUCCESS) {
594             errMaps_.emplace(REQUEST_CMD_SET_LAYER_REGION, ret);
595         }
596         return;
597     }
598 
OnSetLayerCrop(CommandDataUnpacker & unpacker)599     void OnSetLayerCrop(CommandDataUnpacker& unpacker)
600     {
601         DISPLAY_TRACE;
602 
603         uint32_t devId = 0;
604         uint32_t layerId = 0;
605         IRect rect = {0};
606 
607         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
608         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
609 
610         ret = CmdUtils::RectUnpack(unpacker, rect);
611         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
612 
613         {
614             HdfTrace traceVdi("SetLayerCrop", "HDI:DISP:HARDWARE");
615             ret = impl_->SetLayerCrop(devId, layerId, rect);
616         }
617         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
618 EXIT:
619         if (ret != HDF_SUCCESS) {
620             errMaps_.emplace(REQUEST_CMD_SET_LAYER_CROP, ret);
621         }
622         return;
623     }
624 
OnSetLayerZorder(CommandDataUnpacker & unpacker)625     void OnSetLayerZorder(CommandDataUnpacker& unpacker)
626     {
627         DISPLAY_TRACE;
628 
629         uint32_t devId = 0;
630         uint32_t layerId = 0;
631         uint32_t zorder = 0;
632 
633         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
634         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
635 
636         ret = unpacker.ReadUint32(zorder) ? HDF_SUCCESS : HDF_FAILURE;
637         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
638 
639         {
640             HdfTrace traceVdi("SetLayerZorder", "HDI:DISP:HARDWARE");
641             ret = impl_->SetLayerZorder(devId, layerId, zorder);
642         }
643         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
644 EXIT:
645         if (ret != HDF_SUCCESS) {
646             errMaps_.emplace(REQUEST_CMD_SET_LAYER_ZORDER, ret);
647         }
648         return;
649     }
650 
OnSetLayerPreMulti(CommandDataUnpacker & unpacker)651     void OnSetLayerPreMulti(CommandDataUnpacker& unpacker)
652     {
653         DISPLAY_TRACE;
654 
655         uint32_t devId = 0;
656         uint32_t layerId = 0;
657         bool preMulti = false;
658 
659         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
660         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
661 
662         ret = unpacker.ReadBool(preMulti) ? HDF_SUCCESS : HDF_FAILURE;
663         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
664 
665         {
666             HdfTrace traceVdi("SetLayerPreMulti", "HDI:DISP:HARDWARE");
667             ret = impl_->SetLayerPreMulti(devId, layerId, preMulti);
668         }
669         DISPLAY_CHECK(ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT, goto EXIT);
670 EXIT:
671         if (ret != HDF_SUCCESS) {
672             errMaps_.emplace(REQUEST_CMD_SET_LAYER_PREMULTI, ret);
673         }
674         return;
675     }
676 
OnSetLayerTransformMode(CommandDataUnpacker & unpacker)677     void OnSetLayerTransformMode(CommandDataUnpacker& unpacker)
678     {
679         DISPLAY_TRACE;
680 
681         uint32_t devId = 0;
682         uint32_t layerId = 0;
683         int32_t type = 0;
684 
685         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
686         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
687 
688         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
689         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
690 
691         {
692             HdfTrace traceVdi("SetLayerTransformMode", "HDI:DISP:HARDWARE");
693             ret = impl_->SetLayerTransformMode(devId, layerId, static_cast<TransformType>(type));
694         }
695         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
696 EXIT:
697         if (ret != HDF_SUCCESS) {
698             errMaps_.emplace(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE, ret);
699         }
700 
701         return;
702     }
703 
OnSetLayerDirtyRegion(CommandDataUnpacker & unpacker)704     void OnSetLayerDirtyRegion(CommandDataUnpacker& unpacker)
705     {
706         DISPLAY_TRACE;
707 
708         uint32_t devId = 0;
709         uint32_t layerId = 0;
710         uint32_t vectSize = 0;
711         int32_t ret = HDF_SUCCESS;
712 
713         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId),
714             HDF_LOGE("%{public}s, read devId error", __func__));
715 
716         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker.ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE,
717             HDF_LOGE("%{public}s, read vectSize error", __func__));
718 
719         std::vector<IRect> rects(vectSize);
720         if (ret == HDF_SUCCESS) {
721             for (uint32_t i = 0; i < vectSize; i++) {
722                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
723                     HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i));
724                 if (ret != HDF_SUCCESS) {
725                     break;
726                 }
727             }
728         }
729         if (ret == HDF_SUCCESS) {
730             HdfTrace traceVdi("SetLayerDirtyRegion", "HDI:DISP:HARDWARE");
731             impl_->SetLayerDirtyRegion(devId, layerId, rects);
732         } else {
733             HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__);
734             errMaps_.emplace(REQUEST_CMD_SET_LAYER_DIRTY_REGION, ret);
735         }
736         return;
737     }
738 
OnSetLayerVisibleRegion(CommandDataUnpacker & unpacker)739     void OnSetLayerVisibleRegion(CommandDataUnpacker& unpacker)
740     {
741         DISPLAY_TRACE;
742 
743         uint32_t devId = 0;
744         uint32_t layerId = 0;
745         uint32_t vectSize = 0;
746         int32_t ret = HDF_SUCCESS;
747 
748         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId),
749             HDF_LOGE("%{public}s, read devId error", __func__));
750 
751         DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, unpacker.ReadUint32(vectSize) ? HDF_SUCCESS : HDF_FAILURE,
752             HDF_LOGE("%{public}s, read vectSize error", __func__));
753 
754         std::vector<IRect> rects(vectSize);
755         if (ret == HDF_SUCCESS) {
756             for (uint32_t i = 0; i < vectSize; i++) {
757                 DISPLAY_CHK_CONDITION(ret, HDF_SUCCESS, CmdUtils::RectUnpack(unpacker, rects[i]),
758                     HDF_LOGE("%{public}s, read vect error, at i = %{public}d", __func__, i));
759                 if (ret != HDF_SUCCESS) {
760                     break;
761                 }
762             }
763         }
764         if (ret == HDF_SUCCESS) {
765             HdfTrace traceVdi("SetLayerVisibleRegion", "HDI:DISP:HARDWARE");
766             impl_->SetLayerVisibleRegion(devId, layerId, rects);
767         } else {
768             HDF_LOGE("%{public}s, SetLayerDirtyRegion error", __func__);
769             errMaps_.emplace(REQUEST_CMD_SET_LAYER_VISIBLE_REGION, ret);
770         }
771         return;
772     }
773 
774     typedef struct LayerBufferData {
775         bool isValidBuffer;
776         uint32_t devId;
777         uint32_t layerId;
778         uint32_t seqNo;
779         int32_t fence;
780         BufferHandle *buffer;
781     } LayerBufferData;
782 
UnPackLayerBufferInfo(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds,struct LayerBufferData * data,std::vector<uint32_t> & deletingList)783     int32_t UnPackLayerBufferInfo(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds,
784         struct LayerBufferData *data, std::vector<uint32_t> &deletingList)
785     {
786         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::SetupDeviceUnpack(unpacker, data->devId, data->layerId),
787             HDF_FAILURE, HDF_LOGE("%{public}s, read devId error", __func__));
788 
789         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::BufferHandleUnpack(unpacker, inFds, data->buffer), HDF_FAILURE,
790             HDF_LOGE("%{public}s, read BufferHandleUnpack error", __func__));
791 
792         data->isValidBuffer = true;
793 
794         DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(data->seqNo), HDF_FAILURE,
795             HDF_LOGE("%{public}s, read seqNo error", __func__));
796 
797         DISPLAY_CHK_RETURN(HDF_SUCCESS != CmdUtils::FileDescriptorUnpack(unpacker, inFds, data->fence), HDF_FAILURE,
798             HDF_LOGE("%{public}s, FileDescriptorUnpack error", __func__));
799 
800         // unpack deletingList
801         uint32_t vectSize = 0;
802         DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(vectSize), HDF_FAILURE,
803             HDF_LOGE("%{public}s, read vectSize error", __func__));
804         if (vectSize > CmdUtils::MAX_MEMORY) {
805             HDF_LOGE("%{public}s: vectSize:%{public}u is too large", __func__, vectSize);
806             return HDF_FAILURE;
807         }
808 
809         deletingList.resize(vectSize);
810         for (uint32_t i = 0; i < vectSize; i++) {
811             DISPLAY_CHK_RETURN(true != unpacker.ReadUint32(deletingList[i]), HDF_FAILURE,
812                 HDF_LOGE("%{public}s, read seqNo error, at i = %{public}d", __func__, i));
813         }
814         return HDF_SUCCESS;
815     }
816 
SetLayerBuffer(LayerBufferData & data,std::vector<uint32_t> & deletingList,bool & needFreeBuffer,bool & needMoveFd,int fd)817     int32_t SetLayerBuffer(LayerBufferData& data, std::vector<uint32_t> &deletingList,
818         bool &needFreeBuffer, bool &needMoveFd, int fd)
819     {
820         DISPLAY_CHECK(cacheMgr_ == nullptr, return HDF_FAILURE);
821         std::lock_guard<std::mutex> lock(cacheMgr_->GetCacheMgrMutex());
822         DeviceCache* devCache = nullptr;
823         LayerCache* layerCache = nullptr;
824         devCache = cacheMgr_->DeviceCacheInstance(data.devId);
825         DISPLAY_CHECK(devCache == nullptr, return HDF_FAILURE);
826         layerCache = devCache->LayerCacheInstance(data.layerId);
827         DISPLAY_CHECK(layerCache == nullptr, return HDF_FAILURE);
828 
829         int32_t ret = layerCache->SetLayerBuffer(data.buffer, data.seqNo, needFreeBuffer, deletingList,
830             [&data, &needMoveFd, &fd, this](const BufferHandle& handle)->int32_t {
831 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
832             DumpLayerBuffer(data.devId, data.layerId, data.fence, handle, "layer_");
833 #endif
834             if (data.fence > ERROR_FENCE_COUNT) {
835                 HDF_LOGW("SetLayerBuffer:%{public}s data.devId:%{public}d, data.layerId:%{public}d, "
836                          "data.buffer->fd:%{public}d, data.seqNo:%{public}d, fd:%{public}d",
837                     data.buffer == nullptr ? "data.buffer is nullptr!" : "",
838                     data.devId,
839                     data.layerId,
840                     data.buffer == nullptr ? -1 : data.buffer->fd,
841                     data.seqNo,
842                     fd);
843             }
844             needMoveFd = true;
845             HITRACE_METER_FMT(HITRACE_TAG_HDF,
846                 "SetLayerBuffer:%s data.devId:%d, data.layerId:%d, data.buffer->fd:%d, data.seqNo:%d, fd:%d",
847                 data.buffer == nullptr ? "data.buffer is nullptr!" : "",
848                 data.devId,
849                 data.layerId,
850                 data.buffer == nullptr ? -1 : data.buffer->fd,
851                 data.seqNo,
852                 fd);
853             int rc = impl_->SetLayerBuffer(data.devId, data.layerId, handle, fd);
854             DISPLAY_CHK_RETURN(rc != HDF_SUCCESS, HDF_FAILURE, HDF_LOGE(" fail"));
855             return HDF_SUCCESS;
856         });
857         return ret;
858     }
859 
OnSetLayerBuffer(CommandDataUnpacker & unpacker,const std::vector<HdifdInfo> & inFds)860     void OnSetLayerBuffer(CommandDataUnpacker& unpacker, const std::vector<HdifdInfo>& inFds)
861     {
862         DISPLAY_TRACE;
863 
864         struct LayerBufferData data;
865         std::vector<uint32_t> deletingList;
866 
867         int32_t ret = UnPackLayerBufferInfo(unpacker, inFds, &data, deletingList);
868         HdifdParcelable fdParcel(data.fence);
869         bool needFreeBuffer = false;
870         bool needMoveFd = false;
871 
872         if (ret == HDF_SUCCESS) {
873             ret = SetLayerBuffer(data, deletingList, needFreeBuffer, needMoveFd, fdParcel.GetFd());
874         }
875 #ifndef DISPLAY_COMMUNITY
876         // fix fd leak
877         if (data.buffer != nullptr && needFreeBuffer) {
878             FreeBufferWithDelay(data.buffer);
879             data.buffer = nullptr;
880             data.isValidBuffer = false;
881         }
882         if (needMoveFd) {
883             fdParcel.Move();
884         }
885 #endif // DISPLAY_COMMUNITY
886         if (ret != HDF_SUCCESS) {
887             HDF_LOGE("%{public}s, SetLayerBuffer error", __func__);
888             if (data.isValidBuffer && data.buffer != nullptr) {
889                 FreeBufferHandle(data.buffer);
890                 data.buffer = nullptr;
891             }
892             errMaps_.emplace(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER, ret);
893         }
894 
895         return;
896     }
897 
OnSetLayerCompositionType(CommandDataUnpacker & unpacker)898     void OnSetLayerCompositionType(CommandDataUnpacker& unpacker)
899     {
900         DISPLAY_TRACE;
901 
902         uint32_t devId = 0;
903         uint32_t layerId = 0;
904         int32_t type;
905         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
906         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
907 
908         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
909         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
910 
911         {
912             HdfTrace traceVdi("SetLayerCompositionType", "HDI:DISP:HARDWARE");
913             ret = impl_->SetLayerCompositionType(devId, layerId, static_cast<CompositionType>(type));
914         }
915         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
916 EXIT:
917         if (ret != HDF_SUCCESS) {
918             errMaps_.emplace(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE, ret);
919         }
920         return;
921     }
922 
OnSetLayerBlendType(CommandDataUnpacker & unpacker)923     void OnSetLayerBlendType(CommandDataUnpacker& unpacker)
924     {
925         DISPLAY_TRACE;
926 
927         uint32_t devId = 0;
928         uint32_t layerId = 0;
929         int32_t type;
930         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
931         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
932 
933         ret = unpacker.ReadInt32(type) ? HDF_SUCCESS : HDF_FAILURE;
934         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
935 
936         {
937             HdfTrace traceVdi("SetLayerBlendType", "HDI:DISP:HARDWARE");
938             ret = impl_->SetLayerBlendType(devId, layerId, static_cast<BlendType>(type));
939         }
940         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
941 EXIT:
942         if (ret != HDF_SUCCESS) {
943             errMaps_.emplace(REQUEST_CMD_SET_LAYER_BLEND_TYPE, ret);
944         }
945         return;
946     }
947 
OnSetLayerMaskInfo(CommandDataUnpacker & unpacker)948     void OnSetLayerMaskInfo(CommandDataUnpacker& unpacker)
949     {
950         DISPLAY_TRACE;
951 
952         uint32_t devId = 0;
953         uint32_t layerId = 0;
954         uint32_t maskInfo = 0;
955 
956         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
957         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
958 
959         ret = unpacker.ReadUint32(maskInfo) ? HDF_SUCCESS : HDF_FAILURE;
960         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
961 
962         {
963             HdfTrace traceVdi("SetLayerMaskInfo", "HDI:DISP:HARDWARE");
964             ret = impl_->SetLayerMaskInfo(devId, layerId, static_cast<MaskInfo>(maskInfo));
965         }
966         DISPLAY_CHECK(ret != HDF_SUCCESS && ret != DISPLAY_NOT_SUPPORT && ret != HDF_ERR_NOT_SUPPORT, goto EXIT);
967 EXIT:
968         if (ret != HDF_SUCCESS) {
969             errMaps_.emplace(REQUEST_CMD_SET_LAYER_MASK_INFO, ret);
970         }
971         return;
972     }
973 
OnSetLayerColor(CommandDataUnpacker & unpacker)974     void OnSetLayerColor(CommandDataUnpacker& unpacker)
975     {
976         DISPLAY_TRACE;
977 
978         uint32_t devId = 0;
979         uint32_t layerId = 0;
980         LayerColor layerColor = {0};
981 
982         int32_t ret = CmdUtils::SetupDeviceUnpack(unpacker, devId, layerId);
983         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
984 
985         ret = CmdUtils::LayerColorUnpack(unpacker, layerColor);
986         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
987 
988         {
989             HdfTrace traceVdi("SetLayerColor", "HDI:DISP:HARDWARE");
990             ret = impl_->SetLayerColor(devId, layerId, layerColor);
991         }
992         DISPLAY_CHECK(ret != HDF_SUCCESS, goto EXIT);
993 EXIT:
994         if (ret != HDF_SUCCESS) {
995             errMaps_.emplace(REQUEST_CMD_SET_LAYER_COLOR, ret);
996         }
997         return;
998     }
999 
PeriodDataReset()1000     int32_t PeriodDataReset()
1001     {
1002         replyCommandCnt_ = 0;
1003         errMaps_.clear();
1004 
1005         int32_t ret = CmdUtils::StartPack(CONTROL_CMD_REPLY_BEGIN, replyPacker_);
1006         if (ret != HDF_SUCCESS) {
1007             HDF_LOGE("PackBegin failure, ret=%{public}d", ret);
1008         }
1009         return ret;
1010     }
1011 
GetFileName(uint32_t devId,uint32_t layerId,const BufferHandle & buffer)1012     static std::string GetFileName(uint32_t devId, uint32_t layerId, const BufferHandle& buffer)
1013     {
1014         struct timeval tv;
1015         char nowStr[TIME_BUFFER_MAX_LEN] = {0};
1016 
1017         gettimeofday(&tv, nullptr);
1018         if (strftime(nowStr, sizeof(nowStr), "%m-%d-%H-%M-%S", localtime(&tv.tv_sec)) == 0) {
1019             HDF_LOGE("strftime failed");
1020             return "";
1021         };
1022 
1023         std::ostringstream strStream;
1024         const int32_t PIXEL_BYTES = 4;
1025         strStream << "hdi_layer_" << devId << "_" << layerId << "_" << buffer.stride / PIXEL_BYTES << "x" <<
1026             buffer.height << "_" << nowStr << "-" << tv.tv_usec;
1027         return strStream.str();
1028     }
1029 #ifdef DISPLAY_COMSPOER_DEBUG_DUMP
DumpLayerBuffer(uint32_t devId,uint32_t layerId,int32_t fence,const BufferHandle & buffer,std::string tag)1030     static void DumpLayerBuffer(uint32_t devId, uint32_t layerId, int32_t fence, const BufferHandle& buffer,
1031         std::string tag)
1032     {
1033         const std::string SWITCH_ON = "on";
1034         const uint32_t DUMP_BUFFER_SWITCH_LEN = 4;
1035         char dumpSwitch[DUMP_BUFFER_SWITCH_LEN] = {0};
1036         GetParameter("hdi.composer.dumpbuffer", "off", dumpSwitch, DUMP_BUFFER_SWITCH_LEN);
1037 
1038         if (SWITCH_ON.compare(dumpSwitch) != 0) {
1039             return;
1040         }
1041 
1042         const uint32_t FENCE_TIMEOUT = 3000;
1043         int32_t retCode = WaitFence(fence, FENCE_TIMEOUT);
1044         if (retCode != HDF_SUCCESS) {
1045             return;
1046         }
1047 
1048         if (g_bufferServiceImpl == nullptr) {
1049             g_bufferServiceImpl = IMapper::Get(true);
1050             DISPLAY_CHECK((g_bufferServiceImpl == nullptr), HDF_LOGE("get IMapper failed"));
1051         }
1052 
1053         std::string fileName = GetFileName(devId, layerId, buffer);
1054         DISPLAY_CHECK((fileName == ""), HDF_LOGE("GetFileName failed"));
1055         HDF_LOGI("fileName = %{public}s", fileName.c_str());
1056 
1057         const std::string PATH_PREFIX = "/data/local/traces/";
1058         std::stringstream filePath;
1059         filePath << PATH_PREFIX << tag << fileName;
1060         std::ofstream rawDataFile(filePath.str(), std::ofstream::binary);
1061         DISPLAY_CHECK((!rawDataFile.good()), HDF_LOGE("open file failed, %{public}s",
1062             std::strerror(errno)));
1063 
1064         sptr<NativeBuffer> hdiBuffer = new NativeBuffer();
1065         hdiBuffer->SetBufferHandle(const_cast<BufferHandle*>(&buffer));
1066 
1067         int32_t ret = 0;
1068         ret = g_bufferServiceImpl->Mmap(hdiBuffer);
1069         DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Mmap buffer failed"));
1070 
1071         std::chrono::milliseconds time_before = std::chrono::duration_cast<std::chrono::milliseconds> (
1072             std::chrono::system_clock::now().time_since_epoch()
1073         );
1074         rawDataFile.write(static_cast<const char *>(buffer.virAddr), buffer.size);
1075         std::chrono::milliseconds time_after = std::chrono::duration_cast<std::chrono::milliseconds> (
1076             std::chrono::system_clock::now().time_since_epoch()
1077         );
1078         HDF_LOGI("wirte file take time %{public}lld", time_after.count() - time_before.count());
1079         rawDataFile.close();
1080 
1081         ret = g_bufferServiceImpl->Unmap(hdiBuffer);
1082         DISPLAY_CHECK((ret != HDF_SUCCESS), HDF_LOGE("Unmap buffer failed"));
1083     }
1084 #endif
1085 
WaitFence(int32_t fence,uint32_t timeout)1086     static int32_t WaitFence(int32_t fence, uint32_t timeout)
1087     {
1088         int retCode = -1;
1089         if (fence < 0) {
1090             HDF_LOGE("The fence id is invalid.");
1091             return retCode;
1092         }
1093 
1094         struct pollfd pollfds = {0};
1095         pollfds.fd = fence;
1096         pollfds.events = POLLIN;
1097 
1098         do {
1099             retCode = poll(&pollfds, 1, timeout);
1100         } while (retCode == -1 && (errno == EINTR || errno == EAGAIN));
1101 
1102         if (retCode == 0) {
1103             retCode = -1;
1104             errno = ETIME;
1105         } else if (retCode > 0) {
1106             retCode = 0;
1107             if (pollfds.revents & (POLLERR | POLLNVAL)) {
1108                 retCode = -1;
1109                 errno = EINVAL;
1110             }
1111         }
1112 
1113         return retCode < 0 ? -errno : HDF_SUCCESS;
1114     }
1115 
FreeBufferWithDelay(BufferHandle * handle)1116     void FreeBufferWithDelay(BufferHandle *handle)
1117     {
1118         delayFreeQueue_.push(handle);
1119         if (delayFreeQueue_.size() >= BUFFER_QUEUE_MAX_SIZE) {
1120             BufferHandle *temp = delayFreeQueue_.front();
1121             delayFreeQueue_.pop();
1122             FreeBufferHandle(temp);
1123             temp = nullptr;
1124         }
1125     }
1126 
1127 protected:
1128     VdiImpl* impl_ = nullptr;
1129     std::shared_ptr<DeviceCacheManager> cacheMgr_;
1130     std::shared_ptr<Transfer> request_;
1131     bool isReplyUpdated_;
1132     std::shared_ptr<Transfer> reply_;
1133     /* period data */
1134     uint32_t replyCommandCnt_;
1135     CommandDataPacker replyPacker_;
1136     std::unordered_map<int32_t, int32_t> errMaps_;
1137     /* fix fd leak */
1138     std::queue<BufferHandle *> delayFreeQueue_;
1139     std::mutex requestMutex_;
1140     std::mutex replyMutex_;
1141 };
1142 using HdiDisplayCmdResponser = DisplayCmdResponser<SharedMemQueue<int32_t>, DisplayComposerVdiAdapter>;
1143 } // namespace V1_0
1144 } // namespace Composer
1145 } // namespace Display
1146 } // namespace HDI
1147 } // namespace OHOS
1148 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_REQUESTER_H