[Tizen] Fix Coverity issue
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-reflection.cpp
index 4450557..2213fc0 100644 (file)
@@ -25,6 +25,8 @@
 #include <GLES3/gl3.h>
 #include <GLES3/gl31.h>
 
+#include "gles-graphics-program.h"
+
 #include <iostream>
 
 namespace
@@ -48,7 +50,7 @@ Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeTypeFormat(GLenum t
   }
 }
 
-int GetGLDataTypeSize(GLenum type)
+uint32_t GetGLDataTypeSize(GLenum type)
 {
   // There are many more types than what are covered here, but
   // they are not supported in dali.
@@ -77,43 +79,44 @@ int GetGLDataTypeSize(GLenum type)
 
 bool IsSampler(GLenum type)
 {
-  return type == GL_SAMPLER_2D || type == GL_SAMPLER_3D;
+  return type == GL_SAMPLER_2D || type == GL_SAMPLER_3D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES;
+}
+
+bool SortUniformInfoByLocation(Dali::Graphics::UniformInfo a, Dali::Graphics::UniformInfo b)
+{
+  return a.location < b.location;
 }
 
-bool SortByLocation(Dali::Graphics::UniformInfo a, Dali::Graphics::UniformInfo b)
+bool SortUniformExtraInfoByLocation(Dali::Graphics::GLES::Reflection::UniformExtraInfo a, Dali::Graphics::GLES::Reflection::UniformExtraInfo b)
 {
   return a.location < b.location;
 }
 
 } // namespace
 
