Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
97 andreas 1
/*
2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <mutex>
20
 
21
#include "timgcache.h"
22
#include "terror.h"
175 andreas 23
#include "tconfig.h"
97 andreas 24
 
25
using std::string;
26
using std::vector;
27
using std::mutex;
28
 
29
vector<_IMGCACHE> TImgCache::mImgCache;
175 andreas 30
size_t TImgCache::size{0};
97 andreas 31
 
32
mutex _imgCache;
33
 
34
TImgCache::~TImgCache()
35
{
36
    DECL_TRACER("TImgCache::~TImgCache()");
37
 
38
    mImgCache.clear();
39
}
40
 
165 andreas 41
bool TImgCache::addImage(const string& name, SkBitmap& bm, _IMGCACHE_BMTYPE bmType)
97 andreas 42
{
165 andreas 43
    DECL_TRACER("TImgCache::addImage(const string& name, SkBitmap& bm, _IMGCACHE_BMTYPE bmType)");
97 andreas 44
 
175 andreas 45
    if (name.empty() || bm.empty())
46
        return false;
47
 
97 andreas 48
    _imgCache.lock();
49
    _IMGCACHE ic;
50
 
51
    ic.name = name;
165 andreas 52
    ic.bmType = bmType;
97 andreas 53
    ic.bitmap = bm;
175 andreas 54
    ic.handle = 0;
97 andreas 55
 
175 andreas 56
    bool ret = addImage(ic);
57
    _imgCache.unlock();
58
    return ret;
59
}
60
 
61
bool TImgCache::addImage(const string& name, SkBitmap& bm, ulong handle, _IMGCACHE_BMTYPE bmType)
62
{
63
    DECL_TRACER("TImgCache::addImage(const string& name, SkBitmap& bm, uint32_t handle, _IMGCACHE_BMTYPE bmType)");
64
 
65
    if (bm.empty() || handle == 0)
66
        return false;
67
 
68
    _imgCache.lock();
69
    _IMGCACHE ic;
70
 
71
    if (name.empty())
72
        ic.name = handleToString(handle);
73
    else
74
        ic.name = name;
75
 
76
    ic.bmType = bmType;
77
    ic.bitmap = bm;
78
    ic.handle = handle;
79
 
80
    bool ret = addImage(ic);
81
    _imgCache.unlock();
82
    return ret;
83
}
84
 
85
bool TImgCache::addImage(_IMGCACHE ic)
86
{
87
    DECL_TRACER("TImgCache::addImage(_IMGCACHE ic)");
88
 
97 andreas 89
    if (mImgCache.size() == 0)
90
    {
91
        mImgCache.push_back(ic);
177 andreas 92
        size += sizeof(_IMGCACHE);
175 andreas 93
        MSG_DEBUG("Bitmap \"" << ic.name << "\" was freshly added.");
97 andreas 94
        return true;
95
    }
96
 
97
    vector<_IMGCACHE>::iterator iter;
98
 
99
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
100
    {
175 andreas 101
        if (iter->name == ic.name)
97 andreas 102
        {
175 andreas 103
            MSG_DEBUG("Bitmap \"" << ic.name << "\" already in cache.");
97 andreas 104
            return true;
105
        }
106
    }
107
 
108
    // Here we know that the image is not yet in the cache. So we add it now.
109
    mImgCache.push_back(ic);
177 andreas 110
    size += sizeof(_IMGCACHE);
175 andreas 111
    MSG_DEBUG("Bitmap \"" << ic.name << "\" was added.");
112
 
113
    if (size > TConfig::getButttonCache())
114
        shrinkCache();
115
 
97 andreas 116
    return true;
117
}
118
 
167 andreas 119
bool TImgCache::getBitmap(const string& name, SkBitmap *bm, _IMGCACHE_BMTYPE bmType, int *width, int *height)
97 andreas 120
{
240 andreas 121
    DECL_TRACER("TImgCache::getBitmap(const string& name, SkBitmap *bm, _IMGCACHE_BMTYPE bmType, int *width, int *height)");
97 andreas 122
 
123
    if (mImgCache.size() == 0 || !bm)
124
        return false;
125
 
126
    vector<_IMGCACHE>::iterator iter;
127
 
128
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
129
    {
165 andreas 130
        if (iter->name == name && iter->bmType == bmType)
97 andreas 131
        {
132
            *bm = iter->bitmap;
167 andreas 133
 
134
            if (width && !iter->bitmap.empty())
135
                *width = iter->bitmap.info().width();
184 andreas 136
            else if (width)
137
                *width = 0;
167 andreas 138
 
139
            if (height && !iter->bitmap.empty())
140
                *height = iter->bitmap.info().height();
184 andreas 141
            else if (height)
142
                *height = 0;
167 andreas 143
 
97 andreas 144
            MSG_DEBUG("Bitmap \"" << iter->name << "\" was found.");
145
            return true;
146
        }
147
    }
148
 
167 andreas 149
    if (width)
150
        *width = 0;
151
 
152
    if (height)
153
        *height = 0;
154
 
97 andreas 155
    return false;
156
}
157
 
175 andreas 158
bool TImgCache::getBitmap(SkBitmap *bm, ulong handle, int *width, int *height, _IMGCACHE_BMTYPE bmType)
159
{
160
    DECL_TRACER("TImgCache::getBitmap(SkBitmap *bm, uint32_t handle, int *width, int *height, _IMGCACHE_BMTYPE bmType)");
161
 
162
    if (mImgCache.size() == 0 || !bm || handle == 0)
163
        return false;
164
 
165
    vector<_IMGCACHE>::iterator iter;
166
 
167
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
168
    {
169
        if (iter->handle == handle)
170
        {
171
            if (bmType != _BMTYPE_NONE && iter->bmType != bmType)
172
                return false;
173
 
174
            *bm = iter->bitmap;
175
 
176
            if (width && !iter->bitmap.empty())
177
                *width = iter->bitmap.info().width();
178
 
179
            if (height && !iter->bitmap.empty())
180
                *height = iter->bitmap.info().height();
181
 
182
            MSG_DEBUG("Bitmap \"" << iter->name << "\" was found.");
183
            return true;
184
        }
185
    }
186
 
187
    if (width)
188
        *width = 0;
189
 
190
    if (height)
191
        *height = 0;
192
 
193
    return false;
194
}
195
 
165 andreas 196
bool TImgCache::delBitmap(const string& name, _IMGCACHE_BMTYPE bmType)
97 andreas 197
{
165 andreas 198
    DECL_TRACER("TImgCache::delBitmap(const string& name, _IMGCACHE_BMTYPE bmType)");
97 andreas 199
 
200
    if (name.empty() || mImgCache.size() == 0)
201
        return false;
202
 
203
    _imgCache.lock();
204
    vector<_IMGCACHE>::iterator iter;
205
 
206
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
207
    {
165 andreas 208
        if (iter->name == name && iter->bmType == bmType)
97 andreas 209
        {
210
            MSG_DEBUG("Bitmap \"" << iter->name << "\" will be erased.");
211
            mImgCache.erase(iter);
212
            _imgCache.unlock();
213
            return true;
214
        }
215
    }
216
 
217
    _imgCache.unlock();
218
    return false;
219
}
165 andreas 220
 
175 andreas 221
bool TImgCache::delBitmap(ulong handle, _IMGCACHE_BMTYPE bmType)
222
{
223
    DECL_TRACER("TImgCache::delBitmap(uint32_t handle, _IMGCACHE_BMTYPE bmType)");
224
 
225
    if (!handle)
226
        return false;
227
 
228
    _imgCache.lock();
229
    vector<_IMGCACHE>::iterator iter;
230
 
231
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
232
    {
233
        if (iter->handle == handle)
234
        {
235
            if (bmType != _BMTYPE_NONE && iter->bmType != bmType)
236
                return false;
237
 
238
            MSG_DEBUG("Bitmap \"" << iter->name << "\" will be erased.");
239
            mImgCache.erase(iter);
240
            size -= sizeof(_IMGCACHE);
241
            _imgCache.unlock();
242
            return true;
243
        }
244
    }
245
 
246
    _imgCache.unlock();
247
    return false;
248
}
249
 
165 andreas 250
bool TImgCache::existBitmap(const string& name, _IMGCACHE_BMTYPE bmType)
251
{
252
    DECL_TRACER("TImgCache::existBitmap(const string& name, _IMGCACHE_BMTYPE bmType)");
253
 
254
    if (mImgCache.size() == 0)
255
        return false;
256
 
257
    vector<_IMGCACHE>::iterator iter;
258
 
259
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
260
    {
261
        if (iter->name == name && iter->bmType == bmType)
262
            return true;
263
    }
264
 
265
    return false;
266
}
175 andreas 267
 
268
bool TImgCache::existBitmap(ulong handle, _IMGCACHE_BMTYPE bmType)
269
{
270
    DECL_TRACER("TImgCache::existBitmap(uint32_t handle, _IMGCACHE_BMTYPE bmType)");
271
 
272
    if (!handle)
273
        return false;
274
 
275
    vector<_IMGCACHE>::iterator iter;
276
 
277
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
278
    {
279
        if (iter->handle == handle)
280
        {
281
            if (bmType != _BMTYPE_NONE && iter->bmType != bmType)
282
                return false;
283
 
284
            return true;
285
        }
286
    }
287
 
288
    return false;
289
}
290
 
291
bool TImgCache::replaceBitmap(const std::string &name, SkBitmap& bm, _IMGCACHE_BMTYPE bmType)
292
{
293
    DECL_TRACER("TImgCache::replaceBitmap(const std::string &name, SkBitmap& bm, _IMGCACHE_BMTYPE bmType)");
294
 
295
    if (name.empty() || bm.empty())
296
        return false;
297
 
298
    _imgCache.lock();
299
    vector<_IMGCACHE>::iterator iter;
300
 
301
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
302
    {
303
        if (iter->name == name)
304
        {
305
            if (bmType != _BMTYPE_NONE && iter->bmType != bmType)
306
            {
307
                _imgCache.unlock();
308
                return false;
309
            }
310
 
311
            _IMGCACHE ic = *iter;
312
            ic.bitmap = bm;
313
            mImgCache.erase(iter);
314
            mImgCache.push_back(ic);
315
            _imgCache.unlock();
316
            return true;
317
        }
318
    }
319
 
320
    _imgCache.unlock();
321
    return false;
322
}
323
 
324
bool TImgCache::replaceBitmap(ulong handle, SkBitmap& bm, _IMGCACHE_BMTYPE bmType)
325
{
326
    DECL_TRACER("TImgCache::replaceBitmap(ulong handle, SkBitmap& bm, _IMGCACHE_BMTYPE bmType)");
327
 
328
    if (handle == 0 || bm.empty())
329
        return false;
330
 
331
    _imgCache.lock();
332
    vector<_IMGCACHE>::iterator iter;
333
 
334
    for (iter = mImgCache.begin(); iter != mImgCache.end(); ++iter)
335
    {
336
        if (iter->handle == handle)
337
        {
338
            if (bmType != _BMTYPE_NONE && iter->bmType != bmType)
339
            {
340
                _imgCache.unlock();
341
                return false;
342
            }
343
 
344
            _IMGCACHE ic = *iter;
345
            ic.bitmap = bm;
346
            mImgCache.erase(iter);
347
            mImgCache.push_back(ic);
348
            _imgCache.unlock();
349
            return true;
350
        }
351
    }
352
 
353
    _imgCache.unlock();
354
    return false;
355
}
356
 
357
void TImgCache::shrinkCache()
358
{
359
    DECL_TRACER("TImgCache::shrinkCache()");
360
 
361
    if (mImgCache.size() == 0)
362
        return;
363
 
364
    size_t s = TConfig::getButttonCache();
365
 
366
    if (s > size || s <= sizeof(_IMGCACHE))
367
        return;
368
 
369
    while (size > s && mImgCache.size() > 0)
370
    {
177 andreas 371
        MSG_DEBUG("Erasing image " << mImgCache.begin()->name << " -- Size: " << size);
175 andreas 372
        mImgCache.erase(mImgCache.begin());
373
        size -= sizeof(_IMGCACHE);
374
    }
375
}