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
28namespace es2
29{
30ResourceManager::ResourceManager()
31{
32 mRefCount = 1;
33}
34
35ResourceManager::~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
73void ResourceManager::addRef()
74{
75 mRefCount++;
76}
77
78void ResourceManager::release()
79{
80 if(--mRefCount == 0)
81 {
82 delete this;
83 }
84}
85
86// Returns an unused buffer name
87GLuint ResourceManager::createBuffer()
88{
89 return mBufferNameSpace.allocate();
90}
91
92// Returns an unused shader name
93GLuint 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
111GLuint 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
121GLuint ResourceManager::createTexture()
122{
123 return mTextureNameSpace.allocate();
124}
125
126// Returns an unused renderbuffer name
127GLuint ResourceManager::createRenderbuffer()
128{
129 return mRenderbufferNameSpace.allocate();
130}
131
132// Returns an unused sampler name
133GLuint ResourceManager::createSampler()
134{
135 return mSamplerNameSpace.allocate();
136}
137
138// Returns the next unused fence name, and allocates the fence
139GLuint 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
151void ResourceManager::deleteBuffer(GLuint buffer)
152{
153 Buffer *bufferObject = mBufferNameSpace.remove(buffer);
154
155 if(bufferObject)
156 {
157 bufferObject->release();
158 }
159}
160
161void 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
180void 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
199void ResourceManager::deleteTexture(GLuint texture)
200{
201 Texture *textureObject = mTextureNameSpace.remove(texture);
202
203 if(textureObject)
204 {
205 textureObject->release();
206 }
207}
208
209void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
210{
211 Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer);
212
213 if(renderbufferObject)
214 {
215 renderbufferObject->release();
216 }
217}
218
219void ResourceManager::deleteSampler(GLuint sampler)
220{
221 Sampler *samplerObject = mSamplerNameSpace.remove(sampler);
222
223 if(samplerObject)
224 {
225 samplerObject->release();
226 }
227}
228
229void ResourceManager::deleteFenceSync(GLuint fenceSync)
230{
231 FenceSync *fenceObject = mFenceSyncNameSpace.remove(fenceSync);
232
233 if(fenceObject)
234 {
235 fenceObject->release();
236 }
237}
238
239Buffer *ResourceManager::getBuffer(unsigned int handle)
240{
241 return mBufferNameSpace.find(handle);
242}
243
244Shader *ResourceManager::getShader(unsigned int handle)
245{
246 return mShaderNameSpace.find(handle);
247}
248
249Texture *ResourceManager::getTexture(unsigned int handle)
250{
251 return mTextureNameSpace.find(handle);
252}
253
254Program *ResourceManager::getProgram(unsigned int handle)
255{
256 return mProgramNameSpace.find(handle);
257}
258
259Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
260{
261 return mRenderbufferNameSpace.find(handle);
262}
263
264Sampler *ResourceManager::getSampler(unsigned int handle)
265{
266 return mSamplerNameSpace.find(handle);
267}
268
269FenceSync *ResourceManager::getFenceSync(unsigned int handle)
270{
271 return mFenceSyncNameSpace.find(handle);
272}
273
274void 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
285void 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 if(type == TEXTURE_2D_RECT)
312 {
313 textureObject = new Texture2DRect(texture);
314 }
315 else
316 {
317 UNREACHABLE(type);
318 return;
319 }
320
321 textureObject->addRef();
322
323 mTextureNameSpace.insert(texture, textureObject);
324 }
325}
326
327void ResourceManager::checkRenderbufferAllocation(GLuint handle)
328{
329 if(handle != 0 && !getRenderbuffer(handle))
330 {
331 Renderbuffer *renderbufferObject = new Renderbuffer(handle, new Colorbuffer(0, 0, GL_NONE, 0));
332 renderbufferObject->addRef();
333
334 mRenderbufferNameSpace.insert(handle, renderbufferObject);
335 }
336}
337
338void ResourceManager::checkSamplerAllocation(GLuint sampler)
339{
340 if(sampler != 0 && !getSampler(sampler))
341 {
342 Sampler *samplerObject = new Sampler(sampler);
343 samplerObject->addRef();
344
345 mSamplerNameSpace.insert(sampler, samplerObject);
346 }
347}
348
349bool ResourceManager::isSampler(GLuint sampler)
350{
351 return mSamplerNameSpace.isReserved(sampler);
352}
353
354}
355