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 |