Test harness sync
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-gl-abstraction.h
index 99dca10..a1f8405 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_GL_ABSTRACTION_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 namespace Dali
 {
-static const unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 64;
-static const char*        mStdAttribs[MAX_ATTRIBUTE_CACHE_SIZE] =
-  {
-    "aPosition",    // ATTRIB_POSITION
-    "aNormal",      // ATTRIB_NORMAL
-    "aTexCoord",    // ATTRIB_TEXCOORD
-    "aColor",       // ATTRIB_COLOR
-    "aBoneWeights", // ATTRIB_BONE_WEIGHTS
-    "aBoneIndices"  // ATTRIB_BONE_INDICES
+struct UniformData
+{
+  std::string    name;
+  Property::Type type;
+  UniformData(const std::string& name, Property::Type type = Property::Type::NONE)
+  : name(name),
+    type(type)
+  {
+  }
+};
+
+struct ActiveUniform
+{
+  std::string name;
+  GLenum      type;
+  GLint       size;
 };
 
 class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
 {
 public:
+  static const int MAX_ATTRIBUTE_CACHE_SIZE{64};
+
   TestGlAbstraction();
   ~TestGlAbstraction() override;
   void Initialize();
@@ -61,6 +70,16 @@ public:
 
   bool IsSurfacelessContextSupported() const override;
 
+  bool IsAdvancedBlendEquationSupported() override;
+
+  bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
+
+  std::string GetShaderVersionPrefix();
+
+  std::string GetVertexShaderPrefix();
+
+  std::string GetFragmentShaderPrefix();
+
   bool TextureRequiresConverting(const GLenum imageGlFormat, const GLenum textureGlFormat, const bool isSubImage) const override;
 
   /* OpenGL ES 2.0 */
@@ -81,8 +100,8 @@ public:
     out << program << ", " << shader;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["program"] = ToString(program);
-    namedParams["shader"]  = ToString(shader);
+    namedParams["program"] << program;
+    namedParams["shader"] << shader;
     mShaderTrace.PushCall("AttachShader", out.str(), namedParams);
   }
 
@@ -92,6 +111,12 @@ public:
 
   inline void BindBuffer(GLenum target, GLuint buffer) override
   {
+    std::ostringstream o;
+    o << std::hex << target << ", " << buffer;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["target"] << target;
+    namedParams["buffer"] << buffer;
+    mBufferTrace.PushCall("BindBuffer", o.str(), namedParams);
   }
 
   inline void BindFramebuffer(GLenum target, GLuint framebuffer) override
@@ -150,11 +175,11 @@ public:
     }
 
     std::stringstream out;
-    out << target << ", " << texture;
+    out << std::hex << target << ", " << std::dec << texture;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]  = ToString(target);
-    namedParams["texture"] = ToString(texture);
+    namedParams["target"] << std::hex << target;
+    namedParams["texture"] << texture;
 
     mTextureTrace.PushCall("BindTexture", out.str(), namedParams);
   }
@@ -232,11 +257,28 @@ public:
 
   inline void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage) override
   {
+    std::ostringstream o;
+    o << std::hex << target << ", " << size << ", " << data << ", " << usage;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["target"] << std::hex << target;
+    namedParams["size"] << size;
+    namedParams["usage"] << usage;
+
+    mBufferTrace.PushCall("BufferData", o.str(), namedParams);
+
     mBufferDataCalls.push_back(size);
   }
 
   inline void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) override
   {
+    std::ostringstream o;
+    o << std::hex << target << ", " << offset << ", " << size << ", " << data;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["target"] << std::hex << target;
+    namedParams["offset"] << offset;
+    namedParams["size"] << size;
+    mBufferTrace.PushCall("BufferSubData", o.str());
+
     mBufferSubDataCalls.push_back(size);
   }
 
@@ -296,7 +338,7 @@ public:
     out << s;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["s"] = ToString(s);
+    namedParams["s"] << s;
 
     mStencilFunctionTrace.PushCall("ClearStencil", out.str(), namedParams);
   }
@@ -314,7 +356,7 @@ public:
     std::stringstream out;
     out << shader;
     TraceCallStack::NamedParams namedParams;
-    namedParams["shader"] = ToString(shader);
+    namedParams["shader"] << shader;
 
     mShaderTrace.PushCall("CompileShader", out.str(), namedParams);
   }
