• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_UTILS_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H
18 
19 #include "buffer_handle_utils.h"
20 #include "command_data_packer.h"
21 #include "command_data_unpacker.h"
22 #include "v1_0/display_composer_type.h"
23 
24 namespace OHOS {
25 namespace HDI {
26 namespace Display {
27 namespace Composer {
28 namespace V1_0 {
29 using namespace OHOS::HDI::Display::Composer::V1_0;
30 
31 class DisplayCmdUtils {
32 public:
33     static constexpr int32_t MAX_INT = 0x7fffffff;
34     static constexpr int32_t MIN_INT = 0x80000000;
35     static constexpr uint32_t ELEMENT_SIZE = sizeof(int32_t);
36     static constexpr uint32_t TRANSFER_WAIT_TIME = 100000000; // ms
37     static constexpr uint32_t INIT_ELEMENT_COUNT = 32 * 1024;
38 
39     #define SWITCHCASE(x) case (x): {return #x;}
40     #define PARCEL_OPS_CHECK_RET(fn, arg)                                                        \
41     do {                                                                                         \
42         bool ret = fn(arg);                                                                      \
43         if (ret == false) {                                                                      \
44             HDF_LOG("%{public}s: parcel ops failed, line = %{public}d", __func__, __LINE__);     \
45             return HDF_FAILURE;                                                                  \
46         }                                                                                        \
47     } while (0)
48 
49     #define PARCEL_OPS_CHECK_WITHOUT_RET(fn, arg, ret)                                           \
50     do {                                                                                         \
51         if (ret) {                                                                               \
52             ret = fn(arg);                                                                       \
53         } else {                                                                                 \
54             HDF_LOG("%{public}s: parcel ops failed, line = %{public}d", __func__, __LINE__);     \
55         }                                                                                        \
56     } while (0)
57 
CommandToString(int32_t cmdId)58     static const char *CommandToString(int32_t cmdId)
59     {
60         switch (cmdId) {
61             /* request cmd */
62             SWITCHCASE(REQUEST_CMD_PREPAREDISPLAYLAYERS);
63             SWITCHCASE(REQUEST_CMD_SETDISPLAYCLIENTBUFFER);
64             SWITCHCASE(REQUEST_CMD_SETDISPLAYCLIENTDAMAGE);
65             SWITCHCASE(REQUEST_CMD_COMMIT);
66             SWITCHCASE(REQUEST_CMD_SETLAYERALPHA);
67             SWITCHCASE(REQUEST_CMD_SETLAYERPOSITION);
68             SWITCHCASE(REQUEST_CMD_SETLAYERCROP);
69             SWITCHCASE(REQUEST_CMD_SETLAYERZORDER);
70             SWITCHCASE(REQUEST_CMD_SETLAYERPREMULTI);
71             SWITCHCASE(REQUEST_CMD_SETTRANSFORMMODE);
72             SWITCHCASE(REQUEST_CMD_SETLAYERDIRTYREGION);
73             SWITCHCASE(REQUEST_CMD_SETLAYERVISIBLEREGION);
74             SWITCHCASE(REQUEST_CMD_SETLAYERBUFFER);
75             SWITCHCASE(REQUEST_CMD_SETLAYERCOMPOSITIONTYPE);
76             SWITCHCASE(REQUEST_CMD_SETLAYERBLENDTYPE);
77             SWITCHCASE(REQUEST_CMD_SETLAYERVISIBLE);
78             /* reply cmd */
79             SWITCHCASE(REPLY_CMD_SETERROR);
80             SWITCHCASE(REPLY_CMD_PREPAREDISPLAYLAYERS);
81             SWITCHCASE(REPLY_CMD_COMMIT);
82             /* pack control cmd */
83             SWITCHCASE(CONTROL_CMD_REQUEST_BEGIN);
84             SWITCHCASE(CONTROL_CMD_REPLY_BEGIN);
85             SWITCHCASE(CONTROL_CMD_REQUEST_END);
86             SWITCHCASE(CONTROL_CMD_REPLY_END);
87             default:
88                 return "unknow command id.";
89         }
90     }
91 
StartPack(int32_t cmdId,std::shared_ptr<CommandDataPacker> packer)92     static int32_t StartPack(int32_t cmdId, std::shared_ptr<CommandDataPacker> packer)
93     {
94         return packer->PackBegin(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
95     }
96 
EndPack(std::shared_ptr<CommandDataPacker> packer)97     static int32_t EndPack(std::shared_ptr<CommandDataPacker> packer)
98     {
99         return packer->PackEnd(CONTROL_CMD_REQUEST_END) ? HDF_SUCCESS : HDF_FAILURE;
100     }
101 
StartSection(int32_t cmdId,std::shared_ptr<CommandDataPacker> packer)102     static int32_t StartSection(int32_t cmdId, std::shared_ptr<CommandDataPacker> packer)
103     {
104         return packer->BeginSection(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
105     }
106 
SetupDevice(uint32_t devId,uint32_t layerId,std::shared_ptr<CommandDataPacker> packer)107     static int32_t SetupDevice(uint32_t devId, uint32_t layerId, std::shared_ptr<CommandDataPacker> packer)
108     {
109         bool retVal = packer->WriteUint32(devId);
110         if (retVal) {
111             retVal = packer->WriteUint32(layerId);
112         }
113         return retVal ? HDF_SUCCESS : HDF_FAILURE;
114     }
115 
EndSection(std::shared_ptr<CommandDataPacker> packer)116     static int32_t EndSection(std::shared_ptr<CommandDataPacker> packer)
117     {
118         return packer->EndSection() ? HDF_SUCCESS : HDF_FAILURE;
119     }
120 
GenerateHdifdSeqid()121     static int32_t GenerateHdifdSeqid()
122     {
123         static int32_t HdifdSeqidCursor = 0;
124 
125         if (HdifdSeqidCursor <= MAX_INT) {
126             ++HdifdSeqidCursor;
127             return HdifdSeqidCursor;
128         } else {
129             return 0;
130         }
131     }
132 
MatchHdiFd(int32_t id,std::vector<HdifdInfo> hdiFds,int32_t & fd)133     static bool MatchHdiFd(int32_t id, std::vector<HdifdInfo> hdiFds, int32_t &fd)
134     {
135         for (uint32_t i = 0; i < hdiFds.size(); ++i) {
136             if (hdiFds[i].id == id) {
137                 fd = hdiFds[i].hdiFd->Move();
138                 return true;
139             }
140         }
141         return false;
142     }
143 
RectPack(const IRect & rect,std::shared_ptr<CommandDataPacker> packer)144     static int32_t RectPack(const IRect &rect, std::shared_ptr<CommandDataPacker> packer)
145     {
146         bool retVal = packer->WriteInt32(rect.x);
147         if (retVal) {
148             retVal = packer->WriteInt32(rect.y);
149         }
150         if (retVal) {
151             retVal = packer->WriteInt32(rect.w);
152         }
153         if (retVal) {
154             retVal = packer->WriteInt32(rect.h);
155         }
156         return retVal ? HDF_SUCCESS : HDF_FAILURE;
157     }
158 
FileDescriptorPack(const int32_t fd,std::shared_ptr<CommandDataPacker> packer,std::vector<HdifdInfo> & hdiFds)159     static int32_t FileDescriptorPack(
160         const int32_t fd, std::shared_ptr<CommandDataPacker> packer, std::vector<HdifdInfo> &hdiFds)
161     {
162         int32_t ec = HDF_SUCCESS;
163 
164         HdifdInfo hdifdInfo;
165         hdifdInfo.id = GenerateHdifdSeqid();
166         hdifdInfo.hdiFd = new HdifdParcelable();
167         if (hdifdInfo.hdiFd == nullptr) {
168             HDF_LOGE("%{public}s: new HdifdParcelable failed", __func__);
169             ec = HDF_FAILURE;
170         } else {
171             if (fd >= 0) {
172                 // A normal fd is transfered by binder, here just write id for unpacking to match fd.
173                 if (ec == HDF_SUCCESS && hdifdInfo.hdiFd->Init(fd)) {
174                     hdiFds.push_back(hdifdInfo);
175                     ec = packer->WriteInt32(hdifdInfo.id) ? HDF_SUCCESS : HDF_FAILURE;
176                 } else {
177                     HDF_LOGE("%{public}s: WriteInt32 failed, line=%{public}d", __func__, __LINE__);
178                     ec = HDF_FAILURE;
179                 }
180             } else {
181                 // A illegal fd is transfered by smq directly.
182                 ec = packer->WriteInt32(fd);
183                 if (ec != HDF_SUCCESS {
184                     HDF_LOGE("%{public}s: WriteInt32 failed, line=%{public}d", __func__, __LINE__);
185                 }
186             }
187         }
188         return ec;
189     }
190 
191     static int32_t BufferHandlePack(const BufferHandle &buffer, std::shared_ptr<CommandDataPacker> packer,
192         std::vector<HdifdInfo> &hdiFds)
193     {
194         PARCEL_OPS_CHECK_RET(packer->WriteUint32, buffer.reserveFds);
195         PARCEL_OPS_CHECK_RET(packer->WriteUint32, buffer.reserveInts);
196         int32_t ec = FileDescriptorPack(buffer.fd, packer, hdiFds);
197         if (ec != HDF_SUCCESS) {
198             return ec;
199         }
200         PARCEL_OPS_CHECK_RET(packer->WriteInt32, buffer.width);
201         PARCEL_OPS_CHECK_RET(packer->WriteInt32, buffer.stride);
202         PARCEL_OPS_CHECK_RET(packer->WriteInt32, buffer.height);
203         PARCEL_OPS_CHECK_RET(packer->WriteInt32, buffer.size);
204         PARCEL_OPS_CHECK_RET(packer->WriteInt32, buffer.format);
205         PARCEL_OPS_CHECK_RET(packer->WriteUint64, buffer.usage);
206         PARCEL_OPS_CHECK_RET(packer->WriteUint64, buffer.phyAddr);
207         PARCEL_OPS_CHECK_RET(packer->WriteInt32, buffer.key);
208 
209         bool retVal = true;
210         int32_t i = 0;
211         for (i = 0; i < buffer.reserveFds; i++) {
212             ec = FileDescriptorPack(buffer.reserve[i], packer, hdiFds);
213             if (ec != HDF_SUCCESS) {
214                 retVal = false;
215                 break;
216             }
217         }
218         for (int32_t j = 0; j < buffer.reserveInts; j++) {
219             retVal = packer->WriteInt32(buffer.reserve[i++]);
220             if (!retVal) {
221                 break;
222             }
223         }
224         return retVal ? HDF_SUCCESS : HDF_FAILURE;
225     }
226 
227     static int32_t SetupDeviceUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, uint32_t &devId, uint32_t &layerId)
228     {
229         bool retVal = unpacker->ReadUint32(devId);
230         if (retVal) {
231             retVal = unpacker->ReadUint32(layerId);
232         }
233         return retVal ? HDF_SUCCESS : HDF_FAILURE;
234     }
235 
236     static int32_t RectUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, IRect &rect)
237     {
238         bool retVal = unpacker->ReadInt32(rect.x);
239         if (retVal) {
240             retVal = unpacker->ReadInt32(rect.y);
241         }
242         if (retVal) {
243             retVal = unpacker->ReadInt32(rect.w);
244         }
245         if (retVal) {
246             retVal = unpacker->ReadInt32(rect.h);
247         }
248         return retVal ? HDF_SUCCESS : HDF_FAILURE;
249     }
250 
251     static int32_t FileDescriptorUnpack(
252         std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo> &hdiFds, int32_t &fd)
253     {
254         int32_t fdId = -1;
255         int32_t ec = unpacker->ReadInt32(fdId) ? HDF_SUCCESS : HDF_FAILURE;
256         if (ec == HDF_SUCCESS && fdId >= 0) {
257             ec = MatchHdiFd(fdId, hdiFds, fd) ? HDF_SUCCESS : HDF_FAILURE;
258         }
259         if (ec == HDF_FAILURE) {
260             // If matching failure, the illegal fd is transfered by smq directly, not by binder IPC.
261             fd = fdId;
262         }
263         return ec;
264     }
265 
266     static int32_t BufferHandleUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,
267         const std::vector<HdifdInfo> &hdiFds, BufferHandle *&buffer)
268     {
269         uint32_t fdsNum = 0;
270         uint32_t intsNum = 0;
271         PARCEL_OPS_CHECK_RET(unpacker->ReadUint32, fdsNum);
272         PARCEL_OPS_CHECK_RET(unpacker->ReadUint32, intsNum);
273         BufferHandle *handle = AllocateBufferHandle(fdsNum, intsNum);
274         if (handle == nullptr) {
275             return HDF_FAILURE;
276         }
277         handle->reserveFds = fdsNum;
278         handle->reserveInts = intsNum;
279         int32_t ec = FileDescriptorUnpack(unpacker, hdiFds, handle->fd);
280         bool retVal = (ec == HDF_SUCCESS ? true : false);
281         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadInt32, handle->width, retVal);
282         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadInt32, handle->stride, retVal);
283         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadInt32, handle->height, retVal);
284         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadInt32, handle->size, retVal);
285         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadUint64, handle->usage, retVal);
286         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadUint64, handle->phyAddr, retVal);
287         PARCEL_OPS_CHECK_WITHOUT_RET(unpacker->ReadInt32, handle->key, retVal);
288         if (retVal) {
289             int32_t i = 0;
290             for (i = 0; i < handle->reserveFds; i++) {
291                 ec = FileDescriptorUnpack(unpacker, hdiFds, handle->reserve[i]);
292                 if (ec != HDF_SUCCESS) {
293                     retVal = false;
294                     break;
295                 }
296             }
297             for (int32_t j = 0; j < handle->reserveInts; j++) {
298                 retVal = unpacker->ReadInt32(handle->reserve[i++]);
299                 if (!retVal) {
300                     break;
301                 }
302             }
303         }
304         if (!retVal) {
305             if (handle != nullptr) {
306                 FreeBufferHandle(handle);
307                 handle = nullptr;
308             }
309             HDF_LOGE("%{public}s: buffer handle unpack failed", __func__);
310         }
311         buffer = handle;
312         return retVal ? HDF_SUCCESS : HDF_FAILURE;
313     }
314 };
315 using CmdUtils = DisplayCmdUtils;
316 } // namespace V1_0
317 } // namespace Composer
318 } // namespace Display
319 } // namespace HDI
320 } // namespace OHOS
321 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H