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();
92 Graphics::VertexInputState inputState;
94 PipelineCacheL1Container level1nodes;
97 struct PipelineCacheQueryInfo
104 bool cameraUsingReflection;
107 bool blendingEnabled;
108 bool alphaPremultiplied;
109 BlendingOptions* blendingOptions;
111 // Lightweight hash value before compare each query.
112 std::size_t hash{0u};
114 // Generate hash value for this query.
117 // Value comparision between two query info.
118 static bool Equal(const PipelineCacheQueryInfo& lhs, const PipelineCacheQueryInfo& rhs) noexcept;
122 * Result of PipelineCache::GetPipeline() call
124 struct PipelineResult
126 Graphics::Pipeline* pipeline;
127 PipelineCachePtr level2;
138 * @param[in] controller Graphics controller
140 explicit PipelineCache(Graphics::Controller& controller);
143 * Retrieves next cache level
145 PipelineCacheL0Ptr GetPipelineCacheL0(Program* program, Render::Geometry* geometry);
148 * Retrieves pipeline matching queryInfo struct
150 * May retrieve existing pipeline or create one or return nullptr.
152 PipelineResult GetPipeline(const PipelineCacheQueryInfo& queryInfo, bool createNewIfNotFound);
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.
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
163 bool ReuseLatestBoundPipeline(const int latestUsedCacheIndex, const PipelineCacheQueryInfo& queryInfo) const;
166 * @brief This is called before rendering every frame.
171 * @brief Decrease the reference count of the pipeline cache.
172 * @param pipelineCache The pipeline cache to decrease the reference count
174 void ResetPipeline(PipelineCachePtr pipelineCache);
178 * @brief Clear latest bound result.
180 void CleanLatestUsedCache()
182 // Set pipeline as nullptr is enough.
183 mLatestResult[0].pipeline = nullptr;
184 mLatestResult[1].pipeline = nullptr;
188 * @brief Clear unused caches.
190 void ClearUnusedCache();
193 Graphics::Controller* graphicsController{nullptr};
194 PipelineCacheL0Container level0nodes;
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.
201 uint32_t mFrameCount{0u};
204 } // namespace Render
205 } // namespace Dali::Internal
207 #endif // DALI_INTERNAL_RENDER_PIPELINE_CACHE_H