[Tizen] Revert "Added shader support to pipeline cache" 16/301716/1
authorsunghyun kim <scholb.kim@samsung.com>
Wed, 22 Nov 2023 05:00:06 +0000 (14:00 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Wed, 22 Nov 2023 05:00:32 +0000 (14:00 +0900)
This reverts commit 9fe9d7d748b953f1d0feeb825f5a54bcb66f688b.

Change-Id: I3b85d37785aefbd1b877ae1fbec16c37de708fd9

automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-application.cpp
automated-tests/src/dali-graphics/CMakeLists.txt
automated-tests/src/dali-graphics/utc-Dali-GraphicsProgram.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/gles-graphics-pipeline-cache.cpp
dali/internal/graphics/gles-impl/gles-graphics-pipeline-cache.h
dali/internal/graphics/gles-impl/gles-graphics-program.cpp
dali/internal/graphics/gles-impl/gles-graphics-program.h
dali/internal/graphics/gles-impl/gles-graphics-shader.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.h

index 3f04a6b..2ca98dc 100644 (file)
@@ -1041,32 +1041,7 @@ public:
 
     for(const auto& uniform : mActiveUniforms)
     {
-      std::string name = uniform.name;
-      if(uniform.size <= 1)
-      {
-        GetUniformLocation(program, name.c_str());
-      }
-      else
-      {
-        // Convert single active uniform from "uBlah[0]" or "uStruct[0].element" to N versions of the same
-        std::string suffix;
-        auto        iter = name.find("["); // Search for index operator
-        if(iter != std::string::npos)
-        {
-          name = uniform.name.substr(0, iter); // Strip off index operator
-          iter = uniform.name.find("]");
-          if(iter != std::string::npos && iter + 1 != uniform.name.length())
-          {
-            suffix = uniform.name.substr(iter + 1);
-          }
-        }
-        for(int i = 0; i < uniform.size; ++i)
-        {
-          std::stringstream nss;
-          nss << name << "[" << i << "]" << suffix;
-          GetUniformLocation(program, nss.str().c_str()); // Generate N uniforms in the uniform map
-        }
-      }
+      GetUniformLocation(program, uniform.name.c_str());
     }
 
     for(const auto& uniform : mCustomUniformData)
index f4de9af..3e8e171 100644 (file)
@@ -98,7 +98,6 @@ void TestGraphicsApplication::InitializeCore()
 
 TestGraphicsApplication::~TestGraphicsApplication()
 {
-  mGraphicsController.Shutdown();
   Dali::Integration::Log::UninstallLogFunction();
   delete mCore;
 }
index 1dee934..45ca6cb 100644 (file)
@@ -40,6 +40,8 @@ PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
     dali2-core
     dali2-adaptor
     glesv2
+    ecore
+    ecore-x
 )
 
 ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror )
index c2c3e12..9677500 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -36,18 +36,6 @@ void utc_dali_program_cleanup(void)
 namespace
 {
 const std::string VERT_SHADER_SOURCE = "myVertShaderSource";
-
-const std::string VERT_SHADER_SOURCE2 =
-  "\n"
-  "in vec3 aPosition;\n"
-  "in vec3 aTexCoord;\n"
-  "out vec2 vTexCoord;\n"
-  "main()\n"
-  "{\n"
-  "  gl_Position=aPosition;\n"
-  "  vTexCoord = aTexCoord;\n"
-  "}\n";
-
 const std::string FRAG_SHADER_SOURCE =
   "\n"
   "uniform sampler2D sAlbedo;\n"
@@ -60,20 +48,9 @@ const std::string FRAG_SHADER_SOURCE =
   "{\n"
   "  gl_fragColor = texture2d(sAlbedo, vTexCoord) + lightDirection*texture2d(sNormals, vTexCoord);\n"
   "}\n";
-
-const std::string FRAG_SHADER_SOURCE2 =
-  "\n"
-  "uniform sampler2D sTextures[4];\n"
-  "uniform mediump vec3 lightDirection;\n"
-  "in mediump vec2 vTexCoord;\n"
-  "main()\n"
-  "{\n"
-  "  gl_fragColor = texture2d(sTextures[0], vTexCoord) + lightDirection*texture2d(sTextures[2], vTexCoord);\n"
-  "}\n";
-
 } //anonymous namespace
 
