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 | { |
30 | ResourceManager::ResourceManager() |
31 | { |
32 | mRefCount = 1; |
33 | } |
34 | |
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 | |
73 | void ResourceManager::addRef() |
74 | { |
75 | mRefCount++; |
76 | } |
77 | |
78 | void ResourceManager::release() |
79 | { |
80 | if(--mRefCount == 0) |
81 | { |
82 | delete this; |
83 | } |
84 | } |
85 | |
86 | // Returns an unused buffer name |
87 | GLuint ResourceManager::createBuffer() |
88 | { |
89 | return mBufferNameSpace.allocate(); |
90 | } |
91 | |
92 | // Returns an unused shader name |
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 |
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 |
121 | GLuint ResourceManager::createTexture() |
122 | { |
123 | return mTextureNameSpace.allocate(); |
124 | } |
125 | |
126 | // Returns an unused renderbuffer name |
127 | GLuint ResourceManager::createRenderbuffer() |
128 | { |
129 | return mRenderbufferNameSpace.allocate(); |
130 | } |
131 | |
132 | // Returns an unused sampler name |
133 | GLuint ResourceManager::createSampler() |
134 | { |
135 | return mSamplerNameSpace.allocate(); |
136 | } |
137 | |
138 | // Returns the next unused fence name, and allocates the fence |
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 | |
151 | void ResourceManager::deleteBuffer(GLuint buffer) |
152 | { |
153 | Buffer *bufferObject = mBufferNameSpace.remove(buffer); |
154 | |
155 | if(bufferObject) |
156 | { |
157 | bufferObject->release(); |
158 | } |
159 | } |
160 | |
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 | |
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 | |
199 | void ResourceManager::deleteTexture(GLuint texture) |
200 | { |
201 | Texture *textureObject = mTextureNameSpace.remove(texture); |
202 | |
203 | if(textureObject) |
204 | { |
205 | textureObject->release(); |
206 | } |
207 | } |
208 | |
209 | void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) |
210 | { |
211 | Renderbuffer *renderbufferObject = mRenderbufferNameSpace.remove(renderbuffer); |
212 | |
213 | if(renderbufferObject) |
214 | { |
215 | renderbufferObject->release(); |
216 | } |
217 | } |
218 | |
219 | void ResourceManager::deleteSampler(GLuint sampler) |
220 | { |
221 | Sampler *samplerObject = mSamplerNameSpace.remove(sampler); |
222 | |
223 | if(samplerObject) |
224 | { |
225 | samplerObject->release(); |
226 | } |
227 | } |
228 | |
229 | void ResourceManager::deleteFenceSync(GLuint fenceSync) |
230 | { |
231 | FenceSync *fenceObject = mFenceSyncNameSpace.remove(fenceSync); |
232 | |
233 | if(fenceObject) |
234 | { |
235 | fenceObject->release(); |
236 | } |
237 | } |
238 | |
239 | Buffer *ResourceManager::getBuffer(unsigned int handle) |
240 | { |
241 | return mBufferNameSpace.find(handle); |
242 | } |
243 | |
244 | Shader *ResourceManager::getShader(unsigned int handle) |
245 | { |
246 | return mShaderNameSpace.find(handle); |
247 | } |
248 | |
249 | Texture *ResourceManager::getTexture(unsigned int handle) |
250 | { |
251 | return mTextureNameSpace.find(handle); |
252 | } |
253 | |
254 | Program *ResourceManager::getProgram(unsigned int handle) |
255 | { |
256 | return mProgramNameSpace.find(handle); |
257 | } |
258 | |
259 | Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) |
260 | { |
261 | return mRenderbufferNameSpace.find(handle); |
262 | } |
263 | |
264 | Sampler *ResourceManager::getSampler(unsigned int handle) |
265 | { |
266 | return mSamplerNameSpace.find(handle); |
267 | } |
268 | |
269 | FenceSync *ResourceManager::getFenceSync(unsigned int handle) |
270 | { |
271 | return mFenceSyncNameSpace.find(handle); |
272 | } |
273 | |
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 | |
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 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 | |
327 | void 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 | |
338 | void 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 | |
349 | bool ResourceManager::isSampler(GLuint sampler) |
350 | { |
351 | return mSamplerNameSpace.isReserved(sampler); |
352 | } |
353 | |
354 | } |
355 | |