From 465547d40b4d9acc7c3b72adc219a9c00909c04d Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Fri, 3 May 2024 11:10:13 +0100 Subject: [PATCH] Support for recognizing legacy shaders. Legacy shaders should be bypassed through the shader processing pipeline as they are. Change-Id: Ib96810c8dfe9267870b08ab4248ed20ccb5774ad --- automated-tests/src/dali-graphics/CMakeLists.txt | 1 + .../src/dali-graphics/utc-Dali-GraphicsShader.cpp | 121 +++++++++++++++++++++ .../graphics/gles-impl/gles-graphics-shader.cpp | 41 ++++++- .../graphics/gles-impl/gles-graphics-shader.h | 10 +- 4 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 automated-tests/src/dali-graphics/utc-Dali-GraphicsShader.cpp diff --git a/automated-tests/src/dali-graphics/CMakeLists.txt b/automated-tests/src/dali-graphics/CMakeLists.txt index 1dee934..8ec9991 100644 --- a/automated-tests/src/dali-graphics/CMakeLists.txt +++ b/automated-tests/src/dali-graphics/CMakeLists.txt @@ -14,6 +14,7 @@ SET(TC_SOURCES utc-Dali-GraphicsNativeImage.cpp utc-Dali-GraphicsProgram.cpp utc-Dali-GraphicsSampler.cpp + utc-Dali-GraphicsShader.cpp utc-Dali-GraphicsTexture.cpp ) diff --git a/automated-tests/src/dali-graphics/utc-Dali-GraphicsShader.cpp b/automated-tests/src/dali-graphics/utc-Dali-GraphicsShader.cpp new file mode 100644 index 0000000..e2ec99e --- /dev/null +++ b/automated-tests/src/dali-graphics/utc-Dali-GraphicsShader.cpp @@ -0,0 +1,121 @@ +/* +* 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 +#include +#include +#include +#include + +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; +} \ No newline at end of file diff --git a/dali/internal/graphics/gles-impl/gles-graphics-shader.cpp b/dali/internal/graphics/gles-impl/gles-graphics-shader.cpp index ab265a7..897a50d 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-shader.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-shader.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -32,16 +32,23 @@ struct ShaderImpl::Impl 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(_createInfo.sourceData), - reinterpret_cast(_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(_createInfo.sourceData) + dataStartIndex, + reinterpret_cast(_createInfo.sourceData) + dataSize, source.data()); // Substitute pointer createInfo.sourceData = source.data(); + createInfo.sourceSize = dataSize; } ~Impl(){}; @@ -209,6 +216,28 @@ const ShaderCreateInfo& ShaderImpl::GetCreateInfo() const 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 + if(info.shaderVersion != 0) + { + auto text = reinterpret_cast(info.sourceData); + auto result = std::string_view(text).find("//@legacy-prefix-end"); + 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(info.sourceData) + 21, &end, 10); + } + } + + finalDataSize = info.sourceSize - startIndex; +} + Shader::~Shader() { if(!mShader->Release()) diff --git a/dali/internal/graphics/gles-impl/gles-graphics-shader.h b/dali/internal/graphics/gles-impl/gles-graphics-shader.h index 28c7370..45fce49 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-shader.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-shader.h @@ -2,7 +2,7 @@ #define DALI_GRAPHICS_GLES_SHADER_H /* - * 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. @@ -76,6 +76,14 @@ public: [[nodiscard]] EglGraphicsController& GetController() const; + /** + * Strips legacy prefix fromt he GLSL source code if necessary + * @param info valid ShaderCreateInfo strucutre + * @param[out] startIndex Start index of the source code + * @param[out] finalDataSize Size of trimmed data + */ + static void StripLegacyCodeIfNeeded(const ShaderCreateInfo& info, size_t& startIndex, size_t& finalDataSize); + private: friend class Shader; struct Impl; -- 2.7.4