| 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/program_manager.h" | 5 #include "gpu/command_buffer/service/program_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
| 7 #include <algorithm> | 10 #include <algorithm> |
| 8 #include <set> | 11 #include <set> |
| 9 #include <utility> | 12 #include <utility> |
| 10 #include <vector> | 13 #include <vector> |
| 11 | 14 |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 14 #include "base/containers/hash_tables.h" | 16 #include "base/containers/hash_tables.h" |
| 15 #include "base/logging.h" | 17 #include "base/logging.h" |
| 16 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/metrics/histogram.h" | 19 #include "base/metrics/histogram.h" |
| 18 #include "base/numerics/safe_math.h" | 20 #include "base/numerics/safe_math.h" |
| 19 #include "base/strings/string_number_conversions.h" | 21 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 21 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
| 22 #include "base/time/time.h" | 24 #include "base/time/time.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // Look for an array specification. | 68 // Look for an array specification. |
| 67 size_t open_pos = name.find_last_of('['); | 69 size_t open_pos = name.find_last_of('['); |
| 68 if (open_pos == std::string::npos || | 70 if (open_pos == std::string::npos || |
| 69 open_pos >= name.size() - 2) { | 71 open_pos >= name.size() - 2) { |
| 70 return false; | 72 return false; |
| 71 } | 73 } |
| 72 | 74 |
| 73 base::CheckedNumeric<GLint> index = 0; | 75 base::CheckedNumeric<GLint> index = 0; |
| 74 size_t last = name.size() - 1; | 76 size_t last = name.size() - 1; |
| 75 for (size_t pos = open_pos + 1; pos < last; ++pos) { | 77 for (size_t pos = open_pos + 1; pos < last; ++pos) { |
| 76 int8 digit = name[pos] - '0'; | 78 int8_t digit = name[pos] - '0'; |
| 77 if (digit < 0 || digit > 9) { | 79 if (digit < 0 || digit > 9) { |
| 78 return false; | 80 return false; |
| 79 } | 81 } |
| 80 index = index * 10 + digit; | 82 index = index * 10 + digit; |
| 81 } | 83 } |
| 82 if (!index.IsValid()) { | 84 if (!index.IsValid()) { |
| 83 return false; | 85 return false; |
| 84 } | 86 } |
| 85 | 87 |
| 86 *element_index = index.ValueOrDie(); | 88 *element_index = index.ValueOrDie(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 103 } | 105 } |
| 104 | 106 |
| 105 bool IsBuiltInInvariant( | 107 bool IsBuiltInInvariant( |
| 106 const VaryingMap& varyings, const std::string& name) { | 108 const VaryingMap& varyings, const std::string& name) { |
| 107 VaryingMap::const_iterator hit = varyings.find(name); | 109 VaryingMap::const_iterator hit = varyings.find(name); |
| 108 if (hit == varyings.end()) | 110 if (hit == varyings.end()) |
| 109 return false; | 111 return false; |
| 110 return hit->second.isInvariant; | 112 return hit->second.isInvariant; |
| 111 } | 113 } |
| 112 | 114 |
| 113 uint32 ComputeOffset(const void* start, const void* position) { | 115 uint32_t ComputeOffset(const void* start, const void* position) { |
| 114 return static_cast<const uint8*>(position) - | 116 return static_cast<const uint8_t*>(position) - |
| 115 static_cast<const uint8*>(start); | 117 static_cast<const uint8_t*>(start); |
| 116 } | 118 } |
| 117 | 119 |
| 118 } // anonymous namespace. | 120 } // anonymous namespace. |
| 119 | 121 |
| 120 Program::UniformInfo::UniformInfo() | 122 Program::UniformInfo::UniformInfo() |
| 121 : size(0), | 123 : size(0), |
| 122 type(GL_NONE), | 124 type(GL_NONE), |
| 123 accepts_api_type(0), | 125 accepts_api_type(0), |
| 124 fake_location_base(0), | 126 fake_location_base(0), |
| 125 is_array(false) {} | 127 is_array(false) {} |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 } | 318 } |
| 317 scoped_ptr<char[]> temp(new char[max_len]); | 319 scoped_ptr<char[]> temp(new char[max_len]); |
| 318 GLint len = 0; | 320 GLint len = 0; |
| 319 glGetProgramInfoLog(service_id_, max_len, &len, temp.get()); | 321 glGetProgramInfoLog(service_id_, max_len, &len, temp.get()); |
| 320 DCHECK(max_len == 0 || len < max_len); | 322 DCHECK(max_len == 0 || len < max_len); |
| 321 DCHECK(len == 0 || temp[len] == '\0'); | 323 DCHECK(len == 0 || temp[len] == '\0'); |
| 322 std::string log(temp.get(), len); | 324 std::string log(temp.get(), len); |
| 323 set_log_info(ProcessLogInfo(log).c_str()); | 325 set_log_info(ProcessLogInfo(log).c_str()); |
| 324 } | 326 } |
| 325 | 327 |
| 326 void Program::ClearUniforms( | 328 void Program::ClearUniforms(std::vector<uint8_t>* zero_buffer) { |
| 327 std::vector<uint8>* zero_buffer) { | |
| 328 DCHECK(zero_buffer); | 329 DCHECK(zero_buffer); |
| 329 if (uniforms_cleared_) { | 330 if (uniforms_cleared_) { |
| 330 return; | 331 return; |
| 331 } | 332 } |
| 332 uniforms_cleared_ = true; | 333 uniforms_cleared_ = true; |
| 333 for (const UniformInfo& uniform_info : uniform_infos_) { | 334 for (const UniformInfo& uniform_info : uniform_infos_) { |
| 334 GLint location = uniform_info.element_locations[0]; | 335 GLint location = uniform_info.element_locations[0]; |
| 335 GLsizei size = uniform_info.size; | 336 GLsizei size = uniform_info.size; |
| 336 uint32 unit_size = | 337 uint32_t unit_size = |
| 337 GLES2Util::GetElementCountForUniformType(uniform_info.type) * | 338 GLES2Util::GetElementCountForUniformType(uniform_info.type) * |
| 338 GLES2Util::GetElementSizeForUniformType(uniform_info.type); | 339 GLES2Util::GetElementSizeForUniformType(uniform_info.type); |
| 339 DCHECK_LT(0u, unit_size); | 340 DCHECK_LT(0u, unit_size); |
| 340 uint32 size_needed = size * unit_size; | 341 uint32_t size_needed = size * unit_size; |
| 341 if (size_needed > zero_buffer->size()) { | 342 if (size_needed > zero_buffer->size()) { |
| 342 zero_buffer->resize(size_needed, 0u); | 343 zero_buffer->resize(size_needed, 0u); |
| 343 } | 344 } |
| 344 const void* zero = &(*zero_buffer)[0]; | 345 const void* zero = &(*zero_buffer)[0]; |
| 345 switch (uniform_info.type) { | 346 switch (uniform_info.type) { |
| 346 case GL_FLOAT: | 347 case GL_FLOAT: |
| 347 glUniform1fv(location, size, reinterpret_cast<const GLfloat*>(zero)); | 348 glUniform1fv(location, size, reinterpret_cast<const GLfloat*>(zero)); |
| 348 break; | 349 break; |
| 349 case GL_FLOAT_VEC2: | 350 case GL_FLOAT_VEC2: |
| 350 glUniform2fv(location, size, reinterpret_cast<const GLfloat*>(zero)); | 351 glUniform2fv(location, size, reinterpret_cast<const GLfloat*>(zero)); |
| (...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 variables.get(), | 1827 variables.get(), |
| 1827 combined_map.size()); | 1828 combined_map.size()); |
| 1828 } | 1829 } |
| 1829 | 1830 |
| 1830 void Program::GetProgramInfo( | 1831 void Program::GetProgramInfo( |
| 1831 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { | 1832 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { |
| 1832 // NOTE: It seems to me the math in here does not need check for overflow | 1833 // NOTE: It seems to me the math in here does not need check for overflow |
| 1833 // because the data being calucated from has various small limits. The max | 1834 // because the data being calucated from has various small limits. The max |
| 1834 // number of attribs + uniforms is somewhere well under 1024. The maximum size | 1835 // number of attribs + uniforms is somewhere well under 1024. The maximum size |
| 1835 // of an identifier is 256 characters. | 1836 // of an identifier is 256 characters. |
| 1836 uint32 num_locations = 0; | 1837 uint32_t num_locations = 0; |
| 1837 uint32 total_string_size = 0; | 1838 uint32_t total_string_size = 0; |
| 1838 | 1839 |
| 1839 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1840 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
| 1840 const VertexAttrib& info = attrib_infos_[ii]; | 1841 const VertexAttrib& info = attrib_infos_[ii]; |
| 1841 num_locations += 1; | 1842 num_locations += 1; |
| 1842 total_string_size += info.name.size(); | 1843 total_string_size += info.name.size(); |
| 1843 } | 1844 } |
| 1844 | 1845 |
| 1845 for (const UniformInfo& info : uniform_infos_) { | 1846 for (const UniformInfo& info : uniform_infos_) { |
| 1846 num_locations += info.element_locations.size(); | 1847 num_locations += info.element_locations.size(); |
| 1847 total_string_size += info.name.size(); | 1848 total_string_size += info.name.size(); |
| 1848 } | 1849 } |
| 1849 | 1850 |
| 1850 uint32 num_inputs = attrib_infos_.size() + uniform_infos_.size(); | 1851 uint32_t num_inputs = attrib_infos_.size() + uniform_infos_.size(); |
| 1851 uint32 input_size = num_inputs * sizeof(ProgramInput); | 1852 uint32_t input_size = num_inputs * sizeof(ProgramInput); |
| 1852 uint32 location_size = num_locations * sizeof(int32); | 1853 uint32_t location_size = num_locations * sizeof(int32_t); |
| 1853 uint32 size = sizeof(ProgramInfoHeader) + | 1854 uint32_t size = sizeof(ProgramInfoHeader) + input_size + location_size + |
| 1854 input_size + location_size + total_string_size; | 1855 total_string_size; |
| 1855 | 1856 |
| 1856 bucket->SetSize(size); | 1857 bucket->SetSize(size); |
| 1857 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); | 1858 ProgramInfoHeader* header = bucket->GetDataAs<ProgramInfoHeader*>(0, size); |
| 1858 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( | 1859 ProgramInput* inputs = bucket->GetDataAs<ProgramInput*>( |
| 1859 sizeof(ProgramInfoHeader), input_size); | 1860 sizeof(ProgramInfoHeader), input_size); |
| 1860 int32* locations = bucket->GetDataAs<int32*>( | 1861 int32_t* locations = bucket->GetDataAs<int32_t*>( |
| 1861 sizeof(ProgramInfoHeader) + input_size, location_size); | 1862 sizeof(ProgramInfoHeader) + input_size, location_size); |
| 1862 char* strings = bucket->GetDataAs<char*>( | 1863 char* strings = bucket->GetDataAs<char*>( |
| 1863 sizeof(ProgramInfoHeader) + input_size + location_size, | 1864 sizeof(ProgramInfoHeader) + input_size + location_size, |
| 1864 total_string_size); | 1865 total_string_size); |
| 1865 DCHECK(header); | 1866 DCHECK(header); |
| 1866 DCHECK(inputs); | 1867 DCHECK(inputs); |
| 1867 DCHECK(locations); | 1868 DCHECK(locations); |
| 1868 DCHECK(strings); | 1869 DCHECK(strings); |
| 1869 | 1870 |
| 1870 header->link_status = link_status_; | 1871 header->link_status = link_status_; |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2260 if (manager_) { | 2261 if (manager_) { |
| 2261 if (manager_->have_context_) { | 2262 if (manager_->have_context_) { |
| 2262 glDeleteProgram(service_id()); | 2263 glDeleteProgram(service_id()); |
| 2263 } | 2264 } |
| 2264 manager_->StopTracking(this); | 2265 manager_->StopTracking(this); |
| 2265 manager_ = NULL; | 2266 manager_ = NULL; |
| 2266 } | 2267 } |
| 2267 } | 2268 } |
| 2268 | 2269 |
| 2269 ProgramManager::ProgramManager(ProgramCache* program_cache, | 2270 ProgramManager::ProgramManager(ProgramCache* program_cache, |
| 2270 uint32 max_varying_vectors, | 2271 uint32_t max_varying_vectors, |
| 2271 uint32 max_dual_source_draw_buffers, | 2272 uint32_t max_dual_source_draw_buffers, |
| 2272 FeatureInfo* feature_info) | 2273 FeatureInfo* feature_info) |
| 2273 : program_count_(0), | 2274 : program_count_(0), |
| 2274 have_context_(true), | 2275 have_context_(true), |
| 2275 program_cache_(program_cache), | 2276 program_cache_(program_cache), |
| 2276 max_varying_vectors_(max_varying_vectors), | 2277 max_varying_vectors_(max_varying_vectors), |
| 2277 max_dual_source_draw_buffers_(max_dual_source_draw_buffers), | 2278 max_dual_source_draw_buffers_(max_dual_source_draw_buffers), |
| 2278 feature_info_(feature_info) {} | 2279 feature_info_(feature_info) {} |
| 2279 | 2280 |
| 2280 ProgramManager::~ProgramManager() { | 2281 ProgramManager::~ProgramManager() { |
| 2281 DCHECK(programs_.empty()); | 2282 DCHECK(programs_.empty()); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2376 DCHECK(IsOwned(program)); | 2377 DCHECK(IsOwned(program)); |
| 2377 program->DecUseCount(); | 2378 program->DecUseCount(); |
| 2378 RemoveProgramInfoIfUnused(shader_manager, program); | 2379 RemoveProgramInfoIfUnused(shader_manager, program); |
| 2379 } | 2380 } |
| 2380 | 2381 |
| 2381 void ProgramManager::ClearUniforms(Program* program) { | 2382 void ProgramManager::ClearUniforms(Program* program) { |
| 2382 DCHECK(program); | 2383 DCHECK(program); |
| 2383 program->ClearUniforms(&zero_); | 2384 program->ClearUniforms(&zero_); |
| 2384 } | 2385 } |
| 2385 | 2386 |
| 2386 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 2387 int32_t ProgramManager::MakeFakeLocation(int32_t index, int32_t element) { |
| 2387 return index + element * 0x10000; | 2388 return index + element * 0x10000; |
| 2388 } | 2389 } |
| 2389 | 2390 |
| 2390 } // namespace gles2 | 2391 } // namespace gles2 |
| 2391 } // namespace gpu | 2392 } // namespace gpu |
| OLD | NEW |