@@ -325,13 +367,13 @@ public:
     out << target << ", " << level << ", " << width << ", " << height;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]         = ToString(target);
-    namedParams["level"]          = ToString(level);
-    namedParams["internalformat"] = ToString(internalformat);
-    namedParams["width"]          = ToString(width);
-    namedParams["height"]         = ToString(height);
-    namedParams["border"]         = ToString(border);
-    namedParams["size"]           = ToString(imageSize);
+    namedParams["target"] << std::hex << target;
+    namedParams["level"] << level;
+    namedParams["internalformat"] << internalformat;
+    namedParams["width"] << width;
+    namedParams["height"] << height;
+    namedParams["border"] << border;
+    namedParams["size"] << imageSize;
 
     mTextureTrace.PushCall("CompressedTexImage2D", out.str(), namedParams);
   }
@@ -342,12 +384,12 @@ public:
     out << target << ", " << level << ", " << xoffset << ", " << yoffset << ", " << width << ", " << height;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]  = ToString(target);
-    namedParams["level"]   = ToString(level);
-    namedParams["xoffset"] = ToString(xoffset);
-    namedParams["yoffset"] = ToString(yoffset);
-    namedParams["width"]   = ToString(width);
-    namedParams["height"]  = ToString(height);
+    namedParams["target"] << std::hex << target;
+    namedParams["level"] << level;
+    namedParams["xoffset"] << xoffset;
+    namedParams["yoffset"] << yoffset;
+    namedParams["width"] << width;
+    namedParams["height"] << height;
     mTextureTrace.PushCall("CompressedTexSubImage2D", out.str(), namedParams);
   }
 
@@ -374,7 +416,7 @@ public:
     out << type;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["type"] = ToString(type);
+    namedParams["type"] << std::hex << type;
     mShaderTrace.PushCall("CreateShader", out.str(), namedParams);
 
     return ++mLastShaderIdUsed;
@@ -383,10 +425,10 @@ public:
   inline void CullFace(GLenum mode) override
   {
     std::stringstream out;
-    out << mode;
+    out << std::hex << mode;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["program"] = ToString(mode);
+    namedParams["mode"] << std::hex << mode;
 
     mCullFaceTrace.PushCall("CullFace", out.str(), namedParams);
   }
@@ -405,7 +447,7 @@ public:
     out << program;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["program"] = ToString(program);
+    namedParams["program"] << program;
 
     mShaderTrace.PushCall("DeleteProgram", out.str(), namedParams);
   }
@@ -420,7 +462,7 @@ public:
     out << shader;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["shader"] = ToString(shader);
+    namedParams["shader"] << shader;
 
     mShaderTrace.PushCall("DeleteShader", out.str(), namedParams);
   }
@@ -428,16 +470,16 @@ public:
   inline void DeleteTextures(GLsizei n, const GLuint* textures) override
   {
     std::stringstream out;
-    out << n << ", " << textures << " = [";
+    out << "n:" << n << " textures[";
 
     TraceCallStack::NamedParams namedParams;
 
     for(GLsizei i = 0; i < n; i++)
     {
-      out << textures[i] << ", ";
+      out << (i > 0 ? ", " : "") << textures[i];
       std::stringstream paramName;
       paramName << "texture[" << i << "]";
-      namedParams[paramName.str()] = ToString(textures[i]);
+      namedParams[paramName.str()] << textures[i];
       mDeletedTextureIds.push_back(textures[i]);
       mNumGeneratedTextures--;
     }
@@ -474,10 +516,10 @@ public:
   inline void DepthFunc(GLenum func) override
   {
     std::stringstream out;
-    out << func;
+    out << std::hex << func;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["func"] = ToString(func);
+    namedParams["func"] << std::hex << func;
 
     mDepthFunctionTrace.PushCall("DepthFunc", out.str(), namedParams);
   }
@@ -501,22 +543,27 @@ public:
     std::stringstream out;
     out << program << ", " << shader;
     TraceCallStack::NamedParams namedParams;
-    namedParams["program"] = ToString(program);
-    namedParams["shader"]  = ToString(shader);
+    namedParams["program"] << program;
+    namedParams["shader"] << shader;
     mShaderTrace.PushCall("DetachShader", out.str(), namedParams);
   }
 
   inline void Disable(GLenum cap) override
   {
     std::stringstream out;
-    out << cap;
+    out << std::hex << cap;
     TraceCallStack::NamedParams namedParams;
-    namedParams["cap"] = ToString(cap);
+    namedParams["cap"] << std::hex << cap;
     mEnableDisableTrace.PushCall("Disable", out.str(), namedParams);
   }
 
   inline void DisableVertexAttribArray(GLuint index) override
   {
+    std::stringstream out;
+    out << index;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["index"] << index;
+    mBufferTrace.PushCall("DisableVertexAttribArray", out.str(), namedParams);
     SetVertexAttribArray(index, false);
   }
 
