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 |