1 #ifndef DALI_INTERNAL_RENDER_PIPELINE_CACHE_H
2 #define DALI_INTERNAL_RENDER_PIPELINE_CACHE_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
27 namespace Dali::Internal
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;
45 using PipelineCachePtr = PipelineCacheL2Ptr;
48 * Cache Level 2 : Last level of cache, stores actual pipeline
50 struct PipelineCacheL2
53 uint32_t referenceCount{0u};
54 Graphics::ColorBlendState colorBlendState{};
55 Graphics::UniquePtr<Graphics::Pipeline> pipeline{};
59 * Cache Level 1 : Stores rasterization and input assembly states
61 struct PipelineCacheL1
63 PipelineCacheL2Ptr GetPipelineCacheL2(bool blend, bool premul, BlendingOptions& blendingOptions);
66 * @brief Clear unused caches.
68 bool ClearUnusedCache();
70 uint32_t hashCode{}; // 1byte cull, 1byte poly, 1byte frontface
71 Graphics::RasterizationState rs{};
72 Graphics::InputAssemblyState ia{};
74 PipelineCacheL2Container noBlends; // special case
75 PipelineCacheL2Container level2nodes;
79 * Cache Level 0 : Stores hash, geometry, program amd vertex input state
81 struct PipelineCacheL0 // L0 cache
83 PipelineCacheL1Ptr GetPipelineCacheL1(Render::Renderer* renderer, bool usingReflection);
86 * @brief Clear unused caches.
88 void ClearUnusedCache();
93 Graphics::VertexInputState inputState;
95 PipelineCacheL1Container level1nodes;
98 struct PipelineCacheQueryInfo
105 bool cameraUsingReflection;
108 bool blendingEnabled;
109 bool alphaPremultiplied;
110 BlendingOptions* blendingOptions;
112 // Lightweight hash value before compare each query.
113 std::size_t hash{0u};
115 // Generate hash value for this query.
118 // Value comparision between two query info.
119 static bool Equal(const PipelineCacheQueryInfo& lhs, const PipelineCacheQueryInfo& rhs) noexcept;
123 * Result of PipelineCache::GetPipeline() call
125 struct PipelineResult
127 Graphics::Pipeline* pipeline;
128 PipelineCachePtr level2;
139 * @param[in] controller Graphics controller
141 explicit PipelineCache(Graphics::Controller& controller);
144 * Retrieves next cache level
146 PipelineCacheL0Ptr GetPipelineCacheL0(std::size_t hash, Program* program, Render::Geometry* geometry);
149 * Retrieves pipeline matching queryInfo struct
151 * May retrieve existing pipeline or create one or return nullptr.
153 PipelineResult GetPipeline(const PipelineCacheQueryInfo& queryInfo, bool createNewIfNotFound);
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.
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
164 bool ReuseLatestBoundPipeline(const int latestUsedCacheIndex, const PipelineCacheQueryInfo& queryInfo) const;
167 * @brief This is called before rendering every frame.
172 * @brief Decrease the reference count of the pipeline cache.
173 * @param pipelineCache The pipeline cache to decrease the reference count
175 void ResetPipeline(PipelineCachePtr pipelineCache);
179 * @brief Clear latest bound result.
181 void CleanLatestUsedCache()
183 // Set pipeline as nullptr is enough.
184 mLatestResult[0].pipeline = nullptr;
185 mLatestResult[1].pipeline = nullptr;
189 * @brief Clear unused caches.
191 void ClearUnusedCache();
194 Graphics::Controller* graphicsController{nullptr};
195 PipelineCacheL0Container level0nodes;
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.
202 uint32_t mFrameCount{0u};
205 } // namespace Render
206 } // namespace Dali::Internal
208 #endif // DALI_INTERNAL_RENDER_PIPELINE_CACHE_H