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

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

Issue 2435803004: Initialize buffers before allowing access to them. (Closed)
Patch Set: win failure Created 4 years, 2 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
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/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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698