Use active textures mask with robust init.

This should speed up clearUnclearedActiveTextures considerably.
It was showing up as a hotspot when running the aquarium demo with
the passthrough command decoder.

Also rename the complete textures mask in gl::State to an active
textures mask, since it includes incomplete textures.

BUG=angleproject:2188

Change-Id: Idf020fc49c1e74f17a8005c3b88516829767b84c
Reviewed-on: https://chromium-review.googlesource.com/722421
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index f6917f2..c4a132b 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -2838,8 +2838,13 @@
 Error Context::prepareForDraw()
 {
     syncRendererState();
-    ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
-    ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
+
+    if (isRobustResourceInitEnabled())
+    {
+        ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
+        ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
+    }
+
     return NoError();
 }
 
@@ -4283,7 +4288,10 @@
     }
 
     // TODO(jmadill): Dirty bits for compute.
-    ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this));
+    if (isRobustResourceInitEnabled())
+    {
+        ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this));
+    }
 
     handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
 }
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 46fbe5c..1cd0bb7 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2299,8 +2299,8 @@
 
             // Bind the texture unconditionally, to recieve completeness change notifications.
             mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel());
+            mActiveTexturesMask.set(textureUnitIndex);
             newActiveTextures.set(textureUnitIndex);
-            mCompleteTexturesMask.set(textureUnitIndex);
 
             if (sampler != nullptr)
             {
@@ -2310,14 +2310,14 @@
     }
 
     // Unset now missing textures.
-    ActiveTextureMask negativeMask = mCompleteTexturesMask & ~newActiveTextures;
+    ActiveTextureMask negativeMask = mActiveTexturesMask & ~newActiveTextures;
     if (negativeMask.any())
     {
         for (auto textureIndex : negativeMask)
         {
             mCompleteTextureBindings[textureIndex].reset();
             mCompleteTextureCache[textureIndex] = nullptr;
-            mCompleteTexturesMask.reset(textureIndex);
+            mActiveTexturesMask.reset(textureIndex);
         }
     }
 }
@@ -2422,19 +2422,17 @@
 
 Error State::clearUnclearedActiveTextures(const Context *context)
 {
-    if (!mRobustResourceInit)
-    {
-        return NoError();
-    }
+    ASSERT(mRobustResourceInit);
 
-    // TODO(jmadill): Investigate improving the speed here.
-    for (Texture *texture : mCompleteTextureCache)
+    for (auto textureIndex : mActiveTexturesMask)
     {
+        Texture *texture = mCompleteTextureCache[textureIndex];
         if (texture)
         {
             ANGLE_TRY(texture->ensureInitialized(context));
         }
     }
+
     return NoError();
 }
 
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index e476508..14c45d6 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -573,7 +573,7 @@
     std::vector<Texture *> mCompleteTextureCache;
     std::vector<OnAttachmentDirtyBinding> mCompleteTextureBindings;
     using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
-    ActiveTextureMask mCompleteTexturesMask;
+    ActiveTextureMask mActiveTexturesMask;
 
     typedef std::vector<BindingPointer<Sampler>> SamplerBindingVector;
     SamplerBindingVector mSamplers;
diff --git a/src/tests/gl_tests/IncompleteTextureTest.cpp b/src/tests/gl_tests/IncompleteTextureTest.cpp
index 17c69a5..5ee77ae 100644
--- a/src/tests/gl_tests/IncompleteTextureTest.cpp
+++ b/src/tests/gl_tests/IncompleteTextureTest.cpp
@@ -103,14 +103,14 @@
 
     // Should be complete - expect red.
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "complete texture should be red";
 
     // Make texture incomplete.
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
     // Should be incomplete - expect black.
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black) << "incomplete texture should be black";
 
     // Make texture complete by defining the second mip.
     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTextureSize >> 1, kTextureSize >> 1, 0, GL_RGBA,
@@ -118,7 +118,7 @@
 
     // Should be complete - expect red.
     drawQuad(mProgram, "position", 0.5f);
-    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
+    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "mip-complete texture should be red";
 }
 
 // Tests redefining a texture with half the size works as expected.