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/vertex_attrib_manager.h" | 5 #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <list> | 9 #include <list> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/stringprintf.h" | |
14 #include "build/build_config.h" | 13 #include "build/build_config.h" |
15 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 14 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
16 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 15 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
17 #include "gpu/command_buffer/service/buffer_manager.h" | 16 #include "gpu/command_buffer/service/buffer_manager.h" |
18 #include "gpu/command_buffer/service/error_state.h" | 17 #include "gpu/command_buffer/service/error_state.h" |
19 #include "gpu/command_buffer/service/feature_info.h" | 18 #include "gpu/command_buffer/service/feature_info.h" |
20 #include "gpu/command_buffer/service/gl_utils.h" | 19 #include "gpu/command_buffer/service/gl_utils.h" |
21 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 20 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
22 #include "gpu/command_buffer/service/gpu_switches.h" | 21 #include "gpu/command_buffer/service/gpu_switches.h" |
23 #include "gpu/command_buffer/service/program_manager.h" | 22 #include "gpu/command_buffer/service/program_manager.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 if (buffer_.get() == buffer) { | 69 if (buffer_.get() == buffer) { |
71 buffer_ = NULL; | 70 buffer_ = NULL; |
72 } | 71 } |
73 } | 72 } |
74 | 73 |
75 bool VertexAttrib::CanAccess(GLuint index) const { | 74 bool VertexAttrib::CanAccess(GLuint index) const { |
76 if (!enabled_) { | 75 if (!enabled_) { |
77 return true; | 76 return true; |
78 } | 77 } |
79 | 78 |
80 DCHECK(buffer_.get() && !buffer_->IsDeleted()); | 79 if (!buffer_.get() || buffer_->IsDeleted()) { |
| 80 return false; |
| 81 } |
| 82 |
81 // The number of elements that can be accessed. | 83 // The number of elements that can be accessed. |
82 GLsizeiptr buffer_size = buffer_->size(); | 84 GLsizeiptr buffer_size = buffer_->size(); |
83 if (offset_ > buffer_size || real_stride_ == 0) { | 85 if (offset_ > buffer_size || real_stride_ == 0) { |
84 return false; | 86 return false; |
85 } | 87 } |
86 | 88 |
87 uint32_t usable_size = buffer_size - offset_; | 89 uint32_t usable_size = buffer_size - offset_; |
88 GLuint num_elements = usable_size / real_stride_ + | 90 GLuint num_elements = usable_size / real_stride_ + |
89 ((usable_size % real_stride_) >= | 91 ((usable_size % real_stride_) >= |
90 (GLES2Util::GetGroupSizeForBufferType(size_, type_)) ? 1 : 0); | 92 (GLES2Util::GetGroupSizeForBufferType(size_, type_)) ? 1 : 0); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 175 } |
174 for (uint32_t vv = 0; vv < vertex_attribs_.size(); ++vv) { | 176 for (uint32_t vv = 0; vv < vertex_attribs_.size(); ++vv) { |
175 vertex_attribs_[vv].Unbind(buffer); | 177 vertex_attribs_[vv].Unbind(buffer); |
176 } | 178 } |
177 } | 179 } |
178 | 180 |
179 bool VertexAttribManager::ValidateBindings( | 181 bool VertexAttribManager::ValidateBindings( |
180 const char* function_name, | 182 const char* function_name, |
181 GLES2Decoder* decoder, | 183 GLES2Decoder* decoder, |
182 FeatureInfo* feature_info, | 184 FeatureInfo* feature_info, |
183 BufferManager* buffer_manager, | |
184 Program* current_program, | 185 Program* current_program, |
185 GLuint max_vertex_accessed, | 186 GLuint max_vertex_accessed, |
186 bool instanced, | 187 bool instanced, |
187 GLsizei primcount) { | 188 GLsizei primcount) { |
188 DCHECK(primcount); | 189 DCHECK(primcount); |
189 ErrorState* error_state = decoder->GetErrorState(); | 190 ErrorState* error_state = decoder->GetErrorState(); |
190 // true if any enabled, used divisor is zero | 191 // true if any enabled, used divisor is zero |
191 bool divisor0 = false; | 192 bool divisor0 = false; |
192 bool have_enabled_active_attribs = false; | 193 bool have_enabled_active_attribs = false; |
193 const GLuint kInitialBufferId = 0xFFFFFFFFU; | 194 const GLuint kInitialBufferId = 0xFFFFFFFFU; |
194 GLuint current_buffer_id = kInitialBufferId; | 195 GLuint current_buffer_id = kInitialBufferId; |
195 bool use_client_side_arrays_for_stream_buffers = feature_info->workarounds( | 196 bool use_client_side_arrays_for_stream_buffers = feature_info->workarounds( |
196 ).use_client_side_arrays_for_stream_buffers; | 197 ).use_client_side_arrays_for_stream_buffers; |
197 // Validate all attribs currently enabled. If they are used by the current | 198 // Validate all attribs currently enabled. If they are used by the current |
198 // program then check that they have enough elements to handle the draw call. | 199 // program then check that they have enough elements to handle the draw call. |
199 // If they are not used by the current program check that they have a buffer | 200 // If they are not used by the current program check that they have a buffer |
200 // assigned. | 201 // assigned. |
201 for (VertexAttribList::iterator it = enabled_vertex_attribs_.begin(); | 202 for (VertexAttribList::iterator it = enabled_vertex_attribs_.begin(); |
202 it != enabled_vertex_attribs_.end(); ++it) { | 203 it != enabled_vertex_attribs_.end(); ++it) { |
203 VertexAttrib* attrib = *it; | 204 VertexAttrib* attrib = *it; |
204 Buffer* buffer = attrib->buffer(); | |
205 std::string msg_tag = base::StringPrintf( | |
206 "attached to enabled attrib %u", attrib->index()); | |
207 if (!buffer_manager->RequestBufferAccess( | |
208 error_state, buffer, function_name, msg_tag.c_str())) { | |
209 return false; | |
210 } | |
211 const Program::VertexAttrib* attrib_info = | 205 const Program::VertexAttrib* attrib_info = |
212 current_program->GetAttribInfoByLocation(attrib->index()); | 206 current_program->GetAttribInfoByLocation(attrib->index()); |
213 if (attrib_info) { | 207 if (attrib_info) { |
214 divisor0 |= (attrib->divisor() == 0); | 208 divisor0 |= (attrib->divisor() == 0); |
215 have_enabled_active_attribs = true; | 209 have_enabled_active_attribs = true; |
216 GLuint count = attrib->MaxVertexAccessed(primcount, max_vertex_accessed); | 210 GLuint count = attrib->MaxVertexAccessed(primcount, max_vertex_accessed); |
217 // This attrib is used in the current program. | 211 // This attrib is used in the current program. |
218 if (!attrib->CanAccess(count)) { | 212 if (!attrib->CanAccess(count)) { |
219 ERRORSTATE_SET_GL_ERROR( | 213 ERRORSTATE_SET_GL_ERROR( |
220 error_state, GL_INVALID_OPERATION, function_name, | 214 error_state, GL_INVALID_OPERATION, function_name, |
221 (std::string( | 215 (std::string( |
222 "attempt to access out of range vertices in attribute ") + | 216 "attempt to access out of range vertices in attribute ") + |
223 base::UintToString(attrib->index())).c_str()); | 217 base::UintToString(attrib->index())).c_str()); |
224 return false; | 218 return false; |
225 } | 219 } |
226 if (use_client_side_arrays_for_stream_buffers) { | 220 if (use_client_side_arrays_for_stream_buffers) { |
| 221 Buffer* buffer = attrib->buffer(); |
227 glEnableVertexAttribArray(attrib->index()); | 222 glEnableVertexAttribArray(attrib->index()); |
228 if (buffer->IsClientSideArray()) { | 223 if (buffer->IsClientSideArray()) { |
229 if (current_buffer_id != 0) { | 224 if (current_buffer_id != 0) { |
230 current_buffer_id = 0; | 225 current_buffer_id = 0; |
231 glBindBuffer(GL_ARRAY_BUFFER, 0); | 226 glBindBuffer(GL_ARRAY_BUFFER, 0); |
232 } | 227 } |
233 attrib->set_is_client_side_array(true); | 228 attrib->set_is_client_side_array(true); |
234 const void* ptr = buffer->GetRange(attrib->offset(), 0); | 229 const void* ptr = buffer->GetRange(attrib->offset(), 0); |
235 DCHECK(ptr); | 230 DCHECK(ptr); |
236 glVertexAttribPointer( | 231 glVertexAttribPointer( |
(...skipping 15 matching lines...) Expand all Loading... |
252 attrib->index(), | 247 attrib->index(), |
253 attrib->size(), | 248 attrib->size(), |
254 attrib->type(), | 249 attrib->type(), |
255 attrib->normalized(), | 250 attrib->normalized(), |
256 attrib->gl_stride(), | 251 attrib->gl_stride(), |
257 ptr); | 252 ptr); |
258 } | 253 } |
259 } | 254 } |
260 } else { | 255 } else { |
261 // This attrib is not used in the current program. | 256 // This attrib is not used in the current program. |
262 if (use_client_side_arrays_for_stream_buffers) { | 257 if (!attrib->buffer()) { |
| 258 ERRORSTATE_SET_GL_ERROR( |
| 259 error_state, GL_INVALID_OPERATION, function_name, |
| 260 (std::string( |
| 261 "attempt to render with no buffer attached to " |
| 262 "enabled attribute ") + |
| 263 base::UintToString(attrib->index())).c_str()); |
| 264 return false; |
| 265 } else if (use_client_side_arrays_for_stream_buffers) { |
| 266 Buffer* buffer = attrib->buffer(); |
263 // Disable client side arrays for unused attributes else we'll | 267 // Disable client side arrays for unused attributes else we'll |
264 // read bad memory | 268 // read bad memory |
265 if (buffer->IsClientSideArray()) { | 269 if (buffer->IsClientSideArray()) { |
266 // Don't disable attrib 0 since it's special. | 270 // Don't disable attrib 0 since it's special. |
267 if (attrib->index() > 0) { | 271 if (attrib->index() > 0) { |
268 glDisableVertexAttribArray(attrib->index()); | 272 glDisableVertexAttribArray(attrib->index()); |
269 } | 273 } |
270 } | 274 } |
271 } | 275 } |
272 } | 276 } |
(...skipping 13 matching lines...) Expand all Loading... |
286 if (current_buffer_id != kInitialBufferId) { | 290 if (current_buffer_id != kInitialBufferId) { |
287 // Restore the buffer binding. | 291 // Restore the buffer binding. |
288 decoder->RestoreBufferBindings(); | 292 decoder->RestoreBufferBindings(); |
289 } | 293 } |
290 | 294 |
291 return true; | 295 return true; |
292 } | 296 } |
293 | 297 |
294 } // namespace gles2 | 298 } // namespace gles2 |
295 } // namespace gpu | 299 } // namespace gpu |
OLD | NEW |