/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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
{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gGraphicsReflectionLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_GRAPHICS_REFLECTION");
+#endif
+
struct StringSize
{
const char* const mString;
return strncmp(lhs.mString, rhs, lhs.mLength) == 0;
}
-const char* const DELIMITERS = " \t\n";
+const char* const DELIMITERS = " \t\n";
+const char* const DELIMITERS_INC_INDEX = " \t\n[]";
constexpr StringSize UNIFORM{"uniform"};
constexpr StringSize SAMPLER_PREFIX{"sampler"};
constexpr StringSize SAMPLER_TYPES[] = {"2D", "Cube", "ExternalOES"};
while(uniform)
{
+ // From "uniform" to ";", not ignoring comments.
char* outerToken = strtok_r(uniform + UNIFORM.mLength, ";", &uniform);
char* nextPtr = nullptr;
char* token = strtok_r(outerToken, DELIMITERS, &nextPtr);
while(token)
{
+ // Ignore any token up to "sampler"
if(SAMPLER_PREFIX == token)
{
token += SAMPLER_PREFIX.mLength;
if(std::find(SAMPLER_TYPES, END_SAMPLER_TYPES, token) != END_SAMPLER_TYPES)
{
bool found(false);
- token = strtok_r(nullptr, DELIMITERS, &nextPtr);
+ // We now are at next token after "samplerxxx" in outerToken token "stream"
+
+ // Does it use array notation?
+ int arraySize = 0; // 0 = No array
+ auto iter = std::string(token).find("[", 0);
+ if(iter != std::string::npos)
+ {
+ // Get Array size from source. (Warning, may be higher than GetActiveUniform suggests)
+ iter++;
+ arraySize = int(strtol(token + iter, nullptr, 0));
+ }
+
+ token = strtok_r(nullptr, DELIMITERS_INC_INDEX, &nextPtr); // " ", "\t", "\n", "[", "]"
for(uint32_t i = 0; i < static_cast<uint32_t>(uniformOpaques.size()); ++i)
{
if(samplerPositions[i] == -1 &&
strncmp(token, uniformOpaques[i].name.c_str(), uniformOpaques[i].name.size()) == 0)
{
- samplerPositions[i] = uniformOpaques[i].offset = samplerPosition++;
- found = true;
+ // We have found a matching name.
+ samplerPositions[i] = uniformOpaques[i].offset = samplerPosition;
+ if(arraySize == 0)
+ {
+ ++samplerPosition;
+ }
+ else
+ {
+ samplerPosition += arraySize;
+ }
+ found = true;
break;
}
}
if(!found)
{
- DALI_LOG_ERROR("Sampler uniform %s declared but not used in the shader\n", token);
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Sampler uniform %s declared but not used in the shader\n", token);
}
break;
}
return;
}
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Build vertex attribute reflection for glProgram : %u\n", glProgram);
+
gl->GetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
gl->GetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &nAttribs);
mVertexInputAttributes.clear();
mVertexInputAttributes.resize(nAttribs);
+ int maximumLocation = nAttribs - 1;
+
name = new GLchar[maxLength];
for(int i = 0; i < nAttribs; i++)
{
if(location >= 0)
{
+ if(maximumLocation < location)
+ {
+ maximumLocation = location;
+ // Increate continer size s.t. we can use maximumLocation as index.
+ mVertexInputAttributes.resize(maximumLocation + 1u);
+ }
+
AttributeInfo attributeInfo;
- attributeInfo.location = location;
- attributeInfo.name = name;
- attributeInfo.format = GetVertexAttributeTypeFormat(type);
- mVertexInputAttributes.insert(mVertexInputAttributes.begin() + location, attributeInfo);
+ attributeInfo.location = location;
+ attributeInfo.name = name;
+ attributeInfo.format = GetVertexAttributeTypeFormat(type);
+ mVertexInputAttributes[location] = std::move(attributeInfo);
}
}
+
delete[] name;
}
return;
}
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Build uniform reflection for glProgram : %u\n", glProgram);
+
gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
GLenum type;
int written;
gl->GetActiveUniform(glProgram, i, maxLen, &written, &elementCount, &type, name);
+
int location = gl->GetUniformLocation(glProgram, name);
Dali::Graphics::UniformInfo uniformInfo;
uniformInfo.name = name;
if(elementCount > 1)
{
+ // If we have an active uniform that refers to an array, only the first element
+ // is present in this list, and is referenced as "uniform[0]", but the element
+ // count is non-zero to indicate how many uniforms there are in the array.
+
+ // Strip off the array, but store the element count
auto iter = std::string(uniformInfo.name).find("[", 0);
if(iter != std::string::npos)
{
- uniformInfo.name = std::string(name).substr(0, iter);
+ uniformInfo.name = std::string(name).substr(0, iter);
+ uniformInfo.elementCount = elementCount;
}
}
-
uniformInfo.uniformClass = IsSampler(type) ? Dali::Graphics::UniformClass::COMBINED_IMAGE_SAMPLER : Dali::Graphics::UniformClass::UNIFORM;
- uniformInfo.location = location; //IsSampler(type) ? 0 : location;
- uniformInfo.binding = 0; // IsSampler(type) ? location : 0;
+ uniformInfo.location = location; // GL doesn't guarantee that consecutive array elements have sequential locations. But, we only store location of first element.
+ uniformInfo.binding = 0;
uniformInfo.bufferIndex = 0;
uniformInfo.offset = 0;
return;
}
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::General, "Build uniform block reflection for glProgram : %u\n", glProgram);
+
gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
mUniformBlocks.clear();
uint32_t Reflection::GetVertexAttributeLocation(const std::string& name) const
{
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::Verbose, "name : %s\n", name.c_str());
for(auto&& attr : mVertexInputAttributes)
{
if(attr.name == name)
Dali::Graphics::VertexInputAttributeFormat Reflection::GetVertexAttributeFormat(uint32_t location) const
{
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::Verbose, "location : %u\n", location);
if(location >= mVertexInputAttributes.size())
{
return Dali::Graphics::VertexInputAttributeFormat::UNDEFINED;
std::string Reflection::GetVertexAttributeName(uint32_t location) const
{
+ DALI_LOG_INFO(gGraphicsReflectionLogFilter, Debug::Verbose, "location : %u\n", location);
if(location >= mVertexInputAttributes.size())
{
return std::string();