Updating Program to remove shader compilation 16/254416/5
authorDavid Steele <david.steele@samsung.com>
Tue, 2 Mar 2021 12:25:54 +0000 (12:25 +0000)
committerDavid Steele <david.steele@samsung.com>
Tue, 2 Mar 2021 18:21:24 +0000 (18:21 +0000)
New Graphics API manages it's own shader compilation.

Change-Id: I86b08673e64e2cd3b2c70a082c9c0823337a90ec

automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h
automated-tests/src/dali/dali-test-suite-utils/test-graphics-program.cpp
automated-tests/src/dali/dali-test-suite-utils/test-graphics-program.h
dali/internal/render/shaders/program.cpp
dali/internal/render/shaders/program.h

index 5679a01..7aacf76 100644 (file)
@@ -2496,7 +2496,7 @@ private:
 
   // Shaders & Uniforms
   GLuint                                 mLastShaderIdUsed;
-  GLuint                                 mLastProgramIdUsed;
+  GLuint                                 mLastProgramIdUsed{0u};
   GLuint                                 mLastUniformIdUsed;
   typedef std::map<std::string, GLint>   UniformIDMap;
   typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
index adacc11..fe9c329 100644 (file)
@@ -54,6 +54,12 @@ T* Uncast(const Graphics::Buffer* object)
   return const_cast<T*>(static_cast<const T*>(object));
 }
 
+template<typename T>
+T* Uncast(const Graphics::Shader* object)
+{
+  return const_cast<T*>(static_cast<const T*>(object));
+}
+
 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
 {
   return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
@@ -711,7 +717,33 @@ Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(c
 Graphics::UniquePtr<Graphics::Program> TestGraphicsController::CreateProgram(const Graphics::ProgramCreateInfo& programCreateInfo, Graphics::UniquePtr<Graphics::Program>&& oldProgram)
 {
   mCallStack.PushCall("CreateProgram", "");
-  return Graphics::MakeUnique<TestGraphicsProgram>(mGl, programCreateInfo, mVertexFormats);
+
+  for(auto cacheEntry : mProgramCache)
+  {
+    bool found = true;
+    for(auto& shader : *(programCreateInfo.shaderState))
+    {
+      auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
+      if(memcmp(cacheEntry.shaders[shader.pipelineStage], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize))
+      {
+        found = false;
+        break;
+      }
+    }
+    if(found)
+    {
+      return Graphics::MakeUnique<TestGraphicsProgram>(cacheEntry.programImpl);
+    }
+  }
+
+  mProgramCache.emplace_back();
+  mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats);
+  for(auto& shader : *(programCreateInfo.shaderState))
+  {
+    auto graphicsShader                                = Uncast<TestGraphicsShader>(shader.shader);
+    mProgramCache.back().shaders[shader.pipelineStage] = graphicsShader->mCreateInfo.sourceData;
+  }
+  return Graphics::MakeUnique<TestGraphicsProgram>(mProgramCache.back().programImpl);
 }
 
 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
@@ -789,7 +821,7 @@ bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0,
   return false;
 }
 
-bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData )
+bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData)
 {
   mCallStack.PushCall("GetProgramParameter", "");
   auto graphicsProgram = Uncast<TestGraphicsProgram>(&program);
index 9179a39..fa2fd63 100644 (file)
@@ -21,6 +21,7 @@
 #include "test-gl-abstraction.h"
 #include "test-gl-context-helper-abstraction.h"
 #include "test-gl-sync-abstraction.h"
+#include "test-graphics-program.h"
 #include "test-graphics-reflection.h"
 
 namespace Dali
@@ -313,7 +314,7 @@ public: // Test Functions
    * @param[out] outData Pointer to output memory
    * @return True on success
    */
-  bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData ) override;
+  bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
 
 public:
   mutable TraceCallStack                    mCallStack;
@@ -328,6 +329,13 @@ public:
   bool isDrawOnResumeRequiredResult{true};
 
   Property::Array mVertexFormats;
+
+  struct ProgramCache
+  {
+    std::map<Graphics::PipelineStage, const void*> shaders;
+    TestGraphicsProgramImpl*                       programImpl;
+  };
+  std::vector<ProgramCache> mProgramCache;
 };
 
 } // namespace Dali
index 1b23380..9a0afa6 100644 (file)
 
 namespace Dali
 {
-TestGraphicsProgram::TestGraphicsProgram(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats)
+TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats)
 : mGl(gl),
   mCreateInfo(createInfo),
   mReflection(gl, vertexFormats)
 {
-  mId = 0;//mGl.CreateProgram();
+  mId = mGl.CreateProgram();
+  mGl.LinkProgram(1); // Ensure active sampler uniforms are set
 }
 
