Removed the last references to Renderer from ProgramBinary.

BUG=angle:731
Change-Id: I8829a434e59279b1b9c37e9a1922ae05d467b376
Reviewed-on: https://chromium-review.googlesource.com/219421
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Brandon Jones <bajones@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
index 15c6e13..1f0ad7d 100644
--- a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -9,6 +9,7 @@
 #include "libGLESv2/renderer/d3d/ProgramD3D.h"
 
 #include "common/utilities.h"
+#include "libGLESv2/Program.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/renderer/ShaderExecutable.h"
@@ -87,6 +88,16 @@
         stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
     }
 
+    GUID binaryIdentifier = {0};
+    stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
+
+    GUID identifier = mRenderer->getAdapterIdentifier();
+    if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
+    {
+        infoLog.append("Invalid program binary.");
+        return false;
+    }
+
     return true;
 }
 
@@ -112,58 +123,68 @@
         stream->writeInt(variable.outputIndex);
     }
 
+    GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
+    stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier),  sizeof(GUID));
+
     return true;
 }
 
-rx::ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
-                                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
-                                                                    bool separatedOutputBuffers)
+ShaderExecutable *ProgramD3D::getPixelExecutableForOutputLayout(gl::InfoLog &infoLog, const std::vector<GLenum> &outputSignature,
+                                                                const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                                bool separatedOutputBuffers)
 {
     std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(mPixelHLSL, mPixelShaderKey, mUsesFragDepth,
                                                                                      outputSignature);
 
     // Generate new pixel executable
-    rx::ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
-                                                                           transformFeedbackLinkedVaryings, separatedOutputBuffers,
-                                                                           mPixelWorkarounds);
+    ShaderExecutable *pixelExecutable = mRenderer->compileToExecutable(infoLog, finalPixelHLSL.c_str(), rx::SHADER_PIXEL,
+                                                                        transformFeedbackLinkedVaryings, separatedOutputBuffers,
+                                                                        mPixelWorkarounds);
 
     return pixelExecutable;
 }
 
-rx::ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
-                                                                    const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
-                                                                    const sh::Attribute shaderAttributes[],
-                                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
-                                                                    bool separatedOutputBuffers)
+ShaderExecutable *ProgramD3D::getVertexExecutableForInputLayout(gl::InfoLog &infoLog,
+                                                                const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
+                                                                const sh::Attribute shaderAttributes[],
+                                                                const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                                bool separatedOutputBuffers)
 {
     // Generate new dynamic layout with attribute conversions
     std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, shaderAttributes);
 
     // Generate new vertex executable
-    rx::ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(),
-                                                                            rx::SHADER_VERTEX,
-                                                                            transformFeedbackLinkedVaryings, separatedOutputBuffers,
-                                                                            mVertexWorkarounds);
+    ShaderExecutable *vertexExecutable = mRenderer->compileToExecutable(infoLog, finalVertexHLSL.c_str(),
+                                                                        rx::SHADER_VERTEX,
+                                                                        transformFeedbackLinkedVaryings, separatedOutputBuffers,
+                                                                        mVertexWorkarounds);
 
     return vertexExecutable;
 }
 
-rx::ShaderExecutable *ProgramD3D::getGeometryExecutable(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
-                                                        const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
-                                                        bool separatedOutputBuffers, int registers)
+ShaderExecutable *ProgramD3D::getGeometryExecutable(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
+                                                    const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                                    bool separatedOutputBuffers, int registers)
 {
-    rx::ShaderD3D *vertexShaderD3D = rx::ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
-    rx::ShaderD3D *fragmentShaderD3D = rx::ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
+    ShaderD3D *vertexShaderD3D = ShaderD3D::makeShaderD3D(vertexShader->getImplementation());
+    ShaderD3D *fragmentShaderD3D = ShaderD3D::makeShaderD3D(fragmentShader->getImplementation());
 
     std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D);
 
