summaryrefslogtreecommitdiff
path: root/src/OpenGl/OpenGl_ResourceCleaner.cxx
blob: 8ff94df37696ad968e17235abb0cbed91580e368 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
// File:      OpenGl_ResourceCleaner.cxx
// Created:   18.03.11 9:40:00
// Author:    Anton POLETAEV

#include <OpenGl_ResourceCleaner.hxx>
#include <OpenGl_ResourceVBO.hxx>

//=======================================================================
//function : OpenGl_ResourceCleaner
//purpose  : Constructor
//=======================================================================

OpenGl_ResourceCleaner::OpenGl_ResourceCleaner() 
{
  mySharedContexts.Clear();
  mySharedQueue.Clear();
  myInstanceQueue.Clear();
}

//=======================================================================
//function : AppendContext
//purpose  : Append given OpenGl context to the OpenGl_ResourceCleaner
//           control list
//=======================================================================

void OpenGl_ResourceCleaner::AppendContext(GLCONTEXT theContext, Standard_Boolean isShared)
{  
  
  // appending shared context
  if (isShared) 
  {
    mySharedContexts.Add(theContext);
  }
  else
  {
    // if context is already in the list
    if (myInstanceQueue.IsBound(theContext)) 
    {
      QueueOfResources *aQueue = &myInstanceQueue.ChangeFind(theContext);
      aQueue->Clear();
    }
    else 
    {
      // context is not in the list - create empty queue for it and add queue to the list
      QueueOfResources aQueue;
      aQueue.Clear();
      myInstanceQueue.Bind(theContext, aQueue);
    }
  }

}

//=======================================================================
//function : AddResource
//purpose  : Tell the OpenGl_ResourceCleaner to clean up the OpenGl 
//           memory resource
//=======================================================================

Standard_Boolean OpenGl_ResourceCleaner::AddResource(GLCONTEXT theContext, Handle_OpenGl_Resource theResource) 
{
  // if context found in the shared list
  if (mySharedContexts.Contains(theContext)) 
  {
    mySharedQueue.Push(theResource);
    return Standard_True;
  }
  // if not, then it might be found in the non-shared list
  else if (myInstanceQueue.IsBound(theContext)) 
  {
    QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext);
    aQueue->Push(theResource);
    return Standard_True;
  }
  
  // context is not under OpenGl_ResourceCleaner control, do not tell to clean the resource
  return Standard_False;
}

//=======================================================================
//function : Clear
//purpose  : Cancel clean procedure for all the resources added to the 
//           OpenGl_ResourceCleaner 
//=======================================================================

void OpenGl_ResourceCleaner::Clear() 
{
  mySharedQueue.Clear();
  DataMapOfContextsResources::Iterator anIter(myInstanceQueue);

  // remove the resources from the list
  for (anIter.Reset(); anIter.More(); anIter.Next()) 
  {
    QueueOfResources * aQueue = &anIter.ChangeValue();
    aQueue->Clear();
  }

}

//=======================================================================
//function : Clear
//purpose  : Cancel clean procedure for all the resources of the specific
//           OpenGl context which were added to the OpenGl_ResourceCleaner
//=======================================================================

Standard_Boolean OpenGl_ResourceCleaner::Clear(GLCONTEXT theContext) 
{
  // check if the context in the the control list
  if (myInstanceQueue.IsBound(theContext)) 
  {
    QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(theContext);
    aQueue->Clear();
    return Standard_True;
  }

  return Standard_False;
}

//=======================================================================
//function : ClearShared
//purpose  : Cancel clean procedure for all of the shared resources
//=======================================================================

void OpenGl_ResourceCleaner::ClearShared()
{
  mySharedQueue.Clear();
}

//=======================================================================
//function : Cleanup
//purpose  : Clear the unused resources for active OpenGl context
//=======================================================================

void OpenGl_ResourceCleaner::Cleanup() 
{
  GLCONTEXT aContext = GET_GL_CONTEXT();

  // if we have active context, we can delete the resources
  if (aContext != NULL) {
    // if the context is found in shared list
    if (mySharedContexts.Contains(aContext)) 
    {
      while(mySharedQueue.Size() > 0) 
      {
        mySharedQueue.Front()->Clean();  // delete resource memory
        mySharedQueue.Pop();
      }
    }
    // if the context is found in non-shared list
    else if (myInstanceQueue.IsBound(aContext)) 
    {
      QueueOfResources * aQueue = &myInstanceQueue.ChangeFind(aContext);
      while(aQueue->Size() > 0) 
      {
        aQueue->Front()->Clean();          // delete resource memory
        aQueue->Pop();
      }
    }
  }
}

//=======================================================================
//function : RemoveContext
//purpose  : Remove the OpenGl context from the OpenGl_ResourceCleaner list
//=======================================================================

void OpenGl_ResourceCleaner::RemoveContext(GLCONTEXT theContext)
{
  // if context can be found in shared list try to remove it
  // if it wasn't in there, try to remove it from non-shared list
  if (!mySharedContexts.Remove(theContext))
    myInstanceQueue.UnBind(theContext);  

  // if no contexts in shared list, then there is no need to clean
  // the resources on redraw
  if (mySharedContexts.Size() == 0)
    mySharedQueue.Clear();

}

//=======================================================================
//function : GetSharedContext
//purpose  : Get any of shared contexts from the OpenGl_ResourceCleaner list
//=======================================================================

GLCONTEXT OpenGl_ResourceCleaner::GetSharedContext() const
{
  if(mySharedContexts.Size() > 0) 
  {
    MapOfContexts::Iterator anIter(mySharedContexts);
    anIter.Reset();
    return anIter.Value();
  }

  return 0;
}

//=======================================================================
//function : GetInstance
//purpose  : Get the global instance of OpenGl_ResourceCleaner
//=======================================================================

OpenGl_ResourceCleaner* OpenGl_ResourceCleaner::GetInstance()
{
  // the static instance entity
  static OpenGl_ResourceCleaner* anInstance = NULL;

  if (anInstance == NULL)
    anInstance = new OpenGl_ResourceCleaner;

  return anInstance;
}