This source file includes following definitions.
- MakeIds
- FreeIds
- MarkAsUsedForBind
- FreeContext
- MakeIds
- FreeIds
- MarkAsUsedForBind
- FreeContext
- CollectPendingFreeIds
- MakeIds
- FreeIds
- MarkAsUsedForBind
- FreeContext
- set_program_info_manager
#include <stack>
#include <vector>
#include "gpu/command_buffer/client/share_group.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/client/program_info_manager.h"
#include "gpu/command_buffer/common/id_allocator.h"
namespace gpu {
namespace gles2 {
ShareGroupContextData::IdHandlerData::IdHandlerData() : flush_generation_(0) {}
ShareGroupContextData::IdHandlerData::~IdHandlerData() {}
COMPILE_ASSERT(gpu::kInvalidResource == 0,
INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
class IdHandler : public IdHandlerInterface {
public:
IdHandler() { }
virtual ~IdHandler() { }
virtual void MakeIds(
GLES2Implementation* ,
GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
base::AutoLock auto_lock(lock_);
if (id_offset == 0) {
for (GLsizei ii = 0; ii < n; ++ii) {
ids[ii] = id_allocator_.AllocateID();
}
} else {
for (GLsizei ii = 0; ii < n; ++ii) {
ids[ii] = id_allocator_.AllocateIDAtOrAbove(id_offset);
id_offset = ids[ii] + 1;
}
}
}
virtual bool FreeIds(
GLES2Implementation* gl_impl,
GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
base::AutoLock auto_lock(lock_);
for (GLsizei ii = 0; ii < n; ++ii) {
id_allocator_.FreeID(ids[ii]);
}
(gl_impl->*delete_fn)(n, ids);
gl_impl->helper()->CommandBufferHelper::Flush();
return true;
}
virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
if (id == 0)
return true;
base::AutoLock auto_lock(lock_);
return id_allocator_.MarkAsUsed(id);
}
virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
private:
base::Lock lock_;
IdAllocator id_allocator_;
};
class StrictIdHandler : public IdHandlerInterface {
public:
explicit StrictIdHandler(int id_namespace) : id_namespace_(id_namespace) {}
virtual ~StrictIdHandler() {}
virtual void MakeIds(GLES2Implementation* gl_impl,
GLuint ,
GLsizei n,
GLuint* ids) OVERRIDE {
base::AutoLock auto_lock(lock_);
CollectPendingFreeIds(gl_impl);
for (GLsizei ii = 0; ii < n; ++ii) {
if (!free_ids_.empty()) {
ids[ii] = free_ids_.top();
free_ids_.pop();
DCHECK(id_states_[ids[ii] - 1] == kIdFree);
id_states_[ids[ii] - 1] = kIdInUse;
} else {
id_states_.push_back(kIdInUse);
ids[ii] = id_states_.size();
}
}
}
virtual bool FreeIds(GLES2Implementation* gl_impl,
GLsizei n,
const GLuint* ids,
DeleteFn delete_fn) OVERRIDE {
(gl_impl->*delete_fn)(n, ids);
{
base::AutoLock auto_lock(lock_);
CollectPendingFreeIds(gl_impl);
ShareGroupContextData::IdHandlerData* ctxt_data =
gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
for (GLsizei ii = 0; ii < n; ++ii) {
GLuint id = ids[ii];
if (id != 0) {
DCHECK(id_states_[id - 1] == kIdInUse);
id_states_[id - 1] = kIdPendingFree;
ctxt_data->freed_ids_.push_back(id);
}
}
}
return true;
}
virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
#ifndef NDEBUG
if (id != 0) {
base::AutoLock auto_lock(lock_);
DCHECK(id_states_[id - 1] == kIdInUse);
}
#endif
return true;
}
virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {
base::AutoLock auto_lock(lock_);
CollectPendingFreeIds(gl_impl);
}
private:
enum IdState { kIdFree, kIdPendingFree, kIdInUse };
void CollectPendingFreeIds(GLES2Implementation* gl_impl) {
uint32 flush_generation = gl_impl->helper()->flush_generation();
ShareGroupContextData::IdHandlerData* ctxt_data =
gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
if (ctxt_data->flush_generation_ != flush_generation) {
ctxt_data->flush_generation_ = flush_generation;
for (uint32 ii = 0; ii < ctxt_data->freed_ids_.size(); ++ii) {
const GLuint id = ctxt_data->freed_ids_[ii];
DCHECK(id_states_[id - 1] == kIdPendingFree);
id_states_[id - 1] = kIdFree;
free_ids_.push(id);
}
ctxt_data->freed_ids_.clear();
}
}
int id_namespace_;
base::Lock lock_;
std::vector<uint8> id_states_;
std::stack<uint32> free_ids_;
};
class NonReusedIdHandler : public IdHandlerInterface {
public:
NonReusedIdHandler() : last_id_(0) {}
virtual ~NonReusedIdHandler() {}
virtual void MakeIds(
GLES2Implementation* ,
GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE {
base::AutoLock auto_lock(lock_);
for (GLsizei ii = 0; ii < n; ++ii) {
ids[ii] = ++last_id_ + id_offset;
}
}
virtual bool FreeIds(
GLES2Implementation* gl_impl,
GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
(gl_impl->*delete_fn)(n, ids);
return true;
}
virtual bool MarkAsUsedForBind(GLuint ) OVERRIDE {
return false;
}
virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
private:
base::Lock lock_;
GLuint last_id_;
};
ShareGroup::ShareGroup(bool bind_generates_resource)
: bind_generates_resource_(bind_generates_resource) {
if (bind_generates_resource) {
for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
if (i == id_namespaces::kProgramsAndShaders) {
id_handlers_[i].reset(new NonReusedIdHandler());
} else {
id_handlers_[i].reset(new IdHandler());
}
}
} else {
for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) {
if (i == id_namespaces::kProgramsAndShaders) {
id_handlers_[i].reset(new NonReusedIdHandler());
} else {
id_handlers_[i].reset(new StrictIdHandler(i));
}
}
}
program_info_manager_.reset(ProgramInfoManager::Create(false));
}
void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) {
program_info_manager_.reset(manager);
}
ShareGroup::~ShareGroup() {}
}
}