c153716d3f4b3b38816aab657beac25f31d1ff3e
[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   std::size_t                hash{};
91   Geometry*                  geometry{};
92   Program*                   program{};
93   Graphics::VertexInputState inputState;
94
95   PipelineCacheL1Container level1nodes;
96 };
97
98 struct PipelineCacheQueryInfo
99 {
100   // Program/Geometry
101   Renderer* renderer;
102   Program*  program;
103   Geometry* geometry;
104
105   bool cameraUsingReflection;
106
107   // Blending
108   bool             blendingEnabled;
109   bool             alphaPremultiplied;
110   BlendingOptions* blendingOptions;
111
112   // Lightweight hash value before compare each query.
113   std::size_t hash{0u};
114
115   // Generate hash value for this query.
116   void GenerateHash();
117
118   // Value comparision between two query info.
119   static bool Equal(const PipelineCacheQueryInfo& lhs, const PipelineCacheQueryInfo& rhs) noexcept;
120 };
121
122 /**
123  * Result of PipelineCache::GetPipeline() call
124  */
125 struct PipelineResult
126 {
127   Graphics::Pipeline* pipeline;
128   PipelineCachePtr    level2;
129 };
130
131 /**
132  * Pipeline cache
133  */
134 class PipelineCache
135 {
136 public:
137   /**
138    * Constructor
139    * @param[in] controller Graphics controller
140    */
141   explicit PipelineCache(Graphics::Controller& controller);
142
143   /**
144    * Retrieves next cache level
145    */
146   PipelineCacheL0Ptr GetPipelineCacheL0(std::size_t hash, Program* program, Render::Geometry* geometry);
147
148   /**
149    * Retrieves pipeline matching queryInfo struct
150    *
151    * May retrieve existing pipeline or create one or return nullptr.
152    */
153   PipelineResult GetPipeline(const PipelineCacheQueryInfo& queryInfo, bool createNewIfNotFound);
154
155   /**
156    * @brief Check whether we can reuse latest found PipelineResult.
157    * We can reuse latest pipeline only if query info is equal with latest query
158    * and we don't call CleanLatestUsedCache() before.
159    *
160    * @param[in] latestUsedCacheIndex Index of cache we want to compare.
161    * @param[in] queryInfo Query for current pipeline.
162    * @return True if we can reuse latest pipeline result. False otherwise
163    */
164   bool ReuseLatestBoundPipeline(const int latestUsedCacheIndex, const PipelineCacheQueryInfo& queryInfo) const;
165
166   /**
167    * @brief This is called before rendering every frame.
168    */
169   void PreRender();
170
171   /**
172    * @brief Decrease the reference count of the pipeline cache.
173    * @param pipelineCache The pipeline cache to decrease the reference count
174    */
175   void ResetPipeline(PipelineCachePtr pipelineCache);
176
177 private:
178   /**
179    * @brief Clear latest bound result.
180    */
181   void CleanLatestUsedCache()
182   {
183     // Set pipeline as nullptr is enough.
184     mLatestResult[0].pipeline = nullptr;
185     mLatestResult[1].pipeline = nullptr;
186   }
187
188   /**
189    * @brief Clear unused caches.
190    */
191   void ClearUnusedCache();
192
193 private:
194   Graphics::Controller*    graphicsController{nullptr};
195   PipelineCacheL0Container level0nodes;
196
197   // Cache latest queries whether blend enabled or not.
198   // (Since most UI case (like Text and Image) enable blend, and most 3D case disable blend.)
199   PipelineCacheQueryInfo mLatestQuery[2];  ///< Latest requested query info. It will be invalidate after query's renderer / geometry / blendingOptions value changed.
200   PipelineResult         mLatestResult[2]; ///< Latest used result. It will be invalidate when we call CleanLatestUsedCache() or some cache changed.
201
202   uint32_t mFrameCount{0u};
203 };
204
205 } // namespace Render
206 } // namespace Dali::Internal
207
208 #endif // DALI_INTERNAL_RENDER_PIPELINE_CACHE_H