[dali_2.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-gl-abstraction.h
index 7aacf76..a70c21f 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_GL_ABSTRACTION_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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
 {
+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{GL_FLOAT};
+  GLint       size{0};
+  GLint       offset{0};
+};
+
 class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
 {
 public:
@@ -54,8 +73,12 @@ public:
 
   bool IsAdvancedBlendEquationSupported() override;
 
+  bool IsMultisampledRenderToTextureSupported() override;
+
   bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
 
+  uint32_t GetShaderLanguageVersion();
+
   std::string GetShaderVersionPrefix();
 
   std::string GetVertexShaderPrefix();
@@ -157,10 +180,10 @@ public:
     }
 
     std::stringstream out;
-    out << target << ", " << texture;
+    out << std::hex << target << ", " << std::dec << texture;
 
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"] << target;
+    namedParams["target"] << std::hex << target;
     namedParams["texture"] << texture;
 
     mTextureTrace.PushCall("BindTexture", out.str(), namedParams);
@@ -281,6 +304,21 @@ public:
     return mFramebufferColorAttachmentCount;
   }
 
+  inline GLuint CheckFramebufferDepthAttachmentCount()
+  {
+    return mFramebufferDepthAttachmentCount;
+  }
+
+  inline GLuint CheckFramebufferStencilAttachmentCount()
+  {
+    return mFramebufferStencilAttachmentCount;
+  }
+
+  inline GLuint CheckFramebufferDepthStencilAttachmentCount()
+  {
+    return mFramebufferDepthStencilAttachmentCount;
+  }
+
   inline GLenum CheckFramebufferDepthAttachment()
   {
     return mFramebufferDepthAttached;
@@ -291,6 +329,11 @@ public:
     return mFramebufferStencilAttached;
   }
 
+  inline GLenum CheckFramebufferDepthStencilAttachment()
+  {
+    return mFramebufferDepthStencilAttached;
+  }
+
   inline void Clear(GLbitfield mask) override
   {
     mClearCount++;
@@ -417,6 +460,10 @@ public:
 
   inline void DeleteBuffers(GLsizei n, const GLuint* buffers) override
   {
+    TraceCallStack::NamedParams namedParams;
+    namedParams["n"] << n;
+    namedParams["id"] << buffers[0];
+    mBufferTrace.PushCall("DeleteBuffers", namedParams.str(), namedParams);
   }
 
   inline void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override
@@ -610,6 +657,12 @@ public:
     {
       mFramebufferStencilAttached = true;
     }
+    else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+    {
+      mFramebufferStencilAttached      = true;
+      mFramebufferDepthAttached        = true;
+      mFramebufferDepthStencilAttached = true;
+    }
   }
 
   inline void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) override
@@ -627,6 +680,20 @@ public:
         ++mFramebufferColorAttachmentCount;
       }
     }
+    else if(attachment == GL_DEPTH_ATTACHMENT)
+    {
+      ++mFramebufferDepthAttachmentCount;
+    }
+    else if(attachment == GL_STENCIL_ATTACHMENT)
+    {
+      ++mFramebufferStencilAttachmentCount;
+    }
+    else if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+    {
+      ++mFramebufferDepthAttachmentCount;
+      ++mFramebufferStencilAttachmentCount;
+      ++mFramebufferDepthStencilAttachmentCount;
+    }
   }
 
   inline void FrontFace(GLenum mode) override
@@ -637,13 +704,21 @@ public:
   inline void GenBuffers(GLsizei n, GLuint* buffers) override
   {
     // avoids an assert in GpuBuffers
-    *buffers = 1u;
+    static GLuint id = 1;
 
-    std::ostringstream o;
-    o << n;
     TraceCallStack::NamedParams namedParams;
-    namedParams["n"] << o.str();
-    mBufferTrace.PushCall("GenBuffers", o.str(), namedParams);
+    namedParams["n"] << n;
+
+    // Allocate some buffer names
+    bool first = true;
+    while(n)
+    {
+      namedParams["buffers"] << (first ? "" : ", ") << id;
+      first      = false;
+      *buffers++ = id++;
+      --n;
+    }
+    mBufferTrace.PushCall("GenBuffers", namedParams.str(), namedParams);
   }
 
   inline void GenerateMipmap(GLenum target) override
@@ -736,29 +811,19 @@ public:
 
   inline void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) override
   {
+    strncpy(name, mAttribLocs[index].c_str(), 99);
+    *type = mAttribTypes[index];
   }
 
+  void SetActiveUniforms(const std::vector<ActiveUniform>& 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;
     }
   }
 
@@ -812,6 +877,9 @@ public:
       case GL_PROGRAM_BINARY_FORMATS_OES:
         *params = mBinaryFormats;
         break;
+      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+        *params = mUniformBufferOffsetAlignment;
+        break;
     }
   }
 
