| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // A class to emulate GLES2 over command buffers. | 5 // A class to emulate GLES2 over command buffers. |
| 6 | 6 |
| 7 #include "../client/gles2_implementation.h" | 7 #include "../client/gles2_implementation.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| 11 #include <queue> | 11 #include <queue> |
| 12 #include <set> | 12 #include <set> |
| 13 #include <limits> | 13 #include <limits> |
| 14 #include <stdio.h> | 14 #include <stdio.h> |
| 15 #include <string.h> | 15 #include <string.h> |
| 16 #include <GLES2/gl2ext.h> | 16 #include <GLES2/gl2ext.h> |
| 17 #include "../client/buffer_tracker.h" | 17 #include "../client/buffer_tracker.h" |
| 18 #include "../client/mapped_memory.h" | 18 #include "../client/mapped_memory.h" |
| 19 #include "../client/program_info_manager.h" | 19 #include "../client/program_info_manager.h" |
| 20 #include "../client/query_tracker.h" | 20 #include "../client/query_tracker.h" |
| 21 #include "../client/transfer_buffer.h" | 21 #include "../client/transfer_buffer.h" |
| 22 #include "../client/vertex_array_object_manager.h" |
| 22 #include "../common/gles2_cmd_utils.h" | 23 #include "../common/gles2_cmd_utils.h" |
| 23 #include "../common/trace_event.h" | 24 #include "../common/trace_event.h" |
| 24 | 25 |
| 25 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 26 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 26 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | 27 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS |
| 27 #endif | 28 #endif |
| 28 | 29 |
| 29 #if defined(GPU_CLIENT_DEBUG) | 30 #if defined(GPU_CLIENT_DEBUG) |
| 30 #include "ui/gl/gl_switches.h" | 31 #include "ui/gl/gl_switches.h" |
| 31 #include "base/command_line.h" | 32 #include "base/command_line.h" |
| 32 #endif | 33 #endif |
| 33 | 34 |
| 34 namespace gpu { | 35 namespace gpu { |
| 35 namespace gles2 { | 36 namespace gles2 { |
| 36 | 37 |
| 37 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. | 38 // A 32-bit and 64-bit compatible way of converting a pointer to a GLuint. |
| 38 static GLuint ToGLuint(const void* ptr) { | 39 static GLuint ToGLuint(const void* ptr) { |
| 39 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); | 40 return static_cast<GLuint>(reinterpret_cast<size_t>(ptr)); |
| 40 } | 41 } |
| 41 | 42 |
| 42 static GLsizei RoundUpToMultipleOf4(GLsizei size) { | |
| 43 return (size + 3) & ~3; | |
| 44 } | |
| 45 | |
| 46 // This class tracks VertexAttribPointers and helps emulate client side buffers. | |
| 47 // | |
| 48 // The way client side buffers work is we shadow all the Vertex Attribs so we | |
| 49 // know which ones are pointing to client side buffers. | |
| 50 // | |
| 51 // At Draw time, for any attribs pointing to client side buffers we copy them | |
| 52 // to a special VBO and reset the actual vertex attrib pointers to point to this | |
| 53 // VBO. | |
| 54 // | |
| 55 // This also means we have to catch calls to query those values so that when | |
| 56 // an attrib is a client side buffer we pass the info back the user expects. | |
| 57 class ClientSideBufferHelper { | |
| 58 public: | |
| 59 // Info about Vertex Attributes. This is used to track what the user currently | |
| 60 // has bound on each Vertex Attribute so we can simulate client side buffers | |
| 61 // at glDrawXXX time. | |
| 62 class VertexAttribInfo { | |
| 63 public: | |
| 64 VertexAttribInfo() | |
| 65 : enabled_(false), | |
| 66 buffer_id_(0), | |
| 67 size_(4), | |
| 68 type_(GL_FLOAT), | |
| 69 normalized_(GL_FALSE), | |
| 70 pointer_(NULL), | |
| 71 gl_stride_(0), | |
| 72 divisor_(0) { | |
| 73 } | |
| 74 | |
| 75 bool enabled() const { | |
| 76 return enabled_; | |
| 77 } | |
| 78 | |
| 79 void set_enabled(bool enabled) { | |
| 80 enabled_ = enabled; | |
| 81 } | |
| 82 | |
| 83 GLuint buffer_id() const { | |
| 84 return buffer_id_; | |
| 85 } | |
| 86 | |
| 87 GLenum type() const { | |
| 88 return type_; | |
| 89 } | |
| 90 | |
| 91 GLint size() const { | |
| 92 return size_; | |
| 93 } | |
| 94 | |
| 95 GLsizei stride() const { | |
| 96 return gl_stride_; | |
| 97 } | |
| 98 | |
| 99 GLboolean normalized() const { | |
| 100 return normalized_; | |
| 101 } | |
| 102 | |
| 103 const GLvoid* pointer() const { | |
| 104 return pointer_; | |
| 105 } | |
| 106 | |
| 107 bool IsClientSide() const { | |
| 108 return buffer_id_ == 0; | |
| 109 } | |
| 110 | |
| 111 GLuint divisor() const { | |
| 112 return divisor_; | |
| 113 } | |
| 114 | |
| 115 void SetInfo( | |
| 116 GLuint buffer_id, | |
| 117 GLint size, | |
| 118 GLenum type, | |
| 119 GLboolean normalized, | |
| 120 GLsizei gl_stride, | |
| 121 const GLvoid* pointer) { | |
| 122 buffer_id_ = buffer_id; | |
| 123 size_ = size; | |
| 124 type_ = type; | |
| 125 normalized_ = normalized; | |
| 126 gl_stride_ = gl_stride; | |
| 127 pointer_ = pointer; | |
| 128 } | |
| 129 | |
| 130 void SetDivisor(GLuint divisor) { | |
| 131 divisor_ = divisor; | |
| 132 } | |
| 133 | |
| 134 private: | |
| 135 // Whether or not this attribute is enabled. | |
| 136 bool enabled_; | |
| 137 | |
| 138 // The id of the buffer. 0 = client side buffer. | |
| 139 GLuint buffer_id_; | |
| 140 | |
| 141 // Number of components (1, 2, 3, 4). | |
| 142 GLint size_; | |
| 143 | |
| 144 // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer. | |
| 145 GLenum type_; | |
| 146 | |
| 147 // GL_TRUE or GL_FALSE | |
| 148 GLboolean normalized_; | |
| 149 | |
| 150 // The pointer/offset into the buffer. | |
| 151 const GLvoid* pointer_; | |
| 152 | |
| 153 // The stride that will be used to access the buffer. This is the bogus GL | |
| 154 // stride where 0 = compute the stride based on size and type. | |
| 155 GLsizei gl_stride_; | |
| 156 | |
| 157 // Divisor, for geometry instancing. | |
| 158 GLuint divisor_; | |
| 159 }; | |
| 160 | |
| 161 ClientSideBufferHelper(GLuint max_vertex_attribs, | |
| 162 GLuint array_buffer_id, | |
| 163 GLuint element_array_buffer_id) | |
| 164 : max_vertex_attribs_(max_vertex_attribs), | |
| 165 num_client_side_pointers_enabled_(0), | |
| 166 array_buffer_id_(array_buffer_id), | |
| 167 array_buffer_size_(0), | |
| 168 array_buffer_offset_(0), | |
| 169 element_array_buffer_id_(element_array_buffer_id), | |
| 170 element_array_buffer_size_(0), | |
| 171 collection_buffer_size_(0) { | |
| 172 vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs]); | |
| 173 } | |
| 174 | |
| 175 bool HaveEnabledClientSideBuffers() const { | |
| 176 return num_client_side_pointers_enabled_ > 0; | |
| 177 } | |
| 178 | |
| 179 void SetAttribEnable(GLuint index, bool enabled) { | |
| 180 if (index < max_vertex_attribs_) { | |
| 181 VertexAttribInfo& info = vertex_attrib_infos_[index]; | |
| 182 if (info.enabled() != enabled) { | |
| 183 if (info.IsClientSide()) { | |
| 184 num_client_side_pointers_enabled_ += enabled ? 1 : -1; | |
| 185 } | |
| 186 info.set_enabled(enabled); | |
| 187 } | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 void SetAttribPointer( | |
| 192 GLuint buffer_id, | |
| 193 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, | |
| 194 const void* ptr) { | |
| 195 if (index < max_vertex_attribs_) { | |
| 196 VertexAttribInfo& info = vertex_attrib_infos_[index]; | |
| 197 if (info.IsClientSide() && info.enabled()) { | |
| 198 --num_client_side_pointers_enabled_; | |
| 199 } | |
| 200 | |
| 201 info.SetInfo(buffer_id, size, type, normalized, stride, ptr); | |
| 202 | |
| 203 if (info.IsClientSide() && info.enabled()) { | |
| 204 ++num_client_side_pointers_enabled_; | |
| 205 } | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void SetAttribDivisor(GLuint index, GLuint divisor) { | |
| 210 if (index < max_vertex_attribs_) { | |
| 211 VertexAttribInfo& info = vertex_attrib_infos_[index]; | |
| 212 | |
| 213 info.SetDivisor(divisor); | |
| 214 } | |
| 215 } | |
| 216 | |
| 217 // Gets the Attrib pointer for an attrib but only if it's a client side | |
| 218 // pointer. Returns true if it got the pointer. | |
| 219 bool GetAttribPointer(GLuint index, GLenum pname, void** ptr) const { | |
| 220 const VertexAttribInfo* info = GetAttribInfo(index); | |
| 221 if (info && pname == GL_VERTEX_ATTRIB_ARRAY_POINTER) { | |
| 222 *ptr = const_cast<void*>(info->pointer()); | |
| 223 return true; | |
| 224 } | |
| 225 return false; | |
| 226 } | |
| 227 | |
| 228 // Gets an attrib info if it's in range and it's client side. | |
| 229 const VertexAttribInfo* GetAttribInfo(GLuint index) const { | |
| 230 if (index < max_vertex_attribs_) { | |
| 231 VertexAttribInfo* info = &vertex_attrib_infos_[index]; | |
| 232 if (info->IsClientSide()) { | |
| 233 return info; | |
| 234 } | |
| 235 } | |
| 236 return NULL; | |
| 237 } | |
| 238 | |
| 239 // Collects the data into the collection buffer and returns the number of | |
| 240 // bytes collected. | |
| 241 GLsizei CollectData(const void* data, | |
| 242 GLsizei bytes_per_element, | |
| 243 GLsizei real_stride, | |
| 244 GLsizei num_elements) { | |
| 245 GLsizei bytes_needed = bytes_per_element * num_elements; | |
| 246 if (collection_buffer_size_ < bytes_needed) { | |
| 247 collection_buffer_.reset(new int8[bytes_needed]); | |
| 248 collection_buffer_size_ = bytes_needed; | |
| 249 } | |
| 250 const int8* src = static_cast<const int8*>(data); | |
| 251 int8* dst = collection_buffer_.get(); | |
| 252 int8* end = dst + bytes_per_element * num_elements; | |
| 253 for (; dst < end; src += real_stride, dst += bytes_per_element) { | |
| 254 memcpy(dst, src, bytes_per_element); | |
| 255 } | |
| 256 return bytes_needed; | |
| 257 } | |
| 258 | |
| 259 // Returns true if buffers were setup. | |
| 260 void SetupSimulatedClientSideBuffers( | |
| 261 GLES2Implementation* gl, | |
| 262 GLES2CmdHelper* gl_helper, | |
| 263 GLsizei num_elements, | |
| 264 GLsizei primcount) { | |
| 265 GLsizei total_size = 0; | |
| 266 // Compute the size of the buffer we need. | |
| 267 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { | |
| 268 VertexAttribInfo& info = vertex_attrib_infos_[ii]; | |
| 269 if (info.IsClientSide() && info.enabled()) { | |
| 270 size_t bytes_per_element = | |
| 271 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(info.type()) * | |
| 272 info.size(); | |
| 273 GLsizei elements = (primcount && info.divisor() > 0) ? | |
| 274 ((primcount - 1) / info.divisor() + 1) : num_elements; | |
| 275 total_size += RoundUpToMultipleOf4( | |
| 276 bytes_per_element * elements); | |
| 277 } | |
| 278 } | |
| 279 gl_helper->BindBuffer(GL_ARRAY_BUFFER, array_buffer_id_); | |
| 280 array_buffer_offset_ = 0; | |
| 281 if (total_size > array_buffer_size_) { | |
| 282 gl->BufferDataHelper(GL_ARRAY_BUFFER, total_size, NULL, GL_DYNAMIC_DRAW); | |
| 283 array_buffer_size_ = total_size; | |
| 284 } | |
| 285 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { | |
| 286 VertexAttribInfo& info = vertex_attrib_infos_[ii]; | |
| 287 if (info.IsClientSide() && info.enabled()) { | |
| 288 size_t bytes_per_element = | |
| 289 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(info.type()) * | |
| 290 info.size(); | |
| 291 GLsizei real_stride = info.stride() ? | |
| 292 info.stride() : static_cast<GLsizei>(bytes_per_element); | |
| 293 GLsizei elements = (primcount && info.divisor() > 0) ? | |
| 294 ((primcount - 1) / info.divisor() + 1) : num_elements; | |
| 295 GLsizei bytes_collected = CollectData( | |
| 296 info.pointer(), bytes_per_element, real_stride, elements); | |
| 297 gl->BufferSubDataHelper( | |
| 298 GL_ARRAY_BUFFER, array_buffer_offset_, bytes_collected, | |
| 299 collection_buffer_.get()); | |
| 300 gl_helper->VertexAttribPointer( | |
| 301 ii, info.size(), info.type(), info.normalized(), 0, | |
| 302 array_buffer_offset_); | |
| 303 array_buffer_offset_ += RoundUpToMultipleOf4(bytes_collected); | |
| 304 GPU_DCHECK_LE(array_buffer_offset_, array_buffer_size_); | |
| 305 } | |
| 306 } | |
| 307 } | |
| 308 | |
| 309 // Copies in indices to the service and returns the highest index accessed + 1 | |
| 310 bool SetupSimulatedIndexBuffer( | |
| 311 GLES2Implementation* gl, | |
| 312 GLES2CmdHelper* gl_helper, | |
| 313 GLsizei count, | |
| 314 GLenum type, | |
| 315 const void* indices, | |
| 316 GLsizei* max_index_out) { | |
| 317 GLsizei max_index = -1; | |
| 318 switch (type) { | |
| 319 case GL_UNSIGNED_BYTE: { | |
| 320 const uint8* src = static_cast<const uint8*>(indices); | |
| 321 for (GLsizei ii = 0; ii < count; ++ii) { | |
| 322 if (src[ii] > max_index) { | |
| 323 max_index = src[ii]; | |
| 324 } | |
| 325 } | |
| 326 break; | |
| 327 } | |
| 328 case GL_UNSIGNED_SHORT: { | |
| 329 const uint16* src = static_cast<const uint16*>(indices); | |
| 330 for (GLsizei ii = 0; ii < count; ++ii) { | |
| 331 if (src[ii] > max_index) { | |
| 332 max_index = src[ii]; | |
| 333 } | |
| 334 } | |
| 335 break; | |
| 336 } | |
| 337 case GL_UNSIGNED_INT: { | |
| 338 uint32 max_glsizei = static_cast<uint32>( | |
| 339 std::numeric_limits<GLsizei>::max()); | |
| 340 const uint32* src = static_cast<const uint32*>(indices); | |
| 341 for (GLsizei ii = 0; ii < count; ++ii) { | |
| 342 // Other parts of the API use GLsizei (signed) to store limits. | |
| 343 // As such, if we encounter a index that cannot be represented with | |
| 344 // an unsigned int we need to flag it as an error here. | |
| 345 | |
| 346 if(src[ii] > max_glsizei) { | |
| 347 return false; | |
| 348 } | |
| 349 GLsizei signed_index = static_cast<GLsizei>(src[ii]); | |
| 350 if (signed_index > max_index) { | |
| 351 max_index = signed_index; | |
| 352 } | |
| 353 } | |
| 354 break; | |
| 355 } | |
| 356 default: | |
| 357 break; | |
| 358 } | |
| 359 gl_helper->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_array_buffer_id_); | |
| 360 GLsizei bytes_per_element = | |
| 361 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); | |
| 362 GLsizei bytes_needed = bytes_per_element * count; | |
| 363 if (bytes_needed > element_array_buffer_size_) { | |
| 364 element_array_buffer_size_ = bytes_needed; | |
| 365 gl->BufferDataHelper( | |
| 366 GL_ELEMENT_ARRAY_BUFFER, bytes_needed, NULL, GL_DYNAMIC_DRAW); | |
| 367 } | |
| 368 gl->BufferSubDataHelper( | |
| 369 GL_ELEMENT_ARRAY_BUFFER, 0, bytes_needed, indices); | |
| 370 | |
| 371 *max_index_out = max_index + 1; | |
| 372 return true; | |
| 373 } | |
| 374 | |
| 375 private: | |
| 376 GLuint max_vertex_attribs_; | |
| 377 GLuint num_client_side_pointers_enabled_; | |
| 378 GLuint array_buffer_id_; | |
| 379 GLsizei array_buffer_size_; | |
| 380 GLsizei array_buffer_offset_; | |
| 381 GLuint element_array_buffer_id_; | |
| 382 GLsizei element_array_buffer_size_; | |
| 383 scoped_array<VertexAttribInfo> vertex_attrib_infos_; | |
| 384 GLsizei collection_buffer_size_; | |
| 385 scoped_array<int8> collection_buffer_; | |
| 386 | |
| 387 DISALLOW_COPY_AND_ASSIGN(ClientSideBufferHelper); | |
| 388 }; | |
| 389 | |
| 390 #if !defined(_MSC_VER) | 43 #if !defined(_MSC_VER) |
| 391 const size_t GLES2Implementation::kMaxSizeOfSimpleResult; | 44 const size_t GLES2Implementation::kMaxSizeOfSimpleResult; |
| 392 const unsigned int GLES2Implementation::kStartingOffset; | 45 const unsigned int GLES2Implementation::kStartingOffset; |
| 393 #endif | 46 #endif |
| 394 | 47 |
| 395 GLES2Implementation::GLStaticState::IntState::IntState() | 48 GLES2Implementation::GLStaticState::IntState::IntState() |
| 396 : max_combined_texture_image_units(0), | 49 : max_combined_texture_image_units(0), |
| 397 max_cube_map_texture_size(0), | 50 max_cube_map_texture_size(0), |
| 398 max_fragment_uniform_vectors(0), | 51 max_fragment_uniform_vectors(0), |
| 399 max_renderbuffer_size(0), | 52 max_renderbuffer_size(0), |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 unpack_flip_y_(false), | 86 unpack_flip_y_(false), |
| 434 unpack_row_length_(0), | 87 unpack_row_length_(0), |
| 435 unpack_skip_rows_(0), | 88 unpack_skip_rows_(0), |
| 436 unpack_skip_pixels_(0), | 89 unpack_skip_pixels_(0), |
| 437 pack_reverse_row_order_(false), | 90 pack_reverse_row_order_(false), |
| 438 active_texture_unit_(0), | 91 active_texture_unit_(0), |
| 439 bound_framebuffer_(0), | 92 bound_framebuffer_(0), |
| 440 bound_renderbuffer_(0), | 93 bound_renderbuffer_(0), |
| 441 current_program_(0), | 94 current_program_(0), |
| 442 bound_array_buffer_id_(0), | 95 bound_array_buffer_id_(0), |
| 443 bound_element_array_buffer_id_(0), | |
| 444 bound_pixel_unpack_transfer_buffer_id_(0), | 96 bound_pixel_unpack_transfer_buffer_id_(0), |
| 445 client_side_array_id_(0), | |
| 446 client_side_element_array_id_(0), | |
| 447 bound_vertex_array_id_(0), | |
| 448 error_bits_(0), | 97 error_bits_(0), |
| 449 debug_(false), | 98 debug_(false), |
| 450 use_count_(0), | 99 use_count_(0), |
| 451 current_query_(NULL), | 100 current_query_(NULL), |
| 452 error_message_callback_(NULL) { | 101 error_message_callback_(NULL) { |
| 453 GPU_DCHECK(helper); | 102 GPU_DCHECK(helper); |
| 454 GPU_DCHECK(transfer_buffer); | 103 GPU_DCHECK(transfer_buffer); |
| 455 | 104 |
| 456 char temp[128]; | 105 char temp[128]; |
| 457 sprintf(temp, "%p", static_cast<void*>(this)); | 106 sprintf(temp, "%p", static_cast<void*>(this)); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 texture_units_.reset( | 166 texture_units_.reset( |
| 518 new TextureUnit[ | 167 new TextureUnit[ |
| 519 static_state_.int_state.max_combined_texture_image_units]); | 168 static_state_.int_state.max_combined_texture_image_units]); |
| 520 | 169 |
| 521 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 170 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 522 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | 171 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| 523 | 172 |
| 524 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 173 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 525 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 174 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| 526 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 175 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
| 176 #endif |
| 527 | 177 |
| 528 client_side_buffer_helper_.reset(new ClientSideBufferHelper( | 178 vertex_array_object_manager_.reset(new VertexArrayObjectManager( |
| 529 static_state_.int_state.max_vertex_attribs, | 179 static_state_.int_state.max_vertex_attribs, |
| 530 reserved_ids_[0], | 180 reserved_ids_[0], |
| 531 reserved_ids_[1])); | 181 reserved_ids_[1])); |
| 532 #endif | |
| 533 | 182 |
| 534 return true; | 183 return true; |
| 535 } | 184 } |
| 536 | 185 |
| 537 GLES2Implementation::~GLES2Implementation() { | 186 GLES2Implementation::~GLES2Implementation() { |
| 538 // Make sure the queries are finished otherwise we'll delete the | 187 // Make sure the queries are finished otherwise we'll delete the |
| 539 // shared memory (mapped_memory_) which will free the memory used | 188 // shared memory (mapped_memory_) which will free the memory used |
| 540 // by the queries. The GPU process when validating that memory is still | 189 // by the queries. The GPU process when validating that memory is still |
| 541 // shared will fail and abort (ie, it will stop running). | 190 // shared will fail and abort (ie, it will stop running). |
| 542 Finish(); | 191 Finish(); |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 *params = static_state_.int_state.num_shader_binary_formats; | 546 *params = static_state_.int_state.num_shader_binary_formats; |
| 898 return true; | 547 return true; |
| 899 case GL_ARRAY_BUFFER_BINDING: | 548 case GL_ARRAY_BUFFER_BINDING: |
| 900 if (share_group_->bind_generates_resource()) { | 549 if (share_group_->bind_generates_resource()) { |
| 901 *params = bound_array_buffer_id_; | 550 *params = bound_array_buffer_id_; |
| 902 return true; | 551 return true; |
| 903 } | 552 } |
| 904 return false; | 553 return false; |
| 905 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 554 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
| 906 if (share_group_->bind_generates_resource()) { | 555 if (share_group_->bind_generates_resource()) { |
| 907 *params = bound_element_array_buffer_id_; | 556 *params = |
| 557 vertex_array_object_manager_->bound_element_array_buffer(); |
| 908 return true; | 558 return true; |
| 909 } | 559 } |
| 910 return false; | 560 return false; |
| 911 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | 561 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| 912 *params = bound_pixel_unpack_transfer_buffer_id_; | 562 *params = bound_pixel_unpack_transfer_buffer_id_; |
| 913 return true; | 563 return true; |
| 914 case GL_ACTIVE_TEXTURE: | 564 case GL_ACTIVE_TEXTURE: |
| 915 *params = active_texture_unit_ + GL_TEXTURE0; | 565 *params = active_texture_unit_ + GL_TEXTURE0; |
| 916 return true; | 566 return true; |
| 917 case GL_TEXTURE_BINDING_2D: | 567 case GL_TEXTURE_BINDING_2D: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM(" | 637 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM(" |
| 988 << buffer_id << ", " << count << ", " | 638 << buffer_id << ", " << count << ", " |
| 989 << GLES2Util::GetStringGetMaxIndexType(type) | 639 << GLES2Util::GetStringGetMaxIndexType(type) |
| 990 << ", " << offset << ")"); | 640 << ", " << offset << ")"); |
| 991 GLuint result = GetMaxValueInBufferCHROMIUMHelper( | 641 GLuint result = GetMaxValueInBufferCHROMIUMHelper( |
| 992 buffer_id, count, type, offset); | 642 buffer_id, count, type, offset); |
| 993 GPU_CLIENT_LOG("returned " << result); | 643 GPU_CLIENT_LOG("returned " << result); |
| 994 return result; | 644 return result; |
| 995 } | 645 } |
| 996 | 646 |
| 647 void GLES2Implementation::RestoreElementAndArrayBuffers(bool restore) { |
| 648 if (restore) { |
| 649 RestoreArrayBuffer(restore); |
| 650 // Restore the element array binding. |
| 651 // We only need to restore it if it wasn't a client side array. |
| 652 if (vertex_array_object_manager_->bound_element_array_buffer() == 0) { |
| 653 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
| 654 } |
| 655 } |
| 656 } |
| 657 |
| 658 void GLES2Implementation::RestoreArrayBuffer(bool restore) { |
| 659 if (restore) { |
| 660 // Restore the user's current binding. |
| 661 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); |
| 662 } |
| 663 } |
| 664 |
| 997 void GLES2Implementation::Clear(GLbitfield mask) { | 665 void GLES2Implementation::Clear(GLbitfield mask) { |
| 998 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 666 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 999 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")"); | 667 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")"); |
| 1000 helper_->Clear(mask); | 668 helper_->Clear(mask); |
| 1001 } | 669 } |
| 1002 | 670 |
| 1003 void GLES2Implementation::DrawElements( | 671 void GLES2Implementation::DrawElements( |
| 1004 GLenum mode, GLsizei count, GLenum type, const void* indices) { | 672 GLenum mode, GLsizei count, GLenum type, const void* indices) { |
| 1005 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 673 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1006 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" | 674 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" |
| 1007 << GLES2Util::GetStringDrawMode(mode) << ", " | 675 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 1008 << count << ", " | 676 << count << ", " |
| 1009 << GLES2Util::GetStringIndexType(type) << ", " | 677 << GLES2Util::GetStringIndexType(type) << ", " |
| 1010 << static_cast<const void*>(indices) << ")"); | 678 << static_cast<const void*>(indices) << ")"); |
| 1011 if (count < 0) { | 679 if (count < 0) { |
| 1012 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); | 680 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); |
| 1013 return; | 681 return; |
| 1014 } | 682 } |
| 1015 if (count == 0) { | 683 if (count == 0) { |
| 1016 return; | 684 return; |
| 1017 } | 685 } |
| 1018 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 686 GLuint offset = 0; |
| 1019 bool have_client_side = | 687 bool simulated = false; |
| 1020 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 688 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( |
| 1021 GLsizei num_elements = 0; | 689 "glDrawElements", this, helper_, count, type, 0, indices, |
| 1022 GLuint offset = ToGLuint(indices); | 690 &offset, &simulated)) { |
| 1023 bool success; | 691 return; |
| 1024 if (bound_element_array_buffer_id_ == 0) { | |
| 1025 // Index buffer is client side array. | |
| 1026 // Copy to buffer, scan for highest index. | |
| 1027 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer( | |
| 1028 this, helper_, count, type, indices, &num_elements); | |
| 1029 | |
| 1030 if(!success) { | |
| 1031 SetGLError(GL_INVALID_OPERATION, "glDrawElements", "index too large."); | |
| 1032 return; | |
| 1033 } | |
| 1034 | |
| 1035 offset = 0; | |
| 1036 } else { | |
| 1037 // Index buffer is GL buffer. Ask the service for the highest vertex | |
| 1038 // that will be accessed. Note: It doesn't matter if another context | |
| 1039 // changes the contents of any of the buffers. The service will still | |
| 1040 // validate the indices. We just need to know how much to copy across. | |
| 1041 if (have_client_side) { | |
| 1042 num_elements = GetMaxValueInBufferCHROMIUMHelper( | |
| 1043 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1; | |
| 1044 } | |
| 1045 } | |
| 1046 if (have_client_side) { | |
| 1047 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | |
| 1048 this, helper_, num_elements, 0); | |
| 1049 } | 692 } |
| 1050 helper_->DrawElements(mode, count, type, offset); | 693 helper_->DrawElements(mode, count, type, offset); |
| 1051 if (have_client_side) { | 694 RestoreElementAndArrayBuffers(simulated); |
| 1052 // Restore the user's current binding. | |
| 1053 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 1054 } | |
| 1055 if (bound_element_array_buffer_id_ == 0) { | |
| 1056 // Restore the element array binding. | |
| 1057 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 1058 } | |
| 1059 #else | |
| 1060 helper_->DrawElements(mode, count, type, ToGLuint(indices)); | |
| 1061 #endif | |
| 1062 } | 695 } |
| 1063 | 696 |
| 1064 void GLES2Implementation::Flush() { | 697 void GLES2Implementation::Flush() { |
| 1065 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 698 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1066 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); | 699 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); |
| 1067 // Insert the cmd to call glFlush | 700 // Insert the cmd to call glFlush |
| 1068 helper_->Flush(); | 701 helper_->Flush(); |
| 1069 // Flush our command buffer | 702 // Flush our command buffer |
| 1070 // (tell the service to execute up to the flush cmd.) | 703 // (tell the service to execute up to the flush cmd.) |
| 1071 helper_->CommandBufferHelper::Flush(); | 704 helper_->CommandBufferHelper::Flush(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 program, location, kResultBucketId); | 859 program, location, kResultBucketId); |
| 1227 helper_->SetBucketSize(kResultBucketId, 0); | 860 helper_->SetBucketSize(kResultBucketId, 0); |
| 1228 } | 861 } |
| 1229 | 862 |
| 1230 void GLES2Implementation::GetVertexAttribPointerv( | 863 void GLES2Implementation::GetVertexAttribPointerv( |
| 1231 GLuint index, GLenum pname, void** ptr) { | 864 GLuint index, GLenum pname, void** ptr) { |
| 1232 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 865 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1233 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" | 866 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" |
| 1234 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", " | 867 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", " |
| 1235 << static_cast<void*>(ptr) << ")"); | 868 << static_cast<void*>(ptr) << ")"); |
| 1236 | 869 GPU_CLIENT_LOG_CODE_BLOCK(int32 num_results = 1); |
| 1237 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 870 if (!vertex_array_object_manager_->GetAttribPointer(index, pname, ptr)) { |
| 1238 // If it's a client side buffer the client has the data. | 871 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv"); |
| 1239 if (client_side_buffer_helper_->GetAttribPointer(index, pname, ptr)) { | 872 typedef gles2::GetVertexAttribPointerv::Result Result; |
| 1240 return; | 873 Result* result = GetResultAs<Result*>(); |
| 874 if (!result) { |
| 875 return; |
| 876 } |
| 877 result->SetNumResults(0); |
| 878 helper_->GetVertexAttribPointerv( |
| 879 index, pname, GetResultShmId(), GetResultShmOffset()); |
| 880 WaitForCmd(); |
| 881 result->CopyResult(ptr); |
| 882 GPU_CLIENT_LOG_CODE_BLOCK(num_results = result->GetNumResults()); |
| 1241 } | 883 } |
| 1242 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1243 | |
| 1244 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv"); | |
| 1245 typedef gles2::GetVertexAttribPointerv::Result Result; | |
| 1246 Result* result = GetResultAs<Result*>(); | |
| 1247 if (!result) { | |
| 1248 return; | |
| 1249 } | |
| 1250 result->SetNumResults(0); | |
| 1251 helper_->GetVertexAttribPointerv( | |
| 1252 index, pname, GetResultShmId(), GetResultShmOffset()); | |
| 1253 WaitForCmd(); | |
| 1254 result->CopyResult(ptr); | |
| 1255 GPU_CLIENT_LOG_CODE_BLOCK({ | 884 GPU_CLIENT_LOG_CODE_BLOCK({ |
| 1256 for (int32 i = 0; i < result->GetNumResults(); ++i) { | 885 for (int32 i = 0; i < num_results; ++i) { |
| 1257 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); | 886 GPU_CLIENT_LOG(" " << i << ": " << ptr[i]); |
| 1258 } | 887 } |
| 1259 }); | 888 }); |
| 1260 } | 889 } |
| 1261 | 890 |
| 1262 bool GLES2Implementation::DeleteProgramHelper(GLuint program) { | 891 bool GLES2Implementation::DeleteProgramHelper(GLuint program) { |
| 1263 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( | 892 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( |
| 1264 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { | 893 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { |
| 1265 SetGLError( | 894 SetGLError( |
| 1266 GL_INVALID_VALUE, | 895 GL_INVALID_VALUE, |
| 1267 "glDeleteProgram", "id not created by this context."); | 896 "glDeleteProgram", "id not created by this context."); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, | 1090 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, |
| 1462 const void* ptr) { | 1091 const void* ptr) { |
| 1463 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1092 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1464 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" | 1093 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" |
| 1465 << index << ", " | 1094 << index << ", " |
| 1466 << size << ", " | 1095 << size << ", " |
| 1467 << GLES2Util::GetStringVertexAttribType(type) << ", " | 1096 << GLES2Util::GetStringVertexAttribType(type) << ", " |
| 1468 << GLES2Util::GetStringBool(normalized) << ", " | 1097 << GLES2Util::GetStringBool(normalized) << ", " |
| 1469 << stride << ", " | 1098 << stride << ", " |
| 1470 << static_cast<const void*>(ptr) << ")"); | 1099 << static_cast<const void*>(ptr) << ")"); |
| 1100 // Record the info on the client side. |
| 1101 if (!vertex_array_object_manager_->SetAttribPointer( |
| 1102 bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) { |
| 1103 SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer", |
| 1104 "client side arrays are not allowed in vertex array objects."); |
| 1105 return; |
| 1106 } |
| 1471 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1107 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 1472 // Record the info on the client side. | |
| 1473 client_side_buffer_helper_->SetAttribPointer( | |
| 1474 bound_array_buffer_id_, index, size, type, normalized, stride, ptr); | |
| 1475 if (bound_array_buffer_id_ != 0) { | 1108 if (bound_array_buffer_id_ != 0) { |
| 1476 // Only report NON client side buffers to the service. | 1109 // Only report NON client side buffers to the service. |
| 1477 helper_->VertexAttribPointer(index, size, type, normalized, stride, | 1110 helper_->VertexAttribPointer(index, size, type, normalized, stride, |
| 1478 ToGLuint(ptr)); | 1111 ToGLuint(ptr)); |
| 1479 } | 1112 } |
| 1480 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1113 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 1481 helper_->VertexAttribPointer(index, size, type, normalized, stride, | 1114 helper_->VertexAttribPointer(index, size, type, normalized, stride, |
| 1482 ToGLuint(ptr)); | 1115 ToGLuint(ptr)); |
| 1483 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1116 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 1484 } | 1117 } |
| 1485 | 1118 |
| 1486 void GLES2Implementation::VertexAttribDivisorANGLE( | 1119 void GLES2Implementation::VertexAttribDivisorANGLE( |
| 1487 GLuint index, GLuint divisor) { | 1120 GLuint index, GLuint divisor) { |
| 1488 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1121 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1489 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" | 1122 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" |
| 1490 << index << ", " | 1123 << index << ", " |
| 1491 << divisor << ") "); | 1124 << divisor << ") "); |
| 1492 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1493 // Record the info on the client side. | 1125 // Record the info on the client side. |
| 1494 client_side_buffer_helper_->SetAttribDivisor(index, divisor); | 1126 vertex_array_object_manager_->SetAttribDivisor(index, divisor); |
| 1495 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1496 helper_->VertexAttribDivisorANGLE(index, divisor); | 1127 helper_->VertexAttribDivisorANGLE(index, divisor); |
| 1497 } | 1128 } |
| 1498 | 1129 |
| 1499 void GLES2Implementation::ShaderSource( | 1130 void GLES2Implementation::ShaderSource( |
| 1500 GLuint shader, GLsizei count, const char** source, const GLint* length) { | 1131 GLuint shader, GLsizei count, const char** source, const GLint* length) { |
| 1501 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1132 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1502 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" | 1133 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" |
| 1503 << shader << ", " << count << ", " | 1134 << shader << ", " << count << ", " |
| 1504 << static_cast<const void*>(source) << ", " | 1135 << static_cast<const void*>(source) << ", " |
| 1505 << static_cast<const void*>(length) << ")"); | 1136 << static_cast<const void*>(length) << ")"); |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 static_state_.int_state.max_combined_texture_image_units)) { | 2100 static_state_.int_state.max_combined_texture_image_units)) { |
| 2470 SetGLErrorInvalidEnum( | 2101 SetGLErrorInvalidEnum( |
| 2471 "glActiveTexture", texture, "texture"); | 2102 "glActiveTexture", texture, "texture"); |
| 2472 return; | 2103 return; |
| 2473 } | 2104 } |
| 2474 | 2105 |
| 2475 active_texture_unit_ = texture_index; | 2106 active_texture_unit_ = texture_index; |
| 2476 helper_->ActiveTexture(texture); | 2107 helper_->ActiveTexture(texture); |
| 2477 } | 2108 } |
| 2478 | 2109 |
| 2110 void GLES2Implementation::GenBuffersHelper( |
| 2111 GLsizei /* n */, const GLuint* /* buffers */) { |
| 2112 } |
| 2113 |
| 2114 void GLES2Implementation::GenFramebuffersHelper( |
| 2115 GLsizei /* n */, const GLuint* /* framebuffers */) { |
| 2116 } |
| 2117 |
| 2118 void GLES2Implementation::GenRenderbuffersHelper( |
| 2119 GLsizei /* n */, const GLuint* /* renderbuffers */) { |
| 2120 } |
| 2121 |
| 2122 void GLES2Implementation::GenTexturesHelper( |
| 2123 GLsizei /* n */, const GLuint* /* textures */) { |
| 2124 } |
| 2125 |
| 2126 void GLES2Implementation::GenVertexArraysOESHelper( |
| 2127 GLsizei n, const GLuint* arrays) { |
| 2128 vertex_array_object_manager_->GenVertexArrays(n, arrays); |
| 2129 } |
| 2130 |
| 2131 void GLES2Implementation::GenQueriesEXTHelper( |
| 2132 GLsizei /* n */, const GLuint* /* queries */) { |
| 2133 } |
| 2134 |
| 2479 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id | 2135 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id |
| 2480 // generates a new resource. On newer versions of OpenGL they don't. The code | 2136 // generates a new resource. On newer versions of OpenGL they don't. The code |
| 2481 // related to binding below will need to change if we switch to the new OpenGL | 2137 // related to binding below will need to change if we switch to the new OpenGL |
| 2482 // model. Specifically it assumes a bind will succeed which is always true in | 2138 // model. Specifically it assumes a bind will succeed which is always true in |
| 2483 // the old model but possibly not true in the new model if another context has | 2139 // the old model but possibly not true in the new model if another context has |
| 2484 // deleted the resource. | 2140 // deleted the resource. |
| 2485 | 2141 |
| 2486 bool GLES2Implementation::BindBufferHelper( | 2142 bool GLES2Implementation::BindBufferHelper( |
| 2487 GLenum target, GLuint buffer) { | 2143 GLenum target, GLuint buffer) { |
| 2488 // TODO(gman): See note #1 above. | 2144 // TODO(gman): See note #1 above. |
| 2489 bool changed = false; | 2145 bool changed = false; |
| 2490 switch (target) { | 2146 switch (target) { |
| 2491 case GL_ARRAY_BUFFER: | 2147 case GL_ARRAY_BUFFER: |
| 2492 if (bound_array_buffer_id_ != buffer) { | 2148 if (bound_array_buffer_id_ != buffer) { |
| 2493 bound_array_buffer_id_ = buffer; | 2149 bound_array_buffer_id_ = buffer; |
| 2494 changed = true; | 2150 changed = true; |
| 2495 } | 2151 } |
| 2496 break; | 2152 break; |
| 2497 case GL_ELEMENT_ARRAY_BUFFER: | 2153 case GL_ELEMENT_ARRAY_BUFFER: |
| 2498 if (bound_element_array_buffer_id_ != buffer) { | 2154 changed = vertex_array_object_manager_->BindElementArray(buffer); |
| 2499 bound_element_array_buffer_id_ = buffer; | |
| 2500 changed = true; | |
| 2501 } | |
| 2502 break; | 2155 break; |
| 2503 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2156 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2504 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2157 bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| 2505 break; | 2158 break; |
| 2506 default: | 2159 default: |
| 2507 changed = true; | 2160 changed = true; |
| 2508 break; | 2161 break; |
| 2509 } | 2162 } |
| 2510 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2163 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2511 // used even though it's marked it as used here. | 2164 // used even though it's marked it as used here. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 } | 2233 } |
| 2581 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2234 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2582 // used. even though it's marked it as used here. | 2235 // used. even though it's marked it as used here. |
| 2583 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); | 2236 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); |
| 2584 return changed; | 2237 return changed; |
| 2585 } | 2238 } |
| 2586 | 2239 |
| 2587 bool GLES2Implementation::BindVertexArrayHelper(GLuint array) { | 2240 bool GLES2Implementation::BindVertexArrayHelper(GLuint array) { |
| 2588 // TODO(gman): See note #1 above. | 2241 // TODO(gman): See note #1 above. |
| 2589 bool changed = false; | 2242 bool changed = false; |
| 2590 if (bound_vertex_array_id_ != array) { | 2243 if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) { |
| 2591 bound_vertex_array_id_ = array; | 2244 SetGLError( |
| 2592 changed = true; | 2245 GL_INVALID_OPERATION, "glBindVertexArrayOES", |
| 2246 "id was not generated with glGenVertexArrayOES"); |
| 2593 } | 2247 } |
| 2594 GetIdHandler(id_namespaces::kVertexArrays)->MarkAsUsedForBind(array); | 2248 // Unlike other BindXXXHelpers we don't call MarkAsUsedForBind |
| 2249 // because unlike other resources VertexArrayObject ids must |
| 2250 // be generated by GenVertexArrays. A random id to Bind will not |
| 2251 // generate a new object. |
| 2595 return changed; | 2252 return changed; |
| 2596 } | 2253 } |
| 2597 | 2254 |
| 2598 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2599 bool GLES2Implementation::IsBufferReservedId(GLuint id) { | 2255 bool GLES2Implementation::IsBufferReservedId(GLuint id) { |
| 2600 for (size_t ii = 0; ii < arraysize(reserved_ids_); ++ii) { | 2256 return vertex_array_object_manager_->IsReservedId(id); |
| 2601 if (id == reserved_ids_[ii]) { | |
| 2602 return true; | |
| 2603 } | |
| 2604 } | |
| 2605 return false; | |
| 2606 } | 2257 } |
| 2607 #else | |
| 2608 bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) { | |
| 2609 return false; | |
| 2610 } | |
| 2611 #endif | |
| 2612 | 2258 |
| 2613 void GLES2Implementation::DeleteBuffersHelper( | 2259 void GLES2Implementation::DeleteBuffersHelper( |
| 2614 GLsizei n, const GLuint* buffers) { | 2260 GLsizei n, const GLuint* buffers) { |
| 2615 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( | 2261 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( |
| 2616 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { | 2262 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { |
| 2617 SetGLError( | 2263 SetGLError( |
| 2618 GL_INVALID_VALUE, | 2264 GL_INVALID_VALUE, |
| 2619 "glDeleteBuffers", "id not created by this context."); | 2265 "glDeleteBuffers", "id not created by this context."); |
| 2620 return; | 2266 return; |
| 2621 } | 2267 } |
| 2622 for (GLsizei ii = 0; ii < n; ++ii) { | 2268 for (GLsizei ii = 0; ii < n; ++ii) { |
| 2623 if (buffers[ii] == bound_array_buffer_id_) { | 2269 if (buffers[ii] == bound_array_buffer_id_) { |
| 2624 bound_array_buffer_id_ = 0; | 2270 bound_array_buffer_id_ = 0; |
| 2625 } | 2271 } |
| 2626 if (buffers[ii] == bound_element_array_buffer_id_) { | 2272 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
| 2627 bound_element_array_buffer_id_ = 0; | |
| 2628 } | |
| 2629 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | |
| 2630 bound_pixel_unpack_transfer_buffer_id_ = 0; | |
| 2631 } | |
| 2632 | |
| 2633 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | 2273 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| 2634 if (buffer) { | 2274 if (buffer) { |
| 2635 // Free buffer memory, pending the passage of a token. | 2275 // Free buffer memory, pending the passage of a token. |
| 2636 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 2276 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 2637 // Remove buffer. | 2277 // Remove buffer. |
| 2638 buffer_tracker_->RemoveBuffer(buffers[ii]); | 2278 buffer_tracker_->RemoveBuffer(buffers[ii]); |
| 2639 } | 2279 } |
| 2280 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
| 2281 bound_pixel_unpack_transfer_buffer_id_ = 0; |
| 2282 } |
| 2640 } | 2283 } |
| 2641 } | 2284 } |
| 2642 | 2285 |
| 2643 void GLES2Implementation::DeleteBuffersStub( | 2286 void GLES2Implementation::DeleteBuffersStub( |
| 2644 GLsizei n, const GLuint* buffers) { | 2287 GLsizei n, const GLuint* buffers) { |
| 2645 helper_->DeleteBuffersImmediate(n, buffers); | 2288 helper_->DeleteBuffersImmediate(n, buffers); |
| 2646 } | 2289 } |
| 2647 | 2290 |
| 2648 | 2291 |
| 2649 void GLES2Implementation::DeleteFramebuffersHelper( | 2292 void GLES2Implementation::DeleteFramebuffersHelper( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2707 } | 2350 } |
| 2708 if (textures[ii] == unit.bound_texture_cube_map) { | 2351 if (textures[ii] == unit.bound_texture_cube_map) { |
| 2709 unit.bound_texture_cube_map = 0; | 2352 unit.bound_texture_cube_map = 0; |
| 2710 } | 2353 } |
| 2711 } | 2354 } |
| 2712 } | 2355 } |
| 2713 } | 2356 } |
| 2714 | 2357 |
| 2715 void GLES2Implementation::DeleteVertexArraysOESHelper( | 2358 void GLES2Implementation::DeleteVertexArraysOESHelper( |
| 2716 GLsizei n, const GLuint* arrays) { | 2359 GLsizei n, const GLuint* arrays) { |
| 2360 vertex_array_object_manager_->DeleteVertexArrays(n, arrays); |
| 2717 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( | 2361 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( |
| 2718 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { | 2362 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { |
| 2719 SetGLError( | 2363 SetGLError( |
| 2720 GL_INVALID_VALUE, | 2364 GL_INVALID_VALUE, |
| 2721 "glDeleteVertexArraysOES", "id not created by this context."); | 2365 "glDeleteVertexArraysOES", "id not created by this context."); |
| 2722 return; | 2366 return; |
| 2723 } | 2367 } |
| 2724 for (GLsizei ii = 0; ii < n; ++ii) { | |
| 2725 if (arrays[ii] == bound_vertex_array_id_) { | |
| 2726 bound_vertex_array_id_ = 0; | |
| 2727 } | |
| 2728 } | |
| 2729 } | 2368 } |
| 2730 | 2369 |
| 2731 void GLES2Implementation::DeleteVertexArraysOESStub( | 2370 void GLES2Implementation::DeleteVertexArraysOESStub( |
| 2732 GLsizei n, const GLuint* arrays) { | 2371 GLsizei n, const GLuint* arrays) { |
| 2733 helper_->DeleteVertexArraysOESImmediate(n, arrays); | 2372 helper_->DeleteVertexArraysOESImmediate(n, arrays); |
| 2734 } | 2373 } |
| 2735 | 2374 |
| 2736 void GLES2Implementation::DeleteTexturesStub( | 2375 void GLES2Implementation::DeleteTexturesStub( |
| 2737 GLsizei n, const GLuint* textures) { | 2376 GLsizei n, const GLuint* textures) { |
| 2738 helper_->DeleteTexturesImmediate(n, textures); | 2377 helper_->DeleteTexturesImmediate(n, textures); |
| 2739 } | 2378 } |
| 2740 | 2379 |
| 2741 void GLES2Implementation::DisableVertexAttribArray(GLuint index) { | 2380 void GLES2Implementation::DisableVertexAttribArray(GLuint index) { |
| 2742 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2381 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2743 GPU_CLIENT_LOG( | 2382 GPU_CLIENT_LOG( |
| 2744 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")"); | 2383 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")"); |
| 2745 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2384 vertex_array_object_manager_->SetAttribEnable(index, false); |
| 2746 client_side_buffer_helper_->SetAttribEnable(index, false); | |
| 2747 #endif | |
| 2748 helper_->DisableVertexAttribArray(index); | 2385 helper_->DisableVertexAttribArray(index); |
| 2749 } | 2386 } |
| 2750 | 2387 |
| 2751 void GLES2Implementation::EnableVertexAttribArray(GLuint index) { | 2388 void GLES2Implementation::EnableVertexAttribArray(GLuint index) { |
| 2752 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2389 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2753 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray(" | 2390 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray(" |
| 2754 << index << ")"); | 2391 << index << ")"); |
| 2755 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2392 vertex_array_object_manager_->SetAttribEnable(index, true); |
| 2756 client_side_buffer_helper_->SetAttribEnable(index, true); | |
| 2757 #endif | |
| 2758 helper_->EnableVertexAttribArray(index); | 2393 helper_->EnableVertexAttribArray(index); |
| 2759 } | 2394 } |
| 2760 | 2395 |
| 2761 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { | 2396 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { |
| 2762 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2397 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2763 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays(" | 2398 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays(" |
| 2764 << GLES2Util::GetStringDrawMode(mode) << ", " | 2399 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 2765 << first << ", " << count << ")"); | 2400 << first << ", " << count << ")"); |
| 2766 if (count < 0) { | 2401 if (count < 0) { |
| 2767 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0"); | 2402 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0"); |
| 2768 return; | 2403 return; |
| 2769 } | 2404 } |
| 2770 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2405 bool simulated = false; |
| 2771 bool have_client_side = | 2406 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers( |
| 2772 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 2407 "glDrawArrays", this, helper_, first + count, 0, &simulated)) { |
| 2773 if (have_client_side) { | 2408 return; |
| 2774 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | |
| 2775 this, helper_, first + count, 0); | |
| 2776 } | 2409 } |
| 2777 #endif | |
| 2778 helper_->DrawArrays(mode, first, count); | 2410 helper_->DrawArrays(mode, first, count); |
| 2779 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2411 RestoreArrayBuffer(simulated); |
| 2780 if (have_client_side) { | |
| 2781 // Restore the user's current binding. | |
| 2782 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 2783 } | |
| 2784 #endif | |
| 2785 } | 2412 } |
| 2786 | 2413 |
| 2787 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2788 bool GLES2Implementation::GetVertexAttribHelper( | |
| 2789 GLuint index, GLenum pname, uint32* param) { | |
| 2790 const ClientSideBufferHelper::VertexAttribInfo* info = | |
| 2791 client_side_buffer_helper_->GetAttribInfo(index); | |
| 2792 if (!info) { | |
| 2793 return false; | |
| 2794 } | |
| 2795 | |
| 2796 switch (pname) { | |
| 2797 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: | |
| 2798 *param = info->buffer_id(); | |
| 2799 break; | |
| 2800 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: | |
| 2801 *param = info->enabled(); | |
| 2802 break; | |
| 2803 case GL_VERTEX_ATTRIB_ARRAY_SIZE: | |
| 2804 *param = info->size(); | |
| 2805 break; | |
| 2806 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: | |
| 2807 *param = info->stride(); | |
| 2808 break; | |
| 2809 case GL_VERTEX_ATTRIB_ARRAY_TYPE: | |
| 2810 *param = info->type(); | |
| 2811 break; | |
| 2812 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: | |
| 2813 *param = info->normalized(); | |
| 2814 break; | |
| 2815 case GL_CURRENT_VERTEX_ATTRIB: | |
| 2816 return false; // pass through to service side. | |
| 2817 default: | |
| 2818 SetGLErrorInvalidEnum("glGetVertexAttrib", pname, "pname"); | |
| 2819 break; | |
| 2820 } | |
| 2821 return true; | |
| 2822 } | |
| 2823 #endif // GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | |
| 2824 | |
| 2825 void GLES2Implementation::GetVertexAttribfv( | 2414 void GLES2Implementation::GetVertexAttribfv( |
| 2826 GLuint index, GLenum pname, GLfloat* params) { | 2415 GLuint index, GLenum pname, GLfloat* params) { |
| 2827 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2416 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2828 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" | 2417 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" |
| 2829 << index << ", " | 2418 << index << ", " |
| 2830 << GLES2Util::GetStringVertexAttribute(pname) << ", " | 2419 << GLES2Util::GetStringVertexAttribute(pname) << ", " |
| 2831 << static_cast<const void*>(params) << ")"); | 2420 << static_cast<const void*>(params) << ")"); |
| 2832 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2833 uint32 value = 0; | 2421 uint32 value = 0; |
| 2834 if (GetVertexAttribHelper(index, pname, &value)) { | 2422 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { |
| 2835 *params = static_cast<float>(value); | 2423 *params = static_cast<float>(value); |
| 2836 return; | 2424 return; |
| 2837 } | 2425 } |
| 2838 #endif | |
| 2839 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); | 2426 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); |
| 2840 typedef GetVertexAttribfv::Result Result; | 2427 typedef GetVertexAttribfv::Result Result; |
| 2841 Result* result = GetResultAs<Result*>(); | 2428 Result* result = GetResultAs<Result*>(); |
| 2842 if (!result) { | 2429 if (!result) { |
| 2843 return; | 2430 return; |
| 2844 } | 2431 } |
| 2845 result->SetNumResults(0); | 2432 result->SetNumResults(0); |
| 2846 helper_->GetVertexAttribfv( | 2433 helper_->GetVertexAttribfv( |
| 2847 index, pname, GetResultShmId(), GetResultShmOffset()); | 2434 index, pname, GetResultShmId(), GetResultShmOffset()); |
| 2848 WaitForCmd(); | 2435 WaitForCmd(); |
| 2849 result->CopyResult(params); | 2436 result->CopyResult(params); |
| 2850 GPU_CLIENT_LOG_CODE_BLOCK({ | 2437 GPU_CLIENT_LOG_CODE_BLOCK({ |
| 2851 for (int32 i = 0; i < result->GetNumResults(); ++i) { | 2438 for (int32 i = 0; i < result->GetNumResults(); ++i) { |
| 2852 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); | 2439 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); |
| 2853 } | 2440 } |
| 2854 }); | 2441 }); |
| 2855 } | 2442 } |
| 2856 | 2443 |
| 2857 void GLES2Implementation::GetVertexAttribiv( | 2444 void GLES2Implementation::GetVertexAttribiv( |
| 2858 GLuint index, GLenum pname, GLint* params) { | 2445 GLuint index, GLenum pname, GLint* params) { |
| 2859 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2446 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2860 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" | 2447 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" |
| 2861 << index << ", " | 2448 << index << ", " |
| 2862 << GLES2Util::GetStringVertexAttribute(pname) << ", " | 2449 << GLES2Util::GetStringVertexAttribute(pname) << ", " |
| 2863 << static_cast<const void*>(params) << ")"); | 2450 << static_cast<const void*>(params) << ")"); |
| 2864 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2865 uint32 value = 0; | 2451 uint32 value = 0; |
| 2866 if (GetVertexAttribHelper(index, pname, &value)) { | 2452 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { |
| 2867 *params = value; | 2453 *params = value; |
| 2868 return; | 2454 return; |
| 2869 } | 2455 } |
| 2870 #endif | |
| 2871 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); | 2456 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); |
| 2872 typedef GetVertexAttribiv::Result Result; | 2457 typedef GetVertexAttribiv::Result Result; |
| 2873 Result* result = GetResultAs<Result*>(); | 2458 Result* result = GetResultAs<Result*>(); |
| 2874 if (!result) { | 2459 if (!result) { |
| 2875 return; | 2460 return; |
| 2876 } | 2461 } |
| 2877 result->SetNumResults(0); | 2462 result->SetNumResults(0); |
| 2878 helper_->GetVertexAttribiv( | 2463 helper_->GetVertexAttribiv( |
| 2879 index, pname, GetResultShmId(), GetResultShmOffset()); | 2464 index, pname, GetResultShmId(), GetResultShmOffset()); |
| 2880 WaitForCmd(); | 2465 WaitForCmd(); |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3442 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0"); | 3027 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0"); |
| 3443 return; | 3028 return; |
| 3444 } | 3029 } |
| 3445 if (primcount < 0) { | 3030 if (primcount < 0) { |
| 3446 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0"); | 3031 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0"); |
| 3447 return; | 3032 return; |
| 3448 } | 3033 } |
| 3449 if (primcount == 0) { | 3034 if (primcount == 0) { |
| 3450 return; | 3035 return; |
| 3451 } | 3036 } |
| 3452 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 3037 bool simulated = false; |
| 3453 bool have_client_side = | 3038 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers( |
| 3454 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 3039 "glDrawArraysInstancedANGLE", this, helper_, first + count, primcount, |
| 3455 if (have_client_side) { | 3040 &simulated)) { |
| 3456 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | 3041 return; |
| 3457 this, helper_, first + count, primcount); | |
| 3458 } | 3042 } |
| 3459 #endif | |
| 3460 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount); | 3043 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount); |
| 3461 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 3044 RestoreArrayBuffer(simulated); |
| 3462 if (have_client_side) { | |
| 3463 // Restore the user's current binding. | |
| 3464 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 3465 } | |
| 3466 #endif | |
| 3467 } | 3045 } |
| 3468 | 3046 |
| 3469 void GLES2Implementation::DrawElementsInstancedANGLE( | 3047 void GLES2Implementation::DrawElementsInstancedANGLE( |
| 3470 GLenum mode, GLsizei count, GLenum type, const void* indices, | 3048 GLenum mode, GLsizei count, GLenum type, const void* indices, |
| 3471 GLsizei primcount) { | 3049 GLsizei primcount) { |
| 3472 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3050 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3473 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE(" | 3051 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE(" |
| 3474 << GLES2Util::GetStringDrawMode(mode) << ", " | 3052 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 3475 << count << ", " | 3053 << count << ", " |
| 3476 << GLES2Util::GetStringIndexType(type) << ", " | 3054 << GLES2Util::GetStringIndexType(type) << ", " |
| 3477 << static_cast<const void*>(indices) << ", " | 3055 << static_cast<const void*>(indices) << ", " |
| 3478 << primcount << ")"); | 3056 << primcount << ")"); |
| 3479 if (count < 0) { | 3057 if (count < 0) { |
| 3480 SetGLError(GL_INVALID_VALUE, | 3058 SetGLError(GL_INVALID_VALUE, |
| 3481 "glDrawElementsInstancedANGLE", "count less than 0."); | 3059 "glDrawElementsInstancedANGLE", "count less than 0."); |
| 3482 return; | 3060 return; |
| 3483 } | 3061 } |
| 3484 if (count == 0) { | 3062 if (count == 0) { |
| 3485 return; | 3063 return; |
| 3486 } | 3064 } |
| 3487 if (primcount < 0) { | 3065 if (primcount < 0) { |
| 3488 SetGLError(GL_INVALID_VALUE, | 3066 SetGLError(GL_INVALID_VALUE, |
| 3489 "glDrawElementsInstancedANGLE", "primcount < 0"); | 3067 "glDrawElementsInstancedANGLE", "primcount < 0"); |
| 3490 return; | 3068 return; |
| 3491 } | 3069 } |
| 3492 if (primcount == 0) { | 3070 if (primcount == 0) { |
| 3493 return; | 3071 return; |
| 3494 } | 3072 } |
| 3495 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 3073 GLuint offset = 0; |
| 3496 bool have_client_side = | 3074 bool simulated = false; |
| 3497 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 3075 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( |
| 3498 GLsizei num_elements = 0; | 3076 "glDrawElementsInstancedANGLE", this, helper_, count, type, primcount, |
| 3499 GLuint offset = ToGLuint(indices); | 3077 indices, &offset, &simulated)) { |
| 3500 bool success; | 3078 return; |
| 3501 if (bound_element_array_buffer_id_ == 0) { | |
| 3502 // Index buffer is client side array. | |
| 3503 // Copy to buffer, scan for highest index. | |
| 3504 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer( | |
| 3505 this, helper_, count, type, indices, &num_elements); | |
| 3506 | |
| 3507 if(!success) { | |
| 3508 SetGLError(GL_INVALID_OPERATION, "glDrawElementsInstancedANGLE", | |
| 3509 "index too large."); | |
| 3510 return; | |
| 3511 } | |
| 3512 | |
| 3513 offset = 0; | |
| 3514 } else { | |
| 3515 // Index buffer is GL buffer. Ask the service for the highest vertex | |
| 3516 // that will be accessed. Note: It doesn't matter if another context | |
| 3517 // changes the contents of any of the buffers. The service will still | |
| 3518 // validate the indices. We just need to know how much to copy across. | |
| 3519 if (have_client_side) { | |
| 3520 num_elements = GetMaxValueInBufferCHROMIUMHelper( | |
| 3521 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1; | |
| 3522 } | |
| 3523 } | |
| 3524 if (have_client_side) { | |
| 3525 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | |
| 3526 this, helper_, num_elements, primcount); | |
| 3527 } | 3079 } |
| 3528 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount); | 3080 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount); |
| 3529 if (have_client_side) { | 3081 RestoreElementAndArrayBuffers(simulated); |
| 3530 // Restore the user's current binding. | |
| 3531 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 3532 } | |
| 3533 if (bound_element_array_buffer_id_ == 0) { | |
| 3534 // Restore the element array binding. | |
| 3535 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 3536 } | |
| 3537 #else | |
| 3538 helper_->DrawElementsInstancedANGLE( | |
| 3539 mode, count, type, ToGLuint(indices), primcount); | |
| 3540 #endif | |
| 3541 } | 3082 } |
| 3542 | 3083 |
| 3543 void GLES2Implementation::GenMailboxCHROMIUM( | 3084 void GLES2Implementation::GenMailboxCHROMIUM( |
| 3544 GLbyte* mailbox) { | 3085 GLbyte* mailbox) { |
| 3545 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3086 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3546 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM(" | 3087 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM(" |
| 3547 << static_cast<const void*>(mailbox) << ")"); | 3088 << static_cast<const void*>(mailbox) << ")"); |
| 3548 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); | 3089 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); |
| 3549 | 3090 |
| 3550 helper_->GenMailboxCHROMIUM(kResultBucketId); | 3091 helper_->GenMailboxCHROMIUM(kResultBucketId); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3659 return true; | 3200 return true; |
| 3660 } | 3201 } |
| 3661 | 3202 |
| 3662 // Include the auto-generated part of this file. We split this because it means | 3203 // Include the auto-generated part of this file. We split this because it means |
| 3663 // we can easily edit the non-auto generated parts right here in this file | 3204 // we can easily edit the non-auto generated parts right here in this file |
| 3664 // instead of having to edit some template or the code generator. | 3205 // instead of having to edit some template or the code generator. |
| 3665 #include "../client/gles2_implementation_impl_autogen.h" | 3206 #include "../client/gles2_implementation_impl_autogen.h" |
| 3666 | 3207 |
| 3667 } // namespace gles2 | 3208 } // namespace gles2 |
| 3668 } // namespace gpu | 3209 } // namespace gpu |
| OLD | NEW |