From f078ff611a4b19ac779d6e3926b09db4ec3ad4fc Mon Sep 17 00:00:00 2001
From: samcake <samuel.gateau@gmail.com>
Date: Tue, 30 Jan 2018 15:10:52 -0800
Subject: [PATCH] Refining the declaraion signatures and adding the binary
 capture

---
 .../src/display-plugins/hmd/HmdDisplayPlugin.cpp          | 3 ++-
 libraries/gpu-gl/src/gpu/gl/GLBackend.h                   | 4 ++--
 libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp           | 8 +++++---
 libraries/gpu-gl/src/gpu/gl/GLShader.cpp                  | 2 +-
 libraries/gpu-gl/src/gpu/gl/GLShader.h                    | 2 +-
 libraries/gpu-gles/src/gpu/gl/GLBackend.h                 | 2 +-
 libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp         | 4 ++--
 libraries/gpu/src/gpu/Context.h                           | 2 +-
 libraries/gpu/src/gpu/null/NullBackend.h                  | 2 +-
 plugins/openvr/src/OpenVrDisplayPlugin.cpp                | 3 ++-
 tests/shaders/src/main.cpp                                | 3 ++-
 11 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
index 90bb83a663..b64836627c 100644
--- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp
@@ -398,7 +398,8 @@ void HmdDisplayPlugin::HUDRenderer::updatePipeline() {
         auto vs = gpu::Shader::createVertex(std::string(hmd_ui_vert));
         auto ps = gpu::Shader::createPixel(std::string(hmd_ui_frag));
         auto program = gpu::Shader::createProgram(vs, ps);
-        gpu::gl::GLBackend::makeProgram(*program, gpu::Shader::BindingSet());
+    //    gpu::gl::GLBackend::makeProgram(*program, gpu::Shader::BindingSet());
+        gpu::Shader::makeProgram(*program, gpu::Shader::BindingSet());
         uniformsLocation = program->getUniformBuffers().findLocation("hudBuffer");
 
         gpu::StatePointer state = gpu::StatePointer(new gpu::State());
diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h
index 004bfe1c85..f0b74803e4 100644
--- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h
+++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h
@@ -64,7 +64,7 @@ protected:
     explicit GLBackend(bool syncCache);
     GLBackend();
 public:
-    static bool makeProgram(Shader& shader, const Shader::BindingSet& slotBindings = Shader::BindingSet(), Shader::CompilationHandler handler = nullptr);
+    static bool makeProgram(Shader& shader, const Shader::BindingSet& slotBindings, Shader::CompilationHandler handler);
 
     virtual ~GLBackend();
 
@@ -423,7 +423,7 @@ protected:
     } _pipeline;
 
     // Backend dependant compilation of the shader
-    virtual GLShader* compileBackendProgram(const Shader& program);
+    virtual GLShader* compileBackendProgram(const Shader& program, Shader::CompilationHandler handler);
     virtual GLShader* compileBackendShader(const Shader& shader, Shader::CompilationHandler handler);
     virtual std::string getBackendShaderHeader() const;
     virtual void makeProgramBindings(ShaderObject& shaderObject);
diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp
index 84170dbffd..40b9c94610 100644
--- a/libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp
+++ b/libraries/gpu-gl/src/gpu/gl/GLBackendShader.cpp
@@ -101,7 +101,7 @@ GLShader* GLBackend::compileBackendShader(const Shader& shader, Shader::Compilat
     return object;
 }
 
