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

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

Issue 895853003: Update from https://crrev.com/314320 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 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/program_manager.h" 5 #include "gpu/command_buffer/service/program_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 100 }
101 101
102 bool IsBuiltInInvariant( 102 bool IsBuiltInInvariant(
103 const VaryingMap& varyings, const std::string& name) { 103 const VaryingMap& varyings, const std::string& name) {
104 VaryingMap::const_iterator hit = varyings.find(name); 104 VaryingMap::const_iterator hit = varyings.find(name);
105 if (hit == varyings.end()) 105 if (hit == varyings.end())
106 return false; 106 return false;
107 return hit->second.isInvariant; 107 return hit->second.isInvariant;
108 } 108 }
109 109
110 uint32 ComputeOffset(const void* start, const void* position) {
111 return static_cast<const uint8*>(position) -
112 static_cast<const uint8*>(start);
113 }
114
110 } // anonymous namespace. 115 } // anonymous namespace.
111 116
112 Program::UniformInfo::UniformInfo() 117 Program::UniformInfo::UniformInfo()
113 : size(0), 118 : size(0),
114 type(GL_NONE), 119 type(GL_NONE),
115 fake_location_base(0), 120 fake_location_base(0),
116 is_array(false) { 121 is_array(false) {
117 } 122 }
118 123
119 Program::UniformInfo::UniformInfo(GLsizei _size, 124 Program::UniformInfo::UniformInfo(GLsizei _size,
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 variables[index].type = iter->second.type; 1199 variables[index].type = iter->second.type;
1195 variables[index].size = iter->second.size; 1200 variables[index].size = iter->second.size;
1196 ++index; 1201 ++index;
1197 } 1202 }
1198 return ShCheckVariablesWithinPackingLimits( 1203 return ShCheckVariablesWithinPackingLimits(
1199 static_cast<int>(manager_->max_varying_vectors()), 1204 static_cast<int>(manager_->max_varying_vectors()),
1200 variables.get(), 1205 variables.get(),
1201 combined_map.size()); 1206 combined_map.size());
1202 } 1207 }
1203 1208
1204 static uint32 ComputeOffset(const void* start, const void* position) {
1205 return static_cast<const uint8*>(position) -
1206 static_cast<const uint8*>(start);
1207 }
1208
1209 void Program::GetProgramInfo( 1209 void Program::GetProgramInfo(
1210 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { 1210 ProgramManager* manager, CommonDecoder::Bucket* bucket) const {
1211 // NOTE: It seems to me the math in here does not need check for overflow 1211 // NOTE: It seems to me the math in here does not need check for overflow
1212 // because the data being calucated from has various small limits. The max 1212 // because the data being calucated from has various small limits. The max
1213 // number of attribs + uniforms is somewhere well under 1024. The maximum size 1213 // number of attribs + uniforms is somewhere well under 1024. The maximum size
1214 // of an identifier is 256 characters. 1214 // of an identifier is 256 characters.
1215 uint32 num_locations = 0; 1215 uint32 num_locations = 0;
1216 uint32 total_string_size = 0; 1216 uint32 total_string_size = 0;
1217 1217
1218 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { 1218 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 } 1283 }
1284 memcpy(strings, info.name.c_str(), info.name.size()); 1284 memcpy(strings, info.name.c_str(), info.name.size());
1285 strings += info.name.size(); 1285 strings += info.name.size();
1286 ++inputs; 1286 ++inputs;
1287 } 1287 }
1288 } 1288 }
1289 1289
1290 DCHECK_EQ(ComputeOffset(header, strings), size); 1290 DCHECK_EQ(ComputeOffset(header, strings), size);
1291 } 1291 }
1292 1292
1293 bool Program::GetUniformBlocks(CommonDecoder::Bucket* bucket) const {
1294 // The data is packed into the bucket in the following order
1295 // 1) header
1296 // 2) N entries of block data (except for name and indices)
1297 // 3) name1, indices1, name2, indices2, ..., nameN, indicesN
1298 //
1299 // We query all the data directly through GL calls, assuming they are
1300 // cheap through MANGLE.
1301
1302 DCHECK(bucket);
1303 GLuint program = service_id();
1304
1305 uint32_t header_size = sizeof(UniformBlocksHeader);
1306
1307 uint32_t num_uniform_blocks = 0;
1308 GLint param = GL_FALSE;
1309 // We assume program is a valid program service id.
1310 glGetProgramiv(program, GL_LINK_STATUS, &param);
1311 if (param == GL_TRUE) {
1312 param = 0;
1313 glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &param);
1314 num_uniform_blocks = static_cast<uint32_t>(param);
1315 }
1316 if (num_uniform_blocks == 0) {
1317 // Although spec allows an implementation to return uniform block info
1318 // even if a link fails, for consistency, we disallow that.
1319 bucket->SetSize(header_size);
1320 UniformBlocksHeader* header =
1321 bucket->GetDataAs<UniformBlocksHeader*>(0, header_size);
1322 header->num_uniform_blocks = 0;
1323 return true;
1324 }
1325
1326 std::vector<UniformBlockInfo> blocks(num_uniform_blocks);
1327 base::CheckedNumeric<uint32_t> size = sizeof(UniformBlockInfo);
1328 size *= num_uniform_blocks;
1329 uint32_t entry_size = size.ValueOrDefault(0);
1330 size += header_size;
1331 std::vector<std::string> names(num_uniform_blocks);
1332 GLint max_name_length = 0;
1333 glGetProgramiv(
1334 program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_name_length);
1335 std::vector<GLchar> buffer(max_name_length);
1336 GLsizei length;
1337 for (uint32_t ii = 0; ii < num_uniform_blocks; ++ii) {
1338 param = 0;
1339 glGetActiveUniformBlockiv(program, ii, GL_UNIFORM_BLOCK_BINDING, &param);
1340 blocks[ii].binding = static_cast<uint32_t>(param);
1341
1342 param = 0;
1343 glGetActiveUniformBlockiv(program, ii, GL_UNIFORM_BLOCK_DATA_SIZE, &param);
1344 blocks[ii].data_size = static_cast<uint32_t>(param);
1345
1346 blocks[ii].name_offset = size.ValueOrDefault(0);
1347 param = 0;
1348 glGetActiveUniformBlockiv(
1349 program, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, &param);
1350 DCHECK_GE(max_name_length, param);
1351 memset(&buffer[0], 0, param);
1352 length = 0;
1353 glGetActiveUniformBlockName(
1354 program, ii, static_cast<GLsizei>(param), &length, &buffer[0]);
1355 DCHECK_EQ(param, length + 1);
1356 names[ii] = std::string(&buffer[0], length);
1357 // TODO(zmo): optimize the name mapping lookup.
1358 const std::string* original_name = GetOriginalNameFromHashedName(names[ii]);
1359 if (original_name)
1360 names[ii] = *original_name;
1361 blocks[ii].name_length = names[ii].size() + 1;
1362 size += blocks[ii].name_length;
1363
1364 param = 0;
1365 glGetActiveUniformBlockiv(
1366 program, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &param);
1367 blocks[ii].active_uniforms = static_cast<uint32_t>(param);
1368 blocks[ii].active_uniform_offset = size.ValueOrDefault(0);
1369 base::CheckedNumeric<uint32_t> indices_size = blocks[ii].active_uniforms;
1370 indices_size *= sizeof(uint32_t);
1371 if (!indices_size.IsValid())
1372 return false;
1373 size += indices_size.ValueOrDefault(0);
1374
1375 param = 0;
1376 glGetActiveUniformBlockiv(
1377 program, ii, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, &param);
1378 blocks[ii].referenced_by_vertex_shader = static_cast<uint32_t>(param);
1379
1380 param = 0;
1381 glGetActiveUniformBlockiv(
1382 program, ii, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, &param);
1383 blocks[ii].referenced_by_fragment_shader = static_cast<uint32_t>(param);
1384 }
1385 if (!size.IsValid())
1386 return false;
1387 uint32_t total_size = size.ValueOrDefault(0);
1388 DCHECK_LE(header_size + entry_size, total_size);
1389 uint32_t data_size = total_size - header_size - entry_size;
1390
1391 bucket->SetSize(total_size);
1392 UniformBlocksHeader* header =
1393 bucket->GetDataAs<UniformBlocksHeader*>(0, total_size);
1394 UniformBlockInfo* entries = bucket->GetDataAs<UniformBlockInfo*>(
1395 header_size, entry_size);
1396 char* data = bucket->GetDataAs<char*>(header_size + entry_size, data_size);
1397 DCHECK(header);
1398 DCHECK(entries);
1399 DCHECK(data);
1400
1401 // Copy over data for the header and entries.
1402 header->num_uniform_blocks = num_uniform_blocks;
1403 memcpy(entries, &blocks[0], entry_size);
1404
1405 std::vector<GLint> params;
1406 for (uint32_t ii = 0; ii < num_uniform_blocks; ++ii) {
1407 // Get active uniform name.
1408 memcpy(data, names[ii].c_str(), blocks[ii].name_length);
1409 data += blocks[ii].name_length;
1410
1411 // Get active uniform indices.
1412 if (params.size() < blocks[ii].active_uniforms)
1413 params.resize(blocks[ii].active_uniforms);
1414 uint32_t num_bytes = blocks[ii].active_uniforms * sizeof(GLint);
1415 memset(&params[0], 0, num_bytes);
1416 glGetActiveUniformBlockiv(
1417 program, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, &params[0]);
1418 uint32_t* indices = reinterpret_cast<uint32_t*>(data);
1419 for (uint32_t uu = 0; uu < blocks[ii].active_uniforms; ++uu) {
1420 indices[uu] = static_cast<uint32_t>(params[uu]);
1421 }
1422 data += num_bytes;
1423 }
1424 DCHECK_EQ(ComputeOffset(header, data), total_size);
1425 return true;
1426 }
1427
1293 Program::~Program() { 1428 Program::~Program() {
1294 if (manager_) { 1429 if (manager_) {
1295 if (manager_->have_context_) { 1430 if (manager_->have_context_) {
1296 glDeleteProgram(service_id()); 1431 glDeleteProgram(service_id());
1297 } 1432 }
1298 manager_->StopTracking(this); 1433 manager_->StopTracking(this);
1299 manager_ = NULL; 1434 manager_ = NULL;
1300 } 1435 }
1301 } 1436 }
1302 1437
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 DCHECK(program); 1550 DCHECK(program);
1416 program->ClearUniforms(&zero_); 1551 program->ClearUniforms(&zero_);
1417 } 1552 }
1418 1553
1419 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { 1554 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) {
1420 return index + element * 0x10000; 1555 return index + element * 0x10000;
1421 } 1556 }
1422 1557
1423 } // namespace gles2 1558 } // namespace gles2
1424 } // namespace gpu 1559 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/program_manager.h ('k') | gpu/command_buffer/service/program_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698