| Index: Source/core/html/canvas/WebGLProgram.cpp
|
| diff --git a/Source/core/html/canvas/WebGLProgram.cpp b/Source/core/html/canvas/WebGLProgram.cpp
|
| index 5581744f8bbc056fb5d9f67375f292393af78667..81327e2cb95ce4890a5dc49ba2928a8e024f1a54 100644
|
| --- a/Source/core/html/canvas/WebGLProgram.cpp
|
| +++ b/Source/core/html/canvas/WebGLProgram.cpp
|
| @@ -64,39 +64,40 @@ void WebGLProgram::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObje
|
| }
|
| }
|
|
|
| -unsigned WebGLProgram::numActiveAttribLocations()
|
| +unsigned WebGLProgram::numActiveAttribLocations(WebGLRenderingContext* context)
|
| {
|
| - cacheInfoIfNeeded();
|
| + cacheInfoIfNeeded(context);
|
| return m_activeAttribLocations.size();
|
| }
|
|
|
| -GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index)
|
| +GC3Dint WebGLProgram::getActiveAttribLocation(WebGLRenderingContext* context, GC3Duint index)
|
| {
|
| - cacheInfoIfNeeded();
|
| - if (index >= numActiveAttribLocations())
|
| + cacheInfoIfNeeded(context);
|
| + if (index >= numActiveAttribLocations(context))
|
| return -1;
|
| return m_activeAttribLocations[index];
|
| }
|
|
|
| -bool WebGLProgram::isUsingVertexAttrib0()
|
| +bool WebGLProgram::isUsingVertexAttrib0(WebGLRenderingContext* context)
|
| {
|
| - cacheInfoIfNeeded();
|
| - for (unsigned ii = 0; ii < numActiveAttribLocations(); ++ii) {
|
| - if (!getActiveAttribLocation(ii))
|
| + cacheInfoIfNeeded(context);
|
| + unsigned numLocations = numActiveAttribLocations(context);
|
| + for (unsigned ii = 0; ii < numLocations; ++ii) {
|
| + if (!getActiveAttribLocation(context, ii))
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| -bool WebGLProgram::getLinkStatus()
|
| +bool WebGLProgram::getLinkStatus(WebGLRenderingContext* context)
|
| {
|
| - cacheInfoIfNeeded();
|
| + cacheInfoIfNeeded(context);
|
| return m_linkStatus;
|
| }
|
|
|
| -void WebGLProgram::setLinkStatus(bool status)
|
| +void WebGLProgram::setLinkStatus(WebGLRenderingContext* context, bool status)
|
| {
|
| - cacheInfoIfNeeded();
|
| + cacheInfoIfNeeded(context);
|
| m_linkStatus = status;
|
| }
|
|
|
| @@ -172,7 +173,36 @@ void WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
|
| }
|
| }
|
|
|
| -void WebGLProgram::cacheInfoIfNeeded()
|
| +void WebGLProgram::cacheSamplerLocations(GraphicsContext3D* context3d)
|
| +{
|
| + m_samplerLocationToTextureUnit.clear();
|
| +
|
| + GC3Dint numUniforms = 0;
|
| + context3d->getProgramiv(object(), GraphicsContext3D::ACTIVE_UNIFORMS, &numUniforms);
|
| + for (int i = 0; i < numUniforms; ++i) {
|
| + ActiveInfo info;
|
| + context3d->getActiveUniform(object(), i, info);
|
| + if (info.type != GraphicsContext3D::SAMPLER_2D && info.type != GraphicsContext3D::SAMPLER_CUBE) {
|
| + continue;
|
| + }
|
| + GC3Dint location = context3d->getUniformLocation(object(), info.name.charactersWithNullTermination());
|
| + // This loop makes a chain of locations for elements of a uniform array. Given the location of any
|
| + // element in the array you can get the next element's location from 'nextLocation'. If 'nextLocation'
|
| + // is -1 it's the last element.
|
| + for (int j = 0; location >= 0 && j < info.size; ++j) {
|
| + GC3Dint nextLocation = -1;
|
| + if (j < info.size - 1) {
|
| + String elementName(info.name + "[" + String::number(j + 1) + "]");
|
| + nextLocation = context3d->getUniformLocation(object(), elementName.charactersWithNullTermination());
|
| + }
|
| + // Add one because HashMap can't store 0
|
| + m_samplerLocationToTextureUnit.add(location + 1, SamplerInfo(info.type, nextLocation));
|
| + location = nextLocation;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void WebGLProgram::cacheInfoIfNeeded(WebGLRenderingContext* context)
|
| {
|
| if (m_infoValid)
|
| return;
|
| @@ -180,15 +210,35 @@ void WebGLProgram::cacheInfoIfNeeded()
|
| if (!object())
|
| return;
|
|
|
| - GraphicsContext3D* context = getAGraphicsContext3D();
|
| + GraphicsContext3D* gc3d = context->graphicsContext3D();
|
| if (!context)
|
| return;
|
| GC3Dint linkStatus = 0;
|
| - context->getProgramiv(object(), GraphicsContext3D::LINK_STATUS, &linkStatus);
|
| + gc3d->getProgramiv(object(), GraphicsContext3D::LINK_STATUS, &linkStatus);
|
| m_linkStatus = linkStatus;
|
| - if (m_linkStatus)
|
| - cacheActiveAttribLocations(context);
|
| + if (m_linkStatus) {
|
| + cacheActiveAttribLocations(gc3d);
|
| + cacheSamplerLocations(gc3d);
|
| + }
|
| m_infoValid = true;
|
| }
|
|
|
| +void WebGLProgram::conditionallyRecordTextureUnitsAssignedToSamplers(WebGLRenderingContext* context, GC3Dint location, GC3Dsizei size, const GC3Dint* v)
|
| +{
|
| + cacheInfoIfNeeded(context);
|
| +
|
| + // Locations are stored such that each element of a uniform array has a "nextLocation" field
|
| + // that gives the location of the next element in the array. So, given the location of any element
|
| + // you can fill out subsequent elements by following 'nextLocation' until the nextLocation is < 0.
|
| + for (; location >= 0 && size > 0; --size) {
|
| + // Add one because HashMap can't store 0.
|
| + SamplerTextureUnitMap::iterator it = m_samplerLocationToTextureUnit.find(location + 1);
|
| + if (it == m_samplerLocationToTextureUnit.end()) {
|
| + return;
|
| + }
|
| + it->value.unit = *v++;
|
| + location = it->value.nextLocation;
|
| + }
|
| +}
|
| +
|
| }
|
|
|