12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/client/vertex_array_object_manager.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_cmd_helper.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gpu { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gles2 { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static GLsizei RoundUpToMultipleOf4(GLsizei size) { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (size + 3) & ~3; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static GLuint ToGLuint(const void* ptr) { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class tracks VertexAttribPointers and helps emulate client side buffers. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The way client side buffers work is we shadow all the Vertex Attribs so we 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// know which ones are pointing to client side buffers. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// At Draw time, for any attribs pointing to client side buffers we copy them 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to a special VBO and reset the actual vertex attrib pointers to point to this 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// VBO. 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This also means we have to catch calls to query those values so that when 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// an attrib is a client side buffer we pass the info back the user expects. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GLES2_IMPL_EXPORT VertexArrayObject { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Info about Vertex Attributes. This is used to track what the user currently 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // has bound on each Vertex Attribute so we can simulate client side buffers 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // at glDrawXXX time. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class VertexAttrib { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexAttrib() 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : enabled_(false), 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buffer_id_(0), 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_(4), 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_(GL_FLOAT), 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) normalized_(GL_FALSE), 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pointer_(NULL), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl_stride_(0), 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) divisor_(0) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool enabled() const { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return enabled_; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_enabled(bool enabled) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enabled_ = enabled; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint buffer_id() const { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buffer_id_; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_buffer_id(GLuint id) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buffer_id_ = id; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum type() const { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type_; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLint size() const { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return size_; 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei stride() const { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gl_stride_; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLboolean normalized() const { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return normalized_; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GLvoid* pointer() const { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pointer_; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsClientSide() const { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return buffer_id_ == 0; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint divisor() const { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return divisor_; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetInfo( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint buffer_id, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLint size, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum type, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLboolean normalized, 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei gl_stride, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GLvoid* pointer) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buffer_id_ = buffer_id; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_ = size; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type_ = type; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) normalized_ = normalized; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl_stride_ = gl_stride; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pointer_ = pointer; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetDivisor(GLuint divisor) { 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) divisor_ = divisor; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether or not this attribute is enabled. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool enabled_; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The id of the buffer. 0 = client side buffer. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint buffer_id_; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Number of components (1, 2, 3, 4). 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLint size_; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum type_; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // GL_TRUE or GL_FALSE 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLboolean normalized_; 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The pointer/offset into the buffer. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GLvoid* pointer_; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The stride that will be used to access the buffer. This is the bogus GL 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stride where 0 = compute the stride based on size and type. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei gl_stride_; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Divisor, for geometry instancing. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint divisor_; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::vector<VertexAttrib> VertexAttribs; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit VertexArrayObject(GLuint max_vertex_attribs); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UnbindBuffer(GLuint id); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool BindElementArray(GLuint id); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HaveEnabledClientSideBuffers() const; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetAttribEnable(GLuint index, bool enabled); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetAttribPointer( 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint buffer_id, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void* ptr); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool GetVertexAttrib( 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, GLenum pname, uint32* param) const; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetAttribDivisor(GLuint index, GLuint divisor); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool GetAttribPointer(GLuint index, GLenum pname, void** ptr) const; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexAttribs& vertex_attribs() const { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return vertex_attribs_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint bound_element_array_buffer() const { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_element_array_buffer_id_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexAttrib* GetAttrib(GLuint index) const; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_client_side_pointers_enabled_; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The currently bound element array buffer. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint bound_element_array_buffer_id_; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexAttribs vertex_attribs_; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VertexArrayObject); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VertexArrayObject::VertexArrayObject(GLuint max_vertex_attribs) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : num_client_side_pointers_enabled_(0), 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_element_array_buffer_id_(0) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertex_attribs_.resize(max_vertex_attribs); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObject::UnbindBuffer(GLuint id) { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (id == 0) { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t ii = 0; ii < vertex_attribs_.size(); ++ii) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexAttrib& attrib = vertex_attribs_[ii]; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.buffer_id() == id) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.set_buffer_id(0); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.enabled()) { 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_client_side_pointers_enabled_; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bound_element_array_buffer_id_ == id) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_element_array_buffer_id_ = 0; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObject::BindElementArray(GLuint id) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (id == bound_element_array_buffer_id_) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_element_array_buffer_id_ = id; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObject::HaveEnabledClientSideBuffers() const { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return num_client_side_pointers_enabled_ > 0; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObject::SetAttribEnable(GLuint index, bool enabled) { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index < vertex_attribs_.size()) { 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexAttrib& attrib = vertex_attribs_[index]; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.enabled() != enabled) { 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.IsClientSide()) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_client_side_pointers_enabled_ += enabled ? 1 : -1; 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_GE(num_client_side_pointers_enabled_, 0); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.set_enabled(enabled); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObject::SetAttribPointer( 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint buffer_id, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLint size, 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum type, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLboolean normalized, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei stride, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void* ptr) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index < vertex_attribs_.size()) { 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexAttrib& attrib = vertex_attribs_[index]; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.IsClientSide() && attrib.enabled()) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --num_client_side_pointers_enabled_; 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_GE(num_client_side_pointers_enabled_, 0); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.SetInfo(buffer_id, size, type, normalized, stride, ptr); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.IsClientSide() && attrib.enabled()) { 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++num_client_side_pointers_enabled_; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObject::GetVertexAttrib( 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, GLenum pname, uint32* param) const { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexAttrib* attrib = GetAttrib(index); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!attrib) { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (pname) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *param = attrib->buffer_id(); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *param = attrib->enabled(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_VERTEX_ATTRIB_ARRAY_SIZE: 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *param = attrib->size(); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *param = attrib->stride(); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_VERTEX_ATTRIB_ARRAY_TYPE: 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *param = attrib->type(); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *param = attrib->normalized(); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; // pass through to service side. 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObject::SetAttribDivisor(GLuint index, GLuint divisor) { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index < vertex_attribs_.size()) { 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexAttrib& attrib = vertex_attribs_[index]; 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.SetDivisor(divisor); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Gets the Attrib pointer for an attrib but only if it's a client side 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pointer. Returns true if it got the pointer. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObject::GetAttribPointer( 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, GLenum pname, void** ptr) const { 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexAttrib* attrib = GetAttrib(index); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib && pname == GL_VERTEX_ATTRIB_ARRAY_POINTER) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *ptr = const_cast<void*>(attrib->pointer()); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Gets an attrib if it's in range and it's client side. 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const VertexArrayObject::VertexAttrib* VertexArrayObject::GetAttrib( 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index) const { 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index < vertex_attribs_.size()) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexAttrib* attrib = &vertex_attribs_[index]; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return attrib; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VertexArrayObjectManager::VertexArrayObjectManager( 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint max_vertex_attribs, 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint array_buffer_id, 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint element_array_buffer_id) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : max_vertex_attribs_(max_vertex_attribs), 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_id_(array_buffer_id), 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_size_(0), 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_offset_(0), 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_array_buffer_id_(element_array_buffer_id), 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_array_buffer_size_(0), 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collection_buffer_size_(0), 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_vertex_array_object_(new VertexArrayObject(max_vertex_attribs)), 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_(default_vertex_array_object_) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)VertexArrayObjectManager::~VertexArrayObjectManager() { 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (VertexArrayObjectMap::iterator it = vertex_array_objects_.begin(); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != vertex_array_objects_.end(); ++it) { 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete it->second; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete default_vertex_array_object_; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::IsReservedId(GLuint id) const { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (id != 0 && 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (id == array_buffer_id_ || id == element_array_buffer_id_)); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLuint VertexArrayObjectManager::bound_element_array_buffer() const { 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_vertex_array_object_->bound_element_array_buffer(); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObjectManager::UnbindBuffer(GLuint id) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_->UnbindBuffer(id); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::BindElementArray(GLuint id) { 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_vertex_array_object_->BindElementArray(id); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObjectManager::GenVertexArrays( 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei n, const GLuint* arrays) { 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_GE(n, 0); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLsizei i = 0; i < n; ++i) { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::pair<VertexArrayObjectMap::iterator, bool> result = 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertex_array_objects_.insert(std::make_pair( 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) arrays[i], new VertexArrayObject(max_vertex_attribs_))); 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(result.second); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObjectManager::DeleteVertexArrays( 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei n, const GLuint* arrays) { 382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_GE(n, 0); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLsizei i = 0; i < n; ++i) { 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint id = arrays[i]; 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (id) { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexArrayObjectMap::iterator it = vertex_array_objects_.find(id); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != vertex_array_objects_.end()) { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bound_vertex_array_object_ == it->second) { 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_ = default_vertex_array_object_; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete it->second; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertex_array_objects_.erase(it); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::BindVertexArray(GLuint array, bool* changed) { 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *changed = false; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexArrayObject* vertex_array_object = default_vertex_array_object_; 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (array != 0) { 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VertexArrayObjectMap::iterator it = vertex_array_objects_.find(array); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it == vertex_array_objects_.end()) { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) vertex_array_object = it->second; 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *changed = vertex_array_object != bound_vertex_array_object_; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_ = vertex_array_object; 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::HaveEnabledClientSideBuffers() const { 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_vertex_array_object_->HaveEnabledClientSideBuffers(); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObjectManager::SetAttribEnable(GLuint index, bool enabled) { 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_->SetAttribEnable(index, enabled); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::GetVertexAttrib( 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, GLenum pname, uint32* param) { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_vertex_array_object_->GetVertexAttrib(index, pname, param); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::GetAttribPointer( 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, GLenum pname, void** ptr) const { 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_vertex_array_object_->GetAttribPointer(index, pname, ptr); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::SetAttribPointer( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint buffer_id, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint index, 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLint size, 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum type, 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLboolean normalized, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei stride, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void* ptr) { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Client side arrays are not allowed in vaos. 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (buffer_id == 0 && !IsDefaultVAOBound()) { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_->SetAttribPointer( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buffer_id, index, size, type, normalized, stride, ptr); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VertexArrayObjectManager::SetAttribDivisor(GLuint index, GLuint divisor) { 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_->SetAttribDivisor(index, divisor); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Collects the data into the collection buffer and returns the number of 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// bytes collected. 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLsizei VertexArrayObjectManager::CollectData( 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void* data, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei bytes_per_element, 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei real_stride, 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei num_elements) { 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei bytes_needed = bytes_per_element * num_elements; 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (collection_buffer_size_ < bytes_needed) { 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collection_buffer_.reset(new int8[bytes_needed]); 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collection_buffer_size_ = bytes_needed; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int8* src = static_cast<const int8*>(data); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int8* dst = collection_buffer_.get(); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int8* end = dst + bytes_per_element * num_elements; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; dst < end; src += real_stride, dst += bytes_per_element) { 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcpy(dst, src, bytes_per_element); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bytes_needed; 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::IsDefaultVAOBound() const { 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return bound_vertex_array_object_ == default_vertex_array_object_; 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if buffers were setup. 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::SetupSimulatedClientSideBuffers( 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* function_name, 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Implementation* gl, 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2CmdHelper* gl_helper, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei num_elements, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei primcount, 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* simulated) { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *simulated = false; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!bound_vertex_array_object_->HaveEnabledClientSideBuffers()) { 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsDefaultVAOBound()) { 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl->SetGLError( 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GL_INVALID_OPERATION, function_name, 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "client side arrays not allowed with vertex array object"); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *simulated = true; 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei total_size = 0; 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compute the size of the buffer we need. 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexArrayObject::VertexAttribs& vertex_attribs = 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_->vertex_attribs(); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLuint ii = 0; ii < vertex_attribs.size(); ++ii) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexArrayObject::VertexAttrib& attrib = vertex_attribs[ii]; 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.IsClientSide() && attrib.enabled()) { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t bytes_per_element = 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Util::GetGLTypeSizeForTexturesAndBuffers(attrib.type()) * 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.size(); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei elements = (primcount && attrib.divisor() > 0) ? 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ((primcount - 1) / attrib.divisor() + 1) : num_elements; 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_size += RoundUpToMultipleOf4(bytes_per_element * elements); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl_helper->BindBuffer(GL_ARRAY_BUFFER, array_buffer_id_); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_offset_ = 0; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (total_size > array_buffer_size_) { 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl->BufferDataHelper(GL_ARRAY_BUFFER, total_size, NULL, GL_DYNAMIC_DRAW); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_size_ = total_size; 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLuint ii = 0; ii < vertex_attribs.size(); ++ii) { 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const VertexArrayObject::VertexAttrib& attrib = vertex_attribs[ii]; 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (attrib.IsClientSide() && attrib.enabled()) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t bytes_per_element = 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Util::GetGLTypeSizeForTexturesAndBuffers(attrib.type()) * 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.size(); 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei real_stride = attrib.stride() ? 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.stride() : static_cast<GLsizei>(bytes_per_element); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei elements = (primcount && attrib.divisor() > 0) ? 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ((primcount - 1) / attrib.divisor() + 1) : num_elements; 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei bytes_collected = CollectData( 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) attrib.pointer(), bytes_per_element, real_stride, elements); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl->BufferSubDataHelper( 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GL_ARRAY_BUFFER, array_buffer_offset_, bytes_collected, 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) collection_buffer_.get()); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl_helper->VertexAttribPointer( 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ii, attrib.size(), attrib.type(), attrib.normalized(), 0, 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_offset_); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) array_buffer_offset_ += RoundUpToMultipleOf4(bytes_collected); 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_LE(array_buffer_offset_, array_buffer_size_); 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copies in indices to the service and returns the highest index accessed + 1 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VertexArrayObjectManager::SetupSimulatedIndexAndClientSideBuffers( 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* function_name, 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Implementation* gl, 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2CmdHelper* gl_helper, 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei count, 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLenum type, 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei primcount, 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const void* indices, 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLuint* offset, 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool* simulated) { 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *simulated = false; 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *offset = ToGLuint(indices); 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei num_elements = 0; 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bound_vertex_array_object_->bound_element_array_buffer() == 0) { 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *simulated = true; 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *offset = 0; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei max_index = -1; 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_UNSIGNED_BYTE: { 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint8* src = static_cast<const uint8*>(indices); 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLsizei ii = 0; ii < count; ++ii) { 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (src[ii] > max_index) { 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_index = src[ii]; 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_UNSIGNED_SHORT: { 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint16* src = static_cast<const uint16*>(indices); 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLsizei ii = 0; ii < count; ++ii) { 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (src[ii] > max_index) { 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_index = src[ii]; 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GL_UNSIGNED_INT: { 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 max_glsizei = static_cast<uint32>( 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::numeric_limits<GLsizei>::max()); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const uint32* src = static_cast<const uint32*>(indices); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (GLsizei ii = 0; ii < count; ++ii) { 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Other parts of the API use GLsizei (signed) to store limits. 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // As such, if we encounter a index that cannot be represented with 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // an unsigned int we need to flag it as an error here. 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if(src[ii] > max_glsizei) { 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl->SetGLError( 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GL_INVALID_OPERATION, function_name, "index too large."); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei signed_index = static_cast<GLsizei>(src[ii]); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (signed_index > max_index) { 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_index = signed_index; 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl_helper->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_array_buffer_id_); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei bytes_per_element = 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLsizei bytes_needed = bytes_per_element * count; 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (bytes_needed > element_array_buffer_size_) { 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) element_array_buffer_size_ = bytes_needed; 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl->BufferDataHelper( 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GL_ELEMENT_ARRAY_BUFFER, bytes_needed, NULL, GL_DYNAMIC_DRAW); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl->BufferSubDataHelper( 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GL_ELEMENT_ARRAY_BUFFER, 0, bytes_needed, indices); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_elements = max_index + 1; 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (bound_vertex_array_object_->HaveEnabledClientSideBuffers()) { 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Index buffer is GL buffer. Ask the service for the highest vertex 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that will be accessed. Note: It doesn't matter if another context 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // changes the contents of any of the buffers. The service will still 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // validate the indices. We just need to know how much to copy across. 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_elements = gl->GetMaxValueInBufferCHROMIUMHelper( 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bound_vertex_array_object_->bound_element_array_buffer(), 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count, type, ToGLuint(indices)) + 1; 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool simulated_client_side_buffers = false; 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetupSimulatedClientSideBuffers( 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function_name, gl, gl_helper, num_elements, primcount, 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &simulated_client_side_buffers); 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *simulated = *simulated || simulated_client_side_buffers; 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace gles2 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace gpu 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 641