Chromium Code Reviews| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 unpack_alignment_(4), | 85 unpack_alignment_(4), |
| 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 bound_array_buffer_id_(0), | 94 bound_array_buffer_id_(0), |
| 442 bound_element_array_buffer_id_(0), | |
| 443 bound_pixel_unpack_transfer_buffer_id_(0), | 95 bound_pixel_unpack_transfer_buffer_id_(0), |
| 444 client_side_array_id_(0), | |
| 445 client_side_element_array_id_(0), | |
| 446 bound_vertex_array_id_(0), | |
| 447 error_bits_(0), | 96 error_bits_(0), |
| 448 debug_(false), | 97 debug_(false), |
| 449 use_count_(0), | 98 use_count_(0), |
| 450 current_query_(NULL), | 99 current_query_(NULL), |
| 451 error_message_callback_(NULL) { | 100 error_message_callback_(NULL) { |
| 452 GPU_DCHECK(helper); | 101 GPU_DCHECK(helper); |
| 453 GPU_DCHECK(transfer_buffer); | 102 GPU_DCHECK(transfer_buffer); |
| 454 | 103 |
| 455 char temp[128]; | 104 char temp[128]; |
| 456 sprintf(temp, "%p", static_cast<void*>(this)); | 105 sprintf(temp, "%p", static_cast<void*>(this)); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 texture_units_.reset( | 165 texture_units_.reset( |
| 517 new TextureUnit[ | 166 new TextureUnit[ |
| 518 static_state_.int_state.max_combined_texture_image_units]); | 167 static_state_.int_state.max_combined_texture_image_units]); |
| 519 | 168 |
| 520 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 169 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 521 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | 170 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| 522 | 171 |
| 523 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 172 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 524 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 173 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| 525 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 174 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
| 175 #endif | |
| 526 | 176 |
| 527 client_side_buffer_helper_.reset(new ClientSideBufferHelper( | 177 vertex_array_object_manager_.reset(new VertexArrayObjectManager( |
| 528 static_state_.int_state.max_vertex_attribs, | 178 static_state_.int_state.max_vertex_attribs, |
| 529 reserved_ids_[0], | 179 reserved_ids_[0], |
| 530 reserved_ids_[1])); | 180 reserved_ids_[1])); |
| 531 #endif | |
| 532 | 181 |
| 533 return true; | 182 return true; |
| 534 } | 183 } |
| 535 | 184 |
| 536 GLES2Implementation::~GLES2Implementation() { | 185 GLES2Implementation::~GLES2Implementation() { |
| 537 // Make sure the queries are finished otherwise we'll delete the | 186 // Make sure the queries are finished otherwise we'll delete the |
| 538 // shared memory (mapped_memory_) which will free the memory used | 187 // shared memory (mapped_memory_) which will free the memory used |
| 539 // by the queries. The GPU process when validating that memory is still | 188 // by the queries. The GPU process when validating that memory is still |
| 540 // shared will fail and abort (ie, it will stop running). | 189 // shared will fail and abort (ie, it will stop running). |
| 541 Finish(); | 190 Finish(); |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 896 *params = static_state_.int_state.num_shader_binary_formats; | 545 *params = static_state_.int_state.num_shader_binary_formats; |
| 897 return true; | 546 return true; |
| 898 case GL_ARRAY_BUFFER_BINDING: | 547 case GL_ARRAY_BUFFER_BINDING: |
| 899 if (share_group_->bind_generates_resource()) { | 548 if (share_group_->bind_generates_resource()) { |
| 900 *params = bound_array_buffer_id_; | 549 *params = bound_array_buffer_id_; |
| 901 return true; | 550 return true; |
| 902 } | 551 } |
| 903 return false; | 552 return false; |
| 904 case GL_ELEMENT_ARRAY_BUFFER_BINDING: | 553 case GL_ELEMENT_ARRAY_BUFFER_BINDING: |
| 905 if (share_group_->bind_generates_resource()) { | 554 if (share_group_->bind_generates_resource()) { |
| 906 *params = bound_element_array_buffer_id_; | 555 *params = |
| 556 vertex_array_object_manager_->bound_element_array_buffer(); | |
| 907 return true; | 557 return true; |
| 908 } | 558 } |
| 909 return false; | 559 return false; |
| 910 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: | 560 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM: |
| 911 *params = bound_pixel_unpack_transfer_buffer_id_; | 561 *params = bound_pixel_unpack_transfer_buffer_id_; |
| 912 return true; | 562 return true; |
| 913 case GL_ACTIVE_TEXTURE: | 563 case GL_ACTIVE_TEXTURE: |
| 914 *params = active_texture_unit_ + GL_TEXTURE0; | 564 *params = active_texture_unit_ + GL_TEXTURE0; |
| 915 return true; | 565 return true; |
| 916 case GL_TEXTURE_BINDING_2D: | 566 case GL_TEXTURE_BINDING_2D: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM(" | 636 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetMaxValueInBufferCHROMIUM(" |
| 987 << buffer_id << ", " << count << ", " | 637 << buffer_id << ", " << count << ", " |
| 988 << GLES2Util::GetStringGetMaxIndexType(type) | 638 << GLES2Util::GetStringGetMaxIndexType(type) |
| 989 << ", " << offset << ")"); | 639 << ", " << offset << ")"); |
| 990 GLuint result = GetMaxValueInBufferCHROMIUMHelper( | 640 GLuint result = GetMaxValueInBufferCHROMIUMHelper( |
| 991 buffer_id, count, type, offset); | 641 buffer_id, count, type, offset); |
| 992 GPU_CLIENT_LOG("returned " << result); | 642 GPU_CLIENT_LOG("returned " << result); |
| 993 return result; | 643 return result; |
| 994 } | 644 } |
| 995 | 645 |
| 646 void GLES2Implementation::RestoreElementAndArrayBuffers(bool restore) { | |
| 647 if (restore) { | |
| 648 RestoreArrayBuffer(restore); | |
| 649 // Restore the element array binding. | |
| 650 // We only need to restore it if it wasn't a client side array. | |
| 651 if (vertex_array_object_manager_->bound_element_array_buffer() == 0) { | |
| 652 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 653 } | |
| 654 } | |
| 655 } | |
| 656 | |
| 657 void GLES2Implementation::RestoreArrayBuffer(bool restore) { | |
| 658 if (restore) { | |
| 659 // Restore the user's current binding. | |
| 660 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 661 } | |
| 662 } | |
| 663 | |
| 996 void GLES2Implementation::Clear(GLbitfield mask) { | 664 void GLES2Implementation::Clear(GLbitfield mask) { |
| 997 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 665 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 998 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")"); | 666 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClear(" << mask << ")"); |
| 999 helper_->Clear(mask); | 667 helper_->Clear(mask); |
| 1000 } | 668 } |
| 1001 | 669 |
| 1002 void GLES2Implementation::DrawElements( | 670 void GLES2Implementation::DrawElements( |
| 1003 GLenum mode, GLsizei count, GLenum type, const void* indices) { | 671 GLenum mode, GLsizei count, GLenum type, const void* indices) { |
| 1004 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 672 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1005 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" | 673 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElements(" |
| 1006 << GLES2Util::GetStringDrawMode(mode) << ", " | 674 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 1007 << count << ", " | 675 << count << ", " |
| 1008 << GLES2Util::GetStringIndexType(type) << ", " | 676 << GLES2Util::GetStringIndexType(type) << ", " |
| 1009 << static_cast<const void*>(indices) << ")"); | 677 << static_cast<const void*>(indices) << ")"); |
| 1010 if (count < 0) { | 678 if (count < 0) { |
| 1011 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); | 679 SetGLError(GL_INVALID_VALUE, "glDrawElements", "count less than 0."); |
| 1012 return; | 680 return; |
| 1013 } | 681 } |
| 1014 if (count == 0) { | 682 if (count == 0) { |
| 1015 return; | 683 return; |
| 1016 } | 684 } |
| 1017 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 685 GLuint offset = 0; |
| 1018 bool have_client_side = | 686 bool simulated = false; |
| 1019 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 687 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( |
| 1020 GLsizei num_elements = 0; | 688 "glDrawElements", this, helper_, count, type, 0, indices, |
| 1021 GLuint offset = ToGLuint(indices); | 689 &offset, &simulated)) { |
| 1022 bool success; | 690 return; |
| 1023 if (bound_element_array_buffer_id_ == 0) { | |
| 1024 // Index buffer is client side array. | |
| 1025 // Copy to buffer, scan for highest index. | |
| 1026 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer( | |
| 1027 this, helper_, count, type, indices, &num_elements); | |
| 1028 | |
| 1029 if(!success) { | |
| 1030 SetGLError(GL_INVALID_OPERATION, "glDrawElements", "index too large."); | |
| 1031 return; | |
| 1032 } | |
| 1033 | |
| 1034 offset = 0; | |
| 1035 } else { | |
| 1036 // Index buffer is GL buffer. Ask the service for the highest vertex | |
| 1037 // that will be accessed. Note: It doesn't matter if another context | |
| 1038 // changes the contents of any of the buffers. The service will still | |
| 1039 // validate the indices. We just need to know how much to copy across. | |
| 1040 if (have_client_side) { | |
| 1041 num_elements = GetMaxValueInBufferCHROMIUMHelper( | |
| 1042 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1; | |
| 1043 } | |
| 1044 } | |
| 1045 if (have_client_side) { | |
| 1046 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | |
| 1047 this, helper_, num_elements, 0); | |
| 1048 } | 691 } |
| 1049 helper_->DrawElements(mode, count, type, offset); | 692 helper_->DrawElements(mode, count, type, offset); |
| 1050 if (have_client_side) { | 693 RestoreElementAndArrayBuffers(simulated); |
| 1051 // Restore the user's current binding. | |
| 1052 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 1053 } | |
| 1054 if (bound_element_array_buffer_id_ == 0) { | |
| 1055 // Restore the element array binding. | |
| 1056 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 1057 } | |
| 1058 #else | |
| 1059 helper_->DrawElements(mode, count, type, ToGLuint(indices)); | |
| 1060 #endif | |
| 1061 } | 694 } |
| 1062 | 695 |
| 1063 void GLES2Implementation::Flush() { | 696 void GLES2Implementation::Flush() { |
| 1064 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 697 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1065 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); | 698 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFlush()"); |
| 1066 // Insert the cmd to call glFlush | 699 // Insert the cmd to call glFlush |
| 1067 helper_->Flush(); | 700 helper_->Flush(); |
| 1068 // Flush our command buffer | 701 // Flush our command buffer |
| 1069 // (tell the service to execute up to the flush cmd.) | 702 // (tell the service to execute up to the flush cmd.) |
| 1070 helper_->CommandBufferHelper::Flush(); | 703 helper_->CommandBufferHelper::Flush(); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1239 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) | 872 if (target != GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM) |
| 1240 helper_->BindBuffer(target, buffer); | 873 helper_->BindBuffer(target, buffer); |
| 1241 } | 874 } |
| 1242 | 875 |
| 1243 void GLES2Implementation::GetVertexAttribPointerv( | 876 void GLES2Implementation::GetVertexAttribPointerv( |
| 1244 GLuint index, GLenum pname, void** ptr) { | 877 GLuint index, GLenum pname, void** ptr) { |
| 1245 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 878 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1246 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" | 879 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribPointer(" |
| 1247 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", " | 880 << index << ", " << GLES2Util::GetStringVertexPointer(pname) << ", " |
| 1248 << static_cast<void*>(ptr) << ")"); | 881 << static_cast<void*>(ptr) << ")"); |
| 1249 | 882 if (!vertex_array_object_manager_->GetAttribPointer(index, pname, ptr)) { |
| 1250 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 883 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv"); |
| 1251 // If it's a client side buffer the client has the data. | 884 typedef gles2::GetVertexAttribPointerv::Result Result; |
| 1252 if (client_side_buffer_helper_->GetAttribPointer(index, pname, ptr)) { | 885 Result* result = GetResultAs<Result*>(); |
| 1253 return; | 886 if (!result) { |
| 887 return; | |
| 888 } | |
| 889 result->SetNumResults(0); | |
| 890 helper_->GetVertexAttribPointerv( | |
| 891 index, pname, GetResultShmId(), GetResultShmOffset()); | |
| 892 WaitForCmd(); | |
| 893 result->CopyResult(ptr); | |
| 1254 } | 894 } |
| 1255 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1256 | |
| 1257 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribPointerv"); | |
| 1258 typedef gles2::GetVertexAttribPointerv::Result Result; | |
| 1259 Result* result = GetResultAs<Result*>(); | |
| 1260 if (!result) { | |
| 1261 return; | |
| 1262 } | |
| 1263 result->SetNumResults(0); | |
| 1264 helper_->GetVertexAttribPointerv( | |
| 1265 index, pname, GetResultShmId(), GetResultShmOffset()); | |
| 1266 WaitForCmd(); | |
| 1267 result->CopyResult(ptr); | |
| 1268 GPU_CLIENT_LOG_CODE_BLOCK({ | 895 GPU_CLIENT_LOG_CODE_BLOCK({ |
| 1269 for (int32 i = 0; i < result->GetNumResults(); ++i) { | 896 for (int32 i = 0; i < 1; ++i) { |
|
bajones
2012/11/26 18:01:06
Is this a debugging change that should have been r
greggman
2012/11/28 08:18:57
Done.
| |
| 1270 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); | 897 GPU_CLIENT_LOG(" " << i << ": " << ptr[i]); |
| 1271 } | 898 } |
| 1272 }); | 899 }); |
| 1273 } | 900 } |
| 1274 | 901 |
| 1275 bool GLES2Implementation::DeleteProgramHelper(GLuint program) { | 902 bool GLES2Implementation::DeleteProgramHelper(GLuint program) { |
| 1276 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( | 903 if (!GetIdHandler(id_namespaces::kProgramsAndShaders)->FreeIds( |
| 1277 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { | 904 this, 1, &program, &GLES2Implementation::DeleteProgramStub)) { |
| 1278 SetGLError( | 905 SetGLError( |
| 1279 GL_INVALID_VALUE, | 906 GL_INVALID_VALUE, |
| 1280 "glDeleteProgram", "id not created by this context."); | 907 "glDeleteProgram", "id not created by this context."); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1462 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, | 1089 GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, |
| 1463 const void* ptr) { | 1090 const void* ptr) { |
| 1464 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1091 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1465 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" | 1092 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribPointer(" |
| 1466 << index << ", " | 1093 << index << ", " |
| 1467 << size << ", " | 1094 << size << ", " |
| 1468 << GLES2Util::GetStringVertexAttribType(type) << ", " | 1095 << GLES2Util::GetStringVertexAttribType(type) << ", " |
| 1469 << GLES2Util::GetStringBool(normalized) << ", " | 1096 << GLES2Util::GetStringBool(normalized) << ", " |
| 1470 << stride << ", " | 1097 << stride << ", " |
| 1471 << static_cast<const void*>(ptr) << ")"); | 1098 << static_cast<const void*>(ptr) << ")"); |
| 1099 // Record the info on the client side. | |
| 1100 if (!vertex_array_object_manager_->SetAttribPointer( | |
| 1101 bound_array_buffer_id_, index, size, type, normalized, stride, ptr)) { | |
| 1102 SetGLError(GL_INVALID_OPERATION, "glVertexAttribPointer", | |
| 1103 "client side arrays are not allowed in vertex array objects."); | |
| 1104 return; | |
| 1105 } | |
| 1472 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1106 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 1473 // Record the info on the client side. | |
| 1474 client_side_buffer_helper_->SetAttribPointer( | |
| 1475 bound_array_buffer_id_, index, size, type, normalized, stride, ptr); | |
| 1476 if (bound_array_buffer_id_ != 0) { | 1107 if (bound_array_buffer_id_ != 0) { |
| 1477 // Only report NON client side buffers to the service. | 1108 // Only report NON client side buffers to the service. |
| 1478 helper_->VertexAttribPointer(index, size, type, normalized, stride, | 1109 helper_->VertexAttribPointer(index, size, type, normalized, stride, |
| 1479 ToGLuint(ptr)); | 1110 ToGLuint(ptr)); |
| 1480 } | 1111 } |
| 1481 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1112 #else // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 1482 helper_->VertexAttribPointer(index, size, type, normalized, stride, | 1113 helper_->VertexAttribPointer(index, size, type, normalized, stride, |
| 1483 ToGLuint(ptr)); | 1114 ToGLuint(ptr)); |
| 1484 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 1115 #endif // !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 1485 } | 1116 } |
| 1486 | 1117 |
| 1487 void GLES2Implementation::VertexAttribDivisorANGLE( | 1118 void GLES2Implementation::VertexAttribDivisorANGLE( |
| 1488 GLuint index, GLuint divisor) { | 1119 GLuint index, GLuint divisor) { |
| 1489 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1120 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1490 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" | 1121 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" |
| 1491 << index << ", " | 1122 << index << ", " |
| 1492 << divisor << ") "); | 1123 << divisor << ") "); |
| 1493 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1494 // Record the info on the client side. | 1124 // Record the info on the client side. |
| 1495 client_side_buffer_helper_->SetAttribDivisor(index, divisor); | 1125 vertex_array_object_manager_->SetAttribDivisor(index, divisor); |
| 1496 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 1497 helper_->VertexAttribDivisorANGLE(index, divisor); | 1126 helper_->VertexAttribDivisorANGLE(index, divisor); |
| 1498 } | 1127 } |
| 1499 | 1128 |
| 1500 void GLES2Implementation::ShaderSource( | 1129 void GLES2Implementation::ShaderSource( |
| 1501 GLuint shader, GLsizei count, const char** source, const GLint* length) { | 1130 GLuint shader, GLsizei count, const char** source, const GLint* length) { |
| 1502 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1131 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1503 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" | 1132 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" |
| 1504 << shader << ", " << count << ", " | 1133 << shader << ", " << count << ", " |
| 1505 << static_cast<const void*>(source) << ", " | 1134 << static_cast<const void*>(source) << ", " |
| 1506 << static_cast<const void*>(length) << ")"); | 1135 << static_cast<const void*>(length) << ")"); |
| (...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2470 static_state_.int_state.max_combined_texture_image_units)) { | 2099 static_state_.int_state.max_combined_texture_image_units)) { |
| 2471 SetGLErrorInvalidEnum( | 2100 SetGLErrorInvalidEnum( |
| 2472 "glActiveTexture", texture, "texture"); | 2101 "glActiveTexture", texture, "texture"); |
| 2473 return; | 2102 return; |
| 2474 } | 2103 } |
| 2475 | 2104 |
| 2476 active_texture_unit_ = texture_index; | 2105 active_texture_unit_ = texture_index; |
| 2477 helper_->ActiveTexture(texture); | 2106 helper_->ActiveTexture(texture); |
| 2478 } | 2107 } |
| 2479 | 2108 |
| 2109 void GLES2Implementation::GenBuffersHelper( | |
| 2110 GLsizei /* n */, const GLuint* /* buffers */) { | |
| 2111 } | |
| 2112 | |
| 2113 void GLES2Implementation::GenFramebuffersHelper( | |
| 2114 GLsizei /* n */, const GLuint* /* framebuffers */) { | |
| 2115 } | |
| 2116 | |
| 2117 void GLES2Implementation::GenRenderbuffersHelper( | |
| 2118 GLsizei /* n */, const GLuint* /* renderbuffers */) { | |
| 2119 } | |
| 2120 | |
| 2121 void GLES2Implementation::GenTexturesHelper( | |
| 2122 GLsizei /* n */, const GLuint* /* textures */) { | |
| 2123 } | |
| 2124 | |
| 2125 void GLES2Implementation::GenVertexArraysOESHelper( | |
| 2126 GLsizei n, const GLuint* arrays) { | |
| 2127 vertex_array_object_manager_->GenVertexArrays(n, arrays); | |
| 2128 } | |
| 2129 | |
| 2130 void GLES2Implementation::GenQueriesEXTHelper( | |
| 2131 GLsizei /* n */, const GLuint* /* queries */) { | |
| 2132 } | |
| 2133 | |
| 2480 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id | 2134 // NOTE #1: On old versions of OpenGL, calling glBindXXX with an unused id |
| 2481 // generates a new resource. On newer versions of OpenGL they don't. The code | 2135 // generates a new resource. On newer versions of OpenGL they don't. The code |
| 2482 // related to binding below will need to change if we switch to the new OpenGL | 2136 // related to binding below will need to change if we switch to the new OpenGL |
| 2483 // model. Specifically it assumes a bind will succeed which is always true in | 2137 // model. Specifically it assumes a bind will succeed which is always true in |
| 2484 // the old model but possibly not true in the new model if another context has | 2138 // the old model but possibly not true in the new model if another context has |
| 2485 // deleted the resource. | 2139 // deleted the resource. |
| 2486 | 2140 |
| 2487 void GLES2Implementation::BindBufferHelper( | 2141 void GLES2Implementation::BindBufferHelper( |
| 2488 GLenum target, GLuint buffer) { | 2142 GLenum target, GLuint buffer) { |
| 2489 // TODO(gman): See note #1 above. | 2143 // TODO(gman): See note #1 above. |
| 2490 switch (target) { | 2144 switch (target) { |
| 2491 case GL_ARRAY_BUFFER: | 2145 case GL_ARRAY_BUFFER: |
| 2492 bound_array_buffer_id_ = buffer; | 2146 bound_array_buffer_id_ = buffer; |
| 2493 break; | 2147 break; |
| 2494 case GL_ELEMENT_ARRAY_BUFFER: | 2148 case GL_ELEMENT_ARRAY_BUFFER: |
| 2495 bound_element_array_buffer_id_ = buffer; | 2149 vertex_array_object_manager_->BindElementArray(buffer); |
| 2496 break; | 2150 break; |
| 2497 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: | 2151 case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
| 2498 bound_pixel_unpack_transfer_buffer_id_ = buffer; | 2152 bound_pixel_unpack_transfer_buffer_id_ = buffer; |
| 2499 break; | 2153 break; |
| 2500 default: | 2154 default: |
| 2501 break; | 2155 break; |
| 2502 } | 2156 } |
| 2503 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2157 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2504 // used even though it's marked it as used here. | 2158 // used even though it's marked it as used here. |
| 2505 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); | 2159 GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2548 default: | 2202 default: |
| 2549 break; | 2203 break; |
| 2550 } | 2204 } |
| 2551 // TODO(gman): There's a bug here. If the target is invalid the ID will not be | 2205 // TODO(gman): There's a bug here. If the target is invalid the ID will not be |
| 2552 // used. even though it's marked it as used here. | 2206 // used. even though it's marked it as used here. |
| 2553 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); | 2207 GetIdHandler(id_namespaces::kTextures)->MarkAsUsedForBind(texture); |
| 2554 } | 2208 } |
| 2555 | 2209 |
| 2556 void GLES2Implementation::BindVertexArrayHelper(GLuint array) { | 2210 void GLES2Implementation::BindVertexArrayHelper(GLuint array) { |
| 2557 // TODO(gman): See note #1 above. | 2211 // TODO(gman): See note #1 above. |
| 2558 bound_vertex_array_id_ = array; | 2212 bool changed = false; |
| 2559 | 2213 if (!vertex_array_object_manager_->BindVertexArray(array, &changed)) { |
| 2560 GetIdHandler(id_namespaces::kVertexArrays)->MarkAsUsedForBind(array); | 2214 SetGLError( |
| 2215 GL_INVALID_OPERATION, "glBindVertexArrayOES", | |
| 2216 "id was not generated with glGenVertexArrayOES"); | |
| 2217 } | |
| 2561 } | 2218 } |
| 2562 | 2219 |
| 2563 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2564 bool GLES2Implementation::IsBufferReservedId(GLuint id) { | 2220 bool GLES2Implementation::IsBufferReservedId(GLuint id) { |
| 2565 for (size_t ii = 0; ii < arraysize(reserved_ids_); ++ii) { | 2221 return vertex_array_object_manager_->IsReservedId(id); |
| 2566 if (id == reserved_ids_[ii]) { | |
| 2567 return true; | |
| 2568 } | |
| 2569 } | |
| 2570 return false; | |
| 2571 } | 2222 } |
| 2572 #else | |
| 2573 bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) { | |
| 2574 return false; | |
| 2575 } | |
| 2576 #endif | |
| 2577 | 2223 |
| 2578 void GLES2Implementation::DeleteBuffersHelper( | 2224 void GLES2Implementation::DeleteBuffersHelper( |
| 2579 GLsizei n, const GLuint* buffers) { | 2225 GLsizei n, const GLuint* buffers) { |
| 2580 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( | 2226 if (!GetIdHandler(id_namespaces::kBuffers)->FreeIds( |
| 2581 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { | 2227 this, n, buffers, &GLES2Implementation::DeleteBuffersStub)) { |
| 2582 SetGLError( | 2228 SetGLError( |
| 2583 GL_INVALID_VALUE, | 2229 GL_INVALID_VALUE, |
| 2584 "glDeleteBuffers", "id not created by this context."); | 2230 "glDeleteBuffers", "id not created by this context."); |
| 2585 return; | 2231 return; |
| 2586 } | 2232 } |
| 2587 for (GLsizei ii = 0; ii < n; ++ii) { | 2233 for (GLsizei ii = 0; ii < n; ++ii) { |
| 2588 if (buffers[ii] == bound_array_buffer_id_) { | 2234 if (buffers[ii] == bound_array_buffer_id_) { |
| 2589 bound_array_buffer_id_ = 0; | 2235 bound_array_buffer_id_ = 0; |
| 2590 } | 2236 } |
| 2591 if (buffers[ii] == bound_element_array_buffer_id_) { | 2237 vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
| 2592 bound_element_array_buffer_id_ = 0; | |
| 2593 } | |
| 2594 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | |
| 2595 bound_pixel_unpack_transfer_buffer_id_ = 0; | |
| 2596 } | |
| 2597 | |
| 2598 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); | 2238 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
| 2599 if (buffer) { | 2239 if (buffer) { |
| 2600 // Free buffer memory, pending the passage of a token. | 2240 // Free buffer memory, pending the passage of a token. |
| 2601 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); | 2241 buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
| 2602 // Remove buffer. | 2242 // Remove buffer. |
| 2603 buffer_tracker_->RemoveBuffer(buffers[ii]); | 2243 buffer_tracker_->RemoveBuffer(buffers[ii]); |
| 2604 } | 2244 } |
| 2245 if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { | |
| 2246 bound_pixel_unpack_transfer_buffer_id_ = 0; | |
| 2247 } | |
| 2605 } | 2248 } |
| 2606 } | 2249 } |
| 2607 | 2250 |
| 2608 void GLES2Implementation::DeleteBuffersStub( | 2251 void GLES2Implementation::DeleteBuffersStub( |
| 2609 GLsizei n, const GLuint* buffers) { | 2252 GLsizei n, const GLuint* buffers) { |
| 2610 helper_->DeleteBuffersImmediate(n, buffers); | 2253 helper_->DeleteBuffersImmediate(n, buffers); |
| 2611 } | 2254 } |
| 2612 | 2255 |
| 2613 | 2256 |
| 2614 void GLES2Implementation::DeleteFramebuffersHelper( | 2257 void GLES2Implementation::DeleteFramebuffersHelper( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2672 } | 2315 } |
| 2673 if (textures[ii] == unit.bound_texture_cube_map) { | 2316 if (textures[ii] == unit.bound_texture_cube_map) { |
| 2674 unit.bound_texture_cube_map = 0; | 2317 unit.bound_texture_cube_map = 0; |
| 2675 } | 2318 } |
| 2676 } | 2319 } |
| 2677 } | 2320 } |
| 2678 } | 2321 } |
| 2679 | 2322 |
| 2680 void GLES2Implementation::DeleteVertexArraysOESHelper( | 2323 void GLES2Implementation::DeleteVertexArraysOESHelper( |
| 2681 GLsizei n, const GLuint* arrays) { | 2324 GLsizei n, const GLuint* arrays) { |
| 2325 vertex_array_object_manager_->DeleteVertexArrays(n, arrays); | |
| 2682 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( | 2326 if (!GetIdHandler(id_namespaces::kVertexArrays)->FreeIds( |
| 2683 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { | 2327 this, n, arrays, &GLES2Implementation::DeleteVertexArraysOESStub)) { |
| 2684 SetGLError( | 2328 SetGLError( |
| 2685 GL_INVALID_VALUE, | 2329 GL_INVALID_VALUE, |
| 2686 "glDeleteVertexArraysOES", "id not created by this context."); | 2330 "glDeleteVertexArraysOES", "id not created by this context."); |
| 2687 return; | 2331 return; |
| 2688 } | 2332 } |
| 2689 for (GLsizei ii = 0; ii < n; ++ii) { | |
| 2690 if (arrays[ii] == bound_vertex_array_id_) { | |
| 2691 bound_vertex_array_id_ = 0; | |
| 2692 } | |
| 2693 } | |
| 2694 } | 2333 } |
| 2695 | 2334 |
| 2696 void GLES2Implementation::DeleteVertexArraysOESStub( | 2335 void GLES2Implementation::DeleteVertexArraysOESStub( |
| 2697 GLsizei n, const GLuint* arrays) { | 2336 GLsizei n, const GLuint* arrays) { |
| 2698 helper_->DeleteVertexArraysOESImmediate(n, arrays); | 2337 helper_->DeleteVertexArraysOESImmediate(n, arrays); |
| 2699 } | 2338 } |
| 2700 | 2339 |
| 2701 void GLES2Implementation::DeleteTexturesStub( | 2340 void GLES2Implementation::DeleteTexturesStub( |
| 2702 GLsizei n, const GLuint* textures) { | 2341 GLsizei n, const GLuint* textures) { |
| 2703 helper_->DeleteTexturesImmediate(n, textures); | 2342 helper_->DeleteTexturesImmediate(n, textures); |
| 2704 } | 2343 } |
| 2705 | 2344 |
| 2706 void GLES2Implementation::DisableVertexAttribArray(GLuint index) { | 2345 void GLES2Implementation::DisableVertexAttribArray(GLuint index) { |
| 2707 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2346 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2708 GPU_CLIENT_LOG( | 2347 GPU_CLIENT_LOG( |
| 2709 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")"); | 2348 "[" << GetLogPrefix() << "] glDisableVertexAttribArray(" << index << ")"); |
| 2710 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2349 vertex_array_object_manager_->SetAttribEnable(index, false); |
| 2711 client_side_buffer_helper_->SetAttribEnable(index, false); | |
| 2712 #endif | |
| 2713 helper_->DisableVertexAttribArray(index); | 2350 helper_->DisableVertexAttribArray(index); |
| 2714 } | 2351 } |
| 2715 | 2352 |
| 2716 void GLES2Implementation::EnableVertexAttribArray(GLuint index) { | 2353 void GLES2Implementation::EnableVertexAttribArray(GLuint index) { |
| 2717 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2354 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2718 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray(" | 2355 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glEnableVertexAttribArray(" |
| 2719 << index << ")"); | 2356 << index << ")"); |
| 2720 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2357 vertex_array_object_manager_->SetAttribEnable(index, true); |
| 2721 client_side_buffer_helper_->SetAttribEnable(index, true); | |
| 2722 #endif | |
| 2723 helper_->EnableVertexAttribArray(index); | 2358 helper_->EnableVertexAttribArray(index); |
| 2724 } | 2359 } |
| 2725 | 2360 |
| 2726 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { | 2361 void GLES2Implementation::DrawArrays(GLenum mode, GLint first, GLsizei count) { |
| 2727 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2362 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2728 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays(" | 2363 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawArrays(" |
| 2729 << GLES2Util::GetStringDrawMode(mode) << ", " | 2364 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 2730 << first << ", " << count << ")"); | 2365 << first << ", " << count << ")"); |
| 2731 if (count < 0) { | 2366 if (count < 0) { |
| 2732 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0"); | 2367 SetGLError(GL_INVALID_VALUE, "glDrawArrays", "count < 0"); |
| 2733 return; | 2368 return; |
| 2734 } | 2369 } |
| 2735 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2370 bool simulated = false; |
| 2736 bool have_client_side = | 2371 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers( |
| 2737 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 2372 "glDrawArrays", this, helper_, first + count, 0, &simulated)) { |
| 2738 if (have_client_side) { | 2373 return; |
| 2739 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | |
| 2740 this, helper_, first + count, 0); | |
| 2741 } | 2374 } |
| 2742 #endif | |
| 2743 helper_->DrawArrays(mode, first, count); | 2375 helper_->DrawArrays(mode, first, count); |
| 2744 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 2376 RestoreArrayBuffer(simulated); |
| 2745 if (have_client_side) { | |
| 2746 // Restore the user's current binding. | |
| 2747 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 2748 } | |
| 2749 #endif | |
| 2750 } | 2377 } |
| 2751 | 2378 |
| 2752 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2753 bool GLES2Implementation::GetVertexAttribHelper( | |
| 2754 GLuint index, GLenum pname, uint32* param) { | |
| 2755 const ClientSideBufferHelper::VertexAttribInfo* info = | |
| 2756 client_side_buffer_helper_->GetAttribInfo(index); | |
| 2757 if (!info) { | |
| 2758 return false; | |
| 2759 } | |
| 2760 | |
| 2761 switch (pname) { | |
| 2762 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: | |
| 2763 *param = info->buffer_id(); | |
| 2764 break; | |
| 2765 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: | |
| 2766 *param = info->enabled(); | |
| 2767 break; | |
| 2768 case GL_VERTEX_ATTRIB_ARRAY_SIZE: | |
| 2769 *param = info->size(); | |
| 2770 break; | |
| 2771 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: | |
| 2772 *param = info->stride(); | |
| 2773 break; | |
| 2774 case GL_VERTEX_ATTRIB_ARRAY_TYPE: | |
| 2775 *param = info->type(); | |
| 2776 break; | |
| 2777 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: | |
| 2778 *param = info->normalized(); | |
| 2779 break; | |
| 2780 case GL_CURRENT_VERTEX_ATTRIB: | |
| 2781 return false; // pass through to service side. | |
| 2782 default: | |
| 2783 SetGLErrorInvalidEnum("glGetVertexAttrib", pname, "pname"); | |
| 2784 break; | |
| 2785 } | |
| 2786 return true; | |
| 2787 } | |
| 2788 #endif // GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | |
| 2789 | |
| 2790 void GLES2Implementation::GetVertexAttribfv( | 2379 void GLES2Implementation::GetVertexAttribfv( |
| 2791 GLuint index, GLenum pname, GLfloat* params) { | 2380 GLuint index, GLenum pname, GLfloat* params) { |
| 2792 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2381 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2793 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" | 2382 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribfv(" |
| 2794 << index << ", " | 2383 << index << ", " |
| 2795 << GLES2Util::GetStringVertexAttribute(pname) << ", " | 2384 << GLES2Util::GetStringVertexAttribute(pname) << ", " |
| 2796 << static_cast<const void*>(params) << ")"); | 2385 << static_cast<const void*>(params) << ")"); |
| 2797 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2798 uint32 value = 0; | 2386 uint32 value = 0; |
| 2799 if (GetVertexAttribHelper(index, pname, &value)) { | 2387 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { |
| 2800 *params = static_cast<float>(value); | 2388 *params = static_cast<float>(value); |
| 2801 return; | 2389 return; |
| 2802 } | 2390 } |
| 2803 #endif | |
| 2804 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); | 2391 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv"); |
| 2805 typedef GetVertexAttribfv::Result Result; | 2392 typedef GetVertexAttribfv::Result Result; |
| 2806 Result* result = GetResultAs<Result*>(); | 2393 Result* result = GetResultAs<Result*>(); |
| 2807 if (!result) { | 2394 if (!result) { |
| 2808 return; | 2395 return; |
| 2809 } | 2396 } |
| 2810 result->SetNumResults(0); | 2397 result->SetNumResults(0); |
| 2811 helper_->GetVertexAttribfv( | 2398 helper_->GetVertexAttribfv( |
| 2812 index, pname, GetResultShmId(), GetResultShmOffset()); | 2399 index, pname, GetResultShmId(), GetResultShmOffset()); |
| 2813 WaitForCmd(); | 2400 WaitForCmd(); |
| 2814 result->CopyResult(params); | 2401 result->CopyResult(params); |
| 2815 GPU_CLIENT_LOG_CODE_BLOCK({ | 2402 GPU_CLIENT_LOG_CODE_BLOCK({ |
| 2816 for (int32 i = 0; i < result->GetNumResults(); ++i) { | 2403 for (int32 i = 0; i < result->GetNumResults(); ++i) { |
| 2817 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); | 2404 GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]); |
| 2818 } | 2405 } |
| 2819 }); | 2406 }); |
| 2820 } | 2407 } |
| 2821 | 2408 |
| 2822 void GLES2Implementation::GetVertexAttribiv( | 2409 void GLES2Implementation::GetVertexAttribiv( |
| 2823 GLuint index, GLenum pname, GLint* params) { | 2410 GLuint index, GLenum pname, GLint* params) { |
| 2824 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 2411 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 2825 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" | 2412 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetVertexAttribiv(" |
| 2826 << index << ", " | 2413 << index << ", " |
| 2827 << GLES2Util::GetStringVertexAttribute(pname) << ", " | 2414 << GLES2Util::GetStringVertexAttribute(pname) << ", " |
| 2828 << static_cast<const void*>(params) << ")"); | 2415 << static_cast<const void*>(params) << ")"); |
| 2829 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | |
| 2830 uint32 value = 0; | 2416 uint32 value = 0; |
| 2831 if (GetVertexAttribHelper(index, pname, &value)) { | 2417 if (vertex_array_object_manager_->GetVertexAttrib(index, pname, &value)) { |
| 2832 *params = value; | 2418 *params = value; |
| 2833 return; | 2419 return; |
| 2834 } | 2420 } |
| 2835 #endif | |
| 2836 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); | 2421 TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv"); |
| 2837 typedef GetVertexAttribiv::Result Result; | 2422 typedef GetVertexAttribiv::Result Result; |
| 2838 Result* result = GetResultAs<Result*>(); | 2423 Result* result = GetResultAs<Result*>(); |
| 2839 if (!result) { | 2424 if (!result) { |
| 2840 return; | 2425 return; |
| 2841 } | 2426 } |
| 2842 result->SetNumResults(0); | 2427 result->SetNumResults(0); |
| 2843 helper_->GetVertexAttribiv( | 2428 helper_->GetVertexAttribiv( |
| 2844 index, pname, GetResultShmId(), GetResultShmOffset()); | 2429 index, pname, GetResultShmId(), GetResultShmOffset()); |
| 2845 WaitForCmd(); | 2430 WaitForCmd(); |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3407 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0"); | 2992 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "count < 0"); |
| 3408 return; | 2993 return; |
| 3409 } | 2994 } |
| 3410 if (primcount < 0) { | 2995 if (primcount < 0) { |
| 3411 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0"); | 2996 SetGLError(GL_INVALID_VALUE, "glDrawArraysInstancedANGLE", "primcount < 0"); |
| 3412 return; | 2997 return; |
| 3413 } | 2998 } |
| 3414 if (primcount == 0) { | 2999 if (primcount == 0) { |
| 3415 return; | 3000 return; |
| 3416 } | 3001 } |
| 3417 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 3002 bool simulated = false; |
| 3418 bool have_client_side = | 3003 if (!vertex_array_object_manager_->SetupSimulatedClientSideBuffers( |
| 3419 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 3004 "glDrawArraysInstancedANGLE", this, helper_, first + count, primcount, |
| 3420 if (have_client_side) { | 3005 &simulated)) { |
| 3421 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | 3006 return; |
| 3422 this, helper_, first + count, primcount); | |
| 3423 } | 3007 } |
| 3424 #endif | |
| 3425 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount); | 3008 helper_->DrawArraysInstancedANGLE(mode, first, count, primcount); |
| 3426 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 3009 RestoreArrayBuffer(simulated); |
| 3427 if (have_client_side) { | |
| 3428 // Restore the user's current binding. | |
| 3429 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 3430 } | |
| 3431 #endif | |
| 3432 } | 3010 } |
| 3433 | 3011 |
| 3434 void GLES2Implementation::DrawElementsInstancedANGLE( | 3012 void GLES2Implementation::DrawElementsInstancedANGLE( |
| 3435 GLenum mode, GLsizei count, GLenum type, const void* indices, | 3013 GLenum mode, GLsizei count, GLenum type, const void* indices, |
| 3436 GLsizei primcount) { | 3014 GLsizei primcount) { |
| 3437 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3015 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3438 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE(" | 3016 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawElementsInstancedANGLE(" |
| 3439 << GLES2Util::GetStringDrawMode(mode) << ", " | 3017 << GLES2Util::GetStringDrawMode(mode) << ", " |
| 3440 << count << ", " | 3018 << count << ", " |
| 3441 << GLES2Util::GetStringIndexType(type) << ", " | 3019 << GLES2Util::GetStringIndexType(type) << ", " |
| 3442 << static_cast<const void*>(indices) << ", " | 3020 << static_cast<const void*>(indices) << ", " |
| 3443 << primcount << ")"); | 3021 << primcount << ")"); |
| 3444 if (count < 0) { | 3022 if (count < 0) { |
| 3445 SetGLError(GL_INVALID_VALUE, | 3023 SetGLError(GL_INVALID_VALUE, |
| 3446 "glDrawElementsInstancedANGLE", "count less than 0."); | 3024 "glDrawElementsInstancedANGLE", "count less than 0."); |
| 3447 return; | 3025 return; |
| 3448 } | 3026 } |
| 3449 if (count == 0) { | 3027 if (count == 0) { |
| 3450 return; | 3028 return; |
| 3451 } | 3029 } |
| 3452 if (primcount < 0) { | 3030 if (primcount < 0) { |
| 3453 SetGLError(GL_INVALID_VALUE, | 3031 SetGLError(GL_INVALID_VALUE, |
| 3454 "glDrawElementsInstancedANGLE", "primcount < 0"); | 3032 "glDrawElementsInstancedANGLE", "primcount < 0"); |
| 3455 return; | 3033 return; |
| 3456 } | 3034 } |
| 3457 if (primcount == 0) { | 3035 if (primcount == 0) { |
| 3458 return; | 3036 return; |
| 3459 } | 3037 } |
| 3460 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 3038 GLuint offset = 0; |
| 3461 bool have_client_side = | 3039 bool simulated = false; |
| 3462 client_side_buffer_helper_->HaveEnabledClientSideBuffers(); | 3040 if (!vertex_array_object_manager_->SetupSimulatedIndexAndClientSideBuffers( |
| 3463 GLsizei num_elements = 0; | 3041 "glDrawElementsInstancedANGLE", this, helper_, count, type, primcount, |
| 3464 GLuint offset = ToGLuint(indices); | 3042 indices, &offset, &simulated)) { |
| 3465 bool success; | 3043 return; |
| 3466 if (bound_element_array_buffer_id_ == 0) { | |
| 3467 // Index buffer is client side array. | |
| 3468 // Copy to buffer, scan for highest index. | |
| 3469 success = client_side_buffer_helper_->SetupSimulatedIndexBuffer( | |
| 3470 this, helper_, count, type, indices, &num_elements); | |
| 3471 | |
| 3472 if(!success) { | |
| 3473 SetGLError(GL_INVALID_OPERATION, "glDrawElementsInstancedANGLE", | |
| 3474 "index too large."); | |
| 3475 return; | |
| 3476 } | |
| 3477 | |
| 3478 offset = 0; | |
| 3479 } else { | |
| 3480 // Index buffer is GL buffer. Ask the service for the highest vertex | |
| 3481 // that will be accessed. Note: It doesn't matter if another context | |
| 3482 // changes the contents of any of the buffers. The service will still | |
| 3483 // validate the indices. We just need to know how much to copy across. | |
| 3484 if (have_client_side) { | |
| 3485 num_elements = GetMaxValueInBufferCHROMIUMHelper( | |
| 3486 bound_element_array_buffer_id_, count, type, ToGLuint(indices)) + 1; | |
| 3487 } | |
| 3488 } | |
| 3489 if (have_client_side) { | |
| 3490 client_side_buffer_helper_->SetupSimulatedClientSideBuffers( | |
| 3491 this, helper_, num_elements, primcount); | |
| 3492 } | 3044 } |
| 3493 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount); | 3045 helper_->DrawElementsInstancedANGLE(mode, count, type, offset, primcount); |
| 3494 if (have_client_side) { | 3046 RestoreElementAndArrayBuffers(simulated); |
| 3495 // Restore the user's current binding. | |
| 3496 helper_->BindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_id_); | |
| 3497 } | |
| 3498 if (bound_element_array_buffer_id_ == 0) { | |
| 3499 // Restore the element array binding. | |
| 3500 helper_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
| 3501 } | |
| 3502 #else | |
| 3503 helper_->DrawElementsInstancedANGLE( | |
| 3504 mode, count, type, ToGLuint(indices), primcount); | |
| 3505 #endif | |
| 3506 } | 3047 } |
| 3507 | 3048 |
| 3508 void GLES2Implementation::GenMailboxCHROMIUM( | 3049 void GLES2Implementation::GenMailboxCHROMIUM( |
| 3509 GLbyte* mailbox) { | 3050 GLbyte* mailbox) { |
| 3510 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3051 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3511 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM(" | 3052 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenMailboxCHROMIUM(" |
| 3512 << static_cast<const void*>(mailbox) << ")"); | 3053 << static_cast<const void*>(mailbox) << ")"); |
| 3513 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); | 3054 TRACE_EVENT0("gpu", "GLES2::GenMailboxCHROMIUM"); |
| 3514 | 3055 |
| 3515 helper_->GenMailboxCHROMIUM(kResultBucketId); | 3056 helper_->GenMailboxCHROMIUM(kResultBucketId); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3624 return true; | 3165 return true; |
| 3625 } | 3166 } |
| 3626 | 3167 |
| 3627 // Include the auto-generated part of this file. We split this because it means | 3168 // Include the auto-generated part of this file. We split this because it means |
| 3628 // we can easily edit the non-auto generated parts right here in this file | 3169 // we can easily edit the non-auto generated parts right here in this file |
| 3629 // instead of having to edit some template or the code generator. | 3170 // instead of having to edit some template or the code generator. |
| 3630 #include "../client/gles2_implementation_impl_autogen.h" | 3171 #include "../client/gles2_implementation_impl_autogen.h" |
| 3631 | 3172 |
| 3632 } // namespace gles2 | 3173 } // namespace gles2 |
| 3633 } // namespace gpu | 3174 } // namespace gpu |
| OLD | NEW |