-int UtcDaliGraphicsProgram01(void)
+int UtcDaliGraphicsProgram(void)
 {
   TestGraphicsApplication app;
   tet_infoline("UtcDaliProgram - check that right sampler uniforms are bound for textures");
@@ -120,160 +97,3 @@ int UtcDaliGraphicsProgram01(void)
 
   END_TEST;
 }
-
-int UtcDaliGraphicsProgram02(void)
-{
-  TestGraphicsApplication app;
-  tet_infoline("UtcDaliProgram - check that sampler arrays are handled and bound to textures");
-
-  Texture normals        = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-  Texture metalroughness = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-  Texture ao             = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-  Texture albedo         = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-
-  TextureSet textureSet = TextureSet::New();
-  textureSet.SetTexture(0, albedo);
-  textureSet.SetTexture(1, metalroughness);
-  textureSet.SetTexture(2, normals);
-  textureSet.SetTexture(3, ao);
-
-  Actor actor = CreateRenderableActor2(textureSet, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
-  app.GetScene().Add(actor);
-
-  auto& gl             = app.GetGlAbstraction();
-  auto& glUniformTrace = gl.GetSetUniformTrace();
-  glUniformTrace.Enable(true);
-  glUniformTrace.EnableLogging(true);
-  gl.GetShaderTrace().Enable(true);
-  gl.GetShaderTrace().EnableLogging(true);
-
-  std::vector<ActiveUniform> activeUniforms{
-    {"uLightDir", GL_FLOAT_VEC4, 1},
-    {"sTextures[0]", GL_SAMPLER_2D, 4}}; // Array of 4 samplers
-  gl.SetActiveUniforms(activeUniforms);
-
-  app.SendNotification();
-  app.Render(16); // The above actor will get rendered and drawn once.
-
-  // Check what uniform values were set:
-  int value;
-  DALI_TEST_CHECK(gl.GetUniformValue("sTextures[0]", value)); // First in frag shader
-  DALI_TEST_EQUALS(value, 0, TEST_LOCATION);
-  DALI_TEST_CHECK(gl.GetUniformValue("sTextures[3]", value)); // 4th
-  DALI_TEST_EQUALS(value, 3, TEST_LOCATION);
-  DALI_TEST_CHECK(gl.GetUniformValue("sTextures[2]", value)); // 3rd
-  DALI_TEST_EQUALS(value, 2, TEST_LOCATION);
-  DALI_TEST_CHECK(gl.GetUniformValue("sTextures[1]", value)); // 2nd
-  DALI_TEST_EQUALS(value, 1, TEST_LOCATION);
-
-  END_TEST;
-}
-
-int UtcDaliGraphicsShaderNew(void)
-{
-  TestGraphicsApplication app;
-  tet_infoline("UtcDaliProgram - check that multiple shaders from same source only create 1 program");
-
-  Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-
-  // Creates 3 Dali::Shaders
-  Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
-  Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
-  Actor actor3 = CreateRenderableActor(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);
-
-  app.SendNotification();
-  app.Render(16); // The above actors will get rendered and drawn once, only 2 shaders should be created
-
-  DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 2, TEST_LOCATION);
-
-  END_TEST;
-}
-
-int UtcDaliGraphicsShaderNew02(void)
-{
-  TestGraphicsApplication app;
-  tet_infoline("UtcDaliProgram - check that mixed up multiple shaders from same source don't create dups");
-
-  Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-
-  // Creates 3 Dali::Shaders
-  Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
-  Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE2);
-  Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
-  Actor actor4 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE);
-
-  app.GetScene().Add(actor1);
-  app.GetScene().Add(actor2);
-  app.GetScene().Add(actor3);
-  app.GetScene().Add(actor4);
-
-  auto& gl            = app.GetGlAbstraction();
-  auto& glShaderTrace = gl.GetShaderTrace();
-  glShaderTrace.Enable(true);
-  glShaderTrace.EnableLogging(true);
-
-  app.SendNotification();
-  app.Render(16); // The above actors will get rendered and drawn once, only 2 shaders should be created
-
-  // Should only be 4 shaders, not 8.
-  DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 4, TEST_LOCATION);
-
-  END_TEST;
-}
-
-int UtcDaliGraphicsShaderFlush(void)
-{
-  TestGraphicsApplication app;
-  tet_infoline("UtcDaliProgram - check that unused shaders are flushed");
-
-  Texture diffuse       = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
-  auto&   gl            = app.GetGlAbstraction();
-  auto&   glShaderTrace = gl.GetShaderTrace();
-  glShaderTrace.Enable(true);
-  glShaderTrace.EnableLogging(true);
-
-  {
-    // Creates 3 Dali::Shaders
-    Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
-    Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE2);
-    Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
-    Actor actor4 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE);
-
-    app.GetScene().Add(actor1);
-    app.GetScene().Add(actor2);
-    app.GetScene().Add(actor3);
-    app.GetScene().Add(actor4);
-
-    app.SendNotification();
-    app.Render(16); // The above actors will get rendered and drawn once
-
-    // Should only be 4 shaders, not 8.
-    DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 4, TEST_LOCATION);
-
-    UnparentAndReset(actor1);
-    UnparentAndReset(actor2);
-    UnparentAndReset(actor3);
-    UnparentAndReset(actor4);
-  }
-
-  for(int i = 0; i < 1199; ++i) // 3 flushes per frame
-  {
-    app.SendNotification();
-    app.Render(16);
-    DALI_TEST_EQUALS(glShaderTrace.CountMethod("DeleteShader"), 0, TEST_LOCATION);
-  }
-  app.SendNotification();
-  app.Render(16);
-  DALI_TEST_EQUALS(glShaderTrace.CountMethod("DeleteShader"), 4, TEST_LOCATION);
-
-  END_TEST;
-}
index b211897..505201c 100644 (file)
@@ -298,7 +298,7 @@ Graphics::UniquePtr<Pipeline> EglGraphicsController::CreatePipeline(
 Graphics::UniquePtr<Program> EglGraphicsController::CreateProgram(
   const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram)
 {
-  // Create pipeline cache if needed
+  // Create program cache if needed
   if(!mPipelineCache)
   {
     mPipelineCache = std::make_unique<GLES::PipelineCache>(*this);
@@ -309,12 +309,7 @@ Graphics::UniquePtr<Program> EglGraphicsController::CreateProgram(
 
 Graphics::UniquePtr<Shader> EglGraphicsController::CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader)
 {
-  // Create pipeline cache if needed
-  if(!mPipelineCache)
-  {
-    mPipelineCache = std::make_unique<GLES::PipelineCache>(*this);
-  }
-  return mPipelineCache->GetShader(shaderCreateInfo, std::move(oldShader));
+  return NewObject<GLES::Shader>(shaderCreateInfo, *this, std::move(oldShader));
 }
 
 Graphics::UniquePtr<Sampler> EglGraphicsController::CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler)
index b567a27..7f14016 100644 (file)
 #include "gles-graphics-pipeline.h"
 #include "gles-graphics-program.h"
 
-namespace
-{
-constexpr uint32_t CACHE_CLEAN_FLUSH_COUNT = 3600u; // 60fps * 60sec / ~3 flushes per frame
-}
-
 namespace Dali::Graphics::GLES
 {
 /**
@@ -252,8 +247,7 @@ struct PipelineCache::Impl
   explicit Impl(EglGraphicsController& _controller)
   : controller(_controller),
     pipelineEntriesFlushRequired(false),
-    programEntriesFlushRequired(false),
-    shaderEntriesFlushRequired(false)
+    programEntriesFlushRequired(false)
   {
     // Initialise lookup table
     InitialiseStateCompareLookupTable();
@@ -293,6 +287,9 @@ struct PipelineCache::Impl
     uint32_t                stateBitmask{0u};
   };
 
+  EglGraphicsController&  controller;
+  std::vector<CacheEntry> entries;
+
   /**
    * @brief Sorted array of shaders used to create program
    */
@@ -303,19 +300,10 @@ struct PipelineCache::Impl
     UniquePtr<ProgramImpl>               program{nullptr};
   };
 
-  struct ShaderCacheEntry
-  {
-    UniquePtr<ShaderImpl> shaderImpl{nullptr};
-  };
-
-  EglGraphicsController&         controller;
-  std::vector<CacheEntry>        entries;
   std::vector<ProgramCacheEntry> programEntries;
-  std::vector<ShaderCacheEntry>  shaderEntries;
 
   bool pipelineEntriesFlushRequired : 1;
   bool programEntriesFlushRequired : 1;
-  bool shaderEntriesFlushRequired : 1;
 };
 
 PipelineCache::PipelineCache(EglGraphicsController& controller)
@@ -479,53 +467,6 @@ Graphics::UniquePtr<Graphics::Program> PipelineCache::GetProgram(const ProgramCr
   return std::move(wrapper);
 }
 
-ShaderImpl* PipelineCache::FindShaderImpl(const ShaderCreateInfo& shaderCreateInfo)
-{
-  if(!mImpl->shaderEntries.empty())
-  {
-    for(auto& item : mImpl->shaderEntries)
-    {
-      auto& itemInfo = item.shaderImpl->GetCreateInfo();
-      if(itemInfo.pipelineStage != shaderCreateInfo.pipelineStage ||
-         itemInfo.shaderlanguage != shaderCreateInfo.shaderlanguage ||
-         itemInfo.sourceMode != shaderCreateInfo.sourceMode ||
-         itemInfo.sourceSize != shaderCreateInfo.sourceSize)
-      {
-        continue;
-      }
-
-      if(memcmp(itemInfo.sourceData, shaderCreateInfo.sourceData, itemInfo.sourceSize) == 0)
-      {
-        return item.shaderImpl.get();
-      }
-    }
-  }
-  return nullptr;
-}
-
-Graphics::UniquePtr<Graphics::Shader> PipelineCache::GetShader(const ShaderCreateInfo&                 shaderCreateInfo,
-                                                               Graphics::UniquePtr<Graphics::Shader>&& oldShader)
-{
-  ShaderImpl* cachedShader = FindShaderImpl(shaderCreateInfo);
-
-  // Return same pointer if nothing changed
-  if(oldShader && *static_cast<GLES::Shader*>(oldShader.get()) == cachedShader)
-  {
-    return std::move(oldShader);
-  }
-
-  if(!cachedShader)
-  {
-    auto shader  = MakeUnique<GLES::ShaderImpl>(shaderCreateInfo, mImpl->controller);
-    cachedShader = shader.get();
-
-    mImpl->shaderEntries.emplace_back();
-    mImpl->shaderEntries.back().shaderImpl = std::move(shader);
-  }
-  auto wrapper = MakeUnique<GLES::Shader, CachedObjectDeleter<GLES::Shader>>(cachedShader);
-  return std::move(wrapper);
-}
-
 void PipelineCache::FlushCache()
 {
   if(mImpl->pipelineEntriesFlushRequired)
@@ -568,39 +509,6 @@ void PipelineCache::FlushCache()
 
     mImpl->programEntriesFlushRequired = false;
   }
-
-  if(mImpl->shaderEntriesFlushRequired)
-  {
-    // There is at least 1 unused shader
-    mImpl->shaderEntriesFlushRequired = false;
-    bool deleteRequired{false};
-    for(auto& entry : mImpl->shaderEntries)
-    {
-      if(entry.shaderImpl->GetRefCount() == 0)
-      {
-        mImpl->shaderEntriesFlushRequired = true;
-        auto frameCount                   = entry.shaderImpl->IncreaseFlushCount();
-        if(frameCount > CACHE_CLEAN_FLUSH_COUNT)
-        {
-          deleteRequired = true;
-        }
-      }
-    }
-    if(deleteRequired)
-    {
-      decltype(mImpl->shaderEntries) newShaderEntries;
-      newShaderEntries.reserve(mImpl->shaderEntries.size());
-      for(auto& entry : mImpl->shaderEntries)
-      {
-        if(entry.shaderImpl->GetRefCount() > 0 ||
-           entry.shaderImpl->GetFlushCount() <= CACHE_CLEAN_FLUSH_COUNT)
-        {
-          newShaderEntries.emplace_back(std::move(entry));
-        }
-      }
-      mImpl->shaderEntries = std::move(newShaderEntries);
-    }
-  }
 }
 
 void PipelineCache::MarkPipelineCacheFlushRequired()
