summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/client
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-13 08:26:55 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-13 08:26:55 +0000
commit51fd18b10aa37d57d2c4a42581e98423629780d0 (patch)
treeaa886011ab60473e364a1676f16c8fc5b34ca830 /gpu/command_buffer/client
parent2fe6c79fdf2d51e309bfd4d6a3b21cdf5442dc69 (diff)
downloadchromium_src-51fd18b10aa37d57d2c4a42581e98423629780d0.zip
chromium_src-51fd18b10aa37d57d2c4a42581e98423629780d0.tar.gz
chromium_src-51fd18b10aa37d57d2c4a42581e98423629780d0.tar.bz2
Reverting commit 44334
TEST=none BUG=none TBR=dumi@chromium.org git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44335 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/client')
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h5
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc552
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h137
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h110
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc677
-rw-r--r--gpu/command_buffer/client/id_allocator.cc49
-rw-r--r--gpu/command_buffer/client/id_allocator.h37
-rw-r--r--gpu/command_buffer/client/id_allocator_test.cc36
9 files changed, 137 insertions, 1473 deletions
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index c3e445a..777a2d6 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -503,11 +503,6 @@ void GLES2Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
void GLES2SwapBuffers() {
gles2::GetGLContext()->SwapBuffers();
}
-GLuint GLES2GetMaxValueInBuffer(
- GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
- return gles2::GetGLContext()->GetMaxValueInBuffer(
- buffer_id, count, type, offset);
-}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index bb37150..42f6608 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1120,12 +1120,5 @@
c.Init();
}
- void GetMaxValueInBuffer(
- GLuint buffer_id, GLsizei count, GLenum type, GLuint offset,
- uint32 result_shm_id, uint32 result_shm_offset) {
- gles2::GetMaxValueInBuffer& c = GetCmdSpace<gles2::GetMaxValueInBuffer>();
- c.Init(buffer_id, count, type, offset, result_shm_id, result_shm_offset);
- }
-
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index c39af8a..b3fe538 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -15,318 +15,10 @@ static GLuint ToGLuint(const void* ptr) {
return static_cast<GLuint>(reinterpret_cast<size_t>(ptr));
}
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
-static GLsizei RoundUpToMultipleOf4(GLsizei size) {
- return (size + 3) & ~3;
-}
-
-// This class tracks VertexAttribPointers and helps emulate client side buffers.
-//
-// The way client side buffers work is we shadow all the Vertex Attribs so we
-// know which ones are pointing to client side buffers.
-//
-// At Draw time, for any attribs pointing to client side buffers we copy them
-// to a special VBO and reset the actual vertex attrib pointers to point to this
-// VBO.
-//
-// This also means we have to catch calls to query those values so that when
-// an attrib is a client side buffer we pass the info back the user expects.
-class ClientSideBufferHelper {
- public:
- // Info about Vertex Attributes. This is used to track what the user currently
- // has bound on each Vertex Attribute so we can simulate client side buffers
- // at glDrawXXX time.
- class VertexAttribInfo {
- public:
- VertexAttribInfo()
- : enabled_(false),
- buffer_id_(0),
- size_(0),
- type_(0),
- normalized_(GL_FALSE),
- pointer_(NULL),
- gl_stride_(0) {
- }
-
- bool enabled() const {
- return enabled_;
- }
-
- void set_enabled(bool enabled) {
- enabled_ = enabled;
- }
-
- GLuint buffer_id() const {
- return buffer_id_;
- }
-
- GLenum type() const {
- return type_;
- }
-
- GLint size() const {
- return size_;
- }
-
- GLsizei stride() const {
- return gl_stride_;
- }
-
- GLboolean normalized() const {
- return normalized_;
- }
-
- const GLvoid* pointer() const {
- return pointer_;
- }
-
- bool IsClientSide() const {
- return buffer_id_ == 0;
- }
-
- void SetInfo(
- GLuint buffer_id,
- GLint size,
- GLenum type,
- GLboolean normalized,
- GLsizei gl_stride,
- const GLvoid* pointer) {
- buffer_id_ = buffer_id;
- size_ = size;
- type_ = type;
- normalized_ = normalized;
- gl_stride_ = gl_stride;
- pointer_ = pointer;
- }
-
- private:
- // Whether or not this attribute is enabled.
- bool enabled_;
-
- // The id of the buffer. 0 = client side buffer.
- GLuint buffer_id_;
-
- // Number of components (1, 2, 3, 4).
- GLint size_;
-
- // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer.
- GLenum type_;
-
- // GL_TRUE or GL_FALSE
- GLboolean normalized_;
-
- // The pointer/offset into the buffer.
- const GLvoid* pointer_;
-
- // The stride that will be used to access the buffer. This is the bogus GL
- // stride where 0 = compute the stride based on size and type.
- GLsizei gl_stride_;
- };
-
- ClientSideBufferHelper(GLuint max_vertex_attribs,
- GLuint array_buffer_id,
- GLuint element_array_buffer_id)
- : max_vertex_attribs_(max_vertex_attribs),
- num_client_side_pointers_enabled_(0),
- array_buffer_id_(array_buffer_id),
- array_buffer_size_(0),
- array_buffer_offset_(0),
- element_array_buffer_id_(element_array_buffer_id),
- element_array_buffer_size_(0),
- collection_buffer_size_(0) {
- vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs]);
- }
-
- bool HaveEnabledClientSideBuffers() const {
- return num_client_side_pointers_enabled_ > 0;
- }
-
- void SetAttribEnable(GLuint index, bool enabled) {
- if (index < max_vertex_attribs_) {
- VertexAttribInfo& info = vertex_attrib_infos_[index];
- if (info.enabled() != enabled) {
- if (info.IsClientSide()) {
- num_client_side_pointers_enabled_ += enabled ? 1 : -1;
- }
- info.set_enabled(enabled);
- }
- }
- }
-
- void SetAttribPointer(
- GLuint buffer_id,
- GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
- const void* ptr) {
- if (index < max_vertex_attribs_) {
- VertexAttribInfo& info = vertex_attrib_infos_[index];
- if (info.IsClientSide() && info.enabled()) {
- --num_client_side_pointers_enabled_;
- }
-
- info.SetInfo(buffer_id, size, type, normalized, stride, ptr);
-
- if (info.IsClientSide() && info.enabled()) {
- ++num_client_side_pointers_enabled_;
- }
- }
- }
-
- // Gets the Attrib pointer for an attrib but only if it's a client side
- // pointer. Returns true if it got the pointer.
- bool GetAttribPointer(GLuint index, GLenum pname, void** ptr) const {
- const VertexAttribInfo* info = GetAttribInfo(index);
- if (info && pname == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
- *ptr = const_cast<void*>(info->pointer());
- return true;
- }
- return false;
- }
-
- // Gets an attrib info if it's in range and it's client side.
- const VertexAttribInfo* GetAttribInfo(GLuint index) const {
- if (index < max_vertex_attribs_) {
- VertexAttribInfo* info = &vertex_attrib_infos_[index];
- if (info->IsClientSide()) {
- return info;
- }
- }
- return NULL;
- }
-
- // Collects the data into the collection buffer and returns the number of
- // bytes collected.
- GLsizei CollectData(const void* data,
- GLsizei bytes_per_element,
- GLsizei real_stride,
- GLsizei num_elements) {
- GLsizei bytes_needed = bytes_per_element * num_elements;
- if (collection_buffer_size_ < bytes_needed) {
- collection_buffer_.reset(new int8[bytes_needed]);
- collection_buffer_size_ = bytes_needed;
- }
- const int8* src = static_cast<const int8*>(data);
- int8* dst = collection_buffer_.get();
- int8* end = dst + bytes_per_element * num_elements;
- for (; dst < end; src += real_stride, dst += bytes_per_element) {
- memcpy(dst, src, bytes_per_element);
- }
- return bytes_needed;
- }
-
- // Returns true if buffers were setup.
- void SetupSimualtedClientSideBuffers(
- GLES2Implementation* gl,
- GLES2CmdHelper* gl_helper,
- GLsizei num_elements) {
- GLsizei total_size = 0;
- // Compute the size of the buffer we need.
- for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) {
- VertexAttribInfo& info = vertex_attrib_infos_[ii];
- if (info.IsClientSide() && info.enabled()) {
- size_t bytes_per_element =
- GLES2Util::GetGLTypeSizeForTexturesAndBuffers(info.type()) *
- info.size();
- total_size += RoundUpToMultipleOf4(
- bytes_per_element * num_elements);
- }
- }
- gl_helper->BindBuffer(GL_ARRAY_BUFFER, array_buffer_id_);
- array_buffer_offset_ = 0;
- if (total_size > array_buffer_size_) {
- gl->BufferData(GL_ARRAY_BUFFER, total_size, NULL, GL_DYNAMIC_DRAW);
- array_buffer_size_ = total_size;
- }
- for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) {
- VertexAttribInfo& info = vertex_attrib_infos_[ii];
- if (info.IsClientSide() && info.enabled()) {
- size_t bytes_per_element =
- GLES2Util::GetGLTypeSizeForTexturesAndBuffers(info.type()) *
- info.size();
- GLsizei real_stride =
- info.stride() ? info.stride() : bytes_per_element;
- GLsizei bytes_collected = CollectData(
- info.pointer(), bytes_per_element, real_stride, num_elements);
- gl->BufferSubData(
- GL_ARRAY_BUFFER, array_buffer_offset_, bytes_collected,
- collection_buffer_.get());
- gl_helper->VertexAttribPointer(
- ii, info.size(), info.type(), info.normalized(), 0,
- array_buffer_offset_);
- array_buffer_offset_ += RoundUpToMultipleOf4(bytes_collected);
- DCHECK_LE(array_buffer_offset_, array_buffer_size_);
- }
- }
- }
-
- // Copies in indices to the service and returns the highest index accessed + 1
- GLsizei SetupSimulatedIndexBuffer(
- GLES2Implementation* gl,
- GLES2CmdHelper* gl_helper,
- GLsizei count,
- GLenum type,
- const void* indices) {
- gl_helper->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_array_buffer_id_);
- GLsizei bytes_per_element =
- GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
- GLsizei bytes_needed = bytes_per_element * count;
- if (bytes_needed > element_array_buffer_size_) {
- element_array_buffer_size_ = bytes_needed;
- gl->BufferData(GL_ELEMENT_ARRAY_BUFFER, bytes_needed, NULL,
- GL_DYNAMIC_DRAW);
- }
- gl->BufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, bytes_needed, indices);
- GLsizei max_index = -1;
- switch (type) {
- case GL_UNSIGNED_BYTE: {
- const uint8* src = static_cast<const uint8*>(indices);
- for (GLsizei ii = 0; ii < count; ++ii) {
- if (src[ii] > max_index) {
- max_index = src[ii];
- }
- }
- break;
- }
- case GL_UNSIGNED_SHORT: {
- const uint16* src = static_cast<const uint16*>(indices);
- for (GLsizei ii = 0; ii < count; ++ii) {
- if (src[ii] > max_index) {
- max_index = src[ii];
- }
- }
- break;
- }
- default:
- break;
- }
- return max_index + 1;
- }
-
- private:
- GLuint max_vertex_attribs_;
- GLuint num_client_side_pointers_enabled_;
- GLuint array_buffer_id_;
- GLsizei array_buffer_size_;
- GLsizei array_buffer_offset_;
- GLuint element_array_buffer_id_;
- GLsizei element_array_buffer_size_;
- scoped_array<VertexAttribInfo> vertex_attrib_infos_;
- GLsizei collection_buffer_size_;
- scoped_array<int8> collection_buffer_;
-
- DISALLOW_COPY_AND_ASSIGN(ClientSideBufferHelper);
-};
-
-#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
-
#if !defined(COMPILER_MSVC)
const size_t GLES2Implementation::kMaxSizeOfSimpleResult;
#endif
-COMPILE_ASSERT(gpu::kInvalidResource == 0,
- INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
-
GLES2Implementation::GLES2Implementation(
GLES2CmdHelper* helper,
size_t transfer_buffer_size,
@@ -338,34 +30,16 @@ GLES2Implementation::GLES2Implementation(
transfer_buffer_id_(transfer_buffer_id),
pack_alignment_(4),
unpack_alignment_(4),
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- bound_array_buffer_id_(0),
- bound_element_array_buffer_id_(0),
-#endif
error_bits_(0) {
+ // Eat 1 id so we start at 1 instead of 0.
+ GLuint eat;
+ MakeIds(1, &eat);
// Allocate space for simple GL results.
result_buffer_ = transfer_buffer_.Alloc(kMaxSizeOfSimpleResult);
result_shm_offset_ = transfer_buffer_.GetOffset(result_buffer_);
-
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- GLint max_vertex_attribs;
- GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
- id_allocator_.MarkAsUsed(kClientSideArrayId);
- id_allocator_.MarkAsUsed(kClientSideElementArrayId);
-
- reserved_ids_[0] = kClientSideArrayId;
- reserved_ids_[1] = kClientSideElementArrayId;
-
- client_side_buffer_helper_.reset(new ClientSideBufferHelper(
- max_vertex_attribs,
- kClientSideArrayId,
- kClientSideElementArrayId));
-#endif
}
GLES2Implementation::~GLES2Implementation() {
- GLuint buffers[] = { kClientSideArrayId, kClientSideElementArrayId, };
- DeleteBuffers(arraysize(buffers), &buffers[0]);
transfer_buffer_.Free(result_buffer_);
}
@@ -504,50 +178,7 @@ void GLES2Implementation::SetBucketAsString(
void GLES2Implementation::DrawElements(
GLenum mode, GLsizei count, GLenum type, const void* indices) {
- if (count < 0) {
- SetGLError(GL_INVALID_VALUE);
- return;
- }
- if (count == 0) {
- return;
- }
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- bool have_client_side =
- client_side_buffer_helper_->HaveEnabledClientSideBuffers();
- GLsizei num_elements = 0;
- GLuint offset = ToGLuint(indices);
- if (bound_element_array_buffer_id_ == 0) {
- // Index buffer is client side array.
- // Copy to buffer, scan for highest index.
- num_elements = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
- this, helper_, count, type, indices);
- offset = 0;
- } else {
- // Index buffer is GL buffer. Ask the service for the highest vertex
- // that will be accessed. Note: It doesn't matter if another context
- // changes the contents of any of the buffers. The service will still
- // validate the indices. We just need to know how much to copy across.
- if (have_client_side) {
- num_elements = GetMaxValueInBuffer(
- bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
- }
- }
- if (have_client_side) {
- client_side_buffer_helper_->SetupSimualtedClientSideBuffers(
- this, helper_, num_elements);
- }
- helper_->DrawElements(mode, count, type, offset);
- if (have_client_side) {
- // Restore the user's current binding.
- helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
- }
- if (bound_element_array_buffer_id_ == 0) {
- // Restore the element array binding.
- helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
-#else
helper_->DrawElements(mode, count, type, ToGLuint(indices));
-#endif
}
void GLES2Implementation::Flush() {
@@ -581,20 +212,11 @@ void GLES2Implementation::BindAttribLocation(
void GLES2Implementation::GetVertexAttribPointerv(
GLuint index, GLenum pname, void** ptr) {
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- // If it's a client side buffer the client has the data.
- if (client_side_buffer_helper_->GetAttribPointer(index, pname, ptr)) {
- return;
- }
-#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
- typedef gles2::GetVertexAttribPointerv::Result Result;
- Result* result = GetResultAs<Result*>();
- result->SetNumResults(0);
helper_->GetVertexAttribPointerv(
index, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
- result->CopyResult(ptr);
+ static_cast<gles2::GetVertexAttribPointerv::Result*>(
+ result_buffer_)->CopyResult(ptr);
};
GLint GLES2Implementation::GetAttribLocation(
@@ -665,19 +287,8 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) {
void GLES2Implementation::VertexAttribPointer(
GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
const void* ptr) {
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- // Record the info on the client side.
- client_side_buffer_helper_->SetAttribPointer(
- bound_array_buffer_id_, index, size, type, normalized, stride, ptr);
- if (bound_array_buffer_id_ != 0) {
- // Only report NON client side buffers to the service.
- helper_->VertexAttribPointer(index, size, type, normalized, stride,
- ToGLuint(ptr));
- }
-#else // !defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
helper_->VertexAttribPointer(index, size, type, normalized, stride,
ToGLuint(ptr));
-#endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
}
void GLES2Implementation::ShaderSource(
@@ -1159,158 +770,5 @@ void GLES2Implementation::ReadPixels(
}
}
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-bool GLES2Implementation::IsReservedId(GLuint id) {
- for (size_t ii = 0; ii < arraysize(reserved_ids_); ++ii) {
- if (id == reserved_ids_[ii]) {
- return true;
- }
- }
- return false;
-}
-#else
-bool GLES2Implementation::IsReservedId(GLuint) { // NOLINT
- return false;
-}
-#endif
-
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
-void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) {
- if (IsReservedId(buffer)) {
- SetGLError(GL_INVALID_OPERATION);
- return;
- }
- if (buffer != 0) {
- id_allocator_.MarkAsUsed(buffer);
- }
- switch (target) {
- case GL_ARRAY_BUFFER:
- bound_array_buffer_id_ = buffer;
- break;
- case GL_ELEMENT_ARRAY_BUFFER:
- bound_element_array_buffer_id_ = buffer;
- break;
- default:
- break;
- }
- helper_->BindBuffer(target, buffer);
-}
-
-void GLES2Implementation::DeleteBuffers(GLsizei n, const GLuint* buffers) {
- FreeIds(n, buffers);
- for (GLsizei ii = 0; ii < n; ++ii) {
- if (buffers[ii] == bound_array_buffer_id_) {
- bound_array_buffer_id_ = 0;
- }
- if (buffers[ii] == bound_element_array_buffer_id_) {
- bound_element_array_buffer_id_ = 0;
- }
- }
- // TODO(gman): compute the number of buffers we can delete in 1 call
- // based on the size of command buffer and the limit of argument size
- // for comments then loop to delete all the buffers. The same needs to
- // happen for GenBuffer, GenTextures, DeleteTextures, etc...
- helper_->DeleteBuffersImmediate(n, buffers);
-}
-
-void GLES2Implementation::DisableVertexAttribArray(GLuint index) {
- client_side_buffer_helper_->SetAttribEnable(index, false);
- helper_->DisableVertexAttribArray(index);
-}
-
-void GLES2Implementation::EnableVertexAttribArray(GLuint index) {
- client_side_buffer_helper_->SetAttribEnable(index, true);
- helper_->EnableVertexAttribArray(index);
-}
-
-void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) {
- if (count < 0) {
- SetGLError(GL_INVALID_VALUE);
- return;
- }
- bool have_client_side =
- client_side_buffer_helper_->HaveEnabledClientSideBuffers();
- if (have_client_side) {
- client_side_buffer_helper_->SetupSimualtedClientSideBuffers(
- this, helper_, first + count);
- }
- helper_->DrawArrays(mode, first, count);
- if (have_client_side) {
- // Restore the user's current binding.
- helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
- }
-}
-
-bool GLES2Implementation::GetVertexAttribHelper(
- GLuint index, GLenum pname, uint32* param) {
- const ClientSideBufferHelper::VertexAttribInfo* info =
- client_side_buffer_helper_->GetAttribInfo(index);
- if (!info) {
- return false;
- }
-
- switch (pname) {
- case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *param = info->buffer_id();
- break;
- case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- *param = info->enabled();
- break;
- case GL_VERTEX_ATTRIB_ARRAY_SIZE:
- *param = info->size();
- break;
- case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
- *param = info->stride();
- break;
- case GL_VERTEX_ATTRIB_ARRAY_TYPE:
- *param = info->type();
- break;
- case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
- *param = info->normalized();
- break;
- case GL_CURRENT_VERTEX_ATTRIB:
- return false; // pass through to service side.
- default:
- SetGLError(GL_INVALID_ENUM);
- break;
- }
- return true;
-}
-
-void GLES2Implementation::GetVertexAttribfv(
- GLuint index, GLenum pname, GLfloat* params) {
- uint32 value;
- if (GetVertexAttribHelper(index, pname, &value)) {
- *params = static_cast<float>(value);
- return;
- }
- typedef GetVertexAttribfv::Result Result;
- Result* result = GetResultAs<Result*>();
- result->SetNumResults(0);
- helper_->GetVertexAttribfv(
- index, pname, result_shm_id(), result_shm_offset());
- WaitForCmd();
- result->CopyResult(params);
-}
-
-void GLES2Implementation::GetVertexAttribiv(
- GLuint index, GLenum pname, GLint* params) {
- uint32 value;
- if (GetVertexAttribHelper(index, pname, &value)) {
- *params = value;
- return;
- }
- typedef GetVertexAttribiv::Result Result;
- Result* result = GetResultAs<Result*>();
- result->SetNumResults(0);
- helper_->GetVertexAttribiv(
- index, pname, result_shm_id(), result_shm_offset());
- WaitForCmd();
- result->CopyResult(params);
-}
-
-#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index 4200458..fd98686 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -9,18 +9,13 @@
#include <string>
#include <vector>
#include "../common/gles2_cmd_utils.h"
-#include "../common/scoped_ptr.h"
#include "../client/gles2_cmd_helper.h"
#include "../client/id_allocator.h"
#include "../client/fenced_allocator.h"
-#define GLES2_SUPPORT_CLIENT_SIDE_BUFFERS 1
-
namespace gpu {
namespace gles2 {
-class ClientSideBufferHelper;
-
// This class emulates GLES2 over command buffers. It can be used by a client
// program so that the program does not need deal with shared memory and command
// buffer management. See gl2_lib.h. Note that there is a performance gain to
@@ -29,22 +24,6 @@ class ClientSideBufferHelper;
// shared memory and synchronization issues.
class GLES2Implementation {
public:
- // The maxiumum result size from simple GL get commands.
- static const size_t kMaxSizeOfSimpleResult = 16 * sizeof(uint32); // NOLINT.
-
- // used for testing only. If more things are reseved add them here.
- static const unsigned int kStartingOffset = kMaxSizeOfSimpleResult;
-
- // The bucket used for results. Public for testing only.
- static const uint32 kResultBucketId = 1;
-
- // Alignment of allocations.
- static const unsigned int kAlignment = 4;
-
- // GL names for the buffers used to emulate client side buffers.
- static const GLuint kClientSideArrayId = 0xFEDCBA98u;
- static const GLuint kClientSideElementArrayId = 0xFEDCBA99u;
-
GLES2Implementation(
GLES2CmdHelper* helper,
size_t transfer_buffer_size,
@@ -64,68 +43,6 @@ class GLES2Implementation {
// this file instead of having to edit some template or the code generator.
#include "../client/gles2_implementation_autogen.h"
- #if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- void BindBuffer(GLenum target, GLuint buffer);
- void DeleteBuffers(GLsizei n, const GLuint* buffers);
- void DisableVertexAttribArray(GLuint index);
- void DrawArrays(GLenum mode, GLint first, GLsizei count);
- void EnableVertexAttribArray(GLuint index);
- void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
- void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
- #else
- void BindBuffer(GLenum target, GLuint buffer) {
- if (IsReservedId(buffer)) {
- SetGLError(GL_INVALID_OPERATION);
- return;
- }
- if (buffer != 0) {
- id_allocator_.MarkAsUsed(buffer);
- }
- helper_->BindBuffer(target, buffer);
- }
-
- void DeleteBuffers(GLsizei n, const GLuint* buffers) {
- FreeIds(n, buffers);
- helper_->DeleteBuffersImmediate(n, buffers);
- }
-
- void DisableVertexAttribArray(GLuint index) {
- helper_->DisableVertexAttribArray(index);
- }
-
- void DrawArrays(GLenum mode, GLint first, GLsizei count) {
- if (count < 0) {
- SetGLError(GL_INVALID_VALUE);
- return;
- }
- helper_->DrawArrays(mode, first, count);
- }
-
- void EnableVertexAttribArray(GLuint index) {
- helper_->EnableVertexAttribArray(index);
- }
-
- void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) {
- typedef GetVertexAttribfv::Result Result;
- Result* result = GetResultAs<Result*>();
- result->SetNumResults(0);
- helper_->GetVertexAttribfv(
- index, pname, result_shm_id(), result_shm_offset());
- WaitForCmd();
- result->CopyResult(params);
- }
-
- void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) {
- typedef GetVertexAttribiv::Result Result;
- Result* result = GetResultAs<Result*>();
- result->SetNumResults(0);
- helper_->GetVertexAttribiv(
- index, pname, result_shm_id(), result_shm_offset());
- WaitForCmd();
- result->CopyResult(params);
- }
- #endif
-
// Makes a set of Ids for glGen___ functions.
void MakeIds(GLsizei n, GLuint* ids);
@@ -133,30 +50,6 @@ class GLES2Implementation {
void FreeIds(GLsizei n, const GLuint* ids);
private:
- // Wraps FencedAllocatorWrapper to provide aligned allocations.
- class AlignedFencedAllocator : public FencedAllocatorWrapper {
- public:
- AlignedFencedAllocator(unsigned int size,
- CommandBufferHelper *helper,
- void *base)
- : FencedAllocatorWrapper(size, helper, base) {
- }
-
- static unsigned int RoundToAlignment(unsigned int size) {
- return (size + kAlignment - 1) & ~(kAlignment - 1);
- }
-
- // Overrriden from FencedAllocatorWrapper
- void *Alloc(unsigned int size) {
- return FencedAllocatorWrapper::Alloc(RoundToAlignment(size));
- }
-
- // Overrriden from FencedAllocatorWrapper
- template <typename T> T *AllocTyped(unsigned int count) {
- return static_cast<T *>(Alloc(count * sizeof(T)));
- }
- };
-
// Gets the shared memory id for the result buffer.
uint32 result_shm_id() const {
return transfer_buffer_id_;
@@ -202,22 +95,14 @@ class GLES2Implementation {
// Sets the contents of a bucket as a string.
void SetBucketAsString(uint32 bucket_id, const std::string& str);
- // Returns true if id is reserved.
- bool IsReservedId(GLuint id);
-
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- // Helper for GetVertexAttrib
- bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32* param);
-
- // Asks the service for the max index in an element array buffer.
- GLsizei GetMaxIndexInElementArrayBuffer(
- GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
-#endif
+ // The maxiumum result size from simple GL get commands.
+ static const size_t kMaxSizeOfSimpleResult = 16 * sizeof(uint32); // NOLINT.
+ static const uint32 kResultBucketId = 1;
GLES2Util util_;
GLES2CmdHelper* helper_;
IdAllocator id_allocator_;
- AlignedFencedAllocator transfer_buffer_;
+ FencedAllocatorWrapper transfer_buffer_;
int transfer_buffer_id_;
void* result_buffer_;
uint32 result_shm_offset_;
@@ -228,20 +113,6 @@ class GLES2Implementation {
// unpack alignment as last set by glPixelStorei
GLint unpack_alignment_;
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- // The currently bound array buffer.
- GLuint bound_array_buffer_id_;
-
- // The currently bound element array buffer.
- GLuint bound_element_array_buffer_id_;
-
- // Info for each vertex attribute saved so we can simulate client side
- // buffers.
- scoped_ptr<ClientSideBufferHelper> client_side_buffer_helper_;
-
- GLuint reserved_ids_[2];
-#endif
-
// Current GL error bits.
uint32 error_bits_;
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 9938cb8..04e5d76 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -19,36 +19,19 @@ void AttachShader(GLuint program, GLuint shader) {
void BindAttribLocation(GLuint program, GLuint index, const char* name);
+void BindBuffer(GLenum target, GLuint buffer) {
+ helper_->BindBuffer(target, buffer);
+}
+
void BindFramebuffer(GLenum target, GLuint framebuffer) {
- if (IsReservedId(framebuffer)) {
- SetGLError(GL_INVALID_OPERATION);
- return;
- }
- if (framebuffer != 0) {
- id_allocator_.MarkAsUsed(framebuffer);
- }
helper_->BindFramebuffer(target, framebuffer);
}
void BindRenderbuffer(GLenum target, GLuint renderbuffer) {
- if (IsReservedId(renderbuffer)) {
- SetGLError(GL_INVALID_OPERATION);
- return;
- }
- if (renderbuffer != 0) {
- id_allocator_.MarkAsUsed(renderbuffer);
- }
helper_->BindRenderbuffer(target, renderbuffer);
}
void BindTexture(GLenum target, GLuint texture) {
- if (IsReservedId(texture)) {
- SetGLError(GL_INVALID_OPERATION);
- return;
- }
- if (texture != 0) {
- id_allocator_.MarkAsUsed(texture);
- }
helper_->BindTexture(target, texture);
}
@@ -170,6 +153,11 @@ void CullFace(GLenum mode) {
helper_->CullFace(mode);
}
+void DeleteBuffers(GLsizei n, const GLuint* buffers) {
+ FreeIds(n, buffers);
+ helper_->DeleteBuffersImmediate(n, buffers);
+}
+
void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {
FreeIds(n, framebuffers);
helper_->DeleteFramebuffersImmediate(n, framebuffers);
@@ -213,6 +201,18 @@ void Disable(GLenum cap) {
helper_->Disable(cap);
}
+void DisableVertexAttribArray(GLuint index) {
+ helper_->DisableVertexAttribArray(index);
+}
+
+void DrawArrays(GLenum mode, GLint first, GLsizei count) {
+ if (count < 0) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
+ helper_->DrawArrays(mode, first, count);
+}
+
void DrawElements(
GLenum mode, GLsizei count, GLenum type, const void* indices);
@@ -220,6 +220,10 @@ void Enable(GLenum cap) {
helper_->Enable(cap);
}
+void EnableVertexAttribArray(GLuint index) {
+ helper_->EnableVertexAttribArray(index);
+}
+
void Finish();
void Flush();
@@ -282,8 +286,7 @@ void GetBooleanv(GLenum pname, GLboolean* params) {
typedef GetBooleanv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetBooleanv(pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetBooleanv(pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -291,8 +294,8 @@ void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
typedef GetBufferParameteriv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetBufferParameteriv(target, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetBufferParameteriv(
+ target, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -302,8 +305,7 @@ void GetFloatv(GLenum pname, GLfloat* params) {
typedef GetFloatv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetFloatv(pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetFloatv(pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -312,8 +314,8 @@ void GetFramebufferAttachmentParameteriv(
typedef GetFramebufferAttachmentParameteriv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetFramebufferAttachmentParameteriv(target, attachment, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetFramebufferAttachmentParameteriv(
+ target, attachment, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -321,8 +323,7 @@ void GetIntegerv(GLenum pname, GLint* params) {
typedef GetIntegerv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetIntegerv(pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetIntegerv(pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -330,8 +331,7 @@ void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
typedef GetProgramiv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetProgramiv(program, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetProgramiv(program, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -356,8 +356,8 @@ void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) {
typedef GetRenderbufferParameteriv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetRenderbufferParameteriv(target, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetRenderbufferParameteriv(
+ target, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -365,8 +365,7 @@ void GetShaderiv(GLuint shader, GLenum pname, GLint* params) {
typedef GetShaderiv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetShaderiv(shader, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetShaderiv(shader, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -413,8 +412,8 @@ void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
typedef GetTexParameterfv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetTexParameterfv(target, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetTexParameterfv(
+ target, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -422,8 +421,8 @@ void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
typedef GetTexParameteriv::Result Result;
Result* result = GetResultAs<Result*>();
result->SetNumResults(0);
- helper_->GetTexParameteriv(target, pname,
- result_shm_id(), result_shm_offset());
+ helper_->GetTexParameteriv(
+ target, pname, result_shm_id(), result_shm_offset());
WaitForCmd();
result->CopyResult(params);
}
@@ -433,6 +432,24 @@ void GetUniformiv(GLuint program, GLint location, GLint* params);
GLint GetUniformLocation(GLuint program, const char* name);
+void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) {
+ typedef GetVertexAttribfv::Result Result;
+ Result* result = GetResultAs<Result*>();
+ result->SetNumResults(0);
+ helper_->GetVertexAttribfv(
+ index, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ result->CopyResult(params);
+}
+void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) {
+ typedef GetVertexAttribiv::Result Result;
+ Result* result = GetResultAs<Result*>();
+ result->SetNumResults(0);
+ helper_->GetVertexAttribiv(
+ index, pname, result_shm_id(), result_shm_offset());
+ WaitForCmd();
+ result->CopyResult(params);
+}
void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer);
void Hint(GLenum target, GLenum mode) {
@@ -746,16 +763,5 @@ void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
void SwapBuffers();
-GLuint GetMaxValueInBuffer(
- GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
- typedef GetMaxValueInBuffer::Result Result;
- Result* result = GetResultAs<Result*>();
- *result = 0;
- helper_->GetMaxValueInBuffer(
- buffer_id, count, type, offset, result_shm_id(), result_shm_offset());
- WaitForCmd();
- return *result;
-}
-
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
deleted file mode 100644
index 79cf95e..0000000
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ /dev/null
@@ -1,677 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Tests for the Command Buffer Helper.
-
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/common/command_buffer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace gpu {
-
-class GLES2MockCommandBufferHelper : public CommandBuffer {
- public:
- static const int32 kTransferBufferId = 0x123;
-
- GLES2MockCommandBufferHelper() { }
- virtual ~GLES2MockCommandBufferHelper() { }
-
- // CommandBuffer implementation:
- virtual bool Initialize(int32 size) {
- ring_buffer_.reset(new CommandBufferEntry[size]);
- ring_buffer_buffer_.ptr = ring_buffer_.get();
- ring_buffer_buffer_.size = size * sizeof(ring_buffer_[0]);
- state_.size = size;
- state_.token = 10000; // All token checks in the tests should pass.
- return true;
- }
-
- virtual Buffer GetRingBuffer() {
- return ring_buffer_buffer_;
- }
-
- virtual State GetState() {
- return state_;
- }
-
- virtual State Flush(int32 put_offset) {
- state_.put_offset = put_offset;
- state_.get_offset = put_offset;
- OnFlush(transfer_buffer_buffer_.ptr);
-
- return state_;
- }
-
- virtual void SetGetOffset(int32 get_offset) {
- state_.get_offset = get_offset;
- }
-
- virtual int32 CreateTransferBuffer(size_t size) {
- transfer_buffer_.reset(new int8[size]);
- transfer_buffer_buffer_.ptr = transfer_buffer_.get();
- transfer_buffer_buffer_.size = size;
- return kTransferBufferId;
- }
-
- virtual void DestroyTransferBuffer(int32) { // NOLINT
- NOTREACHED();
- }
-
- virtual Buffer GetTransferBuffer(int32 id) {
- DCHECK_EQ(id, kTransferBufferId);
- return transfer_buffer_buffer_;
- }
-
- virtual void SetToken(int32 token) {
- NOTREACHED();
- state_.token = token;
- }
-
- virtual void SetParseError(error::Error error) {
- NOTREACHED();
- state_.error = error;
- }
-
- virtual void OnFlush(void* transfer_buffer) = 0;
-
- private:
- scoped_array<int8> transfer_buffer_;
- Buffer transfer_buffer_buffer_;
- scoped_array<CommandBufferEntry> ring_buffer_;
- Buffer ring_buffer_buffer_;
- State state_;
-};
-
-class MockGLES2CommandBuffer : public GLES2MockCommandBufferHelper {
- public:
- virtual ~MockGLES2CommandBuffer() {
- }
-
- // This is so we can use all the gmock functions when Flush is called.
- MOCK_METHOD1(OnFlush, void(void* result));
-};
-
-namespace gles2 {
-
-using testing::Return;
-using testing::Mock;
-using testing::Truly;
-using testing::Sequence;
-using testing::DoAll;
-using testing::Invoke;
-using testing::_;
-
-ACTION_P(SetMemory, obj) {
- memcpy(arg0, &obj, sizeof(obj));
-}
-
-// Used to help set the transfer buffer result to SizedResult of a single value.
-template <typename T>
-class SizedResultHelper {
- public:
- explicit SizedResultHelper(T result)
- : size_(sizeof(result)),
- result_(result) {
- }
-
- private:
- uint32 size_;
- T result_;
-};
-
-// Struct to make it easy to pass a vec4 worth of floats.
-struct FourFloats {
- FourFloats(float _x, float _y, float _z, float _w)
- : x(_x),
- y(_y),
- z(_z),
- w(_w) {
- }
-
- float x;
- float y;
- float z;
- float w;
-};
-
-// Test fixture for CommandBufferHelper test.
-class GLES2ImplementationTest : public testing::Test {
- protected:
- static const int32 kNumCommandEntries = 100;
- static const int32 kCommandBufferSizeBytes =
- kNumCommandEntries * sizeof(CommandBufferEntry);
- static const size_t kTransferBufferSize = 256;
- static const int32 kTransferBufferId =
- GLES2MockCommandBufferHelper::kTransferBufferId;
- static const uint8 kInitialValue = 0xBD;
- static const GLint kMaxVertexAttribs = 8;
-
- virtual void SetUp() {
- command_buffer_.reset(new MockGLES2CommandBuffer());
- command_buffer_->Initialize(kNumCommandEntries);
-
-
- EXPECT_EQ(kTransferBufferId,
- command_buffer_->CreateTransferBuffer(kTransferBufferSize));
- transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId);
- ClearTransferBuffer();
-
- helper_.reset(new GLES2CmdHelper(command_buffer_.get()));
- helper_->Initialize();
-
- #if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<GLint>(kMaxVertexAttribs)))
- .RetiresOnSaturation();
- #endif
-
- gl_.reset(new GLES2Implementation(
- helper_.get(),
- kTransferBufferSize,
- transfer_buffer_.ptr,
- kTransferBufferId));
-
- EXPECT_CALL(*command_buffer_, OnFlush(_)).Times(1).RetiresOnSaturation();
- helper_->CommandBufferHelper::Flush();
- Buffer ring_buffer = command_buffer_->GetRingBuffer();
- commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) +
- command_buffer_->GetState().put_offset;
- }
-
- virtual void TearDown() {
- }
-
- void ClearTransferBuffer() {
- memset(transfer_buffer_.ptr, kInitialValue, kTransferBufferSize);
- }
-
- static unsigned int RoundToAlignment(unsigned int size) {
- return (size + GLES2Implementation::kAlignment - 1) &
- ~(GLES2Implementation::kAlignment - 1);
- }
-
- Buffer transfer_buffer_;
- CommandBufferEntry* commands_;
- scoped_ptr<MockGLES2CommandBuffer> command_buffer_;
- scoped_ptr<GLES2CmdHelper> helper_;
- Sequence sequence_;
- scoped_ptr<GLES2Implementation> gl_;
-};
-
-// GCC requires these declarations, but MSVC requires they not be present
-#ifndef COMPILER_MSVC
-const int32 GLES2ImplementationTest::kTransferBufferId;
-#endif
-
-
-TEST_F(GLES2ImplementationTest, ShaderSource) {
- const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation
- const GLuint kShaderId = 456;
- const char* kString1 = "foobar";
- const char* kString2 = "barfoo";
- const size_t kString1Size = strlen(kString1);
- const size_t kString2Size = strlen(kString2);
- const size_t kString3Size = 1; // Want the NULL;
- const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
- const size_t kPaddedString1Size = RoundToAlignment(kString1Size);
- const size_t kPaddedString2Size = RoundToAlignment(kString2Size);
- struct Cmds {
- cmd::SetBucketSize set_bucket_size;
- cmd::SetBucketData set_bucket_data1;
- cmd::SetToken set_token1;
- cmd::SetBucketData set_bucket_data2;
- cmd::SetToken set_token2;
- cmd::SetBucketData set_bucket_data3;
- cmd::SetToken set_token3;
- ShaderSourceBucket shader_source_bucket;
- cmd::SetBucketSize clear_bucket_size;
- };
- int32 token = 1;
- uint32 offset = GLES2Implementation::kStartingOffset;
- Cmds expected;
- expected.set_bucket_size.Init(kBucketId, kSourceSize);
- expected.set_bucket_data1.Init(
- kBucketId, 0, kString1Size, kTransferBufferId, offset);
- expected.set_token1.Init(token++);
- expected.set_bucket_data2.Init(
- kBucketId, kString1Size, kString2Size, kTransferBufferId,
- offset + kPaddedString1Size);
- expected.set_token2.Init(token++);
- expected.set_bucket_data3.Init(
- kBucketId, kString1Size + kString2Size,
- kString3Size, kTransferBufferId,
- offset + kPaddedString1Size + kPaddedString2Size);
- expected.set_token3.Init(token++);
- expected.shader_source_bucket.Init(kShaderId, kBucketId);
- expected.clear_bucket_size.Init(kBucketId, 0);
- const char* strings[] = {
- kString1,
- kString2,
- };
- gl_->ShaderSource(kShaderId, 2, strings, NULL);
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
-}
-
-#if defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
-TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
- static const float verts[][4] = {
- { 12.0f, 23.0f, 34.0f, 45.0f, },
- { 56.0f, 67.0f, 78.0f, 89.0f, },
- { 13.0f, 24.0f, 35.0f, 46.0f, },
- };
- struct Cmds {
- EnableVertexAttribArray enable1;
- EnableVertexAttribArray enable2;
- BindBuffer bind_to_emu;
- BufferData set_size;
- BufferSubData copy_data1;
- cmd::SetToken set_token1;
- VertexAttribPointer set_pointer1;
- BufferSubData copy_data2;
- cmd::SetToken set_token2;
- VertexAttribPointer set_pointer2;
- DrawArrays draw;
- BindBuffer restore;
- };
- const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
- const GLuint kAttribIndex1 = 1;
- const GLuint kAttribIndex2 = 3;
- const GLint kNumComponents1 = 3;
- const GLint kNumComponents2 = 2;
- const GLsizei kClientStride = sizeof(verts[0]);
- const GLint kFirst = 1;
- const GLsizei kCount = 2;
- const GLsizei kSize1 =
- arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
- const GLsizei kSize2 =
- arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
- const GLsizei kEmuOffset1 = 0;
- const GLsizei kEmuOffset2 = kSize1;
-
- const GLsizei kTotalSize = kSize1 + kSize2;
- int32 token = 1;
- uint32 offset = GLES2Implementation::kStartingOffset;
- Cmds expected;
- expected.enable1.Init(kAttribIndex1);
- expected.enable2.Init(kAttribIndex2);
- expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
- expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
- expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId, offset);
- expected.set_token1.Init(token++);
- expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
- expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId, offset + kSize1);
- expected.set_token2.Init(token++);
- expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
- expected.draw.Init(GL_POINTS, kFirst, kCount);
- expected.restore.Init(GL_ARRAY_BUFFER, 0);
- gl_->EnableVertexAttribArray(kAttribIndex1);
- gl_->EnableVertexAttribArray(kAttribIndex2);
- gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->DrawArrays(GL_POINTS, kFirst, kCount);
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
-}
-
-TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
- static const float verts[][4] = {
- { 12.0f, 23.0f, 34.0f, 45.0f, },
- { 56.0f, 67.0f, 78.0f, 89.0f, },
- { 13.0f, 24.0f, 35.0f, 46.0f, },
- };
- static const uint16 indices[] = {
- 1, 2,
- };
- struct Cmds {
- EnableVertexAttribArray enable1;
- EnableVertexAttribArray enable2;
- BindBuffer bind_to_index_emu;
- BufferData set_index_size;
- BufferSubData copy_data0;
- cmd::SetToken set_token0;
- BindBuffer bind_to_emu;
- BufferData set_size;
- BufferSubData copy_data1;
- cmd::SetToken set_token1;
- VertexAttribPointer set_pointer1;
- BufferSubData copy_data2;
- cmd::SetToken set_token2;
- VertexAttribPointer set_pointer2;
- DrawElements draw;
- BindBuffer restore;
- BindBuffer restore_element;
- };
- const GLsizei kIndexSize = sizeof(indices);
- const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
- const GLuint kEmuIndexBufferId =
- GLES2Implementation::kClientSideElementArrayId;
- const GLuint kAttribIndex1 = 1;
- const GLuint kAttribIndex2 = 3;
- const GLint kNumComponents1 = 3;
- const GLint kNumComponents2 = 2;
- const GLsizei kClientStride = sizeof(verts[0]);
- const GLsizei kCount = 2;
- const GLsizei kSize1 =
- arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
- const GLsizei kSize2 =
- arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
- const GLsizei kEmuOffset1 = 0;
- const GLsizei kEmuOffset2 = kSize1;
-
- const GLsizei kTotalSize = kSize1 + kSize2;
- int32 token = 1;
- uint32 offset = GLES2Implementation::kStartingOffset;
- Cmds expected;
- expected.enable1.Init(kAttribIndex1);
- expected.enable2.Init(kAttribIndex2);
- expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
- expected.set_index_size.Init(
- GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
- expected.copy_data0.Init(
- GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, kTransferBufferId, offset);
- offset += kIndexSize;
- expected.set_token0.Init(token++);
- expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
- expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
- expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId, offset);
- offset += kSize1;
- expected.set_token1.Init(token++);
- expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
- expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId, offset);
- expected.set_token2.Init(token++);
- expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
- expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
- expected.restore.Init(GL_ARRAY_BUFFER, 0);
- expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
- gl_->EnableVertexAttribArray(kAttribIndex1);
- gl_->EnableVertexAttribArray(kAttribIndex2);
- gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
-}
-
-TEST_F(GLES2ImplementationTest,
- DrawElementsClientSideBuffersServiceSideIndices) {
- static const float verts[][4] = {
- { 12.0f, 23.0f, 34.0f, 45.0f, },
- { 56.0f, 67.0f, 78.0f, 89.0f, },
- { 13.0f, 24.0f, 35.0f, 46.0f, },
- };
- struct Cmds {
- EnableVertexAttribArray enable1;
- EnableVertexAttribArray enable2;
- BindBuffer bind_to_index;
- GetMaxValueInBuffer get_max;
- BindBuffer bind_to_emu;
- BufferData set_size;
- BufferSubData copy_data1;
- cmd::SetToken set_token1;
- VertexAttribPointer set_pointer1;
- BufferSubData copy_data2;
- cmd::SetToken set_token2;
- VertexAttribPointer set_pointer2;
- DrawElements draw;
- BindBuffer restore;
- };
- const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
- const GLuint kClientIndexBufferId = 0x789;
- const GLuint kIndexOffset = 0x40;
- const GLuint kMaxIndex = 2;
- const GLuint kAttribIndex1 = 1;
- const GLuint kAttribIndex2 = 3;
- const GLint kNumComponents1 = 3;
- const GLint kNumComponents2 = 2;
- const GLsizei kClientStride = sizeof(verts[0]);
- const GLsizei kCount = 2;
- const GLsizei kSize1 =
- arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
- const GLsizei kSize2 =
- arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
- const GLsizei kEmuOffset1 = 0;
- const GLsizei kEmuOffset2 = kSize1;
-
- const GLsizei kTotalSize = kSize1 + kSize2;
- int32 token = 1;
- uint32 offset = GLES2Implementation::kStartingOffset;
- Cmds expected;
- expected.enable1.Init(kAttribIndex1);
- expected.enable2.Init(kAttribIndex2);
- expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
- expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
- kIndexOffset, kTransferBufferId, 0);
- expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
- expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
- expected.copy_data1.Init(
- GL_ARRAY_BUFFER, kEmuOffset1, kSize1, kTransferBufferId, offset);
- offset += kSize1;
- expected.set_token1.Init(token++);
- expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
- expected.copy_data2.Init(
- GL_ARRAY_BUFFER, kEmuOffset2, kSize2, kTransferBufferId, offset);
- expected.set_token2.Init(token++);
- expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
- expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
- expected.restore.Init(GL_ARRAY_BUFFER, 0);
-
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(kMaxIndex))
- .RetiresOnSaturation();
-
- gl_->EnableVertexAttribArray(kAttribIndex1);
- gl_->EnableVertexAttribArray(kAttribIndex2);
- gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
- gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, kClientStride, verts);
- gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
- reinterpret_cast<const void*>(kIndexOffset));
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
-}
-
-TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
- static const float verts[1] = { 0.0f, };
- const GLuint kAttribIndex1 = 1;
- const GLuint kAttribIndex2 = 3;
- const GLint kNumComponents1 = 3;
- const GLint kNumComponents2 = 2;
- const GLsizei kStride1 = 12;
- const GLsizei kStride2 = 0;
- const GLuint kBufferId = 0x123;
- const GLint kOffset2 = 0x456;
-
- // Only one set and one get because the client side buffer's info is stored
- // on the client side.
- struct Cmds {
- BindBuffer bind;
- VertexAttribPointer set_pointer;
- GetVertexAttribPointerv get_pointer;
- };
- Cmds expected;
- expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
- expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
- kStride2, kOffset2);
- expected.get_pointer.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER,
- kTransferBufferId, 0);
-
- // One call to flush to way for GetVertexAttribPointerv
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<uint32>(kOffset2)))
- .RetiresOnSaturation();
-
- // Set one client side buffer.
- gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, kStride1, verts);
- // Set one VBO
- gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
- gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, kStride2,
- reinterpret_cast<const void*>(kOffset2));
- // now get them both.
- void* ptr1 = NULL;
- void* ptr2 = NULL;
-
- gl_->GetVertexAttribPointerv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
- gl_->GetVertexAttribPointerv(
- kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
-
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
- EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
- // because the service is not running ptr2 is not read.
- EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
-}
-
-TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
- static const float verts[1] = { 0.0f, };
- const GLuint kAttribIndex1 = 1;
- const GLuint kAttribIndex2 = 3;
- const GLint kNumComponents1 = 3;
- const GLint kNumComponents2 = 2;
- const GLsizei kStride1 = 12;
- const GLsizei kStride2 = 0;
- const GLuint kBufferId = 0x123;
- const GLint kOffset2 = 0x456;
-
- // Only one set and one get because the client side buffer's info is stored
- // on the client side.
- struct Cmds {
- EnableVertexAttribArray enable;
- BindBuffer bind;
- VertexAttribPointer set_pointer;
- GetVertexAttribiv get1; // for getting the buffer from attrib2
- GetVertexAttribfv get2; // for getting the value from attrib1
- };
- Cmds expected;
- expected.enable.Init(kAttribIndex1);
- expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
- expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
- kStride2, kOffset2);
- expected.get1.Init(kAttribIndex2,
- GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
- kTransferBufferId, 0);
- expected.get2.Init(kAttribIndex1,
- GL_CURRENT_VERTEX_ATTRIB,
- kTransferBufferId, 0);
-
- FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
-
- // One call to flush to way for GetVertexAttribiv
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(SizedResultHelper<GLuint>(kBufferId)))
- .WillOnce(SetMemory(SizedResultHelper<FourFloats>(current_attrib)))
- .RetiresOnSaturation();
-
- gl_->EnableVertexAttribArray(kAttribIndex1);
- // Set one client side buffer.
- gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
- GL_FLOAT, GL_FALSE, kStride1, verts);
- // Set one VBO
- gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
- gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
- GL_FLOAT, GL_FALSE, kStride2,
- reinterpret_cast<const void*>(kOffset2));
- // first get the service side once to see that we make a command
- GLint buffer_id = 0;
- GLint enabled = 0;
- GLint size = 0;
- GLint stride = 0;
- GLint type = 0;
- GLint normalized = 1;
- float current[4] = { 0.0f, };
-
- gl_->GetVertexAttribiv(
- kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
- EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
- gl_->GetVertexAttribiv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
- gl_->GetVertexAttribiv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
- gl_->GetVertexAttribiv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
- gl_->GetVertexAttribiv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
- gl_->GetVertexAttribiv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
- gl_->GetVertexAttribiv(
- kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
- gl_->GetVertexAttribfv(
- kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
-
- EXPECT_EQ(0, buffer_id);
- EXPECT_EQ(GL_TRUE, enabled);
- EXPECT_EQ(kNumComponents1, size);
- EXPECT_EQ(kStride1, stride);
- EXPECT_EQ(GL_FLOAT, type);
- EXPECT_EQ(GL_FALSE, normalized);
- EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
-
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
-}
-
-TEST_F(GLES2ImplementationTest, ReservedIds) {
- // Only the get error command should be issued.
- struct Cmds {
- GetError get;
- };
- Cmds expected;
- expected.get.Init(kTransferBufferId, 0);
-
- // One call to flush to way for GetError
- EXPECT_CALL(*command_buffer_, OnFlush(_))
- .WillOnce(SetMemory(GLuint(GL_NO_ERROR)))
- .RetiresOnSaturation();
-
- gl_->BindBuffer(
- GL_ARRAY_BUFFER,
- GLES2Implementation::kClientSideArrayId);
- gl_->BindBuffer(
- GL_ARRAY_BUFFER,
- GLES2Implementation::kClientSideElementArrayId);
- gl_->BindFramebuffer(
- GL_FRAMEBUFFER,
- GLES2Implementation::kClientSideArrayId);
- gl_->BindFramebuffer(
- GL_FRAMEBUFFER,
- GLES2Implementation::kClientSideElementArrayId);
- gl_->BindRenderbuffer(
- GL_RENDERBUFFER,
- GLES2Implementation::kClientSideArrayId);
- gl_->BindRenderbuffer(
- GL_RENDERBUFFER,
- GLES2Implementation::kClientSideElementArrayId);
- gl_->BindTexture(
- GL_TEXTURE_2D,
- GLES2Implementation::kClientSideArrayId);
- gl_->BindTexture(
- GL_TEXTURE_2D,
- GLES2Implementation::kClientSideElementArrayId);
- GLenum err = gl_->GetError();
- EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
- EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
-}
-
-#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_BUFFERS)
-
-
-} // namespace gles2
-} // namespace gpu
-
-
diff --git a/gpu/command_buffer/client/id_allocator.cc b/gpu/command_buffer/client/id_allocator.cc
index 2d244d0..e6f9b6c 100644
--- a/gpu/command_buffer/client/id_allocator.cc
+++ b/gpu/command_buffer/client/id_allocator.cc
@@ -9,19 +9,50 @@
namespace gpu {
-IdAllocator::IdAllocator() {
-}
+IdAllocator::IdAllocator() : bitmap_(1) { bitmap_[0] = 0; }
+
+static const unsigned int kBitsPerUint32 = sizeof(Uint32) * 8; // NOLINT
+// Looks for the first non-full entry, and return the first free bit in that
+// entry. If all the entries are full, it will return the first bit of an entry
+// that would be appended, but doesn't actually append that entry to the vector.
unsigned int IdAllocator::FindFirstFree() const {
- ResourceId id = 1;
- for (ResourceIdSet::const_iterator it = used_ids_.begin();
- it != used_ids_.end(); ++it) {
- if ((*it) != id) {
- return id;
+ size_t size = bitmap_.size();
+ for (unsigned int i = 0; i < size; ++i) {
+ Uint32 value = bitmap_[i];
+ if (value != 0xffffffffU) {
+ for (unsigned int j = 0; j < kBitsPerUint32; ++j) {
+ if (!(value & (1 << j))) return i * kBitsPerUint32 + j;
+ }
+ DLOG(FATAL) << "Code should not reach here.";
}
- ++id;
}
- return id;
+ return size*kBitsPerUint32;
+}
+
+// Sets the correct bit in the proper entry, resizing the vector if needed.
+void IdAllocator::SetBit(unsigned int bit, bool value) {
+ size_t size = bitmap_.size();
+ if (bit >= size * kBitsPerUint32) {
+ size_t newsize = bit / kBitsPerUint32 + 1;
+ bitmap_.resize(newsize);
+ for (size_t i = size; i < newsize; ++i) bitmap_[i] = 0;
+ }
+ Uint32 mask = 1U << (bit % kBitsPerUint32);
+ if (value) {
+ bitmap_[bit / kBitsPerUint32] |= mask;
+ } else {
+ bitmap_[bit / kBitsPerUint32] &= ~mask;
+ }
+}
+
+// Gets the bit from the proper entry. This doesn't resize the vector, just
+// returns false if the bit is beyond the last entry.
+bool IdAllocator::GetBit(unsigned int bit) const {
+ size_t size = bitmap_.size();
+ if (bit / kBitsPerUint32 >= size) return false;
+ Uint32 mask = 1U << (bit % kBitsPerUint32);
+ return (bitmap_[bit / kBitsPerUint32] & mask) != 0;
}
} // namespace gpu
diff --git a/gpu/command_buffer/client/id_allocator.h b/gpu/command_buffer/client/id_allocator.h
index 615f020..8e1ccdb 100644
--- a/gpu/command_buffer/client/id_allocator.h
+++ b/gpu/command_buffer/client/id_allocator.h
@@ -7,8 +7,7 @@
#ifndef GPU_COMMAND_BUFFER_CLIENT_ID_ALLOCATOR_H_
#define GPU_COMMAND_BUFFER_CLIENT_ID_ALLOCATOR_H_
-#include <set>
-#include <utility>
+#include <vector>
#include "../common/types.h"
namespace gpu {
@@ -16,44 +15,36 @@ namespace gpu {
// A resource ID, key to the resource maps.
typedef uint32 ResourceId;
// Invalid resource ID.
-static const ResourceId kInvalidResource = 0u;
+static const ResourceId kInvalidResource = 0xffffffffU;
-// A class to manage the allocation of resource IDs.
+// A class to manage the allocation of resource IDs. It uses a bitfield stored
+// into a vector of unsigned ints.
class IdAllocator {
public:
IdAllocator();
// Allocates a new resource ID.
ResourceId AllocateID() {
- ResourceId id = FindFirstFree();
- MarkAsUsed(id);
- return id;
- }
-
- // Marks an id as used. Returns false if id was already used.
- bool MarkAsUsed(ResourceId id) {
- std::pair<ResourceIdSet::iterator, bool> result = used_ids_.insert(id);
- return result.second;
+ unsigned int bit = FindFirstFree();
+ SetBit(bit, true);
+ return bit;
}
// Frees a resource ID.
void FreeID(ResourceId id) {
- used_ids_.erase(id);
+ SetBit(id, false);
}
// Checks whether or not a resource ID is in use.
- bool InUse(ResourceId id) const {
- return used_ids_.find(id) != used_ids_.end();
+ bool InUse(ResourceId id) {
+ return GetBit(id);
}
-
private:
- // TODO(gman): This would work much better with ranges.
- typedef std::set<ResourceId> ResourceIdSet;
-
- ResourceId FindFirstFree() const;
-
- ResourceIdSet used_ids_;
+ void SetBit(unsigned int bit, bool value);
+ bool GetBit(unsigned int bit) const;
+ unsigned int FindFirstFree() const;
+ std::vector<Uint32> bitmap_;
DISALLOW_COPY_AND_ASSIGN(IdAllocator);
};
diff --git a/gpu/command_buffer/client/id_allocator_test.cc b/gpu/command_buffer/client/id_allocator_test.cc
index eafadd7..df457db 100644
--- a/gpu/command_buffer/client/id_allocator_test.cc
+++ b/gpu/command_buffer/client/id_allocator_test.cc
@@ -23,8 +23,8 @@ class IdAllocatorTest : public testing::Test {
// Checks basic functionality: AllocateID, FreeID, InUse.
TEST_F(IdAllocatorTest, TestBasic) {
IdAllocator *allocator = id_allocator();
- // Check that resource 1 is not in use
- EXPECT_FALSE(allocator->InUse(1));
+ // Check that resource 0 is not in use
+ EXPECT_FALSE(allocator->InUse(0));
// Allocate an ID, check that it's in use.
ResourceId id1 = allocator->AllocateID();
@@ -45,7 +45,8 @@ TEST_F(IdAllocatorTest, TestBasic) {
EXPECT_FALSE(allocator->InUse(id2));
}
-// Checks that the resource IDs are re-used after being freed.
+// Checks that the resource IDs are allocated conservatively, and re-used after
+// being freed.
TEST_F(IdAllocatorTest, TestAdvanced) {
IdAllocator *allocator = id_allocator();
@@ -57,6 +58,18 @@ TEST_F(IdAllocatorTest, TestAdvanced) {
EXPECT_TRUE(allocator->InUse(ids[i]));
}
+ // Check that the allocation is conservative with resource IDs, that is that
+ // the resource IDs don't go over kNumResources - so that the service doesn't
+ // have to allocate too many internal structures when the resources are used.
+ for (unsigned int i = 0; i < kNumResources; ++i) {
+ EXPECT_GT(kNumResources, ids[i]);
+ }
+
+ // Check that the next resources are still free.
+ for (unsigned int i = 0; i < kNumResources; ++i) {
+ EXPECT_FALSE(allocator->InUse(kNumResources + i));
+ }
+
// Check that a new allocation re-uses the resource we just freed.
ResourceId id1 = ids[kNumResources / 2];
allocator->FreeID(id1);
@@ -66,21 +79,4 @@ TEST_F(IdAllocatorTest, TestAdvanced) {
EXPECT_EQ(id1, id2);
}
-// Check that we can choose our own ids and they won't be reused.
-TEST_F(IdAllocatorTest, MarkAsUsed) {
- IdAllocator* allocator = id_allocator();
- ResourceId id = allocator->AllocateID();
- allocator->FreeID(id);
- EXPECT_FALSE(allocator->InUse(id));
- EXPECT_TRUE(allocator->MarkAsUsed(id));
- EXPECT_TRUE(allocator->InUse(id));
- ResourceId id2 = allocator->AllocateID();
- EXPECT_NE(id, id2);
- EXPECT_TRUE(allocator->MarkAsUsed(id2 + 1));
- ResourceId id3 = allocator->AllocateID();
- // Checks our algorithm. If the algorithm changes this check should be
- // changed.
- EXPECT_EQ(id3, id2 + 2);
-}
-
} // namespace gpu