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

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

Issue 887513002: Implement glGetUniformBlocksCHROMIUM: service side data packing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.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 size_t header_size = sizeof(UniformBlocksHeader);
1306
1307 GLuint 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<GLuint>(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<size_t> size = sizeof(UniformBlockInfo);
piman 2015/01/29 02:05:16 CheckedNumeric<uint32_t> (here and other places) s
Zhenyao Mo 2015/01/29 17:52:30 Done.
1328 size *= num_uniform_blocks;
1329 size_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 (GLuint 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 = static_cast<uint32_t>(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 =
1369 static_cast<uint32_t>(size.ValueOrDefault(0));
1370 base::CheckedNumeric<size_t> indices_size = blocks[ii].active_uniforms;
1371 indices_size *= sizeof(uint32_t);
1372 if (!indices_size.IsValid())
1373 return false;
1374 size += indices_size.ValueOrDefault(0);
1375
1376 param = 0;
1377 glGetActiveUniformBlockiv(
1378 program, ii, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, &param);
1379 blocks[ii].referenced_by_vertex_shader = static_cast<uint32_t>(param);
1380
1381 param = 0;
1382 glGetActiveUniformBlockiv(
1383 program, ii, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, &param);
1384 blocks[ii].referenced_by_fragment_shader = static_cast<uint32_t>(param);
1385 }
1386 if (!size.IsValid())
1387 return false;
1388 size_t total_size = size.ValueOrDefault(0);
1389 DCHECK_LE(header_size + entry_size, total_size);
1390 size_t data_size = total_size - header_size - entry_size;
1391
1392 bucket->SetSize(total_size);
1393 UniformBlocksHeader* header =
1394 bucket->GetDataAs<UniformBlocksHeader*>(0, total_size);
1395 UniformBlockInfo* entries = bucket->GetDataAs<UniformBlockInfo*>(
1396 header_size, entry_size);
1397 char* data = bucket->GetDataAs<char*>(header_size + entry_size, data_size);
1398 DCHECK(header);
1399 DCHECK(entries);
1400 DCHECK(data);
1401
1402 // Copy over data for the header and entries.
1403 header->num_uniform_blocks = static_cast<uint32_t>(num_uniform_blocks);
1404 memcpy(entries, &blocks[0], entry_size);
1405
1406 std::vector<GLint> params;
1407 for (size_t ii = 0; ii < num_uniform_blocks; ++ii) {
1408 // Get active uniform name.
1409 size_t num_bytes = static_cast<size_t>(blocks[ii].name_length);
1410 memcpy(data, names[ii].c_str(), num_bytes);
1411 data += num_bytes;
1412
1413 // Get active uniform indices.
1414 if (params.size() < blocks[ii].active_uniforms)
1415 params.resize(blocks[ii].active_uniforms);
1416 num_bytes =
1417 static_cast<size_t>(blocks[ii].active_uniforms) * sizeof(GLint);
1418 memset(&params[0], 0, num_bytes);
1419 glGetActiveUniformBlockiv(
1420 program, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, &params[0]);
1421 uint32_t* indices = reinterpret_cast<uint32_t*>(data);
1422 for (uint32_t uu = 0; uu < blocks[ii].active_uniforms; ++uu) {
1423 indices[uu] = static_cast<uint32_t>(params[uu]);
1424 }
1425 data += num_bytes;
1426 }
1427 DCHECK_EQ(ComputeOffset(header, data), total_size);
1428 return true;
1429 }
1430
1293 Program::~Program() { 1431 Program::~Program() {
1294 if (manager_) { 1432 if (manager_) {
1295 if (manager_->have_context_) { 1433 if (manager_->have_context_) {
1296 glDeleteProgram(service_id()); 1434 glDeleteProgram(service_id());
1297 } 1435 }
1298 manager_->StopTracking(this); 1436 manager_->StopTracking(this);
1299 manager_ = NULL; 1437 manager_ = NULL;
1300 } 1438 }
1301 } 1439 }
1302 1440
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 DCHECK(program); 1553 DCHECK(program);
1416 program->ClearUniforms(&zero_); 1554 program->ClearUniforms(&zero_);
1417 } 1555 }
1418 1556
1419 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { 1557 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) {
1420 return index + element * 0x10000; 1558 return index + element * 0x10000;
1421 } 1559 }
1422 1560
1423 } // namespace gles2 1561 } // namespace gles2
1424 } // namespace gpu 1562 } // 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