• 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_UTILS_H
17 #define OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H
18 
19 #include "buffer_handle_utils.h"
20 #include "command_pack/command_data_packer.h"
21 #include "command_pack/command_data_unpacker.h"
22 #include "common/include/display_interface_utils.h"
23 #include "v1_0/display_composer_type.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "DISP_CMD"
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN 0xD002515
29 
30 namespace OHOS {
31 namespace HDI {
32 namespace Display {
33 namespace Composer {
34 namespace V1_0 {
35 using namespace OHOS::HDI::Display::Composer::V1_0;
36 
37 class DisplayCmdUtils {
38 public:
39     static constexpr int32_t MAX_INT = 0x7fffffff;
40     static constexpr uint32_t ELEMENT_SIZE = sizeof(int32_t);
41     static constexpr uint32_t TRANSFER_WAIT_TIME = 100000000; // ms
42     static constexpr uint32_t INIT_ELEMENT_COUNT = 32 * 1024;
43 
44     #define SWITCHCASE(x) case (x): {return #x;}
CommandToString(int32_t cmdId)45     static const char *CommandToString(int32_t cmdId)
46     {
47         switch (cmdId) {
48             /* request cmd */
49             SWITCHCASE(REQUEST_CMD_PREPARE_DISPLAY_LAYERS);
50             SWITCHCASE(REQUEST_CMD_SET_DISPLAY_CLIENT_BUFFER);
51             SWITCHCASE(REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE);
52             SWITCHCASE(REQUEST_CMD_COMMIT);
53             SWITCHCASE(REQUEST_CMD_SET_LAYER_ALPHA);
54             SWITCHCASE(REQUEST_CMD_SET_LAYER_REGION);
55             SWITCHCASE(REQUEST_CMD_SET_LAYER_CROP);
56             SWITCHCASE(REQUEST_CMD_SET_LAYER_ZORDER);
57             SWITCHCASE(REQUEST_CMD_SET_LAYER_PREMULTI);
58             SWITCHCASE(REQUEST_CMD_SET_LAYER_TRANSFORM_MODE);
59             SWITCHCASE(REQUEST_CMD_SET_LAYER_DIRTY_REGION);
60             SWITCHCASE(REQUEST_CMD_SET_LAYER_VISIBLE_REGION);
61             SWITCHCASE(REQUEST_CMD_SET_LAYER_BUFFER);
62             SWITCHCASE(REQUEST_CMD_SET_LAYER_COMPOSITION_TYPE);
63             SWITCHCASE(REQUEST_CMD_SET_LAYER_BLEND_TYPE);
64             SWITCHCASE(REQUEST_CMD_SET_LAYER_COLOR);
65             /* reply cmd */
66             SWITCHCASE(REPLY_CMD_SET_ERROR);
67             SWITCHCASE(REPLY_CMD_PREPARE_DISPLAY_LAYERS);
68             SWITCHCASE(REPLY_CMD_COMMIT);
69             /* pack control cmd */
70             SWITCHCASE(CONTROL_CMD_REQUEST_BEGIN);
71             SWITCHCASE(CONTROL_CMD_REPLY_BEGIN);
72             SWITCHCASE(CONTROL_CMD_REQUEST_END);
73             SWITCHCASE(CONTROL_CMD_REPLY_END);
74             default:
75                 return "unknow command id.";
76         }
77     }
78 
StartPack(int32_t cmdId,std::shared_ptr<CommandDataPacker> packer)79     static int32_t StartPack(int32_t cmdId, std::shared_ptr<CommandDataPacker> packer)
80     {
81         return packer->PackBegin(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
82     }
83 
EndPack(std::shared_ptr<CommandDataPacker> packer)84     static int32_t EndPack(std::shared_ptr<CommandDataPacker> packer)
85     {
86         return packer->PackEnd(CONTROL_CMD_REQUEST_END) ? HDF_SUCCESS : HDF_FAILURE;
87     }
88 
StartSection(int32_t cmdId,std::shared_ptr<CommandDataPacker> packer)89     static int32_t StartSection(int32_t cmdId, std::shared_ptr<CommandDataPacker> packer)
90     {
91         return packer->BeginSection(cmdId) ? HDF_SUCCESS : HDF_FAILURE;
92     }
93 
SetupDevice(uint32_t devId,uint32_t layerId,std::shared_ptr<CommandDataPacker> packer)94     static int32_t SetupDevice(uint32_t devId, uint32_t layerId, std::shared_ptr<CommandDataPacker> packer)
95     {
96         DISPLAY_CHK_RETURN(packer->WriteUint32(devId) == false, HDF_FAILURE,
97             HDF_LOGE("%{public}s, write devId error", __func__));
98         DISPLAY_CHK_RETURN(packer->WriteUint32(layerId) == false, HDF_FAILURE,
99             HDF_LOGE("%{public}s, write layerId error", __func__));
100         return HDF_SUCCESS;
101     }
102 
EndSection(std::shared_ptr<CommandDataPacker> packer)103     static int32_t EndSection(std::shared_ptr<CommandDataPacker> packer)
104     {
105         return packer->EndSection() ? HDF_SUCCESS : HDF_FAILURE;
106     }
107 
GenerateHdifdSeqid()108     static int32_t GenerateHdifdSeqid()
109     {
110         static int32_t HdifdSeqidCursor = 0;
111 
112         if (HdifdSeqidCursor <= MAX_INT) {
113             ++HdifdSeqidCursor;
114             return HdifdSeqidCursor;
115         } else {
116             return 0;
117         }
118     }
119 
MatchHdiFd(int32_t id,std::vector<HdifdInfo> hdiFds,int32_t & fd)120     static bool MatchHdiFd(int32_t id, std::vector<HdifdInfo> hdiFds, int32_t& fd)
121     {
122         for (uint32_t i = 0; i < hdiFds.size(); ++i) {
123             if (hdiFds[i].hdiFd == nullptr) {
124                 HDF_LOGE("%{public}s, hdiFd is nullptr", __func__);
125                 continue;
126             }
127             if (hdiFds[i].id == id) {
128                 fd = hdiFds[i].hdiFd->Move();
129                 return true;
130             }
131         }
132         return false;
133     }
134 
RectPack(const IRect & rect,std::shared_ptr<CommandDataPacker> packer)135     static int32_t RectPack(const IRect& rect, std::shared_ptr<CommandDataPacker> packer)
136     {
137         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.x) == false, HDF_FAILURE,
138             HDF_LOGE("%{public}s, write rect.x error", __func__));
139         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.y) == false, HDF_FAILURE,
140             HDF_LOGE("%{public}s, write rect.y error", __func__));
141         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.w) == false, HDF_FAILURE,
142             HDF_LOGE("%{public}s, write rect.w error", __func__));
143         DISPLAY_CHK_RETURN(packer->WriteInt32(rect.h) == false, HDF_FAILURE,
144             HDF_LOGE("%{public}s, write rect.h error", __func__));
145         return HDF_SUCCESS;
146     }
147 
LayerColorPack(const LayerColor & layerColor,std::shared_ptr<CommandDataPacker> packer)148     static int32_t LayerColorPack(const LayerColor& layerColor, std::shared_ptr<CommandDataPacker> packer)
149     {
150         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.r) == false, HDF_FAILURE,
151             HDF_LOGE("%{public}s, write layerColor.r error", __func__));
152         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.g) == false, HDF_FAILURE,
153             HDF_LOGE("%{public}s, write layerColor.g error", __func__));
154         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.b) == false, HDF_FAILURE,
155             HDF_LOGE("%{public}s, write layerColor.b error", __func__));
156         DISPLAY_CHK_RETURN(packer->WriteUint8(layerColor.a) == false, HDF_FAILURE,
157             HDF_LOGE("%{public}s, write layerColor.a error", __func__));
158         return HDF_SUCCESS;
159     }
160 
FileDescriptorPack(const int32_t fd,std::shared_ptr<CommandDataPacker> packer,std::vector<HdifdInfo> & hdiFds)161     static int32_t FileDescriptorPack(
162         const int32_t fd, std::shared_ptr<CommandDataPacker> packer, std::vector<HdifdInfo>& hdiFds)
163     {
164         HdifdInfo hdifdInfo;
165         hdifdInfo.id = GenerateHdifdSeqid();
166         hdifdInfo.hdiFd = new HdifdParcelable();
167         DISPLAY_CHK_RETURN(hdifdInfo.hdiFd == nullptr, HDF_FAILURE,
168             HDF_LOGE("%{public}s, new HdifdParcelable failed", __func__));
169         if (fd >= 0) {
170             // A normal fd is transfered by binder, here just write id for unpacking to match fd.
171             DISPLAY_CHK_RETURN(hdifdInfo.hdiFd->Init(fd) == false, HDF_FAILURE,
172                 HDF_LOGE("%{public}s, hdiFd init failed", __func__));
173             hdiFds.push_back(hdifdInfo);
174             DISPLAY_CHK_RETURN(packer->WriteInt32(hdifdInfo.id) == false, HDF_FAILURE,
175                 HDF_LOGE("%{public}s, hdiFd init failed", __func__));
176         } else {
177             // A illegal fd is transfered by smq directly.
178             DISPLAY_CHK_RETURN(packer->WriteInt32(fd) == false, HDF_FAILURE,
179                 HDF_LOGE("%{public}s, write fd error", __func__));
180         }
181         return HDF_SUCCESS;
182     }
183 
BufferHandlePack(const BufferHandle * buffer,std::shared_ptr<CommandDataPacker> packer,std::vector<HdifdInfo> & hdiFds)184     static int32_t BufferHandlePack(const BufferHandle* buffer, std::shared_ptr<CommandDataPacker> packer,
185         std::vector<HdifdInfo>& hdiFds)
186     {
187         if (buffer == nullptr) {
188             DISPLAY_CHK_RETURN(packer->WriteUint32(UINT32_MAX) == false, HDF_FAILURE,
189                 HDF_LOGE("%{public}s, write null buffer reserveFds error", __func__));
190             DISPLAY_CHK_RETURN(packer->WriteUint32(UINT32_MAX) == false, HDF_FAILURE,
191                 HDF_LOGE("%{public}s, write null buffer reservceInts error", __func__));
192             return HDF_SUCCESS;
193         } else {
194             DISPLAY_CHK_RETURN(packer->WriteUint32(buffer->reserveFds) == false, HDF_FAILURE,
195                 HDF_LOGE("%{public}s, write buffer->reserveFds error", __func__));
196             DISPLAY_CHK_RETURN(packer->WriteUint32(buffer->reserveInts) == false, HDF_FAILURE,
197                 HDF_LOGE("%{public}s, write buffer->reserveInts error", __func__));
198         }
199         int32_t ret = FileDescriptorPack(buffer->fd, packer, hdiFds);
200         if (ret != HDF_SUCCESS) {
201             return ret;
202         }
203         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->width) == false, HDF_FAILURE,
204             HDF_LOGE("%{public}s, write buffer->width failed", __func__));
205         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->stride) == false, HDF_FAILURE,
206             HDF_LOGE("%{public}s, write buffer->stride failed", __func__));
207         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->height) == false, HDF_FAILURE,
208             HDF_LOGE("%{public}s, write buffer->height failed", __func__));
209         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->size) == false, HDF_FAILURE,
210             HDF_LOGE("%{public}s, write buffer->size failed", __func__));
211         DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->format) == false, HDF_FAILURE,
212             HDF_LOGE("%{public}s, write buffer->format failed", __func__));
213         DISPLAY_CHK_RETURN(packer->WriteUint64(buffer->usage) == false, HDF_FAILURE,
214             HDF_LOGE("%{public}s, write buffer->usage failed", __func__));
215         DISPLAY_CHK_RETURN(packer->WriteUint64(buffer->phyAddr) == false, HDF_FAILURE,
216             HDF_LOGE("%{public}s, write buffer->phyAddr failed", __func__));
217         uint32_t i = 0;
218         for (i = 0; i < buffer->reserveFds; i++) {
219             ret = FileDescriptorPack(buffer->reserve[i], packer, hdiFds);
220             if (ret != HDF_SUCCESS) {
221                 return ret;
222             }
223         }
224         for (uint32_t j = 0; j < buffer->reserveInts; j++) {
225             DISPLAY_CHK_RETURN(packer->WriteInt32(buffer->reserve[i++]) == false, HDF_FAILURE,
226                 HDF_LOGE("%{public}s, write buffer->reserve failed", __func__));
227         }
228         return HDF_SUCCESS;
229     }
230 
SetupDeviceUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,uint32_t & devId,uint32_t & layerId)231     static int32_t SetupDeviceUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, uint32_t& devId, uint32_t& layerId)
232     {
233         DISPLAY_CHK_RETURN(unpacker->ReadUint32(devId) == false, HDF_FAILURE,
234             HDF_LOGE("%{public}s, read devId failed", __func__));
235         DISPLAY_CHK_RETURN(unpacker->ReadUint32(layerId) == false, HDF_FAILURE,
236             HDF_LOGE("%{public}s, read layerId failed", __func__));
237         return HDF_SUCCESS;
238     }
239 
RectUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,IRect & rect)240     static int32_t RectUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, IRect& rect)
241     {
242         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.x) == false, HDF_FAILURE,
243             HDF_LOGE("%{public}s, read rect.x failed", __func__));
244         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.y) == false, HDF_FAILURE,
245             HDF_LOGE("%{public}s, read rect.y failed", __func__));
246         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.w) == false, HDF_FAILURE,
247             HDF_LOGE("%{public}s, read rect.w failed", __func__));
248         DISPLAY_CHK_RETURN(unpacker->ReadInt32(rect.h) == false, HDF_FAILURE,
249             HDF_LOGE("%{public}s, read rect.h failed", __func__));
250         return HDF_SUCCESS;
251     }
252 
FileDescriptorUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & hdiFds,int32_t & fd)253     static int32_t FileDescriptorUnpack(
254         std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo>& hdiFds, int32_t& fd)
255     {
256         int32_t fdId = -1;
257         DISPLAY_CHK_RETURN(unpacker->ReadInt32(fdId) == false, HDF_FAILURE,
258             HDF_LOGE("%{public}s, read fdId failed", __func__));
259         if (fdId < 0 || MatchHdiFd(fdId, hdiFds, fd) == false) {
260             // If matching failure, the illegal fd is transfered by smq directly, not by binder IPC.
261             fd = fdId;
262         }
263         return HDF_SUCCESS;
264     }
265 
UnpackBasicInfo(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * handle)266     static bool UnpackBasicInfo(std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo>& hdiFds,
267         BufferHandle *handle)
268     {
269         int32_t ret = FileDescriptorUnpack(unpacker, hdiFds, handle->fd);
270         bool retVal = (ret == HDF_SUCCESS ? true : false);
271         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->width),
272             HDF_LOGE("%{public}s, read handle->width error", __func__));
273         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->stride),
274             HDF_LOGE("%{public}s, read handle->stride error", __func__));
275         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->height),
276             HDF_LOGE("%{public}s, read handle->height error", __func__));
277         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->size),
278             HDF_LOGE("%{public}s, read handle->size error", __func__));
279         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadInt32(handle->format),
280             HDF_LOGE("%{public}s, read handle->format error", __func__));
281         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadUint64(handle->usage),
282             HDF_LOGE("%{public}s, read handle->usage error", __func__));
283         DISPLAY_CHK_CONDITION(retVal, true, unpacker->ReadUint64(handle->phyAddr),
284             HDF_LOGE("%{public}s, read handle->phyAddr error", __func__));
285         return retVal;
286     }
287 
UnpackExtraInfo(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * handle)288     static bool UnpackExtraInfo(std::shared_ptr<CommandDataUnpacker> unpacker, const std::vector<HdifdInfo>& hdiFds,
289         BufferHandle *handle)
290     {
291         bool retVal = true;
292         uint32_t i = 0;
293         for (i = 0; i < handle->reserveFds; i++) {
294             int32_t ret = FileDescriptorUnpack(unpacker, hdiFds, handle->reserve[i]);
295             if (ret != HDF_SUCCESS) {
296                 retVal = false;
297                 break;
298             }
299         }
300         for (uint32_t j = 0; j < handle->reserveInts; j++) {
301             retVal = unpacker->ReadInt32(handle->reserve[i++]);
302             if (!retVal) {
303                 HDF_LOGE("%{public}s, get reserve data error, i:%{public}u, j:%{public}u",
304                     __func__, i, j);
305                 break;
306             }
307         }
308         return retVal;
309     }
310 
BufferHandleUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,const std::vector<HdifdInfo> & hdiFds,BufferHandle * & buffer)311     static int32_t BufferHandleUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,
312         const std::vector<HdifdInfo>& hdiFds, BufferHandle*& buffer)
313     {
314         uint32_t fdsNum = 0;
315         uint32_t intsNum = 0;
316         DISPLAY_CHK_RETURN(unpacker->ReadUint32(fdsNum) == false, HDF_FAILURE,
317             HDF_LOGE("%{public}s, read fdsNum error", __func__));
318         DISPLAY_CHK_RETURN(unpacker->ReadUint32(intsNum) == false, HDF_FAILURE,
319             HDF_LOGE("%{public}s, read intsNum error", __func__));
320         if (fdsNum == UINT32_MAX && intsNum == UINT32_MAX) {
321             buffer = nullptr;
322             return HDF_SUCCESS;
323         }
324         BufferHandle *handle = AllocateBufferHandle(fdsNum, intsNum);
325         if (handle == nullptr) {
326             return HDF_FAILURE;
327         }
328         bool retVal = UnpackBasicInfo(unpacker, hdiFds, handle);
329         if (retVal) {
330             retVal = UnpackExtraInfo(unpacker, hdiFds, handle);
331         }
332         if (!retVal) {
333             if (handle != nullptr) {
334                 FreeBufferHandle(handle);
335                 handle = nullptr;
336             }
337             HDF_LOGE("%{public}s: buffer handle unpack failed", __func__);
338         }
339         buffer = handle;
340         return retVal ? HDF_SUCCESS : HDF_FAILURE;
341     }
342 
LayerColorUnpack(std::shared_ptr<CommandDataUnpacker> unpacker,LayerColor & layerColor)343     static int32_t LayerColorUnpack(std::shared_ptr<CommandDataUnpacker> unpacker, LayerColor& layerColor)
344     {
345         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.r) == false, HDF_FAILURE,
346             HDF_LOGE("%{public}s, read layerColor.r failed", __func__));
347         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.g) == false, HDF_FAILURE,
348             HDF_LOGE("%{public}s, read layerColor.g failed", __func__));
349         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.b) == false, HDF_FAILURE,
350             HDF_LOGE("%{public}s, read layerColor.b failed", __func__));
351         DISPLAY_CHK_RETURN(unpacker->ReadUint8(layerColor.a) == false, HDF_FAILURE,
352             HDF_LOGE("%{public}s, read layerColor.a failed", __func__));
353         return HDF_SUCCESS;
354     }
355 };
356 using CmdUtils = DisplayCmdUtils;
357 } // namespace V1_0
358 } // namespace Composer
359 } // namespace Display
360 } // namespace HDI
361 } // namespace OHOS
362 #endif // OHOS_HDI_DISPLAY_V1_0_DISPLAY_CMD_UTILS_H