Pencil2D Animation
Download Community News Docs Contribute
  • Overview
  • Articles
  • Code
  •  
  • Class List
  • Class Index
  • Class Hierarchy
  • Class Members
  • File List
Loading...
Searching...
No Matches
  • core_lib
  • src
activeframepool.cpp
1/*
2
3Pencil2D - Traditional Animation Software
4Copyright (C) 2005-2007 Patrick Corrieri & Pascal Naidon
5Copyright (C) 2012-2020 Matthew Chiawen Chang
6
7This program is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; version 2 of the License.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16*/
17
18#include "activeframepool.h"
19#include "keyframe.h"
20
21
22ActiveFramePool::ActiveFramePool()
23{
24 Q_ASSERT(mMemoryBudgetInBytes >= (1024 * 1024 * 100)); // at least 100MB
25}
26
27ActiveFramePool::~ActiveFramePool()
28{
29 clear();
30}
31
32void ActiveFramePool::put(KeyFrame* key)
33{
34 if (key == nullptr)
35 return;
36
37 Q_ASSERT(key->pos() > 0);
38
39 key->loadFile();
40
41 auto it = mCacheFramesMap.find(key);
42 const bool keyExistsInPool = (it != mCacheFramesMap.end());
43 if (keyExistsInPool)
44 {
45 // move the keyframe to the front of the list, if the key already exists in frame pool
46 mCacheFramesList.erase(it->second);
47 }
48 mCacheFramesList.push_front(key);
49 mCacheFramesMap[key] = mCacheFramesList.begin();
50
51 key->addEventListener(this);
52
53 if (!keyExistsInPool)
54 {
55 mTotalUsedMemory += key->memoryUsage();
56 }
57
58 discardLeastUsedFrames();
59}
60
61void ActiveFramePool::clear()
62{
63 for (KeyFrame* key : mCacheFramesList)
64 {
65 key->removeEventListner(this);
66 }
67 mCacheFramesList.clear();
68 mCacheFramesMap.clear();
69}
70
71void ActiveFramePool::resize(quint64 memoryBudget)
72{
73 memoryBudget = qMin(memoryBudget, quint64(1024) * 1024 * 1024 * 16); // 16GB
74 memoryBudget = qMax(memoryBudget, quint64(1024) * 1024 * 100); // 100MB
75 mMemoryBudgetInBytes = memoryBudget;
76 discardLeastUsedFrames();
77}
78
79bool ActiveFramePool::isFrameInPool(KeyFrame* key)
80{
81 auto it = mCacheFramesMap.find(key);
82 return (it != mCacheFramesMap.end());
83}
84
85void ActiveFramePool::setMinFrameCount(size_t frameCount)
86{
87 mMinFrameCount = frameCount;
88}
89
90void ActiveFramePool::onKeyFrameDestroy(KeyFrame* key)
91{
92 auto it = mCacheFramesMap.find(key);
93 if (it != mCacheFramesMap.end())
94 {
95 mCacheFramesList.erase(it->second);
96 mCacheFramesMap.erase(it);
97
98 // Just recalculate the total usage
99 // Not safe to call key->memoryUsage() here cuz it's in the KeyFrame's destructor
100 recalcuateTotalUsedMemory();
101 }
102}
103
104void ActiveFramePool::discardLeastUsedFrames()
105{
106 while ((mTotalUsedMemory > mMemoryBudgetInBytes) && (mCacheFramesList.size() > mMinFrameCount))
107 {
108 list_iterator_t last = mCacheFramesList.end();
109 last--;
110
111 KeyFrame* lastKeyFrame = *last;
112 unloadFrame(lastKeyFrame);
113
114 mCacheFramesMap.erase(lastKeyFrame);
115 mCacheFramesList.pop_back();
116
117 lastKeyFrame->removeEventListner(this);
118 }
119}
120
121void ActiveFramePool::unloadFrame(KeyFrame* key)
122{
123 mTotalUsedMemory -= key->memoryUsage();
124 key->unloadFile();
125}
126
127void ActiveFramePool::recalcuateTotalUsedMemory()
128{
129 mTotalUsedMemory = 0;
130 for (KeyFrame* key : mCacheFramesList)
131 {
132 mTotalUsedMemory += key->memoryUsage();
133 }
134}
KeyFrame
Definition: keyframe.h:30
Generated on Fri Dec 19 2025 07:54:21 for Pencil2D by doxygen 1.9.6 based on revision 7fd8cd9e03f2d31750e199ecec202e5c0f30e532