Starting refactor of ProgramBinary

This is gonna take a while...

BUG=angle:731
Change-Id: Ief72c3361b6429f3f6e0bc2d2ea0810d523ff178
Reviewed-on: https://chromium-review.googlesource.com/215661
Tested-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/libGLESv2/renderer/ProgramImpl.h b/src/libGLESv2/renderer/ProgramImpl.h
new file mode 100644
index 0000000..28c026a
--- /dev/null
+++ b/src/libGLESv2/renderer/ProgramImpl.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramImpl.h: Defines the abstract rx::ProgramImpl class.
+
+#ifndef LIBGLESV2_RENDERER_PROGRAMIMPL_H_
+#define LIBGLESV2_RENDERER_PROGRAMIMPL_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/Constants.h"
+#include "libGLESv2/ProgramBinary.h"
+
+namespace rx
+{
+
+class DynamicHLSL;
+class Renderer;
+
+class ProgramImpl
+{
+public:
+    virtual ~ProgramImpl() { }
+
+    // TODO: Temporary interfaces to ease migration. Remove soon!
+    virtual Renderer *getRenderer() = 0;
+    virtual DynamicHLSL *getDynamicHLSL() = 0;
+    virtual void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms) = 0;
+
+    virtual void reset() = 0;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_PROGRAMIMPL_H_
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index 7216be9..0148ed7 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -57,6 +57,7 @@
 class BufferStorage;
 struct TranslatedIndexData;
 class ShaderImpl;
+class ProgramImpl;
 class ShaderExecutable;
 class SwapChain;
 class RenderTarget;
@@ -198,6 +199,7 @@
 
     // Shader creation
     virtual ShaderImpl *createShader(GLenum type) = 0;
+    virtual ProgramImpl *createProgram() = 0;
 
     // Shader operations
     virtual void releaseShaderCompiler() = 0;
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.cpp b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
new file mode 100644
index 0000000..87e0132
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.cpp
@@ -0,0 +1,81 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
+
+#include "common/utilities.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/ShaderExecutable.h"
+#include "libGLESv2/renderer/d3d/DynamicHLSL.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+ProgramD3D::ProgramD3D(rx::Renderer *renderer)
+    : ProgramImpl(),
+      mRenderer(renderer),
+      mDynamicHLSL(NULL),
+      mVertexUniformStorage(NULL),
+      mFragmentUniformStorage(NULL)
+{
+    mDynamicHLSL = new rx::DynamicHLSL(renderer);
+}
+
+ProgramD3D::~ProgramD3D()
+{
+    reset();
+    SafeDelete(mDynamicHLSL);
+}
+
+ProgramD3D *ProgramD3D::makeProgramD3D(ProgramImpl *impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(ProgramD3D*, impl));
+    return static_cast<ProgramD3D*>(impl);
+}
+
+const ProgramD3D *ProgramD3D::makeProgramD3D(const ProgramImpl *impl)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(const ProgramD3D*, impl));
+    return static_cast<const ProgramD3D*>(impl);
+}
+
+void ProgramD3D::initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms)
+{
+    // Compute total default block size
+    unsigned int vertexRegisters = 0;
+    unsigned int fragmentRegisters = 0;
+    for (size_t uniformIndex = 0; uniformIndex < uniforms.size(); uniformIndex++)
+    {
+        const gl::LinkedUniform &uniform = *uniforms[uniformIndex];
+
+        if (!gl::IsSampler(uniform.type))
+        {
+            if (uniform.isReferencedByVertexShader())
+            {
+                vertexRegisters = std::max(vertexRegisters, uniform.vsRegisterIndex + uniform.registerCount);
+            }
+            if (uniform.isReferencedByFragmentShader())
+            {
+                fragmentRegisters = std::max(fragmentRegisters, uniform.psRegisterIndex + uniform.registerCount);
+            }
+        }
+    }
+
+    mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u);
+    mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u);
+}
+
+void ProgramD3D::reset()
+{
+    SafeDelete(mVertexUniformStorage);
+    SafeDelete(mFragmentUniformStorage);
+}
+
+}
diff --git a/src/libGLESv2/renderer/d3d/ProgramD3D.h b/src/libGLESv2/renderer/d3d/ProgramD3D.h
new file mode 100644
index 0000000..3dd3b1f
--- /dev/null
+++ b/src/libGLESv2/renderer/d3d/ProgramD3D.h
@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#ifndef LIBGLESV2_RENDERER_PROGRAMD3D_H_
+#define LIBGLESV2_RENDERER_PROGRAMD3D_H_
+
+#include "libGLESv2/renderer/ProgramImpl.h"
+
+namespace gl
+{
+struct LinkedUniform;
+struct VertexFormat;
+}
+
+namespace rx
+{
+
+class UniformStorage;
+
+class ProgramD3D : public ProgramImpl
+{
+  public:
+    ProgramD3D(rx::Renderer *renderer);
+    virtual ~ProgramD3D();
+
+    static ProgramD3D *makeProgramD3D(ProgramImpl *impl);
+    static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl);
+
+    Renderer *getRenderer() { return mRenderer; }
+    DynamicHLSL *getDynamicHLSL() { return mDynamicHLSL; }
+
+    // D3D only
+    void initializeUniformStorage(const std::vector<gl::LinkedUniform*> &uniforms);
+
+    const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
+    const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
+
+    void reset();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
+
+    Renderer *mRenderer;
+    DynamicHLSL *mDynamicHLSL;
+
+    UniformStorage *mVertexUniformStorage;
+    UniformStorage *mFragmentUniformStorage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_PROGRAMD3D_H_
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index fba179f..5e45e2b 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -11,6 +11,7 @@
 #include "libGLESv2/FramebufferAttachment.h"
 #include "libGLESv2/ProgramBinary.h"
 #include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
@@ -1392,8 +1393,9 @@
         }
     }
 