@@ -613,9 +521,4 @@ void PipelineCache::MarkProgramCacheFlushRequired()
   mImpl->programEntriesFlushRequired = true;
 }
 
-void PipelineCache::MarkShaderCacheFlushRequired()
-{
-  mImpl->shaderEntriesFlushRequired = true;
-}
-
 } // namespace Dali::Graphics::GLES
index 685ad32..2a1fd6b 100644 (file)
@@ -23,8 +23,6 @@
 #include <dali/graphics-api/graphics-pipeline.h>
 #include <dali/graphics-api/graphics-program-create-info.h>
 #include <dali/graphics-api/graphics-program.h>
-#include <dali/graphics-api/graphics-shader-create-info.h>
-#include <dali/graphics-api/graphics-shader.h>
 
 // INTERNAL INCLUDES
 #include "gles-graphics-resource.h"
@@ -38,9 +36,6 @@ class Pipeline;
 class PipelineImpl;
 class Program;
 class ProgramImpl;
-class Shader;
-class ShaderImpl;
-
 /**
  * @brief PipelineCache manages pipeline and program
  * objects so there are no duplicates created.
@@ -83,18 +78,6 @@ public:
   Graphics::UniquePtr<Graphics::Program> GetProgram(const ProgramCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Program>&& oldProgram);
 
   /**
-   * @brief Retrieves shader matching the spec
-   *
-   * Function returns either existing shader if one is found
-   * in the cache or creates new one.
-   *
-   * @param[in] shaderCreateInfo Valid ShaderCreateInfo structure
-   * @param[in] oldShader previous shader object
-   * @return Shader object
-   */
-  Graphics::UniquePtr<Graphics::Shader> GetShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader);
-
-  /**
    * @brief Flushes pipeline and program cache
    *
    * Removes cached items when they are no longer needed. This function
@@ -112,11 +95,6 @@ public:
    */
   void MarkProgramCacheFlushRequired();
 
