OCC22199 OpenGL memory leaks in TKOpenGl
[occt.git] / src / OpenGl / OpenGl_ResourceCleaner.cxx
1 // File:      OpenGl_ResourceCleaner.cxx
2 // Created:   18.03.11 9:40:00
3 // Author:    Anton POLETAEV
4
5 #include <OpenGl_ResourceCleaner.hxx>
6 #include <OpenGl_ResourceVBO.hxx>
7
8 //=======================================================================
9 //function : OpenGl_ResourceCleaner
10 //purpose  : Constructor
11 //=======================================================================
12
13 OpenGl_ResourceCleaner::OpenGl_ResourceCleaner() 
14 {
15   mySharedContexts.Clear();
16   mySharedQueue.Clear();
17   myInstanceQueue.Clear();
18 }
19
20 //=======================================================================
21 //function : AppendContext
22 //purpose  : Append given OpenGl context to the OpenGl_ResourceCleaner
23 //           control list
24 //=======================================================================
25
26 void OpenGl_ResourceCleaner::AppendContext(GLCONTEXT theContext, Standard_Boolean isShared)
27 {  
28   
29   // appending shared context
30   if (isShared) 
31   {
32     mySharedContexts.Add(theContext);
33   }
34   else
35   {
36     // if context is already in the list
37     if (myInstanceQueue.IsBound(theContext)) 
38     {
39       QueueOfResources *aQueue = &myInstanceQueue.ChangeFind(theContext);
40       aQueue->Clear();
41     }
42     else 
43     {
44       // context is not in the list - create empty queue for it and add queue to the list
45       QueueOfResources aQueue;
46       aQueue.Clear();
47       myInstanceQueue.Bind(theContext, aQueue);
48     }
49   }
50
51 }
52
53 //=======================================================================
54 //function : AddResource
55 //purpose  : Tell the OpenGl_ResourceCleaner to clean up the OpenGl 
56 //           memory resource
57 //=======================================================================
58
59 Standard_Boolean OpenGl_ResourceCleaner::AddResource(GLCONTEXT theContext, Handle_OpenGl_Resource theResource) 
60 {
61   // if context found in the shared list
62   if (mySharedContexts.Contains(theContext)) 
63   {
64     mySharedQueue.Push(theResource);
65     return Standard_True;
66   }
67   // if not, then it might be found in the non-shared list
68   else if (myInstanceQueue.IsBound(theContext)) 
69   {
70     QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext);
71     aQueue->Push(theResource);
72     return Standard_True;
73   }
74   
75   // context is not under OpenGl_ResourceCleaner control, do not tell to clean the resource
76   return Standard_False;
77 }
78
79 //=======================================================================
80 //function : Clear
81 //purpose  : Cancel clean procedure for all the resources added to the 
82 //           OpenGl_ResourceCleaner 
83 //=======================================================================
84
85 void OpenGl_ResourceCleaner::Clear() 
86 {
87   mySharedQueue.Clear();
88   DataMapOfContextsResources::Iterator anIter(myInstanceQueue);
89
90   // remove the resources from the list
91   for (anIter.Reset(); anIter.More(); anIter.Next()) 
92   {
93     QueueOfResources * aQueue = &anIter.ChangeValue();
94     aQueue->Clear();
95   }
96
97 }
98
99 //=======================================================================
100 //function : Clear
101 //purpose  : Cancel clean procedure for all the resources of the specific
102 //           OpenGl context which were added to the OpenGl_ResourceCleaner
103 //=======================================================================
104
105 Standard_Boolean OpenGl_ResourceCleaner::Clear(GLCONTEXT theContext) 
106 {
107   // check if the context in the the control list
108   if (myInstanceQueue.IsBound(theContext)) 
109   {
110     QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext);
111     aQueue->Clear();
112     return Standard_True;
113   }
114
115   return Standard_False;
116 }
117
118 //=======================================================================
119 //function : ClearShared
120 //purpose  : Cancel clean procedure for all of the shared resources
121 //=======================================================================
122
123 void OpenGl_ResourceCleaner::ClearShared()
124 {
125   mySharedQueue.Clear();
126 }
127
128 //=======================================================================
129 //function : Cleanup
130 //purpose  : Clear the unused resources for active OpenGl context
131 //=======================================================================
132
133 void OpenGl_ResourceCleaner::Cleanup() 
134 {
135   GLCONTEXT aContext = GET_GL_CONTEXT();
136
137   // if we have active context, we can delete the resources
138   if (aContext != NULL) 
139     // if the context is found in shared list
140     if (mySharedContexts.Contains(aContext)) 
141     {
142       while(mySharedQueue.Size() > 0) 
143       {
144         mySharedQueue.Front()->Clean();  // delete resource memory
145         mySharedQueue.Pop();
146       }
147     }
148     // if the context is found in non-shared list
149     else if (myInstanceQueue.IsBound(aContext)) 
150     {
151       QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(aContext);
152       while(aQueue->Size() > 0) 
153       {
154         aQueue->Front()->Clean();          // delete resource memory
155         aQueue->Pop();
156       }
157     }
158 }
159
160 //=======================================================================
161 //function : RemoveContext
162 //purpose  : Remove the OpenGl context from the OpenGl_ResourceCleaner list
163 //=======================================================================
164
165 void OpenGl_ResourceCleaner::RemoveContext(GLCONTEXT theContext)
166 {
167   // if context can be found in shared list try to remove it
168   // if it wasn't in there, try to remove it from non-shared list
169   if (!mySharedContexts.Remove(theContext))
170     myInstanceQueue.UnBind(theContext);  
171
172   // if no contexts in shared list, then there is no need to clean
173   // the resources on redraw
174   if (mySharedContexts.Size() == 0)
175     mySharedQueue.Clear();
176
177 }
178
179 //=======================================================================
180 //function : GetSharedContext
181 //purpose  : Get any of shared contexts from the OpenGl_ResourceCleaner list
182 //=======================================================================
183
184 GLCONTEXT OpenGl_ResourceCleaner::GetSharedContext() const
185 {
186   if(mySharedContexts.Size() > 0) 
187   {
188     MapOfContexts::Iterator anIter(mySharedContexts);
189     anIter.Reset();
190     return anIter.Value();
191   }
192
193   return 0;
194 }
195
196 //=======================================================================
197 //function : GetInstance
198 //purpose  : Get the global instance of OpenGl_ResourceCleaner
199 //=======================================================================
200
201 OpenGl_ResourceCleaner* OpenGl_ResourceCleaner::GetInstance()
202 {
203   // the static instance entity
204   static OpenGl_ResourceCleaner* anInstance = NULL;
205
206   if (anInstance == NULL)
207     anInstance = new OpenGl_ResourceCleaner;
208
209   return anInstance;
210 }