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