--- /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/dali.h>
+#include <dali/integration-api/testing.h>
+#include <dali/internal/graphics/gles-impl/gles-graphics-shader.h>
+#include <test-graphics-application.h>
+
+int UtcDaliGlesStripLegacyCodeIfNeededTest1(void)
+{
+ TestGraphicsApplication application;
+
+ {
+ Dali::Graphics::ShaderCreateInfo info;
+ info.SetPipelineStage(Dali::Graphics::PipelineStage::VERTEX_SHADER);
+ std::string vertexShader =
+ "//@version 100\n"
+ "some code\n";
+
+ info.SetShaderVersion(100);
+ info.SetSourceData(vertexShader.data());
+ info.SetSourceSize(vertexShader.size());
+ info.SetSourceMode(Dali::Graphics::ShaderSourceMode::TEXT);
+
+ size_t dataSize = 0;
+ size_t dataIndex = 0;
+ Graphics::GLES::ShaderImpl::StripLegacyCodeIfNeeded(info, dataIndex, dataSize);
+
+ DALI_TEST_EQUALS(dataIndex, 0, TEST_LOCATION);
+ DALI_TEST_EQUALS(dataSize, vertexShader.size(), TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliGlesStripLegacyCodeTestDifferentPrefix(void)
+{
+ TestGraphicsApplication application;
+
+ std::string vertexShader =
+ "//@version 100\n"
+ "some code\n";
+
+ std::string somePrefix =
+ "This is some prefix\n";
+
+ auto newVertexPrefix = Dali::Integration::Test::GenerateTaggedShaderPrefix(somePrefix);
+ {
+ Dali::Graphics::ShaderCreateInfo info;
+ info.SetPipelineStage(Dali::Graphics::PipelineStage::VERTEX_SHADER);
+
+ std::string prefixedVertexShader = newVertexPrefix + vertexShader;
+
+ info.SetShaderVersion(100);
+ info.SetSourceData(prefixedVertexShader.data());
+ info.SetSourceSize(prefixedVertexShader.size());
+ info.SetSourceMode(Dali::Graphics::ShaderSourceMode::TEXT);
+
+ size_t dataSize = 0;
+ size_t dataIndex = 0;
+ Graphics::GLES::ShaderImpl::StripLegacyCodeIfNeeded(info, dataIndex, dataSize);
+
+ auto index = prefixedVertexShader.find("//@version");
+
+ DALI_TEST_EQUALS(dataIndex, index, TEST_LOCATION);
+
+ // should match original shader size
+ DALI_TEST_EQUALS(dataSize, vertexShader.size(), TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliGlesStripLegacyCodeIfNeededTest2(void)
+{
+ TestGraphicsApplication application;
+
+ std::string vertexShader =
+ "//@version 100\n"
+ "some code\n";
+
+ auto vertexPrefix = Dali::Shader::GetVertexShaderPrefix();
+
+ {
+ Dali::Graphics::ShaderCreateInfo info;
+ info.SetPipelineStage(Dali::Graphics::PipelineStage::VERTEX_SHADER);
+
+ std::string prefixedVertexShader = Dali::Shader::GetVertexShaderPrefix() + vertexShader;
+
+ info.SetShaderVersion(100);
+ info.SetSourceData(prefixedVertexShader.data());
+ info.SetSourceSize(prefixedVertexShader.size());
+ info.SetSourceMode(Dali::Graphics::ShaderSourceMode::TEXT);
+
+ size_t dataSize = 0;
+ size_t dataIndex = 0;
+ Graphics::GLES::ShaderImpl::StripLegacyCodeIfNeeded(info, dataIndex, dataSize);
+
+ DALI_TEST_EQUALS(dataIndex, vertexPrefix.length(), TEST_LOCATION);
+
+ // should match original shader size
+ DALI_TEST_EQUALS(dataSize, vertexShader.size(), TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliGlesLegacyCodeTest(void)
+{
+ TestGraphicsApplication application;
+
+ std::string vertexShader =
+ "#version 320 es\n"
+ "some code\n";
+
+ std::string somePrefix =
+ "This is some prefix\n";
+
+ auto newVertexPrefix = Dali::Integration::Test::GenerateTaggedShaderPrefix(somePrefix);
+ {
+ Dali::Graphics::ShaderCreateInfo info;
+ info.SetPipelineStage(Dali::Graphics::PipelineStage::VERTEX_SHADER);
+
+ std::string prefixedVertexShader = newVertexPrefix + vertexShader;
+
+ info.SetShaderVersion(0);
+ info.SetSourceData(prefixedVertexShader.data());
+ info.SetSourceSize(prefixedVertexShader.size());
+ info.SetSourceMode(Dali::Graphics::ShaderSourceMode::TEXT);
+
+ size_t dataSize = 0;
+ size_t dataIndex = 0;
+ Graphics::GLES::ShaderImpl::StripLegacyCodeIfNeeded(info, dataIndex, dataSize);
+
+ auto index = prefixedVertexShader.find("#version");
+
+ DALI_TEST_EQUALS(dataIndex, index, TEST_LOCATION);
+
+ // should match original shader size
+ DALI_TEST_EQUALS(dataSize, vertexShader.size(), TEST_LOCATION);
+ }
+
+ END_TEST;
+}
\ No newline at end of file
/*
- * Copyright (c) 2023 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.
createInfo.pipelineStage = _createInfo.pipelineStage;
createInfo.shaderlanguage = _createInfo.shaderlanguage;
createInfo.sourceMode = _createInfo.sourceMode;
- createInfo.sourceSize = _createInfo.sourceSize;
+ createInfo.shaderVersion = _createInfo.shaderVersion;
- // Make a copy of source code
- source.resize(_createInfo.sourceSize);
- std::copy(reinterpret_cast<const uint8_t*>(_createInfo.sourceData),
- reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + _createInfo.sourceSize,
+ // Make a copy of source code. if code is meant to be used
+ // by modern parser, skip the prefix part
+ size_t dataStartIndex = 0;
+ size_t dataSize;
+
+ ShaderImpl::StripLegacyCodeIfNeeded( _createInfo, dataStartIndex, dataSize );
+
+ source.resize(dataSize);
+ std::copy(reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + dataStartIndex,
+ reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + dataStartIndex + dataSize,
source.data());
// Substitute pointer
createInfo.sourceData = source.data();
+ createInfo.sourceSize = dataSize;
}
~Impl(){};
return mImpl->controller;
}
+void ShaderImpl::StripLegacyCodeIfNeeded(const ShaderCreateInfo& info, size_t& startIndex, size_t& finalDataSize)
+{
+ // Make a copy of source code. if code is meant to be used
+ // by modern parser, skip the prefix part
+ auto text = reinterpret_cast<const char*>(info.sourceData);
+ auto result = std::string_view(text).find("//@legacy-prefix-end");
+ if(info.shaderVersion != 0)
+ {
+ if(result != 0 && result != std::string::npos)
+ {
+ DALI_LOG_ERROR("Shader processing: @legacy-prefix-end must be a very first statement!\n");
+ }
+ else if(result == 0)
+ {
+ char* end;
+ startIndex = std::strtoul(reinterpret_cast<const char*>(info.sourceData) + 21, &end, 10);
+ }
+ }
+ else
+ {
+ // For legacy shaders we need to make sure that the #version is a very first line
+ // so need to strip //@legacy-prefix-end tag
+ if(result != std::string::npos)
+ {
+ auto versionPos = std::string_view(text).find("#version", result);
+ if(versionPos == std::string::npos)
+ {
+ DALI_LOG_ERROR("Shader processing: new-line missing after @legacy-prefix-end!\n");
+ startIndex = 0; // not trimming anything
+ }
+ else
+ {
+ startIndex = versionPos;
+ }
+ }
+ }
+ finalDataSize = info.sourceSize - startIndex;
+}
+
Shader::~Shader()
{
if(!mShader->Release())