@@ -826,11 +894,17 @@ 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;
+      case GL_ACTIVE_ATTRIBUTES:
+        *params = static_cast<GLint>(mAttribLocs.size());
+        break;
     }
   }
 
@@ -897,7 +971,7 @@ public:
     {
       // Uniform not found, so add it...
       uniformIDs[name] = ++mLastUniformIdUsed;
-      return mLastUniformIdUsed;
+      return uniformIDs[name];
     }
 
     return it2->second;
@@ -967,10 +1041,63 @@ public:
     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)
+    {
+      std::string name = uniform.name;
+      if(uniform.size <= 1)
+      {
+        GetUniformLocation(program, name.c_str());
+      }
+      else
+      {
+        // Convert single active uniform from "uBlah[0]" or "uStruct[0].element" to N versions of the same
+        std::string suffix;
+        auto        iter = name.find("["); // Search for index operator
+        if(iter != std::string::npos)
+        {
+          name = uniform.name.substr(0, iter); // Strip off index operator
+          iter = uniform.name.find("]");
+          if(iter != std::string::npos && iter + 1 != uniform.name.length())
+          {
+            suffix = uniform.name.substr(iter + 1);
+          }
+        }
+        for(int i = 0; i < uniform.size; ++i)
+        {
+          std::stringstream nss;
+          nss << name << "[" << i << "]" << suffix;
+          GetUniformLocation(program, nss.str().c_str()); // Generate N uniforms in the uniform map
+        }
+      }
+    }
+
+    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
@@ -1178,16 +1305,10 @@ public:
     out << std::hex << target << ", " << pname << ", " << param;
     std::string params = out.str();
 
-    out.str("");
-    out << std::hex << target;
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"] << out.str();
-    out.str("");
-    out << std::hex << pname;
-    namedParams["pname"] << out.str();
-    out.str("");
-    out << std::hex << param;
-    namedParams["param"] << out.str();
+    namedParams["target"] << std::hex << target;
+    namedParams["pname"] << std::hex << pname;
+    namedParams["param"] << param;
     mTexParameterTrace.PushCall("TexParameteri", params, namedParams);
   }
 
@@ -1511,6 +1632,18 @@ public:
     mBufferTrace.PushCall("VertexAttribPointer", namedParams.str(), namedParams);
   }
 
+  inline void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) override
+  {
+    TraceCallStack::NamedParams namedParams;
+    namedParams["index"] << index;
+    namedParams["size"] << size;
+    namedParams["type"] << std::hex << type;
+    namedParams["stride"] << stride;
+    namedParams["offset"] << std::to_string(reinterpret_cast<unsigned long>(pointer));
+
+    mBufferTrace.PushCall("VertexAttribIPointer", namedParams.str(), namedParams);
+  }
+
   inline void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
   {
     std::string commaString(", ");
@@ -1580,7 +1713,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
@@ -1623,13 +1761,20 @@ public:
   {
   }
 
+  inline void FramebufferTexture2DMultisample(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) override
+  {
+    // TODO : Check it if need
+    FramebufferTexture2D(target, attachment, textarget, texture, level);
+  }
+
   inline void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) override
   {
   }
 
   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
@@ -1681,10 +1826,6 @@ public:
   {
   }
 
-  inline void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) override
-  {
-  }
-
   inline void GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) override
   {
   }
@@ -1781,6 +1922,44 @@ public:
 
   inline void GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) override
   {
+    for(int i = 0; i < uniformCount; ++i)
+    {
+      if(i < int(mActiveUniforms.size()))
+      {
+        switch(pname)
+        {
+          case GL_UNIFORM_TYPE:
+          {
+            params[i] = mActiveUniforms[i].type;
+            break;
+          }
+          case GL_UNIFORM_SIZE:
+          {
+            params[i] = mActiveUniforms[i].size;
+            break;
+          }
+          case GL_UNIFORM_NAME_LENGTH:
+          {
+            params[i] = mActiveUniforms[i].name.length();
+            break;
+          }
+          case GL_UNIFORM_BLOCK_INDEX:
+          {
+            params[i] = -1;
+            break;
+          }
+          case GL_UNIFORM_OFFSET:
+          {
+            params[i] = mActiveUniforms[i].offset;
+            break;
+          }
+          case GL_UNIFORM_MATRIX_STRIDE:
+          {
+            break;
+          }
+        }
+      }
+    }
   }
 
   inline GLuint GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) override
