OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cmath> | 10 #include <cmath> |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 } | 287 } |
288 // Horizontal tab, line feed, vertical tab, form feed, carriage return | 288 // Horizontal tab, line feed, vertical tab, form feed, carriage return |
289 // are also valid. | 289 // are also valid. |
290 if (c >= 9 && c <= 13) { | 290 if (c >= 9 && c <= 13) { |
291 return true; | 291 return true; |
292 } | 292 } |
293 | 293 |
294 return false; | 294 return false; |
295 } | 295 } |
296 | 296 |
297 static bool StringIsValidForGLES(const char* str) { | 297 static bool StringIsValidForGLES(const std::string& str) { |
298 for (; *str; ++str) { | 298 return str.length() == 0 || |
299 if (!CharacterIsValidForGLES(*str)) { | 299 std::find_if_not(str.begin(), str.end(), CharacterIsValidForGLES) == |
300 return false; | 300 str.end(); |
301 } | |
302 } | |
303 return true; | |
304 } | 301 } |
305 | 302 |
306 // This class prevents any GL errors that occur when it is in scope from | 303 // This class prevents any GL errors that occur when it is in scope from |
307 // being reported to the client. | 304 // being reported to the client. |
308 class ScopedGLErrorSuppressor { | 305 class ScopedGLErrorSuppressor { |
309 public: | 306 public: |
310 explicit ScopedGLErrorSuppressor( | 307 explicit ScopedGLErrorSuppressor( |
311 const char* function_name, ErrorState* error_state); | 308 const char* function_name, ErrorState* error_state); |
312 ~ScopedGLErrorSuppressor(); | 309 ~ScopedGLErrorSuppressor(); |
313 private: | 310 private: |
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 | 1190 |
1194 // Creates a vertex attrib manager for the given vertex array. | 1191 // Creates a vertex attrib manager for the given vertex array. |
1195 scoped_refptr<VertexAttribManager> CreateVertexAttribManager( | 1192 scoped_refptr<VertexAttribManager> CreateVertexAttribManager( |
1196 GLuint client_id, | 1193 GLuint client_id, |
1197 GLuint service_id, | 1194 GLuint service_id, |
1198 bool client_visible) { | 1195 bool client_visible) { |
1199 return vertex_array_manager()->CreateVertexAttribManager( | 1196 return vertex_array_manager()->CreateVertexAttribManager( |
1200 client_id, service_id, group_->max_vertex_attribs(), client_visible); | 1197 client_id, service_id, group_->max_vertex_attribs(), client_visible); |
1201 } | 1198 } |
1202 | 1199 |
1203 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name); | 1200 void DoBindAttribLocation(GLuint client_id, |
1204 void DoBindUniformLocationCHROMIUM( | 1201 GLuint index, |
1205 GLuint client_id, GLint location, const char* name); | 1202 const std::string& name); |
| 1203 |
| 1204 error::Error DoBindFragDataLocation(GLuint program_id, |
| 1205 GLuint colorName, |
| 1206 const std::string& name); |
| 1207 |
| 1208 error::Error DoBindFragDataLocationIndexed(GLuint program_id, |
| 1209 GLuint colorName, |
| 1210 GLuint index, |
| 1211 const std::string& name); |
| 1212 |
| 1213 void DoBindUniformLocationCHROMIUM(GLuint client_id, |
| 1214 GLint location, |
| 1215 const std::string& name); |
1206 | 1216 |
1207 error::Error GetAttribLocationHelper( | 1217 error::Error GetAttribLocationHelper( |
1208 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, | 1218 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, |
1209 const std::string& name_str); | 1219 const std::string& name_str); |
1210 | 1220 |
1211 error::Error GetUniformLocationHelper( | 1221 error::Error GetUniformLocationHelper( |
1212 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, | 1222 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, |
1213 const std::string& name_str); | 1223 const std::string& name_str); |
1214 | 1224 |
1215 error::Error GetFragDataLocationHelper( | 1225 error::Error GetFragDataLocationHelper( |
1216 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, | 1226 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, |
1217 const std::string& name_str); | 1227 const std::string& name_str); |
1218 | 1228 |
| 1229 error::Error GetFragDataIndexHelper(GLuint program_id, |
| 1230 uint32 index_shm_id, |
| 1231 uint32 index_shm_offset, |
| 1232 const std::string& name_str); |
| 1233 |
1219 // Wrapper for glShaderSource. | 1234 // Wrapper for glShaderSource. |
1220 void DoShaderSource( | 1235 void DoShaderSource( |
1221 GLuint client_id, GLsizei count, const char** data, const GLint* length); | 1236 GLuint client_id, GLsizei count, const char** data, const GLint* length); |
1222 | 1237 |
1223 // Wrapper for glTransformFeedbackVaryings. | 1238 // Wrapper for glTransformFeedbackVaryings. |
1224 void DoTransformFeedbackVaryings( | 1239 void DoTransformFeedbackVaryings( |
1225 GLuint client_program_id, GLsizei count, const char* const* varyings, | 1240 GLuint client_program_id, GLsizei count, const char* const* varyings, |
1226 GLenum buffer_mode); | 1241 GLenum buffer_mode); |
1227 | 1242 |
1228 // Clear any textures used by the current program. | 1243 // Clear any textures used by the current program. |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 | 1867 |
1853 // Set remaining commands to process to 0 to force DoCommands to return | 1868 // Set remaining commands to process to 0 to force DoCommands to return |
1854 // and allow context preemption and GPU watchdog checks in GpuScheduler(). | 1869 // and allow context preemption and GPU watchdog checks in GpuScheduler(). |
1855 void ExitCommandProcessingEarly() { commands_to_process_ = 0; } | 1870 void ExitCommandProcessingEarly() { commands_to_process_ = 0; } |
1856 | 1871 |
1857 void ProcessPendingReadPixels(bool did_finish); | 1872 void ProcessPendingReadPixels(bool did_finish); |
1858 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); | 1873 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); |
1859 | 1874 |
1860 void DoBindFragmentInputLocationCHROMIUM(GLuint program_id, | 1875 void DoBindFragmentInputLocationCHROMIUM(GLuint program_id, |
1861 GLint location, | 1876 GLint location, |
1862 const char* name); | 1877 const std::string& name); |
| 1878 |
1863 // Generate a member function prototype for each command in an automated and | 1879 // Generate a member function prototype for each command in an automated and |
1864 // typesafe way. | 1880 // typesafe way. |
1865 #define GLES2_CMD_OP(name) \ | 1881 #define GLES2_CMD_OP(name) \ |
1866 Error Handle##name(uint32 immediate_data_size, const void* data); | 1882 Error Handle##name(uint32 immediate_data_size, const void* data); |
1867 | 1883 |
1868 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 1884 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
1869 | 1885 |
1870 #undef GLES2_CMD_OP | 1886 #undef GLES2_CMD_OP |
1871 | 1887 |
1872 // The GL context this decoder renders to on behalf of the client. | 1888 // The GL context this decoder renders to on behalf of the client. |
(...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3171 resources.MaxVaryingVectors = group_->max_varying_vectors(); | 3187 resources.MaxVaryingVectors = group_->max_varying_vectors(); |
3172 resources.MaxVertexTextureImageUnits = | 3188 resources.MaxVertexTextureImageUnits = |
3173 group_->max_vertex_texture_image_units(); | 3189 group_->max_vertex_texture_image_units(); |
3174 resources.MaxCombinedTextureImageUnits = group_->max_texture_units(); | 3190 resources.MaxCombinedTextureImageUnits = group_->max_texture_units(); |
3175 resources.MaxTextureImageUnits = group_->max_texture_image_units(); | 3191 resources.MaxTextureImageUnits = group_->max_texture_image_units(); |
3176 resources.MaxFragmentUniformVectors = | 3192 resources.MaxFragmentUniformVectors = |
3177 group_->max_fragment_uniform_vectors(); | 3193 group_->max_fragment_uniform_vectors(); |
3178 resources.MaxDrawBuffers = group_->max_draw_buffers(); | 3194 resources.MaxDrawBuffers = group_->max_draw_buffers(); |
3179 resources.MaxExpressionComplexity = 256; | 3195 resources.MaxExpressionComplexity = 256; |
3180 resources.MaxCallStackDepth = 256; | 3196 resources.MaxCallStackDepth = 256; |
| 3197 resources.MaxDualSourceDrawBuffers = group_->max_dual_source_draw_buffers(); |
3181 | 3198 |
3182 GLint range[2] = { 0, 0 }; | 3199 GLint range[2] = { 0, 0 }; |
3183 GLint precision = 0; | 3200 GLint precision = 0; |
3184 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, | 3201 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, |
3185 range, &precision); | 3202 range, &precision); |
3186 resources.FragmentPrecisionHigh = | 3203 resources.FragmentPrecisionHigh = |
3187 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision); | 3204 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision); |
3188 | 3205 |
3189 if (feature_info_->IsWebGLContext()) { | 3206 if (feature_info_->IsWebGLContext()) { |
3190 resources.OES_standard_derivatives = derivatives_explicitly_enabled_; | 3207 resources.OES_standard_derivatives = derivatives_explicitly_enabled_; |
(...skipping 12 matching lines...) Expand all Loading... |
3203 resources.OES_EGL_image_external = | 3220 resources.OES_EGL_image_external = |
3204 features().oes_egl_image_external ? 1 : 0; | 3221 features().oes_egl_image_external ? 1 : 0; |
3205 resources.EXT_draw_buffers = | 3222 resources.EXT_draw_buffers = |
3206 features().ext_draw_buffers ? 1 : 0; | 3223 features().ext_draw_buffers ? 1 : 0; |
3207 resources.EXT_frag_depth = | 3224 resources.EXT_frag_depth = |
3208 features().ext_frag_depth ? 1 : 0; | 3225 features().ext_frag_depth ? 1 : 0; |
3209 resources.EXT_shader_texture_lod = | 3226 resources.EXT_shader_texture_lod = |
3210 features().ext_shader_texture_lod ? 1 : 0; | 3227 features().ext_shader_texture_lod ? 1 : 0; |
3211 resources.NV_draw_buffers = | 3228 resources.NV_draw_buffers = |
3212 features().nv_draw_buffers ? 1 : 0; | 3229 features().nv_draw_buffers ? 1 : 0; |
| 3230 resources.EXT_blend_func_extended = |
| 3231 features().ext_blend_func_extended ? 1 : 0; |
3213 } | 3232 } |
3214 | 3233 |
3215 ShShaderSpec shader_spec; | 3234 ShShaderSpec shader_spec; |
3216 switch (feature_info_->context_type()) { | 3235 switch (feature_info_->context_type()) { |
3217 case CONTEXT_TYPE_WEBGL1: | 3236 case CONTEXT_TYPE_WEBGL1: |
3218 shader_spec = SH_WEBGL_SPEC; | 3237 shader_spec = SH_WEBGL_SPEC; |
3219 break; | 3238 break; |
3220 case CONTEXT_TYPE_WEBGL2: | 3239 case CONTEXT_TYPE_WEBGL2: |
3221 shader_spec = SH_WEBGL2_SPEC; | 3240 shader_spec = SH_WEBGL2_SPEC; |
3222 break; | 3241 break; |
(...skipping 2255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5478 *params = 0; | 5497 *params = 0; |
5479 } | 5498 } |
5480 } | 5499 } |
5481 return true; | 5500 return true; |
5482 case GL_BIND_GENERATES_RESOURCE_CHROMIUM: | 5501 case GL_BIND_GENERATES_RESOURCE_CHROMIUM: |
5483 *num_written = 1; | 5502 *num_written = 1; |
5484 if (params) { | 5503 if (params) { |
5485 params[0] = group_->bind_generates_resource() ? 1 : 0; | 5504 params[0] = group_->bind_generates_resource() ? 1 : 0; |
5486 } | 5505 } |
5487 return true; | 5506 return true; |
| 5507 case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT: |
| 5508 *num_written = 1; |
| 5509 if (params) { |
| 5510 params[0] = group_->max_dual_source_draw_buffers(); |
| 5511 } |
| 5512 return true; |
5488 default: | 5513 default: |
5489 if (pname >= GL_DRAW_BUFFER0_ARB && | 5514 if (pname >= GL_DRAW_BUFFER0_ARB && |
5490 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) { | 5515 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) { |
5491 *num_written = 1; | 5516 *num_written = 1; |
5492 if (params) { | 5517 if (params) { |
5493 Framebuffer* framebuffer = | 5518 Framebuffer* framebuffer = |
5494 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); | 5519 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); |
5495 if (framebuffer) { | 5520 if (framebuffer) { |
5496 params[0] = framebuffer->GetDrawBuffer(pname); | 5521 params[0] = framebuffer->GetDrawBuffer(pname); |
5497 } else { // backbuffer | 5522 } else { // backbuffer |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5607 &state_, target, pname, params); | 5632 &state_, target, pname, params); |
5608 } | 5633 } |
5609 | 5634 |
5610 void GLES2DecoderImpl::DoGetBufferParameteriv( | 5635 void GLES2DecoderImpl::DoGetBufferParameteriv( |
5611 GLenum target, GLenum pname, GLint* params) { | 5636 GLenum target, GLenum pname, GLint* params) { |
5612 // Just delegate it. Some validation is actually done before this. | 5637 // Just delegate it. Some validation is actually done before this. |
5613 buffer_manager()->ValidateAndDoGetBufferParameteriv( | 5638 buffer_manager()->ValidateAndDoGetBufferParameteriv( |
5614 &state_, target, pname, params); | 5639 &state_, target, pname, params); |
5615 } | 5640 } |
5616 | 5641 |
5617 void GLES2DecoderImpl::DoBindAttribLocation( | 5642 void GLES2DecoderImpl::DoBindAttribLocation(GLuint program_id, |
5618 GLuint program_id, GLuint index, const char* name) { | 5643 GLuint index, |
| 5644 const std::string& name) { |
5619 if (!StringIsValidForGLES(name)) { | 5645 if (!StringIsValidForGLES(name)) { |
5620 LOCAL_SET_GL_ERROR( | 5646 LOCAL_SET_GL_ERROR( |
5621 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); | 5647 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); |
5622 return; | 5648 return; |
5623 } | 5649 } |
5624 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { | 5650 if (ProgramManager::HasBuiltInPrefix(name)) { |
5625 LOCAL_SET_GL_ERROR( | 5651 LOCAL_SET_GL_ERROR( |
5626 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); | 5652 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); |
5627 return; | 5653 return; |
5628 } | 5654 } |
5629 if (index >= group_->max_vertex_attribs()) { | 5655 if (index >= group_->max_vertex_attribs()) { |
5630 LOCAL_SET_GL_ERROR( | 5656 LOCAL_SET_GL_ERROR( |
5631 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range"); | 5657 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range"); |
5632 return; | 5658 return; |
5633 } | 5659 } |
5634 Program* program = GetProgramInfoNotShader( | 5660 Program* program = GetProgramInfoNotShader( |
5635 program_id, "glBindAttribLocation"); | 5661 program_id, "glBindAttribLocation"); |
5636 if (!program) { | 5662 if (!program) { |
5637 return; | 5663 return; |
5638 } | 5664 } |
5639 // At this point, the program's shaders may not be translated yet, | 5665 // At this point, the program's shaders may not be translated yet, |
5640 // therefore, we may not find the hashed attribute name. | 5666 // therefore, we may not find the hashed attribute name. |
5641 // glBindAttribLocation call with original name is useless. | 5667 // glBindAttribLocation call with original name is useless. |
5642 // So instead, we should simply cache the binding, and then call | 5668 // So instead, we should simply cache the binding, and then call |
5643 // Program::ExecuteBindAttribLocationCalls() right before link. | 5669 // Program::ExecuteBindAttribLocationCalls() right before link. |
5644 program->SetAttribLocationBinding(name, static_cast<GLint>(index)); | 5670 program->SetAttribLocationBinding(name, static_cast<GLint>(index)); |
5645 // TODO(zmo): Get rid of the following glBindAttribLocation call. | 5671 // TODO(zmo): Get rid of the following glBindAttribLocation call. |
5646 glBindAttribLocation(program->service_id(), index, name); | 5672 glBindAttribLocation(program->service_id(), index, name.c_str()); |
5647 } | 5673 } |
5648 | 5674 |
5649 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( | 5675 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( |
5650 uint32 immediate_data_size, | 5676 uint32 immediate_data_size, |
5651 const void* cmd_data) { | 5677 const void* cmd_data) { |
5652 const gles2::cmds::BindAttribLocationBucket& c = | 5678 const gles2::cmds::BindAttribLocationBucket& c = |
5653 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data); | 5679 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data); |
5654 GLuint program = static_cast<GLuint>(c.program); | 5680 GLuint program = static_cast<GLuint>(c.program); |
5655 GLuint index = static_cast<GLuint>(c.index); | 5681 GLuint index = static_cast<GLuint>(c.index); |
5656 Bucket* bucket = GetBucket(c.name_bucket_id); | 5682 Bucket* bucket = GetBucket(c.name_bucket_id); |
5657 if (!bucket || bucket->size() == 0) { | 5683 if (!bucket || bucket->size() == 0) { |
5658 return error::kInvalidArguments; | 5684 return error::kInvalidArguments; |
5659 } | 5685 } |
5660 std::string name_str; | 5686 std::string name_str; |
5661 if (!bucket->GetAsString(&name_str)) { | 5687 if (!bucket->GetAsString(&name_str)) { |
5662 return error::kInvalidArguments; | 5688 return error::kInvalidArguments; |
5663 } | 5689 } |
5664 DoBindAttribLocation(program, index, name_str.c_str()); | 5690 DoBindAttribLocation(program, index, name_str); |
5665 return error::kNoError; | 5691 return error::kNoError; |
5666 } | 5692 } |
5667 | 5693 |
5668 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM( | 5694 error::Error GLES2DecoderImpl::DoBindFragDataLocation(GLuint program_id, |
5669 GLuint program_id, GLint location, const char* name) { | 5695 GLuint colorName, |
| 5696 const std::string& name) { |
| 5697 const char kFunctionName[] = "glBindFragDataLocationEXT"; |
| 5698 if (!StringIsValidForGLES(name)) { |
| 5699 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); |
| 5700 return error::kNoError; |
| 5701 } |
| 5702 if (ProgramManager::HasBuiltInPrefix(name)) { |
| 5703 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); |
| 5704 return error::kNoError; |
| 5705 } |
| 5706 if (colorName >= group_->max_draw_buffers()) { |
| 5707 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 5708 "colorName out of range"); |
| 5709 return error::kNoError; |
| 5710 } |
| 5711 Program* program = GetProgramInfoNotShader(program_id, kFunctionName); |
| 5712 if (!program) { |
| 5713 return error::kNoError; |
| 5714 } |
| 5715 program->SetProgramOutputLocationBinding(name, colorName); |
| 5716 return error::kNoError; |
| 5717 } |
| 5718 |
| 5719 error::Error GLES2DecoderImpl::HandleBindFragDataLocationEXTBucket( |
| 5720 uint32 immediate_data_size, |
| 5721 const void* cmd_data) { |
| 5722 if (!features().ext_blend_func_extended) { |
| 5723 return error::kUnknownCommand; |
| 5724 } |
| 5725 const gles2::cmds::BindFragDataLocationEXTBucket& c = |
| 5726 *static_cast<const gles2::cmds::BindFragDataLocationEXTBucket*>(cmd_data); |
| 5727 GLuint program = static_cast<GLuint>(c.program); |
| 5728 GLuint colorNumber = static_cast<GLuint>(c.colorNumber); |
| 5729 Bucket* bucket = GetBucket(c.name_bucket_id); |
| 5730 if (!bucket || bucket->size() == 0) { |
| 5731 return error::kInvalidArguments; |
| 5732 } |
| 5733 std::string name_str; |
| 5734 if (!bucket->GetAsString(&name_str)) { |
| 5735 return error::kInvalidArguments; |
| 5736 } |
| 5737 return DoBindFragDataLocation(program, colorNumber, name_str); |
| 5738 } |
| 5739 |
| 5740 error::Error GLES2DecoderImpl::DoBindFragDataLocationIndexed( |
| 5741 GLuint program_id, |
| 5742 GLuint colorName, |
| 5743 GLuint index, |
| 5744 const std::string& name) { |
| 5745 const char kFunctionName[] = "glBindFragDataLocationIndexEXT"; |
| 5746 if (!StringIsValidForGLES(name)) { |
| 5747 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); |
| 5748 return error::kNoError; |
| 5749 } |
| 5750 if (ProgramManager::HasBuiltInPrefix(name)) { |
| 5751 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); |
| 5752 return error::kNoError; |
| 5753 } |
| 5754 if (index != 0 && index != 1) { |
| 5755 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "index out of range"); |
| 5756 return error::kNoError; |
| 5757 } |
| 5758 if ((index == 0 && colorName >= group_->max_draw_buffers()) || |
| 5759 (index == 1 && colorName >= group_->max_dual_source_draw_buffers())) { |
| 5760 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
| 5761 "colorName out of range for the color index"); |
| 5762 return error::kNoError; |
| 5763 } |
| 5764 Program* program = GetProgramInfoNotShader(program_id, kFunctionName); |
| 5765 if (!program) { |
| 5766 return error::kNoError; |
| 5767 } |
| 5768 program->SetProgramOutputLocationIndexedBinding(name, colorName, index); |
| 5769 return error::kNoError; |
| 5770 } |
| 5771 |
| 5772 error::Error GLES2DecoderImpl::HandleBindFragDataLocationIndexedEXTBucket( |
| 5773 uint32 immediate_data_size, |
| 5774 const void* cmd_data) { |
| 5775 if (!features().ext_blend_func_extended) { |
| 5776 return error::kUnknownCommand; |
| 5777 } |
| 5778 const gles2::cmds::BindFragDataLocationIndexedEXTBucket& c = |
| 5779 *static_cast<const gles2::cmds::BindFragDataLocationIndexedEXTBucket*>( |
| 5780 cmd_data); |
| 5781 GLuint program = static_cast<GLuint>(c.program); |
| 5782 GLuint colorNumber = static_cast<GLuint>(c.colorNumber); |
| 5783 GLuint index = static_cast<GLuint>(c.index); |
| 5784 Bucket* bucket = GetBucket(c.name_bucket_id); |
| 5785 if (!bucket || bucket->size() == 0) { |
| 5786 return error::kInvalidArguments; |
| 5787 } |
| 5788 std::string name_str; |
| 5789 if (!bucket->GetAsString(&name_str)) { |
| 5790 return error::kInvalidArguments; |
| 5791 } |
| 5792 return DoBindFragDataLocationIndexed(program, colorNumber, index, name_str); |
| 5793 } |
| 5794 |
| 5795 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(GLuint program_id, |
| 5796 GLint location, |
| 5797 const std::string& name) { |
5670 if (!StringIsValidForGLES(name)) { | 5798 if (!StringIsValidForGLES(name)) { |
5671 LOCAL_SET_GL_ERROR( | 5799 LOCAL_SET_GL_ERROR( |
5672 GL_INVALID_VALUE, | 5800 GL_INVALID_VALUE, |
5673 "glBindUniformLocationCHROMIUM", "Invalid character"); | 5801 "glBindUniformLocationCHROMIUM", "Invalid character"); |
5674 return; | 5802 return; |
5675 } | 5803 } |
5676 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { | 5804 if (ProgramManager::HasBuiltInPrefix(name)) { |
5677 LOCAL_SET_GL_ERROR( | 5805 LOCAL_SET_GL_ERROR( |
5678 GL_INVALID_OPERATION, | 5806 GL_INVALID_OPERATION, |
5679 "glBindUniformLocationCHROMIUM", "reserved prefix"); | 5807 "glBindUniformLocationCHROMIUM", "reserved prefix"); |
5680 return; | 5808 return; |
5681 } | 5809 } |
5682 if (location < 0 || static_cast<uint32>(location) >= | 5810 if (location < 0 || static_cast<uint32>(location) >= |
5683 (group_->max_fragment_uniform_vectors() + | 5811 (group_->max_fragment_uniform_vectors() + |
5684 group_->max_vertex_uniform_vectors()) * 4) { | 5812 group_->max_vertex_uniform_vectors()) * 4) { |
5685 LOCAL_SET_GL_ERROR( | 5813 LOCAL_SET_GL_ERROR( |
5686 GL_INVALID_VALUE, | 5814 GL_INVALID_VALUE, |
(...skipping 21 matching lines...) Expand all Loading... |
5708 GLuint program = static_cast<GLuint>(c.program); | 5836 GLuint program = static_cast<GLuint>(c.program); |
5709 GLint location = static_cast<GLint>(c.location); | 5837 GLint location = static_cast<GLint>(c.location); |
5710 Bucket* bucket = GetBucket(c.name_bucket_id); | 5838 Bucket* bucket = GetBucket(c.name_bucket_id); |
5711 if (!bucket || bucket->size() == 0) { | 5839 if (!bucket || bucket->size() == 0) { |
5712 return error::kInvalidArguments; | 5840 return error::kInvalidArguments; |
5713 } | 5841 } |
5714 std::string name_str; | 5842 std::string name_str; |
5715 if (!bucket->GetAsString(&name_str)) { | 5843 if (!bucket->GetAsString(&name_str)) { |
5716 return error::kInvalidArguments; | 5844 return error::kInvalidArguments; |
5717 } | 5845 } |
5718 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); | 5846 DoBindUniformLocationCHROMIUM(program, location, name_str); |
5719 return error::kNoError; | 5847 return error::kNoError; |
5720 } | 5848 } |
5721 | 5849 |
5722 error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size, | 5850 error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size, |
5723 const void* cmd_data) { | 5851 const void* cmd_data) { |
5724 const gles2::cmds::DeleteShader& c = | 5852 const gles2::cmds::DeleteShader& c = |
5725 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data); | 5853 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data); |
5726 GLuint client_id = c.shader; | 5854 GLuint client_id = c.shader; |
5727 if (client_id) { | 5855 if (client_id) { |
5728 Shader* shader = GetShader(client_id); | 5856 Shader* shader = GetShader(client_id); |
(...skipping 3624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9353 c.background_color, bounds_size, transform)) { | 9481 c.background_color, bounds_size, transform)) { |
9354 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleCALayerCHROMIUM", | 9482 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glScheduleCALayerCHROMIUM", |
9355 "failed to schedule CALayer"); | 9483 "failed to schedule CALayer"); |
9356 } | 9484 } |
9357 return error::kNoError; | 9485 return error::kNoError; |
9358 } | 9486 } |
9359 | 9487 |
9360 error::Error GLES2DecoderImpl::GetAttribLocationHelper( | 9488 error::Error GLES2DecoderImpl::GetAttribLocationHelper( |
9361 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, | 9489 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, |
9362 const std::string& name_str) { | 9490 const std::string& name_str) { |
9363 if (!StringIsValidForGLES(name_str.c_str())) { | 9491 if (!StringIsValidForGLES(name_str)) { |
9364 LOCAL_SET_GL_ERROR( | 9492 LOCAL_SET_GL_ERROR( |
9365 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); | 9493 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); |
9366 return error::kNoError; | 9494 return error::kNoError; |
9367 } | 9495 } |
9368 Program* program = GetProgramInfoNotShader( | 9496 Program* program = GetProgramInfoNotShader( |
9369 client_id, "glGetAttribLocation"); | 9497 client_id, "glGetAttribLocation"); |
9370 if (!program) { | 9498 if (!program) { |
9371 return error::kNoError; | 9499 return error::kNoError; |
9372 } | 9500 } |
9373 if (!program->IsValid()) { | 9501 if (!program->IsValid()) { |
(...skipping 27 matching lines...) Expand all Loading... |
9401 if (!bucket->GetAsString(&name_str)) { | 9529 if (!bucket->GetAsString(&name_str)) { |
9402 return error::kInvalidArguments; | 9530 return error::kInvalidArguments; |
9403 } | 9531 } |
9404 return GetAttribLocationHelper( | 9532 return GetAttribLocationHelper( |
9405 c.program, c.location_shm_id, c.location_shm_offset, name_str); | 9533 c.program, c.location_shm_id, c.location_shm_offset, name_str); |
9406 } | 9534 } |
9407 | 9535 |
9408 error::Error GLES2DecoderImpl::GetUniformLocationHelper( | 9536 error::Error GLES2DecoderImpl::GetUniformLocationHelper( |
9409 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, | 9537 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, |
9410 const std::string& name_str) { | 9538 const std::string& name_str) { |
9411 if (!StringIsValidForGLES(name_str.c_str())) { | 9539 if (!StringIsValidForGLES(name_str)) { |
9412 LOCAL_SET_GL_ERROR( | 9540 LOCAL_SET_GL_ERROR( |
9413 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); | 9541 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); |
9414 return error::kNoError; | 9542 return error::kNoError; |
9415 } | 9543 } |
9416 Program* program = GetProgramInfoNotShader( | 9544 Program* program = GetProgramInfoNotShader( |
9417 client_id, "glGetUniformLocation"); | 9545 client_id, "glGetUniformLocation"); |
9418 if (!program) { | 9546 if (!program) { |
9419 return error::kNoError; | 9547 return error::kNoError; |
9420 } | 9548 } |
9421 if (!program->IsValid()) { | 9549 if (!program->IsValid()) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9501 result->SetNumResults(count); | 9629 result->SetNumResults(count); |
9502 } else { | 9630 } else { |
9503 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", ""); | 9631 LOCAL_SET_GL_ERROR(error, "GetUniformIndices", ""); |
9504 } | 9632 } |
9505 return error::kNoError; | 9633 return error::kNoError; |
9506 } | 9634 } |
9507 | 9635 |
9508 error::Error GLES2DecoderImpl::GetFragDataLocationHelper( | 9636 error::Error GLES2DecoderImpl::GetFragDataLocationHelper( |
9509 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, | 9637 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, |
9510 const std::string& name_str) { | 9638 const std::string& name_str) { |
| 9639 const char kFunctionName[] = "glGetFragDataLocation"; |
9511 GLint* location = GetSharedMemoryAs<GLint*>( | 9640 GLint* location = GetSharedMemoryAs<GLint*>( |
9512 location_shm_id, location_shm_offset, sizeof(GLint)); | 9641 location_shm_id, location_shm_offset, sizeof(GLint)); |
9513 if (!location) { | 9642 if (!location) { |
9514 return error::kOutOfBounds; | 9643 return error::kOutOfBounds; |
9515 } | 9644 } |
9516 // Check that the client initialized the result. | 9645 // Check that the client initialized the result. |
9517 if (*location != -1) { | 9646 if (*location != -1) { |
9518 return error::kInvalidArguments; | 9647 return error::kInvalidArguments; |
9519 } | 9648 } |
9520 Program* program = GetProgramInfoNotShader( | 9649 Program* program = GetProgramInfoNotShader(client_id, kFunctionName); |
9521 client_id, "glGetFragDataLocation"); | |
9522 if (!program) { | 9650 if (!program) { |
9523 return error::kNoError; | 9651 return error::kNoError; |
9524 } | 9652 } |
9525 *location = glGetFragDataLocation(program->service_id(), name_str.c_str()); | 9653 if (!program->IsValid()) { |
| 9654 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 9655 "program not linked"); |
| 9656 return error::kNoError; |
| 9657 } |
| 9658 |
| 9659 *location = program->GetFragDataLocation(name_str); |
9526 return error::kNoError; | 9660 return error::kNoError; |
9527 } | 9661 } |
9528 | 9662 |
9529 error::Error GLES2DecoderImpl::HandleGetFragDataLocation( | 9663 error::Error GLES2DecoderImpl::HandleGetFragDataLocation( |
9530 uint32 immediate_data_size, | 9664 uint32 immediate_data_size, |
9531 const void* cmd_data) { | 9665 const void* cmd_data) { |
9532 if (!unsafe_es3_apis_enabled()) | 9666 if (!unsafe_es3_apis_enabled()) |
9533 return error::kUnknownCommand; | 9667 return error::kUnknownCommand; |
9534 const gles2::cmds::GetFragDataLocation& c = | 9668 const gles2::cmds::GetFragDataLocation& c = |
9535 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data); | 9669 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data); |
9536 Bucket* bucket = GetBucket(c.name_bucket_id); | 9670 Bucket* bucket = GetBucket(c.name_bucket_id); |
9537 if (!bucket) { | 9671 if (!bucket) { |
9538 return error::kInvalidArguments; | 9672 return error::kInvalidArguments; |
9539 } | 9673 } |
9540 std::string name_str; | 9674 std::string name_str; |
9541 if (!bucket->GetAsString(&name_str)) { | 9675 if (!bucket->GetAsString(&name_str)) { |
9542 return error::kInvalidArguments; | 9676 return error::kInvalidArguments; |
9543 } | 9677 } |
9544 return GetFragDataLocationHelper( | 9678 return GetFragDataLocationHelper( |
9545 c.program, c.location_shm_id, c.location_shm_offset, name_str); | 9679 c.program, c.location_shm_id, c.location_shm_offset, name_str); |
9546 } | 9680 } |
9547 | 9681 |
| 9682 error::Error GLES2DecoderImpl::GetFragDataIndexHelper( |
| 9683 GLuint program_id, |
| 9684 uint32 index_shm_id, |
| 9685 uint32 index_shm_offset, |
| 9686 const std::string& name_str) { |
| 9687 const char kFunctionName[] = "glGetFragDataIndexEXT"; |
| 9688 GLint* index = |
| 9689 GetSharedMemoryAs<GLint*>(index_shm_id, index_shm_offset, sizeof(GLint)); |
| 9690 if (!index) { |
| 9691 return error::kOutOfBounds; |
| 9692 } |
| 9693 // Check that the client initialized the result. |
| 9694 if (*index != -1) { |
| 9695 return error::kInvalidArguments; |
| 9696 } |
| 9697 Program* program = GetProgramInfoNotShader(program_id, kFunctionName); |
| 9698 if (!program) { |
| 9699 return error::kNoError; |
| 9700 } |
| 9701 if (!program->IsValid()) { |
| 9702 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
| 9703 "program not linked"); |
| 9704 return error::kNoError; |
| 9705 } |
| 9706 |
| 9707 *index = program->GetFragDataIndex(name_str); |
| 9708 return error::kNoError; |
| 9709 } |
| 9710 |
| 9711 error::Error GLES2DecoderImpl::HandleGetFragDataIndexEXT( |
| 9712 uint32 immediate_data_size, |
| 9713 const void* cmd_data) { |
| 9714 if (!features().ext_blend_func_extended) { |
| 9715 return error::kUnknownCommand; |
| 9716 } |
| 9717 const gles2::cmds::GetFragDataIndexEXT& c = |
| 9718 *static_cast<const gles2::cmds::GetFragDataIndexEXT*>(cmd_data); |
| 9719 Bucket* bucket = GetBucket(c.name_bucket_id); |
| 9720 if (!bucket) { |
| 9721 return error::kInvalidArguments; |
| 9722 } |
| 9723 std::string name_str; |
| 9724 if (!bucket->GetAsString(&name_str)) { |
| 9725 return error::kInvalidArguments; |
| 9726 } |
| 9727 return GetFragDataIndexHelper(c.program, c.index_shm_id, c.index_shm_offset, |
| 9728 name_str); |
| 9729 } |
| 9730 |
9548 error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex( | 9731 error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex( |
9549 uint32 immediate_data_size, const void* cmd_data) { | 9732 uint32 immediate_data_size, const void* cmd_data) { |
9550 if (!unsafe_es3_apis_enabled()) | 9733 if (!unsafe_es3_apis_enabled()) |
9551 return error::kUnknownCommand; | 9734 return error::kUnknownCommand; |
9552 const gles2::cmds::GetUniformBlockIndex& c = | 9735 const gles2::cmds::GetUniformBlockIndex& c = |
9553 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data); | 9736 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data); |
9554 Bucket* bucket = GetBucket(c.name_bucket_id); | 9737 Bucket* bucket = GetBucket(c.name_bucket_id); |
9555 if (!bucket) { | 9738 if (!bucket) { |
9556 return error::kInvalidArguments; | 9739 return error::kInvalidArguments; |
9557 } | 9740 } |
(...skipping 5723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15281 | 15464 |
15282 GLint reference = static_cast<GLint>(c.reference); | 15465 GLint reference = static_cast<GLint>(c.reference); |
15283 GLuint mask = static_cast<GLuint>(c.mask); | 15466 GLuint mask = static_cast<GLuint>(c.mask); |
15284 ApplyDirtyState(); | 15467 ApplyDirtyState(); |
15285 glStencilThenCoverStrokePathInstancedNV( | 15468 glStencilThenCoverStrokePathInstancedNV( |
15286 num_paths, GL_UNSIGNED_INT, paths.path_names(), 0, reference, mask, | 15469 num_paths, GL_UNSIGNED_INT, paths.path_names(), 0, reference, mask, |
15287 cover_mode, transform_type, transforms); | 15470 cover_mode, transform_type, transforms); |
15288 return error::kNoError; | 15471 return error::kNoError; |
15289 } | 15472 } |
15290 | 15473 |
15291 void GLES2DecoderImpl::DoBindFragmentInputLocationCHROMIUM(GLuint program_id, | 15474 void GLES2DecoderImpl::DoBindFragmentInputLocationCHROMIUM( |
15292 GLint location, | 15475 GLuint program_id, |
15293 const char* name) { | 15476 GLint location, |
| 15477 const std::string& name) { |
15294 static const char kFunctionName[] = "glBindFragmentInputLocationCHROMIUM"; | 15478 static const char kFunctionName[] = "glBindFragmentInputLocationCHROMIUM"; |
| 15479 if (!StringIsValidForGLES(name)) { |
| 15480 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); |
| 15481 return; |
| 15482 } |
| 15483 if (ProgramManager::HasBuiltInPrefix(name)) { |
| 15484 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); |
| 15485 return; |
| 15486 } |
15295 Program* program = GetProgram(program_id); | 15487 Program* program = GetProgram(program_id); |
15296 if (!program || program->IsDeleted()) { | 15488 if (!program || program->IsDeleted()) { |
15297 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid program"); | 15489 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "invalid program"); |
15298 return; | 15490 return; |
15299 } | 15491 } |
15300 if (!StringIsValidForGLES(name)) { | |
15301 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "invalid character"); | |
15302 return; | |
15303 } | |
15304 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { | |
15305 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, "reserved prefix"); | |
15306 return; | |
15307 } | |
15308 if (location < 0 || | 15492 if (location < 0 || |
15309 static_cast<uint32>(location) >= group_->max_varying_vectors() * 4) { | 15493 static_cast<uint32>(location) >= group_->max_varying_vectors() * 4) { |
15310 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, | 15494 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, |
15311 "location out of range"); | 15495 "location out of range"); |
15312 return; | 15496 return; |
15313 } | 15497 } |
15314 | 15498 |
15315 program->SetFragmentInputLocationBinding(name, location); | 15499 program->SetFragmentInputLocationBinding(name, location); |
15316 } | 15500 } |
15317 | 15501 |
(...skipping 10 matching lines...) Expand all Loading... |
15328 GLuint program = static_cast<GLuint>(c.program); | 15512 GLuint program = static_cast<GLuint>(c.program); |
15329 GLint location = static_cast<GLint>(c.location); | 15513 GLint location = static_cast<GLint>(c.location); |
15330 Bucket* bucket = GetBucket(c.name_bucket_id); | 15514 Bucket* bucket = GetBucket(c.name_bucket_id); |
15331 if (!bucket || bucket->size() == 0) { | 15515 if (!bucket || bucket->size() == 0) { |
15332 return error::kInvalidArguments; | 15516 return error::kInvalidArguments; |
15333 } | 15517 } |
15334 std::string name_str; | 15518 std::string name_str; |
15335 if (!bucket->GetAsString(&name_str)) { | 15519 if (!bucket->GetAsString(&name_str)) { |
15336 return error::kInvalidArguments; | 15520 return error::kInvalidArguments; |
15337 } | 15521 } |
15338 DoBindFragmentInputLocationCHROMIUM(program, location, name_str.c_str()); | 15522 DoBindFragmentInputLocationCHROMIUM(program, location, name_str); |
15339 return error::kNoError; | 15523 return error::kNoError; |
15340 } | 15524 } |
15341 | 15525 |
15342 error::Error GLES2DecoderImpl::HandleProgramPathFragmentInputGenCHROMIUM( | 15526 error::Error GLES2DecoderImpl::HandleProgramPathFragmentInputGenCHROMIUM( |
15343 uint32 immediate_data_size, | 15527 uint32 immediate_data_size, |
15344 const void* cmd_data) { | 15528 const void* cmd_data) { |
15345 static const char kFunctionName[] = "glProgramPathFragmentInputGenCHROMIUM"; | 15529 static const char kFunctionName[] = "glProgramPathFragmentInputGenCHROMIUM"; |
15346 const gles2::cmds::ProgramPathFragmentInputGenCHROMIUM& c = | 15530 const gles2::cmds::ProgramPathFragmentInputGenCHROMIUM& c = |
15347 *static_cast<const gles2::cmds::ProgramPathFragmentInputGenCHROMIUM*>( | 15531 *static_cast<const gles2::cmds::ProgramPathFragmentInputGenCHROMIUM*>( |
15348 cmd_data); | 15532 cmd_data); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15444 return error::kNoError; | 15628 return error::kNoError; |
15445 } | 15629 } |
15446 | 15630 |
15447 // Include the auto-generated part of this file. We split this because it means | 15631 // Include the auto-generated part of this file. We split this because it means |
15448 // we can easily edit the non-auto generated parts right here in this file | 15632 // we can easily edit the non-auto generated parts right here in this file |
15449 // instead of having to edit some template or the code generator. | 15633 // instead of having to edit some template or the code generator. |
15450 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 15634 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
15451 | 15635 |
15452 } // namespace gles2 | 15636 } // namespace gles2 |
15453 } // namespace gpu | 15637 } // namespace gpu |
OLD | NEW |