Implement full program binary support for ES3.

Refactor validation to be used in both the OES and ES3 entry points.

BUG=angleproject:600
BUG=angleproject:1101

Change-Id: I2008c4ea04ce07910f03ae0b997f8a77b66203d8
Reviewed-on: https://chromium-review.googlesource.com/316620
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index a9d54b8..1e68804 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -37,6 +37,7 @@
 
     virtual LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0;
     virtual gl::Error save(gl::BinaryOutputStream *stream) = 0;
+    virtual void setBinaryRetrievableHint(bool retrievable) = 0;
 
     virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) = 0;
     virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0;
diff --git a/src/libANGLE/renderer/ProgramImpl_mock.h b/src/libANGLE/renderer/ProgramImpl_mock.h
index dbc1534..0db2330 100644
--- a/src/libANGLE/renderer/ProgramImpl_mock.h
+++ b/src/libANGLE/renderer/ProgramImpl_mock.h
@@ -25,6 +25,7 @@
 
     MOCK_METHOD2(load, LinkResult(gl::InfoLog &, gl::BinaryInputStream *));
     MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *));
+    MOCK_METHOD1(setBinaryRetrievableHint, void(bool));
 
     MOCK_METHOD2(link, LinkResult(const gl::Data &, gl::InfoLog &));
     MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *));
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index d6a2a27..7f44d58 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1104,6 +1104,10 @@
     return gl::Error(GL_NO_ERROR);
 }
 
+void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */)
+{
+}
+
 gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo,
                                                        ShaderExecutableD3D **outExecutable)
 {
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index b5eea9b..5ea15aa 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -150,8 +150,9 @@
     bool usesGeometryShader(GLenum drawMode) const;
     bool usesInstancedPointSpriteEmulation() const;
 
-    LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
-    gl::Error save(gl::BinaryOutputStream *stream);
+    LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override;
+    gl::Error save(gl::BinaryOutputStream *stream) override;
+    void setBinaryRetrievableHint(bool retrievable) override;
 
     gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo,
                                                ShaderExecutableD3D **outExectuable);
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index c4739d1..f5adc3b 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -47,6 +47,11 @@
     return gl::Error(GL_INVALID_OPERATION);
 }
 
+void ProgramGL::setBinaryRetrievableHint(bool retrievable)
+{
+    UNIMPLEMENTED();
+}
+
 LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog)
 {
     // Reset the program state, delete the current program if one exists
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index 377ba0f..fa34368 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -33,6 +33,7 @@
 
     LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override;
     gl::Error save(gl::BinaryOutputStream *stream) override;
+    void setBinaryRetrievableHint(bool retrievable) override;
 
     LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override;
     GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;