1#include "precompiled.h"
2//
3// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and
9// retrieves objects which may be shared by multiple Contexts.
10
11#include "libGLESv2/ResourceManager.h"
12
13#include "libGLESv2/Buffer.h"
14#include "libGLESv2/Program.h"
15#include "libGLESv2/Renderbuffer.h"
16#include "libGLESv2/Shader.h"
17#include "libGLESv2/Texture.h"
18#include "libGLESv2/Sampler.h"
19#include "libGLESv2/Fence.h"
20
21namespace gl
22{
23ResourceManager::ResourceManager(rx::Renderer *renderer)
24{
25    mRefCount = 1;
26    mRenderer = renderer;
27}
28
29ResourceManager::~ResourceManager()
30{
31    while (!mBufferMap.empty())
32    {
33        deleteBuffer(mBufferMap.begin()->first);
34    }
35
36    while (!mProgramMap.empty())
37    {
38        deleteProgram(mProgramMap.begin()->first);
39    }
40
41    while (!mShaderMap.empty())
42    {
43        deleteShader(mShaderMap.begin()->first);
44    }
45
46    while (!mRenderbufferMap.empty())
47    {
48        deleteRenderbuffer(mRenderbufferMap.begin()->first);
49    }
50
51    while (!mTextureMap.empty())
52    {
53        deleteTexture(mTextureMap.begin()->first);
54    }
55
56    while (!mSamplerMap.empty())
57    {
58        deleteSampler(mSamplerMap.begin()->first);
59    }
60
61    while (!mFenceSyncMap.empty())
62    {
63        deleteFenceSync(mFenceSyncMap.begin()->first);
64    }
65}
66
67void ResourceManager::addRef()
68{
69    mRefCount++;
70}
71
72void ResourceManager::release()
73{
74    if (--mRefCount == 0)
75    {
76        delete this;
77    }
78}
79
80// Returns an unused buffer name
81GLuint ResourceManager::createBuffer()
82{
83    GLuint handle = mBufferHandleAllocator.allocate();
84
85    mBufferMap[handle] = NULL;
86
87    return handle;
88}
89
90// Returns an unused shader/program name
91GLuint ResourceManager::createShader(GLenum type)
92{
93    GLuint handle = mProgramShaderHandleAllocator.allocate();
94
95    if (type == GL_VERTEX_SHADER)
96    {
97        mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
98    }
99    else if (type == GL_FRAGMENT_SHADER)
100    {
101        mShaderMap[handle] = new FragmentShader(this, mRenderer, handle);
102    }
103    else UNREACHABLE();
104
105    return handle;
106}
107
108// Returns an unused program/shader name
109GLuint ResourceManager::createProgram()
110{
111    GLuint handle = mProgramShaderHandleAllocator.allocate();
112
113    mProgramMap[handle] = new Program(mRenderer, this, handle);
114
115    return handle;
116}
117
118// Returns an unused texture name
119GLuint ResourceManager::createTexture()
120{
121    GLuint handle = mTextureHandleAllocator.allocate();
122
123    mTextureMap[handle] = NULL;
124
125    return handle;
126}
127
128// Returns an unused renderbuffer name
129GLuint ResourceManager::createRenderbuffer()
130{
131    GLuint handle = mRenderbufferHandleAllocator.allocate();
132
133    mRenderbufferMap[handle] = NULL;
134
135    return handle;
136}
137
138// Returns an unused sampler name
139GLuint ResourceManager::createSampler()
140{
141    GLuint handle = mSamplerHandleAllocator.allocate();
142
143    mSamplerMap[handle] = NULL;
144
145    return handle;
146}
147
148// Returns the next unused fence name, and allocates the fence
149GLuint ResourceManager::createFenceSync()
150{
151    GLuint handle = mFenceSyncHandleAllocator.allocate();
152
153    mFenceSyncMap[handle] = new FenceSync(mRenderer, handle);
154
155    return handle;
156}
157
158void ResourceManager::deleteBuffer(GLuint buffer)
159{
160    BufferMap::iterator bufferObject = mBufferMap.find(buffer);
161
162    if (bufferObject != mBufferMap.end())
163    {
164        mBufferHandleAllocator.release(bufferObject->first);
165        if (bufferObject->second) bufferObject->second->release();
166        mBufferMap.erase(bufferObject);
167    }
168}
169
170void ResourceManager::deleteShader(GLuint shader)
171{
172    ShaderMap::iterator shaderObject = mShaderMap.find(shader);
173
174    if (shaderObject != mShaderMap.end())
175    {
176        if (shaderObject->second->getRefCount() == 0)
177        {
178            mProgramShaderHandleAllocator.release(shaderObject->first);
179            delete shaderObject->second;
180            mShaderMap.erase(shaderObject);
181        }
182        else
183        {
184            shaderObject->second->flagForDeletion();
185        }
186    }
187}
188
189void ResourceManager::deleteProgram(GLuint program)
190{
191    ProgramMap::iterator programObject = mProgramMap.find(program);
192
193    if (programObject != mProgramMap.end())
194    {
195        if (programObject->second->getRefCount() == 0)
196        {
197            mProgramShaderHandleAllocator.release(programObject->first);
198            delete programObject->second;
199            mProgramMap.erase(programObject);
200        }
201        else
202        {
203            programObject->second->flagForDeletion();
204        }
205    }
206}
207
208void ResourceManager::deleteTexture(GLuint texture)
209{
210    TextureMap::iterator textureObject = mTextureMap.find(texture);
211
212    if (textureObject != mTextureMap.end())
213    {
214        mTextureHandleAllocator.release(textureObject->first);
215        if (textureObject->second) textureObject->second->release();
216        mTextureMap.erase(textureObject);
217    }
218}
219
220void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
221{
222    RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
223
224    if (renderbufferObject != mRenderbufferMap.end())
225    {
226        mRenderbufferHandleAllocator.release(renderbufferObject->first);
227        if (renderbufferObject->second) renderbufferObject->second->release();
228        mRenderbufferMap.erase(renderbufferObject);
229    }
230}
231
232void ResourceManager::deleteSampler(GLuint sampler)
233{
234    auto samplerObject = mSamplerMap.find(sampler);
235
236    if (samplerObject != mSamplerMap.end())
237    {
238        mSamplerHandleAllocator.release(samplerObject->first);
239        if (samplerObject->second) samplerObject->second->release();
240        mSamplerMap.erase(samplerObject);
241    }
242}
243
244void ResourceManager::deleteFenceSync(GLuint fenceSync)
245{
246    auto fenceObjectIt = mFenceSyncMap.find(fenceSync);
247
248    if (fenceObjectIt != mFenceSyncMap.end())
249    {
250        mFenceSyncHandleAllocator.release(fenceObjectIt->first);
251        if (fenceObjectIt->second) fenceObjectIt->second->release();
252        mFenceSyncMap.erase(fenceObjectIt);
253    }
254}
255
256Buffer *ResourceManager::getBuffer(unsigned int handle)
257{
258    BufferMap::iterator buffer = mBufferMap.find(handle);
259
260    if (buffer == mBufferMap.end())
261    {
262        return NULL;
263    }
264    else
265    {
266        return buffer->second;
267    }
268}
269
270Shader *ResourceManager::getShader(unsigned int handle)
271{
272    ShaderMap::iterator shader = mShaderMap.find(handle);
273
274    if (shader == mShaderMap.end())
275    {
276        return NULL;
277    }
278    else
279    {
280        return shader->second;
281    }
282}
283
284Texture *ResourceManager::getTexture(unsigned int handle)
285{
286    if (handle == 0) return NULL;
287
288    TextureMap::iterator texture = mTextureMap.find(handle);
289
290    if (texture == mTextureMap.end())
291    {
292        return NULL;
293    }
294    else
295    {
296        return texture->second;
297    }
298}
299
300Program *ResourceManager::getProgram(unsigned int handle)
301{
302    ProgramMap::iterator program = mProgramMap.find(handle);
303
304    if (program == mProgramMap.end())
305    {
306        return NULL;
307    }
308    else
309    {
310        return program->second;
311    }
312}
313
314FramebufferAttachment *ResourceManager::getRenderbuffer(unsigned int handle)
315{
316    RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
317
318    if (renderbuffer == mRenderbufferMap.end())
319    {
320        return NULL;
321    }
322    else
323    {
324        return renderbuffer->second;
325    }
326}
327
328Sampler *ResourceManager::getSampler(unsigned int handle)
329{
330    auto sampler = mSamplerMap.find(handle);
331
332    if (sampler == mSamplerMap.end())
333    {
334        return NULL;
335    }
336    else
337    {
338        return sampler->second;
339    }
340}
341
342FenceSync *ResourceManager::getFenceSync(unsigned int handle)
343{
344    auto fenceObjectIt = mFenceSyncMap.find(handle);
345
346    if (fenceObjectIt == mFenceSyncMap.end())
347    {
348        return NULL;
349    }
350    else
351    {
352        return fenceObjectIt->second;
353    }
354}
355
356void ResourceManager::setRenderbuffer(GLuint handle, FramebufferAttachment *buffer)
357{
358    mRenderbufferMap[handle] = buffer;
359}
360
361void ResourceManager::checkBufferAllocation(unsigned int buffer)
362{
363    if (buffer != 0 && !getBuffer(buffer))
364    {
365        Buffer *bufferObject = new Buffer(mRenderer, buffer);
366        mBufferMap[buffer] = bufferObject;
367        bufferObject->addRef();
368    }
369}
370
371void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
372{
373    if (!getTexture(texture) && texture != 0)
374    {
375        Texture *textureObject;
376
377        if (type == TEXTURE_2D)
378        {
379            textureObject = new Texture2D(mRenderer, texture);
380        }
381        else if (type == TEXTURE_CUBE)
382        {
383            textureObject = new TextureCubeMap(mRenderer, texture);
384        }
385        else if (type == TEXTURE_3D)
386        {
387            textureObject = new Texture3D(mRenderer, texture);
388        }
389        else if (type == TEXTURE_2D_ARRAY)
390        {
391            textureObject = new Texture2DArray(mRenderer, texture);
392        }
393        else
394        {
395            UNREACHABLE();
396            return;
397        }
398
399        mTextureMap[texture] = textureObject;
400        textureObject->addRef();
401    }
402}
403
404void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
405{
406    if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
407    {
408        FramebufferAttachment *renderbufferObject = new FramebufferAttachment(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
409        mRenderbufferMap[renderbuffer] = renderbufferObject;
410        renderbufferObject->addRef();
411    }
412}
413
414void ResourceManager::checkSamplerAllocation(GLuint sampler)
415{
416    if (sampler != 0 && !getSampler(sampler))
417    {
418        Sampler *samplerObject = new Sampler(sampler);
419        mSamplerMap[sampler] = samplerObject;
420        samplerObject->addRef();
421    }
422}
423
424bool ResourceManager::isSampler(GLuint sampler)
425{
426    return mSamplerMap.find(sampler) != mSamplerMap.end();
427}
428
429}
430