Make Context handle dirty texture events.

Moving from State to Context allows the Context to update the State
Cache class directly. It also calls through to the State class to
update the Texture cache. This consolidates notification events into
the Context class. This is also in line with how we handle state event
updates in other gl classes.

Bug: angleproject:2747
Bug: angleproject:2763
Change-Id: Iff7dc7e46ee8768819235ebd151707cd2a03dfc9
Reviewed-on: https://chromium-review.googlesource.com/1166143
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 0d30951..48fd5fc 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -298,9 +298,11 @@
 static_assert(static_cast<gl::PrimitiveMode>(11) == gl::PrimitiveMode::EnumCount,
               "gl::PrimitiveMode enum values have changed, update kMinimumPrimitiveCounts.");
 
-constexpr angle::SubjectIndex kVertexArraySubjectIndex     = 0;
-constexpr angle::SubjectIndex kReadFramebufferSubjectIndex = 1;
-constexpr angle::SubjectIndex kDrawFramebufferSubjectIndex = 2;
+constexpr angle::SubjectIndex kVertexArraySubjectIndex = gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 0;
+constexpr angle::SubjectIndex kReadFramebufferSubjectIndex =
+    gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 1;
+constexpr angle::SubjectIndex kDrawFramebufferSubjectIndex =
+    gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES + 2;
 }  // anonymous namespace
 
 namespace gl
@@ -7561,7 +7563,6 @@
                                    angle::SubjectIndex index,
                                    angle::SubjectMessage message)
 {
-    ASSERT(message == angle::SubjectMessage::CONTENTS_CHANGED);
     switch (index)
     {
         case kVertexArraySubjectIndex:
@@ -7578,7 +7579,8 @@
             break;
 
         default:
-            UNREACHABLE();
+            ASSERT(index < mGLState.getActiveTexturesCache().size());
+            mGLState.onActiveTextureStateChange(index);
             break;
     }
 }
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index bb813ff..27d7e93 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -123,7 +123,7 @@
 {
 }
 
-void State::initialize(const Context *context)
+void State::initialize(Context *context)
 {
     const Caps &caps                   = context->getCaps();
     const Extensions &extensions       = context->getExtensions();
@@ -218,7 +218,7 @@
     for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
          ++textureIndex)
     {
-        mCompleteTextureBindings.emplace_back(this, textureIndex);
+        mCompleteTextureBindings.emplace_back(context, textureIndex);
     }
 
     mSamplers.resize(caps.maxCombinedTextureImageUnits);
@@ -2796,16 +2796,14 @@
 }
 
 // Handle a dirty texture event.
-void State::onSubjectStateChange(const Context *context,
-                                 angle::SubjectIndex index,
-                                 angle::SubjectMessage message)
+void State::onActiveTextureStateChange(size_t textureIndex)
 {
     // Conservatively assume all textures are dirty.
     // TODO(jmadill): More fine-grained update.
     mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
 
-    if (!mActiveTexturesCache[index] ||
-        mActiveTexturesCache[index]->initState() == InitState::MayNeedInit)
+    if (!mActiveTexturesCache[textureIndex] ||
+        mActiveTexturesCache[textureIndex]->initState() == InitState::MayNeedInit)
     {
         mCachedTexturesInitState = InitState::MayNeedInit;
     }
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index fa91613..fc8aa33 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -35,7 +35,7 @@
 class Context;
 struct Caps;
 
-class State : public angle::ObserverInterface, angle::NonCopyable
+class State : angle::NonCopyable
 {
   public:
     State(bool debug,
@@ -43,9 +43,9 @@
           bool clientArraysEnabled,
           bool robustResourceInit,
           bool programBinaryCacheEnabled);
-    ~State() override;
+    ~State();
 
-    void initialize(const Context *context);
+    void initialize(Context *context);
     void reset(const Context *context);
 
     // State chunk getters
@@ -472,10 +472,7 @@
     const ActiveTexturePointerArray &getActiveTexturesCache() const { return mActiveTexturesCache; }
     ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
 
-    // Observer implementation.
-    void onSubjectStateChange(const Context *context,
-                              angle::SubjectIndex index,
-                              angle::SubjectMessage message) override;
+    void onActiveTextureStateChange(size_t textureIndex);
 
     Error clearUnclearedActiveTextures(const Context *context);