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