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

Side by Side Diff: gpu/command_buffer/service/vertex_attrib_manager.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/vertex_attrib_manager.h" 5 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
6 6
7 #include <list> 7 #include <list>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/string_number_conversions.h"
12 #include "build/build_config.h" 13 #include "build/build_config.h"
13 #define GLES2_GPU_SERVICE 1 14 #define GLES2_GPU_SERVICE 1
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"
18 #include "gpu/command_buffer/service/feature_info.h"
17 #include "gpu/command_buffer/service/gl_utils.h" 19 #include "gpu/command_buffer/service/gl_utils.h"
20 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
18 #include "gpu/command_buffer/service/gpu_switches.h" 21 #include "gpu/command_buffer/service/gpu_switches.h"
22 #include "gpu/command_buffer/service/program_manager.h"
19 #include "gpu/command_buffer/service/vertex_array_manager.h" 23 #include "gpu/command_buffer/service/vertex_array_manager.h"
20 24
21 namespace gpu { 25 namespace gpu {
22 namespace gles2 { 26 namespace gles2 {
23 27
24 VertexAttrib::VertexAttrib() 28 VertexAttrib::VertexAttrib()
25 : index_(0), 29 : index_(0),
26 enabled_(false), 30 enabled_(false),
27 size_(4), 31 size_(4),
28 type_(GL_FLOAT), 32 type_(GL_FLOAT),
29 offset_(0), 33 offset_(0),
30 normalized_(GL_FALSE), 34 normalized_(GL_FALSE),
31 gl_stride_(0), 35 gl_stride_(0),
32 real_stride_(16), 36 real_stride_(16),
33 divisor_(0), 37 divisor_(0),
38 is_client_side_array_(false),
34 list_(NULL) { 39 list_(NULL) {
35 } 40 }
36 41
37 VertexAttrib::~VertexAttrib() { 42 VertexAttrib::~VertexAttrib() {
38 } 43 }
39 44
40 void VertexAttrib::SetInfo( 45 void VertexAttrib::SetInfo(
41 Buffer* buffer, 46 Buffer* buffer,
42 GLint size, 47 GLint size,
43 GLenum type, 48 GLenum type,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 152
148 void VertexAttribManager::Unbind(Buffer* buffer) { 153 void VertexAttribManager::Unbind(Buffer* buffer) {
149 if (element_array_buffer_ == buffer) { 154 if (element_array_buffer_ == buffer) {
150 element_array_buffer_ = NULL; 155 element_array_buffer_ = NULL;
151 } 156 }
152 for (uint32 vv = 0; vv < vertex_attrib_infos_.size(); ++vv) { 157 for (uint32 vv = 0; vv < vertex_attrib_infos_.size(); ++vv) {
153 vertex_attrib_infos_[vv].Unbind(buffer); 158 vertex_attrib_infos_[vv].Unbind(buffer);
154 } 159 }
155 } 160 }
156 161
162 bool VertexAttribManager::ValidateBindings(
163 const char* function_name,
164 GLES2Decoder* decoder,
165 FeatureInfo* feature_info,
166 Program* current_program,
167 GLuint max_vertex_accessed,
168 GLsizei primcount) {
169 // true if any enabled, used divisor is zero
170 bool divisor0 = false;
171 const GLuint kInitialBufferId = 0xFFFFFFFFU;
172 GLuint current_buffer_id = kInitialBufferId;
173 bool use_client_side_arrays_for_stream_buffers = feature_info->workarounds(
174 ).use_client_side_arrays_for_stream_buffers;
175 // Validate all attribs currently enabled. If they are used by the current
176 // program then check that they have enough elements to handle the draw call.
177 // If they are not used by the current program check that they have a buffer
178 // assigned.
179 for (VertexAttribInfoList::iterator it = enabled_vertex_attribs_.begin();
180 it != enabled_vertex_attribs_.end(); ++it) {
181 VertexAttrib* attrib = *it;
182 const Program::VertexAttrib* attrib_info =
183 current_program->GetAttribInfoByLocation(attrib->index());
184 if (attrib_info) {
185 divisor0 |= (attrib->divisor() == 0);
186 GLuint count = attrib->MaxVertexAccessed(primcount, max_vertex_accessed);
187 // This attrib is used in the current program.
188 if (!attrib->CanAccess(count)) {
189 decoder->SetGLError(
190 GL_INVALID_OPERATION, function_name,
191 (std::string(
192 "attempt to access out of range vertices in attribute ") +
193 base::IntToString(attrib->index())).c_str());
194 return false;
195 }
196 if (use_client_side_arrays_for_stream_buffers) {
197 Buffer* buffer = attrib->buffer();
198 glEnableVertexAttribArray(attrib->index());
199 if (buffer->IsClientSideArray()) {
200 if (current_buffer_id != 0) {
201 current_buffer_id = 0;
202 glBindBuffer(GL_ARRAY_BUFFER, 0);
203 }
204 attrib->set_is_client_side_array(true);
205 const void* ptr = buffer->GetRange(attrib->offset(), 0);
206 DCHECK(ptr);
207 glVertexAttribPointer(
208 attrib->index(),
209 attrib->size(),
210 attrib->type(),
211 attrib->normalized(),
212 attrib->gl_stride(),
213 ptr);
214 } else if (attrib->is_client_side_array()) {
215 attrib->set_is_client_side_array(false);
216 GLuint new_buffer_id = buffer->service_id();
217 if (new_buffer_id != current_buffer_id) {
218 current_buffer_id = new_buffer_id;
219 glBindBuffer(GL_ARRAY_BUFFER, current_buffer_id);
220 }
221 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
222 glVertexAttribPointer(
223 attrib->index(),
224 attrib->size(),
225 attrib->type(),
226 attrib->normalized(),
227 attrib->gl_stride(),
228 ptr);
229 }
230 }
231 } else {
232 // This attrib is not used in the current program.
233 if (!attrib->buffer()) {
234 decoder->SetGLError(
235 GL_INVALID_OPERATION, function_name,
236 (std::string(
237 "attempt to render with no buffer attached to "
238 "enabled attribute ") +
239 base::IntToString(attrib->index())).c_str());
240 return false;
241 } else if (use_client_side_arrays_for_stream_buffers) {
242 Buffer* buffer = attrib->buffer();
243 // Disable client side arrays for unused attributes else we'll
244 // read bad memory
245 if (buffer->IsClientSideArray()) {
246 // Don't disable attrib 0 since it's special.
247 if (attrib->index() > 0) {
248 glDisableVertexAttribArray(attrib->index());
249 }
250 }
251 }
252 }
253 }
254
255 if (primcount && !divisor0) {
256 decoder->SetGLError(
257 GL_INVALID_OPERATION, function_name,
258 "attempt instanced render with all attributes having "
259 "non-zero divisors");
260 return false;
261 }
262
263 if (current_buffer_id != kInitialBufferId) {
264 // Restore the buffer binding.
265 decoder->RestoreBufferBindings();
266 }
267
268 return true;
269 }
270
157 } // namespace gles2 271 } // namespace gles2
158 } // namespace gpu 272 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/vertex_attrib_manager.h ('k') | gpu/command_buffer/service/vertex_attrib_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698