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