Keep offset of removal prefix of shader code, and use it at cache comparision 20/318220/1
authorEunki Hong <eunkiki.hong@samsung.com>
Wed, 25 Sep 2024 16:53:31 +0000 (01:53 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Wed, 25 Sep 2024 17:03:49 +0000 (02:03 +0900)
Since source code after ShaderImpl::StripLegacyCodeIfNeeded might be changed,
shader code comparision not works well.

To fix this issue, let we store the offset of code what we removed,
and compare with inputed shader code, only after that offset.

Change-Id: I699125fa2c471473e85ad6104b200d609fdd92e4
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
dali/internal/graphics/gles-impl/gles-graphics-pipeline-cache.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.h

index 183efb6e02e1222fc82c6abdbd92d7312e13ce9c..4f9c8d785f3ec66cb1d1da915947964582b2fda2 100644 (file)
@@ -502,15 +502,24 @@ ShaderImpl* PipelineCache::FindShaderImpl(const ShaderCreateInfo& shaderCreateIn
     for(auto& item : mImpl->shaderEntries)
     {
       auto& itemInfo = item.shaderImpl->GetCreateInfo();
+
+      // Check metadata
       if(itemInfo.pipelineStage != shaderCreateInfo.pipelineStage ||
          itemInfo.shaderlanguage != shaderCreateInfo.shaderlanguage ||
-         itemInfo.sourceMode != shaderCreateInfo.sourceMode ||
-         itemInfo.sourceSize != shaderCreateInfo.sourceSize)
+         itemInfo.sourceMode != shaderCreateInfo.sourceMode)
+      {
+        continue;
+      }
+
+      // Get offset of source. Since prefix might be removed after ShaderImpl created,
+      // we should compare only after the offset.
+      auto sourceOffset = item.shaderImpl->GetSourceOffset();
+      if(itemInfo.sourceSize + sourceOffset != shaderCreateInfo.sourceSize)
       {
         continue;
       }
 
-      if(memcmp(itemInfo.sourceData, shaderCreateInfo.sourceData, itemInfo.sourceSize) == 0)
+      if(memcmp(itemInfo.sourceData, reinterpret_cast<const uint8_t*>(shaderCreateInfo.sourceData) + sourceOffset, itemInfo.sourceSize) == 0)
       {
         return item.shaderImpl.get();
       }
index 2ee3020fd36a31ebe3ccfec2d2512ab9323f64d4..2a4ba73db205884ff1f26030778b0fb16ecf682d 100644 (file)
@@ -36,14 +36,13 @@ struct ShaderImpl::Impl
 
     // 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, glslVersion, dataSize);
+    ShaderImpl::StripLegacyCodeIfNeeded(_createInfo, sourceOffset, glslVersion, dataSize);
 
     source.resize(dataSize);
-    std::copy(reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + dataStartIndex,
-              reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + dataStartIndex + dataSize,
+    std::copy(reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + sourceOffset,
+              reinterpret_cast<const uint8_t*>(_createInfo.sourceData) + sourceOffset + dataSize,
               source.data());
 
     // Substitute pointer
@@ -155,6 +154,10 @@ struct ShaderImpl::Impl
   std::vector<uint8_t>   source{};
   std::vector<uint8_t>   sourcePreprocessed{};
 
+  size_t sourceOffset{0u}; /// byte offset of source data from original CreateInfo.
+                             /// It will be changed after call StripLegacyCodeIfNeeded
+                             /// More detail, createInfo.sourceData[0] == source[0] == (original CreateInfo).sourceData[sourceOffset];
+
   uint32_t glShader{};
   uint32_t refCount{0u};
   uint32_t flushCount{0u};  ///< Number of frames at refCount=0
@@ -207,6 +210,11 @@ uint32_t ShaderImpl::Release()
   return mImpl->glslVersion;
 }
 
+[[nodiscard]] size_t ShaderImpl::GetSourceOffset() const
+{
+  return mImpl->sourceOffset;
+}
+
 /**
  * @brief Compiles shader
  *
@@ -234,6 +242,16 @@ const ShaderCreateInfo& ShaderImpl::GetCreateInfo() const
 
 void ShaderImpl::StripLegacyCodeIfNeeded(const ShaderCreateInfo& info, size_t& startIndex, uint32_t& glslVersion, size_t& finalDataSize)
 {
+  startIndex = 0u;
+
+  // Fast-out if shader is not a text.
+  if(info.sourceMode != ShaderSourceMode::TEXT)
+  {
+    glslVersion   = info.shaderVersion;
+    finalDataSize = info.sourceSize;
+    return;
+  }
+
   // 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);
@@ -248,7 +266,8 @@ void ShaderImpl::StripLegacyCodeIfNeeded(const ShaderCreateInfo& info, size_t& s
     else if(result == 0)
     {
       char* end;
-      startIndex = std::strtoul(reinterpret_cast<const char*>(info.sourceData) + 21, &end, 10);
+      startIndex  = std::strtoul(reinterpret_cast<const char*>(info.sourceData) + 21, &end, 10);
+      glslVersion = info.shaderVersion;
     }
   }
   else
index ac85822e0c908c557e1370e2bca5c8120585fbda..077fcbd3a591cd9d9851629501b55eefe2377c4e 100644 (file)
@@ -126,6 +126,12 @@ public:
    */
   [[nodiscard]] uint32_t GetGLSLVersion() const;
 
+  /**
+   * @brief Returns source prefix offset infomation.
+   * @return Returns source prefix offset value
+   */
+  [[nodiscard]] size_t GetSourceOffset() const;
+
 private:
   friend class Shader;
   struct Impl;