1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "imgdecode/cache_manager.h" 17a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h" 18a3e0fd82Sopenharmony_ci#include "hal_tick.h" 19a3e0fd82Sopenharmony_ci#include "securec.h" 20a3e0fd82Sopenharmony_ci 21a3e0fd82Sopenharmony_cinamespace OHOS { 22a3e0fd82Sopenharmony_ciconst uint8_t* CacheEntry::GetImgData() const 23a3e0fd82Sopenharmony_ci{ 24a3e0fd82Sopenharmony_ci return dsc_.imgInfo.data; 25a3e0fd82Sopenharmony_ci} 26a3e0fd82Sopenharmony_ci 27a3e0fd82Sopenharmony_ciRetCode CacheEntry::ReadLine(const Point& start, int16_t len, uint8_t* buf) 28a3e0fd82Sopenharmony_ci{ 29a3e0fd82Sopenharmony_ci RetCode ret; 30a3e0fd82Sopenharmony_ci if (dsc_.decoder != nullptr) { 31a3e0fd82Sopenharmony_ci ret = dsc_.decoder->ReadLine(dsc_, start, len, buf); 32a3e0fd82Sopenharmony_ci } else { 33a3e0fd82Sopenharmony_ci ret = RetCode::FAIL; 34a3e0fd82Sopenharmony_ci } 35a3e0fd82Sopenharmony_ci 36a3e0fd82Sopenharmony_ci return ret; 37a3e0fd82Sopenharmony_ci} 38a3e0fd82Sopenharmony_ci 39a3e0fd82Sopenharmony_civoid CacheEntry::Clear() 40a3e0fd82Sopenharmony_ci{ 41a3e0fd82Sopenharmony_ci if (dsc_.decoder != nullptr) { 42a3e0fd82Sopenharmony_ci dsc_.decoder->Close(dsc_); 43a3e0fd82Sopenharmony_ci } 44a3e0fd82Sopenharmony_ci 45a3e0fd82Sopenharmony_ci dsc_.decoder = nullptr; 46a3e0fd82Sopenharmony_ci ClearSrc(); 47a3e0fd82Sopenharmony_ci dsc_.imgInfo.data = nullptr; 48a3e0fd82Sopenharmony_ci dsc_.fd = -1; 49a3e0fd82Sopenharmony_ci dsc_.srcType = IMG_SRC_UNKNOWN; 50a3e0fd82Sopenharmony_ci life_ = 0; 51a3e0fd82Sopenharmony_ci} 52a3e0fd82Sopenharmony_ci 53a3e0fd82Sopenharmony_civoid CacheEntry::ClearSrc() 54a3e0fd82Sopenharmony_ci{ 55a3e0fd82Sopenharmony_ci if (dsc_.srcType == IMG_SRC_FILE) { 56a3e0fd82Sopenharmony_ci UIFree(const_cast<char*>(dsc_.path)); 57a3e0fd82Sopenharmony_ci } 58a3e0fd82Sopenharmony_ci dsc_.path = nullptr; 59a3e0fd82Sopenharmony_ci} 60a3e0fd82Sopenharmony_ci 61a3e0fd82Sopenharmony_ciRetCode CacheEntry::SetSrc(const char* path) 62a3e0fd82Sopenharmony_ci{ 63a3e0fd82Sopenharmony_ci ClearSrc(); 64a3e0fd82Sopenharmony_ci if (dsc_.srcType == IMG_SRC_FILE) { 65a3e0fd82Sopenharmony_ci size_t strLen = strlen(path); 66a3e0fd82Sopenharmony_ci if (strLen > MAX_SRC_LENGTH) { 67a3e0fd82Sopenharmony_ci return RetCode::FAIL; 68a3e0fd82Sopenharmony_ci } 69a3e0fd82Sopenharmony_ci char* newStr = static_cast<char*>(UIMalloc(static_cast<uint32_t>(strLen) + 1)); 70a3e0fd82Sopenharmony_ci if (newStr == nullptr) { 71a3e0fd82Sopenharmony_ci return RetCode::FAIL; 72a3e0fd82Sopenharmony_ci } 73a3e0fd82Sopenharmony_ci if (memcpy_s(newStr, strLen + 1, path, strLen) != EOK) { 74a3e0fd82Sopenharmony_ci UIFree(reinterpret_cast<void*>(newStr)); 75a3e0fd82Sopenharmony_ci newStr = nullptr; 76a3e0fd82Sopenharmony_ci return RetCode::FAIL; 77a3e0fd82Sopenharmony_ci } 78a3e0fd82Sopenharmony_ci newStr[strLen] = '\0'; 79a3e0fd82Sopenharmony_ci dsc_.path = newStr; 80a3e0fd82Sopenharmony_ci } else { 81a3e0fd82Sopenharmony_ci dsc_.path = path; 82a3e0fd82Sopenharmony_ci } 83a3e0fd82Sopenharmony_ci return RetCode::OK; 84a3e0fd82Sopenharmony_ci} 85a3e0fd82Sopenharmony_ci 86a3e0fd82Sopenharmony_ciCacheManager& CacheManager::GetInstance() 87a3e0fd82Sopenharmony_ci{ 88a3e0fd82Sopenharmony_ci static CacheManager instance; 89a3e0fd82Sopenharmony_ci return instance; 90a3e0fd82Sopenharmony_ci} 91a3e0fd82Sopenharmony_ci 92a3e0fd82Sopenharmony_ciRetCode CacheManager::Init(uint16_t size) 93a3e0fd82Sopenharmony_ci{ 94a3e0fd82Sopenharmony_ci if ((size == 0) || (size > DEFAULT_MAX_CACHE_ENTRY_NUM)) { 95a3e0fd82Sopenharmony_ci return RetCode::FAIL; 96a3e0fd82Sopenharmony_ci } 97a3e0fd82Sopenharmony_ci Reset(); 98a3e0fd82Sopenharmony_ci if (entryArr_ != nullptr) { 99a3e0fd82Sopenharmony_ci UIFree(reinterpret_cast<void*>(entryArr_)); 100a3e0fd82Sopenharmony_ci } 101a3e0fd82Sopenharmony_ci 102a3e0fd82Sopenharmony_ci uint32_t tmpCacheSize = size * sizeof(CacheEntry); 103a3e0fd82Sopenharmony_ci entryArr_ = static_cast<CacheEntry*>(UIMalloc(tmpCacheSize)); 104a3e0fd82Sopenharmony_ci if (entryArr_ == nullptr) { 105a3e0fd82Sopenharmony_ci size_ = 0; 106a3e0fd82Sopenharmony_ci return RetCode::FAIL; 107a3e0fd82Sopenharmony_ci } 108a3e0fd82Sopenharmony_ci 109a3e0fd82Sopenharmony_ci if (memset_s(entryArr_, tmpCacheSize, 0, tmpCacheSize) != EOK) { 110a3e0fd82Sopenharmony_ci UIFree(reinterpret_cast<void*>(entryArr_)); 111a3e0fd82Sopenharmony_ci entryArr_ = nullptr; 112a3e0fd82Sopenharmony_ci return RetCode::FAIL; 113a3e0fd82Sopenharmony_ci } 114a3e0fd82Sopenharmony_ci 115a3e0fd82Sopenharmony_ci size_ = size; 116a3e0fd82Sopenharmony_ci return RetCode::OK; 117a3e0fd82Sopenharmony_ci} 118a3e0fd82Sopenharmony_ci 119a3e0fd82Sopenharmony_ciRetCode CacheManager::Open(const char* path, const Style& style, CacheEntry& entry) 120a3e0fd82Sopenharmony_ci{ 121a3e0fd82Sopenharmony_ci if ((path == nullptr) || (GetSize() <= 0)) { 122a3e0fd82Sopenharmony_ci return RetCode::FAIL; 123a3e0fd82Sopenharmony_ci } 124a3e0fd82Sopenharmony_ci 125a3e0fd82Sopenharmony_ci AgingAll(); 126a3e0fd82Sopenharmony_ci uint16_t indexHitted = 0; 127a3e0fd82Sopenharmony_ci RetCode ret = GetIndex(path, indexHitted); 128a3e0fd82Sopenharmony_ci if (ret == RetCode::OK) { 129a3e0fd82Sopenharmony_ci ReadToCache(entryArr_[indexHitted]); 130a3e0fd82Sopenharmony_ci entry = entryArr_[indexHitted]; 131a3e0fd82Sopenharmony_ci return RetCode::OK; 132a3e0fd82Sopenharmony_ci } 133a3e0fd82Sopenharmony_ci 134a3e0fd82Sopenharmony_ci SelectEntryToReplace(indexHitted); 135a3e0fd82Sopenharmony_ci if ((entryArr_[indexHitted].dsc_.path != nullptr) && (entryArr_[indexHitted].dsc_.decoder != nullptr)) { 136a3e0fd82Sopenharmony_ci entryArr_[indexHitted].dsc_.decoder->Close(entryArr_[indexHitted].dsc_); 137a3e0fd82Sopenharmony_ci } 138a3e0fd82Sopenharmony_ci 139a3e0fd82Sopenharmony_ci uint32_t startTime = HALTick::GetInstance().GetTime(); 140a3e0fd82Sopenharmony_ci entryArr_[indexHitted].life_ = 0; 141a3e0fd82Sopenharmony_ci 142a3e0fd82Sopenharmony_ci ret = TryDecode(path, style, entryArr_[indexHitted]); 143a3e0fd82Sopenharmony_ci if (ret != RetCode::OK) { 144a3e0fd82Sopenharmony_ci return ret; 145a3e0fd82Sopenharmony_ci } 146a3e0fd82Sopenharmony_ci ReadToCache(entryArr_[indexHitted]); 147a3e0fd82Sopenharmony_ci entryArr_[indexHitted].life_ = HALTick::GetInstance().GetElapseTime(startTime); 148a3e0fd82Sopenharmony_ci entry = entryArr_[indexHitted]; 149a3e0fd82Sopenharmony_ci return RetCode::OK; 150a3e0fd82Sopenharmony_ci} 151a3e0fd82Sopenharmony_ci 152a3e0fd82Sopenharmony_ciRetCode CacheManager::Close(const char* path) 153a3e0fd82Sopenharmony_ci{ 154a3e0fd82Sopenharmony_ci if (path == nullptr) { 155a3e0fd82Sopenharmony_ci return RetCode::FAIL; 156a3e0fd82Sopenharmony_ci } 157a3e0fd82Sopenharmony_ci 158a3e0fd82Sopenharmony_ci for (uint16_t index = 0; index < GetSize(); index++) { 159a3e0fd82Sopenharmony_ci if (entryArr_[index].dsc_.srcType == IMG_SRC_FILE) { 160a3e0fd82Sopenharmony_ci if (entryArr_[index].dsc_.path == nullptr) { 161a3e0fd82Sopenharmony_ci continue; 162a3e0fd82Sopenharmony_ci } 163a3e0fd82Sopenharmony_ci if (strcmp(entryArr_[index].dsc_.path, path) == 0) { 164a3e0fd82Sopenharmony_ci Clear(entryArr_[index]); 165a3e0fd82Sopenharmony_ci break; 166a3e0fd82Sopenharmony_ci } 167a3e0fd82Sopenharmony_ci } else { 168a3e0fd82Sopenharmony_ci if (entryArr_[index].dsc_.path == path) { 169a3e0fd82Sopenharmony_ci Clear(entryArr_[index]); 170a3e0fd82Sopenharmony_ci break; 171a3e0fd82Sopenharmony_ci } 172a3e0fd82Sopenharmony_ci } 173a3e0fd82Sopenharmony_ci } 174a3e0fd82Sopenharmony_ci 175a3e0fd82Sopenharmony_ci return RetCode::OK; 176a3e0fd82Sopenharmony_ci} 177a3e0fd82Sopenharmony_ci 178a3e0fd82Sopenharmony_cibool CacheManager::GetImageHeader(const char* path, ImageHeader& header) 179a3e0fd82Sopenharmony_ci{ 180a3e0fd82Sopenharmony_ci CacheEntry entry; 181a3e0fd82Sopenharmony_ci Style useless; 182a3e0fd82Sopenharmony_ci RetCode ret = Open(path, useless, entry); 183a3e0fd82Sopenharmony_ci if (ret != RetCode::OK) { 184a3e0fd82Sopenharmony_ci GRAPHIC_LOGW("CacheManager::GetImageHeader Image get info found unknown src type\n"); 185a3e0fd82Sopenharmony_ci return false; 186a3e0fd82Sopenharmony_ci } 187a3e0fd82Sopenharmony_ci 188a3e0fd82Sopenharmony_ci header = entry.GetImgHeader(); 189a3e0fd82Sopenharmony_ci return true; 190a3e0fd82Sopenharmony_ci} 191a3e0fd82Sopenharmony_ci 192a3e0fd82Sopenharmony_ciRetCode CacheManager::Reset() 193a3e0fd82Sopenharmony_ci{ 194a3e0fd82Sopenharmony_ci if (entryArr_ == nullptr) { 195a3e0fd82Sopenharmony_ci return RetCode::OK; 196a3e0fd82Sopenharmony_ci } 197a3e0fd82Sopenharmony_ci 198a3e0fd82Sopenharmony_ci for (uint16_t index = 0; index < GetSize(); index++) { 199a3e0fd82Sopenharmony_ci if (entryArr_[index].dsc_.path != nullptr) { 200a3e0fd82Sopenharmony_ci Clear(entryArr_[index]); 201a3e0fd82Sopenharmony_ci } 202a3e0fd82Sopenharmony_ci } 203a3e0fd82Sopenharmony_ci 204a3e0fd82Sopenharmony_ci return RetCode::OK; 205a3e0fd82Sopenharmony_ci} 206a3e0fd82Sopenharmony_ci 207a3e0fd82Sopenharmony_ciRetCode CacheManager::ReadToCache(CacheEntry& entry) 208a3e0fd82Sopenharmony_ci{ 209a3e0fd82Sopenharmony_ci if (entry.dsc_.decoder == nullptr) { 210a3e0fd82Sopenharmony_ci return RetCode::FAIL; 211a3e0fd82Sopenharmony_ci } 212a3e0fd82Sopenharmony_ci return entry.dsc_.decoder->ReadToCache(entry.dsc_); 213a3e0fd82Sopenharmony_ci} 214a3e0fd82Sopenharmony_ci 215a3e0fd82Sopenharmony_civoid CacheManager::Clear(CacheEntry& entry) 216a3e0fd82Sopenharmony_ci{ 217a3e0fd82Sopenharmony_ci entry.Clear(); 218a3e0fd82Sopenharmony_ci} 219a3e0fd82Sopenharmony_ci 220a3e0fd82Sopenharmony_civoid CacheManager::AgingAll(int32_t time) 221a3e0fd82Sopenharmony_ci{ 222a3e0fd82Sopenharmony_ci for (uint16_t index = 0; index < GetSize(); index++) { 223a3e0fd82Sopenharmony_ci if (entryArr_[index].life_ > INT32_MIN + AGING_INTERVAL) { 224a3e0fd82Sopenharmony_ci entryArr_[index].life_ -= time; 225a3e0fd82Sopenharmony_ci } 226a3e0fd82Sopenharmony_ci } 227a3e0fd82Sopenharmony_ci} 228a3e0fd82Sopenharmony_ci 229a3e0fd82Sopenharmony_ciRetCode CacheManager::GetIndex(const char* path, uint16_t& hittedIndex) 230a3e0fd82Sopenharmony_ci{ 231a3e0fd82Sopenharmony_ci for (uint16_t index = 0; index < GetSize(); index++) { 232a3e0fd82Sopenharmony_ci if (entryArr_[index].dsc_.srcType == IMG_SRC_FILE) { 233a3e0fd82Sopenharmony_ci if ((entryArr_[index].dsc_.path != nullptr) && !strcmp(path, entryArr_[index].dsc_.path)) { 234a3e0fd82Sopenharmony_ci entryArr_[index].life_ += entryArr_[index].dsc_.timeToOpen * LIFE_GAIN_INTERVAL; 235a3e0fd82Sopenharmony_ci if (entryArr_[index].life_ > LIFE_LIMIT) { 236a3e0fd82Sopenharmony_ci entryArr_[index].life_ = LIFE_LIMIT; 237a3e0fd82Sopenharmony_ci } 238a3e0fd82Sopenharmony_ci hittedIndex = index; 239a3e0fd82Sopenharmony_ci return RetCode::OK; 240a3e0fd82Sopenharmony_ci } 241a3e0fd82Sopenharmony_ci } else { 242a3e0fd82Sopenharmony_ci ImageInfo* imgDsc = reinterpret_cast<ImageInfo*>(const_cast<char*>(path)); 243a3e0fd82Sopenharmony_ci if ((entryArr_[index].dsc_.path == path) && (entryArr_[index].dsc_.imgInfo.data == imgDsc->data)) { 244a3e0fd82Sopenharmony_ci entryArr_[index].life_ += entryArr_[index].dsc_.timeToOpen * LIFE_GAIN_INTERVAL; 245a3e0fd82Sopenharmony_ci if (entryArr_[index].life_ > LIFE_LIMIT) { 246a3e0fd82Sopenharmony_ci entryArr_[index].life_ = LIFE_LIMIT; 247a3e0fd82Sopenharmony_ci } 248a3e0fd82Sopenharmony_ci hittedIndex = index; 249a3e0fd82Sopenharmony_ci return RetCode::OK; 250a3e0fd82Sopenharmony_ci } 251a3e0fd82Sopenharmony_ci } 252a3e0fd82Sopenharmony_ci } 253a3e0fd82Sopenharmony_ci 254a3e0fd82Sopenharmony_ci return RetCode::FAIL; 255a3e0fd82Sopenharmony_ci} 256a3e0fd82Sopenharmony_ci 257a3e0fd82Sopenharmony_ciRetCode CacheManager::SelectEntryToReplace(uint16_t& selectedIndex) 258a3e0fd82Sopenharmony_ci{ 259a3e0fd82Sopenharmony_ci selectedIndex = 0; 260a3e0fd82Sopenharmony_ci for (uint16_t index = 0; index < GetSize(); index++) { 261a3e0fd82Sopenharmony_ci if (entryArr_[index].life_ < entryArr_[selectedIndex].life_) { 262a3e0fd82Sopenharmony_ci selectedIndex = index; 263a3e0fd82Sopenharmony_ci } 264a3e0fd82Sopenharmony_ci } 265a3e0fd82Sopenharmony_ci 266a3e0fd82Sopenharmony_ci return RetCode::OK; 267a3e0fd82Sopenharmony_ci} 268a3e0fd82Sopenharmony_ci 269a3e0fd82Sopenharmony_ciRetCode CacheManager::TryDecode(const char* path, const Style& style, CacheEntry& entry) 270a3e0fd82Sopenharmony_ci{ 271a3e0fd82Sopenharmony_ci FileImgDecoder* decoder = &(FileImgDecoder::GetInstance()); 272a3e0fd82Sopenharmony_ci if (decoder == nullptr) { 273a3e0fd82Sopenharmony_ci Clear(entry); 274a3e0fd82Sopenharmony_ci return RetCode::FAIL; 275a3e0fd82Sopenharmony_ci } 276a3e0fd82Sopenharmony_ci 277a3e0fd82Sopenharmony_ci entry.dsc_.srcType = IMG_SRC_FILE; 278a3e0fd82Sopenharmony_ci RetCode ret = entry.SetSrc(path); 279a3e0fd82Sopenharmony_ci if (ret != RetCode::OK) { 280a3e0fd82Sopenharmony_ci Clear(entry); 281a3e0fd82Sopenharmony_ci return ret; 282a3e0fd82Sopenharmony_ci } 283a3e0fd82Sopenharmony_ci entry.dsc_.decoder = decoder; 284a3e0fd82Sopenharmony_ci 285a3e0fd82Sopenharmony_ci ret = entry.dsc_.decoder->GetHeader(entry.dsc_); 286a3e0fd82Sopenharmony_ci if (ret != RetCode::OK) { 287a3e0fd82Sopenharmony_ci Clear(entry); 288a3e0fd82Sopenharmony_ci return ret; 289a3e0fd82Sopenharmony_ci } 290a3e0fd82Sopenharmony_ci 291a3e0fd82Sopenharmony_ci ret = entry.dsc_.decoder->Open(entry.dsc_); 292a3e0fd82Sopenharmony_ci if (ret != RetCode::OK) { 293a3e0fd82Sopenharmony_ci Clear(entry); 294a3e0fd82Sopenharmony_ci return ret; 295a3e0fd82Sopenharmony_ci } 296a3e0fd82Sopenharmony_ci 297a3e0fd82Sopenharmony_ci return ret; 298a3e0fd82Sopenharmony_ci} 299a3e0fd82Sopenharmony_ci} // namespace OHOS 300