Merge pull request #110 from tesselode/fixes
[wdl/wdl-ol.git] / WDL / swell / swell-gdi-internalpool.h
blobd55b7bb16481d4525ee9bb15be824024f864169a
1 /* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
2 Copyright (C) 2006 and later, Cockos, Inc.
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
20 // used for HDC/HGDIOBJ pooling (to avoid excess heap use), used by swell-gdi.mm and swell-gdi-generic.cpp
23 #if defined(_DEBUG)
24 #define SWELL_GDI_DEBUG
25 #endif
27 static WDL_Mutex *m_ctxpool_mutex;
28 #ifdef SWELL_GDI_DEBUG
29 #include <assert.h>
30 #include "../ptrlist.h"
31 static WDL_PtrList<HDC__> *m_ctxpool_debug;
32 static WDL_PtrList<HGDIOBJ__> *m_objpool_debug;
33 #else
34 static HDC__ *m_ctxpool;
35 static int m_ctxpool_size;
36 static HGDIOBJ__ *m_objpool;
37 static int m_objpool_size;
38 #endif
42 HDC__ *SWELL_GDP_CTX_NEW()
44 if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
46 HDC__ *p=NULL;
47 #ifdef SWELL_GDI_DEBUG
48 m_ctxpool_mutex->Enter();
49 if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList<HDC__>;
50 if (m_ctxpool_debug->GetSize() > 8192)
52 p = m_ctxpool_debug->Get(0);
53 m_ctxpool_debug->Delete(0);
54 memset(p,0,sizeof(*p));
56 m_ctxpool_mutex->Leave();
57 #else
58 if (m_ctxpool)
60 m_ctxpool_mutex->Enter();
61 if ((p=m_ctxpool))
63 m_ctxpool=p->_next;
64 m_ctxpool_size--;
65 memset(p,0,sizeof(*p));
67 m_ctxpool_mutex->Leave();
69 #endif
70 if (!p)
72 // printf("alloc ctx\n");
73 p=(HDC__ *)calloc(sizeof(HDC__)+128,1); // extra space in case things want to use it (i.e. swell-gdi-lice does)
75 return p;
77 static void SWELL_GDP_CTX_DELETE(HDC__ *p)
79 if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
81 if (!p) return;
83 if (p->_infreelist)
85 #ifdef SWELL_GDI_DEBUG
86 assert(!p->_infreelist);
87 #endif
88 return;
91 memset(p,0,sizeof(*p));
93 #ifdef SWELL_GDI_DEBUG
94 m_ctxpool_mutex->Enter();
95 p->_infreelist=true;
96 if (!m_ctxpool_debug) m_ctxpool_debug = new WDL_PtrList<HDC__>;
97 m_ctxpool_debug->Add(p);
98 m_ctxpool_mutex->Leave();
99 #else
100 if (m_ctxpool_size<100)
102 m_ctxpool_mutex->Enter();
103 p->_infreelist=true;
104 p->_next = m_ctxpool;
105 m_ctxpool = p;
106 m_ctxpool_size++;
107 m_ctxpool_mutex->Leave();
109 else
111 // printf("free ctx\n");
112 free(p);
114 #endif
116 static HGDIOBJ__ *GDP_OBJECT_NEW()
118 if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
119 HGDIOBJ__ *p=NULL;
120 #ifdef SWELL_GDI_DEBUG
121 m_ctxpool_mutex->Enter();
122 if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList<HGDIOBJ__>;
123 if (m_objpool_debug->GetSize()>8192)
125 p = m_objpool_debug->Get(0);
126 m_objpool_debug->Delete(0);
127 memset(p,0,sizeof(*p));
129 m_ctxpool_mutex->Leave();
130 #else
131 if (m_objpool)
133 m_ctxpool_mutex->Enter();
134 if ((p=m_objpool))
136 m_objpool = p->_next;
137 m_objpool_size--;
138 memset(p,0,sizeof(*p));
140 m_ctxpool_mutex->Leave();
142 #endif
143 if (!p)
145 // printf("alloc obj\n");
146 p=(HGDIOBJ__ *)calloc(sizeof(HGDIOBJ__),1);
148 return p;
150 static void GDP_OBJECT_DELETE(HGDIOBJ__ *p)
152 if (!m_ctxpool_mutex) m_ctxpool_mutex=new WDL_Mutex;
153 if (!p) return;
155 if (p->_infreelist)
157 #ifdef SWELL_GDI_DEBUG
158 assert(!p->_infreelist);
159 #endif
160 return;
163 memset(p,0,sizeof(*p));
164 #ifdef SWELL_GDI_DEBUG
165 m_ctxpool_mutex->Enter();
166 p->_infreelist = true;
167 if (!m_objpool_debug) m_objpool_debug = new WDL_PtrList<HGDIOBJ__>;
168 m_objpool_debug->Add(p);
169 m_ctxpool_mutex->Leave();
170 #else
171 if (m_objpool_size<200)
173 m_ctxpool_mutex->Enter();
174 p->_infreelist = true;
175 p->_next = m_objpool;
176 m_objpool = p;
177 m_objpool_size++;
178 m_ctxpool_mutex->Leave();
180 else
182 // printf("free obj\n");
183 free(p);
185 #endif
188 static bool HGDIOBJ_VALID(HGDIOBJ__ *p, int reqType=0)
190 if (p == (HGDIOBJ__*)TYPE_PEN || p == (HGDIOBJ__*)TYPE_BRUSH ||
191 p == (HGDIOBJ__*)TYPE_FONT || p == (HGDIOBJ__*)TYPE_BITMAP) return false;
192 #ifdef SWELL_GDI_DEBUG
193 if (p) { assert(!p->_infreelist); }
194 #endif
195 // insert breakpoints in these parts for debugging
196 if (p && !p->_infreelist)
198 #ifdef SWELL_GDI_DEBUG
199 if (reqType) { assert(reqType == p->type); }
200 #endif
202 return !reqType || reqType == p->type;
204 return false;
207 static bool HDC_VALID(HDC__ *ct)
209 #ifdef SWELL_GDI_DEBUG
210 if (ct) { assert(!ct->_infreelist); }
211 #endif
212 // insert breakpoints in these parts for debugging
213 return ct && !ct->_infreelist;
217 #if !defined(SWELL_GDI_DEBUG) && defined(SWELL_CLEANUP_ON_UNLOAD)
219 class _swellGdiUnloader
221 public:
222 _swellGdiUnloader() { }
223 ~_swellGdiUnloader()
226 HDC__ *p = m_ctxpool;
227 m_ctxpool = NULL;
228 while (p)
230 HDC__ *t = p;
231 p = p->_next;
232 free(t);
236 HGDIOBJ__ *p = m_objpool;
237 m_objpool = NULL;
238 while (p)
240 HGDIOBJ__ *t = p;
241 p = p->_next;
242 free(t);
246 delete m_ctxpool_mutex;
247 m_ctxpool_mutex=NULL;
251 _swellGdiUnloader __swell__swellGdiUnloader;
252 #endif