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#include "pencildef.h"
21
22
23ActiveFramePool::ActiveFramePool()
24{
25 Q_ASSERT(mMemoryBudgetInBytes >= (1024 * 1024 * 100)); // at least 100MB
26}
27
28ActiveFramePool::~ActiveFramePool()
29{
30 clear();
31}
32
33void ActiveFramePool::put(KeyFrame* key)
34{
35 if (key == nullptr)
36 return;
37
38 Q_ASSERT(key->pos() > 0);
39
40 key->loadFile();
41
42 auto it = mCacheFramesMap.find(key);
43 const bool keyExistsInPool = (it != mCacheFramesMap.end());
44 if (keyExistsInPool)
45 {
46 // move the keyframe to the front of the list, if the key already exists in frame pool
47 mCacheFramesList.erase(it->second);
48 }
49 mCacheFramesList.push_front(key);
50 mCacheFramesMap[key] = mCacheFramesList.begin();
51
52 key->addEventListener(this);
53
54 if (!keyExistsInPool)
55 {
56 mTotalUsedMemory += key->memoryUsage();
57 }
58
59 discardLeastUsedFrames();
60}
61
62void ActiveFramePool::clear()
63{
64 for (KeyFrame* key : mCacheFramesList)
65 {
66 key->removeEventListner(this);
67 }
68 mCacheFramesList.clear();
69 mCacheFramesMap.clear();
70}
71
72void ActiveFramePool::resize(quint64 memoryBudget)
73{
74 memoryBudget = qMin(memoryBudget, quint64(1024) * 1024 * 1024 * 16); // 16GB
75 memoryBudget = qMax(memoryBudget, quint64(1024) * 1024 * 100); // 100MB
76 mMemoryBudgetInBytes = memoryBudget;
77 discardLeastUsedFrames();
78}
79
80bool ActiveFramePool::isFrameInPool(KeyFrame* key)
81{
82 auto it = mCacheFramesMap.find(key);
83 return (it != mCacheFramesMap.end());
84}
85
86void ActiveFramePool::setMinFrameCount(size_t frameCount)
87{
88 mMinFrameCount = frameCount;
89}
90
91void ActiveFramePool::onKeyFrameDestroy(KeyFrame* key)
92{
93 auto it = mCacheFramesMap.find(key);
94 if (it != mCacheFramesMap.end())
95 {
96 mCacheFramesList.erase(it->second);
97 mCacheFramesMap.erase(it);
98
99 // Just recalculate the total usage
100 // Not safe to call key->memoryUsage() here cuz it's in the KeyFrame's destructor
101 recalcuateTotalUsedMemory();
102 }
103}
104
105void ActiveFramePool::discardLeastUsedFrames()
106{
107 while ((mTotalUsedMemory > mMemoryBudgetInBytes) && (mCacheFramesList.size() > mMinFrameCount))
108 {
109 list_iterator_t last = mCacheFramesList.end();
110 last--;
111
112 KeyFrame* lastKeyFrame = *last;
113 unloadFrame(lastKeyFrame);
114
115 mCacheFramesMap.erase(lastKeyFrame);
116 mCacheFramesList.pop_back();
117
118 lastKeyFrame->removeEventListner(this);
119 }
120}
121
122void ActiveFramePool::unloadFrame(KeyFrame* key)
123{
124 mTotalUsedMemory -= key->memoryUsage();
125 key->unloadFile();
126}
127
128void ActiveFramePool::recalcuateTotalUsedMemory()
129{
130 mTotalUsedMemory = 0;
131 for (KeyFrame* key : mCacheFramesList)
132 {
133 mTotalUsedMemory += key->memoryUsage();
134 }
135}
KeyFrame
Definition: keyframe.h:30
Generated on Thu May 8 2025 04:47:53 for Pencil2D by doxygen 1.9.6 based on revision 4513250b1d5b1a3676ec0e67b06b7a885ceaae39