Make sure that global variables are initialized lazily.
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-pipeline-cache.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 5d575f7..69f45b7
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -17,6 +17,7 @@
 
 #include "gles-graphics-pipeline-cache.h"
 #include <algorithm>
+#include "egl-graphics-controller.h"
 #include "gles-graphics-pipeline.h"
 #include "gles-graphics-program.h"
 
@@ -37,6 +38,26 @@ struct CachedObjectDeleter
   }
 };
 
+template<>
+struct CachedObjectDeleter<GLES::Program>
+{
+  CachedObjectDeleter() = default;
+
+  void operator()(GLES::Program* object)
+  {
+    // Program deleter should skip discard queue if controller shutting down
+    if(!object->GetController().IsShuttingDown())
+    {
+      object->DiscardResource();
+    }
+    else
+    {
+      // delete object otherwise
+      delete object;
+    }
+  }
+};
+
 /**
  * @brief The order of states being stored in the cache and mask
  */
@@ -44,13 +65,12 @@ enum class StateLookupIndex : uint32_t
 {
   COLOR_BLEND_STATE_BIT    = 0,
   VIEWPORT_STATE_BIT       = 1,
-  FRAMEBUFFER_STATE_BIT    = 2,
-  BASE_PIPELINE_STATE_BIT  = 3,
-  DEPTH_STENCIL_STATE_BIT  = 4,
-  RASTERIZATION_STATE_BIT  = 5,
-  VERTEX_INPUT_STATE_BIT   = 6,
-  INPUT_ASSEMBLY_STATE_BIT = 7,
-  MAX_STATE                = 8
+  BASE_PIPELINE_STATE_BIT  = 2,
+  DEPTH_STENCIL_STATE_BIT  = 3,
+  RASTERIZATION_STATE_BIT  = 4,
+  VERTEX_INPUT_STATE_BIT   = 5,
+  INPUT_ASSEMBLY_STATE_BIT = 6,
+  MAX_STATE                = 7
 };
 
 /**
@@ -113,91 +133,88 @@ operator==(const Dali::Graphics::VertexInputState::Binding& lhs, const Dali::Gra
 using PipelineStateCompateFunctionType = bool(const Graphics::PipelineCreateInfo*,
                                               const Graphics::PipelineCreateInfo*);
 
-static std::vector<PipelineStateCompateFunctionType*> STATE_COMPARE_FUNC_TABLE{};
+static std::vector<PipelineStateCompateFunctionType*>& GetStateCompareFuncTable()
+{
+  static std::vector<PipelineStateCompateFunctionType*> stateCompareFuncTable{};
+  return stateCompareFuncTable;
+}
 
 /**
  * @brief Initialises compare function lookup table
  */
 void InitialiseStateCompareLookupTable()
 {
-  STATE_COMPARE_FUNC_TABLE = {
-    [](const auto* lhs, const auto* rhs) -> bool // colorBlendState
-    {
-      const auto& lcb = *lhs->colorBlendState;
-      const auto& rcb = *rhs->colorBlendState;
-      return lcb.logicOpEnable == rcb.logicOpEnable &&
-             lcb.logicOp == rcb.logicOp &&
-             cmpf(lcb.blendConstants[0], rcb.blendConstants[0]) &&
-             cmpf(lcb.blendConstants[1], rcb.blendConstants[1]) &&
-             cmpf(lcb.blendConstants[2], rcb.blendConstants[2]) &&
-             cmpf(lcb.blendConstants[3], rcb.blendConstants[3]) &&
-             lcb.blendEnable == rcb.blendEnable &&
-             lcb.srcColorBlendFactor == rcb.srcColorBlendFactor &&
-             lcb.dstColorBlendFactor == rcb.dstColorBlendFactor &&
-             lcb.colorBlendOp == rcb.colorBlendOp &&
-             lcb.srcAlphaBlendFactor == rcb.srcAlphaBlendFactor &&
-             lcb.dstAlphaBlendFactor == rcb.dstAlphaBlendFactor &&
-             lcb.alphaBlendOp == rcb.alphaBlendOp &&
-             lcb.colorComponentWriteBits == rcb.colorComponentWriteBits;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // viewport state
-    {
-      const auto& lvp = *lhs->viewportState;
-      const auto& rvp = *rhs->viewportState;
-      return lvp.viewport == rvp.viewport &&
-             lvp.scissor == rvp.scissor &&
-             lvp.scissorTestEnable == rvp.scissorTestEnable;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // framebufferState
-    {
-      const auto& lfb = *lhs->framebufferState;
-      const auto& rfb = *rhs->framebufferState;
-      return lfb.framebuffer == rfb.framebuffer;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // basePipeline
-    {
-      return lhs->basePipeline == rhs->basePipeline;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // depthStencilState
-    {
-      const auto& lds = *lhs->depthStencilState;
-      const auto& rds = *rhs->depthStencilState;
-      return lds.depthTestEnable == rds.depthTestEnable &&
-             lds.depthWriteEnable == rds.depthWriteEnable &&
-             lds.depthCompareOp == rds.depthCompareOp &&
-             lds.stencilTestEnable == rds.stencilTestEnable &&
-             lds.front == rds.front &&
-             lds.back == rds.back;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // rasterizationState
-    {
-      const auto& lrs = *lhs->rasterizationState;
-      const auto& rrs = *rhs->rasterizationState;
-      return lrs.cullMode == rrs.cullMode &&
-             lrs.polygonMode == rrs.polygonMode &&
-             lrs.frontFace == rrs.frontFace;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // vertexInputState
-    {
-      const auto& lvi = *lhs->vertexInputState;
-      const auto& rvi = *rhs->vertexInputState;
-      return lvi.bufferBindings.size() == rvi.bufferBindings.size() &&
-             lvi.attributes.size() == rvi.attributes.size() &&
-             std::equal(lvi.bufferBindings.begin(), lvi.bufferBindings.end(), rvi.bufferBindings.begin(), [](const auto& lhs, const auto& rhs) {
-               return operator==(lhs, rhs);
-             }) &&
-             std::equal(lvi.attributes.begin(), lvi.attributes.end(), rvi.attributes.begin(), [](const auto& lhs, const auto& rhs) {
-               return operator==(lhs, rhs);
-             });
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // inputAssemblyState
-    {
-      const auto& lia = *lhs->inputAssemblyState;
-      const auto& ria = *rhs->inputAssemblyState;
-      return lia.topology == ria.topology &&
-             lia.primitiveRestartEnable == ria.primitiveRestartEnable;
-    },
-  };
+  GetStateCompareFuncTable().clear();
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // colorBlendState
+                                       {
+                                         const auto& lcb = *lhs->colorBlendState;
+                                         const auto& rcb = *rhs->colorBlendState;
+                                         return lcb.logicOpEnable == rcb.logicOpEnable &&
+                                                lcb.logicOp == rcb.logicOp &&
+                                                cmpf(lcb.blendConstants[0], rcb.blendConstants[0]) &&
+                                                cmpf(lcb.blendConstants[1], rcb.blendConstants[1]) &&
+                                                cmpf(lcb.blendConstants[2], rcb.blendConstants[2]) &&
+                                                cmpf(lcb.blendConstants[3], rcb.blendConstants[3]) &&
+                                                lcb.blendEnable == rcb.blendEnable &&
+                                                lcb.srcColorBlendFactor == rcb.srcColorBlendFactor &&
+                                                lcb.dstColorBlendFactor == rcb.dstColorBlendFactor &&
+                                                lcb.colorBlendOp == rcb.colorBlendOp &&
+                                                lcb.srcAlphaBlendFactor == rcb.srcAlphaBlendFactor &&
+                                                lcb.dstAlphaBlendFactor == rcb.dstAlphaBlendFactor &&
+                                                lcb.alphaBlendOp == rcb.alphaBlendOp &&
+                                                lcb.colorComponentWriteBits == rcb.colorComponentWriteBits;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // viewport state
+                                       {
+                                         const auto& lvp = *lhs->viewportState;
+                                         const auto& rvp = *rhs->viewportState;
+                                         return lvp.viewport == rvp.viewport &&
+                                                lvp.scissor == rvp.scissor &&
+                                                lvp.scissorTestEnable == rvp.scissorTestEnable;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // basePipeline
+                                       {
+                                         return lhs->basePipeline == rhs->basePipeline;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // depthStencilState
+                                       {
+                                         const auto& lds = *lhs->depthStencilState;
+                                         const auto& rds = *rhs->depthStencilState;
+                                         return lds.depthTestEnable == rds.depthTestEnable &&
+                                                lds.depthWriteEnable == rds.depthWriteEnable &&
+                                                lds.depthCompareOp == rds.depthCompareOp &&
+                                                lds.stencilTestEnable == rds.stencilTestEnable &&
+                                                lds.front == rds.front &&
+                                                lds.back == rds.back;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // rasterizationState
+                                       {
+                                         const auto& lrs = *lhs->rasterizationState;
+                                         const auto& rrs = *rhs->rasterizationState;
+                                         return lrs.cullMode == rrs.cullMode &&
+                                                lrs.polygonMode == rrs.polygonMode &&
+                                                lrs.frontFace == rrs.frontFace;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // vertexInputState
+                                       {
+                                         const auto& lvi = *lhs->vertexInputState;
+                                         const auto& rvi = *rhs->vertexInputState;
+                                         return lvi.bufferBindings.size() == rvi.bufferBindings.size() &&
+                                                lvi.attributes.size() == rvi.attributes.size() &&
+                                                std::equal(lvi.bufferBindings.begin(), lvi.bufferBindings.end(), rvi.bufferBindings.begin(), [](const auto& lhs, const auto& rhs) {
+                                                  return operator==(lhs, rhs);
+                                                }) &&
+                                                std::equal(lvi.attributes.begin(), lvi.attributes.end(), rvi.attributes.begin(), [](const auto& lhs, const auto& rhs) {
+                                                  return operator==(lhs, rhs);
+                                                });
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // inputAssemblyState
+                                       {
+                                         const auto& lia = *lhs->inputAssemblyState;
+                                         const auto& ria = *rhs->inputAssemblyState;
+                                         return lia.topology == ria.topology &&
+                                                lia.primitiveRestartEnable == ria.primitiveRestartEnable;
+                                       });
 }
 
 /**
@@ -211,7 +228,6 @@ inline uint32_t GetStateBitmask(const PipelineCreateInfo& info)
   uint32_t mask{0u};
   mask |= bool(info.colorBlendState) << int(StateLookupIndex::COLOR_BLEND_STATE_BIT);
   mask |= bool(info.viewportState) << int(StateLookupIndex::VIEWPORT_STATE_BIT);
-  mask |= bool(info.framebufferState) << int(StateLookupIndex::FRAMEBUFFER_STATE_BIT);
   mask |= bool(info.basePipeline) << int(StateLookupIndex::BASE_PIPELINE_STATE_BIT);
   mask |= bool(info.depthStencilState) << int(StateLookupIndex::DEPTH_STENCIL_STATE_BIT);
   mask |= bool(info.rasterizationState) << int(StateLookupIndex::RASTERIZATION_STATE_BIT);
@@ -278,8 +294,8 @@ struct PipelineCache::Impl
   struct ProgramCacheEntry
   {
     // sorted array of shaders
-    std::vector<const Shader*> shaders;
-    UniquePtr<ProgramImpl>     program{nullptr};
+    std::vector<const Graphics::Shader*> shaders;
+    UniquePtr<ProgramImpl>               program{nullptr};
   };
 
   std::vector<ProgramCacheEntry> programEntries;
@@ -328,7 +344,7 @@ PipelineImpl* PipelineCache::FindPipelineImpl(const PipelineCreateInfo& info)
         // Test only set states
         if((entry.stateBitmask & (1 << i)))
         {
-          if(!STATE_COMPARE_FUNC_TABLE[i](&info, &cacheInfo))
+          if(!(GetStateCompareFuncTable()[i](&info, &cacheInfo)))
           {
             break;
           }
@@ -354,7 +370,7 @@ ProgramImpl* PipelineCache::FindProgramImpl(const ProgramCreateInfo& info)
   }
 
   // assert if no shaders given
-  std::vector<const Shader*> shaders;
+  std::vector<const Graphics::Shader*> shaders;
   shaders.reserve(info.shaderState->size());
 
   for(auto& state : *info.shaderState)
@@ -470,4 +486,4 @@ void PipelineCache::FlushCache()
   //       killing the program (if program isn't in use anymore)
 }
 
-} // namespace Dali::Graphics::GLES
\ No newline at end of file
+} // namespace Dali::Graphics::GLES