@@ -525,9 +572,9 @@ public:
     std::stringstream out;
     out << mode << ", " << first << ", " << count;
     TraceCallStack::NamedParams namedParams;
-    namedParams["mode"]  = ToString(mode);
-    namedParams["first"] = ToString(first);
-    namedParams["count"] = ToString(count);
+    namedParams["mode"] << std::hex << mode;
+    namedParams["first"] << first;
+    namedParams["count"] << count;
     mDrawTrace.PushCall("DrawArrays", out.str(), namedParams);
   }
 
@@ -537,9 +584,9 @@ public:
     out << mode << ", " << count << ", " << type << ", indices";
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["mode"]  = ToString(mode);
-    namedParams["count"] = ToString(count);
-    namedParams["type"]  = ToString(type);
+    namedParams["mode"] << std::hex << mode;
+    namedParams["count"] << count;
+    namedParams["type"] << type;
     // Skip void pointers - are they of any use?
     mDrawTrace.PushCall("DrawElements", out.str(), namedParams);
   }
@@ -547,14 +594,19 @@ public:
   inline void Enable(GLenum cap) override
   {
     std::stringstream out;
-    out << cap;
+    out << std::hex << cap;
     TraceCallStack::NamedParams namedParams;
-    namedParams["cap"] = ToString(cap);
+    namedParams["cap"] << std::hex << cap;
     mEnableDisableTrace.PushCall("Enable", out.str(), namedParams);
   }
 
   inline void EnableVertexAttribArray(GLuint index) override
   {
+    std::stringstream out;
+    out << index;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["index"] << index;
+    mBufferTrace.PushCall("EnableVertexAttribArray", out.str(), namedParams);
     SetVertexAttribArray(index, true);
   }
 
@@ -576,6 +628,11 @@ public:
     {
       mFramebufferStencilAttached = true;
     }
+    else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+    {
+      mFramebufferStencilAttached = true;
+      mFramebufferDepthAttached   = true;
+    }
   }
 
   inline void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) override
@@ -597,12 +654,19 @@ public:
 
   inline void FrontFace(GLenum mode) override
   {
+    // do nothing
   }
 
   inline void GenBuffers(GLsizei n, GLuint* buffers) override
   {
     // avoids an assert in GpuBuffers
     *buffers = 1u;
+
+    std::ostringstream o;
+    o << n;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["n"] << o.str();
+    mBufferTrace.PushCall("GenBuffers", o.str(), namedParams);
   }
 
   inline void GenerateMipmap(GLenum target) override
@@ -610,7 +674,7 @@ public:
     std::stringstream out;
     out << target;
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"] = ToString(target);
+    namedParams["target"] << std::hex << target;
 
     mTextureTrace.PushCall("GenerateMipmap", out.str(), namedParams);
   }
@@ -665,7 +729,7 @@ public:
     }
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["count"] = ToString(count);
+    namedParams["count"] << count;
 
     std::stringstream out;
     for(int i = 0; i < count; i++)
@@ -677,7 +741,7 @@ public:
       }
       std::ostringstream oss;
       oss << "indices[" << i << "]";
-      namedParams[oss.str()] = ToString(textures[i]);
+      namedParams[oss.str()] << textures[i];
     }
 
     mTextureTrace.PushCall("GenTextures", out.str(), namedParams);
@@ -697,27 +761,18 @@ public:
   {
   }
 
