[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-reflection.cpp
1 /*
2  * Copyright (c) 2024 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 #include "test-graphics-reflection.h"
18 #include "test-graphics-controller.h"
19 #include "test-graphics-shader.h"
20
21 #include <dali/public-api/object/property-map.h>
22 #include <string>
23 #include <vector>
24
25 extern "C"
26 {
27   void tet_infoline(const char* str);
28   void tet_printf(const char* format, ...);
29 }
30
31 namespace Dali
32 {
33 namespace
34 {
35 static const std::vector<UniformData> UNIFORMS =
36   {
37     UniformData("uColor", Property::Type::VECTOR4),
38     UniformData("uRendererColor", Property::Type::FLOAT),
39     UniformData("uCustom", Property::Type::INTEGER),
40     UniformData("uCustom3", Property::Type::VECTOR3),
41     UniformData("uFadeColor", Property::Type::VECTOR4),
42     UniformData("uUniform1", Property::Type::VECTOR4),
43     UniformData("uUniform2", Property::Type::VECTOR4),
44     UniformData("uUniform3", Property::Type::VECTOR4),
45     UniformData("uFadeProgress", Property::Type::FLOAT),
46     UniformData("uANormalMatrix", Property::Type::MATRIX3),
47     UniformData("sEffect", Property::Type::FLOAT),
48     UniformData("sTexture", Property::Type::FLOAT),
49     UniformData("sTextureRect", Property::Type::FLOAT),
50     UniformData("sGloss", Property::Type::FLOAT),
51     UniformData("uActorColor", Property::Type::VECTOR4),
52     UniformData("uModelMatrix", Property::Type::MATRIX),
53     UniformData("uModelView", Property::Type::MATRIX),
54     UniformData("uMvpMatrix", Property::Type::MATRIX),
55     UniformData("uNormalMatrix", Property::Type::MATRIX3),
56     UniformData("uProjection", Property::Type::MATRIX),
57     UniformData("uScale", Property::Type::VECTOR3),
58     UniformData("uSize", Property::Type::VECTOR3),
59     UniformData("uViewMatrix", Property::Type::MATRIX),
60     UniformData("uLightCameraProjectionMatrix", Property::Type::MATRIX),
61     UniformData("uLightCameraViewMatrix", Property::Type::MATRIX),
62
63     // WARNING: IF YOU CHANGE THIS LIST, ALSO CHANGE mActiveUniforms IN test-gl-abstraction, Initialize
64 };
65
66 /**
67  * Helper function that returns size of uniform datatypes based
68  * on property type.
69  */
70 constexpr int GetSizeForType(Property::Type type)
71 {
72   switch(type)
73   {
74     case Property::Type::BOOLEAN:
75     {
76       return sizeof(bool);
77     }
78     case Property::Type::FLOAT:
79     {
80       return sizeof(float);
81     }
82     case Property::Type::INTEGER:
83     {
84       return sizeof(int);
85     }
86     case Property::Type::VECTOR2:
87     {
88       return sizeof(Vector2);
89     }
90     case Property::Type::VECTOR3:
91     {
92       return sizeof(Vector3);
93     }
94     case Property::Type::VECTOR4:
95     {
96       return sizeof(Vector4);
97     }
98     case Property::Type::MATRIX3:
99     {
100       return sizeof(Matrix3);
101     }
102     case Property::Type::MATRIX:
103     {
104       return sizeof(Matrix);
105     }
106     default:
107     {
108       return 0;
109     }
110   };
111 }
112
113 } // namespace
114
115 TestGraphicsReflection::TestGraphicsReflection(TestGraphicsController& controller, TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms, std::vector<TestGraphicsReflection::TestUniformBlockInfo>& customUniformBlocks)
116 : mController(controller),
117   mGl(gl),
118   mCustomUniforms(customUniforms)
119 {
120   for(Property::Array::SizeType i = 0; i < vfs.Count(); ++i)
121   {
122     Property::Map* vertexFormat = vfs[i].GetMap();
123     if(vertexFormat)
124     {
125       for(Property::Map::SizeType j = 0; j < vertexFormat->Count(); ++j)
126       {
127         auto key = vertexFormat->GetKeyAt(j);
128         if(key.type == Property::Key::STRING)
129         {
130           mAttributes.push_back(key.stringKey);
131         }
132       }
133     }
134   }
135
136   mDefaultUniformBlock.name          = "";
137   mDefaultUniformBlock.members       = {};
138   mDefaultUniformBlock.binding       = 0;
139   mDefaultUniformBlock.descriptorSet = 0;
140   mDefaultUniformBlock.members.clear();
141
142   int offset = 0;
143
144   for(const auto& data : mCustomUniforms)
145   {
146     fprintf(stderr, "\ncustom uniforms: %s\n", data.name.c_str());
147
148     auto iter        = data.name.find("[", 0);
149     int  numElements = 1;
150     if(iter != std::string::npos)
151     {
152       auto baseName = data.name.substr(0, iter);
153       iter++;
154       numElements = std::stoi(data.name.substr(iter));
155       if(numElements == 0)
156       {
157         numElements = 1;
158       }
159       iter = data.name.find("]");
160       std::string suffix;
161       if(iter != std::string::npos && iter + 1 != data.name.length())
162       {
163         suffix = data.name.substr(iter + 1); // If there is a suffix, it means it is an element of an array of struct
164       }
165
166       if(!suffix.empty())
167       {
168         // Write multiple items
169         for(int i = 0; i < numElements; ++i)
170         {
171           std::stringstream elementNameStream;
172           elementNameStream << baseName << "[" << i << "]" << suffix;
173           mDefaultUniformBlock.members.emplace_back();
174           auto& item   = mDefaultUniformBlock.members.back();
175           item.name    = elementNameStream.str();
176           item.binding = 0;
177           item.offsets.push_back(offset);
178           item.locations.push_back(gl.GetUniformLocation(programId, elementNameStream.str().c_str()));
179           item.bufferIndex  = 0;
180           item.uniformClass = Graphics::UniformClass::UNIFORM;
181           item.type         = data.type;
182           offset += GetSizeForType(data.type);
183         }
184       }
185       else
186       {
187         // Write 1 item with multiple elements
188         mDefaultUniformBlock.members.emplace_back();
189         auto& item = mDefaultUniformBlock.members.back();
190
191         item.name         = baseName;
192         item.binding      = 0;
193         item.bufferIndex  = 0;
194         item.uniformClass = Graphics::UniformClass::UNIFORM;
195         item.type         = data.type;
196         item.numElements  = numElements;
197
198         for(int i = 0; i < numElements; ++i)
199         {
200           std::stringstream elementNameStream;
201           elementNameStream << baseName << "[" << i << "]";
202           item.locations.push_back(gl.GetUniformLocation(programId, elementNameStream.str().c_str()));
203           item.offsets.push_back(offset);
204           offset += GetSizeForType(data.type);
205         }
206       }
207     }
208     else
209     {
210       // Write 1 item with 1 element
211       mDefaultUniformBlock.members.emplace_back();
212       auto& item   = mDefaultUniformBlock.members.back();
213       item.name    = data.name;
214       item.binding = 0;
215       item.offsets.push_back(offset);
216       item.locations.push_back(gl.GetUniformLocation(programId, item.name.c_str()));
217       item.bufferIndex  = 0;
218       item.uniformClass = Graphics::UniformClass::UNIFORM;
219       item.type         = data.type;
220       offset += GetSizeForType(data.type);
221     }
222   }
223
224   for(const auto& data : UNIFORMS)
225   {
226     mDefaultUniformBlock.members.emplace_back();
227     auto& item   = mDefaultUniformBlock.members.back();
228     item.name    = data.name;
229     item.binding = 0;
230     item.offsets.push_back(offset);
231     item.locations.push_back(gl.GetUniformLocation(programId, data.name.c_str()));
232     item.bufferIndex  = 0;
233     item.uniformClass = Graphics::UniformClass::UNIFORM;
234     item.type         = data.type;
235     offset += GetSizeForType(data.type);
236   }
237
238   mDefaultUniformBlock.size = offset;
239
240   mUniformBlocks.push_back(mDefaultUniformBlock);
241   for(auto& element : customUniformBlocks)
242   {
243     mUniformBlocks.push_back(element);
244   }
245 }
246
247 uint32_t TestGraphicsReflection::GetVertexAttributeLocation(const std::string& name) const
248 {
249   auto iter = std::find(mAttributes.begin(), mAttributes.end(), name);
250   if(iter != mAttributes.end())
251   {
252     return iter - mAttributes.begin();
253   }
254   else if(mController.AutoAttrCreation())
255   {
256     uint32_t location = mAttributes.size();
257     mAttributes.push_back(name);
258     return location;
259   }
260
261   return -1;
262 }
263
264 Dali::Graphics::VertexInputAttributeFormat TestGraphicsReflection::GetVertexAttributeFormat(uint32_t location) const
265 {
266   tet_infoline("Warning, TestGraphicsReflection::GetVertexAttributeFormat is unimplemented\n");
267   return Dali::Graphics::VertexInputAttributeFormat{};
268 }
269
270 std::string TestGraphicsReflection::GetVertexAttributeName(uint32_t location) const
271 {
272   tet_infoline("Warning, TestGraphicsReflection::GetVertexAttributeName is unimplemented\n");
273   return 0u;
274 }
275
276 std::vector<uint32_t> TestGraphicsReflection::GetVertexAttributeLocations() const
277 {
278   std::vector<uint32_t> locs;
279   for(uint32_t i = 0; i < mAttributes.size(); ++i)
280   {
281     locs.push_back(i);
282   }
283   return locs;
284 }
285
286 uint32_t TestGraphicsReflection::GetUniformBlockCount() const
287 {
288   return mUniformBlocks.size();
289 }
290
291 uint32_t TestGraphicsReflection::GetUniformBlockBinding(uint32_t index) const
292 {
293   if(index >= mUniformBlocks.size())
294   {
295     return 0;
296   }
297   return mUniformBlocks[index].binding;
298 }
299
300 uint32_t TestGraphicsReflection::GetUniformBlockSize(uint32_t index) const
301 {
302   if(index >= mUniformBlocks.size())
303   {
304     return 0;
305   }
306
307   const auto& block = mUniformBlocks[index];
308   return block.size;
309 }
310
311 bool TestGraphicsReflection::GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInfo& out) const
312 {
313   if(index >= mUniformBlocks.size())
314   {
315     return false;
316   }
317
318   const auto& block = mUniformBlocks[index];
319
320   out.name          = block.name;
321   out.binding       = block.binding;
322   out.descriptorSet = block.descriptorSet;
323   auto membersSize  = block.members.size();
324   out.members.resize(membersSize);
325   out.size = block.size;
326   for(auto i = 0u; i < out.members.size(); ++i)
327   {
328     const auto& memberUniform   = block.members[i];
329     out.members[i].name         = memberUniform.name;
330     out.members[i].binding      = block.binding;
331     out.members[i].uniformClass = Graphics::UniformClass::UNIFORM;
332     out.members[i].offset       = memberUniform.offsets[0];
333     out.members[i].location     = memberUniform.locations[0];
334     out.members[i].elementCount = memberUniform.numElements;
335   }
336
337   return true;
338 }
339
340 std::vector<uint32_t> TestGraphicsReflection::GetUniformBlockLocations() const
341 {
342   tet_infoline("Warning, TestGraphicsReflection::GetUniformBlockLocations is unimplemented\n");
343   return std::vector<uint32_t>{};
344 }
345
346 std::string TestGraphicsReflection::GetUniformBlockName(uint32_t blockIndex) const
347 {
348   tet_infoline("Warning, TestGraphicsReflection::GetUniformBlockName is unimplemented\n");
349   return std::string{};
350 }
351
352 uint32_t TestGraphicsReflection::GetUniformBlockMemberCount(uint32_t blockIndex) const
353 {
354   if(blockIndex < mUniformBlocks.size())
355   {
356     return static_cast<uint32_t>(mUniformBlocks[blockIndex].members.size());
357   }
358   else
359   {
360     return 0u;
361   }
362 }
363
364 std::string TestGraphicsReflection::GetUniformBlockMemberName(uint32_t blockIndex, uint32_t memberLocation) const
365 {
366   if(blockIndex < mUniformBlocks.size() && memberLocation < mUniformBlocks[blockIndex].members.size())
367   {
368     return mUniformBlocks[blockIndex].members[memberLocation].name;
369   }
370   else
371   {
372     return std::string();
373   }
374 }
375
376 uint32_t TestGraphicsReflection::GetUniformBlockMemberOffset(uint32_t blockIndex, uint32_t memberLocation) const
377 {
378   if(blockIndex < mUniformBlocks.size() && memberLocation < mUniformBlocks[blockIndex].members.size())
379   {
380     return mUniformBlocks[blockIndex].members[memberLocation].offsets[0];
381   }
382   else
383   {
384     return 0u;
385   }
386 }
387
388 bool TestGraphicsReflection::GetNamedUniform(const std::string& name, Dali::Graphics::UniformInfo& out) const
389 {
390   tet_infoline("Warning, TestGraphicsReflection::GetNamedUniform is unimplemented\n");
391   return true;
392 }
393
394 const std::vector<Dali::Graphics::UniformInfo>& TestGraphicsReflection::GetSamplers() const
395 {
396   tet_infoline("Warning, TestGraphicsReflection::GetSamplers is unimplemented\n");
397   static std::vector<Dali::Graphics::UniformInfo> samplers{};
398   return samplers;
399 }
400
401 Graphics::ShaderLanguage TestGraphicsReflection::GetLanguage() const
402 {
403   return Graphics::ShaderLanguage::GLSL_3_1;
404 }
405
406 } // namespace Dali