-namespace Dali
-{
-namespace Graphics
+namespace Dali::Graphics::GLES
 {
-namespace GLES
-{
-Reflection::Reflection(Graphics::EglGraphicsController& controller)
+Reflection::Reflection(GLES::ProgramImpl& program, Graphics::EglGraphicsController& controller)
 : Graphics::Reflection(),
   mController(controller),
-  mGlProgram(0u)
+  mProgram(program)
 {
 }
 
-Reflection::~Reflection()
-{
-}
+Reflection::~Reflection() = default;
 
 void Reflection::BuildVertexAttributeReflection()
 {
+  auto glProgram = mProgram.GetGlProgram();
+
   int    written, size, location, maxLength, nAttribs;
   GLenum type;
   char*  name;
 
   auto gl = mController.GetGL();
 
-  gl->GetProgramiv(mGlProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
-  gl->GetProgramiv(mGlProgram, GL_ACTIVE_ATTRIBUTES, &nAttribs);
+  gl->GetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
+  gl->GetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &nAttribs);
 
   mVertexInputAttributes.clear();
   mVertexInputAttributes.resize(nAttribs);
@@ -121,21 +124,25 @@ void Reflection::BuildVertexAttributeReflection()
   name = new GLchar[maxLength];
   for(int i = 0; i < nAttribs; i++)
   {
-    gl->GetActiveAttrib(mGlProgram, i, maxLength, &written, &size, &type, name);
-    location = gl->GetAttribLocation(mGlProgram, name);
+    gl->GetActiveAttrib(glProgram, i, maxLength, &written, &size, &type, name);
+    location = gl->GetAttribLocation(glProgram, name);
 
-    AttributeInfo attributeInfo;
-    attributeInfo.location = location;
-    attributeInfo.name     = name;
-    attributeInfo.format   = GetVertexAttributeTypeFormat(type);
-
-    mVertexInputAttributes.insert(mVertexInputAttributes.begin() + location, attributeInfo);
+    if(location >= 0)
+    {
+      AttributeInfo attributeInfo;
+      attributeInfo.location = location;
+      attributeInfo.name     = name;
+      attributeInfo.format   = GetVertexAttributeTypeFormat(type);
+      mVertexInputAttributes.insert(mVertexInputAttributes.begin() + location, attributeInfo);
+    }
   }
   delete[] name;
 }
 
 void Reflection::BuildUniformReflection()
 {
+  auto glProgram = mProgram.GetGlProgram();
+
   int   maxLen;
   char* name;
 
@@ -143,8 +150,8 @@ void Reflection::BuildUniformReflection()
 
   auto gl = mController.GetGL();
 
-  gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
-  gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
+  gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
+  gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
 
   mUniformBlocks.clear();
   mDefaultUniformBlock.members.clear();
@@ -152,23 +159,28 @@ void Reflection::BuildUniformReflection()
 
   name = new char[maxLen];
 
-  int maxUniformLocations;
-  gl->GetProgramiv(mGlProgram, GL_MAX_UNIFORM_LOCATIONS, &maxUniformLocations);
-
-  std::vector<int> uniformSize;
-  uniformSize.reserve(maxUniformLocations);
+  mStandaloneUniformExtraInfos.clear();
 
   for(int i = 0; i < numUniforms; ++i)
   {
-    int    size;
+    int    elementCount;
     GLenum type;
     int    written;
-    gl->GetActiveUniform(mGlProgram, i, maxLen, &written, &size, &type, name);
-    int location          = gl->GetUniformLocation(mGlProgram, name);
-    uniformSize[location] = GetGLDataTypeSize(type);
+    gl->GetActiveUniform(glProgram, i, maxLen, &written, &elementCount, &type, name);
+    int location = gl->GetUniformLocation(glProgram, name);
 
     Dali::Graphics::UniformInfo uniformInfo;
-    uniformInfo.name         = name;
+
+    uniformInfo.name = name;
+    if(elementCount > 1)
+    {
+      auto iter = std::string(uniformInfo.name).find("[", 0);
+      if(iter != std::string::npos)
+      {
+        uniformInfo.name = std::string(name).substr(0, iter);
+      }
+    }
+
     uniformInfo.uniformClass = IsSampler(type) ? Dali::Graphics::UniformClass::COMBINED_IMAGE_SAMPLER : Dali::Graphics::UniformClass::UNIFORM;
     uniformInfo.location     = IsSampler(type) ? 0 : location;
     uniformInfo.binding      = IsSampler(type) ? location : 0;
@@ -181,29 +193,56 @@ void Reflection::BuildUniformReflection()
     else
     {
       mDefaultUniformBlock.members.push_back(uniformInfo);
+      mStandaloneUniformExtraInfos.emplace_back(location, GetGLDataTypeSize(type), uniformInfo.offset, elementCount, type);
     }
   }
 
   // Re-order according to uniform locations.
+
   if(mDefaultUniformBlock.members.size() > 1)
   {
-    std::sort(mDefaultUniformBlock.members.begin(), mDefaultUniformBlock.members.end(), SortByLocation);
+    std::sort(mDefaultUniformBlock.members.begin(), mDefaultUniformBlock.members.end(), SortUniformInfoByLocation);
+    std::sort(mStandaloneUniformExtraInfos.begin(), mStandaloneUniformExtraInfos.end(), SortUniformExtraInfoByLocation);
   }
 
   if(mUniformOpaques.size() > 1)
   {
-    std::sort(mUniformOpaques.begin(), mUniformOpaques.end(), SortByLocation);
+    std::sort(mUniformOpaques.begin(), mUniformOpaques.end(), SortUniformInfoByLocation);
   }
 
   // Calculate the uniform offset
   for(unsigned int i = 0; i < mDefaultUniformBlock.members.size(); ++i)
   {
-    mDefaultUniformBlock.members[i].offset = i == 0 ? 0 : mDefaultUniformBlock.members[i - 1].offset + uniformSize[mDefaultUniformBlock.members[i - 1].location];
+    if(i == 0)
+    {
+      mDefaultUniformBlock.members[i].offset = 0;
+    }
+    else
+    {
+      uint32_t previousUniformLocation = mDefaultUniformBlock.members[i - 1].location;
+      auto     previousUniform         = std::find_if(mStandaloneUniformExtraInfos.begin(), mStandaloneUniformExtraInfos.end(), [&previousUniformLocation](const UniformExtraInfo& iter) { return iter.location == previousUniformLocation; });
+      if(previousUniform != mStandaloneUniformExtraInfos.end())
+      {
+        mDefaultUniformBlock.members[i].offset = mDefaultUniformBlock.members[i - 1].offset + (previousUniform->size * previousUniform->arraySize);
+        mStandaloneUniformExtraInfos[i].offset = mDefaultUniformBlock.members[i].offset;
+      }
+    }
   }
 
-  mDefaultUniformBlock.size = mDefaultUniformBlock.members.back().offset + uniformSize[mDefaultUniformBlock.members.back().location];
-
-  mUniformBlocks.push_back(mDefaultUniformBlock);
+  if(mDefaultUniformBlock.members.size() > 0)
+  {
+    uint32_t lastUniformLocation = mDefaultUniformBlock.members.back().location;
+    auto     lastUniform         = std::find_if(mStandaloneUniformExtraInfos.begin(), mStandaloneUniformExtraInfos.end(), [&lastUniformLocation](const UniformExtraInfo& iter) { return iter.location == lastUniformLocation; });
+    if(lastUniform != mStandaloneUniformExtraInfos.end())
+    {
+      mDefaultUniformBlock.size = mDefaultUniformBlock.members.back().offset + (lastUniform->size * lastUniform->arraySize);
+      mUniformBlocks.push_back(mDefaultUniformBlock);
+    }
+  }
+  else
+  {
+    mDefaultUniformBlock.size = 0;
+  }
 
   delete[] name;
 }
@@ -211,16 +250,16 @@ void Reflection::BuildUniformReflection()
 // TODO: Maybe this is not needed if uniform block is not support by dali shaders?
 void Reflection::BuildUniformBlockReflection()
 {
-  auto gl = mController.GetGL();
-
-  int numUniformBlocks = 0;
-  gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
+  auto gl               = mController.GetGL();
+  auto glProgram        = mProgram.GetGlProgram();
+  int  numUniformBlocks = 0;
+  gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
 
   mUniformBlocks.clear();
   mUniformBlocks.resize(numUniformBlocks);
 
   int uniformBlockMaxLength = 0;
-  gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &uniformBlockMaxLength);
+  gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &uniformBlockMaxLength);
 
   char* uniformBlockName = new char[uniformBlockMaxLength];
   for(int i = 0; i < numUniformBlocks; i++)
@@ -228,9 +267,9 @@ void Reflection::BuildUniformBlockReflection()
     int length;
     int blockBinding;
     int blockDataSize;
-    gl->GetActiveUniformBlockName(mGlProgram, i, uniformBlockMaxLength, &length, uniformBlockName);
-    gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_BINDING, &blockBinding);
-    gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &blockDataSize);
+    gl->GetActiveUniformBlockName(glProgram, i, uniformBlockMaxLength, &length, uniformBlockName);
+    gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_BINDING, &blockBinding);
+    gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &blockDataSize);
 
     Dali::Graphics::UniformBlockInfo uniformBlockInfo;
     uniformBlockInfo.name    = uniformBlockName;