+  inline void SetActiveUniforms(const std::vector<ActiveUniform>& uniforms)
+  {
+    mActiveUniforms = uniforms;
+  }
+
   inline void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
   {
-    switch(index)
+    if(index < mActiveUniforms.size())
     {
-      case 0:
-        *length = snprintf(name, bufsize, "sTexture");
-        *type   = GL_SAMPLER_2D;
-        *size   = 1;
-        break;
-      case 1:
-        *length = snprintf(name, bufsize, "sEffect");
-        *type   = GL_SAMPLER_2D;
-        *size   = 1;
-        break;
-      case 2:
-        *length = snprintf(name, bufsize, "sGloss");
-        *type   = GL_SAMPLER_2D;
-        *size   = 1;
-        break;
-      default:
-        break;
+      *length = snprintf(name, bufsize, "%s", mActiveUniforms[index].name.c_str());
+      *type   = mActiveUniforms[index].type;
+      *size   = mActiveUniforms[index].size;
     }
   }
 
@@ -727,18 +782,11 @@ public:
 
   inline int GetAttribLocation(GLuint program, const char* name) override
   {
-    std::string attribName(name);
-
-    for(unsigned int i = 0; i < ATTRIB_TYPE_LAST; ++i)
-    {
-      if(mStdAttribs[i] == attribName)
-      {
-        return i;
-      }
-    }
-
-    // 0 is a valid location
-    return 0;
+    std::string check(name);
+    auto        iter = std::find(mAttribLocs.begin(), mAttribLocs.end(), check);
+    if(iter == mAttribLocs.end())
+      return -1;
+    return iter - mAttribLocs.begin();
   }
 
   inline void GetBooleanv(GLenum pname, GLboolean* params) override
@@ -792,11 +840,14 @@ public:
         *params = mProgramBinaryLength;
         break;
       case GL_ACTIVE_UNIFORMS:
-        *params = mNumberOfActiveUniforms;
+        *params = mActiveUniforms.size();
         break;
       case GL_ACTIVE_UNIFORM_MAX_LENGTH:
         *params = 100;
         break;
+      case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+        *params = 100;
+        break;
     }
   }
 
@@ -863,7 +914,7 @@ public:
     {
       // Uniform not found, so add it...
       uniformIDs[name] = ++mLastUniformIdUsed;
-      return mLastUniformIdUsed;
+      return uniformIDs[name];
     }
 
     return it2->second;
@@ -930,13 +981,41 @@ public:
     out << program;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["program"] = ToString(program);
+    namedParams["program"] << program;
     mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
 
-    mNumberOfActiveUniforms = 3;
-    GetUniformLocation(program, "sTexture");
-    GetUniformLocation(program, "sEffect");
-    GetUniformLocation(program, "sGloss");
+    for(const auto& uniform : mActiveUniforms)
+    {
+      GetUniformLocation(program, uniform.name.c_str());
+    }
+
+    for(const auto& uniform : mCustomUniformData)
+    {
+      auto iter = uniform.name.find("[");
+      auto name = uniform.name;
+      if(iter != std::string::npos)
+      {
+        name            = uniform.name.substr(0, iter);
+        auto arrayCount = std::stoi(uniform.name.substr(iter + 1));
+        iter            = uniform.name.find("]");
+        std::string suffix;
+        if(iter != std::string::npos && iter + 1 != uniform.name.length())
+        {
+          suffix = uniform.name.substr(iter + 1); // If there is a suffix, it means its an element of an array of struct
+        }
+
+        for(int i = 0; i < arrayCount; ++i)
+        {
+          std::stringstream nss;
+          nss << name << "[" << i << "]" << suffix;
+          GetUniformLocation(program, nss.str().c_str()); // Generate a GL loc per element
+        }
+      }
+      else
+      {
+        GetUniformLocation(program, name.c_str());
+      }
+    }
   }
 
   inline void PixelStorei(GLenum pname, GLint param) override
@@ -973,10 +1052,10 @@ public:
     std::stringstream out;
     out << x << ", " << y << ", " << width << ", " << height;
     TraceCallStack::NamedParams namedParams;
-    namedParams["x"]      = ToString(x);
-    namedParams["y"]      = ToString(y);
-    namedParams["width"]  = ToString(width);
-    namedParams["height"] = ToString(height);
+    namedParams["x"] << x;
+    namedParams["y"] << y;
+    namedParams["width"] << width;
+    namedParams["height"] << height;
     mScissorTrace.PushCall("Scissor", out.str(), namedParams);
   }
 
@@ -1023,9 +1102,9 @@ public:
     out << func << ", " << ref << ", " << mask;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["func"] = ToString(func);
