OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 #include <string> | 10 #include <string> |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ | 93 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ |
94 | 94 |
95 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 95 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
96 | 96 |
97 #undef GLES2_CMD_OP | 97 #undef GLES2_CMD_OP |
98 }; | 98 }; |
99 | 99 |
100 namespace GLErrorBit { | 100 namespace GLErrorBit { |
101 enum GLErrorBit { | 101 enum GLErrorBit { |
102 kNoError = 0, | 102 kNoError = 0, |
103 kInvalidEnum, | 103 kInvalidEnum = (1 << 0), |
104 kInvalidValue, | 104 kInvalidValue = (1 << 1), |
105 kInvalidOperation, | 105 kInvalidOperation = (1 << 2), |
106 kOutOfMemory, | 106 kOutOfMemory = (1 << 3), |
107 kInvalidFrameBufferOperation, | 107 kInvalidFrameBufferOperation = (1 << 4), |
108 }; | 108 }; |
109 } | 109 } |
110 | 110 |
111 uint32 GLErrorToErrorBit(GLenum error) { | 111 uint32 GLErrorToErrorBit(GLenum error) { |
112 switch (error) { | 112 switch (error) { |
113 case GL_INVALID_ENUM: | 113 case GL_INVALID_ENUM: |
114 return GLErrorBit::kInvalidEnum; | 114 return GLErrorBit::kInvalidEnum; |
115 case GL_INVALID_VALUE: | 115 case GL_INVALID_VALUE: |
116 return GLErrorBit::kInvalidValue; | 116 return GLErrorBit::kInvalidValue; |
117 case GL_INVALID_OPERATION: | 117 case GL_INVALID_OPERATION: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 GLES2Decoder::GLES2Decoder() | 157 GLES2Decoder::GLES2Decoder() |
158 : debug_(false), | 158 : debug_(false), |
159 hwnd_(NULL) { | 159 hwnd_(NULL) { |
160 #else | 160 #else |
161 GLES2Decoder::GLES2Decoder() | 161 GLES2Decoder::GLES2Decoder() |
162 : debug_(false) { | 162 : debug_(false) { |
163 #endif | 163 #endif |
164 } | 164 } |
165 | 165 |
166 // This class maps one set of ids to another. | 166 // This class maps one set of ids to another. |
167 class IdMap { | 167 // |
| 168 // NOTE: To support shared resources an instance of this class will |
| 169 // need to be shared by multiple GLES2Decoders. |
| 170 class IdManager { |
168 public: | 171 public: |
169 // Maps a client_id to a service_id. Return false if the client_id or | 172 // Maps a client_id to a service_id. Return false if the client_id or |
170 // service_id are already mapped to something else. | 173 // service_id are already mapped to something else. |
171 bool AddMapping(GLuint client_id, GLuint service_id); | 174 bool AddMapping(GLuint client_id, GLuint service_id); |
172 | 175 |
173 // Unmaps a pair of ids. Returns false if the pair were not previously mapped. | 176 // Unmaps a pair of ids. Returns false if the pair were not previously mapped. |
174 bool RemoveMapping(GLuint client_id, GLuint service_id); | 177 bool RemoveMapping(GLuint client_id, GLuint service_id); |
175 | 178 |
176 // Gets the corresponding service_id for the given client_id. | 179 // Gets the corresponding service_id for the given client_id. |
177 // Returns false if there is no corresponding service_id. | 180 // Returns false if there is no corresponding service_id. |
178 bool GetServiceId(GLuint client_id, GLuint* service_id); | 181 bool GetServiceId(GLuint client_id, GLuint* service_id); |
179 | 182 |
180 // Gets the corresponding client_id for the given service_id. | 183 // Gets the corresponding client_id for the given service_id. |
181 // Returns false if there is no corresponding client_id. | 184 // Returns false if there is no corresponding client_id. |
182 bool GetClientId(GLuint service_id, GLuint* client_id); | 185 bool GetClientId(GLuint service_id, GLuint* client_id); |
183 | 186 |
184 private: | 187 private: |
185 // TODO(gman): Replace with faster implementation. | 188 // TODO(gman): Replace with faster implementation. |
186 typedef std::map<GLuint, GLuint> MapType; | 189 typedef std::map<GLuint, GLuint> MapType; |
187 MapType id_map_; | 190 MapType id_map_; |
188 }; | 191 }; |
189 | 192 |
190 bool IdMap::AddMapping(GLuint client_id, GLuint service_id) { | 193 bool IdManager::AddMapping(GLuint client_id, GLuint service_id) { |
191 std::pair<MapType::iterator, bool> result = id_map_.insert( | 194 std::pair<MapType::iterator, bool> result = id_map_.insert( |
192 std::make_pair(client_id, service_id)); | 195 std::make_pair(client_id, service_id)); |
193 return result.second; | 196 return result.second; |
194 } | 197 } |
195 | 198 |
196 bool IdMap::RemoveMapping(GLuint client_id, GLuint service_id) { | 199 bool IdManager::RemoveMapping(GLuint client_id, GLuint service_id) { |
197 MapType::iterator iter = id_map_.find(client_id); | 200 MapType::iterator iter = id_map_.find(client_id); |
198 if (iter != id_map_.end() && iter->second == service_id) { | 201 if (iter != id_map_.end() && iter->second == service_id) { |
199 id_map_.erase(iter); | 202 id_map_.erase(iter); |
200 return true; | 203 return true; |
201 } | 204 } |
202 return false; | 205 return false; |
203 } | 206 } |
204 | 207 |
205 bool IdMap::GetServiceId(GLuint client_id, GLuint* service_id) { | 208 bool IdManager::GetServiceId(GLuint client_id, GLuint* service_id) { |
206 DCHECK(service_id); | 209 DCHECK(service_id); |
207 MapType::iterator iter = id_map_.find(client_id); | 210 MapType::iterator iter = id_map_.find(client_id); |
208 if (iter != id_map_.end()) { | 211 if (iter != id_map_.end()) { |
209 *service_id = iter->second; | 212 *service_id = iter->second; |
210 return true; | 213 return true; |
211 } | 214 } |
212 return false; | 215 return false; |
213 } | 216 } |
214 | 217 |
215 bool IdMap::GetClientId(GLuint service_id, GLuint* client_id) { | 218 bool IdManager::GetClientId(GLuint service_id, GLuint* client_id) { |
216 DCHECK(client_id); | 219 DCHECK(client_id); |
217 MapType::iterator end(id_map_.end()); | 220 MapType::iterator end(id_map_.end()); |
218 for (MapType::iterator iter(id_map_.begin()); | 221 for (MapType::iterator iter(id_map_.begin()); |
219 iter != end; | 222 iter != end; |
220 ++iter) { | 223 ++iter) { |
221 if (iter->second == service_id) { | 224 if (iter->second == service_id) { |
222 *client_id = iter->first; | 225 *client_id = iter->first; |
223 return true; | 226 return true; |
224 } | 227 } |
225 } | 228 } |
226 return false; | 229 return false; |
227 } | 230 } |
228 | 231 |
| 232 // This class keeps track of the buffers and their sizes so we can do |
| 233 // bounds checking. |
| 234 // |
| 235 // NOTE: To support shared resources an instance of this class will need to be |
| 236 // shared by multiple GLES2Decoders. |
| 237 class BufferManager { |
| 238 public: |
| 239 // Info about Buffers currently in the system. |
| 240 class BufferInfo { |
| 241 public: |
| 242 BufferInfo() |
| 243 : size_(0) { |
| 244 } |
| 245 |
| 246 explicit BufferInfo(GLsizeiptr size) |
| 247 : size_(size) { |
| 248 } |
| 249 |
| 250 GLsizeiptr size() const { |
| 251 return size_; |
| 252 } |
| 253 |
| 254 // Returns the maximum value in the buffer for the given range |
| 255 // interpreted as the given type. |
| 256 GLuint GetMaxValueForRange(GLuint offset, GLsizei count, GLenum type); |
| 257 |
| 258 private: |
| 259 GLsizeiptr size_; |
| 260 }; |
| 261 |
| 262 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used |
| 263 // on glDeleteBuffers so we can make sure the user does not try to render |
| 264 // with deleted buffers. |
| 265 void RemoveBufferInfo(GLuint buffer_id); |
| 266 |
| 267 // Gets the buffer info for the given buffer. |
| 268 BufferInfo* GetBufferInfo(GLuint buffer); |
| 269 |
| 270 // Sets the info for a buffer. |
| 271 void SetBufferInfo(GLuint buffer, GLsizeiptr size); |
| 272 |
| 273 private: |
| 274 // Info for each buffer in the system. |
| 275 // TODO(gman): Choose a faster container. |
| 276 typedef std::map<GLuint, BufferInfo> BufferInfoMap; |
| 277 BufferInfoMap buffer_infos_; |
| 278 }; |
| 279 |
| 280 BufferManager::BufferInfo* BufferManager::GetBufferInfo( |
| 281 GLuint buffer) { |
| 282 BufferInfoMap::iterator it = buffer_infos_.find(buffer); |
| 283 return it != buffer_infos_.end() ? &it->second : NULL; |
| 284 } |
| 285 |
| 286 void BufferManager::SetBufferInfo(GLuint buffer, GLsizeiptr size) { |
| 287 buffer_infos_[buffer] = BufferInfo(size); |
| 288 } |
| 289 |
| 290 void BufferManager::RemoveBufferInfo(GLuint buffer_id) { |
| 291 buffer_infos_.erase(buffer_id); |
| 292 } |
| 293 |
| 294 GLuint BufferManager::BufferInfo::GetMaxValueForRange( |
| 295 GLuint offset, GLsizei count, GLenum type) { |
| 296 // TODO(gman): Scan the values in the given range and cache their results. |
| 297 return 0u; |
| 298 } |
| 299 |
| 300 // Tracks the Programs. |
| 301 // |
| 302 // NOTE: To support shared resources an instance of this class will |
| 303 // need to be shared by multiple GLES2Decoders. |
| 304 class ProgramManager { |
| 305 public: |
| 306 // This is used to track which attributes a particular program needs |
| 307 // so we can verify at glDrawXXX time that every attribute is either disabled |
| 308 // or if enabled that it points to a valid source. |
| 309 class ProgramInfo { |
| 310 public: |
| 311 typedef std::vector<GLuint> AttribLocationVector; |
| 312 |
| 313 ProgramInfo() { |
| 314 } |
| 315 |
| 316 void SetNumAttributes(int num_attribs) { |
| 317 attrib_locations_.resize(num_attribs); |
| 318 } |
| 319 |
| 320 void SetAttributeLocation(GLuint index, int location) { |
| 321 DCHECK(index < attrib_locations_.size()); |
| 322 attrib_locations_[index] = location; |
| 323 } |
| 324 |
| 325 const AttribLocationVector& GetAttribLocations() const { |
| 326 return attrib_locations_; |
| 327 } |
| 328 private: |
| 329 AttribLocationVector attrib_locations_; |
| 330 }; |
| 331 |
| 332 ProgramInfo* GetProgramInfo(GLuint program); |
| 333 |
| 334 // Updates the program info for the given program. |
| 335 void UpdateProgramInfo(GLuint program); |
| 336 |
| 337 // Deletes the program info for the given program. |
| 338 void RemoveProgramInfo(GLuint program); |
| 339 |
| 340 private: |
| 341 // Info for each "successfully linked" program by service side program Id. |
| 342 // TODO(gman): Choose a faster container. |
| 343 typedef std::map<GLuint, ProgramInfo> ProgramInfoMap; |
| 344 ProgramInfoMap program_infos_; |
| 345 }; |
| 346 |
| 347 ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint program) { |
| 348 ProgramInfoMap::iterator it = program_infos_.find(program); |
| 349 return it != program_infos_.end() ? &it->second : NULL; |
| 350 } |
| 351 |
| 352 void ProgramManager::UpdateProgramInfo(GLuint program) { |
| 353 ProgramInfo* info = GetProgramInfo(program); |
| 354 if (!info) { |
| 355 std::pair<ProgramInfoMap::iterator, bool> result = |
| 356 program_infos_.insert(std::make_pair(program, ProgramInfo())); |
| 357 DCHECK(result.second); |
| 358 info = &result.first->second; |
| 359 } |
| 360 GLint num_attribs = 0; |
| 361 GLint max_len = 0; |
| 362 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs); |
| 363 info->SetNumAttributes(num_attribs); |
| 364 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); |
| 365 // TODO(gman): Should we check for error? |
| 366 scoped_array<char> name_buffer(new char[max_len + 1]); |
| 367 for (GLint ii = 0; ii < num_attribs; ++ii) { |
| 368 GLsizei length; |
| 369 GLsizei size; |
| 370 GLenum type; |
| 371 glGetActiveAttrib( |
| 372 program, ii, max_len + 1, &length, &size, &type, name_buffer.get()); |
| 373 // TODO(gman): Should we check for error? |
| 374 GLint location = glGetAttribLocation(program, name_buffer.get()); |
| 375 info->SetAttributeLocation(ii, location); |
| 376 } |
| 377 } |
| 378 |
| 379 void ProgramManager::RemoveProgramInfo(GLuint program) { |
| 380 ProgramInfoMap::iterator it = program_infos_.find(program); |
| 381 if (it != program_infos_.end()) { |
| 382 program_infos_.erase(it); |
| 383 } |
| 384 } |
| 385 |
229 // This class implements GLES2Decoder so we don't have to expose all the GLES2 | 386 // This class implements GLES2Decoder so we don't have to expose all the GLES2 |
230 // cmd stuff to outside this class. | 387 // cmd stuff to outside this class. |
231 class GLES2DecoderImpl : public GLES2Decoder { | 388 class GLES2DecoderImpl : public GLES2Decoder { |
232 public: | 389 public: |
233 // Info about Vertex Attributes. This is used to track what the user currently | 390 // Info about Vertex Attributes. This is used to track what the user currently |
234 // has bound on each Vertex Attribute so that checking can be done at | 391 // has bound on each Vertex Attribute so that checking can be done at |
235 // glDrawXXX time. | 392 // glDrawXXX time. |
236 class VertexAttribInfo { | 393 class VertexAttribInfo { |
237 public: | 394 public: |
238 VertexAttribInfo() | 395 VertexAttribInfo() |
(...skipping 20 matching lines...) Expand all Loading... |
259 void Clear() { | 416 void Clear() { |
260 buffer_ = 0; | 417 buffer_ = 0; |
261 SetBufferSize(0); | 418 SetBufferSize(0); |
262 } | 419 } |
263 | 420 |
264 void SetBufferSize(GLsizeiptr buffer_size) { | 421 void SetBufferSize(GLsizeiptr buffer_size) { |
265 buffer_size_ = buffer_size; | 422 buffer_size_ = buffer_size; |
266 if (offset_ > buffer_size || real_stride_ == 0) { | 423 if (offset_ > buffer_size || real_stride_ == 0) { |
267 num_elements_ = 0; | 424 num_elements_ = 0; |
268 } else { | 425 } else { |
269 uint32 size = buffer_size - offset_; | 426 uint32 usable_size = buffer_size - offset_; |
270 num_elements_ = size / real_stride_ + | 427 num_elements_ = usable_size / real_stride_ + |
271 (size % real_stride_ >= GetGLTypeSize(type_) ? 1 : 0); | 428 ((usable_size % real_stride_) >= |
| 429 (GetGLTypeSize(type_) * size_) ? 1 : 0); |
272 } | 430 } |
273 } | 431 } |
274 | 432 |
275 void SetInfo( | 433 void SetInfo( |
276 GLuint buffer, | 434 GLuint buffer, |
277 GLsizeiptr buffer_size, | 435 GLsizeiptr buffer_size, |
278 GLint size, | 436 GLint size, |
279 GLenum type, | 437 GLenum type, |
280 GLsizei real_stride, | 438 GLsizei real_stride, |
281 GLsizei offset) { | 439 GLsizei offset) { |
(...skipping 27 matching lines...) Expand all Loading... |
309 // The service side name of the buffer bound to this attribute. 0 = invalid | 467 // The service side name of the buffer bound to this attribute. 0 = invalid |
310 GLuint buffer_; | 468 GLuint buffer_; |
311 | 469 |
312 // The size of the buffer. | 470 // The size of the buffer. |
313 GLsizeiptr buffer_size_; | 471 GLsizeiptr buffer_size_; |
314 | 472 |
315 // The number of elements that can be accessed. | 473 // The number of elements that can be accessed. |
316 GLuint num_elements_; | 474 GLuint num_elements_; |
317 }; | 475 }; |
318 | 476 |
319 // Info about Buffers currently in the system. | |
320 struct BufferInfo { | |
321 BufferInfo() | |
322 : size(0) { | |
323 } | |
324 | |
325 explicit BufferInfo(GLsizeiptr _size) | |
326 : size(_size) { | |
327 } | |
328 | |
329 GLsizeiptr size; | |
330 }; | |
331 | |
332 // This is used to track which attributes a particular program needs | |
333 // so we can verify at glDrawXXX time that every attribute is either disabled | |
334 // or if enabled that it points to a valid source. | |
335 class ProgramInfo { | |
336 public: | |
337 typedef std::vector<GLuint> AttribLocationVector; | |
338 | |
339 ProgramInfo() { | |
340 } | |
341 | |
342 void SetNumAttributes(int num_attribs) { | |
343 attrib_locations_.resize(num_attribs); | |
344 } | |
345 | |
346 void SetAttributeLocation(GLuint index, int location) { | |
347 DCHECK(index < attrib_locations_.size()); | |
348 attrib_locations_[index] = location; | |
349 } | |
350 | |
351 const AttribLocationVector& GetAttribLocations() const { | |
352 return attrib_locations_; | |
353 } | |
354 private: | |
355 AttribLocationVector attrib_locations_; | |
356 }; | |
357 | |
358 GLES2DecoderImpl(); | 477 GLES2DecoderImpl(); |
359 | 478 |
360 // Overridden from AsyncAPIInterface. | 479 // Overridden from AsyncAPIInterface. |
361 virtual ParseError DoCommand(unsigned int command, | 480 virtual ParseError DoCommand(unsigned int command, |
362 unsigned int arg_count, | 481 unsigned int arg_count, |
363 const void* args); | 482 const void* args); |
364 | 483 |
365 // Overridden from AsyncAPIInterface. | 484 // Overridden from AsyncAPIInterface. |
366 virtual const char* GetCommandName(unsigned int command_id) const; | 485 virtual const char* GetCommandName(unsigned int command_id) const; |
367 | 486 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 bool RegisterObjects( | 533 bool RegisterObjects( |
415 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); | 534 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); |
416 | 535 |
417 // Unregisters client ids with service ids. | 536 // Unregisters client ids with service ids. |
418 void UnregisterObjects( | 537 void UnregisterObjects( |
419 GLsizei n, const GLuint* client_ids, GLuint* service_ids); | 538 GLsizei n, const GLuint* client_ids, GLuint* service_ids); |
420 | 539 |
421 // Gets the program info for the given program. Returns NULL if none exists. | 540 // Gets the program info for the given program. Returns NULL if none exists. |
422 // Programs that have no had glLinkProgram succesfully called on them will | 541 // Programs that have no had glLinkProgram succesfully called on them will |
423 // not exist. | 542 // not exist. |
424 ProgramInfo* GetProgramInfo(GLuint program); | 543 ProgramManager::ProgramInfo* GetProgramInfo(GLuint program) { |
| 544 return program_manager_->GetProgramInfo(program); |
| 545 } |
425 | 546 |
426 // Updates the program info for the given program. | 547 // Updates the program info for the given program. |
427 void UpdateProgramInfo(GLuint program); | 548 void UpdateProgramInfo(GLuint program) { |
| 549 program_manager_->UpdateProgramInfo(program); |
| 550 } |
428 | 551 |
429 // Deletes the program info for the given program. | 552 // Deletes the program info for the given program. |
430 void RemoveProgramInfo(GLuint program); | 553 void RemoveProgramInfo(GLuint program) { |
| 554 program_manager_->RemoveProgramInfo(program); |
| 555 } |
431 | 556 |
432 // Gets the buffer info for the given buffer. | 557 // Gets the buffer info for the given buffer. |
433 const BufferInfo* GetBufferInfo(GLuint buffer); | 558 BufferManager::BufferInfo* GetBufferInfo(GLuint buffer) { |
| 559 return buffer_manager_->GetBufferInfo(buffer); |
| 560 } |
434 | 561 |
435 // Sets the info for a buffer. | 562 // Sets the info for a buffer. |
436 void SetBufferInfo(GLuint buffer, GLsizeiptr size); | 563 void SetBufferInfo(GLuint buffer, GLsizeiptr size); |
437 | 564 |
438 // Wrapper for glCreateProgram | 565 // Wrapper for glCreateProgram |
439 void CreateProgramHelper(GLuint client_id); | 566 void CreateProgramHelper(GLuint client_id); |
440 | 567 |
441 // Wrapper for glCreateShader | 568 // Wrapper for glCreateShader |
442 void CreateShaderHelper(GLenum type, GLuint client_id); | 569 void CreateShaderHelper(GLenum type, GLuint client_id); |
443 | 570 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 const gles2::name& args); \ | 619 const gles2::name& args); \ |
493 | 620 |
494 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 621 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
495 | 622 |
496 #undef GLES2_CMD_OP | 623 #undef GLES2_CMD_OP |
497 | 624 |
498 // Current GL error bits. | 625 // Current GL error bits. |
499 uint32 error_bits_; | 626 uint32 error_bits_; |
500 | 627 |
501 // Map of client ids to GL ids. | 628 // Map of client ids to GL ids. |
502 IdMap id_map_; | 629 scoped_ptr<IdManager> id_manager_; |
503 | 630 |
504 // Util to help with GL. | 631 // Util to help with GL. |
505 GLES2Util util_; | 632 GLES2Util util_; |
506 | 633 |
507 // pack alignment as last set by glPixelStorei | 634 // pack alignment as last set by glPixelStorei |
508 GLint pack_alignment_; | 635 GLint pack_alignment_; |
509 | 636 |
510 // unpack alignment as last set by glPixelStorei | 637 // unpack alignment as last set by glPixelStorei |
511 GLint unpack_alignment_; | 638 GLint unpack_alignment_; |
512 | 639 |
513 // The currently bound array buffer. If this is 0 it is illegal to call | 640 // The currently bound array buffer. If this is 0 it is illegal to call |
514 // glVertexAttribPointer. | 641 // glVertexAttribPointer. |
515 GLuint bound_array_buffer_; | 642 GLuint bound_array_buffer_; |
516 | 643 |
517 // The currently bound element array buffer. If this is 0 it is illegal | 644 // The currently bound element array buffer. If this is 0 it is illegal |
518 // to call glDrawElements. | 645 // to call glDrawElements. |
519 GLuint bound_element_array_buffer_; | 646 GLuint bound_element_array_buffer_; |
520 | 647 |
521 // The maximum vertex attributes. | 648 // The maximum vertex attributes. |
522 GLuint max_vertex_attribs_; | 649 GLuint max_vertex_attribs_; |
523 | 650 |
524 // Info for each vertex attribute saved so we can check at glDrawXXX time | 651 // Info for each vertex attribute saved so we can check at glDrawXXX time |
525 // if it is safe to draw. | 652 // if it is safe to draw. |
526 scoped_array<VertexAttribInfo> vertex_attrib_infos_; | 653 scoped_array<VertexAttribInfo> vertex_attrib_infos_; |
527 | 654 |
528 // Info for each buffer in the system. | 655 scoped_ptr<BufferManager> buffer_manager_; |
529 // TODO(gman): Choose a faster container. | |
530 typedef std::map<GLuint, BufferInfo> BufferInfoMap; | |
531 BufferInfoMap buffer_infos_; | |
532 | 656 |
533 // Info for each "successfully linked" program by service side program Id. | 657 scoped_ptr<ProgramManager> program_manager_; |
534 // TODO(gman): Choose a faster container. | |
535 typedef std::map<GLuint, ProgramInfo> ProgramInfoMap; | |
536 ProgramInfoMap program_infos_; | |
537 | 658 |
538 // The program in current use through glUseProgram. | 659 // The program in use by glUseProgram |
539 ProgramInfo* current_program_info_; | 660 GLuint current_program_; |
540 | 661 |
541 #if defined(UNIT_TEST) | 662 #if defined(UNIT_TEST) |
542 #elif defined(OS_WIN) | 663 #elif defined(OS_WIN) |
543 HDC device_context_; | 664 HDC device_context_; |
544 HGLRC gl_context_; | 665 HGLRC gl_context_; |
545 #endif | 666 #endif |
546 | 667 |
547 bool anti_aliased_; | 668 bool anti_aliased_; |
548 | 669 |
549 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 670 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
550 }; | 671 }; |
551 | 672 |
552 GLES2Decoder* GLES2Decoder::Create() { | 673 GLES2Decoder* GLES2Decoder::Create() { |
553 return new GLES2DecoderImpl(); | 674 return new GLES2DecoderImpl(); |
554 } | 675 } |
555 | 676 |
556 GLES2DecoderImpl::GLES2DecoderImpl() | 677 GLES2DecoderImpl::GLES2DecoderImpl() |
557 : GLES2Decoder(), | 678 : GLES2Decoder(), |
558 error_bits_(0), | 679 error_bits_(0), |
559 util_(0), // TODO(gman): Set to actual num compress texture formats. | 680 util_(0), // TODO(gman): Set to actual num compress texture formats. |
560 pack_alignment_(4), | 681 pack_alignment_(4), |
561 unpack_alignment_(4), | 682 unpack_alignment_(4), |
562 bound_array_buffer_(0), | 683 bound_array_buffer_(0), |
563 bound_element_array_buffer_(0), | 684 bound_element_array_buffer_(0), |
564 max_vertex_attribs_(0), | 685 max_vertex_attribs_(0), |
565 current_program_info_(NULL), | 686 current_program_(0), |
566 #if defined(UNIT_TEST) | 687 #if defined(UNIT_TEST) |
567 #elif defined(OS_WIN) | 688 #elif defined(OS_WIN) |
568 device_context_(NULL), | 689 device_context_(NULL), |
569 gl_context_(NULL), | 690 gl_context_(NULL), |
570 #endif | 691 #endif |
571 anti_aliased_(false) { | 692 anti_aliased_(false) { |
572 } | 693 } |
573 | 694 |
574 bool GLES2DecoderImpl::Initialize() { | 695 bool GLES2DecoderImpl::Initialize() { |
| 696 id_manager_.reset(new IdManager()); |
| 697 buffer_manager_.reset(new BufferManager()); |
| 698 program_manager_.reset(new ProgramManager()); |
| 699 |
575 if (!InitPlatformSpecific()) | 700 if (!InitPlatformSpecific()) |
576 return false; | 701 return false; |
577 if (!InitGlew()) | 702 if (!InitGlew()) |
578 return false; | 703 return false; |
579 CHECK_GL_ERROR(); | 704 CHECK_GL_ERROR(); |
580 | 705 |
581 // Lookup GL things we need to know. | 706 // Lookup GL things we need to know. |
582 GLint value; | 707 GLint value; |
583 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); | 708 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); |
584 max_vertex_attribs_ = value; | 709 max_vertex_attribs_ = value; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 void GLDeleteTexturesHelper( | 933 void GLDeleteTexturesHelper( |
809 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { | 934 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { |
810 glDeleteTextures(n, ids); | 935 glDeleteTextures(n, ids); |
811 } | 936 } |
812 | 937 |
813 } // anonymous namespace | 938 } // anonymous namespace |
814 | 939 |
815 uint32 GLES2DecoderImpl::GetServiceIdForTesting(uint32 client_id) { | 940 uint32 GLES2DecoderImpl::GetServiceIdForTesting(uint32 client_id) { |
816 #if defined(UNIT_TEST) | 941 #if defined(UNIT_TEST) |
817 GLuint service_id; | 942 GLuint service_id; |
818 bool result = id_map_.GetServiceId(client_id, &service_id); | 943 bool result = id_manager_->GetServiceId(client_id, &service_id); |
819 return result ? service_id : 0u; | 944 return result ? service_id : 0u; |
820 #else | 945 #else |
821 DCHECK(false); | 946 DCHECK(false); |
822 return 0u; | 947 return 0u; |
823 #endif | 948 #endif |
824 } | 949 } |
825 | 950 |
826 bool GLES2DecoderImpl::ValidateIdsAreUnused( | 951 bool GLES2DecoderImpl::ValidateIdsAreUnused( |
827 GLsizei n, const GLuint* client_ids) { | 952 GLsizei n, const GLuint* client_ids) { |
828 for (GLsizei ii = 0; ii < n; ++ii) { | 953 for (GLsizei ii = 0; ii < n; ++ii) { |
829 GLuint service_id; | 954 GLuint service_id; |
830 if (id_map_.GetServiceId(client_ids[ii], &service_id)) { | 955 if (id_manager_->GetServiceId(client_ids[ii], &service_id)) { |
831 return false; | 956 return false; |
832 } | 957 } |
833 } | 958 } |
834 return true; | 959 return true; |
835 } | 960 } |
836 | 961 |
837 bool GLES2DecoderImpl::RegisterObjects( | 962 bool GLES2DecoderImpl::RegisterObjects( |
838 GLsizei n, const GLuint* client_ids, const GLuint* service_ids) { | 963 GLsizei n, const GLuint* client_ids, const GLuint* service_ids) { |
839 for (GLsizei ii = 0; ii < n; ++ii) { | 964 for (GLsizei ii = 0; ii < n; ++ii) { |
840 if (!id_map_.AddMapping(client_ids[ii], service_ids[ii])) { | 965 if (!id_manager_->AddMapping(client_ids[ii], service_ids[ii])) { |
841 NOTREACHED(); | 966 NOTREACHED(); |
842 return false; | 967 return false; |
843 } | 968 } |
844 } | 969 } |
845 return true; | 970 return true; |
846 } | 971 } |
847 | 972 |
848 void GLES2DecoderImpl::UnregisterObjects( | 973 void GLES2DecoderImpl::UnregisterObjects( |
849 GLsizei n, const GLuint* client_ids, GLuint* service_ids) { | 974 GLsizei n, const GLuint* client_ids, GLuint* service_ids) { |
850 for (GLsizei ii = 0; ii < n; ++ii) { | 975 for (GLsizei ii = 0; ii < n; ++ii) { |
851 if (id_map_.GetServiceId(client_ids[ii], &service_ids[ii])) { | 976 if (id_manager_->GetServiceId(client_ids[ii], &service_ids[ii])) { |
852 id_map_.RemoveMapping(client_ids[ii], service_ids[ii]); | 977 id_manager_->RemoveMapping(client_ids[ii], service_ids[ii]); |
853 } else { | 978 } else { |
854 service_ids[ii] = 0; | 979 service_ids[ii] = 0; |
855 } | 980 } |
856 } | 981 } |
857 } | 982 } |
858 | 983 |
859 void GLES2DecoderImpl::RemoveBufferInfo(GLuint buffer_id) { | |
860 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { | |
861 if (vertex_attrib_infos_[ii].buffer() == buffer_id) { | |
862 vertex_attrib_infos_[ii].Clear(); | |
863 } | |
864 } | |
865 buffer_infos_.erase(buffer_id); | |
866 } | |
867 | |
868 bool GLES2DecoderImpl::InitPlatformSpecific() { | 984 bool GLES2DecoderImpl::InitPlatformSpecific() { |
869 #if defined(UNIT_TEST) | 985 #if defined(UNIT_TEST) |
870 #elif defined(OS_WIN) | 986 #elif defined(OS_WIN) |
871 device_context_ = ::GetDC(hwnd()); | 987 device_context_ = ::GetDC(hwnd()); |
872 | 988 |
873 int pixel_format; | 989 int pixel_format; |
874 | 990 |
875 if (!GetWindowsPixelFormat(hwnd(), | 991 if (!GetWindowsPixelFormat(hwnd(), |
876 anti_aliased_, | 992 anti_aliased_, |
877 &pixel_format)) { | 993 &pixel_format)) { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1023 } else { | 1139 } else { |
1024 result = DoCommonCommand(command, arg_count, cmd_data); | 1140 result = DoCommonCommand(command, arg_count, cmd_data); |
1025 } | 1141 } |
1026 return result; | 1142 return result; |
1027 } | 1143 } |
1028 | 1144 |
1029 void GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { | 1145 void GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { |
1030 // TODO(gman): verify client_id is unused. | 1146 // TODO(gman): verify client_id is unused. |
1031 GLuint service_id = glCreateProgram(); | 1147 GLuint service_id = glCreateProgram(); |
1032 if (service_id) { | 1148 if (service_id) { |
1033 id_map_.AddMapping(client_id, service_id); | 1149 id_manager_->AddMapping(client_id, service_id); |
1034 } | 1150 } |
1035 } | 1151 } |
1036 | 1152 |
1037 void GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { | 1153 void GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { |
1038 // TODO(gman): verify client_id is unused. | 1154 // TODO(gman): verify client_id is unused. |
1039 GLuint service_id = glCreateShader(type); | 1155 GLuint service_id = glCreateShader(type); |
1040 if (service_id) { | 1156 if (service_id) { |
1041 id_map_.AddMapping(client_id, service_id); | 1157 id_manager_->AddMapping(client_id, service_id); |
1042 } | 1158 } |
1043 } | 1159 } |
1044 | 1160 |
1045 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint buffer) { | 1161 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint buffer) { |
1046 switch (target) { | 1162 switch (target) { |
1047 case GL_ARRAY_BUFFER: | 1163 case GL_ARRAY_BUFFER: |
1048 bound_array_buffer_ = buffer; | 1164 bound_array_buffer_ = buffer; |
1049 break; | 1165 break; |
1050 case GL_ELEMENT_ARRAY_BUFFER: | 1166 case GL_ELEMENT_ARRAY_BUFFER: |
1051 bound_element_array_buffer_ = buffer; | 1167 bound_element_array_buffer_ = buffer; |
(...skipping 20 matching lines...) Expand all Loading... |
1072 glEnableVertexAttribArray(index); | 1188 glEnableVertexAttribArray(index); |
1073 } else { | 1189 } else { |
1074 SetGLError(GL_INVALID_VALUE); | 1190 SetGLError(GL_INVALID_VALUE); |
1075 } | 1191 } |
1076 } | 1192 } |
1077 | 1193 |
1078 parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( | 1194 parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( |
1079 uint32 immediate_data_size, const gles2::DeleteShader& c) { | 1195 uint32 immediate_data_size, const gles2::DeleteShader& c) { |
1080 GLuint shader = c.shader; | 1196 GLuint shader = c.shader; |
1081 GLuint service_id; | 1197 GLuint service_id; |
1082 if (!id_map_.GetServiceId(shader, &service_id)) { | 1198 if (!id_manager_->GetServiceId(shader, &service_id)) { |
1083 SetGLError(GL_INVALID_VALUE); | 1199 SetGLError(GL_INVALID_VALUE); |
1084 return parse_error::kParseNoError; | 1200 return parse_error::kParseNoError; |
1085 } | 1201 } |
1086 glDeleteShader(service_id); | 1202 glDeleteShader(service_id); |
1087 id_map_.RemoveMapping(shader, service_id); | 1203 id_manager_->RemoveMapping(shader, service_id); |
1088 return parse_error::kParseNoError; | 1204 return parse_error::kParseNoError; |
1089 } | 1205 } |
1090 | 1206 |
1091 parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram( | 1207 parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram( |
1092 uint32 immediate_data_size, const gles2::DeleteProgram& c) { | 1208 uint32 immediate_data_size, const gles2::DeleteProgram& c) { |
1093 GLuint program = c.program; | 1209 GLuint program = c.program; |
1094 GLuint service_id; | 1210 GLuint service_id; |
1095 if (!id_map_.GetServiceId(program, &service_id)) { | 1211 if (!id_manager_->GetServiceId(program, &service_id)) { |
1096 SetGLError(GL_INVALID_VALUE); | 1212 SetGLError(GL_INVALID_VALUE); |
1097 return parse_error::kParseNoError; | 1213 return parse_error::kParseNoError; |
1098 } | 1214 } |
1099 RemoveProgramInfo(program); | 1215 RemoveProgramInfo(service_id); |
1100 glDeleteProgram(service_id); | 1216 glDeleteProgram(service_id); |
1101 id_map_.RemoveMapping(program, service_id); | 1217 id_manager_->RemoveMapping(program, service_id); |
1102 return parse_error::kParseNoError; | 1218 return parse_error::kParseNoError; |
1103 } | 1219 } |
1104 | 1220 |
1105 void GLES2DecoderImpl::DoDrawArrays( | 1221 void GLES2DecoderImpl::DoDrawArrays( |
1106 GLenum mode, GLint first, GLsizei count) { | 1222 GLenum mode, GLint first, GLsizei count) { |
1107 if (IsDrawValid(first + count - 1)) { | 1223 if (IsDrawValid(first + count - 1)) { |
1108 glDrawArrays(mode, first, count); | 1224 glDrawArrays(mode, first, count); |
1109 } | 1225 } |
1110 } | 1226 } |
1111 | 1227 |
(...skipping 15 matching lines...) Expand all Loading... |
1127 #if defined(UNIT_TEST) | 1243 #if defined(UNIT_TEST) |
1128 #elif defined(OS_WIN) | 1244 #elif defined(OS_WIN) |
1129 ::SwapBuffers(device_context_); | 1245 ::SwapBuffers(device_context_); |
1130 #elif defined(OS_LINUX) | 1246 #elif defined(OS_LINUX) |
1131 DCHECK(window()); | 1247 DCHECK(window()); |
1132 window()->SwapBuffers(); | 1248 window()->SwapBuffers(); |
1133 #endif | 1249 #endif |
1134 } | 1250 } |
1135 | 1251 |
1136 void GLES2DecoderImpl::DoUseProgram(GLuint program) { | 1252 void GLES2DecoderImpl::DoUseProgram(GLuint program) { |
1137 ProgramInfo* info = GetProgramInfo(program); | 1253 ProgramManager::ProgramInfo* info = GetProgramInfo(program); |
1138 if (!info) { | 1254 if (!info) { |
1139 // Program was not linked successfully. (ie, glLinkProgram) | 1255 // Program was not linked successfully. (ie, glLinkProgram) |
1140 SetGLError(GL_INVALID_OPERATION); | 1256 SetGLError(GL_INVALID_OPERATION); |
1141 } else { | 1257 } else { |
1142 current_program_info_ = info; | 1258 current_program_ = program; |
1143 glUseProgram(program); | 1259 glUseProgram(program); |
1144 } | 1260 } |
1145 } | 1261 } |
1146 | 1262 |
1147 GLenum GLES2DecoderImpl::GetGLError() { | 1263 GLenum GLES2DecoderImpl::GetGLError() { |
1148 // Check the GL error first, then our wrapped error. | 1264 // Check the GL error first, then our wrapped error. |
1149 GLenum error = glGetError(); | 1265 GLenum error = glGetError(); |
1150 if (error == GL_NO_ERROR && error_bits_ != 0) { | 1266 if (error == GL_NO_ERROR && error_bits_ != 0) { |
1151 for (uint32 mask = 1; mask != 0; mask = mask << 1) { | 1267 for (uint32 mask = 1; mask != 0; mask = mask << 1) { |
1152 if ((error_bits_ & mask) != 0) { | 1268 if ((error_bits_ & mask) != 0) { |
(...skipping 14 matching lines...) Expand all Loading... |
1167 error_bits_ |= GLErrorToErrorBit(error); | 1283 error_bits_ |= GLErrorToErrorBit(error); |
1168 } | 1284 } |
1169 | 1285 |
1170 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { | 1286 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { |
1171 GLenum error; | 1287 GLenum error; |
1172 while ((error = glGetError()) != GL_NO_ERROR) { | 1288 while ((error = glGetError()) != GL_NO_ERROR) { |
1173 SetGLError(error); | 1289 SetGLError(error); |
1174 } | 1290 } |
1175 } | 1291 } |
1176 | 1292 |
1177 const GLES2DecoderImpl::BufferInfo* GLES2DecoderImpl::GetBufferInfo( | |
1178 GLuint buffer) { | |
1179 BufferInfoMap::iterator it = buffer_infos_.find(buffer); | |
1180 return it != buffer_infos_.end() ? &it->second : NULL; | |
1181 } | |
1182 | |
1183 void GLES2DecoderImpl::SetBufferInfo(GLuint buffer, GLsizeiptr size) { | 1293 void GLES2DecoderImpl::SetBufferInfo(GLuint buffer, GLsizeiptr size) { |
1184 buffer_infos_[buffer] = BufferInfo(size); | 1294 buffer_manager_->SetBufferInfo(buffer, size); |
1185 | 1295 |
1186 // Also go through VertexAttribInfo and update any info that references | 1296 // Also go through VertexAttribInfo and update any info that references |
1187 // the same buffer. | 1297 // the same buffer. |
| 1298 // TODO(gman): This code needs to change for shared resources. |
1188 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { | 1299 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { |
1189 if (vertex_attrib_infos_[ii].buffer() == buffer) { | 1300 if (vertex_attrib_infos_[ii].buffer() == buffer) { |
1190 vertex_attrib_infos_[ii].SetBufferSize(size); | 1301 vertex_attrib_infos_[ii].SetBufferSize(size); |
1191 } | 1302 } |
1192 } | 1303 } |
1193 } | 1304 } |
1194 | 1305 |
1195 GLES2DecoderImpl::ProgramInfo* GLES2DecoderImpl::GetProgramInfo( | 1306 void GLES2DecoderImpl::RemoveBufferInfo(GLuint buffer_id) { |
1196 GLuint program) { | 1307 // TODO(gman): This code needs to change for shared resources. |
1197 ProgramInfoMap::iterator it = program_infos_.find(program); | 1308 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { |
1198 return it != program_infos_.end() ? &it->second : NULL; | 1309 if (vertex_attrib_infos_[ii].buffer() == buffer_id) { |
1199 } | 1310 vertex_attrib_infos_[ii].Clear(); |
1200 | 1311 } |
1201 void GLES2DecoderImpl::UpdateProgramInfo(GLuint program) { | |
1202 ProgramInfo* info = GetProgramInfo(program); | |
1203 if (!info) { | |
1204 std::pair<ProgramInfoMap::iterator, bool> result = | |
1205 program_infos_.insert(std::make_pair(program, ProgramInfo())); | |
1206 DCHECK(result.second); | |
1207 info = &result.first->second; | |
1208 } | 1312 } |
1209 GLint num_attribs = 0; | 1313 buffer_manager_->RemoveBufferInfo(buffer_id); |
1210 GLint max_len = 0; | |
1211 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs); | |
1212 info->SetNumAttributes(num_attribs); | |
1213 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); | |
1214 // TODO(gman): Should we check for error? | |
1215 scoped_array<char> name_buffer(new char[max_len + 1]); | |
1216 for (GLint ii = 0; ii < num_attribs; ++ii) { | |
1217 GLsizei length; | |
1218 GLsizei size; | |
1219 GLenum type; | |
1220 glGetActiveAttrib( | |
1221 program, ii, max_len + 1, &length, &size, &type, name_buffer.get()); | |
1222 // TODO(gman): Should we check for error? | |
1223 GLint location = glGetAttribLocation(program, name_buffer.get()); | |
1224 info->SetAttributeLocation(ii, location); | |
1225 } | |
1226 } | |
1227 | |
1228 void GLES2DecoderImpl::RemoveProgramInfo(GLuint program) { | |
1229 ProgramInfoMap::iterator it = program_infos_.find(program); | |
1230 if (it != program_infos_.end()) { | |
1231 if (current_program_info_ == &it->second) { | |
1232 current_program_info_ = NULL; | |
1233 } | |
1234 program_infos_.erase(it); | |
1235 } | |
1236 } | 1314 } |
1237 | 1315 |
1238 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) { | 1316 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) { |
1239 return !enabled_ || (buffer_ != 0 && index < num_elements_); | 1317 return !enabled_ || (buffer_ != 0 && index < num_elements_); |
1240 } | 1318 } |
1241 | 1319 |
1242 bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) { | 1320 bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) { |
1243 if (current_program_info_) { | 1321 if (current_program_) { |
| 1322 ProgramManager::ProgramInfo* info = GetProgramInfo(current_program_); |
| 1323 if (!info) { |
| 1324 // The program does not exist. |
| 1325 SetGLError(GL_INVALID_OPERATION); |
| 1326 return false; |
| 1327 } |
1244 // Validate that all attribs current program needs are setup correctly. | 1328 // Validate that all attribs current program needs are setup correctly. |
1245 const ProgramInfo::AttribLocationVector& locations = | 1329 const ProgramManager::ProgramInfo::AttribLocationVector& locations = |
1246 current_program_info_->GetAttribLocations(); | 1330 info->GetAttribLocations(); |
1247 for (size_t ii = 0; ii < locations.size(); ++ii) { | 1331 for (size_t ii = 0; ii < locations.size(); ++ii) { |
1248 GLuint location = locations[ii]; | 1332 GLuint location = locations[ii]; |
1249 DCHECK_LT(location, max_vertex_attribs_); | 1333 DCHECK_LT(location, max_vertex_attribs_); |
1250 if (!vertex_attrib_infos_[location].CanAccess(max_vertex_accessed)) { | 1334 if (!vertex_attrib_infos_[location].CanAccess(max_vertex_accessed)) { |
1251 SetGLError(GL_INVALID_OPERATION); | 1335 SetGLError(GL_INVALID_OPERATION); |
| 1336 return false; |
1252 } | 1337 } |
1253 } | 1338 } |
1254 return true; | 1339 return true; |
1255 } | 1340 } |
1256 // We do not set a GL error here because the GL spec says no error if the | 1341 // We do not set a GL error here because the GL spec says no error if the |
1257 // program is invalid. | 1342 // program is invalid. |
1258 return false; | 1343 return false; |
1259 }; | 1344 }; |
1260 | 1345 |
1261 parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( | 1346 parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( |
1262 uint32 immediate_data_size, const gles2::DrawElements& c) { | 1347 uint32 immediate_data_size, const gles2::DrawElements& c) { |
1263 if (bound_element_array_buffer_ != 0) { | 1348 if (bound_element_array_buffer_ != 0) { |
1264 GLenum mode = c.mode; | 1349 GLenum mode = c.mode; |
1265 GLsizei count = c.count; | 1350 GLsizei count = c.count; |
1266 GLenum type = c.type; | 1351 GLenum type = c.type; |
| 1352 int32 offset = c.index_offset; |
1267 if (!ValidateGLenumDrawMode(mode) || | 1353 if (!ValidateGLenumDrawMode(mode) || |
1268 !ValidateGLenumIndexType(type)) { | 1354 !ValidateGLenumIndexType(type)) { |
1269 SetGLError(GL_INVALID_VALUE); | 1355 SetGLError(GL_INVALID_ENUM); |
1270 } else { | 1356 } else { |
1271 const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset); | 1357 // TODO(gman): We could cache this lookup in glBindBuffer. |
1272 // TODO(gman): Validate indices. Get maximum index. | 1358 BufferManager::BufferInfo* info = |
1273 // | 1359 GetBufferInfo(bound_element_array_buffer_); |
1274 // This value should be computed by walking the index buffer from 0 to | 1360 if (!info) { |
1275 // count and finding the maximum vertex accessed. | 1361 SetGLError(GL_INVALID_OPERATION); |
1276 // For now we'll special case 0 to not check. | 1362 } else { |
1277 GLuint max_vertex_accessed = 0; | 1363 GLsizeiptr buffer_size = info->size(); |
1278 if (IsDrawValid(max_vertex_accessed)) { | 1364 if (offset > buffer_size) { |
1279 glDrawElements(mode, count, type, indices); | 1365 SetGLError(GL_INVALID_OPERATION); |
| 1366 } else { |
| 1367 GLsizei usable_size = buffer_size - offset; |
| 1368 GLsizei num_elements = usable_size / GetGLTypeSize(type); |
| 1369 if (count > num_elements) { |
| 1370 SetGLError(GL_INVALID_OPERATION); |
| 1371 } else { |
| 1372 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
| 1373 // TODO(gman): Validate indices. Get maximum index. |
| 1374 // |
| 1375 // This value should be computed by walking the index buffer from 0 |
| 1376 // to count and finding the maximum vertex accessed. For now we'll |
| 1377 // pass 0 so it should always pass. |
| 1378 GLuint max_vertex_accessed = info->GetMaxValueForRange( |
| 1379 offset, count, type); |
| 1380 if (IsDrawValid(max_vertex_accessed)) { |
| 1381 glDrawElements(mode, count, type, indices); |
| 1382 } |
| 1383 } |
| 1384 } |
1280 } | 1385 } |
1281 } | 1386 } |
1282 } else { | 1387 } else { |
1283 SetGLError(GL_INVALID_VALUE); | 1388 SetGLError(GL_INVALID_VALUE); |
1284 } | 1389 } |
1285 return parse_error::kParseNoError; | 1390 return parse_error::kParseNoError; |
1286 } | 1391 } |
1287 | 1392 |
1288 namespace { | 1393 namespace { |
1289 | 1394 |
(...skipping 22 matching lines...) Expand all Loading... |
1312 | 1417 |
1313 glShaderSource(shader, count, string_pointers.get(), NULL); | 1418 glShaderSource(shader, count, string_pointers.get(), NULL); |
1314 return parse_error::kParseNoError; | 1419 return parse_error::kParseNoError; |
1315 } | 1420 } |
1316 | 1421 |
1317 } // anonymous namespace. | 1422 } // anonymous namespace. |
1318 | 1423 |
1319 parse_error::ParseError GLES2DecoderImpl::HandleShaderSource( | 1424 parse_error::ParseError GLES2DecoderImpl::HandleShaderSource( |
1320 uint32 immediate_data_size, const gles2::ShaderSource& c) { | 1425 uint32 immediate_data_size, const gles2::ShaderSource& c) { |
1321 GLuint shader; | 1426 GLuint shader; |
1322 if (!id_map_.GetServiceId(c.shader, &shader)) { | 1427 if (!id_manager_->GetServiceId(c.shader, &shader)) { |
1323 SetGLError(GL_INVALID_VALUE); | 1428 SetGLError(GL_INVALID_VALUE); |
1324 return parse_error::kParseNoError; | 1429 return parse_error::kParseNoError; |
1325 } | 1430 } |
1326 GLsizei count = c.count; | 1431 GLsizei count = c.count; |
1327 uint32 data_size = c.data_size; | 1432 uint32 data_size = c.data_size; |
1328 const char** data = GetSharedMemoryAs<const char**>( | 1433 const char** data = GetSharedMemoryAs<const char**>( |
1329 c.data_shm_id, c.data_shm_offset, data_size); | 1434 c.data_shm_id, c.data_shm_offset, data_size); |
1330 if (!data) { | 1435 if (!data) { |
1331 return parse_error::kParseOutOfBounds; | 1436 return parse_error::kParseOutOfBounds; |
1332 } | 1437 } |
1333 return ShaderSourceHelper( | 1438 return ShaderSourceHelper( |
1334 shader, count, reinterpret_cast<const char*>(data), data_size); | 1439 shader, count, reinterpret_cast<const char*>(data), data_size); |
1335 } | 1440 } |
1336 | 1441 |
1337 parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( | 1442 parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( |
1338 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) { | 1443 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) { |
1339 GLuint shader; | 1444 GLuint shader; |
1340 if (!id_map_.GetServiceId(c.shader, &shader)) { | 1445 if (!id_manager_->GetServiceId(c.shader, &shader)) { |
1341 SetGLError(GL_INVALID_VALUE); | 1446 SetGLError(GL_INVALID_VALUE); |
1342 return parse_error::kParseNoError; | 1447 return parse_error::kParseNoError; |
1343 } | 1448 } |
1344 GLsizei count = c.count; | 1449 GLsizei count = c.count; |
1345 uint32 data_size = c.data_size; | 1450 uint32 data_size = c.data_size; |
1346 const char** data = GetImmediateDataAs<const char**>( | 1451 const char** data = GetImmediateDataAs<const char**>( |
1347 c, data_size, immediate_data_size); | 1452 c, data_size, immediate_data_size); |
1348 if (!data) { | 1453 if (!data) { |
1349 return parse_error::kParseOutOfBounds; | 1454 return parse_error::kParseOutOfBounds; |
1350 } | 1455 } |
(...skipping 11 matching lines...) Expand all Loading... |
1362 GLsizei stride = c.stride; | 1467 GLsizei stride = c.stride; |
1363 GLsizei offset = c.offset; | 1468 GLsizei offset = c.offset; |
1364 const void* ptr = reinterpret_cast<const void*>(offset); | 1469 const void* ptr = reinterpret_cast<const void*>(offset); |
1365 if (!ValidateGLenumVertexAttribType(type) || | 1470 if (!ValidateGLenumVertexAttribType(type) || |
1366 !ValidateGLintVertexAttribSize(size) || | 1471 !ValidateGLintVertexAttribSize(size) || |
1367 indx >= max_vertex_attribs_ || | 1472 indx >= max_vertex_attribs_ || |
1368 stride < 0) { | 1473 stride < 0) { |
1369 SetGLError(GL_INVALID_VALUE); | 1474 SetGLError(GL_INVALID_VALUE); |
1370 return parse_error::kParseNoError; | 1475 return parse_error::kParseNoError; |
1371 } | 1476 } |
1372 const BufferInfo* buffer_info = GetBufferInfo(bound_array_buffer_); | 1477 const BufferManager::BufferInfo* buffer_info = |
| 1478 GetBufferInfo(bound_array_buffer_); |
1373 GLsizei component_size = GetGLTypeSize(type); | 1479 GLsizei component_size = GetGLTypeSize(type); |
1374 GLsizei real_stride = stride != 0 ? stride : component_size * size; | 1480 GLsizei real_stride = stride != 0 ? stride : component_size * size; |
1375 if (offset % component_size > 0) { | 1481 if (offset % component_size > 0) { |
1376 SetGLError(GL_INVALID_VALUE); | 1482 SetGLError(GL_INVALID_VALUE); |
1377 return parse_error::kParseNoError; | 1483 return parse_error::kParseNoError; |
1378 } | 1484 } |
1379 vertex_attrib_infos_[indx].SetInfo( | 1485 vertex_attrib_infos_[indx].SetInfo( |
1380 bound_array_buffer_, | 1486 bound_array_buffer_, |
1381 buffer_info ? buffer_info->size : 0, | 1487 buffer_info ? buffer_info->size() : 0, |
1382 size, | 1488 size, |
1383 type, | 1489 type, |
1384 real_stride, | 1490 real_stride, |
1385 offset); | 1491 offset); |
1386 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); | 1492 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); |
1387 } else { | 1493 } else { |
1388 SetGLError(GL_INVALID_VALUE); | 1494 SetGLError(GL_INVALID_VALUE); |
1389 } | 1495 } |
1390 return parse_error::kParseNoError; | 1496 return parse_error::kParseNoError; |
1391 } | 1497 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 // Validation should have prevented us from getting here. | 1541 // Validation should have prevented us from getting here. |
1436 DCHECK(false); | 1542 DCHECK(false); |
1437 break; | 1543 break; |
1438 } | 1544 } |
1439 return parse_error::kParseNoError; | 1545 return parse_error::kParseNoError; |
1440 } | 1546 } |
1441 | 1547 |
1442 parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocation( | 1548 parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocation( |
1443 uint32 immediate_data_size, const gles2::GetAttribLocation& c) { | 1549 uint32 immediate_data_size, const gles2::GetAttribLocation& c) { |
1444 GLuint program; | 1550 GLuint program; |
1445 if (!id_map_.GetServiceId(c.program, &program)) { | 1551 if (!id_manager_->GetServiceId(c.program, &program)) { |
1446 SetGLError(GL_INVALID_VALUE); | 1552 SetGLError(GL_INVALID_VALUE); |
1447 return parse_error::kParseNoError; | 1553 return parse_error::kParseNoError; |
1448 } | 1554 } |
1449 uint32 name_size = c.data_size; | 1555 uint32 name_size = c.data_size; |
1450 const char* name = GetSharedMemoryAs<const char*>( | 1556 const char* name = GetSharedMemoryAs<const char*>( |
1451 c.name_shm_id, c.name_shm_offset, name_size); | 1557 c.name_shm_id, c.name_shm_offset, name_size); |
1452 GLint* location = GetSharedMemoryAs<GLint*>( | 1558 GLint* location = GetSharedMemoryAs<GLint*>( |
1453 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); | 1559 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); |
1454 if (!location || !name) { | 1560 if (!location || !name) { |
1455 return parse_error::kParseOutOfBounds; | 1561 return parse_error::kParseOutOfBounds; |
1456 } | 1562 } |
1457 String name_str(name, name_size); | 1563 String name_str(name, name_size); |
1458 *location = glGetAttribLocation(program, name_str.c_str()); | 1564 *location = glGetAttribLocation(program, name_str.c_str()); |
1459 return parse_error::kParseNoError; | 1565 return parse_error::kParseNoError; |
1460 } | 1566 } |
1461 | 1567 |
1462 parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate( | 1568 parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate( |
1463 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) { | 1569 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) { |
1464 GLuint program; | 1570 GLuint program; |
1465 if (!id_map_.GetServiceId(c.program, &program)) { | 1571 if (!id_manager_->GetServiceId(c.program, &program)) { |
1466 SetGLError(GL_INVALID_VALUE); | 1572 SetGLError(GL_INVALID_VALUE); |
1467 return parse_error::kParseNoError; | 1573 return parse_error::kParseNoError; |
1468 } | 1574 } |
1469 uint32 name_size = c.data_size; | 1575 uint32 name_size = c.data_size; |
1470 const char* name = GetImmediateDataAs<const char*>( | 1576 const char* name = GetImmediateDataAs<const char*>( |
1471 c, name_size, immediate_data_size); | 1577 c, name_size, immediate_data_size); |
1472 GLint* location = GetSharedMemoryAs<GLint*>( | 1578 GLint* location = GetSharedMemoryAs<GLint*>( |
1473 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); | 1579 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); |
1474 if (!location || !name) { | 1580 if (!location || !name) { |
1475 return parse_error::kParseOutOfBounds; | 1581 return parse_error::kParseOutOfBounds; |
1476 } | 1582 } |
1477 String name_str(name, name_size); | 1583 String name_str(name, name_size); |
1478 *location = glGetAttribLocation(program, name_str.c_str()); | 1584 *location = glGetAttribLocation(program, name_str.c_str()); |
1479 return parse_error::kParseNoError; | 1585 return parse_error::kParseNoError; |
1480 } | 1586 } |
1481 | 1587 |
1482 parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocation( | 1588 parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocation( |
1483 uint32 immediate_data_size, const gles2::GetUniformLocation& c) { | 1589 uint32 immediate_data_size, const gles2::GetUniformLocation& c) { |
1484 GLuint program; | 1590 GLuint program; |
1485 if (!id_map_.GetServiceId(c.program, &program)) { | 1591 if (!id_manager_->GetServiceId(c.program, &program)) { |
1486 SetGLError(GL_INVALID_VALUE); | 1592 SetGLError(GL_INVALID_VALUE); |
1487 return parse_error::kParseNoError; | 1593 return parse_error::kParseNoError; |
1488 } | 1594 } |
1489 uint32 name_size = c.data_size; | 1595 uint32 name_size = c.data_size; |
1490 const char* name = GetSharedMemoryAs<const char*>( | 1596 const char* name = GetSharedMemoryAs<const char*>( |
1491 c.name_shm_id, c.name_shm_offset, name_size); | 1597 c.name_shm_id, c.name_shm_offset, name_size); |
1492 GLint* location = GetSharedMemoryAs<GLint*>( | 1598 GLint* location = GetSharedMemoryAs<GLint*>( |
1493 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); | 1599 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); |
1494 if (!location || !name) { | 1600 if (!location || !name) { |
1495 return parse_error::kParseOutOfBounds; | 1601 return parse_error::kParseOutOfBounds; |
1496 } | 1602 } |
1497 String name_str(name, name_size); | 1603 String name_str(name, name_size); |
1498 *location = glGetUniformLocation(program, name_str.c_str()); | 1604 *location = glGetUniformLocation(program, name_str.c_str()); |
1499 return parse_error::kParseNoError; | 1605 return parse_error::kParseNoError; |
1500 } | 1606 } |
1501 | 1607 |
1502 parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate( | 1608 parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate( |
1503 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) { | 1609 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) { |
1504 GLuint program; | 1610 GLuint program; |
1505 if (!id_map_.GetServiceId(c.program, &program)) { | 1611 if (!id_manager_->GetServiceId(c.program, &program)) { |
1506 SetGLError(GL_INVALID_VALUE); | 1612 SetGLError(GL_INVALID_VALUE); |
1507 return parse_error::kParseNoError; | 1613 return parse_error::kParseNoError; |
1508 } | 1614 } |
1509 uint32 name_size = c.data_size; | 1615 uint32 name_size = c.data_size; |
1510 const char* name = GetImmediateDataAs<const char*>( | 1616 const char* name = GetImmediateDataAs<const char*>( |
1511 c, name_size, immediate_data_size); | 1617 c, name_size, immediate_data_size); |
1512 GLint* location = GetSharedMemoryAs<GLint*>( | 1618 GLint* location = GetSharedMemoryAs<GLint*>( |
1513 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); | 1619 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); |
1514 if (!location || !name) { | 1620 if (!location || !name) { |
1515 return parse_error::kParseOutOfBounds; | 1621 return parse_error::kParseOutOfBounds; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1754 return parse_error::kParseNoError; | 1860 return parse_error::kParseNoError; |
1755 } | 1861 } |
1756 | 1862 |
1757 // Include the auto-generated part of this file. We split this because it means | 1863 // Include the auto-generated part of this file. We split this because it means |
1758 // we can easily edit the non-auto generated parts right here in this file | 1864 // we can easily edit the non-auto generated parts right here in this file |
1759 // instead of having to edit some template or the code generator. | 1865 // instead of having to edit some template or the code generator. |
1760 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 1866 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
1761 | 1867 |
1762 } // namespace gles2 | 1868 } // namespace gles2 |
1763 } // namespace gpu | 1869 } // namespace gpu |
OLD | NEW |