@@ -1802,10 +1981,26 @@ public:
 
   inline void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) override
   {
+    std::stringstream out;
+    out << mode << ", " << first << ", " << count << ", " << instanceCount;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["mode"] << std::hex << mode;
+    namedParams["first"] << first;
+    namedParams["count"] << count;
+    namedParams["instanceCount"] << instanceCount;
+    mDrawTrace.PushCall("DrawArraysInstanced", out.str(), namedParams);
   }
 
   inline void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) override
   {
+    std::stringstream out;
+    out << mode << ", " << count << ", " << type << ", " << instanceCount;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["mode"] << std::hex << mode;
+    namedParams["count"] << count;
+    namedParams["type"] << std::hex << type;
+    namedParams["indexCount"] << instanceCount;
+    mDrawTrace.PushCall("DrawElementsInstanced", out.str(), namedParams);
   }
 
   inline GLsync FenceSync(GLenum condition, GLbitfield flags) override
@@ -1890,6 +2085,12 @@ public:
 
   inline void VertexAttribDivisor(GLuint index, GLuint divisor) override
   {
+    std::stringstream out;
+    out << index << ", " << divisor;
+    TraceCallStack::NamedParams namedParams;
+    namedParams["index"] << index;
+    namedParams["divisor"] << divisor;
+    mBufferTrace.PushCall("VertexAttribDivisor", out.str(), namedParams);
   }
 
   inline void BindTransformFeedback(GLenum target, GLuint id) override
@@ -1986,10 +2187,14 @@ public: // TEST FUNCTIONS
   {
     mLinkStatus = value;
   }
-  inline void SetAttribLocations(std::vector<std::string> locs)
+  inline void SetAttribLocations(std::vector<std::string>& locs)
   {
     mAttribLocs = locs;
   }
+  inline void SetAttribTypes(std::vector<GLenum>& types)
+  {
+    mAttribTypes = types;
+  }
   inline void SetGetErrorResult(GLenum result)
   {
     mGetErrorResult = result;
@@ -2042,7 +2247,10 @@ public: // TEST FUNCTIONS
   {
     mProgramBinaryLength = length;
   }
-
+  inline void SetUniformBufferOffsetAlignment(GLint align)
+  {
+    mUniformBufferOffsetAlignment = align;
+  }
   inline bool GetVertexAttribArrayState(GLuint index)
   {
     if(index >= MAX_ATTRIBUTE_CACHE_SIZE)
@@ -2267,7 +2475,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)
@@ -2286,7 +2494,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());
         }
       }
@@ -2320,6 +2528,11 @@ public: // TEST FUNCTIONS
     return false;
   }
 
+  inline void SetCustomUniforms(std::vector<UniformData>& customUniformData)
+  {
+    mCustomUniformData = customUniformData;
+  }
+
   inline GLuint GetLastShaderCompiled() const
   {
     return mLastShaderCompiled;
@@ -2420,13 +2633,13 @@ public: // TEST FUNCTIONS
     mBufferSubDataCalls.clear();
   }
 
-private:
+public:
   GLuint                                mCurrentProgram;
   GLuint                                mCompileStatus;
   BufferDataCalls                       mBufferDataCalls;
   BufferSubDataCalls                    mBufferSubDataCalls;
+  GLvoid*                               mMappedBuffer{nullptr};
   GLuint                                mLinkStatus;
-  GLint                                 mNumberOfActiveUniforms;
   GLenum                                mGetErrorResult;
   GLubyte*                              mGetStringResult;
   GLboolean                             mIsBufferResult;
@@ -2441,17 +2654,23 @@ private:
   GLint                                 mFramebufferStatus;
   GLenum                                mFramebufferDepthAttached;
   GLenum                                mFramebufferStencilAttached;
+  GLenum                                mFramebufferDepthStencilAttached;
   GLuint                                mFramebufferColorAttachmentCount;
   GLuint                                mFrameBufferColorStatus;
+  GLuint                                mFramebufferDepthAttachmentCount;
+  GLuint                                mFramebufferStencilAttachmentCount;
+  GLuint                                mFramebufferDepthStencilAttachmentCount;
   GLint                                 mNumBinaryFormats;
   GLint                                 mBinaryFormats;
   GLint                                 mProgramBinaryLength;
+  GLint                                 mUniformBufferOffsetAlignment{1};
   bool                                  mVertexAttribArrayState[MAX_ATTRIBUTE_CACHE_SIZE];
   bool                                  mVertexAttribArrayChanged; // whether the vertex attrib array has been changed
   bool                                  mGetProgramBinaryCalled;
   typedef std::map<GLuint, std::string> ShaderSourceMap;
   ShaderSourceMap                       mShaderSources;
-  std::vector<std::string>              mAttribLocs; // should be bound to shader
+  std::vector<std::string>              mAttribLocs;  // should be bound to shader
+  std::vector<GLenum>                   mAttribTypes; // should be bound to shader
   GLuint                                mLastShaderCompiled;
   GLbitfield                            mLastClearBitMask;
   Vector4                               mLastClearColor;
@@ -2495,12 +2714,16 @@ private:
   TraceCallStack mViewportTrace;
 
   // Shaders & Uniforms
+  uint32_t mShaderLanguageVersion{320u};
+
   GLuint                                 mLastShaderIdUsed;
   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> >