-    namedParams["ref"]  = ToString(ref);
-    namedParams["mask"] = ToString(mask);
+    namedParams["func"] << std::hex << func;
+    namedParams["ref"] << ref;
+    namedParams["mask"] << mask;
 
     mStencilFunctionTrace.PushCall("StencilFunc", out.str(), namedParams);
   }
@@ -1036,10 +1115,10 @@ public:
     out << face << ", " << func << ", " << ref << ", " << mask;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["face"] = ToString(face);
-    namedParams["func"] = ToString(func);
-    namedParams["ref"]  = ToString(ref);
-    namedParams["mask"] = ToString(mask);
+    namedParams["face"] << std::hex << face;
+    namedParams["func"] << std::hex << func;
+    namedParams["ref"] << ref;
+    namedParams["mask"] << mask;
 
     mStencilFunctionTrace.PushCall("StencilFuncSeparate", out.str(), namedParams);
   }
@@ -1050,7 +1129,7 @@ public:
     out << mask;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["mask"] = ToString(mask);
+    namedParams["mask"] << mask;
 
     mStencilFunctionTrace.PushCall("StencilMask", out.str(), namedParams);
   }
@@ -1061,8 +1140,8 @@ public:
     out << face << ", " << mask;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["face"] = ToString(face);
-    namedParams["mask"] = ToString(mask);
+    namedParams["face"] << std::hex << face;
+    namedParams["mask"] << mask;
 
     mStencilFunctionTrace.PushCall("StencilMaskSeparate", out.str(), namedParams);
   }
@@ -1073,9 +1152,9 @@ public:
     out << fail << ", " << zfail << ", " << zpass;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["fail"]  = ToString(fail);
-    namedParams["zfail"] = ToString(zfail);
-    namedParams["zpass"] = ToString(zpass);
+    namedParams["fail"] << std::hex << fail;
+    namedParams["zfail"] << std::hex << zfail;
+    namedParams["zpass"] << std::hex << zpass;
 
     mStencilFunctionTrace.PushCall("StencilOp", out.str(), namedParams);
   }
@@ -1086,10 +1165,10 @@ public:
     out << face << ", " << fail << ", " << zfail << "," << zpass;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["face"]  = ToString(face);
-    namedParams["fail"]  = ToString(fail);
-    namedParams["zfail"] = ToString(zfail);
-    namedParams["zpass"] = ToString(zpass);
+    namedParams["face"] << std::hex << face;
+    namedParams["fail"] << std::hex << fail;
+    namedParams["zfail"] << std::hex << zfail;
+    namedParams["zpass"] << std::hex << zpass;
 
     mStencilFunctionTrace.PushCall("StencilOpSeparate", out.str(), namedParams);
   }
@@ -1100,14 +1179,14 @@ public:
     out << target << ", " << level << ", " << width << ", " << height;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]         = ToString(target);
-    namedParams["level"]          = ToString(level);
-    namedParams["internalformat"] = ToString(internalformat);
-    namedParams["width"]          = ToString(width);
-    namedParams["height"]         = ToString(height);
-    namedParams["border"]         = ToString(border);
-    namedParams["format"]         = ToString(format);
-    namedParams["type"]           = ToString(type);
+    namedParams["target"] << std::hex << target;
+    namedParams["level"] << level;
+    namedParams["internalformat"] << internalformat;
+    namedParams["width"] << width;
+    namedParams["height"] << height;
+    namedParams["border"] << border;
+    namedParams["format"] << std::hex << format;
+    namedParams["type"] << std::hex << type;
 
     mTextureTrace.PushCall("TexImage2D", out.str(), namedParams);
   }
@@ -1118,11 +1197,11 @@ public:
     out << target << ", " << pname << ", " << param;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"] = ToString(target);
-    namedParams["pname"]  = ToString(pname);
-    namedParams["param"]  = ToString(param);
+    namedParams["target"] << std::hex << target;
+    namedParams["pname"] << std::hex << pname;
+    namedParams["param"] << param;
 
-    mTexParamaterTrace.PushCall("TexParameterf", out.str(), namedParams);
+    mTexParameterTrace.PushCall("TexParameterf", out.str(), namedParams);
   }
 
   inline void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) override
@@ -1131,22 +1210,24 @@ public:
     out << target << ", " << pname << ", " << params[0];
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]    = ToString(target);
-    namedParams["pname"]     = ToString(pname);
-    namedParams["params[0]"] = ToString(params[0]);
+    namedParams["target"] << std::hex << target;
+    namedParams["pname"] << std::hex << pname;
+    namedParams["params[0]"] << params[0];
 