-bool TestGraphicsProgram::GetParameter(uint32_t parameterId, void* outData )
+bool TestGraphicsProgramImpl::GetParameter(uint32_t parameterId, void* outData)
 {
   reinterpret_cast<uint32_t*>(outData)[0] = mId;
   return true;
 }
 
+TestGraphicsProgram::TestGraphicsProgram(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats)
+{
+  mImpl = new TestGraphicsProgramImpl(gl, createInfo, vertexFormats);
+}
 
+TestGraphicsProgram::TestGraphicsProgram(TestGraphicsProgramImpl* impl)
+{
+  mImpl = impl;
+}
 
 } // namespace Dali
index d5f5b85..c098718 100644 (file)
 
 namespace Dali
 {
-class TestGraphicsProgram : public Graphics::Program
+class TestGraphicsProgramImpl
 {
 public:
-  TestGraphicsProgram(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats);
+  TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats);
 
   // For API
   const TestGraphicsReflection& GetReflection() const
@@ -37,12 +37,12 @@ public:
   }
 
   // For tests
-  TestGraphicsReflection& GetProgamReflection()
+  TestGraphicsReflection& GetProgramReflection()
   {
     return mReflection;
   }
 
-  bool GetParameter(uint32_t parameterId, void* outData );
+  bool GetParameter(uint32_t parameterId, void* outData);
 
 public:
   TestGlAbstraction&          mGl;
@@ -51,6 +51,30 @@ public:
   TestGraphicsReflection      mReflection;
 };
 
+class TestGraphicsProgram : public Graphics::Program
+{
+public:
+  TestGraphicsProgram(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats);
+  TestGraphicsProgram(TestGraphicsProgramImpl* impl);
+
+  const TestGraphicsReflection& GetReflection() const
+  {
+    return mImpl->GetReflection();
+  }
+  bool GetParameter(uint32_t parameterId, void* outData)
+  {
+    return mImpl->GetParameter(parameterId, outData);
+  }
+
+  TestGraphicsReflection& GetProgamReflection()
+  {
+    return mImpl->GetProgramReflection();
+  }
+
+public:
+  TestGraphicsProgramImpl* mImpl;
+};
+
 } // namespace Dali
 
 #endif //DALI_TEST_GRAPHICS_PROGRAM_H
index 6d42581..a6f6883 100644 (file)
@@ -23,6 +23,8 @@
 #include <iomanip>
 
 // INTERNAL INCLUDES
+#include <dali/graphics-api/graphics-controller.h>
+#include <dali/graphics-api/graphics-program.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/gl-defines.h>
 #include <dali/internal/common/shader-data.h>
 #include <dali/public-api/common/constants.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/dali-vector.h>
-#include <dali/graphics-api/graphics-program.h>
-#include <dali/graphics-api/graphics-controller.h>
-namespace
-{
-void LogWithLineNumbers(const char* source)
-{
-  uint32_t    lineNumber = 0u;
-  const char* prev       = source;
-  const char* ptr        = prev;
-
-  while(true)
-  {
-    if(lineNumber > 200u)
-    {
-      break;
-    }
-    // seek the next end of line or end of text
-    while(*ptr != '\n' && *ptr != '\0')
-    {
-      ++ptr;
-    }
-
-    std::string line(prev, ptr - prev);
-    Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, "%4d %s\n", lineNumber, line.c_str());
-
-    if(*ptr == '\0')
-    {
-      break;
-    }
-    prev = ++ptr;
-    ++lineNumber;
-  }
-}
-
-} //namespace
 
 namespace Dali
 {
@@ -106,35 +73,26 @@ Program* Program::New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, G
 
   // Get program id and use it as hash for the cache
   // in order to maintain current functionality as long as needed
-  gfxController.GetProgramParameter( *gfxProgram, 1, &programId );
+  gfxController.GetProgramParameter(*gfxProgram, 1, &programId);
 
   size_t   shaderHash = programId;
-
   Program* program    = cache.GetProgram(shaderHash);
 
   if(nullptr == program)
   {
     // program not found so create it
     program = new Program(cache, shaderData, gfxController, std::move(gfxProgram), modifiesGeometry);
-    program->Load();
+    program->GetActiveSamplerUniforms();
     cache.AddProgram(shaderHash, program);
   }
   return program;
 }
 
