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 <vector> | 6 #include <vector> |
6 #include <string> | 7 #include <string> |
7 #include <map> | 8 #include <map> |
8 #include <build/build_config.h> | 9 #include <build/build_config.h> |
9 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
10 #define GLES2_GPU_SERVICE 1 | 11 #define GLES2_GPU_SERVICE 1 |
11 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 12 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
12 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
13 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 14 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
14 #include "gpu/command_buffer/service/gl_utils.h" | 15 #include "gpu/command_buffer/service/gl_utils.h" |
15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | |
16 #include "gpu/command_buffer/service/gles2_cmd_validation.h" | 16 #include "gpu/command_buffer/service/gles2_cmd_validation.h" |
17 | 17 |
18 namespace gpu { | 18 namespace gpu { |
19 namespace gles2 { | 19 namespace gles2 { |
20 | 20 |
21 // Check that certain assumptions the code makes are true. There are places in | 21 // Check that certain assumptions the code makes are true. There are places in |
22 // the code where shared memory is passed direclty to GL. Example, glUniformiv, | 22 // the code where shared memory is passed direclty to GL. Example, glUniformiv, |
23 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe | 23 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe |
24 // a few others) are 32bits. If they are not 32bits the code will have to change | 24 // a few others) are 32bits. If they are not 32bits the code will have to change |
25 // to call those GL functions with service side memory and then copy the results | 25 // to call those GL functions with service side memory and then copy the results |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 return GL_INVALID_FRAMEBUFFER_OPERATION; | 134 return GL_INVALID_FRAMEBUFFER_OPERATION; |
135 default: | 135 default: |
136 DCHECK(false); | 136 DCHECK(false); |
137 return GL_NO_ERROR; | 137 return GL_NO_ERROR; |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 } // anonymous namespace. | 141 } // anonymous namespace. |
142 | 142 |
143 #if defined(UNIT_TEST) | 143 #if defined(UNIT_TEST) |
144 GLES2Decoder::GLES2Decoder() { | 144 GLES2Decoder::GLES2Decoder() |
| 145 : debug_(false) { |
145 #elif defined(OS_LINUX) | 146 #elif defined(OS_LINUX) |
146 GLES2Decoder::GLES2Decoder() | 147 GLES2Decoder::GLES2Decoder() |
147 : debug_(false), | 148 : debug_(false), |
148 window_(NULL) { | 149 window_(NULL) { |
149 #elif defined(OS_WIN) | 150 #elif defined(OS_WIN) |
150 GLES2Decoder::GLES2Decoder() | 151 GLES2Decoder::GLES2Decoder() |
151 : debug_(false), | 152 : debug_(false), |
152 hwnd_(NULL) { | 153 hwnd_(NULL) { |
153 #else | 154 #else |
154 GLES2Decoder::GLES2Decoder() { | 155 GLES2Decoder::GLES2Decoder() |
| 156 : debug_(false) { |
155 #endif | 157 #endif |
156 } | 158 } |
157 | 159 |
158 // This class maps one set of ids to another. | 160 // This class maps one set of ids to another. |
159 class IdMap { | 161 class IdMap { |
160 public: | 162 public: |
161 // Maps a client_id to a service_id. Return false if the client_id or | 163 // Maps a client_id to a service_id. Return false if the client_id or |
162 // service_id are already mapped to something else. | 164 // service_id are already mapped to something else. |
163 bool AddMapping(GLuint client_id, GLuint service_id); | 165 bool AddMapping(GLuint client_id, GLuint service_id); |
164 | 166 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 } | 266 } |
265 } | 267 } |
266 | 268 |
267 void SetInfo( | 269 void SetInfo( |
268 GLuint buffer, | 270 GLuint buffer, |
269 GLsizeiptr buffer_size, | 271 GLsizeiptr buffer_size, |
270 GLint size, | 272 GLint size, |
271 GLenum type, | 273 GLenum type, |
272 GLsizei real_stride, | 274 GLsizei real_stride, |
273 GLsizei offset) { | 275 GLsizei offset) { |
274 DCHECK(real_stride > 0); | 276 DCHECK_GT(real_stride, 0); |
275 buffer_ = buffer; | 277 buffer_ = buffer; |
276 size_ = size; | 278 size_ = size; |
277 type_ = type; | 279 type_ = type; |
278 real_stride_ = real_stride; | 280 real_stride_ = real_stride; |
279 offset_ = offset; | 281 offset_ = offset; |
280 SetBufferSize(buffer_size); | 282 SetBufferSize(buffer_size); |
281 } | 283 } |
282 | 284 |
283 private: | 285 private: |
284 // Whether or not this attribute is enabled. | 286 // Whether or not this attribute is enabled. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 | 358 |
357 // Overridden from AsyncAPIInterface. | 359 // Overridden from AsyncAPIInterface. |
358 virtual const char* GetCommandName(unsigned int command_id) const; | 360 virtual const char* GetCommandName(unsigned int command_id) const; |
359 | 361 |
360 // Overridden from GLES2Decoder. | 362 // Overridden from GLES2Decoder. |
361 virtual bool Initialize(); | 363 virtual bool Initialize(); |
362 | 364 |
363 // Overridden from GLES2Decoder. | 365 // Overridden from GLES2Decoder. |
364 virtual void Destroy(); | 366 virtual void Destroy(); |
365 | 367 |
| 368 // Overridden from GLES2Decoder. |
| 369 virtual uint32 GetServiceIdForTesting(uint32 client_id); |
| 370 |
366 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used | 371 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used |
367 // on glDeleteBuffers so we can make sure the user does not try to render | 372 // on glDeleteBuffers so we can make sure the user does not try to render |
368 // with deleted buffers. | 373 // with deleted buffers. |
369 void RemoveBufferInfo(GLuint buffer_id); | 374 void RemoveBufferInfo(GLuint buffer_id); |
370 | 375 |
371 private: | 376 private: |
372 bool InitPlatformSpecific(); | 377 bool InitPlatformSpecific(); |
373 bool InitGlew(); | 378 bool InitGlew(); |
374 | 379 |
375 // Template to help call glGenXXX functions. | 380 // Template to help call glGenXXX functions. |
376 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)> | 381 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)> |
377 bool GenGLObjects(GLsizei n, const GLuint* client_ids) { | 382 bool GenGLObjects(GLsizei n, const GLuint* client_ids) { |
378 // TODO(gman): Verify client ids are unused. | 383 if (n < 0) { |
| 384 SetGLError(GL_INVALID_VALUE); |
| 385 return true; |
| 386 } |
| 387 if (!ValidateIdsAreUnused(n, client_ids)) { |
| 388 return false; |
| 389 } |
379 scoped_array<GLuint>temp(new GLuint[n]); | 390 scoped_array<GLuint>temp(new GLuint[n]); |
380 gl_gen_function(this, n, temp.get()); | 391 gl_gen_function(this, n, temp.get()); |
381 // TODO(gman): check for success before copying results. | |
382 return RegisterObjects(n, client_ids, temp.get()); | 392 return RegisterObjects(n, client_ids, temp.get()); |
383 } | 393 } |
384 | 394 |
385 // Template to help call glDeleteXXX functions. | 395 // Template to help call glDeleteXXX functions. |
386 template <void gl_delete_function(GLES2DecoderImpl*, GLsizei, GLuint*)> | 396 template <void gl_delete_function(GLES2DecoderImpl*, GLsizei, GLuint*)> |
387 bool DeleteGLObjects(GLsizei n, const GLuint* client_ids) { | 397 bool DeleteGLObjects(GLsizei n, const GLuint* client_ids) { |
388 scoped_array<GLuint>temp(new GLuint[n]); | 398 scoped_array<GLuint>temp(new GLuint[n]); |
389 UnregisterObjects(n, client_ids, temp.get()); | 399 UnregisterObjects(n, client_ids, temp.get()); |
390 gl_delete_function(this, n, temp.get()); | 400 gl_delete_function(this, n, temp.get()); |
391 return true; | 401 return true; |
392 } | 402 } |
393 | 403 |
| 404 // Check that the given ids are not used. |
| 405 bool ValidateIdsAreUnused(GLsizei n, const GLuint* client_ids); |
| 406 |
394 // Register client ids with generated service ids. | 407 // Register client ids with generated service ids. |
395 bool RegisterObjects( | 408 bool RegisterObjects( |
396 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); | 409 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); |
397 | 410 |
398 // Unregisters client ids with service ids. | 411 // Unregisters client ids with service ids. |
399 void UnregisterObjects( | 412 void UnregisterObjects( |
400 GLsizei n, const GLuint* client_ids, GLuint* service_ids); | 413 GLsizei n, const GLuint* client_ids, GLuint* service_ids); |
401 | 414 |
402 // Gets the program info for the given program. Returns NULL if none exists. | 415 // Gets the program info for the given program. Returns NULL if none exists. |
403 // Programs that have no had glLinkProgram succesfully called on them will | 416 // Programs that have no had glLinkProgram succesfully called on them will |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 GLint value; | 576 GLint value; |
564 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); | 577 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); |
565 max_vertex_attribs_ = value; | 578 max_vertex_attribs_ = value; |
566 | 579 |
567 DCHECK_GE(max_vertex_attribs_, 8u); | 580 DCHECK_GE(max_vertex_attribs_, 8u); |
568 | 581 |
569 vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs_]); | 582 vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs_]); |
570 memset(vertex_attrib_infos_.get(), 0, | 583 memset(vertex_attrib_infos_.get(), 0, |
571 sizeof(vertex_attrib_infos_[0]) * max_vertex_attribs_); | 584 sizeof(vertex_attrib_infos_[0]) * max_vertex_attribs_); |
572 | 585 |
573 //glBindFramebuffer(0, 0); | 586 // glBindFramebuffer(0, 0); |
574 return true; | 587 return true; |
575 } | 588 } |
576 | 589 |
577 namespace { | 590 namespace { |
578 | 591 |
579 #if defined(UNIT_TEST) | 592 #if defined(UNIT_TEST) |
580 #elif defined(OS_WIN) | 593 #elif defined(OS_WIN) |
581 | 594 |
582 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { | 595 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { |
583 sizeof(kPixelFormatDescriptor), // Size of structure. | 596 sizeof(kPixelFormatDescriptor), // Size of structure. |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 glDeleteRenderbuffersEXT(n, ids); | 799 glDeleteRenderbuffersEXT(n, ids); |
787 } | 800 } |
788 | 801 |
789 void GLDeleteTexturesHelper( | 802 void GLDeleteTexturesHelper( |
790 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { | 803 GLES2DecoderImpl*, GLsizei n, GLuint* ids) { |
791 glDeleteTextures(n, ids); | 804 glDeleteTextures(n, ids); |
792 } | 805 } |
793 | 806 |
794 } // anonymous namespace | 807 } // anonymous namespace |
795 | 808 |
| 809 uint32 GLES2DecoderImpl::GetServiceIdForTesting(uint32 client_id) { |
| 810 #if defined(UNIT_TEST) |
| 811 GLuint service_id; |
| 812 bool result = id_map_.GetServiceId(client_id, &service_id); |
| 813 return result ? service_id : 0u; |
| 814 #else |
| 815 DCHECK(false); |
| 816 return 0u; |
| 817 #endif |
| 818 } |
| 819 |
| 820 bool GLES2DecoderImpl::ValidateIdsAreUnused( |
| 821 GLsizei n, const GLuint* client_ids) { |
| 822 for (GLsizei ii = 0; ii < n; ++ii) { |
| 823 GLuint service_id; |
| 824 if (id_map_.GetServiceId(client_ids[ii], &service_id)) { |
| 825 return false; |
| 826 } |
| 827 } |
| 828 return true; |
| 829 } |
| 830 |
796 bool GLES2DecoderImpl::RegisterObjects( | 831 bool GLES2DecoderImpl::RegisterObjects( |
797 GLsizei n, const GLuint* client_ids, const GLuint* service_ids) { | 832 GLsizei n, const GLuint* client_ids, const GLuint* service_ids) { |
798 for (GLsizei ii = 0; ii < n; ++ii) { | 833 for (GLsizei ii = 0; ii < n; ++ii) { |
799 if (!id_map_.AddMapping(client_ids[ii], service_ids[ii])) { | 834 if (!id_map_.AddMapping(client_ids[ii], service_ids[ii])) { |
800 // TODO(gman): fail. | 835 NOTREACHED(); |
| 836 return false; |
801 } | 837 } |
802 } | 838 } |
803 return true; | 839 return true; |
804 } | 840 } |
805 | 841 |
806 void GLES2DecoderImpl::UnregisterObjects( | 842 void GLES2DecoderImpl::UnregisterObjects( |
807 GLsizei n, const GLuint* client_ids, GLuint* service_ids) { | 843 GLsizei n, const GLuint* client_ids, GLuint* service_ids) { |
808 // TODO(gman): check for success before copying results. | |
809 for (GLsizei ii = 0; ii < n; ++ii) { | 844 for (GLsizei ii = 0; ii < n; ++ii) { |
810 if (id_map_.GetServiceId(client_ids[ii], &service_ids[ii])) { | 845 if (id_map_.GetServiceId(client_ids[ii], &service_ids[ii])) { |
811 id_map_.RemoveMapping(client_ids[ii], service_ids[ii]); | 846 id_map_.RemoveMapping(client_ids[ii], service_ids[ii]); |
812 } else { | 847 } else { |
813 service_ids[ii] = 0; | 848 service_ids[ii] = 0; |
814 } | 849 } |
815 } | 850 } |
816 } | 851 } |
817 | 852 |
818 void GLES2DecoderImpl::RemoveBufferInfo(GLuint buffer_id) { | 853 void GLES2DecoderImpl::RemoveBufferInfo(GLuint buffer_id) { |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 default: | 1048 default: |
1014 DCHECK(false); // Validation should prevent us getting here. | 1049 DCHECK(false); // Validation should prevent us getting here. |
1015 break; | 1050 break; |
1016 } | 1051 } |
1017 glBindBuffer(target, buffer); | 1052 glBindBuffer(target, buffer); |
1018 } | 1053 } |
1019 | 1054 |
1020 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { | 1055 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { |
1021 if (index < max_vertex_attribs_) { | 1056 if (index < max_vertex_attribs_) { |
1022 vertex_attrib_infos_[index].set_enabled(false); | 1057 vertex_attrib_infos_[index].set_enabled(false); |
1023 glEnableVertexAttribArray(index); | 1058 glDisableVertexAttribArray(index); |
1024 } else { | 1059 } else { |
1025 SetGLError(GL_INVALID_VALUE); | 1060 SetGLError(GL_INVALID_VALUE); |
1026 } | 1061 } |
1027 } | 1062 } |
1028 | 1063 |
1029 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { | 1064 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { |
1030 if (index < max_vertex_attribs_) { | 1065 if (index < max_vertex_attribs_) { |
1031 vertex_attrib_infos_[index].set_enabled(true); | 1066 vertex_attrib_infos_[index].set_enabled(true); |
1032 glEnableVertexAttribArray(index); | 1067 glEnableVertexAttribArray(index); |
1033 } else { | 1068 } else { |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { | 1352 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { |
1318 if (bound_array_buffer_ != 0) { | 1353 if (bound_array_buffer_ != 0) { |
1319 GLuint indx = c.indx; | 1354 GLuint indx = c.indx; |
1320 GLint size = c.size; | 1355 GLint size = c.size; |
1321 GLenum type = c.type; | 1356 GLenum type = c.type; |
1322 GLboolean normalized = c.normalized; | 1357 GLboolean normalized = c.normalized; |
1323 GLsizei stride = c.stride; | 1358 GLsizei stride = c.stride; |
1324 GLsizei offset = c.offset; | 1359 GLsizei offset = c.offset; |
1325 const void* ptr = reinterpret_cast<const void*>(offset); | 1360 const void* ptr = reinterpret_cast<const void*>(offset); |
1326 if (!ValidateGLenumVertexAttribType(type) || | 1361 if (!ValidateGLenumVertexAttribType(type) || |
1327 !ValidateGLenumVertexAttribSize(size) || | 1362 !ValidateGLintVertexAttribSize(size) || |
1328 indx >= max_vertex_attribs_ || | 1363 indx >= max_vertex_attribs_ || |
1329 stride < 0) { | 1364 stride < 0) { |
1330 SetGLError(GL_INVALID_VALUE); | 1365 SetGLError(GL_INVALID_VALUE); |
1331 return parse_error::kParseNoError; | 1366 return parse_error::kParseNoError; |
1332 } | 1367 } |
1333 const BufferInfo* buffer_info = GetBufferInfo(bound_array_buffer_); | 1368 const BufferInfo* buffer_info = GetBufferInfo(bound_array_buffer_); |
1334 GLsizei component_size = GetGLTypeSize(type); | 1369 GLsizei component_size = GetGLTypeSize(type); |
1335 GLsizei real_stride = stride != 0 ? stride : component_size * size; | 1370 GLsizei real_stride = stride != 0 ? stride : component_size * size; |
1336 if (offset % component_size > 0) { | 1371 if (offset % component_size > 0) { |
1337 SetGLError(GL_INVALID_VALUE); | 1372 SetGLError(GL_INVALID_VALUE); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 } | 1408 } |
1374 glReadPixels(x, y, width, height, format, type, pixels); | 1409 glReadPixels(x, y, width, height, format, type, pixels); |
1375 return parse_error::kParseNoError; | 1410 return parse_error::kParseNoError; |
1376 } | 1411 } |
1377 | 1412 |
1378 parse_error::ParseError GLES2DecoderImpl::HandlePixelStorei( | 1413 parse_error::ParseError GLES2DecoderImpl::HandlePixelStorei( |
1379 uint32 immediate_data_size, const gles2::PixelStorei& c) { | 1414 uint32 immediate_data_size, const gles2::PixelStorei& c) { |
1380 GLenum pname = c.pname; | 1415 GLenum pname = c.pname; |
1381 GLenum param = c.param; | 1416 GLenum param = c.param; |
1382 if (!ValidateGLenumPixelStore(pname) || | 1417 if (!ValidateGLenumPixelStore(pname) || |
1383 !ValidateGLenumPixelStoreAlignment(param)) { | 1418 !ValidateGLintPixelStoreAlignment(param)) { |
1384 SetGLError(GL_INVALID_VALUE); | 1419 SetGLError(GL_INVALID_VALUE); |
1385 return parse_error::kParseNoError; | 1420 return parse_error::kParseNoError; |
1386 } | 1421 } |
1387 glPixelStorei(pname, param); | 1422 glPixelStorei(pname, param); |
1388 switch (pname) { | 1423 switch (pname) { |
1389 case GL_PACK_ALIGNMENT: | 1424 case GL_PACK_ALIGNMENT: |
1390 pack_alignment_ = param; | 1425 pack_alignment_ = param; |
1391 break; | 1426 break; |
1392 case GL_UNPACK_ALIGNMENT: | 1427 case GL_UNPACK_ALIGNMENT: |
1393 unpack_alignment_ = param; | 1428 unpack_alignment_ = param; |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1716 } | 1751 } |
1717 | 1752 |
1718 // Include the auto-generated part of this file. We split this because it means | 1753 // Include the auto-generated part of this file. We split this because it means |
1719 // we can easily edit the non-auto generated parts right here in this file | 1754 // we can easily edit the non-auto generated parts right here in this file |
1720 // instead of having to edit some template or the code generator. | 1755 // instead of having to edit some template or the code generator. |
1721 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 1756 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
1722 | 1757 |
1723 } // namespace gles2 | 1758 } // namespace gles2 |
1724 } // namespace gpu | 1759 } // namespace gpu |
1725 | 1760 |
OLD | NEW |