1 /*
2  * Copyright (c) 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 "font/font_ram_allocator.h"
17 #include "font/ui_font_header.h"
18 
19 namespace OHOS {
FontRamAllocator()20 FontRamAllocator::FontRamAllocator() : ramAddr_(0), ramLen_(0), currentRamAddr_(0), dynamicAddr_(0) {}
~FontRamAllocator()21 FontRamAllocator::~FontRamAllocator() {}
22 
SetRamAddr(uintptr_t ramAddr,uint32_t ramLen)23 void FontRamAllocator::SetRamAddr(uintptr_t ramAddr, uint32_t ramLen)
24 {
25     if (ramAddr_ != 0) {
26         return;
27     }
28 
29     ramAddr_ = ramAddr;
30     ramLen_ = ramLen;
31     if (!IsAligned(ramAddr)) {
32         currentRamAddr_ = AlignUp(ramAddr);
33     } else {
34         currentRamAddr_ = ramAddr;
35     }
36 }
37 
Allocate(uint32_t size)38 void* FontRamAllocator::Allocate(uint32_t size)
39 {
40     if ((ramAddr_ == 0) || (size == 0)) {
41         return nullptr;
42     }
43 
44     if (!IsAligned(size)) {
45         size = AlignUp(size);
46     }
47 
48     if ((size + currentRamAddr_) > (ramAddr_ + ramLen_)) {
49         return nullptr;
50     }
51 
52     void* addr = reinterpret_cast<void *>(currentRamAddr_);
53     currentRamAddr_ += size;
54     return addr;
55 }
56 
GetRamUsedLen()57 uint32_t FontRamAllocator::GetRamUsedLen()
58 {
59     return (currentRamAddr_ - ramAddr_);
60 }
61 
ClearRam()62 void FontRamAllocator::ClearRam()
63 {
64     if (dynamicAddr_) {
65         currentRamAddr_ = dynamicAddr_;
66         dynamicAddr_ = 0;
67         allocator_.SetRamAddr(0, 0);
68     }
69 }
70 
DynamicAllocate(uint32_t size)71 void* FontRamAllocator::DynamicAllocate(uint32_t size)
72 {
73     if (!dynamicAddr_) {
74         dynamicAddr_ = currentRamAddr_;
75         allocator_.SetRamAddr(reinterpret_cast<uint8_t*>(dynamicAddr_), ramLen_ - dynamicAddr_ + ramAddr_);
76         allocator_.SetMinChunkSize(4); // 4: min align size
77         currentRamAddr_ = ramAddr_ + ramLen_;
78     }
79 
80     return allocator_.Allocate(size);
81 }
82 
DynamicFree(void * addr)83 void FontRamAllocator::DynamicFree(void* addr)
84 {
85     return allocator_.Free(addr);
86 }
87 
GetMemSize(void * addr)88 uint32_t FontRamAllocator::GetMemSize(void* addr)
89 {
90     return allocator_.GetSize(addr);
91 }
92 
AlignUp(uint32_t addr)93 uint32_t FontRamAllocator::AlignUp(uint32_t addr)
94 {
95     return (((addr + (1 << RAM_ALIGN)) >> RAM_ALIGN) << RAM_ALIGN);
96 }
97 
IsAligned(uint32_t addr)98 bool FontRamAllocator::IsAligned(uint32_t addr)
99 {
100     return ((addr % (1 << RAM_ALIGN)) == 0);
101 }
102 } // namespace OHOS
103