| 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 <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  Loading... | 
|  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 | 
| OLD | NEW |