Add flag for precompile shader 50/322650/8
authorsunghyun kim <scholb.kim@samsung.com>
Mon, 14 Apr 2025 04:31:22 +0000 (13:31 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Tue, 22 Apr 2025 06:13:48 +0000 (15:13 +0900)
Change-Id: If48a07ac3943fd82f8c316bb68ff4d49701ff405

automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali-egl-graphics/utc-Dali-GraphicsProgram.cpp
dali/internal/adaptor/common/combined-update-render-controller.cpp
dali/internal/adaptor/common/combined-update-render-controller.h
dali/internal/graphics/gles-impl/gles-graphics-program.cpp

index a70c21f40c50941975feeb75cb4aa03dbf9252fc..52b7411b17735907f946af75448daf65f293cdb8 100644 (file)
@@ -2120,6 +2120,7 @@ public:
 
   inline void GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) override
   {
+    *length = bufSize; // commonly it is same. so we provide bufSize for test
     mGetProgramBinaryCalled = true;
   }
 
index 772fc4cb5a118f9c87a313805961375f1ee322fa..016193e2d9d9892d97d16e04608f3a3cc89d06b4 100644 (file)
 
 #include <dali-test-suite-utils.h>
 #include <dali/dali.h>
+#include <adaptor-environment-variable.h>
 
 #include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
 #include <test-actor-utils.h>
 #include <test-graphics-egl-application.h>
 #include <test-graphics-sampler.h>
 
+#include "mesh-builder.h"
+
 using namespace Dali;
 
 void utc_dali_program_startup(void)
@@ -73,6 +76,39 @@ const std::string FRAG_SHADER_SOURCE2 =
 
 } // anonymous namespace
 
+namespace
+{
+  Actor CreateRenderablegActorWithShaderFileCaching(Texture texture, const std::string& vertexShader, const std::string& fragmentShader)
+{
+  // Create the geometry
+  Geometry geometry = CreateQuadGeometry();
+
+  // Create Shader
+  Shader shader = Shader::New(vertexShader, fragmentShader, Shader::Hint::FILE_CACHE_SUPPORT);
+
+  // Create renderer from geometry and material
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  // Create actor and set renderer
+  Actor actor = Actor::New();
+  actor.AddRenderer(renderer);
+
+  // If we a texture, then create a texture-set and add to renderer
+  if(texture)
+  {
+    TextureSet textureSet = TextureSet::New();
+    textureSet.SetTexture(0u, texture);
+    renderer.SetTextures(textureSet);
+
+    // Set actor to the size of the texture if set
+    actor.SetProperty(Actor::Property::SIZE, Vector2(texture.GetWidth(), texture.GetHeight()));
+  }
+
+  return actor;
+}
+
+} // anonymous namespace
+
 int UtcDaliGraphicsProgram01(void)
 {
   TestGraphicsApplication app;
@@ -232,6 +268,41 @@ int UtcDaliGraphicsShaderNew02(void)
   END_TEST;
 }
 