-    const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getVertexUniformStorage());
-    const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programBinary.getFragmentUniformStorage());
+    const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation());
+    const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
+    const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
     ASSERT(vertexUniformStorage);
     ASSERT(fragmentUniformStorage);
 
@@ -2217,6 +2219,11 @@
     return new ShaderD3D(type, this);
 }
 
+ProgramImpl *Renderer11::createProgram()
+{
+    return new ProgramD3D(this);
+}
+
 void Renderer11::releaseShaderCompiler()
 {
     ShaderD3D::releaseCompiler();
diff --git a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
index 865de21..64de7b0 100644
--- a/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
+++ b/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h
@@ -141,6 +141,7 @@
 
     // Shader creation
     virtual ShaderImpl *createShader(GLenum type);
+    virtual ProgramImpl *createProgram();
 
     // Shader operations
     virtual void releaseShaderCompiler();
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index e3615f4..5136829 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -22,6 +22,7 @@
 #include "libGLESv2/renderer/d3d/d3d9/Fence9.h"
 #include "libGLESv2/renderer/d3d/d3d9/VertexArray9.h"
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
+#include "libGLESv2/renderer/d3d/ProgramD3D.h"
 #include "libGLESv2/renderer/d3d/ShaderD3D.h"
 #include "libGLESv2/renderer/d3d/TextureD3D.h"
 #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h"
@@ -2766,6 +2767,11 @@
     return new ShaderD3D(type, this);
 }
 
+ProgramImpl *Renderer9::createProgram()
+{
+    return new ProgramD3D(this);
+}
+
 void Renderer9::releaseShaderCompiler()
 {
     ShaderD3D::releaseCompiler();
diff --git a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
index 826a649..84e64dc 100644
--- a/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
+++ b/src/libGLESv2/renderer/d3d/d3d9/Renderer9.h
@@ -144,6 +144,7 @@
 
     // Shader creation
     virtual ShaderImpl *createShader(GLenum type);
+    virtual ProgramImpl *createProgram();
 
     // Shader operations
     virtual void releaseShaderCompiler();