D3D11: Update cached dynamically recompiled programs.

This change makes it so that when we need to recompile a program on a
draw call, we also update the cache. It also streamlines the internal
queries of the dynamic vertex and fragment shaders such that we only
update the input and output signatures a single time per draw. This
should also facilitate dirty bit implementations for the D3D11 back-
end.

BUG=angleproject:2116

Change-Id: Iccb0501b700bc894f40a8c68d7f297ff0c8f46bd
Reviewed-on: https://chromium-review.googlesource.com/531798
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 98efef9..2e7ec29 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -1837,14 +1837,14 @@
 
 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
     MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
 }
 
 void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(
         mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
     MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
@@ -1852,7 +1852,7 @@
 
 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
 }
 
@@ -1862,7 +1862,7 @@
                                     const void *indices,
                                     GLsizei instances)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(
         mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
 }
@@ -1874,20 +1874,20 @@
                                 GLenum type,
                                 const void *indices)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(
         mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
 }
 
 void Context::drawArraysIndirect(GLenum mode, const void *indirect)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
 }
 
 void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
 {
-    ANGLE_CONTEXT_TRY(prepareForDraw());
+    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
     ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
 }
 
@@ -2170,7 +2170,7 @@
     return QueryProgramResourceLocation(programObject, programInterface, name);
 }
 
-void Context::handleError(const Error &error)
+Error Context::handleError(const Error &error)
 {
     if (error.isError())
     {
@@ -2188,6 +2188,8 @@
                                  GL_DEBUG_SEVERITY_HIGH, error.getMessage());
         }
     }
+
+    return error;
 }
 
 // Get one of the recorded errors and clear its flag, if any.
@@ -2820,10 +2822,18 @@
     mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
 }
 
-Error Context::prepareForDraw()
+Error Context::prepareForDraw(GLenum drawMode)
 {
     syncRendererState();
-    return NoError();
+
+    InfoLog infoLog;
+    Error err = mImplementation->triggerDrawCallProgramRecompilation(this, &infoLog,
+                                                                     mMemoryProgramCache, drawMode);
+    if (err.isError())
+    {
+        WARN() << "Dynamic recompilation error log: " << infoLog.str();
+    }
+    return err;
 }
 
 void Context::syncRendererState()