1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // ResourceManager.cpp: Implements the ResourceManager class, which tracks and
16 // retrieves objects which may be shared by multiple Contexts.
17
18 #include "ResourceManager.h"
19
20 #include "Buffer.h"
21 #include "Program.h"
22 #include "Renderbuffer.h"
23 #include "Shader.h"
24 #include "Texture.h"
25
26 namespace gl
27 {
ResourceManager()28 ResourceManager::ResourceManager()
29 {
30 mRefCount = 1;
31 }
32
~ResourceManager()33 ResourceManager::~ResourceManager()
34 {
35 while(!mBufferMap.empty())
36 {
37 deleteBuffer(mBufferMap.begin()->first);
38 }
39
40 while(!mProgramMap.empty())
41 {
42 deleteProgram(mProgramMap.begin()->first);
43 }
44
45 while(!mShaderMap.empty())
46 {
47 deleteShader(mShaderMap.begin()->first);
48 }
49
50 while(!mRenderbufferMap.empty())
51 {
52 deleteRenderbuffer(mRenderbufferMap.begin()->first);
53 }
54
55 while(!mTextureMap.empty())
56 {
57 deleteTexture(mTextureMap.begin()->first);
58 }
59 }
60
addRef()61 void ResourceManager::addRef()
62 {
63 mRefCount++;
64 }
65
release()66 void ResourceManager::release()
67 {
68 if(--mRefCount == 0)
69 {
70 delete this;
71 }
72 }
73
74 // Returns an unused buffer name
createBuffer()75 GLuint ResourceManager::createBuffer()
76 {
77 //GLuint handle = mBufferNameSpace.allocate();
78 unsigned int handle = 1;
79
80 while (mBufferMap.find(handle) != mBufferMap.end())
81 {
82 handle++;
83 }
84
85 mBufferMap[handle] = nullptr;
86
87 return handle;
88 }
89
90 // Returns an unused shader/program name
createShader(GLenum type)91 GLuint ResourceManager::createShader(GLenum type)
92 {
93 //GLuint handle = mProgramShaderNameSpace.allocate();
94 unsigned int handle = 1;
95
96 while (mShaderMap.find(handle) != mShaderMap.end())
97 {
98 handle++;
99 }
100
101 if(type == GL_VERTEX_SHADER)
102 {
103 mShaderMap[handle] = new VertexShader(this, handle);
104 }
105 else if(type == GL_FRAGMENT_SHADER)
106 {
107 mShaderMap[handle] = new FragmentShader(this, handle);
108 }
109 else UNREACHABLE(type);
110
111 return handle;
112 }
113
114 // Returns an unused program/shader name
createProgram()115 GLuint ResourceManager::createProgram()
116 {
117 //GLuint handle = mProgramShaderNameSpace.allocate();
118 unsigned int handle = 1;
119
120 while (mProgramMap.find(handle) != mProgramMap.end())
121 {
122 handle++;
123 }
124
125 mProgramMap[handle] = new Program(this, handle);
126
127 return handle;
128 }
129
130 // Returns an unused texture name
createTexture()131 GLuint ResourceManager::createTexture()
132 {
133 //GLuint handle = mTextureNameSpace.allocate();
134 unsigned int handle = 1;
135
136 while (mTextureMap.find(handle) != mTextureMap.end())
137 {
138 handle++;
139 }
140
141 mTextureMap[handle] = nullptr;
142
143 return handle;
144 }
145
146 // Returns an unused renderbuffer name
createRenderbuffer()147 GLuint ResourceManager::createRenderbuffer()
148 {
149 //GLuint handle = mRenderbufferNameSpace.allocate();
150 unsigned int handle = 1;
151
152 while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
153 {
154 handle++;
155 }
156
157 mRenderbufferMap[handle] = nullptr;
158
159 return handle;
160 }
161
deleteBuffer(GLuint buffer)162 void ResourceManager::deleteBuffer(GLuint buffer)
163 {
164 BufferMap::iterator bufferObject = mBufferMap.find(buffer);
165
166 if(bufferObject != mBufferMap.end())
167 {
168 //mBufferNameSpace.release(bufferObject->first);
169 if(bufferObject->second) bufferObject->second->release();
170 mBufferMap.erase(bufferObject);
171 }
172 }
173
deleteShader(GLuint shader)174 void ResourceManager::deleteShader(GLuint shader)
175 {
176 ShaderMap::iterator shaderObject = mShaderMap.find(shader);
177
178 if(shaderObject != mShaderMap.end())
179 {
180 if(shaderObject->second->getRefCount() == 0)
181 {
182 //mProgramShaderNameSpace.release(shaderObject->first);
183 delete shaderObject->second;
184 mShaderMap.erase(shaderObject);
185 }
186 else
187 {
188 shaderObject->second->flagForDeletion();
189 }
190 }
191 }
192
deleteProgram(GLuint program)193 void ResourceManager::deleteProgram(GLuint program)
194 {
195 ProgramMap::iterator programObject = mProgramMap.find(program);
196
197 if(programObject != mProgramMap.end())
198 {
199 if(programObject->second->getRefCount() == 0)
200 {
201 //mProgramShaderNameSpace.release(programObject->first);
202 delete programObject->second;
203 mProgramMap.erase(programObject);
204 }
205 else
206 {
207 programObject->second->flagForDeletion();
208 }
209 }
210 }
211
deleteTexture(GLuint texture)212 void ResourceManager::deleteTexture(GLuint texture)
213 {
214 TextureMap::iterator textureObject = mTextureMap.find(texture);
215
216 if(textureObject != mTextureMap.end())
217 {
218 //mTextureNameSpace.release(textureObject->first);
219 if(textureObject->second) textureObject->second->release();
220 mTextureMap.erase(textureObject);
221 }
222 }
223
deleteRenderbuffer(GLuint renderbuffer)224 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
225 {
226 RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
227
228 if(renderbufferObject != mRenderbufferMap.end())
229 {
230 //mRenderbufferNameSpace.release(renderbufferObject->first);
231 if(renderbufferObject->second) renderbufferObject->second->release();
232 mRenderbufferMap.erase(renderbufferObject);
233 }
234 }
235
getBuffer(unsigned int handle)236 Buffer *ResourceManager::getBuffer(unsigned int handle)
237 {
238 BufferMap::iterator buffer = mBufferMap.find(handle);
239
240 if(buffer == mBufferMap.end())
241 {
242 return nullptr;
243 }
244 else
245 {
246 return buffer->second;
247 }
248 }
249
getShader(unsigned int handle)250 Shader *ResourceManager::getShader(unsigned int handle)
251 {
252 ShaderMap::iterator shader = mShaderMap.find(handle);
253
254 if(shader == mShaderMap.end())
255 {
256 return nullptr;
257 }
258 else
259 {
260 return shader->second;
261 }
262 }
263
getTexture(unsigned int handle)264 Texture *ResourceManager::getTexture(unsigned int handle)
265 {
266 if(handle == 0) return nullptr;
267
268 TextureMap::iterator texture = mTextureMap.find(handle);
269
270 if(texture == mTextureMap.end())
271 {
272 return nullptr;
273 }
274 else
275 {
276 return texture->second;
277 }
278 }
279
getProgram(unsigned int handle)280 Program *ResourceManager::getProgram(unsigned int handle)
281 {
282 ProgramMap::iterator program = mProgramMap.find(handle);
283
284 if(program == mProgramMap.end())
285 {
286 return nullptr;
287 }
288 else
289 {
290 return program->second;
291 }
292 }
293
getRenderbuffer(unsigned int handle)294 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
295 {
296 RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
297
298 if(renderbuffer == mRenderbufferMap.end())
299 {
300 return nullptr;
301 }
302 else
303 {
304 return renderbuffer->second;
305 }
306 }
307
setRenderbuffer(GLuint handle,Renderbuffer * buffer)308 void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
309 {
310 mRenderbufferMap[handle] = buffer;
311 }
312
checkBufferAllocation(unsigned int buffer)313 void ResourceManager::checkBufferAllocation(unsigned int buffer)
314 {
315 if(buffer != 0 && !getBuffer(buffer))
316 {
317 Buffer *bufferObject = new Buffer(buffer);
318 mBufferMap[buffer] = bufferObject;
319 bufferObject->addRef();
320 }
321 }
322
checkTextureAllocation(GLuint texture,TextureType type)323 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
324 {
325 if(!getTexture(texture) && texture != 0)
326 {
327 Texture *textureObject;
328
329 if(type == TEXTURE_2D)
330 {
331 textureObject = new Texture2D(texture);
332 }
333 else if(type == TEXTURE_CUBE)
334 {
335 textureObject = new TextureCubeMap(texture);
336 }
337 else
338 {
339 UNREACHABLE(type);
340 return;
341 }
342
343 mTextureMap[texture] = textureObject;
344 textureObject->addRef();
345 }
346 }
347
checkRenderbufferAllocation(GLuint renderbuffer)348 void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
349 {
350 if(renderbuffer != 0 && !getRenderbuffer(renderbuffer))
351 {
352 Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
353 mRenderbufferMap[renderbuffer] = renderbufferObject;
354 renderbufferObject->addRef();
355 }
356 }
357
358 }
359