@@ -238,12 +277,12 @@ void Reflection::BuildUniformBlockReflection()
     uniformBlockInfo.binding = blockBinding;
 
     int nUnis;
-    gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &nUnis);
+    gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &nUnis);
     int* unifIndexes = new GLint[nUnis];
-    gl->GetActiveUniformBlockiv(mGlProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, unifIndexes);
+    gl->GetActiveUniformBlockiv(glProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, unifIndexes);
     char* uniformName{};
     int   maxUniLen;
-    gl->GetProgramiv(mGlProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLen);
+    gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLen);
 
     for(int unif = 0; unif < nUnis; ++unif)
     {
@@ -251,8 +290,14 @@ void Reflection::BuildUniformBlockReflection()
       int    size;
       GLenum type;
 
-      gl->GetActiveUniform(mGlProgram, uniIndex, maxUniLen, &length, &size, &type, uniformName);
-      int location = gl->GetUniformLocation(mGlProgram, uniformName);
+      gl->GetActiveUniform(glProgram, uniIndex, maxUniLen, &length, &size, &type, uniformName);
+
+      if(!uniformName)
+      {
+        continue;
+      }
+
+      int location = gl->GetUniformLocation(glProgram, uniformName);
 
       Dali::Graphics::UniformInfo uniform;
       uniform.name     = uniformName;
@@ -452,6 +497,22 @@ bool Reflection::GetNamedUniform(const std::string& name, Dali::Graphics::Unifor
   return false;
 }
 
+std::vector<GLenum> Reflection::GetStandaloneUniformTypes() const
+{
+  std::vector<GLenum> retval{};
+  for(auto&& uniform : mStandaloneUniformExtraInfos)
+  {
+    retval.emplace_back(uniform.type);
+  }
+
+  return retval;
+}
+
+const std::vector<Reflection::UniformExtraInfo>& Reflection::GetStandaloneUniformExtraInfo() const
+{
+  return mStandaloneUniformExtraInfos;
+}
+
 std::vector<Dali::Graphics::UniformInfo> Reflection::GetSamplers() const
 {
   return mUniformOpaques;
@@ -472,14 +533,4 @@ Graphics::ShaderLanguage Reflection::GetLanguage() const
   return Graphics::ShaderLanguage::GLSL_3_2;
 }
 
-void Reflection::SetGlProgram(uint32_t glProgram)
-{
-  mGlProgram = glProgram;
-
-  BuildVertexAttributeReflection();
-  BuildUniformReflection();
-}
-
-} // namespace GLES
-} // namespace Graphics
-} // namespace Dali
+} // namespace Dali::Graphics::GLES