-
 void Program::Use()
 {
-  if(mLinked)
-  {
-    if(this != mCache.GetCurrentProgram())
-    {
-      LOG_GL("UseProgram(%d)\n", mProgramId);
-      CHECK_GL(mGlAbstraction, mGlAbstraction.UseProgram(mProgramId));
-
-      mCache.SetCurrentProgram(this);
-    }
-  }
+  LOG_GL("UseProgram(%d)\n", mProgramId);
+  CHECK_GL(mGlAbstraction, mGlAbstraction.UseProgram(mProgramId));
+  mCache.SetCurrentProgram(this);
 }
 
 bool Program::IsUsed()
@@ -619,11 +577,6 @@ void Program::GlContextCreated()
 
 void Program::GlContextDestroyed()
 {
-  mLinked           = false;
-  mVertexShaderId   = 0;
-  mFragmentShaderId = 0;
-  mProgramId        = 0;
-
   ResetAttribsUniformCache();
 }
 
@@ -637,12 +590,9 @@ Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphi
   mGlAbstraction(mCache.GetGlAbstraction()),
   mProjectionMatrix(nullptr),
   mViewMatrix(nullptr),
-  mLinked(false),
-  mVertexShaderId(0),
-  mFragmentShaderId(0),
   mProgramId(0),
-  mGfxProgram( std::move(gfxProgram)),
-  mGfxController( controller ),
+  mGfxProgram(std::move(gfxProgram)),
+  mGfxController(controller),
   mProgramData(shaderData),
   mModifiesGeometry(modifiesGeometry)
 {
@@ -666,237 +616,11 @@ Program::Program(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphi
 
   // Get program id and use it as hash for the cache
   // in order to maintain current functionality as long as needed
-  mGfxController.GetProgramParameter( *mGfxProgram, 1, &mProgramId );
-  mLinked = true;
+  mGfxController.GetProgramParameter(*mGfxProgram, 1, &mProgramId);
 }
 
 Program::~Program()
 {
-  Unload();
-}
-
-void Program::Load()
-{
-  // Temporary, exist if program id is already set
-  if(mProgramId)
-  {
-    GetActiveSamplerUniforms();
-    return;
-  }
-
-  DALI_ASSERT_ALWAYS(nullptr != mProgramData.Get() && "Program data is not initialized");
-  DALI_ASSERT_DEBUG(mProgramId == 0 && "mProgramId != 0, so about to leak a GL resource by overwriting it.");
-
-  LOG_GL("CreateProgram()\n");
-  mProgramId = CHECK_GL(mGlAbstraction, mGlAbstraction.CreateProgram());
-
-  GLint linked = GL_FALSE;
-
-  const bool binariesSupported = mCache.IsBinarySupported();
-
-  // if shader binaries are supported and ShaderData contains compiled bytecode?
-  if(binariesSupported && mProgramData->HasBinary())
-  {
-    DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - Using Compiled Shader, Size = %d\n", mProgramData->GetBufferSize());
-
-    CHECK_GL(mGlAbstraction, mGlAbstraction.ProgramBinary(mProgramId, mCache.ProgramBinaryFormat(), mProgramData->GetBufferData(), static_cast<GLsizei>(mProgramData->GetBufferSize()))); // truncated
-
-    CHECK_GL(mGlAbstraction, mGlAbstraction.ValidateProgram(mProgramId));
-
-    GLint success;
-    CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramiv(mProgramId, GL_VALIDATE_STATUS, &success));
-
-    DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "ValidateProgram Status = %d\n", success);
-
-    CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramiv(mProgramId, GL_LINK_STATUS, &linked));
-
-    if(GL_FALSE == linked)
-    {
-      DALI_LOG_ERROR("Failed to load program binary \n");
-
-      GLint nLength;
-      CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramiv(mProgramId, GL_INFO_LOG_LENGTH, &nLength));
-      if(nLength > 0)
-      {
-        Dali::Vector<char> szLog;
-        szLog.Reserve(nLength); // Don't call Resize as we don't want to initialise the data, just reserve a buffer
-        CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramInfoLog(mProgramId, nLength, &nLength, szLog.Begin()));
-        DALI_LOG_ERROR("Program Link Error: %s\n", szLog.Begin());
-      }
-    }
-    else
-    {
-      mLinked = true;
-      DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Reused binary.\n");
-    }
-  }
-
-  // Fall back to compiling and linking the vertex and fragment sources
-  if(GL_FALSE == linked)
-  {
-    DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - Runtime compilation\n");
-    if(CompileShader(GL_VERTEX_SHADER, mVertexShaderId, mProgramData->GetVertexShader()))
-    {
-      if(CompileShader(GL_FRAGMENT_SHADER, mFragmentShaderId, mProgramData->GetFragmentShader()))
-      {
-        Link();
-
-        if(binariesSupported && mLinked)
-        {
-          GLint  binaryLength = 0;
-          GLenum binaryFormat;
-          DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Compiled and linked.\n\nVS:\n%s\nFS:\n%s\n", mProgramData->GetVertexShader(), mProgramData->GetFragmentShader());
-
-          CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramiv(mProgramId, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength));
-          DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Program::Load() - GL_PROGRAM_BINARY_LENGTH_OES: %d\n", binaryLength);
-          if(binaryLength > 0)
-          {
-            // Allocate space for the bytecode in ShaderData
-            mProgramData->AllocateBuffer(binaryLength);
-            // Copy the bytecode to ShaderData
-            CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramBinary(mProgramId, binaryLength, nullptr, &binaryFormat, mProgramData->GetBufferData()));
-            mCache.StoreBinary(mProgramData);
-            DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "Saved binary.\n");
-          }
-        }
-      }
-    }
-  }
-
-  GetActiveSamplerUniforms();
-
-  // No longer needed
-  FreeShaders();
-}
-
-void Program::Unload()
-{
-  // Bypass when using gfx program
-  if(!mProgramData && mProgramId)
-  {
-    return;
-  }
-  FreeShaders();
-
-  if(this == mCache.GetCurrentProgram())
-  {
-    CHECK_GL(mGlAbstraction, mGlAbstraction.UseProgram(0));
-
-    mCache.SetCurrentProgram(nullptr);
-  }
-
-  if(mProgramId)
-  {
-    LOG_GL("DeleteProgram(%d)\n", mProgramId);
-    CHECK_GL(mGlAbstraction, mGlAbstraction.DeleteProgram(mProgramId));
-    mProgramId = 0;
-  }
-
-  mLinked = false;
-}
-
-bool Program::CompileShader(GLenum shaderType, GLuint& shaderId, const char* src)
-{
-  // Bypass when using gfx program
-  if(!mProgramData && mProgramId)
-  {
-    return true;
-  }
-  if(!shaderId)
-  {
-    LOG_GL("CreateShader(%d)\n", shaderType);
-    shaderId = CHECK_GL(mGlAbstraction, mGlAbstraction.CreateShader(shaderType));
-    LOG_GL("AttachShader(%d,%d)\n", mProgramId, shaderId);
-    CHECK_GL(mGlAbstraction, mGlAbstraction.AttachShader(mProgramId, shaderId));
-  }
-
-  LOG_GL("ShaderSource(%d)\n", shaderId);
-  CHECK_GL(mGlAbstraction, mGlAbstraction.ShaderSource(shaderId, 1, &src, nullptr));
-
-  LOG_GL("CompileShader(%d)\n", shaderId);
-  CHECK_GL(mGlAbstraction, mGlAbstraction.CompileShader(shaderId));
-
-  GLint compiled;
-  LOG_GL("GetShaderiv(%d)\n", shaderId);
-  CHECK_GL(mGlAbstraction, mGlAbstraction.GetShaderiv(shaderId, GL_COMPILE_STATUS, &compiled));
-
-  if(compiled == GL_FALSE)
-  {
-    DALI_LOG_ERROR("Failed to compile shader\n");
-    LogWithLineNumbers(src);
-
-    GLint nLength;
-    mGlAbstraction.GetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &nLength);
-    if(nLength > 0)
-    {
-      Dali::Vector<char> szLog;
-      szLog.Reserve(nLength); // Don't call Resize as we don't want to initialise the data, just reserve a buffer
-      mGlAbstraction.GetShaderInfoLog(shaderId, nLength, &nLength, szLog.Begin());
-      DALI_LOG_ERROR("Shader Compiler Error: %s\n", szLog.Begin());
-    }
-
-    DALI_ASSERT_ALWAYS(0 && "Shader compilation failure");
-  }
-
-  return compiled != 0;
-}
-
-void Program::Link()
-{
-  // Bypass when using gfx program
-  if(!mProgramData && mProgramId)
-  {
-    return;
-  }
-  LOG_GL("LinkProgram(%d)\n", mProgramId);
-  CHECK_GL(mGlAbstraction, mGlAbstraction.LinkProgram(mProgramId));
-
-  GLint linked;
-  LOG_GL("GetProgramiv(%d)\n", mProgramId);
-  CHECK_GL(mGlAbstraction, mGlAbstraction.GetProgramiv(mProgramId, GL_LINK_STATUS, &linked));
-
-  if(linked == GL_FALSE)
-  {
-    DALI_LOG_ERROR("Shader failed to link \n");
-
-    GLint nLength;
-    mGlAbstraction.GetProgramiv(mProgramId, GL_INFO_LOG_LENGTH, &nLength);
-    if(nLength > 0)
-    {
-      Dali::Vector<char> szLog;
-      szLog.Reserve(nLength); // Don't call Resize as we don't want to initialise the data, just reserve a buffer
-      mGlAbstraction.GetProgramInfoLog(mProgramId, nLength, &nLength, szLog.Begin());
-      DALI_LOG_ERROR("Shader Link Error: %s\n", szLog.Begin());
-    }
-
-    DALI_ASSERT_ALWAYS(0 && "Shader linking failure");
-  }
-
-  mLinked = linked != GL_FALSE;
-}
-
-void Program::FreeShaders()
-{
-  // Bypass when using gfx program
-  if(!mProgramData && mProgramId)
-  {
-    return;
-  }
-  if(mVertexShaderId)
-  {
-    LOG_GL("DeleteShader(%d)\n", mVertexShaderId);
-    CHECK_GL(mGlAbstraction, mGlAbstraction.DetachShader(mProgramId, mVertexShaderId));
-    CHECK_GL(mGlAbstraction, mGlAbstraction.DeleteShader(mVertexShaderId));
-    mVertexShaderId = 0;
-  }
-
-  if(mFragmentShaderId)
-  {
-    LOG_GL("DeleteShader(%d)\n", mFragmentShaderId);
-    CHECK_GL(mGlAbstraction, mGlAbstraction.DetachShader(mProgramId, mFragmentShaderId));
-    CHECK_GL(mGlAbstraction, mGlAbstraction.DeleteShader(mFragmentShaderId));
-    mFragmentShaderId = 0;
-  }
 }
 
 void Program::ResetAttribsUniformCache()
