[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-texture-set.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include "scene-graph-texture-set.h"
19
20 // INTERNAL HEADERS
21 #include <dali/internal/common/internal-constants.h>
22 #include <dali/internal/common/memory-pool-object-allocator.h>
23 #include <dali/internal/render/common/render-manager.h>
24 #include <dali/internal/render/renderers/render-texture.h>
25 #include <dali/internal/update/controllers/render-message-dispatcher.h>
26 #include <dali/internal/update/rendering/scene-graph-renderer.h>
27
28 namespace //Unnamed namespace
29 {
30 //Memory pool used to allocate new texture sets. Memory used by this pool will be released when shutting down DALi
31 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::TextureSet>& GetTextureSetMemoryPool()
32 {
33   static Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::TextureSet> gTextureSetMemoryPool;
34   return gTextureSetMemoryPool;
35 }
36 } // namespace
37
38 namespace Dali
39 {
40 namespace Internal
41 {
42 namespace SceneGraph
43 {
44 TextureSet* TextureSet::New()
45 {
46   return new(GetTextureSetMemoryPool().AllocateRawThreadSafe()) TextureSet();
47 }
48
49 TextureSet::TextureSet()
50 : mSamplers(),
51   mTextures(),
52   mHasAlpha(false)
53 {
54 }
55
56 TextureSet::~TextureSet()
57 {
58 }
59
60 void TextureSet::operator delete(void* ptr)
61 {
62   GetTextureSetMemoryPool().FreeThreadSafe(static_cast<TextureSet*>(ptr));
63 }
64
65 void TextureSet::SetSampler(uint32_t index, Render::Sampler* sampler)
66 {
67   const uint32_t samplerCount = static_cast<uint32_t>(mSamplers.Size());
68   if(samplerCount < index + 1)
69   {
70     SetSamplerCount(index + 1);
71   }
72
73   mSamplers[index] = sampler;
74
75   if(index < static_cast<uint32_t>(mTextures.Size()) && mTextures[index])
76   {
77     // Send a message to the RenderManagerReserveMessageSlot
78     using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
79
80     // Reserve some memory inside the render queue
81     uint32_t* slot = mRenderMessageDispatcher->ReserveMessageSlot(sizeof(DerivedType));
82
83     // Construct message in the render queue memory; note that delete should not be called on the return value
84     new(slot) DerivedType(&mRenderMessageDispatcher->GetRenderManager(), &RenderManager::SetTextureUpdated, mTextures[index]);
85   }
86
87   if(!sampler)
88   {
89     // Check wheter we need to pop back sampler
90     TrimContainers();
91   }
92 }
93
94 void TextureSet::SetTexture(uint32_t index, const Render::TextureKey& texture)
95 {
96   const uint32_t textureCount = static_cast<uint32_t>(mTextures.Size());
97   if(textureCount < index + 1)
98   {
99     SetTextureCount(index + 1);
100   }
101
102   mTextures[index] = texture;
103   if(texture)
104   {
105     mHasAlpha |= texture->HasAlphaChannel();
106
107     // Send a message to the RenderManagerReserveMessageSlot
108     using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
109
110     // Reserve some memory inside the render queue
111     uint32_t* slot = mRenderMessageDispatcher->ReserveMessageSlot(sizeof(DerivedType));
112
113     // Construct message in the render queue memory; note that delete should not be called on the return value
114     new(slot) DerivedType(&mRenderMessageDispatcher->GetRenderManager(), &RenderManager::SetTextureUpdated, texture);
115   }
116   else
117   {
118     // Check wheter we need to pop back textures
119     TrimContainers();
120   }
121 }
122
123 void TextureSet::SetTextureCount(uint32_t count)
124 {
125   const uint32_t textureCount = static_cast<uint32_t>(mTextures.Size());
126
127   if(textureCount != count)
128   {
129     mTextures.Resize(count, Render::TextureKey{});
130   }
131 }
132
133 void TextureSet::SetSamplerCount(uint32_t count)
134 {
135   const uint32_t samplerCount = static_cast<uint32_t>(mSamplers.Size());
136
137   if(samplerCount != count)
138   {
139     mSamplers.Resize(count, nullptr);
140   }
141 }
142
143 void TextureSet::TrimContainers()
144 {
145   uint32_t textureCount = static_cast<uint32_t>(mTextures.Size());
146   uint32_t samplerCount = static_cast<uint32_t>(mSamplers.Size());
147
148   while(textureCount > 0u)
149   {
150     if(mTextures[textureCount - 1u])
151     {
152       break;
153     }
154     --textureCount;
155   }
156
157   while(samplerCount > 0u)
158   {
159     if(mSamplers[samplerCount - 1u])
160     {
161       break;
162     }
163     --samplerCount;
164   }
165
166   SetTextureCount(textureCount);
167   SetSamplerCount(samplerCount);
168 }
169
170 bool TextureSet::HasAlpha() const
171 {
172   return mHasAlpha;
173 }
174
175 void TextureSet::SetRenderMessageDispatcher(RenderMessageDispatcher* renderMessageDispatcher)
176 {
177   mRenderMessageDispatcher = renderMessageDispatcher;
178 }
179
180 uint32_t TextureSet::GetMemoryPoolCapacity()
181 {
182   return GetTextureSetMemoryPool().GetCapacity();
183 }
184
185 } // namespace SceneGraph
186
187 } // namespace Internal
188
189 } // namespace Dali