-    mTexParamaterTrace.PushCall("TexParameterfv", out.str(), namedParams);
+    mTexParameterTrace.PushCall("TexParameterfv", out.str(), namedParams);
   }
 
   inline void TexParameteri(GLenum target, GLenum pname, GLint param) override
   {
     std::stringstream out;
-    out << target << ", " << pname << ", " << param;
+    out << std::hex << target << ", " << pname << ", " << param;
+    std::string params = out.str();
+
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"] = ToString(target);
-    namedParams["pname"]  = ToString(pname);
-    namedParams["param"]  = ToString(param);
-    mTexParamaterTrace.PushCall("TexParameteri", out.str(), namedParams);
+    namedParams["target"] << std::hex << target;
+    namedParams["pname"] << std::hex << pname;
+    namedParams["param"] << param;
+    mTexParameterTrace.PushCall("TexParameteri", params, namedParams);
   }
 
   inline void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override
@@ -1154,10 +1235,10 @@ public:
     std::stringstream out;
     out << target << ", " << pname << ", " << params[0];
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]    = ToString(target);
-    namedParams["pname"]     = ToString(pname);
-    namedParams["params[0]"] = ToString(params[0]);
-    mTexParamaterTrace.PushCall("TexParameteriv", out.str(), namedParams);
+    namedParams["target"] << std::hex << target;
+    namedParams["pname"] << std::hex << pname;
+    namedParams["params[0]"] << params[0];
+    mTexParameterTrace.PushCall("TexParameteriv", out.str(), namedParams);
   }
 
   inline void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) override
@@ -1166,18 +1247,18 @@ public:
     out << target << ", " << level << ", " << xoffset << ", " << yoffset << ", " << width << ", " << height;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"]  = ToString(target);
