Fix pipeline hash
[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 #include <dali/public-api/common/list-wrapper.h>
26
27 namespace Dali::Internal
28 {
29 class Program;
30 namespace Render
31 {
32 class Renderer;
33 class Geometry;
34
35 struct PipelineCacheL2;
36 struct PipelineCacheL1;
37 struct PipelineCacheL0;
38 using PipelineCacheL2Container = std::list<PipelineCacheL2>;
39 using PipelineCacheL1Container = std::list<PipelineCacheL1>;
40 using PipelineCacheL0Container = std::list<PipelineCacheL0>;
41 using PipelineCacheL2Ptr       = PipelineCacheL2Container::iterator;
42 using PipelineCacheL1Ptr       = PipelineCacheL1Container::iterator;
43 using PipelineCacheL0Ptr       = PipelineCacheL0Container::iterator;
44
45 using PipelineCachePtr = PipelineCacheL2Ptr;
46
47 /**
48  * Cache Level 2 : Last level of cache, stores actual pipeline
49  */
50 struct PipelineCacheL2
51 {
52   uint32_t                                hash{};
53   uint32_t                                referenceCount{0u};
54   Graphics::ColorBlendState               colorBlendState{};
55   Graphics::UniquePtr<Graphics::Pipeline> pipeline{};
56 };
57
58 /**
59  * Cache Level 1 : Stores rasterization and input assembly states
60  */
61 struct PipelineCacheL1
62 {
63   PipelineCacheL2Ptr GetPipelineCacheL2(bool blend, bool premul, BlendingOptions& blendingOptions);
64
65   /**
66    * @brief Clear unused caches.
67    */
68   bool ClearUnusedCache();
69
70   uint32_t                     hashCode{}; // 1byte cull, 1byte poly, 1byte frontface
71   Graphics::RasterizationState rs{};
72   Graphics::InputAssemblyState ia{};
73
74   PipelineCacheL2Container noBlends; // special case
75   PipelineCacheL2Container level2nodes;
76 };
77
78 /**
79  * Cache Level 0 : Stores hash, geometry, program amd vertex input state
80  */
81 struct PipelineCacheL0 // L0 cache
82 {
83   PipelineCacheL1Ptr GetPipelineCacheL1(Render::Renderer* renderer, bool usingReflection);
84
85   /**
86    * @brief Clear unused caches.
87    */
88   void ClearUnusedCache();
89
90   Geometry*                  geometry{};
91   Program*                   program{};
92   Graphics::VertexInputState inputState;
93
94   PipelineCacheL1Container level1nodes;
95 };
96
97 struct PipelineCacheQueryInfo
98 {
99   // Program/Geometry
100   Renderer* renderer;
101   Program*  program;
102   Geometry* geometry;
103
104   bool cameraUsingReflection;
105
106   // Blending
107   bool             blendingEnabled;
108   bool             alphaPremultiplied;
109   BlendingOptions* blendingOptions;
110
111   // Lightweight hash value before compare each query.
112   std::size_t hash{0u};
113
114   // Generate hash value for this query.
115   void GenerateHash();
116
117   // Value comparision between two query info.
118   static bool Equal(const PipelineCacheQueryInfo& lhs, const PipelineCacheQueryInfo& rhs) noexcept;
119 };
120
121 /**
122  * Result of PipelineCache::GetPipeline() call
123  */
124 struct PipelineResult
125 {
126   Graphics::Pipeline* pipeline;
127   PipelineCachePtr    level2;
128 };
129
130 /**
131  * Pipeline cache
132  */
133 class PipelineCache
134 {
135 public:
136   /**
137    * Constructor
138    * @param[in] controller Graphics controller
139    */
140   explicit PipelineCache(Graphics::Controller& controller);
141
142   /**
143    * Retrieves next cache level
144    */
145   PipelineCacheL0Ptr GetPipelineCacheL0(Program* program, Render::Geometry* geometry);
146
147   /**
148    * Retrieves pipeline matching queryInfo struct
149    *
150    * May retrieve existing pipeline or create one or return nullptr.
151    */
152   PipelineResult GetPipeline(const PipelineCacheQueryInfo& queryInfo, bool createNewIfNotFound);
153
154   /**
155    * @brief Check whether we can reuse latest found PipelineResult.
156    * We can reuse latest pipeline only if query info is equal with latest query
157    * and we don't call CleanLatestUsedCache() before.
158    *
159    * @param[in] latestUsedCacheIndex Index of cache we want to compare.
160    * @param[in] queryInfo Query for current pipeline.
161    * @return True if we can reuse latest pipeline result. False otherwise
162    */
163   bool ReuseLatestBoundPipeline(const int latestUsedCacheIndex, const PipelineCacheQueryInfo& queryInfo) const;
164
165   /**
166    * @brief This is called before rendering every frame.
167    */
168   void PreRender();
169
170   /**
171    * @brief Decrease the reference count of the pipeline cache.
172    * @param pipelineCache The pipeline cache to decrease the reference count
173    */
174   void ResetPipeline(PipelineCachePtr pipelineCache);
175
176 private:
177   /**
178    * @brief Clear latest bound result.
179    */
180   void CleanLatestUsedCache()
181   {
182     // Set pipeline as nullptr is enough.
183     mLatestResult[0].pipeline = nullptr;
184     mLatestResult[1].pipeline = nullptr;
185   }
186
187   /**
188    * @brief Clear unused caches.
189    */
190   void ClearUnusedCache();
191
192 private:
193   Graphics::Controller*    graphicsController{nullptr};
194   PipelineCacheL0Container level0nodes;
195
196   // Cache latest queries whether blend enabled or not.
197   // (Since most UI case (like Text and Image) enable blend, and most 3D case disable blend.)
198   PipelineCacheQueryInfo mLatestQuery[2];  ///< Latest requested query info. It will be invalidate after query's renderer / geometry / blendingOptions value changed.
199   PipelineResult         mLatestResult[2]; ///< Latest used result. It will be invalidate when we call CleanLatestUsedCache() or some cache changed.
200
201   uint32_t mFrameCount{0u};
202 };
203
204 } // namespace Render
205 } // namespace Dali::Internal
206
207 #endif // DALI_INTERNAL_RENDER_PIPELINE_CACHE_H