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