Remove old pipeline caches
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / pipeline-cache.h
1 #ifndef DALI_INTERNAL_RENDER_PIPELINE_CACHE_H
2 #define DALI_INTERNAL_RENDER_PIPELINE_CACHE_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // INTERNAL INCLUDES
21 #include <dali/graphics-api/graphics-controller.h>
22 #include <dali/graphics-api/graphics-pipeline.h>
23 #include <dali/graphics-api/graphics-types.h>
24 #include <dali/internal/common/blending-options.h>
25
26 // EXTERNAL INCLUDES
27 #include <vector>
28
29 namespace Dali::Internal
30 {
31 class Program;
32 namespace Render
33 {
34 class Renderer;
35 class Geometry;
36
37 /**
38  * Cache Level 2 : Last level of cache, stores actual pipeline
39  */
40 struct PipelineCacheL2
41 {
42   uint32_t                                hash{};
43   uint32_t                                referenceCount{0u};
44   Graphics::ColorBlendState               colorBlendState;
45   Graphics::UniquePtr<Graphics::Pipeline> pipeline;
46 };
47
48 /**
49  * Cache Level 1 : Stores rasterization and input assembly states
50  */
51 struct PipelineCacheL1
52 {
53   PipelineCacheL2* GetPipelineCacheL2(bool blend, bool premul, BlendingOptions& blendingOptions);
54
55   /**
56    * @brief Clear unused caches.
57    */
58   bool ClearUnusedCache();
59
60   uint32_t                     hashCode{}; // 1byte cull, 1byte poly, 1byte frontface
61   Graphics::RasterizationState rs{};
62   Graphics::InputAssemblyState ia{};
63
64   PipelineCacheL2              noBlend; // special case
65   std::vector<PipelineCacheL2> level2nodes;
66 };
67
68 /**
69  * Cache Level 0 : Stores hash, geometry, program amd vertex input state
70  */
71 struct PipelineCacheL0 // L0 cache
72 {
73   PipelineCacheL1* GetPipelineCacheL1(Render::Renderer* renderer, bool usingReflection);
74
75   /**
76    * @brief Clear unused caches.
77    */
78   void ClearUnusedCache();
79
80   std::size_t                hash{};
81   Geometry*                  geometry{};
82   Program*                   program{};
83   Graphics::VertexInputState inputState;
84
85   std::vector<PipelineCacheL1> level1nodes;
86 };
87
88 struct PipelineCacheQueryInfo
89 {
90   // Program/Geometry
91   Renderer* renderer;
92   Program*  program;
93   Geometry* geometry;
94
95   bool cameraUsingReflection;
96
97   // Blending
98   bool             blendingEnabled;
99   bool             alphaPremultiplied;
100   BlendingOptions* blendingOptions;
101
102   // Lightweight hash value before compare each query.
103   std::size_t hash{0u};
104
105   // Generate hash value for this query.
106   void GenerateHash();
107
108   // Value comparision between two query info.
109   static bool Equal(const PipelineCacheQueryInfo& lhs, const PipelineCacheQueryInfo& rhs) noexcept;
110 };
111
112 /**
113  * Result of PipelineCache::GetPipeline() call
114  */
115 struct PipelineResult
116 {
117   Graphics::Pipeline* pipeline;
118   PipelineCacheL2*    level2;
119 };
120
121 /**
122  * Pipeline cache
123  */
124 class PipelineCache
125 {
126 public:
127   /**
128    * Constructor
129    * @param[in] controller Graphics controller
130    */
131   explicit PipelineCache(Graphics::Controller& controller);
132
133   /**
134    * Retrieves next cache level
135    */
136   PipelineCacheL0* GetPipelineCacheL0(std::size_t hash, Program* program, Render::Geometry* geometry);
137
138   /**
139    * Retrieves pipeline matching queryInfo struct
140    *
141    * May retrieve existing pipeline or create one or return nullptr.
142    */
143   PipelineResult GetPipeline(const PipelineCacheQueryInfo& queryInfo, bool createNewIfNotFound);
144
145   /**
146    * @brief Check whether we can reuse latest found PipelineResult.
147    * We can reuse latest pipeline only if query info is equal with latest query
148    * and we don't call CleanLatestUsedCache() before.
149    *
150    * @param[in] latestUsedCacheIndex Index of cache we want to compare.
151    * @param[in] queryInfo Query for current pipeline.
152    * @return True if we can reuse latest pipeline result. False otherwise
153    */
154   bool ReuseLatestBoundPipeline(const int latestUsedCacheIndex, const PipelineCacheQueryInfo& queryInfo) const;
155
156   /**
157    * @brief This is called before rendering every frame.
158    */
159   void PreRender();
160
161   /**
162    * @brief Decrease the reference count of the pipeline cache.
163    * @param pipelineCache The pipeline cache to decrease the reference count
164    */
165   void ResetPipeline(PipelineCacheL2* pipelineCache);
166
167 private:
168   /**
169    * @brief Clear latest bound result.
170    */
171   void CleanLatestUsedCache()
172   {
173     // Set pipeline as nullptr is enough.
174     mLatestResult[0].pipeline = nullptr;
175     mLatestResult[1].pipeline = nullptr;
176   }
177
178   /**
179    * @brief Clear unused caches.
180    */
181   void ClearUnusedCache();
182
183 private:
184   Graphics::Controller*        graphicsController{nullptr};
185   std::vector<PipelineCacheL0> level0nodes;
186
187   // Cache latest queries whether blend enabled or not.
188   // (Since most UI case (like Text and Image) enable blend, and most 3D case disable blend.)
189   PipelineCacheQueryInfo mLatestQuery[2];  ///< Latest requested query info. It will be invalidate after query's renderer / geometry / blendingOptions value changed.
190   PipelineResult         mLatestResult[2]; ///< Latest used result. It will be invalidate when we call CleanLatestUsedCache() or some cache changed.
191
192   uint32_t mFrameCount{0u};
193 };
194
195 } // namespace Render
196 } // namespace Dali::Internal
197
198 #endif // DALI_INTERNAL_RENDER_PIPELINE_CACHE_H