utc-Dali-Internal-PinchGestureProcessor.cpp
utc-Dali-Internal-PipelineCache.cpp
utc-Dali-Internal-RotationGesture.cpp
+ utc-Dali-Internal-Shader.cpp
utc-Dali-Internal-TapGesture.cpp
utc-Dali-Internal-TapGestureProcessor.cpp
utc-Dali-Internal-Texture.cpp
--- /dev/null
+/*
+* 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.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <dali-test-suite-utils.h>
+#include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
+#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/event/effects/shader-factory.h>
+#include <dali/internal/event/rendering/shader-impl.h>
+#include <dali/internal/update/manager/update-manager.h>
+#include <dali/public-api/dali-core.h>
+#include <dali/public-api/object/type-registry.h>
+
+using namespace Dali;
+
+int UtcDaliShaderTestVersion(void)
+{
+ TestApplication application;
+
+ std::string vertexShader =
+ "//@version 100\n"
+ "some code\n";
+ std::string fragmentShader =
+ "//@version 101\n"
+ "some code\n";
+
+ Dali::Shader shader = Dali::Shader::New(vertexShader, fragmentShader);
+ {
+ auto vertexPrefix = Dali::Shader::GetVertexShaderPrefix();
+ auto fragmentPrefix = Dali::Shader::GetFragmentShaderPrefix();
+
+ DALI_TEST_EQUALS(vertexPrefix.substr(0, 20), "//@legacy-prefix-end", TEST_LOCATION);
+ DALI_TEST_EQUALS(fragmentPrefix.substr(0, 20), "//@legacy-prefix-end", TEST_LOCATION);
+ }
+
+ // Test version number in the shader data
+ Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
+ Dali::Internal::ShaderFactory& shaderFactory = tls.GetShaderFactory();
+ size_t shaderHash;
+ Internal::ShaderDataPtr shaderData = shaderFactory.Load(vertexShader, fragmentShader, {}, {}, "", shaderHash);
+
+ bool dataValid = (shaderData != nullptr);
+ DALI_TEST_EQUALS(dataValid, true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(shaderData->GetVertexShaderVersion(), 100, TEST_LOCATION);
+ DALI_TEST_EQUALS(shaderData->GetFragmentShaderVersion(), 101, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliShaderWithPrefixTestVersion(void)
+{
+ TestApplication application;
+
+ std::string vertexShader =
+ "//@version 100\n"
+ "some code\n";
+ std::string fragmentShader =
+ "//@version 101\n"
+ "some code\n";
+
+ auto vertexPrefix = Dali::Shader::GetVertexShaderPrefix();
+ auto fragmentPrefix = Dali::Shader::GetFragmentShaderPrefix();
+
+ Dali::Shader shader = Dali::Shader::New(
+ vertexPrefix + vertexShader,
+ fragmentPrefix + fragmentShader);
+
+ DALI_TEST_EQUALS(vertexPrefix.substr(0, 20), "//@legacy-prefix-end", TEST_LOCATION);
+ DALI_TEST_EQUALS(fragmentPrefix.substr(0, 20), "//@legacy-prefix-end", TEST_LOCATION);
+
+ // Test version number in the shader data
+ Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
+ Dali::Internal::ShaderFactory& shaderFactory = tls.GetShaderFactory();
+ size_t shaderHash;
+ Internal::ShaderDataPtr shaderData = shaderFactory.Load(vertexShader, fragmentShader, {}, {}, "", shaderHash);
+
+ bool dataValid = (shaderData != nullptr);
+ DALI_TEST_EQUALS(dataValid, true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(shaderData->GetVertexShaderVersion(), 100, TEST_LOCATION);
+ DALI_TEST_EQUALS(shaderData->GetFragmentShaderVersion(), 101, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
#define DALI_GRAPHICS_SHADER_CREATE_INFO_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.
return *this;
}
+ /**
+ * @brief Sets shader code DALi-specific version
+ *
+ * @param[in] value shader version
+ * @return reference to this structure
+ */
+ auto& SetShaderVersion(uint32_t value)
+ {
+ shaderVersion = value;
+ return *this;
+ }
+
/**
* @brief Sets allocation callbacks which will be used when object is created
* and destroyed.
const void* sourceData{nullptr};
uint32_t sourceSize{0u};
ShaderSourceMode sourceMode{};
+ uint32_t shaderVersion{};
const AllocationCallbacks* allocationCallbacks{nullptr};
};
${platform_abstraction_src_dir}/profiling.cpp
${platform_abstraction_src_dir}/render-task-list-integ.cpp
${platform_abstraction_src_dir}/scene.cpp
+ ${platform_abstraction_src_dir}/testing.cpp
${platform_abstraction_src_dir}/texture-integ.cpp
${platform_abstraction_src_dir}/trace.cpp
)
${platform_abstraction_src_dir}/resource-policies.h
${platform_abstraction_src_dir}/resource-types.h
${platform_abstraction_src_dir}/scene.h
+ ${platform_abstraction_src_dir}/testing.h
${platform_abstraction_src_dir}/texture-integ.h
${platform_abstraction_src_dir}/trace.h
)
--- /dev/null
+/*
+* 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.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+#include <dali/integration-api/testing.h>
+#include <dali/internal/event/rendering/shader-impl.h>
+
+namespace Dali
+{
+namespace Integration
+{
+namespace Test
+{
+std::string GenerateTaggedShaderPrefix(std::string prefix)
+{
+ return Internal::Shader::GenerateTaggedShaderPrefix(prefix);
+}
+} // Namespace Test
+} // Namespace Integration
+} // Namespace Dali
--- /dev/null
+#ifndef DALI_INTEGRATION_TESTING_H
+#define DALI_INTEGRATION_TESTING_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <string>
+
+namespace Dali
+{
+namespace Integration
+{
+/**
+ * This functions should be used only within automated tests suit
+ */
+namespace Test
+{
+/**
+ * @brief Generates internal tag for shader prefix
+ * @param[in] prefix Prefix to generate tag for
+ * @return Tagged prefix
+ */
+std::string GenerateTaggedShaderPrefix(std::string prefix);
+
+} // Namespace Test
+} // Namespace Integration
+} // Namespace Dali
+
+#endif
\ No newline at end of file
mRenderPassTag(renderPassTag),
mName(name)
{
+ UpdateShaderVersion(mVertexShader, mVertexShaderVersion);
+ UpdateShaderVersion(mFragmentShader, mFragmentShaderVersion);
}
/**
mRenderPassTag(renderPassTag),
mName(name)
{
+ UpdateShaderVersion(mVertexShader, mVertexShaderVersion);
+ UpdateShaderVersion(mFragmentShader, mFragmentShaderVersion);
}
/**
mRenderPassTag(renderPassTag),
mName(name)
{
+ UpdateShaderVersion(mVertexShader, mVertexShaderVersion);
+ UpdateShaderVersion(mFragmentShader, mFragmentShaderVersion);
}
/**
return mName;
}
+ /**
+ * Returns DALi specific vertex shader version
+ * @return valid version number
+ */
+ uint32_t GetVertexShaderVersion() const
+ {
+ return mVertexShaderVersion;
+ }
+
+ /**
+ * Returns DALi specific fragment shader version
+ * @return valid version number
+ */
+ uint32_t GetFragmentShaderVersion() const
+ {
+ return mFragmentShaderVersion;
+ }
+
private: // Not implemented
ShaderData(const ShaderData& other); ///< no copying of this object
ShaderData& operator=(const ShaderData& rhs); ///< no copying of this object
-private: // Data
- std::size_t mShaderHash; ///< hash key created with vertex and fragment shader code
- std::vector<char> mVertexShader; ///< source code for vertex program
- std::vector<char> mFragmentShader; ///< source code for fragment program
- Dali::Shader::Hint::Value mHints; ///< take a hint
- Dali::Vector<uint8_t> mBuffer; ///< buffer containing compiled binary bytecode
- Graphics::ShaderSourceMode mSourceMode; ///< Source mode of shader data ( text or binary )
- uint32_t mRenderPassTag{0u}; ///< Render Pass Tag for this shader
- std::string mName{""}; ///< Name for this shader
+private:
+ /**
+ * Updates shader version.
+ */
+ void UpdateShaderVersion(std::vector<char>& code, uint32_t& outVersion)
+ {
+ // The version may be updated only for GLSL language.
+ // If we support direct SPIRV this will be skipped
+ std::string_view strView = code.data();
+
+ // find first occurence of 'version' tag
+ // the tag is expected at the start of line
+ static const std::string VERSION_TAG = "//@version";
+
+ auto pos = strView.find(VERSION_TAG);
+ if(pos != std::string_view::npos && (pos == 0 || strView[pos - 1] == '\n'))
+ {
+ char* end;
+ // Update version
+ outVersion = std::strtoul(strView.data() + pos + VERSION_TAG.length(), &end, 10);
+ }
+ else
+ {
+ outVersion = 0;
+ }
+ }
+
+private: // Data
+ std::size_t mShaderHash; ///< hash key created with vertex and fragment shader code
+ std::vector<char> mVertexShader; ///< source code for vertex program
+ std::vector<char> mFragmentShader; ///< source code for fragment program
+ Dali::Shader::Hint::Value mHints; ///< take a hint
+ Dali::Vector<uint8_t> mBuffer; ///< buffer containing compiled binary bytecode
+ Graphics::ShaderSourceMode mSourceMode; ///< Source mode of shader data ( text or binary )
+ uint32_t mRenderPassTag{0u}; ///< Render Pass Tag for this shader
+ std::string mName{""}; ///< Name for this shader
+ uint32_t mVertexShaderVersion; ///< Vertex shader version
+ uint32_t mFragmentShaderVersion; ///< Fragment shader version
};
} // namespace Internal
std::string Shader::GetVertexShaderPrefix()
{
Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
- return tls.GetVertexShaderPrefix();
+ return GenerateTaggedShaderPrefix(tls.GetVertexShaderPrefix());
}
std::string Shader::GetFragmentShaderPrefix()
{
Dali::Internal::ThreadLocalStorage& tls = Dali::Internal::ThreadLocalStorage::Get();
- return tls.GetFragmentShaderPrefix();
+ return GenerateTaggedShaderPrefix(tls.GetFragmentShaderPrefix());
+}
+
+std::string Shader::GenerateTaggedShaderPrefix(const std::string& shaderPrefix)
+{
+ // The tag is added at the top of vertex/fragment shader and
+ // contains an offset where the source code starts after
+ // the prefix.
+ // This offset is used later by the graphics backend to ignore
+ // the legacy prefix if provided with new versioned shader.
+ // When shader contains tagged prefix, then it starts with:
+ // "//@legacy-prefix-end <offset>" tag.
+ static const std::string TAG = "//@legacy-prefix-end ";
+ const uint32_t OFFSET_DIGITS = 5; // offset allocates 5 digits
+
+ auto prefix = std::string(TAG + "00000\n") + shaderPrefix;
+ auto prefixLength = prefix.length();
+ char tmp = *(prefix.data() + TAG.length() + OFFSET_DIGITS);
+ std::snprintf(prefix.data() + TAG.size(), OFFSET_DIGITS + 1, "%05d", int(prefixLength));
+ *(prefix.data() + TAG.length() + OFFSET_DIGITS) = tmp;
+ return prefix;
}
} // namespace Internal
* @copydoc Dali::Shader::GetFragmentShaderPrefix()
*/
static std::string GetFragmentShaderPrefix();
+
+public:
+ /**
+ * Generates tag 'legacy-prefix-end' with end position of
+ * prefix text to make shader code parsing easier.
+ * Function is public to be testable
+ */
+ static std::string GenerateTaggedShaderPrefix(const std::string& shaderPrefix);
};
} // namespace Internal
const std::vector<char>& vertexShaderSrc = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::VERTEX_SHADER);
vertexShaderCreateInfo.SetSourceSize(vertexShaderSrc.size());
vertexShaderCreateInfo.SetSourceData(static_cast<const void*>(vertexShaderSrc.data()));
+ vertexShaderCreateInfo.SetShaderVersion(shaderData->GetVertexShaderVersion());
auto vertexShader = mGraphicsController->CreateShader(vertexShaderCreateInfo, nullptr);
Graphics::ShaderCreateInfo fragmentShaderCreateInfo;
const std::vector<char>& fragmentShaderSrc = shaderData->GetShaderForPipelineStage(Graphics::PipelineStage::FRAGMENT_SHADER);
fragmentShaderCreateInfo.SetSourceSize(fragmentShaderSrc.size());
fragmentShaderCreateInfo.SetSourceData(static_cast<const void*>(fragmentShaderSrc.data()));
+ fragmentShaderCreateInfo.SetShaderVersion(shaderData->GetFragmentShaderVersion());
auto fragmentShader = mGraphicsController->CreateShader(fragmentShaderCreateInfo, nullptr);
std::vector<Graphics::ShaderState> shaderStates{
mRenderCallbackInput->usingOwnEglContext = isolatedNotDirect;
// Set storage for the context to be used
info.glesNativeInfo.eglSharedContextStoragePointer = &mRenderCallbackInput->eglContext;
- info.executionMode = isolatedNotDirect ?
- Graphics::DrawNativeExecutionMode::ISOLATED : Graphics::DrawNativeExecutionMode::DIRECT;
- info.reserved = nullptr;
+ info.executionMode = isolatedNotDirect ? Graphics::DrawNativeExecutionMode::ISOLATED : Graphics::DrawNativeExecutionMode::DIRECT;
+ info.reserved = nullptr;
auto& textureResources = mRenderCallback->GetTextureResources();