1/* 2 * Copyright (c) 2020-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#include "surface_buffer_impl.h" 17#include "securec.h" 18 19namespace OHOS { 20const uint16_t MAX_USER_DATA_COUNT = 1000; 21 22SurfaceBufferImpl::SurfaceBufferImpl() : len_(0) 23{ 24 struct SurfaceBufferData bufferData = {{0}, 0, 0, 0, BUFFER_STATE_NONE, NULL}; 25 bufferData_ = bufferData; 26} 27 28int32_t SurfaceBufferImpl::SetInt32(uint32_t key, int32_t value) 29{ 30 return SetData(key, BUFFER_DATA_TYPE_INT_32, &value, sizeof(value)); 31} 32 33int32_t SurfaceBufferImpl::GetInt32(uint32_t key, int32_t& value) 34{ 35 uint8_t type = BUFFER_DATA_TYPE_NONE; 36 void *data = nullptr; 37 uint8_t size; 38 if (GetData(key, &type, &data, &size) != SURFACE_ERROR_OK || type != BUFFER_DATA_TYPE_INT_32) { 39 return SURFACE_ERROR_INVALID_PARAM; 40 } 41 if (size != sizeof(value)) { 42 return SURFACE_ERROR_INVALID_PARAM; 43 } 44 value = *(reinterpret_cast<int32_t *>(data)); 45 return SURFACE_ERROR_OK; 46} 47 48int32_t SurfaceBufferImpl::SetInt64(uint32_t key, int64_t value) 49{ 50 return SetData(key, BUFFER_DATA_TYPE_INT_64, &value, sizeof(value)); 51} 52 53int32_t SurfaceBufferImpl::GetInt64(uint32_t key, int64_t& value) 54{ 55 uint8_t type = BUFFER_DATA_TYPE_NONE; 56 void *data = nullptr; 57 uint8_t size; 58 if (GetData(key, &type, &data, &size) != SURFACE_ERROR_OK || type != BUFFER_DATA_TYPE_INT_64) { 59 return SURFACE_ERROR_INVALID_PARAM; 60 } 61 if (size != sizeof(value)) { 62 return SURFACE_ERROR_INVALID_PARAM; 63 } 64 value = *(reinterpret_cast<int64_t *>(data)); 65 return SURFACE_ERROR_OK; 66} 67 68int32_t SurfaceBufferImpl::SetData(uint32_t key, uint8_t type, const void* data, uint8_t size) 69{ 70 if (type <= BUFFER_DATA_TYPE_NONE || 71 type >= BUFFER_DATA_TYPE_MAX || 72 size <= 0 || 73 size > sizeof(int64_t)) { 74 GRAPHIC_LOGI("Invalid Param"); 75 return SURFACE_ERROR_INVALID_PARAM; 76 } 77 if (extDatas_.size() > MAX_USER_DATA_COUNT) { 78 GRAPHIC_LOGI("No more data can be saved because the storage space is full."); 79 return SURFACE_ERROR_SYSTEM_ERROR; 80 } 81 ExtraData extData = {0}; 82 std::map<uint32_t, ExtraData>::iterator iter = extDatas_.find(key); 83 if (iter != extDatas_.end()) { 84 extData = iter->second; 85 if (size != extData.size) { 86 free(extData.value); 87 extData.value = nullptr; 88 } 89 } 90 if (extData.value == nullptr) { 91 extData.value = malloc(size); 92 if (extData.value == nullptr) { 93 GRAPHIC_LOGE("Couldn't allocate %zu bytes for ext data", size); 94 return SURFACE_ERROR_SYSTEM_ERROR; 95 } 96 } 97 if (memcpy_s(extData.value, size, data, size) != EOK) { 98 free(extData.value); 99 GRAPHIC_LOGW("Couldn't copy %zu bytes for ext data", size); 100 return SURFACE_ERROR_SYSTEM_ERROR; 101 } 102 extData.size = size; 103 extData.type = type; 104 extDatas_[key] = extData; 105 return SURFACE_ERROR_OK; 106} 107 108int32_t SurfaceBufferImpl::GetData(uint32_t key, uint8_t* type, void** data, uint8_t* size) 109{ 110 if ((type == nullptr) || (data == nullptr) || (size == nullptr)) { 111 return SURFACE_ERROR_INVALID_PARAM; 112 } 113 114 std::map<uint32_t, ExtraData>::iterator iter = extDatas_.find(key); 115 if (iter == extDatas_.end()) { 116 return SURFACE_ERROR_INVALID_PARAM; 117 } 118 ExtraData extData = extDatas_[key]; 119 *data = extData.value; 120 *size = extData.size; 121 *type = extData.type; 122 return SURFACE_ERROR_OK; 123} 124 125void SurfaceBufferImpl::ReadFromIpcIo(IpcIo& io) 126{ 127 ReadInt32(&io, &(bufferData_.handle.key)); 128 ReadUint64(&io, &(bufferData_.handle.phyAddr)); 129 ReadUint32(&io, &(bufferData_.handle.reserveFds)); 130 ReadUint32(&io, &(bufferData_.handle.reserveInts)); 131 ReadUint32(&io, &(bufferData_.size)); 132 ReadUint32(&io, &(bufferData_.usage)); 133 ReadUint32(&io, &len_); 134 uint32_t extDataSize; 135 ReadUint32(&io, &extDataSize); 136 if (extDataSize > 0 && extDataSize < MAX_USER_DATA_COUNT) { 137 for (uint32_t i = 0; i < extDataSize; i++) { 138 uint32_t key; 139 ReadUint32(&io, &key); 140 uint32_t type; 141 ReadUint32(&io, &type); 142 switch (type) { 143 case BUFFER_DATA_TYPE_INT_32: { 144 int32_t value; 145 ReadInt32(&io, &value); 146 SetInt32(key, value); 147 break; 148 } 149 case BUFFER_DATA_TYPE_INT_64: { 150 int64_t value; 151 ReadInt64(&io, &value); 152 SetInt64(key, value); 153 break; 154 } 155 default: 156 break; 157 } 158 } 159 } 160} 161void SurfaceBufferImpl::WriteToIpcIo(IpcIo& io) 162{ 163 WriteInt32(&io, bufferData_.handle.key); 164 WriteUint64(&io, bufferData_.handle.phyAddr); 165 WriteUint32(&io, bufferData_.handle.reserveFds); 166 WriteUint32(&io, bufferData_.handle.reserveInts); 167 WriteUint32(&io, bufferData_.size); 168 WriteUint32(&io, bufferData_.usage); 169 WriteUint32(&io, len_); 170 WriteUint32(&io, extDatas_.size()); 171 if (!extDatas_.empty()) { 172 std::map<uint32_t, ExtraData>::iterator iter; 173 for (iter = extDatas_.begin(); iter != extDatas_.end(); ++iter) { 174 uint32_t key = iter->first; 175 ExtraData value = iter->second; 176 WriteUint32(&io, key); 177 WriteUint32(&io, value.type); 178 switch (value.type) { 179 case BUFFER_DATA_TYPE_INT_32: 180 WriteInt32(&io, *(reinterpret_cast<int32_t *>(value.value))); 181 break; 182 case BUFFER_DATA_TYPE_INT_64: 183 WriteInt64(&io, *(reinterpret_cast<int64_t *>(value.value))); 184 break; 185 default: 186 break; 187 } 188 } 189 } 190} 191 192void SurfaceBufferImpl::CopyExtraData(SurfaceBufferImpl& buffer) 193{ 194 len_ = buffer.len_; 195 extDatas_ = buffer.extDatas_; 196 buffer.extDatas_.clear(); 197} 198 199void SurfaceBufferImpl::ClearExtraData() 200{ 201 if (!extDatas_.empty()) { 202 std::map<uint32_t, ExtraData>::iterator iter; 203 for (iter = extDatas_.begin(); iter != extDatas_.end(); ++iter) { 204 ExtraData value = iter->second; 205 free(value.value); 206 value.value = nullptr; 207 } 208 extDatas_.clear(); 209 } 210} 211 212SurfaceBufferImpl::~SurfaceBufferImpl() 213{ 214 ClearExtraData(); 215 struct SurfaceBufferData bufferData = {{0}, 0, 0, 0, BUFFER_STATE_NONE, NULL}; 216 bufferData_ = bufferData; 217} 218} 219