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