1/* 2 * Copyright (c) 2023-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#include "light_lux_buffer.h" 17 18#include <cerrno> 19#include <cstdlib> 20#include <new> 21#include <string> 22#include <securec.h> 23#include <securectype.h> 24 25#include "display_log.h" 26 27namespace OHOS { 28namespace DisplayPowerMgr { 29 30namespace { 31const unsigned int BUFFER_SIZE_INCREASE = 2; 32const unsigned int LUX_BUFFER_SIZE_MAX = 512; 33} 34 35LightLuxBuffer::LightLuxBuffer(unsigned int initialCapacity) 36{ 37 if (initialCapacity == 0 || initialCapacity >= LUX_BUFFER_SIZE_MAX) { 38 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "initialCapacity=%{public}d out of range, Reset to %{public}d", 39 initialCapacity, LUX_BUFFER_SIZE_DEFAULT); 40 mCapacity = LUX_BUFFER_SIZE_DEFAULT; 41 } else { 42 mCapacity = initialCapacity; 43 } 44} 45 46LightLuxBuffer::~LightLuxBuffer() 47{ 48 if (mBufferData != nullptr) { 49 delete[] mBufferData; 50 mBufferData = nullptr; 51 } 52 53 if (mBufferTime != nullptr) { 54 delete[] mBufferTime; 55 mBufferTime = nullptr; 56 } 57} 58 59int LightLuxBuffer::LuxBufferCheck() 60{ 61 if (mBufferData == nullptr) { 62 mBufferData = new(std::nothrow) float[mCapacity]; 63 if (mBufferData == nullptr) { 64 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "new mBufferData failed!"); 65 return -1; 66 } 67 } 68 if (mBufferTime == nullptr) { 69 mBufferTime = new(std::nothrow) int64_t[mCapacity]; 70 if (mBufferTime == nullptr) { 71 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "new mBufferTime failed!"); 72 delete[] mBufferData; 73 mBufferData = nullptr; 74 return -1; 75 } 76 } 77 return 0; 78} 79 80int LightLuxBuffer::CopyLuxBuffer(int newSize) 81{ 82 auto newBufferData = new(std::nothrow) float[newSize]; 83 if (newBufferData == nullptr) { 84 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "newBufferData id null"); 85 return -1; 86 } 87 auto newBufferTime = new(std::nothrow) int64_t[newSize]; 88 if (newBufferTime == nullptr) { 89 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "newBufferTime id null"); 90 delete[] newBufferData; 91 return -1; 92 } 93 unsigned int length = mCapacity - mStart; 94 bool isError = false; 95 isError = isError || (memcpy_s(newBufferData, newSize * sizeof(newBufferData[0]), 96 mBufferData + mStart, length * sizeof(mBufferData[0])) != EOK); 97 isError = isError || (memcpy_s(newBufferTime, newSize * sizeof(newBufferTime[0]), 98 mBufferTime + mStart, length * sizeof(mBufferTime[0])) != EOK); 99 if (mStart != 0) { 100 isError = isError || (memcpy_s(newBufferData + length, (newSize - length) * sizeof(newBufferData[0]), 101 mBufferData, mStart * sizeof(mBufferData[0])) != EOK); 102 isError = isError || (memcpy_s(newBufferTime + length, (newSize - length) * sizeof(newBufferTime[0]), 103 mBufferTime, mStart * sizeof(mBufferTime[0])) != EOK); 104 } 105 if (isError) { 106 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "memcpy_s error, mCapacity=%{public}d, mStart=%{public}d", mCapacity, mStart); 107 delete[] newBufferData; 108 delete[] newBufferTime; 109 return -1; 110 } 111 delete[] mBufferData; 112 mBufferData = newBufferData; 113 delete[] mBufferTime; 114 mBufferTime = newBufferTime; 115 116 return 0; 117} 118 119void LightLuxBuffer::Push(const int64_t timestamp, const float data) 120{ 121 if (LuxBufferCheck() != 0) { 122 return; 123 } 124 125 unsigned int next = mEnd; 126 if (mCount == mCapacity) { 127 unsigned long newSize = mCapacity * static_cast<unsigned long>(BUFFER_SIZE_INCREASE); 128 if (newSize > static_cast<unsigned long>(LUX_BUFFER_SIZE_MAX)) { 129 DISPLAY_HILOGW(FEAT_BRIGHTNESS, "buffer size larger than max value %{public}d already, stop expand", 130 LUX_BUFFER_SIZE_MAX); 131 return; 132 } 133 if (mStart >= mCapacity) { 134 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mStart error! mStart(%{public}d) >= mCapacity(%{public}d)", 135 mStart, mCapacity); 136 return; 137 } 138 139 if (CopyLuxBuffer(newSize) != 0) { 140 return; 141 } 142 143 next = mCapacity; 144 mCapacity = static_cast<unsigned int>(newSize); 145 mStart = 0; 146 } 147 148 if (mBufferTime != nullptr) { 149 mBufferTime[next] = timestamp; 150 } 151 152 if (mBufferData != nullptr) { 153 mBufferData[next] = data; 154 } 155 156 mEnd = next + 1; 157 if (mEnd == mCapacity) { 158 mEnd = 0; 159 } 160 mCount++; 161} 162 163void LightLuxBuffer::Prune(const int64_t horizon) 164{ 165 if (mCount == 0 || mBufferTime == nullptr) { 166 return; 167 } 168 169 while (mCount > 1) { 170 unsigned int next = mStart + 1; 171 if (next >= mCapacity) { 172 next -= mCapacity; 173 } 174 if (mBufferTime[next] > horizon) { 175 break; 176 } 177 mStart = next; 178 mCount--; 179 } 180 if (mBufferTime[mStart] < horizon) { 181 mBufferTime[mStart] = horizon; 182 } 183} 184 185void LightLuxBuffer::Clear() 186{ 187 mStart = 0; 188 mEnd = 0; 189 mCount = 0; 190} 191 192float LightLuxBuffer::GetData(const unsigned int index) const 193{ 194 if (mBufferData == nullptr) { 195 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mBufferData is nullptr."); 196 return 0; 197 } 198 if (index >= mCount) { 199 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "error! index = %{public}d, out of range mCount = %{public}d", index, mCount); 200 return 0; 201 } 202 return mBufferData[OffsetOf(index)]; 203} 204 205int64_t LightLuxBuffer::GetTime(const unsigned int index) const 206{ 207 if (mBufferTime == nullptr) { 208 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "mBufferTime is nullptr"); 209 return 0; 210 } 211 212 if (index >= mCount) { 213 DISPLAY_HILOGE(FEAT_BRIGHTNESS, "error! index = %{public}d, out of range mCount = %{public}d", index, mCount); 214 return 0; 215 } 216 return mBufferTime[OffsetOf(index)]; 217} 218 219unsigned int LightLuxBuffer::GetSize() const 220{ 221 return mCount; 222} 223 224unsigned int LightLuxBuffer::OffsetOf(const unsigned int index) const 225{ 226 unsigned actualIndex = index + mStart; 227 if (actualIndex >= mCapacity) { 228 actualIndex -= mCapacity; 229 } 230 return actualIndex; 231} 232 233std::string LightLuxBuffer::ToString(unsigned int n) 234{ 235 std::ostringstream result; 236 if (n > mCount) { 237 n = mCount; 238 } 239 result << "["; 240 for (unsigned int i = mCount-n; i>=0 && i < mCount;i++) { 241 result << GetData(i); 242 result << "/"; 243 result << GetTime(i); 244 result << ", "; 245 } 246 result << "]"; 247 return result.str(); 248} 249} // namespace DisplayPowerMgr 250} // namespace OHOS