| 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 |