+int UtcDaliGraphicsShaderNewUsingProgramBinary(void)
+{
+  EnvironmentVariable::SetTestEnvironmentVariable("DALI_SHADER_USE_PROGRAM_BINARY","1");
+
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliProgram - Check programBinary functionality");
+
+  Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
+
+  // Creates 3 Dali::Shaders
+  Actor actor1 = CreateRenderablegActorWithShaderFileCaching(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
+  Actor actor2 = CreateRenderablegActorWithShaderFileCaching(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
+  Actor actor3 = CreateRenderablegActorWithShaderFileCaching(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
+
+  app.GetScene().Add(actor1);
+  app.GetScene().Add(actor2);
+  app.GetScene().Add(actor3);
+
+  auto& gl            = app.GetGlAbstraction();
+  auto& glShaderTrace = gl.GetShaderTrace();
+  glShaderTrace.Enable(true);
+  glShaderTrace.EnableLogging(true);
+
+  gl.SetProgramBinaryLength(1); // Set ProgramBinaryLength for Test
+
+  app.SendNotification();
+  app.Render(16); // The above actors will get rendered and drawn once, only 1 program and 2 shaders should be created
+
+  DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateProgram"), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(gl.GetProgramBinaryCalled(), true, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliGraphicsShaderFlush(void)
 {
   // Note : This UTC will not works well since now GLES::ProgramImpl hold the reference of shader,
index 49857c60cf37eb63aeae1e84dd2930d7b3bdced8..ca3996be10c0afa1b3d0901c1209c871b7bd1932 100644 (file)
@@ -662,8 +662,7 @@ void CombinedUpdateRenderController::UpdateRenderThread()
             vertexShader   = Dali::Integration::GenerateTaggedShaderPrefix(graphics.GetController().GetGraphicsConfig().GetVertexShaderPrefix()) + shaderRawData.vertexPrefix[i] + std::string(shaderRawData.vertexShader);
             fragmentShader = Dali::Integration::GenerateTaggedShaderPrefix(graphics.GetController().GetGraphicsConfig().GetFragmentShaderPrefix()) + shaderRawData.fragmentPrefix[i] + std::string(shaderRawData.fragmentShader);
           }
-
-          PreCompileShader(std::move(vertexShader), std::move(fragmentShader), static_cast<uint32_t>(i) < shaderRawData.shaderName.size() ? shaderRawData.shaderName[i] : "");
+          PreCompileShader(std::move(vertexShader), std::move(fragmentShader), static_cast<uint32_t>(i) < shaderRawData.shaderName.size() ? shaderRawData.shaderName[i] : "", !shaderRawData.custom);
           DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], precompile shader [%u/%u] >> %s \n", i + 1u, numberOfPrecompiledShader, shaderRawData.shaderName.size() ? shaderRawData.shaderName[i].c_str() : "");
         }
 
@@ -1161,7 +1160,7 @@ void CombinedUpdateRenderController::SurfaceResized(uint32_t resizedCount)
   }
 }
 
-void CombinedUpdateRenderController::PreCompileShader(std::string vertexShader, std::string fragmentShader, std::string shaderName)
+void CombinedUpdateRenderController::PreCompileShader(std::string vertexShader, std::string fragmentShader, std::string shaderName, bool useFileCache)
 {
   auto& graphics = mAdaptorInterfaces.GetGraphicsInterface();
 
@@ -1202,7 +1201,7 @@ void CombinedUpdateRenderController::PreCompileShader(std::string vertexShader,
   auto createInfo = Graphics::ProgramCreateInfo();
   createInfo.SetShaderState(shaderStates);
   createInfo.SetName(shaderName);
-
+  createInfo.SetFileCaching(useFileCache);
   auto graphicsProgram = graphics.GetController().CreateProgram(createInfo, nullptr);
   ShaderPreCompiler::Get().AddPreCompiledProgram(std::move(graphicsProgram));
 }
index e4a2bb6df8a6c016ffcf7d90a990bc4f5d9ae57d..a9baa4cc3489f944566b0c0f10f5837551cb2685 100644 (file)
@@ -279,9 +279,10 @@ private:
    *
    * @param[in] vertexShader vertexShader need to precompile
    * @param[in] fragmentShader fragmentShader need to precompile
-   * @param[in] shaderName the name of precompile shader (option)
+   * @param[in] shaderName the name of precompile shader
+   * @param[in] useFileCache whether to use file cache or not. Default value is false.
    */
-  void PreCompileShader(std::string vertexShader, std::string fragmentShader, std::string shaderName = "");
+  void PreCompileShader(std::string vertexShader, std::string fragmentShader, std::string shaderName, bool useFileCache);
 
   /**
    * Cancel the precompile
index 025626267a0ad7e979e313658d9c4752bbc085ad..29c239a758618da7cd60e77796904c9c866588d9 100644 (file)
@@ -555,13 +555,14 @@ bool ProgramImpl::IsEnableProgramBinary() const
 {
   if(mImpl->controller.IsUsingProgramBinary())
   {
-    if(!mImpl->name.empty())
+    const auto& info = mImpl->createInfo;
+    if(info.useFileCache)
     {
       return true;
     }
 
-    // If the shader name is empty, it means that the shader is not an internally defined shader
-    DALI_LOG_DEBUG_INFO("[Enable] Shader program binary, but this shader can't be used ProgramBinary because the shader is not an internally defined shader.\n");
+    // If the Hint of shader is not Shader::Hint::FILE_CACHE_SUPPORT, we can't enable program binary
+    DALI_LOG_DEBUG_INFO("[Enable] Shader program binary, but this shader[%s] cannot be use file caching. because Shader::Hint::FILE_CACHE_SUPPORT is not set \n", mImpl->name.c_str());
   }
 
   return false;