Remove State::syncProgramTextures.

Removes the concept of the program textures dirty object. Instead we
use a set of dirty bits to represent dirty texture samples. We mark
certain textures dirty and update state structures whenever there is
a new Texture/Program/Sampler bound, or when Texture/Program/Sampler
state changes.

This is in preparation for making clearing the uncleared active
textures into a dirty bit as well.

Also includes new dirty bit handling for texture image units. These are
a GLES 3.1 feature.

Bug: angleproject:2966
Change-Id: Ibb8619dd2669bb39fdbcd75e3685be9a8aeeee91
Reviewed-on: https://chromium-review.googlesource.com/c/1346649
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 8a67428..94a8432 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -2052,7 +2052,7 @@
     mProgram->setUniform4fv(location, clampedCount, v);
 }
 
-Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+void Program::setUniform1iv(Context *context, GLint location, GLsizei count, const GLint *v)
 {
     ASSERT(mLinkResolved);
     const VariableLocation &locationInfo = mState.mUniformLocations[location];
@@ -2062,11 +2062,8 @@
 
     if (mState.isSamplerUniformIndex(locationInfo.index))
     {
-        updateSamplerUniform(locationInfo, clampedCount, v);
-        return SetUniformResult::SamplerChanged;
+        updateSamplerUniform(context, locationInfo, clampedCount, v);
     }
-
-    return SetUniformResult::NoSamplerChange;
 }
 
 void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
@@ -3858,7 +3855,10 @@
             {
                 boundTextureUnits.push_back(samplerUniform.binding + elementIndex);
             }
-            setUniform1iv(location, static_cast<GLsizei>(boundTextureUnits.size()),
+
+            // Here we pass nullptr to avoid a large chain of calls that need a non-const Context.
+            // We know it's safe not to notify the Context because this is only called after link.
+            setUniform1iv(nullptr, location, static_cast<GLsizei>(boundTextureUnits.size()),
                           boundTextureUnits.data());
         }
     }
@@ -3874,7 +3874,8 @@
     }
 }
 
-void Program::updateSamplerUniform(const VariableLocation &locationInfo,
+void Program::updateSamplerUniform(Context *context,
+                                   const VariableLocation &locationInfo,
                                    GLsizei clampedCount,
                                    const GLint *v)
 {
@@ -3889,30 +3890,30 @@
     // Update the sampler uniforms.
     for (GLsizei arrayIndex = 0; arrayIndex < clampedCount; ++arrayIndex)
     {
-        GLint oldSamplerIndex = boundTextureUnits[arrayIndex + locationInfo.arrayIndex];
-        GLint newSamplerIndex = v[arrayIndex];
+        GLint oldTextureUnit = boundTextureUnits[arrayIndex + locationInfo.arrayIndex];
+        GLint newTextureUnit = v[arrayIndex];
 
-        if (oldSamplerIndex == newSamplerIndex)
+        if (oldTextureUnit == newTextureUnit)
             continue;
 
-        boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newSamplerIndex;
+        boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newTextureUnit;
 
         // Update the reference counts.
-        uint32_t &oldRefCount = mState.mActiveSamplerRefCounts[oldSamplerIndex];
-        uint32_t &newRefCount = mState.mActiveSamplerRefCounts[newSamplerIndex];
+        uint32_t &oldRefCount = mState.mActiveSamplerRefCounts[oldTextureUnit];
+        uint32_t &newRefCount = mState.mActiveSamplerRefCounts[newTextureUnit];
         ASSERT(oldRefCount > 0);
         ASSERT(newRefCount < std::numeric_limits<uint32_t>::max());
         oldRefCount--;
         newRefCount++;
 
         // Check for binding type change.
-        TextureType &newSamplerType = mState.mActiveSamplerTypes[newSamplerIndex];
-        TextureType &oldSamplerType = mState.mActiveSamplerTypes[oldSamplerIndex];
+        TextureType &newSamplerType = mState.mActiveSamplerTypes[newTextureUnit];
+        TextureType &oldSamplerType = mState.mActiveSamplerTypes[oldTextureUnit];
 
         if (newRefCount == 1)
         {
             newSamplerType = samplerBinding.textureType;
-            mState.mActiveSamplersMask.set(newSamplerIndex);
+            mState.mActiveSamplersMask.set(newTextureUnit);
         }
         else if (newSamplerType != samplerBinding.textureType)
         {
@@ -3924,12 +3925,19 @@
         if (oldRefCount == 0)
         {
             oldSamplerType = TextureType::InvalidEnum;
-            mState.mActiveSamplersMask.reset(oldSamplerIndex);
+            mState.mActiveSamplersMask.reset(oldTextureUnit);
         }
         else if (oldSamplerType == TextureType::InvalidEnum)
         {
             // Previous conflict. Check if this new change fixed the conflict.
-            oldSamplerType = mState.getSamplerUniformTextureType(oldSamplerIndex);
+            oldSamplerType = mState.getSamplerUniformTextureType(oldTextureUnit);
+        }
+
+        // Notify context.
+        if (context)
+        {
+            context->onSamplerUniformChange(newTextureUnit);
+            context->onSamplerUniformChange(oldTextureUnit);
         }
     }