-GLShader* GLBackend::compileBackendProgram(const Shader& program) {
+GLShader* GLBackend::compileBackendProgram(const Shader& program, Shader::CompilationHandler handler) {
     if (!program.isProgram()) {
         return nullptr;
     }
@@ -116,11 +116,13 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program) {
         // Let's go through every shaders and make sure they are ready to go
         std::vector< GLuint > shaderGLObjects;
         for (auto subShader : program.getShaders()) {
-            auto object = GLShader::sync((*this), *subShader);
+            auto object = GLShader::sync((*this), *subShader, handler);
             if (object) {
                 shaderGLObjects.push_back(object->_shaderObjects[version].glshader);
             } else {
                 qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?";
+                compilationLogs[version].compiled = false;
+                compilationLogs[version].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
                 program.setCompilationLogs(compilationLogs);
                 return nullptr;
             }
@@ -132,7 +134,7 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program) {
             program.setCompilationLogs(compilationLogs);
             return nullptr;
         }
-
+        compilationLogs[version].compiled = true;
         programObject.glprogram = glprogram;
 
         makeProgramBindings(programObject);
diff --git a/libraries/gpu-gl/src/gpu/gl/GLShader.cpp b/libraries/gpu-gl/src/gpu/gl/GLShader.cpp
index a626376e27..42d4fe3845 100644
--- a/libraries/gpu-gl/src/gpu/gl/GLShader.cpp
+++ b/libraries/gpu-gl/src/gpu/gl/GLShader.cpp
@@ -39,7 +39,7 @@ GLShader* GLShader::sync(GLBackend& backend, const Shader& shader, Shader::Compi
     }
     // need to have a gpu object?
     if (shader.isProgram()) {
-        GLShader* tempObject = backend.compileBackendProgram(shader);
+        GLShader* tempObject = backend.compileBackendProgram(shader, handler);
         if (tempObject) {
             object = tempObject;
             Backend::setGPUObject(shader, object);
diff --git a/libraries/gpu-gl/src/gpu/gl/GLShader.h b/libraries/gpu-gl/src/gpu/gl/GLShader.h
index 42d63f8dfb..8625b3e64a 100644
--- a/libraries/gpu-gl/src/gpu/gl/GLShader.h
+++ b/libraries/gpu-gl/src/gpu/gl/GLShader.h
@@ -22,7 +22,7 @@ struct ShaderObject {
 class GLShader : public GPUObject {
 public:
     static GLShader* sync(GLBackend& backend, const Shader& shader, Shader::CompilationHandler handler = nullptr);
-    static bool makeProgram(GLBackend& backend, Shader& shader, const Shader::BindingSet& slotBindings, Shader::CompilationHandler handler = nullptr);
+    static bool makeProgram(GLBackend& backend, Shader& shader, const Shader::BindingSet& slotBindings, Shader::CompilationHandler handler);
 
     enum Version {
         Mono = 0,
diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackend.h b/libraries/gpu-gles/src/gpu/gl/GLBackend.h
index bb8e15bad3..0db46985f7 100644
--- a/libraries/gpu-gles/src/gpu/gl/GLBackend.h
+++ b/libraries/gpu-gles/src/gpu/gl/GLBackend.h
@@ -420,7 +420,7 @@ protected:
     } _pipeline;
 
     // Backend dependant compilation of the shader
-    virtual GLShader* compileBackendProgram(const Shader& program);
+    virtual GLShader* compileBackendProgram(const Shader& program, Shader::CompilationHandler handler);
     virtual GLShader* compileBackendShader(const Shader& shader, Shader::CompilationHandler handler);
     virtual std::string getBackendShaderHeader() const;
     virtual void makeProgramBindings(ShaderObject& shaderObject);
diff --git a/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp
index 26dbb12cf7..1d7636c159 100644
--- a/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp
+++ b/libraries/gpu-gles/src/gpu/gl/GLBackendShader.cpp
@@ -140,7 +140,7 @@ GLShader* GLBackend::compileBackendShader(const Shader& shader, Shader::Compilat
     return object;
 }
 
-GLShader* GLBackend::compileBackendProgram(const Shader& program) {
+GLShader* GLBackend::compileBackendProgram(const Shader& program, Shader::CompilationHandler handler) {
     if (!program.isProgram()) {
         return nullptr;
     }
@@ -155,7 +155,7 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program) {
         // Let's go through every shaders and make sure they are ready to go
         std::vector< GLuint > shaderGLObjects;
         for (auto subShader : program.getShaders()) {
-            auto object = GLShader::sync((*this), *subShader);
+            auto object = GLShader::sync((*this), *subShader, handler);
             if (object) {
                 shaderGLObjects.push_back(object->_shaderObjects[version].glshader);
             } else {
diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h
index 7d04463609..e22cc57570 100644
--- a/libraries/gpu/src/gpu/Context.h
+++ b/libraries/gpu/src/gpu/Context.h
@@ -262,7 +262,7 @@ protected:
     // makeProgramShader(...) make a program shader ready to be used in a Batch.
     // It compiles the sub shaders, link them and defines the Slots and their bindings.
     // If the shader passed is not a program, nothing happens. 
-    static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings, Shader::CompilationHandler handler = nullptr);
+    static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings, Shader::CompilationHandler handler);
 
     static CreateBackend _createBackendCallback;
     static MakeProgram _makeProgramCallback;
diff --git a/libraries/gpu/src/gpu/null/NullBackend.h b/libraries/gpu/src/gpu/null/NullBackend.h
index c9d249aec7..abaa24812f 100644
--- a/libraries/gpu/src/gpu/null/NullBackend.h
+++ b/libraries/gpu/src/gpu/null/NullBackend.h
@@ -28,7 +28,7 @@ class Backend : public gpu::Backend {
     friend class gpu::Context;
     static void init() {}
     static gpu::Backend* createBackend() { return new Backend(); }
-    static bool makeProgram(Shader& shader, const Shader::BindingSet& slotBindings) { return true; }
+    static bool makeProgram(Shader& shader, const Shader::BindingSet& slotBindings, Shader::CompilationHandler handler) { return true; }
 
 protected:
     explicit Backend(bool syncCache) : Parent() { }
diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp
index 4403eaeff7..4b5f0e6517 100644
--- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp
+++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp
@@ -200,9 +200,10 @@ public:
             std::string fsSource = HMD_REPROJECTION_FRAG;
             GLuint vertexShader { 0 }, fragmentShader { 0 };
             std::string error;
+            std::vector<char> binary;
             ::gl::compileShader(GL_VERTEX_SHADER, vsSource, "", vertexShader, error);
             ::gl::compileShader(GL_FRAGMENT_SHADER, fsSource, "", fragmentShader, error);
-            _program = ::gl::compileProgram({ { vertexShader, fragmentShader } }, error);
+            _program = ::gl::compileProgram({ { vertexShader, fragmentShader } }, error, binary);
             glDeleteShader(vertexShader);
             glDeleteShader(fragmentShader);
             qDebug() << "Rebuild proigram";
diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp
index cd307ba362..3f48e37a76 100644
--- a/tests/shaders/src/main.cpp
+++ b/tests/shaders/src/main.cpp
@@ -137,12 +137,13 @@ const std::string PIXEL_SHADER_DEFINES{ R"GLSL(
 
 void testShaderBuild(const char* vs_src, const char * fs_src) {
     std::string error;
+    std::vector<char> binary;
     GLuint vs, fs;
     if (!gl::compileShader(GL_VERTEX_SHADER, vs_src, VERTEX_SHADER_DEFINES, vs, error) || 
         !gl::compileShader(GL_FRAGMENT_SHADER, fs_src, PIXEL_SHADER_DEFINES, fs, error)) {
         throw std::runtime_error("Failed to compile shader");
     }
-    auto pr = gl::compileProgram({ vs, fs }, error);
+    auto pr = gl::compileProgram({ vs, fs }, error, binary);
     if (!pr) {
         throw std::runtime_error("Failed to link shader");
     }