| Index: gpu/command_buffer/client/gles2_implementation.cc
|
| diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
|
| index 8fc6e752c3e4ba08e547a8de9510afaaaf6e810e..30389fa281a582810a0a090650730048c1a4c846 100644
|
| --- a/gpu/command_buffer/client/gles2_implementation.cc
|
| +++ b/gpu/command_buffer/client/gles2_implementation.cc
|
| @@ -19,6 +19,7 @@
|
| #include "../client/program_info_manager.h"
|
| #include "../client/query_tracker.h"
|
| #include "../client/transfer_buffer.h"
|
| +#include "../client/vertex_array_object_manager.h"
|
| #include "../common/gles2_cmd_utils.h"
|
| #include "../common/trace_event.h"
|
|
|
| @@ -39,354 +40,6 @@ static GLuint ToGLuint(const void* ptr) {
|
| return static_cast<GLuint>(reinterpret_cast<size_t>(ptr));
|
| }
|
|
|
| -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_(4),
|
| - type_(GL_FLOAT),
|
| - normalized_(GL_FALSE),
|
| - pointer_(NULL),
|
| - gl_stride_(0),
|
| - divisor_(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;
|
| - }
|
| -
|
| - GLuint divisor() const {
|
| - return divisor_;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - void SetDivisor(GLuint divisor) {
|
| - divisor_ = divisor;
|
| - }
|
| -
|
| - 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_;
|
| -
|
| - // Divisor, for geometry instancing.
|
| - GLuint divisor_;
|
| - };
|
| -
|
| - 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_;
|
| - }
|
| - }
|
| - }
|
| -
|
| - void SetAttribDivisor(GLuint index, GLuint divisor) {
|
| - if (index < max_vertex_attribs_) {
|
| - VertexAttribInfo& info = vertex_attrib_infos_[index];
|
| -
|
| - info.SetDivisor(divisor);
|
| - }
|
| - }
|
| -
|
| - // 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 SetupSimulatedClientSideBuffers(
|
| - GLES2Implementation* gl,
|
| - GLES2CmdHelper* gl_helper,
|
| - GLsizei num_elements,
|
| - GLsizei primcount) {
|
| - 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();
|
| - GLsizei elements = (primcount && info.divisor() > 0) ?
|
| - ((primcount - 1) / info.divisor() + 1) : num_elements;
|
| - total_size += RoundUpToMultipleOf4(
|
| - bytes_per_element * elements);
|
| - }
|
| - }
|
| - gl_helper->BindBuffer(GL_ARRAY_BUFFER, array_buffer_id_);
|
| - array_buffer_offset_ = 0;
|
| - if (total_size > array_buffer_size_) {
|
| - gl->BufferDataHelper(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() : static_cast<GLsizei>(bytes_per_element);
|
| - GLsizei elements = (primcount && info.divisor() > 0) ?
|
| - ((primcount - 1) / info.divisor() + 1) : num_elements;
|
| - GLsizei bytes_collected = CollectData(
|
| - info.pointer(), bytes_per_element, real_stride, elements);
|
| - gl->BufferSubDataHelper(
|
| - 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);
|
| - GPU_DCHECK_LE(array_buffer_offset_, array_buffer_size_);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Copies in indices to the service and returns the highest index accessed + 1
|
| - bool SetupSimulatedIndexBuffer(
|
| - GLES2Implementation* gl,
|
| - GLES2CmdHelper* gl_helper,
|
| - GLsizei count,
|
| - GLenum type,
|
| - const void* indices,
|
| - GLsizei* max_index_out) {
|
| - 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;
|
| - }
|
| - case GL_UNSIGNED_INT: {
|
| - uint32 max_glsizei = static_cast<uint32>(
|
| - std::numeric_limits<GLsizei>::max());
|
| - const uint32* src = static_cast<const uint32*>(indices);
|
| - for (GLsizei ii = 0; ii < count; ++ii) {
|
| - // Other parts of the API use GLsizei (signed) to store limits.
|
| - // As such, if we encounter a index that cannot be represented with
|
| - // an unsigned int we need to flag it as an error here.
|
| -
|
| - if(src[ii] > max_glsizei) {
|
| - return false;
|
| - }
|
| - GLsizei signed_index = static_cast<GLsizei>(src[ii]);
|
| - if (signed_index > max_index) {
|
| - max_index = signed_index;
|
| - }
|
| - }
|
| - break;
|
| - }
|
| - default:
|
| - break;
|
| - }
|
| - 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->BufferDataHelper(
|
| - GL_ELEMENT_ARRAY_BUFFER, bytes_needed, NULL, GL_DYNAMIC_DRAW);
|
| - }
|
| - gl->BufferSubDataHelper(
|
| - GL_ELEMENT_ARRAY_BUFFER, 0, bytes_needed, indices);
|
| -
|
| - *max_index_out = max_index + 1;
|
| - return true;
|
| - }
|
| -
|
| - 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);
|
| -};
|
| -
|
| #if !defined(_MSC_VER)
|
| const size_t GLES2Implementation::kMaxSizeOfSimpleResult;
|
| const unsigned int GLES2Implementation::kStartingOffset;
|
| @@ -440,11 +93,7 @@ GLES2Implementation::GLES2Implementation(
|
| bound_renderbuffer_(0),
|
| current_program_(0),
|
| bound_array_buffer_id_(0),
|
| - bound_element_array_buffer_id_(0),
|
| bound_pixel_unpack_transfer_buffer_id_(0),
|
| - client_side_array_id_(0),
|
| - client_side_element_array_id_(0),
|
| - bound_vertex_array_id_(0),
|
| error_bits_(0),
|
| debug_(false),
|
| use_count_(0),
|
| @@ -524,12 +173,12 @@ bool GLES2Implementation::Initialize(
|
| #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| GetIdHandler(id_namespaces::kBuffers)->MakeIds(
|
| this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]);
|
| +#endif
|
|
|
| - client_side_buffer_helper_.reset(new ClientSideBufferHelper(
|
| + vertex_array_object_manager_.reset(new VertexArrayObjectManager(
|
| static_state_.int_state.max_vertex_attribs,
|
| reserved_ids_[0],
|
| reserved_ids_[1]));
|
| -#endif
|
|
|
| return true;
|
| }
|
| @@ -904,7 +553,8 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
|
| return false;
|
| case GL_ELEMENT_ARRAY_BUFFER_BINDING:
|
| if (share_group_->bind_generates_resource()) {
|
| - *params = bound_element_array_buffer_id_;
|
| + *params =
|
| + vertex_array_object_manager_->bound_element_array_buffer();
|
| return true;
|
| }
|
| return false;
|
| @@ -994,6 +644,24 @@ GLuint GLES2Implementation::GetMaxValueInBufferCHROMIUM(
|
| return result;
|
| }
|
|
|
| +void GLES2Implementation::RestoreElementAndArrayBuffers(bool restore) {
|
| + if (restore) {
|
| + RestoreArrayBuffer(restore);
|
| + // Restore the element array binding.
|
| + // We only need to restore it if it wasn't a client side array.
|
| + if (vertex_array_object_manager_->bound_element_array_buffer() == 0) {
|
| + helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void GLES2Implementation::RestoreArrayBuffer(bool restore) {
|
| + if (restore) {
|
| + // Restore the user's current binding.
|
| + helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
|
| + }
|
| +}
|
| +
|
| void GLES2Implementation::Clear(GLbitfield mask) {
|
| GPU_CLIENT_SINGLE_THREAD_CHECK();
|
| GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")");
|
| @@ -1015,50 +683,15 @@ void GLES2Implementation::DrawElements(
|
| if (count == 0) {
|
| return;
|
| }
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - bool have_client_side =
|
| - client_side_buffer_helper_->HaveEnabledClientSideBuffers();
|
| - GLsizei num_elements = 0;
|
| - GLuint offset = ToGLuint(indices);
|
| - bool success;
|
| - if (bound_element_array_buffer_id_ == 0) {
|
| - // Index buffer is client side array.
|
| - // Copy to buffer, scan for highest index.
|
| - success = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
|
| - this, helper_, count, type, indices, &num_elements);
|
| -
|
| - if(!success) {
|
| - SetGLError(GL_INVALID_OPERATION, "glDrawElements", "index too large.");
|
| - return;
|
| - }
|
| -
|
| - 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 = GetMaxValueInBufferCHROMIUMHelper(
|
| - bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
|
| - }
|
| - }
|
| - if (have_client_side) {
|
| - client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
|
| - this, helper_, num_elements, 0);
|
| + GLuint offset = 0;
|
| + bool simulated = false;
|
| + if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
|
| + "glDrawElements", this, helper_, count, type, 0, indices,
|
| + &offset, &simulated)) {
|
| + return;
|
| }
|
| 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
|
| + RestoreElementAndArrayBuffers(simulated);
|
| }
|
|
|
| void GLES2Implementation::Flush() {
|
| @@ -1233,28 +866,24 @@ void GLES2Implementation::GetVertexAttribPointerv(
|
| GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer("
|
| << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", "
|
| << static_cast<void*>(ptr) << ")");
|
| -
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - // 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_ARRAYS)
|
| -
|
| - TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
|
| - typedef gles2::GetVertexAttribPointerv::Result Result;
|
| - Result* result = GetResultAs<Result*>();
|
| - if (!result) {
|
| - return;
|
| + GPU_CLIENT_LOG_CODE_BLOCK(int32 num_results = 1);
|
| + if (!vertex_array_object_manager_->GetAttribPointer(index, pname, ptr)) {
|
| + TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv");
|
| + typedef gles2::GetVertexAttribPointerv::Result Result;
|
| + Result* result = GetResultAs<Result*>();
|
| + if (!result) {
|
| + return;
|
| + }
|
| + result->SetNumResults(0);
|
| + helper_->GetVertexAttribPointerv(
|
| + index, pname, GetResultShmId(), GetResultShmOffset());
|
| + WaitForCmd();
|
| + result->CopyResult(ptr);
|
| + GPU_CLIENT_LOG_CODE_BLOCK(num_results = result->GetNumResults());
|
| }
|
| - result->SetNumResults(0);
|
| - helper_->GetVertexAttribPointerv(
|
| - index, pname, GetResultShmId(), GetResultShmOffset());
|
| - WaitForCmd();
|
| - result->CopyResult(ptr);
|
| GPU_CLIENT_LOG_CODE_BLOCK({
|
| - for (int32 i = 0; i < result->GetNumResults(); ++i) {
|
| - GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
|
| + for (int32 i = 0; i < num_results; ++i) {
|
| + GPU_CLIENT_LOG(" " << i << ": " << ptr[i]);
|
| }
|
| });
|
| }
|
| @@ -1468,10 +1097,14 @@ void GLES2Implementation::VertexAttribPointer(
|
| << GLES2Util::GetStringBool(normalized) << ", "
|
| << stride << ", "
|
| << static_cast<const void*>(ptr) << ")");
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| // Record the info on the client side.
|
| - client_side_buffer_helper_->SetAttribPointer(
|
| - bound_array_buffer_id_, index, size, type, normalized, stride, ptr);
|
| + if (!vertex_array_object_manager_->SetAttribPointer(
|
| + bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) {
|
| + SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer",
|
| + "client side arrays are not allowed in vertex array objects.");
|
| + return;
|
| + }
|
| +#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| if (bound_array_buffer_id_ != 0) {
|
| // Only report NON client side buffers to the service.
|
| helper_->VertexAttribPointer(index, size, type, normalized, stride,
|
| @@ -1489,10 +1122,8 @@ void GLES2Implementation::VertexAttribDivisorANGLE(
|
| GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE("
|
| << index << ", "
|
| << divisor << ") ");
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| // Record the info on the client side.
|
| - client_side_buffer_helper_->SetAttribDivisor(index, divisor);
|
| -#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| + vertex_array_object_manager_->SetAttribDivisor(index, divisor);
|
| helper_->VertexAttribDivisorANGLE(index, divisor);
|
| }
|
|
|
| @@ -2476,6 +2107,31 @@ void GLES2Implementation::ActiveTexture(GLenum texture) {
|
| helper_->ActiveTexture(texture);
|
| }
|
|
|
| +void GLES2Implementation::GenBuffersHelper(
|
| + GLsizei /* n */, const GLuint* /* buffers */) {
|
| +}
|
| +
|
| +void GLES2Implementation::GenFramebuffersHelper(
|
| + GLsizei /* n */, const GLuint* /* framebuffers */) {
|
| +}
|
| +
|
| +void GLES2Implementation::GenRenderbuffersHelper(
|
| + GLsizei /* n */, const GLuint* /* renderbuffers */) {
|
| +}
|
| +
|
| +void GLES2Implementation::GenTexturesHelper(
|
| + GLsizei /* n */, const GLuint* /* textures */) {
|
| +}
|
| +
|
| +void GLES2Implementation::GenVertexArraysOESHelper(
|
| + GLsizei n, const GLuint* arrays) {
|
| + vertex_array_object_manager_->GenVertexArrays(n, arrays);
|
| +}
|
| +
|
| +void GLES2Implementation::GenQueriesEXTHelper(
|
| + GLsizei /* n */, const GLuint* /* queries */) {
|
| +}
|
| +
|
| // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id
|
| // generates a new resource. On newer versions of OpenGL they don't. The code
|
| // related to binding below will need to change if we switch to the new OpenGL
|
| @@ -2495,10 +2151,7 @@ bool GLES2Implementation::BindBufferHelper(
|
| }
|
| break;
|
| case GL_ELEMENT_ARRAY_BUFFER:
|
| - if (bound_element_array_buffer_id_ != buffer) {
|
| - bound_element_array_buffer_id_ = buffer;
|
| - changed = true;
|
| - }
|
| + changed = vertex_array_object_manager_->BindElementArray(buffer);
|
| break;
|
| case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM:
|
| bound_pixel_unpack_transfer_buffer_id_ = buffer;
|
| @@ -2587,28 +2240,21 @@ bool GLES2Implementation::BindTextureHelper(GLenum target, GLuint texture) {
|
| bool GLES2Implementation::BindVertexArrayHelper(GLuint array) {
|
| // TODO(gman): See note #1 above.
|
| bool changed = false;
|
| - if (bound_vertex_array_id_ != array) {
|
| - bound_vertex_array_id_ = array;
|
| - changed = true;
|
| + if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) {
|
| + SetGLError(
|
| + GL_INVALID_OPERATION, "glBindVertexArrayOES",
|
| + "id was not generated with glGenVertexArrayOES");
|
| }
|
| - GetIdHandler(id_namespaces::kVertexArrays)->MarkAsUsedForBind(array);
|
| + // Unlike other BindXXXHelpers we don't call MarkAsUsedForBind
|
| + // because unlike other resources VertexArrayObject ids must
|
| + // be generated by GenVertexArrays. A random id to Bind will not
|
| + // generate a new object.
|
| return changed;
|
| }
|
|
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| bool GLES2Implementation::IsBufferReservedId(GLuint id) {
|
| - for (size_t ii = 0; ii < arraysize(reserved_ids_); ++ii) {
|
| - if (id == reserved_ids_[ii]) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -#else
|
| -bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) {
|
| - return false;
|
| + return vertex_array_object_manager_->IsReservedId(id);
|
| }
|
| -#endif
|
|
|
| void GLES2Implementation::DeleteBuffersHelper(
|
| GLsizei n, const GLuint* buffers) {
|
| @@ -2623,13 +2269,7 @@ void GLES2Implementation::DeleteBuffersHelper(
|
| 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;
|
| - }
|
| - if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
|
| - bound_pixel_unpack_transfer_buffer_id_ = 0;
|
| - }
|
| -
|
| + vertex_array_object_manager_->UnbindBuffer(buffers[ii]);
|
| BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]);
|
| if (buffer) {
|
| // Free buffer memory, pending the passage of a token.
|
| @@ -2637,6 +2277,9 @@ void GLES2Implementation::DeleteBuffersHelper(
|
| // Remove buffer.
|
| buffer_tracker_->RemoveBuffer(buffers[ii]);
|
| }
|
| + if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) {
|
| + bound_pixel_unpack_transfer_buffer_id_ = 0;
|
| + }
|
| }
|
| }
|
|
|
| @@ -2714,6 +2357,7 @@ void GLES2Implementation::DeleteTexturesHelper(
|
|
|
| void GLES2Implementation::DeleteVertexArraysOESHelper(
|
| GLsizei n, const GLuint* arrays) {
|
| + vertex_array_object_manager_->DeleteVertexArrays(n, arrays);
|
| if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds(
|
| this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) {
|
| SetGLError(
|
| @@ -2721,11 +2365,6 @@ void GLES2Implementation::DeleteVertexArraysOESHelper(
|
| "glDeleteVertexArraysOES", "id not created by this context.");
|
| return;
|
| }
|
| - for (GLsizei ii = 0; ii < n; ++ii) {
|
| - if (arrays[ii] == bound_vertex_array_id_) {
|
| - bound_vertex_array_id_ = 0;
|
| - }
|
| - }
|
| }
|
|
|
| void GLES2Implementation::DeleteVertexArraysOESStub(
|
| @@ -2742,9 +2381,7 @@ void GLES2Implementation::DisableVertexAttribArray(GLuint index) {
|
| GPU_CLIENT_SINGLE_THREAD_CHECK();
|
| GPU_CLIENT_LOG(
|
| "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")");
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - client_side_buffer_helper_->SetAttribEnable(index, false);
|
| -#endif
|
| + vertex_array_object_manager_->SetAttribEnable(index, false);
|
| helper_->DisableVertexAttribArray(index);
|
| }
|
|
|
| @@ -2752,9 +2389,7 @@ void GLES2Implementation::EnableVertexAttribArray(GLuint index) {
|
| GPU_CLIENT_SINGLE_THREAD_CHECK();
|
| GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray("
|
| << index << ")");
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - client_side_buffer_helper_->SetAttribEnable(index, true);
|
| -#endif
|
| + vertex_array_object_manager_->SetAttribEnable(index, true);
|
| helper_->EnableVertexAttribArray(index);
|
| }
|
|
|
| @@ -2767,60 +2402,14 @@ void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) {
|
| SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0");
|
| return;
|
| }
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - bool have_client_side =
|
| - client_side_buffer_helper_->HaveEnabledClientSideBuffers();
|
| - if (have_client_side) {
|
| - client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
|
| - this, helper_, first + count, 0);
|
| + bool simulated = false;
|
| + if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers(
|
| + "glDrawArrays", this, helper_, first + count, 0, &simulated)) {
|
| + return;
|
| }
|
| -#endif
|
| helper_->DrawArrays(mode, first, count);
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - if (have_client_side) {
|
| - // Restore the user's current binding.
|
| - helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
|
| - }
|
| -#endif
|
| -}
|
| -
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| -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:
|
| - SetGLErrorInvalidEnum("glGetVertexAttrib", pname, "pname");
|
| - break;
|
| - }
|
| - return true;
|
| + RestoreArrayBuffer(simulated);
|
| }
|
| -#endif // GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
|
|
|
| void GLES2Implementation::GetVertexAttribfv(
|
| GLuint index, GLenum pname, GLfloat* params) {
|
| @@ -2829,13 +2418,11 @@ void GLES2Implementation::GetVertexAttribfv(
|
| << index << ", "
|
| << GLES2Util::GetStringVertexAttribute(pname) << ", "
|
| << static_cast<const void*>(params) << ")");
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| uint32 value = 0;
|
| - if (GetVertexAttribHelper(index, pname, &value)) {
|
| + if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
|
| *params = static_cast<float>(value);
|
| return;
|
| }
|
| -#endif
|
| TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv");
|
| typedef GetVertexAttribfv::Result Result;
|
| Result* result = GetResultAs<Result*>();
|
| @@ -2861,13 +2448,11 @@ void GLES2Implementation::GetVertexAttribiv(
|
| << index << ", "
|
| << GLES2Util::GetStringVertexAttribute(pname) << ", "
|
| << static_cast<const void*>(params) << ")");
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| uint32 value = 0;
|
| - if (GetVertexAttribHelper(index, pname, &value)) {
|
| + if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) {
|
| *params = value;
|
| return;
|
| }
|
| -#endif
|
| TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv");
|
| typedef GetVertexAttribiv::Result Result;
|
| Result* result = GetResultAs<Result*>();
|
| @@ -3449,21 +3034,14 @@ void GLES2Implementation::DrawArraysInstancedANGLE(
|
| if (primcount == 0) {
|
| return;
|
| }
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - bool have_client_side =
|
| - client_side_buffer_helper_->HaveEnabledClientSideBuffers();
|
| - if (have_client_side) {
|
| - client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
|
| - this, helper_, first + count, primcount);
|
| + bool simulated = false;
|
| + if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers(
|
| + "glDrawArraysInstancedANGLE", this, helper_, first + count, primcount,
|
| + &simulated)) {
|
| + return;
|
| }
|
| -#endif
|
| helper_->DrawArraysInstancedANGLE(mode, first, count, primcount);
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - if (have_client_side) {
|
| - // Restore the user's current binding.
|
| - helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_);
|
| - }
|
| -#endif
|
| + RestoreArrayBuffer(simulated);
|
| }
|
|
|
| void GLES2Implementation::DrawElementsInstancedANGLE(
|
| @@ -3492,52 +3070,15 @@ void GLES2Implementation::DrawElementsInstancedANGLE(
|
| if (primcount == 0) {
|
| return;
|
| }
|
| -#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
|
| - bool have_client_side =
|
| - client_side_buffer_helper_->HaveEnabledClientSideBuffers();
|
| - GLsizei num_elements = 0;
|
| - GLuint offset = ToGLuint(indices);
|
| - bool success;
|
| - if (bound_element_array_buffer_id_ == 0) {
|
| - // Index buffer is client side array.
|
| - // Copy to buffer, scan for highest index.
|
| - success = client_side_buffer_helper_->SetupSimulatedIndexBuffer(
|
| - this, helper_, count, type, indices, &num_elements);
|
| -
|
| - if(!success) {
|
| - SetGLError(GL_INVALID_OPERATION, "glDrawElementsInstancedANGLE",
|
| - "index too large.");
|
| - return;
|
| - }
|
| -
|
| - 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 = GetMaxValueInBufferCHROMIUMHelper(
|
| - bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1;
|
| - }
|
| - }
|
| - if (have_client_side) {
|
| - client_side_buffer_helper_->SetupSimulatedClientSideBuffers(
|
| - this, helper_, num_elements, primcount);
|
| + GLuint offset = 0;
|
| + bool simulated = false;
|
| + if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers(
|
| + "glDrawElementsInstancedANGLE", this, helper_, count, type, primcount,
|
| + indices, &offset, &simulated)) {
|
| + return;
|
| }
|
| helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount);
|
| - 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_->DrawElementsInstancedANGLE(
|
| - mode, count, type, ToGLuint(indices), primcount);
|
| -#endif
|
| + RestoreElementAndArrayBuffers(simulated);
|
| }
|
|
|
| void GLES2Implementation::GenMailboxCHROMIUM(
|
|
|