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