Render still had a Program::Use call, this has now been removed.
Cleaned up Program and Render::Renderer to remove much unused code.
Moved sampler uniform initialization to implementation in adaptor.
Change-Id: I831c4adb7dbac071f6b95edc77723b74e063e2b6
return actor;
}
+Actor CreateRenderableActor2(TextureSet textures, const std::string& vertexShader, const std::string& fragmentShader)
+{
+ // Create the geometry
+ Geometry geometry = CreateQuadGeometry();
+
+ // Create Shader
+ Shader shader = Shader::New(vertexShader, fragmentShader);
+
+ // Create renderer from geometry and material
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ // Create actor and set renderer
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+
+ // If we a texture, then create a texture-set and add to renderer
+ if(textures)
+ {
+ renderer.SetTextures(textures);
+
+ auto texture = textures.GetTexture(0);
+
+ // Set actor to the size of the texture if set
+ actor.SetProperty(Actor::Property::SIZE, Vector2(texture.GetWidth(), texture.GetHeight()));
+ }
+
+ return actor;
+}
+
Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
{
Texture texture = Texture::New(type, format, width, height);
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/rendering/texture-set.h>
#include <dali/public-api/rendering/texture.h>
#include <string>
*/
Actor CreateRenderableActor(Texture texture, const std::string& vertexShader, const std::string& fragmentShader);
+/**
+ * @brief Creates a renderable-actor with a texture and custom shaders.
+ * @param[in] textures TextureSet to set.
+ * @param[in] vertexShader The vertex-shader.
+ * @param[in] fragmentShader The fragment-shader.
+ * @return An actor with a renderer.
+ */
+Actor CreateRenderableActor2(TextureSet textures, const std::string& vertexShader, const std::string& fragmentShader);
+
Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height);
} // namespace Dali
// Create render target for the scene
Graphics::RenderTargetCreateInfo rtInfo{};
- rtInfo.SetExtent( {mSurfaceWidth, mSurfaceHeight });
- mRenderTarget = mGraphicsController.CreateRenderTarget( rtInfo, nullptr );
- mScene.SetSurfaceRenderTarget( mRenderTarget.get() );
+ rtInfo.SetExtent({mSurfaceWidth, mSurfaceHeight});
+ mRenderTarget = mGraphicsController.CreateRenderTarget(rtInfo, nullptr);
+ mScene.SetSurfaceRenderTarget(mRenderTarget.get());
}
void TestApplication::InitializeCore()
mCurrentProgram = 0;
mCompileStatus = GL_TRUE;
mLinkStatus = GL_TRUE;
- mNumberOfActiveUniforms = 0;
mGetErrorResult = 0;
mGetStringResult = NULL;
mIsBufferResult = 0;
{
mVertexAttribArrayState[i] = false;
}
+
+ mActiveUniforms = std::vector<ActiveUniform>{
+ {"uRendererColor", GL_FLOAT, 1},
+ {"uCustom", GL_FLOAT_VEC3, 1},
+ {"uCustom3", GL_FLOAT_VEC3, 1},
+ {"uFadeColor", GL_FLOAT_VEC4, 1},
+ {"uUniform1", GL_FLOAT_VEC4, 1},
+ {"uUniform2", GL_FLOAT_VEC4, 1},
+ {"uUniform3", GL_FLOAT_VEC4, 1},
+ {"uFadeProgress", GL_FLOAT, 1},
+ {"uANormalMatrix", GL_FLOAT_MAT3, 1},
+ {"sEffect", GL_SAMPLER_2D, 1},
+ {"sTexture", GL_SAMPLER_2D, 1},
+ {"sTextureRect", GL_SAMPLER_2D, 1},
+ {"sGloss", GL_SAMPLER_2D, 1},
+ {"uColor", GL_FLOAT_VEC4, 1},
+ {"uModelMatrix", GL_FLOAT_MAT4, 1},
+ {"uModelView", GL_FLOAT_MAT4, 1},
+ {"uMvpMatrix", GL_FLOAT_MAT4, 1},
+ {"uNormalMatrix", GL_FLOAT_MAT4, 1},
+ {"uProjection", GL_FLOAT_MAT4, 1},
+ {"uSize", GL_FLOAT_VEC3, 1},
+ {"uViewMatrix", GL_FLOAT_MAT4, 1},
+ {"uLightCameraProjectionMatrix", GL_FLOAT_MAT4, 1},
+ {"uLightCameraViewMatrix", GL_FLOAT_MAT4, 1}};
}
void TestGlAbstraction::PreRender()
}
};
+struct ActiveUniform
+{
+ std::string name;
+ GLenum type;
+ GLint size;
+};
+
class DALI_CORE_API TestGlAbstraction : public Dali::Integration::GlAbstraction
{
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;
}
}
*params = mProgramBinaryLength;
break;
case GL_ACTIVE_UNIFORMS:
- *params = mNumberOfActiveUniforms;
+ *params = mActiveUniforms.size();
break;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
*params = 100;
namedParams["program"] << program;
mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
- mNumberOfActiveUniforms = 3;
-
- GetUniformLocation(program, "uRendererColor");
- GetUniformLocation(program, "uCustom");
- GetUniformLocation(program, "uCustom3");
- GetUniformLocation(program, "uFadeColor");
- GetUniformLocation(program, "uUniform1");
- GetUniformLocation(program, "uUniform2");
- GetUniformLocation(program, "uUniform3");
- GetUniformLocation(program, "uFadeProgress");
- GetUniformLocation(program, "uANormalMatrix");
- GetUniformLocation(program, "sEffect");
- GetUniformLocation(program, "sTexture");
- GetUniformLocation(program, "sTextureRect");
- GetUniformLocation(program, "sGloss");
- GetUniformLocation(program, "uColor");
- GetUniformLocation(program, "uModelMatrix");
- GetUniformLocation(program, "uModelView");
- GetUniformLocation(program, "uMvpMatrix");
- GetUniformLocation(program, "uNormalMatrix");
- GetUniformLocation(program, "uProjection");
- GetUniformLocation(program, "uSize");
- GetUniformLocation(program, "uViewMatrix");
- GetUniformLocation(program, "uLightCameraProjectionMatrix");
- GetUniformLocation(program, "uLightCameraViewMatrix");
+ for(const auto& uniform : mActiveUniforms)
+ {
+ GetUniformLocation(program, uniform.name.c_str());
+ }
for(const auto& uniform : mCustomUniformData)
{
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;
typedef std::map<std::string, GLint> UniformIDMap;
typedef std::map<GLuint, UniformIDMap> ProgramUniformMap;
ProgramUniformMap mUniforms;
-
- std::vector<UniformData> mCustomUniformData{};
+ std::vector<ActiveUniform> mActiveUniforms;
+ std::vector<UniformData> mCustomUniformData{};
template<typename T>
struct ProgramUniformValue : public std::map<GLuint, std::map<GLint, T> >
return o;
}
-
int GetNumComponents(Graphics::VertexInputFormat vertexFormat)
{
switch(vertexFormat)
return op;
}
-
class TestGraphicsMemory : public Graphics::Memory
{
public:
trace.EnableLogging(true);
}
-
void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
{
TraceCallStack::NamedParams namedParams;
{
// Test scissor area and RT size
const auto& area = cmd.data.beginRenderPass.renderArea;
- if( area.x == 0 &&
- area.y == 0 &&
- area.width == renderTarget->mCreateInfo.extent.width &&
- area.height == renderTarget->mCreateInfo.extent.height )
+ if(area.x == 0 &&
+ area.y == 0 &&
+ area.width == renderTarget->mCreateInfo.extent.width &&
+ area.height == renderTarget->mCreateInfo.extent.height)
{
mGl.Disable(GL_SCISSOR_TEST);
mGl.Clear(mask);
else
{
mGl.Enable(GL_SCISSOR_TEST);
- mGl.Scissor(cmd.data.beginRenderPass.renderArea.x, cmd.data.beginRenderPass.renderArea.y,
- cmd.data.beginRenderPass.renderArea.width, cmd.data.beginRenderPass.renderArea.height);
+ mGl.Scissor(cmd.data.beginRenderPass.renderArea.x, cmd.data.beginRenderPass.renderArea.y, cmd.data.beginRenderPass.renderArea.width, cmd.data.beginRenderPass.renderArea.height);
mGl.Clear(mask);
mGl.Disable(GL_SCISSOR_TEST);
}
{
mGl.Disable(GL_BLEND);
}
+
+ auto* program = static_cast<const TestGraphicsProgram*>(pipeline->programState.program);
+ mGl.UseProgram(program->mImpl->mId);
}
/**
mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
}
-void Renderer::SetUniformFromProperty(BufferIndex bufferIndex, Program& program, UniformIndexMap& map)
-{
- GLint location = program.GetUniformLocation(map.uniformIndex);
- if(Program::UNIFORM_UNKNOWN != location)
- {
- // switch based on property type to use correct GL uniform setter
- switch(map.propertyValue->GetType())
- {
- case Property::INTEGER:
- {
- program.SetUniform1i(location, map.propertyValue->GetInteger(bufferIndex));
- break;
- }
- case Property::FLOAT:
- {
- program.SetUniform1f(location, map.propertyValue->GetFloat(bufferIndex));
- break;
- }
- case Property::VECTOR2:
- {
- Vector2 value(map.propertyValue->GetVector2(bufferIndex));
- program.SetUniform2f(location, value.x, value.y);
- break;
- }
-
- case Property::VECTOR3:
- {
- Vector3 value(map.propertyValue->GetVector3(bufferIndex));
- program.SetUniform3f(location, value.x, value.y, value.z);
- break;
- }
-
- case Property::VECTOR4:
- {
- Vector4 value(map.propertyValue->GetVector4(bufferIndex));
- program.SetUniform4f(location, value.x, value.y, value.z, value.w);
- break;
- }
-
- case Property::ROTATION:
- {
- Quaternion value(map.propertyValue->GetQuaternion(bufferIndex));
- program.SetUniform4f(location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w);
- break;
- }
-
- case Property::MATRIX:
- {
- const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
- program.SetUniformMatrix4fv(location, 1, value.AsFloat());
- break;
- }
-
- case Property::MATRIX3:
- {
- const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
- program.SetUniformMatrix3fv(location, 1, value.AsFloat());
- break;
- }
-
- default:
- {
- // Other property types are ignored
- break;
- }
- }
- }
-}
-
-void Renderer::BindTextures(Program& program, Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures)
+void Renderer::BindTextures(Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures)
{
uint32_t textureUnit = 0;
- GLint uniformLocation(-1);
std::vector<Render::Sampler*>& samplers(mRenderDataProvider->GetSamplers());
std::vector<Render::Texture*>& textures(mRenderDataProvider->GetTextures());
{
if(textures[i] && textures[i]->GetGraphicsObject())
{
- if(program.GetSamplerUniformLocation(i, uniformLocation))
- {
- // if the sampler exists,
- // if it's default, delete the graphics object
- // otherwise re-initialize it if dirty
+ // if the sampler exists,
+ // if it's default, delete the graphics object
+ // otherwise re-initialize it if dirty
- const Graphics::Sampler* graphicsSampler = (samplers[i] ? samplers[i]->GetGraphicsObject()
- : nullptr);
+ const Graphics::Sampler* graphicsSampler = (samplers[i] ? samplers[i]->GetGraphicsObject()
+ : nullptr);
- boundTextures.PushBack(textures[i]->GetGraphicsObject());
- const Graphics::TextureBinding textureBinding{textures[i]->GetGraphicsObject(), graphicsSampler, textureUnit};
- textureBindings.push_back(textureBinding);
+ boundTextures.PushBack(textures[i]->GetGraphicsObject());
+ const Graphics::TextureBinding textureBinding{textures[i]->GetGraphicsObject(), graphicsSampler, textureUnit};
+ textureBindings.push_back(textureBinding);
- program.SetUniform1i(uniformLocation, textureUnit); // Get through shader reflection
- ++textureUnit;
- }
+ ++textureUnit;
}
}
commandBuffer->BindPipeline(*mGraphicsPipeline.get());
- BindTextures(*program, *commandBuffer.get(), boundTextures);
+ BindTextures(*commandBuffer.get(), boundTextures);
BuildUniformIndexMap(bufferIndex, node, size, *program);
}
}
- // Take the program into use so we can send uniforms to it
- // @todo Remove this call entirely!
- program.Use();
-
mUpdated = true;
// Create a new pipeline
*/
void BuildUniformIndexMap(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program);
- /**
- * Set the program uniform in the map from the mapped property
- * @param[in] bufferIndex The index of the previous update buffer.
- * @param[in] program The shader program
- * @param[in] map The uniform
- */
- void SetUniformFromProperty(BufferIndex bufferIndex, Program& program, UniformIndexMap& map);
-
/**
* Bind the textures and setup the samplers
- * @param[in] context The GL context
- * @param[in] program The shader program
+ * @param[in] commandBuffer The command buffer to record binding into
* @param[in] boundTextures The textures bound for rendering
*/
- void BindTextures(Program& program, Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures);
+ void BindTextures(Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures);
/**
* Prepare a pipeline for this renderer
// LOCAL STUFF
namespace
{
-const char* const gStdAttribs[Program::ATTRIB_TYPE_LAST] =
- {
- "aPosition", // ATTRIB_POSITION
- "aTexCoord", // ATTRIB_TEXCOORD
-};
-
const char* const gStdUniforms[Program::UNIFORM_TYPE_LAST] =
{
"uMvpMatrix", // UNIFORM_MVP_MATRIX
{
// program not found so create it
program = new Program(cache, shaderData, gfxController, std::move(gfxProgram), modifiesGeometry);
- program->GetActiveSamplerUniforms();
cache.AddProgram(shaderHash, program);
}
return program;
}
-void Program::Use()
-{
- LOG_GL("UseProgram(%d)\n", mProgramId);
- CHECK_GL(mGlAbstraction, mGlAbstraction.UseProgram(mProgramId));
- mCache.SetCurrentProgram(this);
-}
-
-bool Program::IsUsed()
-{
- return (this == mCache.GetCurrentProgram());
-}
-
-GLint Program::GetAttribLocation(AttribType type)
-{
- DALI_ASSERT_DEBUG(type != ATTRIB_UNKNOWN);
-
- return GetCustomAttributeLocation(type);
-}
-
-uint32_t Program::RegisterCustomAttribute(ConstString name)
-{
- uint32_t index = 0;
- // find the value from cache
- for(; index < static_cast<uint32_t>(mAttributeLocations.size()); ++index)
- {
- if(mAttributeLocations[index].first == name)
- {
- // name found so return index
- return index;
- }
- }
- // if we get here, index is one past end so push back the new name
- mAttributeLocations.push_back(std::make_pair(name, ATTRIB_UNKNOWN));
- return index;
-}
-
-GLint Program::GetCustomAttributeLocation(uint32_t attributeIndex)
-{
- // debug check that index is within name cache
- DALI_ASSERT_DEBUG(mAttributeLocations.size() > attributeIndex);
-
- // check if we have already queried the location of the attribute
- GLint location = mAttributeLocations[attributeIndex].second;
-
- if(location == ATTRIB_UNKNOWN)
- {
- location = CHECK_GL(mGlAbstraction, mGlAbstraction.GetAttribLocation(mProgramId, mAttributeLocations[attributeIndex].first.GetCString()));
-
- mAttributeLocations[attributeIndex].second = location;
- LOG_GL("GetAttributeLocation(program=%d,%s) = %d\n", mProgramId, mAttributeLocations[attributeIndex].first.GetCString(), mAttributeLocations[attributeIndex].second);
- }
-
- return location;
-}
-
uint32_t Program::RegisterUniform(ConstString name)
{
uint32_t index = 0;
return index;
}
-GLint Program::GetUniformLocation(uint32_t uniformIndex)
-{
- // debug check that index is within name cache
- DALI_ASSERT_DEBUG(mUniformLocations.size() > uniformIndex);
-
- // check if we have already queried the location of the uniform
- GLint location = mUniformLocations[uniformIndex].second;
-
- if(location == UNIFORM_NOT_QUERIED)
- {
- location = CHECK_GL(mGlAbstraction, mGlAbstraction.GetUniformLocation(mProgramId, mUniformLocations[uniformIndex].first.GetCString()));
-
- mUniformLocations[uniformIndex].second = location;
- LOG_GL("GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mUniformLocations[uniformIndex].first.GetCString(), mUniformLocations[uniformIndex].second);
- }
-
- return location;
-}
-
-namespace
-{
-/**
- * This struct is used to record the position of a uniform declaration
- * within the fragment shader source code.
- */
-struct LocationPosition
-{
- GLint uniformLocation; ///< The location of the uniform (used as an identifier)
- int32_t position; ///< the position of the uniform declaration
- LocationPosition(GLint uniformLocation, int32_t position)
- : uniformLocation(uniformLocation),
- position(position)
- {
- }
-};
-
-bool sortByPosition(LocationPosition a, LocationPosition b)
-{
- return a.position < b.position;
-}
-
-const char* const DELIMITERS = " \t\n";
-
-struct StringSize
-{
- const char* const mString;
- const uint32_t mLength;
-
- template<uint32_t kLength>
- constexpr StringSize(const char (&string)[kLength])
- : mString(string),
- mLength(kLength - 1) // remove terminating null; N.B. there should be no other null.
- {
- }
-
- operator const char*() const
- {
- return mString;
- }
-};
-
-bool operator==(const StringSize& lhs, const char* rhs)
-{
- return strncmp(lhs.mString, rhs, lhs.mLength) == 0;
-}
-
-constexpr StringSize UNIFORM{"uniform"};
-constexpr StringSize SAMPLER_PREFIX{"sampler"};
-constexpr StringSize SAMPLER_TYPES[] = {
- "2D",
- "Cube",
- "ExternalOES"};
-
-constexpr auto END_SAMPLER_TYPES = SAMPLER_TYPES + std::extent<decltype(SAMPLER_TYPES)>::value;
-
-} // namespace
-
-void Program::GetActiveSamplerUniforms()
-{
- GLint numberOfActiveUniforms = -1;
- GLint uniformMaxNameLength = -1;
-
- mGlAbstraction.GetProgramiv(mProgramId, GL_ACTIVE_UNIFORMS, &numberOfActiveUniforms);
- mGlAbstraction.GetProgramiv(mProgramId, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformMaxNameLength);
-
- std::vector<std::string> samplerNames;
- std::vector<char> name(uniformMaxNameLength + 1); // Allow for null terminator
- std::vector<LocationPosition> samplerUniformLocations;
-
- {
- int nameLength = -1;
- int number = -1;
- GLenum type = GL_ZERO;
-
- for(int i = 0; i < numberOfActiveUniforms; ++i)
- {
- mGlAbstraction.GetActiveUniform(mProgramId, static_cast<GLuint>(i), uniformMaxNameLength, &nameLength, &number, &type, name.data());
-
- if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES)
- {
- GLuint location = mGlAbstraction.GetUniformLocation(mProgramId, name.data());
- samplerNames.push_back(name.data());
- samplerUniformLocations.push_back(LocationPosition(location, -1));
- }
- }
- }
-
- //Determine declaration order of each sampler
- char* fragShader = strdup(mProgramData->GetFragmentShader());
- char* uniform = strstr(fragShader, UNIFORM);
- int samplerPosition = 0;
- while(uniform)
- {
- char* outerToken = strtok_r(uniform + UNIFORM.mLength, ";", &uniform);
-
- char* nextPtr = nullptr;
- char* token = strtok_r(outerToken, DELIMITERS, &nextPtr);
- while(token)
- {
- 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);
- for(uint32_t i = 0; i < static_cast<uint32_t>(samplerUniformLocations.size()); ++i)
- {
- if(samplerUniformLocations[i].position == -1 &&
- strncmp(token, samplerNames[i].c_str(), samplerNames[i].size()) == 0)
- {
- samplerUniformLocations[i].position = samplerPosition++;
- found = true;
- break;
- }
- }
-
- if(!found)
- {
- DALI_LOG_ERROR("Sampler uniform %s declared but not used in the shader\n", token);
- }
- break;
- }
- }
-
- token = strtok_r(nullptr, DELIMITERS, &nextPtr);
- }
-
- uniform = strstr(uniform, UNIFORM);
- }
-
- free(fragShader);
-
- // Re-order according to declaration order in the fragment source.
- uint32_t samplerUniformCount = static_cast<uint32_t>(samplerUniformLocations.size());
- if(samplerUniformCount > 1)
- {
- std::sort(samplerUniformLocations.begin(), samplerUniformLocations.end(), sortByPosition);
- }
-
- mSamplerUniformLocations.resize(samplerUniformCount);
- for(uint32_t i = 0; i < samplerUniformCount; ++i)
- {
- mSamplerUniformLocations[i] = samplerUniformLocations[i].uniformLocation;
- }
-}
-
-bool Program::GetSamplerUniformLocation(uint32_t index, GLint& location)
-{
- bool result = false;
- if(index < mSamplerUniformLocations.size())
- {
- location = mSamplerUniformLocations[index];
- result = true;
- }
- return result;
-}
-
-uint32_t Program::GetActiveSamplerCount() const
-{
- return static_cast<uint32_t>(mSamplerUniformLocations.size());
-}
-
-void Program::SetUniform1i(GLint location, GLint value0)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // check if uniform location fits the cache
- if(location >= MAX_UNIFORM_CACHE_SIZE)
- {
- // not cached, make the gl call
- LOG_GL("Uniform1i(%d,%d)\n", location, value0);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform1i(location, value0));
- }
- else
- {
- // check if the value is different from what's already been set
- if(value0 != mUniformCacheInt[location])
- {
- // make the gl call
- LOG_GL("Uniform1i(%d,%d)\n", location, value0);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform1i(location, value0));
- // update cache
- mUniformCacheInt[location] = value0;
- }
- }
-}
-
-void Program::SetUniform4i(GLint location, GLint value0, GLint value1, GLint value2, GLint value3)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // Not caching these as based on current analysis this is not called that often by our shaders
- LOG_GL("Uniform4i(%d,%d,%d,%d,%d)\n", location, value0, value1, value2, value3);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform4i(location, value0, value1, value2, value3));
-}
-
-void Program::SetUniform1f(GLint location, GLfloat value0)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // check if uniform location fits the cache
- if(location >= MAX_UNIFORM_CACHE_SIZE)
- {
- // not cached, make the gl call
- LOG_GL("Uniform1f(%d,%f)\n", location, value0);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform1f(location, value0));
- }
- else
- {
- // check if the same value has already been set, reset if it is different
- if((fabsf(value0 - mUniformCacheFloat[location]) >= Math::MACHINE_EPSILON_1))
- {
- // make the gl call
- LOG_GL("Uniform1f(%d,%f)\n", location, value0);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform1f(location, value0));
-
- // update cache
- mUniformCacheFloat[location] = value0;
- }
- }
-}
-
-void Program::SetUniform2f(GLint location, GLfloat value0, GLfloat value1)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // check if uniform location fits the cache
- if(location >= MAX_UNIFORM_CACHE_SIZE)
- {
- // not cached, make the gl call
- LOG_GL("Uniform2f(%d,%f,%f)\n", location, value0, value1);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform2f(location, value0, value1));
- }
- else
- {
- // check if the same value has already been set, reset if it is different
- if((fabsf(value0 - mUniformCacheFloat2[location][0]) >= Math::MACHINE_EPSILON_1) ||
- (fabsf(value1 - mUniformCacheFloat2[location][1]) >= Math::MACHINE_EPSILON_1))
- {
- // make the gl call
- LOG_GL("Uniform2f(%d,%f,%f)\n", location, value0, value1);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform2f(location, value0, value1));
-
- // update cache
- mUniformCacheFloat2[location][0] = value0;
- mUniformCacheFloat2[location][1] = value1;
- }
- }
-}
-
-void Program::SetSizeUniform3f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2)
-{
- if((fabsf(value0 - mSizeUniformCache.x) >= Math::MACHINE_EPSILON_1) ||
- (fabsf(value1 - mSizeUniformCache.y) >= Math::MACHINE_EPSILON_1) ||
- (fabsf(value2 - mSizeUniformCache.z) >= Math::MACHINE_EPSILON_1))
- {
- mSizeUniformCache.x = value0;
- mSizeUniformCache.y = value1;
- mSizeUniformCache.z = value2;
- SetUniform3f(location, value0, value1, value2);
- }
-}
-
-void Program::SetUniform3f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // Not caching these as based on current analysis this is not called that often by our shaders
- LOG_GL("Uniform3f(%d,%f,%f,%f)\n", location, value0, value1, value2);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform3f(location, value0, value1, value2));
-}
-
-void Program::SetUniform4f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // check if uniform location fits the cache
- if(location >= MAX_UNIFORM_CACHE_SIZE)
- {
- // not cached, make the gl call
- LOG_GL("Uniform4f(%d,%f,%f,%f,%f)\n", location, value0, value1, value2, value3);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform4f(location, value0, value1, value2, value3));
- }
- else
- {
- // check if the same value has already been set, reset if any component is different
- // checking index 3 first because we're often animating alpha (rgba)
- if((fabsf(value3 - mUniformCacheFloat4[location][3]) >= Math::MACHINE_EPSILON_1) ||
- (fabsf(value0 - mUniformCacheFloat4[location][0]) >= Math::MACHINE_EPSILON_1) ||
- (fabsf(value1 - mUniformCacheFloat4[location][1]) >= Math::MACHINE_EPSILON_1) ||
- (fabsf(value2 - mUniformCacheFloat4[location][2]) >= Math::MACHINE_EPSILON_1))
- {
- // make the gl call
- LOG_GL("Uniform4f(%d,%f,%f,%f,%f)\n", location, value0, value1, value2, value3);
- CHECK_GL(mGlAbstraction, mGlAbstraction.Uniform4f(location, value0, value1, value2, value3));
- // update cache
- mUniformCacheFloat4[location][0] = value0;
- mUniformCacheFloat4[location][1] = value1;
- mUniformCacheFloat4[location][2] = value2;
- mUniformCacheFloat4[location][3] = value3;
- }
- }
-}
-
-void Program::SetUniformMatrix4fv(GLint location, GLsizei count, const GLfloat* value)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // Not caching these calls. Based on current analysis this is called very often
- // but with different values (we're using this for MVP matrices)
- // NOTE! we never want driver or GPU to transpose
- LOG_GL("UniformMatrix4fv(%d,%d,GL_FALSE,%x)\n", location, count, value);
- CHECK_GL(mGlAbstraction, mGlAbstraction.UniformMatrix4fv(location, count, GL_FALSE, value));
-}
-
-void Program::SetUniformMatrix3fv(GLint location, GLsizei count, const GLfloat* value)
-{
- DALI_ASSERT_DEBUG(IsUsed()); // should not call this if this program is not used
-
- if(UNIFORM_UNKNOWN == location)
- {
- // From http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml : Notes
- // If location is equal to UNIFORM_UNKNOWN, the data passed in will be silently ignored and the
- // specified uniform variable will not be changed.following opengl silently do nothing
- return;
- }
-
- // Not caching these calls. Based on current analysis this is called very often
- // but with different values (we're using this for MVP matrices)
- // NOTE! we never want driver or GPU to transpose
- LOG_GL("UniformMatrix3fv(%d,%d,GL_FALSE,%x)\n", location, count, value);
- CHECK_GL(mGlAbstraction, mGlAbstraction.UniformMatrix3fv(location, count, GL_FALSE, value));
-}
-
void Program::GlContextCreated()
{
}
void Program::GlContextDestroyed()
{
- ResetAttribsUniformCache();
+ ResetUniformCache();
}
bool Program::ModifiesGeometry()
mProgramData(shaderData),
mModifiesGeometry(modifiesGeometry)
{
- // reserve space for standard attributes
- mAttributeLocations.reserve(ATTRIB_TYPE_LAST);
- for(uint32_t i = 0; i < ATTRIB_TYPE_LAST; ++i)
- {
- RegisterCustomAttribute(ConstString(gStdAttribs[i]));
- }
-
// reserve space for standard uniforms
mUniformLocations.reserve(UNIFORM_TYPE_LAST);
+
// reset built in uniform names in cache
for(uint32_t i = 0; i < UNIFORM_TYPE_LAST; ++i)
{
}
// reset values
- ResetAttribsUniformCache();
+ ResetUniformCache();
// Get program id and use it as hash for the cache
// in order to maintain current functionality as long as needed
{
}
-void Program::ResetAttribsUniformCache()
+void Program::ResetUniformCache()
{
- // reset attribute locations
- for(uint32_t i = 0; i < mAttributeLocations.size(); ++i)
- {
- mAttributeLocations[i].second = ATTRIB_UNKNOWN;
- }
-
// reset all gl uniform locations
for(uint32_t i = 0; i < mUniformLocations.size(); ++i)
{
/**
* A program contains a vertex & fragment shader.
- *
- * Program caches some of vertex attribute locations and uniform variable values to reduce unnecessary state changes.
+ * It interfaces to the implementation program and it's reflection.
*/
class Program
{
static const int32_t MAX_UNIFORM_CACHE_SIZE = 16;
/**
- * Constant for uniform / attribute not found
+ * Constant for uniform not found
*/
static const int32_t NOT_FOUND = -1;
- /**
- * Vertex attributes
- */
- enum AttribType
- {
- ATTRIB_UNKNOWN = -1,
- ATTRIB_POSITION,
- ATTRIB_TEXCOORD,
- ATTRIB_TYPE_LAST
- };
-
/**
* Common shader uniform names
*/
*/
static Program* New(ProgramCache& cache, Internal::ShaderDataPtr shaderData, Graphics::Controller& gfxController, Graphics::UniquePtr<Graphics::Program>&& gfxProgram, bool modifiesGeometry);
- /**
- * Takes this program into use
- */
- void Use();
-
- /**
- * @return true if this program is used currently
- */
- bool IsUsed();
-
- /**
- * @param [in] type of the attribute
- * @return the index of the attribute
- */
- GLint GetAttribLocation(AttribType type);
-
- /**
- * Register an attribute name in our local cache
- * @param [in] name attribute name
- * @return the index of the attribute name in local cache
- */
- uint32_t RegisterCustomAttribute(ConstString name);
-
- /**
- * Gets the location of a pre-registered attribute.
- * @param [in] attributeIndex of the attribute in local cache
- * @return the index of the attribute in the GL program
- */
- GLint GetCustomAttributeLocation(uint32_t attributeIndex);
-
- /**
+ /*
* Register a uniform name in our local cache
* @param [in] name uniform name
* @return the index of the uniform name in local cache
*/
uint32_t RegisterUniform(ConstString name);
- /**
- * Gets the location of a pre-registered uniform.
- * Uniforms in list UniformType are always registered and in the order of the enumeration
- * @param [in] uniformIndex of the uniform in local cache
- * @return the index of the uniform in the GL program
- */
- GLint GetUniformLocation(uint32_t uniformIndex);
-
- /**
- * Introspect the newly loaded shader to get the active sampler locations
- */
- void GetActiveSamplerUniforms();
-
- /**
- * Gets the uniform location for a sampler
- * @param [in] index The index of the active sampler
- * @param [out] location The location of the requested sampler
- * @return true if the active sampler was found
- */
- bool GetSamplerUniformLocation(uint32_t index, GLint& location);
-
- /**
- * Get the number of active samplers present in the shader
- * @return The number of active samplers
- */
- uint32_t GetActiveSamplerCount() const;
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as int
- */
- void SetUniform1i(GLint location, GLint value0);
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as int
- * @param [in] value1 as int
- * @param [in] value2 as int
- * @param [in] value3 as int
- */
- void SetUniform4i(GLint location, GLint value0, GLint value1, GLint value2, GLint value3);
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- */
- void SetUniform1f(GLint location, GLfloat value0);
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- */
- void SetUniform2f(GLint location, GLfloat value0, GLfloat value1);
-
- /**
- * Special handling for size as we're using uniform geometry so size is passed on to most programs
- * but it rarely changes so we can cache it
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- * @param [in] value2 as float
- */
- void SetSizeUniform3f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2);
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- * @param [in] value2 as float
- */
- void SetUniform3f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2);
-
- /**
- * Sets the uniform value
- * @param [in] location of uniform
- * @param [in] value0 as float
- * @param [in] value1 as float
- * @param [in] value2 as float
- * @param [in] value3 as float
- */
- void SetUniform4f(GLint location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3);
-
- /**
- * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
- * so make sure your matrix is in correct order for GL.
- * @param [in] location Location of uniform
- * @param [in] count Count of matrices
- * @param [in] value values as float pointers
- */
- void SetUniformMatrix4fv(GLint location, GLsizei count, const GLfloat* value);
-
- /**
- * Sets the uniform value as matrix. NOTE! we never want GPU to transpose
- * so make sure your matrix is in correct order for GL.
- * @param [in] location Location of uniform
- * @param [in] count Count of matrices
- * @param [in] value values as float pointers
- */
- void SetUniformMatrix3fv(GLint location, GLsizei count, const GLfloat* value);
-
/**
* Needs to be called when GL context is (re)created
*/
Program& operator=(const Program&); ///< assignment operator, not defined
/**
- * Resets caches
+ * Resets uniform cache
*/
- void ResetAttribsUniformCache();
+ void ResetUniformCache();
/**
* Struct ReflectionUniformInfo
using NameLocationPair = std::pair<ConstString, GLint>;
using Locations = std::vector<NameLocationPair>;
- Locations mAttributeLocations; ///< attribute location cache
Locations mUniformLocations; ///< uniform location cache
std::vector<GLint> mSamplerUniformLocations; ///< sampler uniform location cache