-  /**
-   * @brief Notify that we need to flush shader cache next FlushCache API.
-   */
-  void MarkShaderCacheFlushRequired();
-
 private:
   /**
    * @brief Finds pipeline implementation based on the spec
@@ -126,20 +104,12 @@ private:
   PipelineImpl* FindPipelineImpl(const PipelineCreateInfo& info);
 
   /**
  * @brief Finds program implementation based on the spec
  * @param[in] info Valid create info structure
  * @return Returns pointer to program or nullptr
  */
+ * @brief Finds program implementation based on the spec
+ * @param[in] info Valid create info structure
+ * @return Returns pointer to program or nullptr
+ */
   ProgramImpl* FindProgramImpl(const ProgramCreateInfo& info);
 
-  /**
-   * @brief Finds shader implementation based on create info
-   *
-   * @param[in] shadercreateinfo Valid create info structure
-   * @return Returns pointer to shader or nullptr
-   */
-  ShaderImpl* FindShaderImpl(const ShaderCreateInfo& shaderCreateInfo);
-
 private:
   struct Impl;
   std::unique_ptr<Impl> mImpl;
index 3b28c23..d7fc0a7 100644 (file)
@@ -148,9 +148,9 @@ bool ProgramImpl::Create()
     const auto* shader = static_cast<const GLES::Shader*>(state.shader);
 
     // Compile shader first (ignored when compiled)
