• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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/ui_font_allocator.h"
17 
18 namespace OHOS {
UIFontAllocator()19 UIFontAllocator::UIFontAllocator() : ram_(nullptr), ramSize_(0), freeSize_(0),
20     minSize_(0), end_(nullptr), free_(nullptr) {}
21 
~UIFontAllocator()22 UIFontAllocator::~UIFontAllocator() {}
23 
SetRamAddr(uint8_t * ram,uint32_t size)24 void UIFontAllocator::SetRamAddr(uint8_t* ram, uint32_t size)
25 {
26     struct Chunk* chunk = nullptr;
27 
28     ram_ = ram;
29     ramSize_ = size - sizeof(struct Chunk) * 2; // head and tail two chunk
30     chunk = reinterpret_cast<struct Chunk*>(ram_);
31     chunk->next = size - sizeof(struct Chunk);
32     chunk->prev = 0;
33     chunk->used = false;
34 
35     end_ = reinterpret_cast<struct Chunk*>(ram_ + size - sizeof(struct Chunk));
36     end_->next = size - sizeof(struct Chunk);
37     end_->prev = size - sizeof(struct Chunk);
38     end_->used = true;
39 
40     free_ = chunk;
41     freeSize_ = size - sizeof(struct Chunk);
42 }
43 
GetSize(void * addr)44 uint32_t UIFontAllocator::GetSize(void *addr)
45 {
46     struct Chunk *chunk = reinterpret_cast<struct Chunk*>(static_cast<uint8_t*>(addr) - sizeof(struct Chunk));
47     return chunk->next - (reinterpret_cast<uint8_t*>(addr) - reinterpret_cast<uint8_t*>(ram_));
48 }
49 
SetMinChunkSize(uint32_t size)50 void UIFontAllocator::SetMinChunkSize(uint32_t size)
51 {
52     minSize_ = AlignSize(size);
53 }
54 
Allocate(uint32_t size)55 void* UIFontAllocator::Allocate(uint32_t size)
56 {
57     uint32_t free, left;
58     uint32_t ptr, ptr2;
59     struct Chunk* chunk = nullptr;
60     struct Chunk* chunk2 = nullptr;
61     struct Chunk* chunk3 = nullptr;
62 
63     size = AlignSize(size);
64     if (size < minSize_) {
65         size = minSize_;
66     }
67 
68     for (ptr = reinterpret_cast<uint8_t*>(free_) - ram_; ptr < ramSize_;
69          ptr = reinterpret_cast<struct Chunk*>(ram_ + ptr)->next) {
70         chunk = reinterpret_cast<struct Chunk*>(ram_ + ptr);
71         if (chunk->used) {
72             continue;
73         }
74         free = chunk->next - ptr;
75         if (free < sizeof(struct Chunk) + size) {
76             continue;
77         }
78         left = free - sizeof(struct Chunk) - size;
79         if (left >= sizeof(struct Chunk) + minSize_) {
80             ptr2 = ptr + sizeof(struct Chunk) + size;
81             chunk2 = reinterpret_cast<struct Chunk*>(ram_ + ptr2);
82             chunk2->used = false;
83             chunk2->next = chunk->next;
84             chunk2->prev = ptr;
85             chunk->next = ptr2;
86             chunk->used = true;
87             if (chunk2->next != end_->next) {
88                 chunk3 = reinterpret_cast<struct Chunk*>(ram_ + chunk2->next);
89                 chunk3->prev = ptr2;
90             }
91             freeSize_ -= size + sizeof(struct Chunk);
92         } else {
93             chunk->used = true;
94             freeSize_ -= chunk->next - ptr;
95         }
96 
97         if (chunk == free_) {
98             struct Chunk* cur = free_;
99             while (cur->used && (cur != end_)) {
100                 cur = reinterpret_cast<struct Chunk*>(ram_ + cur->next);
101             }
102             free_ = cur;
103         }
104 
105         return reinterpret_cast<uint8_t*>(chunk) + sizeof(struct Chunk);
106     }
107 
108     return nullptr;
109 }
110 
CombineFree(struct Chunk * chunk)111 void UIFontAllocator::CombineFree(struct Chunk* chunk)
112 {
113     if (chunk == nullptr) {
114         return;
115     }
116     struct Chunk* nextChunk = nullptr;
117     struct Chunk* prevChunk = nullptr;
118 
119     nextChunk = reinterpret_cast<struct Chunk*>(ram_ + chunk->next);
120     if (((nextChunk != chunk) && !(nextChunk->used)) && (nextChunk != end_)) {
121         if (free_ == nextChunk) {
122             free_ = chunk;
123         }
124         chunk->next = nextChunk->next;
125         reinterpret_cast<struct Chunk*>(ram_ + nextChunk->next)->prev = reinterpret_cast<uint8_t*>(chunk) - ram_;
126     }
127 
128     prevChunk = reinterpret_cast<struct Chunk*>(ram_ + chunk->prev);
129     if ((prevChunk != chunk) && !(prevChunk->used)) {
130         if (free_ == chunk) {
131             free_ = prevChunk;
132         }
133         prevChunk->next = chunk->next;
134         reinterpret_cast<struct Chunk*>(ram_ + chunk->next)->prev = reinterpret_cast<uint8_t*>(prevChunk) - ram_;
135     }
136 }
137 
Free(void * addr)138 void UIFontAllocator::Free(void* addr)
139 {
140     struct Chunk* chunk = nullptr;
141 
142     if (addr == nullptr) {
143         return;
144     }
145 
146     if ((reinterpret_cast<uint8_t*>(addr) < ram_) ||
147         (reinterpret_cast<uint8_t*>(addr) > reinterpret_cast<uint8_t*>(end_))) {
148         return;
149     }
150 
151     chunk = reinterpret_cast<struct Chunk*>(static_cast<uint8_t*>(addr) - sizeof(struct Chunk));
152     chunk->used = false;
153     if (chunk < free_) {
154         free_ = chunk;
155     }
156 
157     freeSize_ += chunk->next - (reinterpret_cast<uint8_t*>(chunk) - ram_);
158     CombineFree(chunk);
159 }
160 } // namespace OHOS
161