[Tizen] Support for recognizing legacy shaders.
authorWonsik Jung <sidein@samsung.com>
Wed, 26 Jun 2024 04:30:03 +0000 (13:30 +0900)
committerWonsik Jung <sidein@samsung.com>
Wed, 26 Jun 2024 04:30:10 +0000 (13:30 +0900)
This reverts commit fae8eeed315598f3daa0b9cdd5edb741567e7223.

automated-tests/src/dali-graphics/CMakeLists.txt
automated-tests/src/dali-graphics/utc-Dali-GraphicsShader.cpp [new file with mode: 0644]
dali/internal/graphics/gles-impl/gles-graphics-shader.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.h

index 1dee934..8ec9991 100644 (file)
@@ -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 (file)
index 0000000..6b9bad3
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+* 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
index ab265a7..36ffd27 100644 (file)
@@ -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<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(){};
@@ -209,6 +216,45 @@ 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
+  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())
index 28c7370..45fce49 100644 (file)
@@ -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;