index d1047b5..d26fcc5 100644 (file)
@@ -35,7 +35,7 @@ namespace Graphics
 {
 class Controller;
 class Program;
-}
+} // namespace Graphics
 class Matrix;
 
 namespace Integration
@@ -341,51 +341,19 @@ private:
   Program& operator=(const Program&); ///< assignment operator, not defined
 
   /**
-   * Load the shader, from a precompiled binary if available, else from source code
-   */
-  void Load();
-
-  /**
-   * Unload the shader
-   */
-  void Unload();
-
-  /**
-   * Compile the shader
-   * @param shaderType vertex or fragment shader
-   * @param shaderId of the shader, returned
-   * @param src of the shader
-   * @return true if the compilation succeeded
-   */
-  bool CompileShader(GLenum shaderType, GLuint& shaderId, const char* src);
-
-  /**
-   * Links the shaders together to create program
-   */
-  void Link();
-
-  /**
-   * Frees the shader programs
-   */
-  void FreeShaders();
-
-  /**
    * Resets caches
    */
   void ResetAttribsUniformCache();
 
-private:                                         // Data
-  ProgramCache&               mCache;            ///< The program cache
-  Integration::GlAbstraction& mGlAbstraction;    ///< The OpenGL Abstraction layer
-  const Matrix*               mProjectionMatrix; ///< currently set projection matrix
-  const Matrix*               mViewMatrix;       ///< currently set view matrix
-  bool                        mLinked;           ///< whether the program is linked
-  GLuint                      mVertexShaderId;   ///< GL identifier for vertex shader
-  GLuint                      mFragmentShaderId; ///< GL identifier for fragment shader
-  GLuint                      mProgramId;        ///< GL identifier for program
-  Graphics::UniquePtr<Graphics::Program> mGfxProgram; ///< Gfx program
-  Graphics::Controller&       mGfxController;    /// < Gfx controller
-  Internal::ShaderDataPtr     mProgramData;      ///< Shader program source and binary (when compiled & linked or loaded)
+private:                                                    // Data
+  ProgramCache&                          mCache;            ///< The program cache
+  Integration::GlAbstraction&            mGlAbstraction;    ///< The OpenGL Abstraction layer
+  const Matrix*                          mProjectionMatrix; ///< currently set projection matrix
+  const Matrix*                          mViewMatrix;       ///< currently set view matrix
+  GLuint                                 mProgramId;        ///< GL identifier for program
+  Graphics::UniquePtr<Graphics::Program> mGfxProgram;       ///< Gfx program
+  Graphics::Controller&                  mGfxController;    /// < Gfx controller
+  Internal::ShaderDataPtr                mProgramData;      ///< Shader program source and binary (when compiled & linked or loaded)
 
   // location caches
   using NameLocationPair = std::pair<ConstString, GLint>;