-    namedParams["level"]   = ToString(level);
-    namedParams["xoffset"] = ToString(xoffset);
-    namedParams["yoffset"] = ToString(yoffset);
-    namedParams["width"]   = ToString(width);
-    namedParams["height"]  = ToString(height);
+    namedParams["target"] << std::hex << target;
+    namedParams["level"] << level;
+    namedParams["xoffset"] << xoffset;
+    namedParams["yoffset"] << yoffset;
+    namedParams["width"] << width;
+    namedParams["height"] << height;
     mTextureTrace.PushCall("TexSubImage2D", out.str(), namedParams);
   }
 
   inline void Uniform1f(GLint location, GLfloat value) override
   {
-    std::string params = ToString(value);
+    std::string params = std::to_string(value);
     AddUniformCallToTraceStack(location, params);
 
     if(!mProgramUniforms1f.SetUniformValue(mCurrentProgram, location, value))
@@ -1191,7 +1272,7 @@ public:
     std::string params;
     for(int i = 0; i < count; ++i)
     {
-      params = params + ToString(v[i]) + ",";
+      params = params + std::to_string(v[i]) + ",";
     }
 
     AddUniformCallToTraceStack(location, params);
@@ -1208,7 +1289,7 @@ public:
 
   inline void Uniform1i(GLint location, GLint x) override
   {
-    std::string params = ToString(x);
+    std::string params = std::to_string(x);
 
     AddUniformCallToTraceStack(location, params);
 
@@ -1220,8 +1301,9 @@ public:
 
   inline void Uniform1iv(GLint location, GLsizei count, const GLint* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
 
     for(int i = 0; i < count; ++i)
     {
@@ -1237,7 +1319,7 @@ public:
 
   inline void Uniform2f(GLint location, GLfloat x, GLfloat y) override
   {
-    std::string params = ToString(x) + "," + ToString(y);
+    std::string params = std::to_string(x) + "," + std::to_string(y);
     AddUniformCallToTraceStack(location, params);
 
     if(!mProgramUniforms2f.SetUniformValue(mCurrentProgram,
@@ -1250,8 +1332,9 @@ public:
 
   inline void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
 
     for(int i = 0; i < count; ++i)
     {
@@ -1267,19 +1350,20 @@ public:
 
   inline void Uniform2i(GLint location, GLint x, GLint y) override
   {
-    std::string params = ToString(x) + "," + ToString(y);
+    std::string params = std::to_string(x) + "," + std::to_string(y);
     AddUniformCallToTraceStack(location, params);
   }
 
   inline void Uniform2iv(GLint location, GLsizei count, const GLint* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
   }
 
   inline void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) override
   {
-    std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z);
+    std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z);
     AddUniformCallToTraceStack(location, params);
 
     if(!mProgramUniforms3f.SetUniformValue(mCurrentProgram,
@@ -1292,8 +1376,9 @@ public:
 
   inline void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
 
     for(int i = 0; i < count; ++i)
     {
@@ -1310,19 +1395,20 @@ public:
 
   inline void Uniform3i(GLint location, GLint x, GLint y, GLint z) override
   {
-    std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z);
+    std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z);
     AddUniformCallToTraceStack(location, params);
   }
 
   inline void Uniform3iv(GLint location, GLsizei count, const GLint* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
   }
 
   inline void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) override
   {
-    std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z) + "," + ToString(w);
+    std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "," + std::to_string(w);
     AddUniformCallToTraceStack(location, params);
 
     if(!mProgramUniforms4f.SetUniformValue(mCurrentProgram,
@@ -1335,8 +1421,9 @@ public:
 
   inline void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
 
     for(int i = 0; i < count; ++i)
     {
@@ -1353,26 +1440,29 @@ public:
 
   inline void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) override
   {
-    std::string params = ToString(x) + "," + ToString(y) + "," + ToString(z) + "," + ToString(w);
+    std::string params = std::to_string(x) + "," + std::to_string(y) + "," + std::to_string(z) + "," + std::to_string(w);
     AddUniformCallToTraceStack(location, params);
   }
 
   inline void Uniform4iv(GLint location, GLsizei count, const GLint* v) override
   {
-    std::string params = ToString(v);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << v[i];
+    AddUniformCallToTraceStack(location, out.str());
   }
 
   inline void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
   {
-    std::string params = ToString(value);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << value[i];
+    AddUniformCallToTraceStack(location, out.str());
   }
 
   inline void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
   {
-    std::string params = ToString(value);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << value[i];
+    AddUniformCallToTraceStack(location, out.str());
 
     for(int i = 0; i < count; ++i)
     {
@@ -1389,8 +1479,9 @@ public:
 
   inline void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) override
   {
-    std::string params = ToString(value);
-    AddUniformCallToTraceStack(location, params);
+    std::ostringstream out;
+    for(GLsizei i = 0; i < count; ++i) out << (!i ? "" : ", ") << value[i];
+    AddUniformCallToTraceStack(location, out.str());
 
     for(int i = 0; i < count; ++i)
     {
@@ -1446,8 +1537,17 @@ public:
   {
   }
 
-  inline void VertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) override
+  inline void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) override
   {
+    TraceCallStack::NamedParams namedParams;
+    namedParams["index"] << index;
+    namedParams["size"] << size;
+    namedParams["type"] << std::hex << type;
+    namedParams["normalized"] << (normalized ? "T" : "F");
+    namedParams["stride"] << stride;
+    namedParams["offset"] << std::to_string(reinterpret_cast<unsigned long>(ptr));
+
+    mBufferTrace.PushCall("VertexAttribPointer", namedParams.str(), namedParams);
   }
 
   inline void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
@@ -1519,7 +1619,12 @@ public:
 
   inline GLboolean UnmapBuffer(GLenum target) override
   {
-    return false;
+    if(mMappedBuffer)
+    {
+      free(mMappedBuffer);
+      mMappedBuffer = nullptr;
+    }
+    return true; // false indicates corruption, nothing else.
   }
 
   inline void GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) override
@@ -1568,7 +1673,8 @@ public:
 
   inline GLvoid* MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) override
   {
-    return NULL;
+    mMappedBuffer = reinterpret_cast<GLvoid*>(malloc(offset + length));
+    return mMappedBuffer;
   }
 
   inline void FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) override
@@ -1889,8 +1995,12 @@ public:
   {
   }
 
+  inline void BlendBarrier(void)
+  {
+  }
+
 private:
-  inline void AddUniformCallToTraceStack(GLint location, std::string& value)
+  inline void AddUniformCallToTraceStack(GLint location, const std::string& value)
   {
     std::string name    = "<not found>";
     bool        matched = false;
@@ -1921,9 +2031,9 @@ public: // TEST FUNCTIONS
   {
     mLinkStatus = value;
   }
-  inline void SetGetAttribLocationResult(int result)
+  inline void SetAttribLocations(std::vector<std::string> locs)
   {
-    mGetAttribLocationResult = result;
+    mAttribLocs = locs;
   }
   inline void SetGetErrorResult(GLenum result)
   {
@@ -2055,15 +2165,15 @@ public: // TEST FUNCTIONS
   //Methods for Texture verification
   inline void EnableTexParameterCallTrace(bool enable)
   {
-    mTexParamaterTrace.Enable(enable);
+    mTexParameterTrace.Enable(enable);
   }
   inline void ResetTexParameterCallStack()
   {
-    mTexParamaterTrace.Reset();
+    mTexParameterTrace.Reset();
   }
   inline TraceCallStack& GetTexParameterTrace()
   {
-    return mTexParamaterTrace;
+    return mTexParameterTrace;
   }
 
   //Methods for Draw verification
@@ -2149,6 +2259,10 @@ public: // TEST FUNCTIONS
   {
     return mViewportTrace;
   }
+  inline TraceCallStack& GetBufferTrace()
+  {
+    return mBufferTrace;
+  }
 
   template<typename T>
   inline bool GetUniformValue(const char* name, T& value) const
@@ -2198,7 +2312,7 @@ public: // TEST FUNCTIONS
       }
     }
 
-    fprintf(stderr, "Not found, printing possible values:\n");
+    fprintf(stderr, "%s Not found, printing possible values:\n", name);
     for(ProgramUniformMap::const_iterator program_it = mUniforms.begin();
         program_it != mUniforms.end();
         ++program_it)
@@ -2217,7 +2331,7 @@ public: // TEST FUNCTIONS
         if(mProgramUniforms.GetUniformValue(programId, uniformId, origValue))
         {
           std::stringstream out;
-          out << uniform_it->first << ": " << origValue;
+          out << "Program: " << programId << ", " << uniform_it->first << ": " << origValue;
           fprintf(stderr, "%s\n", out.str().c_str());
         }
       }
@@ -2251,6 +2365,11 @@ public: // TEST FUNCTIONS
     return false;
   }
 
+  inline void SetCustomUniforms(std::vector<UniformData>& customUniformData)
+  {
+    mCustomUniformData = customUniformData;
+  }
+
   inline GLuint GetLastShaderCompiled() const
   {
     return mLastShaderCompiled;
@@ -2351,14 +2470,13 @@ public: // TEST FUNCTIONS
     mBufferSubDataCalls.clear();
   }
 
-private:
+public:
   GLuint                                mCurrentProgram;
   GLuint                                mCompileStatus;
   BufferDataCalls                       mBufferDataCalls;
   BufferSubDataCalls                    mBufferSubDataCalls;
+  GLvoid*                               mMappedBuffer{nullptr};
   GLuint                                mLinkStatus;
-  GLint                                 mNumberOfActiveUniforms;
-  GLint                                 mGetAttribLocationResult;
   GLenum                                mGetErrorResult;
   GLubyte*                              mGetStringResult;
   GLboolean                             mIsBufferResult;
@@ -2383,6 +2501,7 @@ private:
   bool                                  mGetProgramBinaryCalled;
   typedef std::map<GLuint, std::string> ShaderSourceMap;
   ShaderSourceMap                       mShaderSources;
+  std::vector<std::string>              mAttribLocs; // should be bound to shader
   GLuint                                mLastShaderCompiled;
   GLbitfield                            mLastClearBitMask;
   Vector4                               mLastClearColor;
@@ -2412,11 +2531,12 @@ private:
 
   ActiveTextureType mActiveTextures[MIN_TEXTURE_UNIT_LIMIT];
 
+  TraceCallStack mBufferTrace;
   TraceCallStack mCullFaceTrace;
   TraceCallStack mEnableDisableTrace;
   TraceCallStack mShaderTrace;
   TraceCallStack mTextureTrace;
-  TraceCallStack mTexParamaterTrace;
+  TraceCallStack mTexParameterTrace;
   TraceCallStack mDrawTrace;
   TraceCallStack mDepthFunctionTrace;
   TraceCallStack mStencilFunctionTrace;
@@ -2426,11 +2546,13 @@ 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;
   ProgramUniformMap                      mUniforms;
+  std::vector<ActiveUniform>             mActiveUniforms;
+  std::vector<UniformData>               mCustomUniformData{};
 
   template<typename T>
   struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >