[dali_2.3.20] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-buffer.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-buffer.h"
18 #include <sstream>
19 #include "dali-test-suite-utils.h"
20 #include "test-graphics-program.h"
21 #include "test-graphics-reflection.h"
22
23 namespace Dali
24 {
25 TestGraphicsBuffer::TestGraphicsBuffer(const Graphics::BufferCreateInfo& createInfo, TestGraphicsController& controller, TestGlAbstraction& glAbstraction, TraceCallStack& callStack)
26 : mCallStack(callStack),
27   mController(controller),
28   mGl(glAbstraction),
29   mCreateInfo(createInfo),
30   mUsage(createInfo.usage)
31 {
32   if(createInfo.propertiesFlags & int(Graphics::BufferPropertiesFlagBit::CPU_ALLOCATED))
33   {
34     mCpuOnly = true;
35   }
36   else
37   {
38     mGl.GenBuffers(1, &mId);
39   }
40   memory.resize(createInfo.size);
41 }
42
43 TestGraphicsBuffer::~TestGraphicsBuffer()
44 {
45   // Not strictly parameters, but useful for testing
46   TraceCallStack::NamedParams namedParams;
47   namedParams["usage"] << "0x" << std::hex << mCreateInfo.usage;
48   namedParams["propertiesFlags"] << mCreateInfo.propertiesFlags;
49
50   mCallStack.PushCall("Buffer::~Buffer", namedParams.str(), namedParams);
51   if(!mCpuOnly && mId)
52   {
53     mGl.DeleteBuffers(1, &mId);
54   }
55 }
56
57 void TestGraphicsBuffer::DiscardResource()
58 {
59   mController.DiscardBuffer(this);
60 }
61
62 void TestGraphicsBuffer::Bind()
63 {
64   mCallStack.PushCall("Buffer::Bind", "");
65   if(!mCpuOnly && mId > 0)
66   {
67     mGl.BindBuffer(GetTarget(), mId);
68   }
69 }
70
71 void TestGraphicsBuffer::Unbind()
72 {
73   mCallStack.PushCall("Buffer::Unbind", "");
74   if(!mCpuOnly)
75   {
76     if(mId)
77     {
78       mGl.BindBuffer(GetTarget(), 0);
79     }
80   }
81 }
82
83 void TestGraphicsBuffer::Upload(uint32_t offset, uint32_t size)
84 {
85   std::ostringstream o;
86   o << offset << ", " << size;
87   TraceCallStack::NamedParams namedParams;
88   namedParams["offset"] << offset;
89   namedParams["size"] << size;
90   mCallStack.PushCall("Buffer::Upload", o.str(), namedParams);
91
92   if(!mCpuOnly)
93   {
94     if(size <= memory.size() && mCreated)
95     {
96       // Use subData to avoid re-allocation
97       mGl.BufferSubData(GetTarget(), static_cast<GLintptr>(static_cast<unsigned long>(offset)), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[offset]);
98     }
99     else
100     {
101       mGl.BufferData(GetTarget(), static_cast<GLsizeiptr>(static_cast<unsigned long>(size)), &memory[0], GL_STATIC_DRAW); //@todo Query - do we need other usages?
102       mCreated = true;
103     }
104   }
105 }
106
107 GLenum TestGraphicsBuffer::GetTarget()
108 {
109   GLenum target = GL_ARRAY_BUFFER;
110   if((mUsage & static_cast<Graphics::BufferUsageFlags>(Graphics::BufferUsage::INDEX_BUFFER)) != 0)
111   {
112     target = GL_ELEMENT_ARRAY_BUFFER;
113   }
114   return target;
115 }
116
117 void TestGraphicsBuffer::BindAsUniformBuffer(const TestGraphicsProgram* program, const Dali::UniformBufferBindingDescriptor& uboBinding) const
118 {
119   auto*       reflection = static_cast<const TestGraphicsReflection*>(&program->GetReflection());
120   const auto& uboInfo    = reflection->GetTestUniformBlock(0u);
121
122   auto  offset = uboBinding.offset;
123   auto* data   = memory.data() + offset;
124
125   for(const auto& member : uboInfo.members)
126   {
127     uint32_t numElements = member.numElements > 0 ? member.numElements : 1;
128
129     for(uint32_t i = 0; i < numElements; ++i)
130     {
131       switch(member.type)
132       {
133         case Property::VECTOR4:
134         {
135           auto value = *reinterpret_cast<const Dali::Vector4*>(data + member.offsets[i]);
136           mGl.Uniform4f(member.locations[i], value.x, value.y, value.z, value.w);
137           break;
138         }
139         case Property::VECTOR3:
140         {
141           auto value = *reinterpret_cast<const Dali::Vector3*>(data + member.offsets[i]);
142           mGl.Uniform3f(member.locations[i], value.x, value.y, value.z);
143           break;
144         }
145         case Property::VECTOR2:
146         {
147           auto value = *reinterpret_cast<const Dali::Vector2*>(data + member.offsets[i]);
148           mGl.Uniform2f(member.locations[i], value.x, value.y);
149           break;
150         }
151         case Property::FLOAT:
152         {
153           auto value = *reinterpret_cast<const float*>(data + member.offsets[i]);
154           mGl.Uniform1f(member.locations[i], value);
155           break;
156         }
157         case Property::INTEGER:
158         {
159           auto ptr   = reinterpret_cast<const GLint*>(data + member.offsets[i]);
160           auto value = *ptr;
161           mGl.Uniform1i(member.locations[i], value);
162           break;
163         }
164         case Property::MATRIX:
165         {
166           auto value = reinterpret_cast<const float*>(data + member.offsets[i]);
167           mGl.UniformMatrix4fv(member.locations[i], 1, GL_FALSE, value);
168           break;
169         }
170         case Property::MATRIX3:
171         {
172           auto value = reinterpret_cast<const float*>(data + member.offsets[i]);
173           mGl.UniformMatrix3fv(member.locations[i], 1, GL_FALSE, value);
174           break;
175         }
176         default:
177         {
178           fprintf(stderr, "\n%s type not found\n", member.name.c_str());
179         }
180       }
181     }
182   }
183 }
184
185 } // namespace Dali