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 <list> | 10 #include <list> |
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1226 void DoGetFramebufferAttachmentParameteriv( | 1226 void DoGetFramebufferAttachmentParameteriv( |
1227 GLenum target, GLenum attachment, GLenum pname, GLint* params); | 1227 GLenum target, GLenum attachment, GLenum pname, GLint* params); |
1228 | 1228 |
1229 // Wrapper for glGetIntegerv. | 1229 // Wrapper for glGetIntegerv. |
1230 void DoGetIntegerv(GLenum pname, GLint* params); | 1230 void DoGetIntegerv(GLenum pname, GLint* params); |
1231 | 1231 |
1232 // Gets the max value in a range in a buffer. | 1232 // Gets the max value in a range in a buffer. |
1233 GLuint DoGetMaxValueInBufferCHROMIUM( | 1233 GLuint DoGetMaxValueInBufferCHROMIUM( |
1234 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); | 1234 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); |
1235 | 1235 |
1236 // Wrapper for glGetBufferParameteriv. | |
1237 void DoGetBufferParameteriv( | |
1238 GLenum target, GLenum pname, GLint* params); | |
1239 | |
1240 // Wrapper for glGetProgramiv. | 1236 // Wrapper for glGetProgramiv. |
1241 void DoGetProgramiv( | 1237 void DoGetProgramiv( |
1242 GLuint program_id, GLenum pname, GLint* params); | 1238 GLuint program_id, GLenum pname, GLint* params); |
1243 | 1239 |
1244 // Wrapper for glRenderbufferParameteriv. | 1240 // Wrapper for glRenderbufferParameteriv. |
1245 void DoGetRenderbufferParameteriv( | 1241 void DoGetRenderbufferParameteriv( |
1246 GLenum target, GLenum pname, GLint* params); | 1242 GLenum target, GLenum pname, GLint* params); |
1247 | 1243 |
1248 // Wrapper for glGetShaderiv | 1244 // Wrapper for glGetShaderiv |
1249 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params); | 1245 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params); |
(...skipping 3060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4310 void GLES2DecoderImpl::DoGetProgramiv( | 4306 void GLES2DecoderImpl::DoGetProgramiv( |
4311 GLuint program_id, GLenum pname, GLint* params) { | 4307 GLuint program_id, GLenum pname, GLint* params) { |
4312 Program* info = GetProgramInfoNotShader( | 4308 Program* info = GetProgramInfoNotShader( |
4313 program_id, "glGetProgramiv"); | 4309 program_id, "glGetProgramiv"); |
4314 if (!info) { | 4310 if (!info) { |
4315 return; | 4311 return; |
4316 } | 4312 } |
4317 info->GetProgramiv(pname, params); | 4313 info->GetProgramiv(pname, params); |
4318 } | 4314 } |
4319 | 4315 |
4320 void GLES2DecoderImpl::DoGetBufferParameteriv( | |
4321 GLenum target, GLenum pname, GLint* params) { | |
4322 Buffer* buffer = GetBufferInfoForTarget(target); | |
4323 if (!buffer) { | |
4324 return; | |
4325 } | |
4326 switch (pname) { | |
4327 case GL_BUFFER_SIZE: | |
4328 *params = buffer->size(); | |
4329 break; | |
4330 case GL_BUFFER_USAGE: | |
4331 *params = buffer->usage(); | |
4332 break; | |
4333 default: | |
4334 NOTREACHED(); | |
4335 } | |
4336 } | |
4337 | |
4338 void GLES2DecoderImpl::DoBindAttribLocation( | 4316 void GLES2DecoderImpl::DoBindAttribLocation( |
4339 GLuint program, GLuint index, const char* name) { | 4317 GLuint program, GLuint index, const char* name) { |
4340 if (!StringIsValidForGLES(name)) { | 4318 if (!StringIsValidForGLES(name)) { |
4341 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); | 4319 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); |
4342 return; | 4320 return; |
4343 } | 4321 } |
4344 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { | 4322 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { |
4345 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); | 4323 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); |
4346 return; | 4324 return; |
4347 } | 4325 } |
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5752 // it could never be invalid since glUseProgram would have failed. While | 5730 // it could never be invalid since glUseProgram would have failed. While |
5753 // glLinkProgram could later mark the program as invalid the previous | 5731 // glLinkProgram could later mark the program as invalid the previous |
5754 // valid program will still function if it is still the current program. | 5732 // valid program will still function if it is still the current program. |
5755 if (!state_.current_program) { | 5733 if (!state_.current_program) { |
5756 // The program does not exist. | 5734 // The program does not exist. |
5757 // But GL says no ERROR. | 5735 // But GL says no ERROR. |
5758 RenderWarning("Drawing with no current shader program."); | 5736 RenderWarning("Drawing with no current shader program."); |
5759 return false; | 5737 return false; |
5760 } | 5738 } |
5761 | 5739 |
5762 return state_.vertex_attrib_manager->ValidateBindings( | 5740 // true if any enabled, used divisor is zero |
5763 function_name, | 5741 bool divisor0 = false; |
5764 this, | 5742 // Validate all attribs currently enabled. If they are used by the current |
5765 feature_info_.get(), | 5743 // program then check that they have enough elements to handle the draw call. |
5766 state_.current_program, | 5744 // If they are not used by the current program check that they have a buffer |
5767 max_vertex_accessed, | 5745 // assigned. |
5768 primcount); | 5746 const VertexAttribManager::VertexAttribInfoList& infos = |
| 5747 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos(); |
| 5748 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = |
| 5749 infos.begin(); it != infos.end(); ++it) { |
| 5750 const VertexAttrib* info = *it; |
| 5751 const Program::VertexAttrib* attrib_info = |
| 5752 state_.current_program->GetAttribInfoByLocation(info->index()); |
| 5753 if (attrib_info) { |
| 5754 divisor0 |= (info->divisor() == 0); |
| 5755 GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed); |
| 5756 // This attrib is used in the current program. |
| 5757 if (!info->CanAccess(count)) { |
| 5758 SetGLError( |
| 5759 GL_INVALID_OPERATION, function_name, |
| 5760 (std::string( |
| 5761 "attempt to access out of range vertices in attribute ") + |
| 5762 base::IntToString(info->index())).c_str()); |
| 5763 return false; |
| 5764 } |
| 5765 } else { |
| 5766 // This attrib is not used in the current program. |
| 5767 if (!info->buffer()) { |
| 5768 SetGLError( |
| 5769 GL_INVALID_OPERATION, function_name, |
| 5770 (std::string( |
| 5771 "attempt to render with no buffer attached to " |
| 5772 "enabled attribute ") + |
| 5773 base::IntToString(info->index())).c_str()); |
| 5774 return false; |
| 5775 } |
| 5776 } |
| 5777 } |
| 5778 |
| 5779 if (primcount && !divisor0) { |
| 5780 SetGLError( |
| 5781 GL_INVALID_OPERATION, function_name, |
| 5782 "attempt instanced render with all attributes having " |
| 5783 "non-zero divisors"); |
| 5784 return false; |
| 5785 } |
| 5786 |
| 5787 return true; |
5769 } | 5788 } |
5770 | 5789 |
5771 bool GLES2DecoderImpl::SimulateAttrib0( | 5790 bool GLES2DecoderImpl::SimulateAttrib0( |
5772 const char* function_name, GLuint max_vertex_accessed, bool* simulated) { | 5791 const char* function_name, GLuint max_vertex_accessed, bool* simulated) { |
5773 DCHECK(simulated); | 5792 DCHECK(simulated); |
5774 *simulated = false; | 5793 *simulated = false; |
5775 | 5794 |
5776 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) | 5795 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) |
5777 return true; | 5796 return true; |
5778 | 5797 |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6119 | 6138 |
6120 if (!CheckBoundFramebuffersValid(function_name)) { | 6139 if (!CheckBoundFramebuffersValid(function_name)) { |
6121 return error::kNoError; | 6140 return error::kNoError; |
6122 } | 6141 } |
6123 | 6142 |
6124 if (count == 0 || (instanced && primcount == 0)) { | 6143 if (count == 0 || (instanced && primcount == 0)) { |
6125 return error::kNoError; | 6144 return error::kNoError; |
6126 } | 6145 } |
6127 | 6146 |
6128 GLuint max_vertex_accessed; | 6147 GLuint max_vertex_accessed; |
6129 Buffer* element_array_buffer = | 6148 if (!state_.vertex_attrib_manager->element_array_buffer()-> |
6130 state_.vertex_attrib_manager->element_array_buffer(); | 6149 GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) { |
6131 | |
6132 if (!element_array_buffer->GetMaxValueForRange( | |
6133 offset, count, type, &max_vertex_accessed)) { | |
6134 SetGLError(GL_INVALID_OPERATION, | 6150 SetGLError(GL_INVALID_OPERATION, |
6135 function_name, "range out of bounds for buffer"); | 6151 function_name, "range out of bounds for buffer"); |
6136 return error::kNoError; | 6152 return error::kNoError; |
6137 } | 6153 } |
6138 | 6154 |
6139 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { | 6155 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { |
6140 if (!ClearUnclearedTextures()) { | 6156 if (!ClearUnclearedTextures()) { |
6141 SetGLError(GL_INVALID_VALUE, function_name, "out of memory"); | 6157 SetGLError(GL_INVALID_VALUE, function_name, "out of memory"); |
6142 return error::kNoError; | 6158 return error::kNoError; |
6143 } | 6159 } |
6144 bool simulated_attrib_0 = false; | 6160 bool simulated_attrib_0 = false; |
6145 if (!SimulateAttrib0( | 6161 if (!SimulateAttrib0( |
6146 function_name, max_vertex_accessed, &simulated_attrib_0)) { | 6162 function_name, max_vertex_accessed, &simulated_attrib_0)) { |
6147 return error::kNoError; | 6163 return error::kNoError; |
6148 } | 6164 } |
6149 bool simulated_fixed_attribs = false; | 6165 bool simulated_fixed_attribs = false; |
6150 if (SimulateFixedAttribs( | 6166 if (SimulateFixedAttribs( |
6151 function_name, max_vertex_accessed, &simulated_fixed_attribs, | 6167 function_name, max_vertex_accessed, &simulated_fixed_attribs, |
6152 primcount)) { | 6168 primcount)) { |
6153 bool textures_set = SetBlackTextureForNonRenderableTextures(); | 6169 bool textures_set = SetBlackTextureForNonRenderableTextures(); |
6154 ApplyDirtyState(); | 6170 ApplyDirtyState(); |
6155 // TODO(gman): Refactor to hide these details in BufferManager or | |
6156 // VertexAttribManager. | |
6157 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 6171 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
6158 bool used_client_side_array = false; | |
6159 if (element_array_buffer->IsClientSideArray()) { | |
6160 used_client_side_array = true; | |
6161 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
6162 indices = element_array_buffer->GetRange(offset, 0); | |
6163 } | |
6164 | |
6165 if (!instanced) { | 6172 if (!instanced) { |
6166 glDrawElements(mode, count, type, indices); | 6173 glDrawElements(mode, count, type, indices); |
6167 } else { | 6174 } else { |
6168 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); | 6175 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); |
6169 } | 6176 } |
6170 | |
6171 if (used_client_side_array) { | |
6172 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, | |
6173 element_array_buffer->service_id()); | |
6174 } | |
6175 | |
6176 ProcessPendingQueries(); | 6177 ProcessPendingQueries(); |
6177 if (textures_set) { | 6178 if (textures_set) { |
6178 RestoreStateForNonRenderableTextures(); | 6179 RestoreStateForNonRenderableTextures(); |
6179 } | 6180 } |
6180 if (simulated_fixed_attribs) { | 6181 if (simulated_fixed_attribs) { |
6181 RestoreStateForSimulatedFixedAttribs(); | 6182 RestoreStateForSimulatedFixedAttribs(); |
6182 } | 6183 } |
6183 } | 6184 } |
6184 if (simulated_attrib_0) { | 6185 if (simulated_attrib_0) { |
6185 RestoreStateForAttrib(0); | 6186 RestoreStateForAttrib(0); |
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7183 return; | 7184 return; |
7184 } | 7185 } |
7185 if (!validators_->buffer_usage.IsValid(usage)) { | 7186 if (!validators_->buffer_usage.IsValid(usage)) { |
7186 SetGLErrorInvalidEnum("glBufferData", usage, "usage"); | 7187 SetGLErrorInvalidEnum("glBufferData", usage, "usage"); |
7187 return; | 7188 return; |
7188 } | 7189 } |
7189 if (size < 0) { | 7190 if (size < 0) { |
7190 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 7191 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); |
7191 return; | 7192 return; |
7192 } | 7193 } |
7193 Buffer* buffer = GetBufferInfoForTarget(target); | 7194 Buffer* info = GetBufferInfoForTarget(target); |
7194 if (!buffer) { | 7195 if (!info) { |
7195 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); | 7196 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); |
7196 return; | 7197 return; |
7197 } | 7198 } |
7198 | 7199 |
7199 if (!EnsureGPUMemoryAvailable(size)) { | 7200 if (!EnsureGPUMemoryAvailable(size)) { |
7200 SetGLError(GL_OUT_OF_MEMORY, "glBufferData", "out of memory"); | 7201 SetGLError(GL_OUT_OF_MEMORY, "glBufferData", "out of memory"); |
7201 return; | 7202 return; |
7202 } | 7203 } |
7203 | 7204 |
7204 buffer_manager()->DoBufferData(this, buffer, size, usage, data); | 7205 // Clear the buffer to 0 if no initial data was passed in. |
| 7206 scoped_array<int8> zero; |
| 7207 if (!data) { |
| 7208 zero.reset(new int8[size]); |
| 7209 memset(zero.get(), 0, size); |
| 7210 data = zero.get(); |
| 7211 } |
| 7212 |
| 7213 CopyRealGLErrorsToWrapper(); |
| 7214 glBufferData(target, size, data, usage); |
| 7215 GLenum error = PeekGLError(); |
| 7216 if (error == GL_NO_ERROR) { |
| 7217 buffer_manager()->SetInfo(info, size, usage); |
| 7218 info->SetRange(0, size, data); |
| 7219 } else { |
| 7220 buffer_manager()->SetInfo(info, 0, usage); |
| 7221 } |
7205 } | 7222 } |
7206 | 7223 |
7207 error::Error GLES2DecoderImpl::HandleBufferData( | 7224 error::Error GLES2DecoderImpl::HandleBufferData( |
7208 uint32 immediate_data_size, const cmds::BufferData& c) { | 7225 uint32 immediate_data_size, const cmds::BufferData& c) { |
7209 GLenum target = static_cast<GLenum>(c.target); | 7226 GLenum target = static_cast<GLenum>(c.target); |
7210 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); | 7227 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); |
7211 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); | 7228 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); |
7212 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); | 7229 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); |
7213 GLenum usage = static_cast<GLenum>(c.usage); | 7230 GLenum usage = static_cast<GLenum>(c.usage); |
7214 const void* data = NULL; | 7231 const void* data = NULL; |
(...skipping 16 matching lines...) Expand all Loading... |
7231 if (!data) { | 7248 if (!data) { |
7232 return error::kOutOfBounds; | 7249 return error::kOutOfBounds; |
7233 } | 7250 } |
7234 GLenum usage = static_cast<GLenum>(c.usage); | 7251 GLenum usage = static_cast<GLenum>(c.usage); |
7235 DoBufferData(target, size, data, usage); | 7252 DoBufferData(target, size, data, usage); |
7236 return error::kNoError; | 7253 return error::kNoError; |
7237 } | 7254 } |
7238 | 7255 |
7239 void GLES2DecoderImpl::DoBufferSubData( | 7256 void GLES2DecoderImpl::DoBufferSubData( |
7240 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { | 7257 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { |
7241 Buffer* buffer = GetBufferInfoForTarget(target); | 7258 Buffer* info = GetBufferInfoForTarget(target); |
7242 if (!buffer) { | 7259 if (!info) { |
7243 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); | 7260 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); |
7244 return; | 7261 return; |
7245 } | 7262 } |
7246 | 7263 if (!info->SetRange(offset, size, data)) { |
7247 buffer_manager()->DoBufferSubData(this, buffer, offset, size, data); | 7264 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); |
| 7265 return; |
| 7266 } |
| 7267 glBufferSubData(target, offset, size, data); |
7248 } | 7268 } |
7249 | 7269 |
7250 bool GLES2DecoderImpl::ClearLevel( | 7270 bool GLES2DecoderImpl::ClearLevel( |
7251 unsigned service_id, | 7271 unsigned service_id, |
7252 unsigned bind_target, | 7272 unsigned bind_target, |
7253 unsigned target, | 7273 unsigned target, |
7254 int level, | 7274 int level, |
7255 unsigned format, | 7275 unsigned format, |
7256 unsigned type, | 7276 unsigned type, |
7257 int width, | 7277 int width, |
(...skipping 2893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10151 return error::kNoError; | 10171 return error::kNoError; |
10152 } | 10172 } |
10153 | 10173 |
10154 // Include the auto-generated part of this file. We split this because it means | 10174 // Include the auto-generated part of this file. We split this because it means |
10155 // we can easily edit the non-auto generated parts right here in this file | 10175 // we can easily edit the non-auto generated parts right here in this file |
10156 // instead of having to edit some template or the code generator. | 10176 // instead of having to edit some template or the code generator. |
10157 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10177 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
10158 | 10178 |
10159 } // namespace gles2 | 10179 } // namespace gles2 |
10160 } // namespace gpu | 10180 } // namespace gpu |
OLD | NEW |