-    if(shader->GetImplementation()->Compile())
+    if(shader->Compile())
     {
-      gl->AttachShader(program, shader->GetImplementation()->GetGLShader());
+      gl->AttachShader(program, shader->GetGLShader());
     }
   }
   gl->LinkProgram(program);
index ee8a888..050b04b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_GRAPHICS_GLES_PROGRAM_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -154,7 +154,7 @@ private:
 ///////////////////////////////////////////////////////////////
 
 /**
- * @brief Wrapper for the program implementation
+ * @brief Wrapper for the pipeline implementation
  *
  * This object is returned back to the client-side
  */
index 676884f..5e46e97 100644 (file)
 
 namespace Dali::Graphics::GLES
 {
-struct ShaderImpl::Impl
+struct Shader::Impl
 {
-  explicit Impl(Graphics::EglGraphicsController& _controller, const Graphics::ShaderCreateInfo& _createInfo)
-  : controller(_controller)
-  {
-    createInfo.pipelineStage  = _createInfo.pipelineStage;
-    createInfo.shaderlanguage = _createInfo.shaderlanguage;
-    createInfo.sourceMode     = _createInfo.sourceMode;
-    createInfo.sourceSize     = _createInfo.sourceSize;
-
-    // Make a copy of source code
-    source.resize(_createInfo.sourceSize);
-    std::copy(reinterpret_cast<const char*>(_createInfo.sourceData),
-              reinterpret_cast<const char*>(_createInfo.sourceData) + _createInfo.sourceSize,
-              source.data());
-
-    // Substitute pointer
-    createInfo.sourceData = source.data();
-  }
+  Impl()  = default;
+  ~Impl() = default;
 
-  ~Impl(){};
+  std::vector<char> source{};
+  uint32_t          glShader{};
+};
 
-  bool Compile()
-  {
-    auto gl = controller.GetGL();
+Shader::Shader(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
+: ShaderResource(createInfo, controller)
+{
+  // push shader to the create queue
+  mImpl = std::make_unique<Impl>();
 
-    if(!gl)
-    {
-      return false;
-    }
+  // Make a copy of source code
+  mImpl->source.resize(createInfo.sourceSize);
+  std::copy(reinterpret_cast<const char*>(mCreateInfo.sourceData),
+            reinterpret_cast<const char*>(mCreateInfo.sourceData) + mCreateInfo.sourceSize,
+            mImpl->source.begin());
+
+  // Substitute pointer
+  mCreateInfo.sourceData = mImpl->source.data();
+}
+
+Shader::~Shader() = default;
 
-    if(!glShader)
+bool Shader::Compile() const
+{
+  auto gl = GetController().GetGL();
+
+  if(!gl)
+  {
+    return false;
+  }
+
+  if(!mImpl->glShader)
+  {
+    GLenum pipelineStage{0u};
+    switch(GetCreateInfo().pipelineStage)
     {
-      GLenum pipelineStage{0u};
-      switch(createInfo.pipelineStage)
+      case Graphics::PipelineStage::TOP_OF_PIPELINE:
       {
-        case Graphics::PipelineStage::TOP_OF_PIPELINE:
-        {
-          break;
-        }
-        case Graphics::PipelineStage::VERTEX_SHADER:
-        {
-          pipelineStage = GL_VERTEX_SHADER;
-          break;
-        }
-        case Graphics::PipelineStage::GEOMETRY_SHADER:
-        {
-          break;
-        }
-        case Graphics::PipelineStage::FRAGMENT_SHADER:
-        {
-          pipelineStage = GL_FRAGMENT_SHADER;
-          break;
-        }
-        case Graphics::PipelineStage::COMPUTE_SHADER:
-        {
-          break;
-        }
-        case Graphics::PipelineStage::TESSELATION_CONTROL:
-        {
-          break;
-        }
-        case Graphics::PipelineStage::TESSELATION_EVALUATION:
-        {
-          break;
-        }
-        case Graphics::PipelineStage::BOTTOM_OF_PIPELINE:
-        {
-          break;
-        }
+        break;
       }
-
-      if(pipelineStage)
+      case Graphics::PipelineStage::VERTEX_SHADER:
       {
-        auto       shader = gl->CreateShader(pipelineStage);
-        const auto src    = reinterpret_cast<const char*>(createInfo.sourceData);
-        GLint      size   = createInfo.sourceSize;
-        gl->ShaderSource(shader, 1, const_cast<const char**>(&src), &size);
-        gl->CompileShader(shader);
-
-        GLint status{0};
-        gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
-        if(status != GL_TRUE)
-        {
-          char    output[4096];
-          GLsizei size{0u};
-          gl->GetShaderInfoLog(shader, 4096, &size, output);
-          DALI_LOG_ERROR("Code: %s\n", reinterpret_cast<const char*>(createInfo.sourceData));
-          DALI_LOG_ERROR("glCompileShader() failed: \n%s\n", output);
-          gl->DeleteShader(shader);
-          return false;
-        }
-        glShader = shader;
+        pipelineStage = GL_VERTEX_SHADER;
+        break;
+      }
+      case Graphics::PipelineStage::GEOMETRY_SHADER:
+      {
+        break;
+      }
+      case Graphics::PipelineStage::FRAGMENT_SHADER:
+      {
+        pipelineStage = GL_FRAGMENT_SHADER;
+        break;
+      }
+      case Graphics::PipelineStage::COMPUTE_SHADER:
+      {
+        break;
+      }
+      case Graphics::PipelineStage::TESSELATION_CONTROL:
+      {
+        break;
+      }
+      case Graphics::PipelineStage::TESSELATION_EVALUATION:
+      {
+        break;
+      }
+      case Graphics::PipelineStage::BOTTOM_OF_PIPELINE:
+      {
+        break;
       }
-      return true;
     }
-    return true;
-  }
-
-  void Destroy()
-  {
-    auto gl = controller.GetGL();
 
-    if(gl && glShader)
+    if(pipelineStage)
     {
-      gl->DeleteShader(glShader);
-      glShader = 0;
+      auto       shader = gl->CreateShader(pipelineStage);
+      const auto src    = reinterpret_cast<const char*>(GetCreateInfo().sourceData);
+      GLint      size   = GetCreateInfo().sourceSize;
+      gl->ShaderSource(shader, 1, const_cast<const char**>(&src), &size);
+      gl->CompileShader(shader);
+
+      GLint status{0};
+      gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
+      if(status != GL_TRUE)
+      {
+        char    output[4096];
+        GLsizei size{0u};
+        gl->GetShaderInfoLog(shader, 4096, &size, output);
+        DALI_LOG_ERROR("Code: %s\n", reinterpret_cast<const char*>(GetCreateInfo().sourceData));
+        DALI_LOG_ERROR("glCompileShader() failed: \n%s\n", output);
+        gl->DeleteShader(shader);
+        return false;
+      }
+      mImpl->glShader = shader;
     }
+    return true;
   }
-
-  EglGraphicsController& controller;
-  ShaderCreateInfo       createInfo;
-  std::vector<char>      source{};
-
-  uint32_t glShader{};
-  uint32_t refCount{0u};
-  uint32_t flushCount{0u}; ///< Number of frames at refCount=0
-};
-
-ShaderImpl::ShaderImpl(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
-{
-  mImpl = std::make_unique<Impl>(controller, createInfo);
-}
-
-ShaderImpl::~ShaderImpl()
-{
-  if(!mImpl->controller.IsShuttingDown())
-  {
-    mImpl->Destroy();
-  }
-}
-
-uint32_t ShaderImpl::Retain()
-{
-  mImpl->flushCount = 0;
-  return ++mImpl->refCount;
-}
-
-uint32_t ShaderImpl::Release()
-{
-  uint32_t remainingCount = --mImpl->refCount;
-  mImpl->flushCount       = 0;
-  return remainingCount;
-}
-
-[[nodiscard]] uint32_t ShaderImpl::GetRefCount() const
-{
-  return mImpl->refCount;
-}
-
-[[nodiscard]] uint32_t ShaderImpl::IncreaseFlushCount()
-{
-  return ++mImpl->flushCount;
-}
-
-[[nodiscard]] uint32_t ShaderImpl::GetFlushCount() const
-{
-  return mImpl->flushCount;
-}
-
-/**
- * @brief Compiles shader
- *
- * @return True on success
- */
-[[nodiscard]] bool ShaderImpl::Compile() const
-{
-  return mImpl->Compile();
+  return true;
 }
 
-[[nodiscard]] uint32_t ShaderImpl::GetGLShader() const
+uint32_t Shader::GetGLShader() const
 {
   return mImpl->glShader;
 }
 
-const ShaderCreateInfo& ShaderImpl::GetCreateInfo() const
-{
-  return mImpl->createInfo;
-}
-
-[[nodiscard]] EglGraphicsController& ShaderImpl::GetController() const
-{
-  return mImpl->controller;
-}
-
-Shader::~Shader()
+void Shader::DestroyResource()
 {
-  if(!mShader->Release())
+  if(mImpl->glShader)
   {
-    GetImplementation()->GetController().GetPipelineCache().MarkShaderCacheFlushRequired();
+    auto gl = GetController().GetGL();
+    if(!gl)
+    {
+      return;
+    }
+    gl->DeleteShader(mImpl->glShader);
   }
 }
 
-[[nodiscard]] const ShaderCreateInfo& Shader::GetCreateInfo() const
-{
-  return GetImplementation()->GetCreateInfo();
-}
-
 void Shader::DiscardResource()
 {
-  auto& controller = GetImplementation()->GetController();
-  if(!controller.IsShuttingDown())
-  {
-    controller.DiscardResource(this);
-  }
+  GetController().DiscardResource(this);
 }
 
 } // namespace Dali::Graphics::GLES
index 28c7370..180a14b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_GRAPHICS_GLES_SHADER_H
 
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -27,7 +27,9 @@
 
 namespace Dali::Graphics::GLES
 {
-class ShaderImpl
+using ShaderResource = Resource<Graphics::Shader, Graphics::ShaderCreateInfo>;
+
+class Shader : public ShaderResource
 {
 public:
   /**
@@ -35,28 +37,29 @@ public:
    * @param[in] createInfo Valid createInfo structure
    * @param[in] controller Reference to the controller
    */
-  ShaderImpl(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller);
-  ~ShaderImpl();
-
-  uint32_t Retain();
+  Shader(const Graphics::ShaderCreateInfo& createInfo, Graphics::EglGraphicsController& controller);
 
-  uint32_t Release();
-
-  [[nodiscard]] uint32_t GetRefCount() const;
+  /**
+   * @brief Destructor
+   */
+  ~Shader() override;
 
   /**
-   * Whilst unreferenced, increase the flush count and return it
-   *
-   * @return The new flush count
+   * @brief Called when GL resources are destroyed
    */
-  [[nodiscard]] uint32_t IncreaseFlushCount();
+  void DestroyResource() override;
 
   /**
-   * Get the flush count whilst unreferenced
+   * @brief Called when initializing the resource
    *
-   * @return the flush count
+   * @return True on success
    */
-  [[nodiscard]] uint32_t GetFlushCount() const;
+  bool InitializeResource() override
+  {
+    // The Shader has instant initialization, hence no need to initialize GL resource
+    // here
+    return true;
+  }
 
   /**
    * @brief Compiles shader
@@ -66,83 +69,17 @@ public:
   [[nodiscard]] bool Compile() const;
 
   /**
-   * @brief Destroys GL shader
+   * @brief Called when UniquePtr<> on client-side dies
    */
-  void Destroy();
+  void DiscardResource() override;
 
   uint32_t GetGLShader() const;
 
-  [[nodiscard]] const ShaderCreateInfo& GetCreateInfo() const;
-
-  [[nodiscard]] EglGraphicsController& GetController() const;
-
 private:
-  friend class Shader;
   struct Impl;
   std::unique_ptr<Impl> mImpl{nullptr};
 };
 
-class Shader : public Graphics::Shader
-{
-public:
-  /**
-   * @brief Constructor
-   *
-   * @param[in] impl Pointer to valid implementation
-   */
-  explicit Shader(ShaderImpl* impl)
-  : mShader(impl)
-  {
-    mShader->Retain();
-  }
-
-  /**
-   * @brief Destructor
-   */
-  ~Shader() override;
-
-  [[nodiscard]] ShaderImpl* GetImplementation() const
-  {
-    return mShader;
-  }
-
-  [[nodiscard]] const ShaderCreateInfo& GetCreateInfo() const;
-
-  bool operator==(const GLES::Shader& shader) const
-  {
-    return (shader.mShader == mShader);
-  }
-
-  bool operator==(const GLES::ShaderImpl* shaderImpl) const
-  {
-    return (shaderImpl == mShader);
-  }
-
-  bool operator!=(const GLES::Shader& shader) const
-  {
-    return (shader.mShader != mShader);
-  }
-
-  /**
-   * @brief Called when UniquePtr<> on client-side dies.
-   */
-  void DiscardResource();
-
-  /**
-   * @brief Destroying GL resources
-   *
-   * This function is kept for compatibility with Resource<> class
-   * so can the object can be use with templated functions.
-   */
-  void DestroyResource()
-  {
-    // nothing to do here
-  }
-
-private:
-  ShaderImpl* mShader{nullptr};
-};
-
 } // namespace Dali::Graphics::GLES
 
 #endif