| Index: gpu/command_buffer/service/program_manager.cc
|
| diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
|
| index faf5b3f3771ede5f06c5a5fd535f976999852e4e..c72caba80fa145e9fd174fc22ce2d2595b8d8df6 100644
|
| --- a/gpu/command_buffer/service/program_manager.cc
|
| +++ b/gpu/command_buffer/service/program_manager.cc
|
| @@ -9,6 +9,7 @@
|
| #include "base/basictypes.h"
|
| #include "base/logging.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/rand_util.h"
|
| #include "base/string_number_conversions.h"
|
| #include "gpu/command_buffer/common/gles2_cmd_format.h"
|
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
|
| @@ -450,7 +451,7 @@ static uint32 ComputeOffset(const void* start, const void* position) {
|
| }
|
|
|
| void ProgramManager::ProgramInfo::GetProgramInfo(
|
| - CommonDecoder::Bucket* bucket) const {
|
| + ProgramManager* manager, CommonDecoder::Bucket* bucket) const {
|
| // NOTE: It seems to me the math in here does not need check for overflow
|
| // because the data being calucated from has various small limits. The max
|
| // number of attribs + uniforms is somewhere well under 1024. The maximum size
|
| @@ -516,7 +517,7 @@ void ProgramManager::ProgramInfo::GetProgramInfo(
|
| inputs->name_length = info.name.size();
|
| DCHECK(static_cast<size_t>(info.size) == info.element_locations.size());
|
| for (size_t jj = 0; jj < info.element_locations.size(); ++jj) {
|
| - *locations++ = info.element_locations[jj];
|
| + *locations++ = manager->SwizzleLocation(info.element_locations[jj]);
|
| }
|
| memcpy(strings, info.name.c_str(), info.name.size());
|
| strings += info.name.size();
|
| @@ -528,7 +529,9 @@ void ProgramManager::ProgramInfo::GetProgramInfo(
|
|
|
| ProgramManager::ProgramInfo::~ProgramInfo() {}
|
|
|
| -ProgramManager::ProgramManager() {}
|
| +ProgramManager::ProgramManager()
|
| + : uniform_swizzle_(base::RandInt(0, 15)) {
|
| +}
|
|
|
| ProgramManager::~ProgramManager() {
|
| DCHECK(program_infos_.empty());
|
| @@ -628,6 +631,25 @@ void ProgramManager::UnuseProgram(
|
| RemoveProgramInfoIfUnused(shader_manager, info);
|
| }
|
|
|
| +// Swizzles the locations to prevent developers from assuming they
|
| +// can do math on uniforms. According to the OpenGL ES 2.0 spec
|
| +// the location of "someuniform[1]" is not 1 more than "someuniform[0]".
|
| +static GLint Swizzle(GLint location) {
|
| + return (location & 0xFFFF0000U) |
|
| + ((location & 0x0000AAAAU) >> 1) |
|
| + ((location & 0x00005555U) << 1);
|
| +}
|
| +
|
| +// Adds uniform_swizzle_ to prevent developers from assuming that locations are
|
| +// always the same across GPUs and drivers.
|
| +GLint ProgramManager::SwizzleLocation(GLint v) const {
|
| + return v < 0 ? v : (Swizzle(v) + uniform_swizzle_);
|
| +}
|
| +
|
| +GLint ProgramManager::UnswizzleLocation(GLint v) const {
|
| + return v < 0 ? v : Swizzle(v - uniform_swizzle_);
|
| +}
|
| +
|
| } // namespace gles2
|
| } // namespace gpu
|
|
|
|
|