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; |
+ } |
+} |
+ |
} |