Revert "Merge the ProgramBinary class into Program."

Issues appeared on the FYI waterfall, content_gl_tests hangs.

This reverts commit 2195a6d6032883ed05468d5ecd019e7cb9a27bce.

Change-Id: I9fe1a53cf40887ae5a98fd77b4872f41085fcea7
Reviewed-on: https://chromium-review.googlesource.com/232386
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index a39499b..c02bbe6 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -18,6 +18,7 @@
 #include "libANGLE/FramebufferAttachment.h"
 #include "libANGLE/Renderbuffer.h"
 #include "libANGLE/Program.h"
+#include "libANGLE/ProgramBinary.h"
 #include "libANGLE/Query.h"
 #include "libANGLE/ResourceManager.h"
 #include "libANGLE/Sampler.h"
@@ -122,6 +123,18 @@
 
 Context::~Context()
 {
+    GLuint currentProgram = mState.getCurrentProgramId();
+    if (currentProgram != 0)
+    {
+        Program *programObject = mResourceManager->getProgram(currentProgram);
+        if (programObject)
+        {
+            programObject->release();
+        }
+        currentProgram = 0;
+    }
+    mState.setCurrentProgram(0, NULL);
+
     while (!mFramebufferMap.empty())
     {
         deleteFramebuffer(mFramebufferMap.begin()->first);
@@ -610,7 +623,58 @@
 
 void Context::useProgram(GLuint program)
 {
-    mState.setProgram(getProgram(program));
+    GLuint priorProgramId = mState.getCurrentProgramId();
+    Program *priorProgram = mResourceManager->getProgram(priorProgramId);
+
+    if (priorProgramId != program)
+    {
+        mState.setCurrentProgram(program, mResourceManager->getProgram(program));
+
+        if (priorProgram)
+        {
+            priorProgram->release();
+        }
+    }
+}
+
+Error Context::linkProgram(GLuint program)
+{
+    Program *programObject = mResourceManager->getProgram(program);
+
+    Error error = programObject->link(getData());
+    if (error.isError())
+    {
+        return error;
+    }
+
+    // if the current program was relinked successfully we
+    // need to install the new executables
+    if (programObject->isLinked() && program == mState.getCurrentProgramId())
+    {
+        mState.setCurrentProgramBinary(programObject->getProgramBinary());
+    }
+
+    return Error(GL_NO_ERROR);
+}
+
+Error Context::setProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+{
+    Program *programObject = mResourceManager->getProgram(program);
+
+    Error error = programObject->setProgramBinary(binaryFormat, binary, length);
+    if (error.isError())
+    {
+        return error;
+    }
+
+    // if the current program was reloaded successfully we
+    // need to install the new executables
+    if (programObject->isLinked() && program == mState.getCurrentProgramId())
+    {
+        mState.setCurrentProgramBinary(programObject->getProgramBinary());
+    }
+
+    return Error(GL_NO_ERROR);
 }
 
 void Context::bindTransformFeedback(GLuint transformFeedback)