-    rx::ShaderExecutable *geometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(),
-                                                                              rx::SHADER_GEOMETRY, transformFeedbackLinkedVaryings,
-                                                                              separatedOutputBuffers, rx::ANGLE_D3D_WORKAROUND_NONE);
+    ShaderExecutable *geometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(),
+                                                                          rx::SHADER_GEOMETRY, transformFeedbackLinkedVaryings,
+                                                                          separatedOutputBuffers, rx::ANGLE_D3D_WORKAROUND_NONE);
 
     return geometryExecutable;
 }
 
+ShaderExecutable *ProgramD3D::loadExecutable(const void *function, size_t length, rx::ShaderType type,
+                                             const std::vector<gl::LinkedVarying> &transformFeedbackLinkedVaryings,
+                                             bool separatedOutputBuffers)
+{
+    return mRenderer->loadExecutable(function, length, type, transformFeedbackLinkedVaryings, separatedOutputBuffers);
+}
+
 bool ProgramD3D::link(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
                       const std::vector<std::string> &transformFeedbackVaryings, int *registers,
                       std::vector<gl::LinkedVarying> *linkedVaryings, std::map<int, gl::VariableLocation> *outputVariables)
@@ -235,6 +256,100 @@
     mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
 }
 
+gl::Error ProgramD3D::applyUniforms(const std::vector<gl::LinkedUniform*> &uniforms)
+{
+    return mRenderer->applyUniforms(*this, uniforms);
+}
+
+gl::Error ProgramD3D::applyUniformBuffers(const std::vector<gl::UniformBlock*> uniformBlocks, const std::vector<gl::Buffer*> boundBuffers,
+                                     const gl::Caps &caps)
+{
+    const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
+    const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
+
+    const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
+    const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+
+    for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
+    {
+        gl::UniformBlock *uniformBlock = uniformBlocks[uniformBlockIndex];
+        gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
+
+        ASSERT(uniformBlock && uniformBuffer);
+
+        if (uniformBuffer->getSize() < uniformBlock->dataSize)
+        {
+            // undefined behaviour
+            return gl::Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.");
+        }
+
+        // Unnecessary to apply an unreferenced standard or shared UBO
+        if (!uniformBlock->isReferencedByVertexShader() && !uniformBlock->isReferencedByFragmentShader())
+        {
+            continue;
+        }
+
+        if (uniformBlock->isReferencedByVertexShader())
+        {
+            unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
+            ASSERT(vertexUniformBuffers[registerIndex] == NULL);
+            ASSERT(registerIndex < caps.maxVertexUniformBlocks);
+            vertexUniformBuffers[registerIndex] = uniformBuffer;
+        }
+
+        if (uniformBlock->isReferencedByFragmentShader())
+        {
+            unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
+            ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
+            ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
+            fragmentUniformBuffers[registerIndex] = uniformBuffer;
+        }
+    }
+
+    return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+}
+
+bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
+                                            unsigned int registerIndex, const gl::Caps &caps)
+{
+    if (shader == GL_VERTEX_SHADER)
+    {
+        uniformBlock->vsRegisterIndex = registerIndex;
+        if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
+        {
+            infoLog.append("Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (%u)", caps.maxVertexUniformBlocks);
+            return false;
+        }
+    }
+    else if (shader == GL_FRAGMENT_SHADER)
+    {
+        uniformBlock->psRegisterIndex = registerIndex;
+        if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
+        {
+            infoLog.append("Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (%u)", caps.maxFragmentUniformBlocks);
+            return false;
+        }
+    }
+    else UNREACHABLE();
+
+    return true;
+}
+
+unsigned int ProgramD3D::getReservedUniformVectors(GLenum shader)
+{
+    if (shader == GL_VERTEX_SHADER)
+    {
+        return mRenderer->getReservedVertexUniformVectors();
+    }
+    else if (shader == GL_FRAGMENT_SHADER)
+    {
+        return mRenderer->getReservedFragmentUniformVectors();
+    }
+    else UNREACHABLE();
+
+    return 0;
+}
+
 void ProgramD3D::reset()
 {
     mVertexHLSL.clear();