Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 12494005: Use client side arrays for GL_STREAM_DRAW attributes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/feature_info_unittest.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698