Commit 1a23334f by benvanik@google.com

Unifying resource handle allocation code with an allocator optimized for O(1) allocs/releases.

Issue=143 Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/trunk@623 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent aa614605
...@@ -165,6 +165,8 @@ ...@@ -165,6 +165,8 @@
'libGLESv2/Fence.h', 'libGLESv2/Fence.h',
'libGLESv2/Framebuffer.cpp', 'libGLESv2/Framebuffer.cpp',
'libGLESv2/Framebuffer.h', 'libGLESv2/Framebuffer.h',
'libGLESv2/HandleAllocator.cpp',
'libGLESv2/HandleAllocator.h',
'libGLESv2/libGLESv2.cpp', 'libGLESv2/libGLESv2.cpp',
'libGLESv2/libGLESv2.def', 'libGLESv2/libGLESv2.def',
'libGLESv2/main.cpp', 'libGLESv2/main.cpp',
......
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 622 #define BUILD_REVISION 623
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -35,6 +35,8 @@ namespace gl ...@@ -35,6 +35,8 @@ namespace gl
{ {
Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config) Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
{ {
mFenceHandleAllocator.setBaseHandle(0);
setClearColor(0.0f, 0.0f, 0.0f, 0.0f); setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
mState.depthClearValue = 1.0f; mState.depthClearValue = 1.0f;
...@@ -818,12 +820,7 @@ GLuint Context::createRenderbuffer() ...@@ -818,12 +820,7 @@ GLuint Context::createRenderbuffer()
// Returns an unused framebuffer name // Returns an unused framebuffer name
GLuint Context::createFramebuffer() GLuint Context::createFramebuffer()
{ {
unsigned int handle = 1; GLuint handle = mFramebufferHandleAllocator.allocate();
while (mFramebufferMap.find(handle) != mFramebufferMap.end())
{
handle++;
}
mFramebufferMap[handle] = NULL; mFramebufferMap[handle] = NULL;
...@@ -832,12 +829,7 @@ GLuint Context::createFramebuffer() ...@@ -832,12 +829,7 @@ GLuint Context::createFramebuffer()
GLuint Context::createFence() GLuint Context::createFence()
{ {
unsigned int handle = 0; GLuint handle = mFenceHandleAllocator.allocate();
while (mFenceMap.find(handle) != mFenceMap.end())
{
handle++;
}
mFenceMap[handle] = new Fence; mFenceMap[handle] = new Fence;
...@@ -892,6 +884,7 @@ void Context::deleteFramebuffer(GLuint framebuffer) ...@@ -892,6 +884,7 @@ void Context::deleteFramebuffer(GLuint framebuffer)
{ {
detachFramebuffer(framebuffer); detachFramebuffer(framebuffer);
mFramebufferHandleAllocator.release(framebufferObject->first);
delete framebufferObject->second; delete framebufferObject->second;
mFramebufferMap.erase(framebufferObject); mFramebufferMap.erase(framebufferObject);
} }
...@@ -903,6 +896,7 @@ void Context::deleteFence(GLuint fence) ...@@ -903,6 +896,7 @@ void Context::deleteFence(GLuint fence)
if (fenceObject != mFenceMap.end()) if (fenceObject != mFenceMap.end())
{ {
mFenceHandleAllocator.release(fenceObject->first);
delete fenceObject->second; delete fenceObject->second;
mFenceMap.erase(fenceObject); mFenceMap.erase(fenceObject);
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libGLESv2/ResourceManager.h" #include "libGLESv2/ResourceManager.h"
#include "libGLESv2/HandleAllocator.h"
#include "libGLESv2/RefCountObject.h" #include "libGLESv2/RefCountObject.h"
namespace egl namespace egl
...@@ -480,9 +481,11 @@ class Context ...@@ -480,9 +481,11 @@ class Context
typedef std::map<GLuint, Framebuffer*> FramebufferMap; typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap; FramebufferMap mFramebufferMap;
HandleAllocator mFramebufferHandleAllocator;
typedef std::map<GLuint, Fence*> FenceMap; typedef std::map<GLuint, Fence*> FenceMap;
FenceMap mFenceMap; FenceMap mFenceMap;
HandleAllocator mFenceHandleAllocator;
void initExtensionString(); void initExtensionString();
std::string mExtensionString; std::string mExtensionString;
......
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used
// to allocate GL handles.
#include "libGLESv2/HandleAllocator.h"
#include "libGLESv2/main.h"
namespace gl
{
HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1)
{
}
HandleAllocator::~HandleAllocator()
{
}
void HandleAllocator::setBaseHandle(GLuint value)
{
ASSERT(mBaseValue == mNextValue);
mBaseValue = value;
mNextValue = value;
}
GLuint HandleAllocator::allocate()
{
if (mFreeValues.size())
{
GLuint handle = mFreeValues.back();
mFreeValues.pop_back();
return handle;
}
return mNextValue++;
}
void HandleAllocator::release(GLuint handle)
{
if (handle == mNextValue - 1)
{
ASSERT(mBaseValue < mNextValue);
mNextValue--;
return;
}
mFreeValues.push_back(handle);
}
}
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// HandleAllocator.h: Defines the gl::HandleAllocator class, which is used to
// allocate GL handles.
#ifndef LIBGLESV2_HANDLEALLOCATOR_H_
#define LIBGLESV2_HANDLEALLOCATOR_H_
#define GL_APICALL
#include <GLES2/gl2.h>
#include <vector>
#include "common/angleutils.h"
namespace gl
{
class HandleAllocator
{
public:
HandleAllocator();
virtual ~HandleAllocator();
void setBaseHandle(GLuint value);
GLuint allocate();
void release(GLuint handle);
private:
DISALLOW_COPY_AND_ASSIGN(HandleAllocator);
GLuint mBaseValue;
GLuint mNextValue;
typedef std::vector<GLuint> HandleList;
HandleList mFreeValues;
};
}
#endif // LIBGLESV2_HANDLEALLOCATOR_H_
...@@ -66,12 +66,7 @@ void ResourceManager::release() ...@@ -66,12 +66,7 @@ void ResourceManager::release()
// Returns an unused buffer name // Returns an unused buffer name
GLuint ResourceManager::createBuffer() GLuint ResourceManager::createBuffer()
{ {
unsigned int handle = 1; GLuint handle = mBufferHandleAllocator.allocate();
while (mBufferMap.find(handle) != mBufferMap.end())
{
handle++;
}
mBufferMap[handle] = NULL; mBufferMap[handle] = NULL;
...@@ -81,12 +76,7 @@ GLuint ResourceManager::createBuffer() ...@@ -81,12 +76,7 @@ GLuint ResourceManager::createBuffer()
// Returns an unused shader/program name // Returns an unused shader/program name
GLuint ResourceManager::createShader(GLenum type) GLuint ResourceManager::createShader(GLenum type)
{ {
unsigned int handle = 1; GLuint handle = mProgramShaderHandleAllocator.allocate();
while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space
{
handle++;
}
if (type == GL_VERTEX_SHADER) if (type == GL_VERTEX_SHADER)
{ {
...@@ -104,12 +94,7 @@ GLuint ResourceManager::createShader(GLenum type) ...@@ -104,12 +94,7 @@ GLuint ResourceManager::createShader(GLenum type)
// Returns an unused program/shader name // Returns an unused program/shader name
GLuint ResourceManager::createProgram() GLuint ResourceManager::createProgram()
{ {
unsigned int handle = 1; GLuint handle = mProgramShaderHandleAllocator.allocate();
while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space
{
handle++;
}
mProgramMap[handle] = new Program(this, handle); mProgramMap[handle] = new Program(this, handle);
...@@ -119,12 +104,7 @@ GLuint ResourceManager::createProgram() ...@@ -119,12 +104,7 @@ GLuint ResourceManager::createProgram()
// Returns an unused texture name // Returns an unused texture name
GLuint ResourceManager::createTexture() GLuint ResourceManager::createTexture()
{ {
unsigned int handle = 1; GLuint handle = mTextureHandleAllocator.allocate();
while (mTextureMap.find(handle) != mTextureMap.end())
{
handle++;
}
mTextureMap[handle] = NULL; mTextureMap[handle] = NULL;
...@@ -134,12 +114,7 @@ GLuint ResourceManager::createTexture() ...@@ -134,12 +114,7 @@ GLuint ResourceManager::createTexture()
// Returns an unused renderbuffer name // Returns an unused renderbuffer name
GLuint ResourceManager::createRenderbuffer() GLuint ResourceManager::createRenderbuffer()
{ {
unsigned int handle = 1; GLuint handle = mRenderbufferHandleAllocator.allocate();
while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
{
handle++;
}
mRenderbufferMap[handle] = NULL; mRenderbufferMap[handle] = NULL;
...@@ -152,6 +127,7 @@ void ResourceManager::deleteBuffer(GLuint buffer) ...@@ -152,6 +127,7 @@ void ResourceManager::deleteBuffer(GLuint buffer)
if (bufferObject != mBufferMap.end()) if (bufferObject != mBufferMap.end())
{ {
mBufferHandleAllocator.release(bufferObject->first);
if (bufferObject->second) bufferObject->second->release(); if (bufferObject->second) bufferObject->second->release();
mBufferMap.erase(bufferObject); mBufferMap.erase(bufferObject);
} }
...@@ -165,6 +141,7 @@ void ResourceManager::deleteShader(GLuint shader) ...@@ -165,6 +141,7 @@ void ResourceManager::deleteShader(GLuint shader)
{ {
if (shaderObject->second->getRefCount() == 0) if (shaderObject->second->getRefCount() == 0)
{ {
mProgramShaderHandleAllocator.release(shaderObject->first);
delete shaderObject->second; delete shaderObject->second;
mShaderMap.erase(shaderObject); mShaderMap.erase(shaderObject);
} }
...@@ -183,6 +160,7 @@ void ResourceManager::deleteProgram(GLuint program) ...@@ -183,6 +160,7 @@ void ResourceManager::deleteProgram(GLuint program)
{ {
if (programObject->second->getRefCount() == 0) if (programObject->second->getRefCount() == 0)
{ {
mProgramShaderHandleAllocator.release(programObject->first);
delete programObject->second; delete programObject->second;
mProgramMap.erase(programObject); mProgramMap.erase(programObject);
} }
...@@ -199,6 +177,7 @@ void ResourceManager::deleteTexture(GLuint texture) ...@@ -199,6 +177,7 @@ void ResourceManager::deleteTexture(GLuint texture)
if (textureObject != mTextureMap.end()) if (textureObject != mTextureMap.end())
{ {
mTextureHandleAllocator.release(textureObject->first);
if (textureObject->second) textureObject->second->release(); if (textureObject->second) textureObject->second->release();
mTextureMap.erase(textureObject); mTextureMap.erase(textureObject);
} }
...@@ -210,6 +189,7 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) ...@@ -210,6 +189,7 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
if (renderbufferObject != mRenderbufferMap.end()) if (renderbufferObject != mRenderbufferMap.end())
{ {
mRenderbufferHandleAllocator.release(renderbufferObject->first);
if (renderbufferObject->second) renderbufferObject->second->release(); if (renderbufferObject->second) renderbufferObject->second->release();
mRenderbufferMap.erase(renderbufferObject); mRenderbufferMap.erase(renderbufferObject);
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <hash_map> #include <hash_map>
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libGLESv2/HandleAllocator.h"
namespace gl namespace gl
{ {
...@@ -73,18 +74,22 @@ class ResourceManager ...@@ -73,18 +74,22 @@ class ResourceManager
typedef stdext::hash_map<GLuint, Buffer*> BufferMap; typedef stdext::hash_map<GLuint, Buffer*> BufferMap;
BufferMap mBufferMap; BufferMap mBufferMap;
HandleAllocator mBufferHandleAllocator;
typedef stdext::hash_map<GLuint, Shader*> ShaderMap; typedef stdext::hash_map<GLuint, Shader*> ShaderMap;
ShaderMap mShaderMap; ShaderMap mShaderMap;
typedef stdext::hash_map<GLuint, Program*> ProgramMap; typedef stdext::hash_map<GLuint, Program*> ProgramMap;
ProgramMap mProgramMap; ProgramMap mProgramMap;
HandleAllocator mProgramShaderHandleAllocator;
typedef stdext::hash_map<GLuint, Texture*> TextureMap; typedef stdext::hash_map<GLuint, Texture*> TextureMap;
TextureMap mTextureMap; TextureMap mTextureMap;
HandleAllocator mTextureHandleAllocator;
typedef stdext::hash_map<GLuint, Renderbuffer*> RenderbufferMap; typedef stdext::hash_map<GLuint, Renderbuffer*> RenderbufferMap;
RenderbufferMap mRenderbufferMap; RenderbufferMap mRenderbufferMap;
HandleAllocator mRenderbufferHandleAllocator;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment