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