6bf11d8cbb4415bd8318816691321e525de29d01
[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   Graphics::ColorBlendState               colorBlendState;
44   Graphics::UniquePtr<Graphics::Pipeline> pipeline;
45 };
46
47 /**
48  * Cache Level 1 : Stores rasterization and input assembly states
49  */
50 struct PipelineCacheL1
51 {
52   PipelineCacheL2* GetPipelineCacheL2(bool blend, bool premul, BlendingOptions& blendingOptions);
53
54   uint32_t                     hashCode{}; // 1byte cull, 1byte poly, 1byte frontface
55   Graphics::RasterizationState rs{};
56   Graphics::InputAssemblyState ia{};
57
58   PipelineCacheL2              noBlend; // special case
59   std::vector<PipelineCacheL2> level2nodes;
60 };
61
62 /**
63  * Cache Level 0 : Stores hash, geometry, program amd vertex input state
64  */
65 struct PipelineCacheL0 // L0 cache
66 {
67   PipelineCacheL1* GetPipelineCacheL1(Render::Renderer* renderer, bool usingReflection);
68
69   std::size_t                hash{};
70   Geometry*                  geometry{};
71   Program*                   program{};
72   Graphics::VertexInputState inputState;
73
74   std::vector<PipelineCacheL1> level1nodes;
75 };
76
77 struct PipelineCacheQueryInfo
78 {
79   // Program/Geometry
80   Renderer* renderer;
81   Program*  program;
82   Geometry* geometry;
83
84   bool cameraUsingReflection;
85
86   // Blending
87   bool             blendingEnabled;
88   bool             alphaPremultiplied;
89   BlendingOptions* blendingOptions;
90
91   // Lightweight hash value before compare each query.
92   std::size_t hash{0u};
93
94   // Generate hash value for this query.
95   void GenerateHash();
96
97   // Value comparision between two query info.
98   static bool Equal(const PipelineCacheQueryInfo& lhs, const PipelineCacheQueryInfo& rhs) noexcept;
99 };
100
101 /**
102  * Result of PipelineCache::GetPipeline() call
103  */
104 struct PipelineResult
105 {
106   Graphics::Pipeline* pipeline;
107
108   PipelineCacheL0* level0;
109   PipelineCacheL1* level1;
110   PipelineCacheL2* level2;
111 };
112
113 /**
114  * Pipeline cache
115  */
116 class PipelineCache
117 {
118 public:
119   /**
120    * Constructor
121    * @param[in] controller Graphics controller
122    */
123   explicit PipelineCache(Graphics::Controller& controller);
124
125   /**
126    * Retrieves next cache level
127    */
128   PipelineCacheL0* GetPipelineCacheL0(std::size_t hash, Program* program, Render::Geometry* geometry);
129
130   /**
131    * Retrieves pipeline matching queryInfo struct
132    *
133    * May retrieve existing pipeline or create one or return nullptr.
134    */
135   PipelineResult GetPipeline(const PipelineCacheQueryInfo& queryInfo, bool createNewIfNotFound);
136
137   /**
138    * @brief Check whether we can reuse latest found PipelineResult.
139    * We can reuse latest pipeline only if query info is equal with latest query
140    * and we don't call CleanLatestUsedCache() before.
141    *
142    * @param[in] latestUsedCacheIndex Index of cache we want to compare.
143    * @param[in] queryInfo Query for current pipeline.
144    * @return True if we can reuse latest pipeline result. False otherwise
145    */
146   bool ReuseLatestBoundPipeline(const int latestUsedCacheIndex, const PipelineCacheQueryInfo& queryInfo) const;
147
148   /**
149    * @brief Clear latest bound result.
150    */
151   void CleanLatestUsedCache()
152   {
153     // Set pipeline as nullptr is enough.
154     mLatestResult[0].pipeline = nullptr;
155     mLatestResult[1].pipeline = nullptr;
156   }
157
158 private:
159   Graphics::Controller*        graphicsController{nullptr};
160   std::vector<PipelineCacheL0> level0nodes;
161
162   // Cache latest queries whether blend enabled or not.
163   // (Since most UI case (like Text and Image) enable blend, and most 3D case disable blend.)
164   PipelineCacheQueryInfo mLatestQuery[2];  ///< Latest requested query info. It will be invalidate after query's renderer / geometry / blendingOptions value changed.
165   PipelineResult         mLatestResult[2]; ///< Latest used result. It will be invalidate when we call CleanLatestUsedCache() or some cache changed.
166 };
167
168 } // namespace Render
169 } // namespace Dali::Internal
170
171 #endif // DALI_INTERNAL_RENDER_PIPELINE_CACHE_H