| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-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 <vector> | 5 #include <vector> |
| 6 #include <string> | 6 #include <string> |
| 7 #include <map> | 7 #include <map> |
| 8 #include <build/build_config.h> | 8 #include <build/build_config.h> |
| 9 #include "base/scoped_ptr.h" | 9 #include "base/scoped_ptr.h" |
| 10 #define GLES2_GPU_SERVICE 1 | 10 #define GLES2_GPU_SERVICE 1 |
| 11 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 11 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| 12 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 12 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 13 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 13 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
| 14 #include "gpu/command_buffer/service/gl_utils.h" | 14 #include "gpu/command_buffer/service/gl_utils.h" |
| 15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 16 #include "gpu/command_buffer/service/gles2_cmd_validation.h" |
| 16 | 17 |
| 17 namespace gpu { | 18 namespace gpu { |
| 18 namespace gles2 { | 19 namespace gles2 { |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| 22 // Returns the address of the first byte after a struct. | 23 // Returns the address of the first byte after a struct. |
| 23 template <typename T> | 24 template <typename T> |
| 24 const void* AddressAfterStruct(const T& pod) { | 25 const void* AddressAfterStruct(const T& pod) { |
| 25 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); | 26 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 274 |
| 274 // Wrapper for glCreateProgram | 275 // Wrapper for glCreateProgram |
| 275 void CreateProgramHelper(GLuint client_id); | 276 void CreateProgramHelper(GLuint client_id); |
| 276 | 277 |
| 277 // Wrapper for glCreateShader | 278 // Wrapper for glCreateShader |
| 278 void CreateShaderHelper(GLenum type, GLuint client_id); | 279 void CreateShaderHelper(GLenum type, GLuint client_id); |
| 279 | 280 |
| 280 // Wrapper for glBindBuffer since we need to track the current targets. | 281 // Wrapper for glBindBuffer since we need to track the current targets. |
| 281 void DoBindBuffer(GLenum target, GLuint buffer); | 282 void DoBindBuffer(GLenum target, GLuint buffer); |
| 282 | 283 |
| 283 // Wrapper for glDeleteProgram. | |
| 284 void DoDeleteProgram(GLuint program); | |
| 285 | |
| 286 // Wrapper for glDeleteShader. | |
| 287 void DoDeleteShader(GLuint shader); | |
| 288 | |
| 289 // Swaps the buffers (copies/renders to the current window). | 284 // Swaps the buffers (copies/renders to the current window). |
| 290 void DoSwapBuffers(); | 285 void DoSwapBuffers(); |
| 291 | 286 |
| 292 // Gets the GLError through our wrapper. | 287 // Gets the GLError through our wrapper. |
| 293 GLenum GetGLError(); | 288 GLenum GetGLError(); |
| 294 | 289 |
| 295 // Sets our wrapper for the GLError. | 290 // Sets our wrapper for the GLError. |
| 296 void SetGLError(GLenum error); | 291 void SetGLError(GLenum error); |
| 297 | 292 |
| 298 // Generate a member function prototype for each command in an automated and | 293 // Generate a member function prototype for each command in an automated and |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 } | 685 } |
| 691 } else { | 686 } else { |
| 692 result = parse_error::kParseInvalidArguments; | 687 result = parse_error::kParseInvalidArguments; |
| 693 } | 688 } |
| 694 } else { | 689 } else { |
| 695 result = DoCommonCommand(command, arg_count, cmd_data); | 690 result = DoCommonCommand(command, arg_count, cmd_data); |
| 696 } | 691 } |
| 697 return result; | 692 return result; |
| 698 } | 693 } |
| 699 | 694 |
| 700 } // namespace gles2 | |
| 701 } // namespace gpu | |
| 702 | |
| 703 // This is included so the compiler will make these inline. | |
| 704 #include "gpu/command_buffer/service/gles2_cmd_decoder_validate.h" | |
| 705 | |
| 706 namespace gpu { | |
| 707 namespace gles2 { | |
| 708 | |
| 709 void GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { | 695 void GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { |
| 710 // TODO(gman): verify client_id is unused. | 696 // TODO(gman): verify client_id is unused. |
| 711 GLuint service_id = glCreateProgram(); | 697 GLuint service_id = glCreateProgram(); |
| 712 if (service_id) { | 698 if (service_id) { |
| 713 id_map_.AddMapping(client_id, service_id); | 699 id_map_.AddMapping(client_id, service_id); |
| 714 } | 700 } |
| 715 } | 701 } |
| 716 | 702 |
| 717 void GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { | 703 void GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { |
| 718 // TODO(gman): verify client_id is unused. | 704 // TODO(gman): verify client_id is unused. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 729 break; | 715 break; |
| 730 case GL_ELEMENT_ARRAY_BUFFER: | 716 case GL_ELEMENT_ARRAY_BUFFER: |
| 731 bound_element_array_buffer_ = buffer; | 717 bound_element_array_buffer_ = buffer; |
| 732 break; | 718 break; |
| 733 default: | 719 default: |
| 734 break; | 720 break; |
| 735 } | 721 } |
| 736 glBindBuffer(target, buffer); | 722 glBindBuffer(target, buffer); |
| 737 } | 723 } |
| 738 | 724 |
| 739 void GLES2DecoderImpl::DoDeleteProgram(GLuint program) { | 725 parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( |
| 726 uint32 immediate_data_size, const gles2::DeleteShader& c) { |
| 727 GLuint shader = c.shader; |
| 740 GLuint service_id; | 728 GLuint service_id; |
| 741 if (id_map_.GetServiceId(program, &service_id)) { | 729 if (!id_map_.GetServiceId(shader, &service_id)) { |
| 742 glDeleteProgram(service_id); | 730 SetGLError(GL_INVALID_VALUE); |
| 743 id_map_.RemoveMapping(program, service_id); | 731 return parse_error::kParseNoError; |
| 744 } | 732 } |
| 733 glDeleteProgram(service_id); |
| 734 id_map_.RemoveMapping(shader, service_id); |
| 735 return parse_error::kParseNoError; |
| 745 } | 736 } |
| 746 | 737 |
| 747 void GLES2DecoderImpl::DoDeleteShader(GLuint shader) { | 738 parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram( |
| 739 uint32 immediate_data_size, const gles2::DeleteProgram& c) { |
| 740 GLuint program = c.program; |
| 748 GLuint service_id; | 741 GLuint service_id; |
| 749 if (id_map_.GetServiceId(shader, &service_id)) { | 742 if (!id_map_.GetServiceId(program, &service_id)) { |
| 750 glDeleteProgram(service_id); | 743 SetGLError(GL_INVALID_VALUE); |
| 751 id_map_.RemoveMapping(shader, service_id); | 744 return parse_error::kParseNoError; |
| 752 } | 745 } |
| 746 glDeleteProgram(service_id); |
| 747 id_map_.RemoveMapping(program, service_id); |
| 748 return parse_error::kParseNoError; |
| 753 } | 749 } |
| 754 | 750 |
| 755 // NOTE: If you need to know the results of SwapBuffers (like losing | 751 // NOTE: If you need to know the results of SwapBuffers (like losing |
| 756 // the context) then add a new command. Do NOT make SwapBuffers synchronous. | 752 // the context) then add a new command. Do NOT make SwapBuffers synchronous. |
| 757 void GLES2DecoderImpl::DoSwapBuffers() { | 753 void GLES2DecoderImpl::DoSwapBuffers() { |
| 758 #ifdef OS_WIN | 754 #ifdef OS_WIN |
| 759 ::SwapBuffers(device_context_); | 755 ::SwapBuffers(device_context_); |
| 760 #endif | 756 #endif |
| 761 | 757 |
| 762 #ifdef OS_LINUX | 758 #ifdef OS_LINUX |
| (...skipping 25 matching lines...) Expand all Loading... |
| 788 void GLES2DecoderImpl::SetGLError(GLenum error) { | 784 void GLES2DecoderImpl::SetGLError(GLenum error) { |
| 789 error_bits_ |= GLErrorToErrorBit(error); | 785 error_bits_ |= GLErrorToErrorBit(error); |
| 790 } | 786 } |
| 791 | 787 |
| 792 parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( | 788 parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( |
| 793 uint32 immediate_data_size, const gles2::DrawElements& c) { | 789 uint32 immediate_data_size, const gles2::DrawElements& c) { |
| 794 if (bound_element_array_buffer_ != 0) { | 790 if (bound_element_array_buffer_ != 0) { |
| 795 GLenum mode = c.mode; | 791 GLenum mode = c.mode; |
| 796 GLsizei count = c.count; | 792 GLsizei count = c.count; |
| 797 GLenum type = c.type; | 793 GLenum type = c.type; |
| 798 const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset); | 794 if (!ValidateGLenumDrawMode(mode) || |
| 799 glDrawElements(mode, count, type, indices); | 795 !ValidateGLenumIndexType(type)) { |
| 796 SetGLError(GL_INVALID_VALUE); |
| 797 } else { |
| 798 const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset); |
| 799 // TODO(gman): Validate indices |
| 800 // TOOD(gman): Validate all attribs current program needs are setup. |
| 801 glDrawElements(mode, count, type, indices); |
| 802 } |
| 800 } else { | 803 } else { |
| 801 SetGLError(GL_INVALID_VALUE); | 804 SetGLError(GL_INVALID_VALUE); |
| 802 } | 805 } |
| 803 return parse_error::kParseNoError; | 806 return parse_error::kParseNoError; |
| 804 } | 807 } |
| 805 | 808 |
| 806 namespace { | 809 namespace { |
| 807 | 810 |
| 808 // Calls glShaderSource for the various versions of the ShaderSource command. | 811 // Calls glShaderSource for the various versions of the ShaderSource command. |
| 809 // Assumes that data / data_size points to a piece of memory that is in range | 812 // Assumes that data / data_size points to a piece of memory that is in range |
| (...skipping 28 matching lines...) Expand all Loading... |
| 838 uint32 immediate_data_size, const gles2::ShaderSource& c) { | 841 uint32 immediate_data_size, const gles2::ShaderSource& c) { |
| 839 GLuint shader; | 842 GLuint shader; |
| 840 if (!id_map_.GetServiceId(c.shader, &shader)) { | 843 if (!id_map_.GetServiceId(c.shader, &shader)) { |
| 841 SetGLError(GL_INVALID_VALUE); | 844 SetGLError(GL_INVALID_VALUE); |
| 842 return parse_error::kParseNoError; | 845 return parse_error::kParseNoError; |
| 843 } | 846 } |
| 844 GLsizei count = c.count; | 847 GLsizei count = c.count; |
| 845 uint32 data_size = c.data_size; | 848 uint32 data_size = c.data_size; |
| 846 const char** data = GetSharedMemoryAs<const char**>( | 849 const char** data = GetSharedMemoryAs<const char**>( |
| 847 c.data_shm_id, c.data_shm_offset, data_size); | 850 c.data_shm_id, c.data_shm_offset, data_size); |
| 848 parse_error::ParseError result = | 851 if (!data) { |
| 849 // TODO(gman): Manually implement validation. | 852 return parse_error::kParseOutOfBounds; |
| 850 ValidateShaderSource( | |
| 851 this, immediate_data_size, shader, count, data, | |
| 852 reinterpret_cast<const GLint*>(1)); | |
| 853 if (result != parse_error::kParseNoError) { | |
| 854 return result; | |
| 855 } | 853 } |
| 856 return ShaderSourceHelper( | 854 return ShaderSourceHelper( |
| 857 shader, count, reinterpret_cast<const char*>(data), data_size); | 855 shader, count, reinterpret_cast<const char*>(data), data_size); |
| 858 } | 856 } |
| 859 | 857 |
| 860 parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( | 858 parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( |
| 861 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) { | 859 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) { |
| 862 GLuint shader; | 860 GLuint shader; |
| 863 if (!id_map_.GetServiceId(c.shader, &shader)) { | 861 if (!id_map_.GetServiceId(c.shader, &shader)) { |
| 864 SetGLError(GL_INVALID_VALUE); | 862 SetGLError(GL_INVALID_VALUE); |
| 865 return parse_error::kParseNoError; | 863 return parse_error::kParseNoError; |
| 866 } | 864 } |
| 867 GLsizei count = c.count; | 865 GLsizei count = c.count; |
| 868 uint32 data_size = c.data_size; | 866 uint32 data_size = c.data_size; |
| 869 // TODO(gman): need to check that data_size is in range for arg_count. | 867 // TODO(gman): need to check that data_size is in range for arg_count. |
| 870 const char** data = GetImmediateDataAs<const char**>(c); | 868 const char** data = GetImmediateDataAs<const char**>(c); |
| 871 parse_error::ParseError result = | 869 if (!data) { |
| 872 ValidateShaderSourceImmediate( | 870 return parse_error::kParseOutOfBounds; |
| 873 this, immediate_data_size, shader, count, data, NULL); | |
| 874 if (result != parse_error::kParseNoError) { | |
| 875 return result; | |
| 876 } | 871 } |
| 877 return ShaderSourceHelper( | 872 return ShaderSourceHelper( |
| 878 shader, count, reinterpret_cast<const char*>(data), data_size); | 873 shader, count, reinterpret_cast<const char*>(data), data_size); |
| 879 } | 874 } |
| 880 | 875 |
| 881 parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer( | 876 parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer( |
| 882 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { | 877 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { |
| 883 if (bound_array_buffer_ != 0) { | 878 if (bound_array_buffer_ != 0) { |
| 884 GLuint indx = c.indx; | 879 GLuint indx = c.indx; |
| 885 GLint size = c.size; | 880 GLint size = c.size; |
| 886 GLenum type = c.type; | 881 GLenum type = c.type; |
| 887 GLboolean normalized = c.normalized; | 882 GLboolean normalized = c.normalized; |
| 888 GLsizei stride = c.stride; | 883 GLsizei stride = c.stride; |
| 889 GLuint offset = c.offset; | 884 GLuint offset = c.offset; |
| 890 const void* ptr = reinterpret_cast<const void*>(c.offset); | 885 const void* ptr = reinterpret_cast<const void*>(c.offset); |
| 891 // TODO(gman): Do manual validation. | 886 // TODO(gman): Do manual validation. |
| 892 parse_error::ParseError result = | 887 if (!ptr) { |
| 893 ValidateVertexAttribPointer( | 888 return parse_error::kParseOutOfBounds; |
| 894 this, immediate_data_size, indx, size, type, normalized, stride, | 889 } |
| 895 reinterpret_cast<const void*>(1)); | 890 if (!ValidateGLenumVertexAttribType(type) || |
| 896 if (result != parse_error::kParseNoError) { | 891 !ValidateGLenumVertexAttribSize(size)) { |
| 897 return result; | 892 SetGLError(GL_INVALID_VALUE); |
| 893 return parse_error::kParseNoError; |
| 898 } | 894 } |
| 899 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); | 895 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); |
| 900 } else { | 896 } else { |
| 901 SetGLError(GL_INVALID_VALUE); | 897 SetGLError(GL_INVALID_VALUE); |
| 902 } | 898 } |
| 903 return parse_error::kParseNoError; | 899 return parse_error::kParseNoError; |
| 904 } | 900 } |
| 905 | 901 |
| 906 parse_error::ParseError GLES2DecoderImpl::HandleReadPixels( | 902 parse_error::ParseError GLES2DecoderImpl::HandleReadPixels( |
| 907 uint32 immediate_data_size, const gles2::ReadPixels& c) { | 903 uint32 immediate_data_size, const gles2::ReadPixels& c) { |
| 908 GLint x = c.x; | 904 GLint x = c.x; |
| 909 GLint y = c.y; | 905 GLint y = c.y; |
| 910 GLsizei width = c.width; | 906 GLsizei width = c.width; |
| 911 GLsizei height = c.height; | 907 GLsizei height = c.height; |
| 912 GLenum format = c.format; | 908 GLenum format = c.format; |
| 913 GLenum type = c.type; | 909 GLenum type = c.type; |
| 914 uint32 pixels_size = GLES2Util::ComputeImageDataSize( | 910 uint32 pixels_size = GLES2Util::ComputeImageDataSize( |
| 915 width, height, format, type, pack_alignment_); | 911 width, height, format, type, pack_alignment_); |
| 916 void* pixels = GetSharedMemoryAs<void*>( | 912 void* pixels = GetSharedMemoryAs<void*>( |
| 917 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); | 913 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); |
| 918 parse_error::ParseError result = ValidateReadPixels( | 914 if (!pixels) { |
| 919 this, immediate_data_size, x, y, width, height, format, type, pixels); | 915 return parse_error::kParseOutOfBounds; |
| 920 if (result != parse_error::kParseNoError) { | 916 } |
| 921 return result; | 917 if (!ValidateGLenumReadPixelFormat(format) || |
| 918 !ValidateGLenumPixelType(type)) { |
| 919 SetGLError(GL_INVALID_VALUE); |
| 920 return parse_error::kParseNoError; |
| 922 } | 921 } |
| 923 glReadPixels(x, y, width, height, format, type, pixels); | 922 glReadPixels(x, y, width, height, format, type, pixels); |
| 924 return parse_error::kParseNoError; | 923 return parse_error::kParseNoError; |
| 925 } | 924 } |
| 926 | 925 |
| 927 parse_error::ParseError GLES2DecoderImpl::HandlePixelStorei( | 926 parse_error::ParseError GLES2DecoderImpl::HandlePixelStorei( |
| 928 uint32 immediate_data_size, const gles2::PixelStorei& c) { | 927 uint32 immediate_data_size, const gles2::PixelStorei& c) { |
| 929 GLenum pname = c.pname; | 928 GLenum pname = c.pname; |
| 930 GLenum param = c.param; | 929 GLenum param = c.param; |
| 931 parse_error::ParseError result = | 930 if (!ValidateGLenumPixelStore(pname) || |
| 932 ValidatePixelStorei(this, immediate_data_size, pname, param); | 931 !ValidateGLenumPixelStoreAlignment(param)) { |
| 933 if (result != parse_error::kParseNoError) { | 932 SetGLError(GL_INVALID_VALUE); |
| 934 return result; | 933 return parse_error::kParseNoError; |
| 935 } | 934 } |
| 936 glPixelStorei(pname, param); | 935 glPixelStorei(pname, param); |
| 937 switch (pname) { | 936 switch (pname) { |
| 938 case GL_PACK_ALIGNMENT: | 937 case GL_PACK_ALIGNMENT: |
| 939 pack_alignment_ = param; | 938 pack_alignment_ = param; |
| 940 break; | 939 break; |
| 941 case GL_UNPACK_ALIGNMENT: | 940 case GL_UNPACK_ALIGNMENT: |
| 942 unpack_alignment_ = param; | 941 unpack_alignment_ = param; |
| 943 break; | 942 break; |
| 944 default: | 943 default: |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 parse_error::ParseError GLES2DecoderImpl::HandleBufferData( | 1033 parse_error::ParseError GLES2DecoderImpl::HandleBufferData( |
| 1035 uint32 immediate_data_size, const gles2::BufferData& c) { | 1034 uint32 immediate_data_size, const gles2::BufferData& c) { |
| 1036 GLenum target = static_cast<GLenum>(c.target); | 1035 GLenum target = static_cast<GLenum>(c.target); |
| 1037 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); | 1036 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); |
| 1038 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); | 1037 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); |
| 1039 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); | 1038 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); |
| 1040 GLenum usage = static_cast<GLenum>(c.usage); | 1039 GLenum usage = static_cast<GLenum>(c.usage); |
| 1041 const void* data = NULL; | 1040 const void* data = NULL; |
| 1042 if (data_shm_id != 0 || data_shm_offset != 0) { | 1041 if (data_shm_id != 0 || data_shm_offset != 0) { |
| 1043 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); | 1042 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); |
| 1044 parse_error::ParseError result = | 1043 if (!data) { |
| 1045 ValidateBufferData(this, immediate_data_size, target, size, data, | 1044 return parse_error::kParseOutOfBounds; |
| 1046 usage); | |
| 1047 if (result != parse_error::kParseNoError) { | |
| 1048 return result; | |
| 1049 } | 1045 } |
| 1050 } | 1046 } |
| 1051 // TODO(gman): Validate case where data is NULL. | 1047 // TODO(gman): Validate case where data is NULL. |
| 1048 if (!ValidateGLenumBufferTarget(target) || |
| 1049 !ValidateGLenumBufferUsage(usage)) { |
| 1050 SetGLError(GL_INVALID_VALUE); |
| 1051 return parse_error::kParseNoError; |
| 1052 } |
| 1052 glBufferData(target, size, data, usage); | 1053 glBufferData(target, size, data, usage); |
| 1053 return parse_error::kParseNoError; | 1054 return parse_error::kParseNoError; |
| 1054 } | 1055 } |
| 1055 | 1056 |
| 1056 parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate( | 1057 parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate( |
| 1057 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) { | 1058 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) { |
| 1058 GLenum target = static_cast<GLenum>(c.target); | 1059 GLenum target = static_cast<GLenum>(c.target); |
| 1059 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); | 1060 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); |
| 1060 const void* data = GetImmediateDataAs<const void*>(c); | 1061 const void* data = GetImmediateDataAs<const void*>(c); |
| 1061 GLenum usage = static_cast<GLenum>(c.usage); | 1062 GLenum usage = static_cast<GLenum>(c.usage); |
| 1062 // Immediate version. | 1063 if (!ValidateGLenumBufferTarget(target) || |
| 1064 !ValidateGLenumBufferUsage(usage)) { |
| 1065 SetGLError(GL_INVALID_VALUE); |
| 1066 return parse_error::kParseNoError; |
| 1067 } |
| 1063 // TODO(gman): Handle case where data is NULL. | 1068 // TODO(gman): Handle case where data is NULL. |
| 1064 parse_error::ParseError result = | |
| 1065 ValidateBufferDataImmediate(this, immediate_data_size, target, size, data, | |
| 1066 usage); | |
| 1067 if (result != parse_error::kParseNoError) { | |
| 1068 return result; | |
| 1069 } | |
| 1070 glBufferData(target, size, data, usage); | 1069 glBufferData(target, size, data, usage); |
| 1071 return parse_error::kParseNoError; | 1070 return parse_error::kParseNoError; |
| 1072 } | 1071 } |
| 1073 | 1072 |
| 1074 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D( | 1073 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D( |
| 1075 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) { | 1074 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) { |
| 1076 GLenum target = static_cast<GLenum>(c.target); | 1075 GLenum target = static_cast<GLenum>(c.target); |
| 1077 GLint level = static_cast<GLint>(c.level); | 1076 GLint level = static_cast<GLint>(c.level); |
| 1078 GLenum internal_format = static_cast<GLenum>(c.internalformat); | 1077 GLenum internal_format = static_cast<GLenum>(c.internalformat); |
| 1079 GLsizei width = static_cast<GLsizei>(c.width); | 1078 GLsizei width = static_cast<GLsizei>(c.width); |
| 1080 GLsizei height = static_cast<GLsizei>(c.height); | 1079 GLsizei height = static_cast<GLsizei>(c.height); |
| 1081 GLint border = static_cast<GLint>(c.border); | 1080 GLint border = static_cast<GLint>(c.border); |
| 1082 GLsizei image_size = static_cast<GLsizei>(c.imageSize); | 1081 GLsizei image_size = static_cast<GLsizei>(c.imageSize); |
| 1083 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); | 1082 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); |
| 1084 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); | 1083 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); |
| 1085 const void* data = NULL; | 1084 const void* data = NULL; |
| 1086 if (data_shm_id != 0 || data_shm_offset != 0) { | 1085 if (data_shm_id != 0 || data_shm_offset != 0) { |
| 1087 data = GetSharedMemoryAs<const void*>( | 1086 data = GetSharedMemoryAs<const void*>( |
| 1088 data_shm_id, data_shm_offset, image_size); | 1087 data_shm_id, data_shm_offset, image_size); |
| 1089 parse_error::ParseError result = | 1088 if (!data) { |
| 1090 ValidateCompressedTexImage2D( | 1089 return parse_error::kParseOutOfBounds; |
| 1091 this, immediate_data_size, target, level, internal_format, width, | |
| 1092 height, border, image_size, data); | |
| 1093 if (result != parse_error::kParseNoError) { | |
| 1094 return result; | |
| 1095 } | 1090 } |
| 1096 } | 1091 } |
| 1092 // TODO(gman): Validate internal_format |
| 1093 if (!ValidateGLenumTextureTarget(target)) { |
| 1094 SetGLError(GL_INVALID_VALUE); |
| 1095 return parse_error::kParseNoError; |
| 1096 } |
| 1097 // TODO(gman): Validate case where data is NULL. | 1097 // TODO(gman): Validate case where data is NULL. |
| 1098 glCompressedTexImage2D( | 1098 glCompressedTexImage2D( |
| 1099 target, level, internal_format, width, height, border, image_size, data); | 1099 target, level, internal_format, width, height, border, image_size, data); |
| 1100 return parse_error::kParseNoError; | 1100 return parse_error::kParseNoError; |
| 1101 } | 1101 } |
| 1102 | 1102 |
| 1103 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( | 1103 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( |
| 1104 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) { | 1104 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) { |
| 1105 GLenum target = static_cast<GLenum>(c.target); | 1105 GLenum target = static_cast<GLenum>(c.target); |
| 1106 GLint level = static_cast<GLint>(c.level); | 1106 GLint level = static_cast<GLint>(c.level); |
| 1107 GLenum internal_format = static_cast<GLenum>(c.internalformat); | 1107 GLenum internal_format = static_cast<GLenum>(c.internalformat); |
| 1108 GLsizei width = static_cast<GLsizei>(c.width); | 1108 GLsizei width = static_cast<GLsizei>(c.width); |
| 1109 GLsizei height = static_cast<GLsizei>(c.height); | 1109 GLsizei height = static_cast<GLsizei>(c.height); |
| 1110 GLint border = static_cast<GLint>(c.border); | 1110 GLint border = static_cast<GLint>(c.border); |
| 1111 GLsizei image_size = static_cast<GLsizei>(c.imageSize); | 1111 GLsizei image_size = static_cast<GLsizei>(c.imageSize); |
| 1112 const void* data = GetImmediateDataAs<const void*>(c); | 1112 const void* data = GetImmediateDataAs<const void*>(c); |
| 1113 // Immediate version. | 1113 // Immediate version. |
| 1114 // TODO(gman): Handle case where data is NULL. | 1114 // TODO(gman): Handle case where data is NULL. |
| 1115 parse_error::ParseError result = | 1115 if (!data) { |
| 1116 ValidateCompressedTexImage2DImmediate( | 1116 return parse_error::kParseOutOfBounds; |
| 1117 this, immediate_data_size, target, level, internal_format, width, | 1117 } |
| 1118 height, border, image_size, data); | 1118 // TODO(gman): Validate internal_format |
| 1119 if (result != parse_error::kParseNoError) { | 1119 if (!ValidateGLenumTextureTarget(target)) { |
| 1120 return result; | 1120 SetGLError(GL_INVALID_VALUE); |
| 1121 return parse_error::kParseNoError; |
| 1121 } | 1122 } |
| 1122 glCompressedTexImage2D( | 1123 glCompressedTexImage2D( |
| 1123 target, level, internal_format, width, height, border, image_size, data); | 1124 target, level, internal_format, width, height, border, image_size, data); |
| 1124 return parse_error::kParseNoError; | 1125 return parse_error::kParseNoError; |
| 1125 } | 1126 } |
| 1126 | 1127 |
| 1127 parse_error::ParseError GLES2DecoderImpl::HandleTexImage2D( | 1128 parse_error::ParseError GLES2DecoderImpl::HandleTexImage2D( |
| 1128 uint32 immediate_data_size, const gles2::TexImage2D& c) { | 1129 uint32 immediate_data_size, const gles2::TexImage2D& c) { |
| 1129 GLenum target = static_cast<GLenum>(c.target); | 1130 GLenum target = static_cast<GLenum>(c.target); |
| 1130 GLint level = static_cast<GLint>(c.level); | 1131 GLint level = static_cast<GLint>(c.level); |
| 1131 GLint internal_format = static_cast<GLint>(c.internalformat); | 1132 GLint internal_format = static_cast<GLint>(c.internalformat); |
| 1132 GLsizei width = static_cast<GLsizei>(c.width); | 1133 GLsizei width = static_cast<GLsizei>(c.width); |
| 1133 GLsizei height = static_cast<GLsizei>(c.height); | 1134 GLsizei height = static_cast<GLsizei>(c.height); |
| 1134 GLint border = static_cast<GLint>(c.border); | 1135 GLint border = static_cast<GLint>(c.border); |
| 1135 GLenum format = static_cast<GLenum>(c.format); | 1136 GLenum format = static_cast<GLenum>(c.format); |
| 1136 GLenum type = static_cast<GLenum>(c.type); | 1137 GLenum type = static_cast<GLenum>(c.type); |
| 1137 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); | 1138 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); |
| 1138 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); | 1139 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); |
| 1139 uint32 pixels_size = GLES2Util::ComputeImageDataSize( | 1140 uint32 pixels_size = GLES2Util::ComputeImageDataSize( |
| 1140 width, height, format, type, unpack_alignment_); | 1141 width, height, format, type, unpack_alignment_); |
| 1141 const void* pixels = NULL; | 1142 const void* pixels = NULL; |
| 1142 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { | 1143 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { |
| 1143 pixels = GetSharedMemoryAs<const void*>( | 1144 pixels = GetSharedMemoryAs<const void*>( |
| 1144 pixels_shm_id, pixels_shm_offset, pixels_size); | 1145 pixels_shm_id, pixels_shm_offset, pixels_size); |
| 1145 parse_error::ParseError result = | 1146 if (!pixels) { |
| 1146 ValidateTexImage2D( | 1147 return parse_error::kParseOutOfBounds; |
| 1147 this, immediate_data_size, target, level, internal_format, width, | |
| 1148 height, border, format, type, pixels); | |
| 1149 if (result != parse_error::kParseNoError) { | |
| 1150 return result; | |
| 1151 } | 1148 } |
| 1152 } | 1149 } |
| 1150 if (!ValidateGLenumTextureTarget(target) || |
| 1151 !ValidateGLenumTextureFormat(internal_format) || |
| 1152 !ValidateGLenumTextureFormat(format) || |
| 1153 !ValidateGLenumPixelType(type)) { |
| 1154 SetGLError(GL_INVALID_VALUE); |
| 1155 return parse_error::kParseNoError; |
| 1156 } |
| 1153 // TODO(gman): Validate case where data is NULL. | 1157 // TODO(gman): Validate case where data is NULL. |
| 1154 glTexImage2D( | 1158 glTexImage2D( |
| 1155 target, level, internal_format, width, height, border, format, type, | 1159 target, level, internal_format, width, height, border, format, type, |
| 1156 pixels); | 1160 pixels); |
| 1157 return parse_error::kParseNoError; | 1161 return parse_error::kParseNoError; |
| 1158 } | 1162 } |
| 1159 | 1163 |
| 1160 parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate( | 1164 parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate( |
| 1161 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) { | 1165 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) { |
| 1162 GLenum target = static_cast<GLenum>(c.target); | 1166 GLenum target = static_cast<GLenum>(c.target); |
| 1163 GLint level = static_cast<GLint>(c.level); | 1167 GLint level = static_cast<GLint>(c.level); |
| 1164 GLint internalformat = static_cast<GLint>(c.internalformat); | 1168 GLint internal_format = static_cast<GLint>(c.internalformat); |
| 1165 GLsizei width = static_cast<GLsizei>(c.width); | 1169 GLsizei width = static_cast<GLsizei>(c.width); |
| 1166 GLsizei height = static_cast<GLsizei>(c.height); | 1170 GLsizei height = static_cast<GLsizei>(c.height); |
| 1167 GLint border = static_cast<GLint>(c.border); | 1171 GLint border = static_cast<GLint>(c.border); |
| 1168 GLenum format = static_cast<GLenum>(c.format); | 1172 GLenum format = static_cast<GLenum>(c.format); |
| 1169 GLenum type = static_cast<GLenum>(c.type); | 1173 GLenum type = static_cast<GLenum>(c.type); |
| 1170 const void* pixels = GetImmediateDataAs<const void*>(c); | 1174 const void* pixels = GetImmediateDataAs<const void*>(c); |
| 1171 // Immediate version. | 1175 // Immediate version. |
| 1172 // TODO(gman): Handle case where data is NULL. | 1176 // TODO(gman): Handle case where data is NULL. |
| 1173 parse_error::ParseError result = | 1177 if (!pixels) { |
| 1174 ValidateTexImage2DImmediate( | 1178 return parse_error::kParseOutOfBounds; |
| 1175 this, immediate_data_size, target, level, internalformat, width, | 1179 } |
| 1176 height, border, format, type, pixels); | 1180 if (!ValidateGLenumTextureTarget(target) || |
| 1177 if (result != parse_error::kParseNoError) { | 1181 !ValidateGLenumTextureFormat(internal_format) || |
| 1178 return result; | 1182 !ValidateGLenumTextureFormat(format) || |
| 1183 !ValidateGLenumPixelType(type)) { |
| 1184 SetGLError(GL_INVALID_VALUE); |
| 1185 return parse_error::kParseNoError; |
| 1179 } | 1186 } |
| 1180 glTexImage2D( | 1187 glTexImage2D( |
| 1181 target, level, internalformat, width, height, border, format, type, | 1188 target, level, internal_format, width, height, border, format, type, |
| 1182 pixels); | 1189 pixels); |
| 1183 return parse_error::kParseNoError; | 1190 return parse_error::kParseNoError; |
| 1184 } | 1191 } |
| 1185 | 1192 |
| 1186 parse_error::ParseError GLES2DecoderImpl::HandleGetVertexAttribPointerv( | 1193 parse_error::ParseError GLES2DecoderImpl::HandleGetVertexAttribPointerv( |
| 1187 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) { | 1194 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) { |
| 1188 // TODO(gman): Implement. | 1195 // TODO(gman): Implement. |
| 1189 return parse_error::kParseNoError; | 1196 return parse_error::kParseNoError; |
| 1190 } | 1197 } |
| 1191 | 1198 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 } | 1233 } |
| 1227 | 1234 |
| 1228 // Include the auto-generated part of this file. We split this because it means | 1235 // Include the auto-generated part of this file. We split this because it means |
| 1229 // we can easily edit the non-auto generated parts right here in this file | 1236 // we can easily edit the non-auto generated parts right here in this file |
| 1230 // instead of having to edit some template or the code generator. | 1237 // instead of having to edit some template or the code generator. |
| 1231 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 1238 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 1232 | 1239 |
| 1233 } // namespace gles2 | 1240 } // namespace gles2 |
| 1234 } // namespace gpu | 1241 } // namespace gpu |
| 1235 | 1242 |
| OLD | NEW |