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 "Fence.h"
22 #include "Program.h"
23 #include "Renderbuffer.h"
24 #include "Sampler.h"
25 #include "Shader.h"
26 #include "Texture.h"
27
28 namespace es2
29 {
ResourceManager()30 ResourceManager::ResourceManager()
31 {
32 mRefCount = 1;
33 }
34
~ResourceManager()35 ResourceManager::~ResourceManager()
36 {
37 while(!mBufferNameSpace.empty())
38 {
39 deleteBuffer(mBufferNameSpace.firstName());
40 }
41
42 while(!mProgramNameSpace.empty())
43 {
44 deleteProgram(mProgramNameSpace.firstName());
45 }
46
47 while(!mShaderNameSpace.empty())
48 {
49 deleteShader(mShaderNameSpace.firstName());
50 }
51
52 while(!mRenderbufferNameSpace.empty())
53 {
54 deleteRenderbuffer(mRenderbufferNameSpace.firstName());
55 }
56
57 while(!mTextureNameSpace.empty())
58 {
59 deleteTexture(mTextureNameSpace.firstName());
60 }
61
62 while(!mSamplerNameSpace.empty())
63 {
64 deleteSampler(mSamplerNameSpace.firstName());
65 }
66
67 while(!mFenceSyncNameSpace.empty())
68 {
69 deleteFenceSync(mFenceSyncNameSpace.firstName());
70 }
71 }
72
addRef()73 void ResourceManager::addRef()
74 {
75 mRefCount++;
76 }
77
release()78 void ResourceManager::release()
79 {
80 if(--mRefCount == 0)
81 {
82 delete this;
83 }
84 }
85
86 // Returns an unused buffer name
createBuffer()87 GLuint ResourceManager::createBuffer()
88 {
89 return mBufferNameSpace.allocate();
90 }
91
92 // Returns an unused shader name
createShader(GLenum type)93 GLuint ResourceManager::createShader(GLenum type)
94 {
95 GLuint name = mProgramShaderNameSpace.allocate();
96
97 if(type == GL_VERTEX_SHADER)
98 {
99 mShaderNameSpace.insert(name, new VertexShader(this, name));
100 }
101 else if(type == GL_FRAGMENT_SHADER)
102 {
103 mShaderNameSpace.insert(name, new FragmentShader(this, name));
104 }
105 else UNREACHABLE(type);
106
107 return name;
108 }
109
110 // Returns an unused program name
createProgram()111 GLuint ResourceManager::createProgram()
112 {
113 GLuint name = mProgramShaderNameSpace.allocate();
114
115 mProgramNameSpace.insert(name, new Program(this, name));
116
117 return name;
118 }
119
120 // Returns an unused texture name
createTexture()121 GLuint ResourceManager::createTexture()
122 {
123 return mTextureNameSpace.allocate();
124 }
125
126 // Returns an unused renderbuffer name
createRenderbuffer()127 GLuint ResourceManager::createRenderbuffer()
128 {
129 return mRenderbufferNameSpace.allocate();
130 }
131
132 // Returns an unused sampler name
createSampler()133 GLuint ResourceManager::createSampler()
134 {
135 return mSamplerNameSpace.allocate();
136 }
137
138 // Returns the next unused fence name, and allocates the fence
createFenceSync(GLenum condition,GLbitfield flags)139 GLuint ResourceManager::createFenceSync(GLenum condition, GLbitfield flags)
140 {
141 GLuint name = mFenceSyncNameSpace.allocate();
142
143 FenceSync *fenceSync = new FenceSync(name, condition, flags);
144 fenceSync->addRef();
145
146 mFenceSyncNameSpace.insert(name, fenceSync);
147
148 return name;
149 }
150
deleteBuffer(GLuint buffer)151 void ResourceManager::deleteBuffer(GLuint buffer)
152 {
153 Buffer *bufferObject = mBufferNameSpace.remove(buffer);
154
155 if(bufferObject)
156 {
157 bufferObject->release();
158 }
159 }
160
deleteShader(GLuint shader)161 void ResourceManager::deleteShader(GLuint shader)
162 {
163 Shader *shaderObject = mShaderNameSpace.find(shader);
164
165 if(shaderObject)
166 {
167 if(shaderObject->getRefCount() == 0)
168 {
169 delete shaderObject;
170 mShaderNameSpace.remove(shader);
171 mProgramShaderNameSpace.remove(shader);
172 }
173 else
174 {
175 shaderObject->flagForDeletion();
176 }
177 }
178 }
179
deleteProgram(GLuint program)180 void ResourceManager::deleteProgram(GLuint program)
181 {
182 Program *programObject = mProgramNameSpace.find(program);
183
184 if(programObject)
185 {
186 if(programObject->getRefCount() == 0)
187 {
188 delete programObject;
189 mProgramNameSpace.remove(program);
190 mProgramShaderNameSpace.remove(program);
191 }
192 else
193 {
194 programObject->flagForDeletion();
195 }
196 }
197 }
198
deleteTexture(GLuint texture)199 void ResourceManager::deleteTexture(GLuint texture)
200 {
201 Texture *textureObject = mTextureNameSpace.remove(texture);
202
203 if(textureObject)
204 {
205 textureObject->release();
206 }
207 }
208
deleteRenderbuffer(GLuint renderbuffer)209 void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
210 {
211 Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
212
213 if(renderbufferObject)
214 {
215 renderbufferObject->release();
216 }
217 }
218
deleteSampler(GLuint sampler)219 void ResourceManager::deleteSampler(GLuint sampler)
220 {
221 Sampler *samplerObject = mSamplerNameSpace.remove(sampler);
222
223 if(samplerObject)
224 {
225 samplerObject->release();
226 }
227 }
228
deleteFenceSync(GLuint fenceSync)229 void ResourceManager::deleteFenceSync(GLuint fenceSync)
230 {
231 FenceSync *fenceObject = mFenceSyncNameSpace.remove(fenceSync);
232
233 if(fenceObject)
234 {
235 fenceObject->release();
236 }
237 }
238
getBuffer(unsigned int handle)239 Buffer *ResourceManager::getBuffer(unsigned int handle)
240 {
241 return mBufferNameSpace.find(handle);
242 }
243
getShader(unsigned int handle)244 Shader *ResourceManager::getShader(unsigned int handle)
245 {
246 return mShaderNameSpace.find(handle);
247 }
248
getTexture(unsigned int handle)249 Texture *ResourceManager::getTexture(unsigned int handle)
250 {
251 return mTextureNameSpace.find(handle);
252 }
253
getProgram(unsigned int handle)254 Program *ResourceManager::getProgram(unsigned int handle)
255 {
256 return mProgramNameSpace.find(handle);
257 }
258
getRenderbuffer(unsigned int handle)259 Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
260 {
261 return mRenderbufferNameSpace.find(handle);
262 }
263
getSampler(unsigned int handle)264 Sampler *ResourceManager::getSampler(unsigned int handle)
265 {
266 return mSamplerNameSpace.find(handle);
267 }
268
getFenceSync(unsigned int handle)269 FenceSync *ResourceManager::getFenceSync(unsigned int handle)
270 {
271 return mFenceSyncNameSpace.find(handle);
272 }
273
checkBufferAllocation(unsigned int buffer)274 void ResourceManager::checkBufferAllocation(unsigned int buffer)
275 {
276 if(buffer != 0 && !getBuffer(buffer))
277 {
278 Buffer *bufferObject = new Buffer(buffer);
279 bufferObject->addRef();
280
281 mBufferNameSpace.insert(buffer, bufferObject);
282 }
283 }
284
checkTextureAllocation(GLuint texture,TextureType type)285 void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
286 {
287 if(!getTexture(texture) && texture != 0)
288 {
289 Texture *textureObject;
290
291 if(type == TEXTURE_2D)
292 {
293 textureObject = new Texture2D(texture);
294 }
295 else if(type == TEXTURE_CUBE)
296 {
297 textureObject = new TextureCubeMap(texture);
298 }
299 else if(type == TEXTURE_EXTERNAL)
300 {
301 textureObject = new TextureExternal(texture);
302 }
303 else if(type == TEXTURE_3D)
304 {
305 textureObject = new Texture3D(texture);
306 }
307 else if(type == TEXTURE_2D_ARRAY)
308 {
309 textureObject = new Texture2DArray(texture);
310 }
311 else
312 {
313 UNREACHABLE(type);
314 return;
315 }
316
317 textureObject->addRef();
318
319 mTextureNameSpace.insert(texture, textureObject);
320 }
321 }
322
checkRenderbufferAllocation(GLuint handle)323 void ResourceManager::checkRenderbufferAllocation(GLuint handle)
324 {
325 if(handle != 0 && !getRenderbuffer(handle))
326 {
327 Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_RGBA4_OES, 0));
328 renderbufferObject->addRef();
329
330 mRenderbufferNameSpace.insert(handle, renderbufferObject);
331 }
332 }
333
checkSamplerAllocation(GLuint sampler)334 void ResourceManager::checkSamplerAllocation(GLuint sampler)
335 {
336 if(sampler != 0 && !getSampler(sampler))
337 {
338 Sampler *samplerObject = new Sampler(sampler);
339 samplerObject->addRef();
340
341 mSamplerNameSpace.insert(sampler, samplerObject);
342 }
343 }
344
isSampler(GLuint sampler)345 bool ResourceManager::isSampler(GLuint sampler)
346 {
347 return mSamplerNameSpace.isReserved(sampler);
348 }
349
350 }
351