2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <dali-test-suite-utils.h>
18 #include <dali/dali.h>
20 #include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
21 #include <test-actor-utils.h>
22 #include <test-graphics-application.h>
23 #include <test-graphics-sampler.h>
27 void utc_dali_program_startup(void)
29 test_return_value = TET_UNDEF;
31 void utc_dali_program_cleanup(void)
33 test_return_value = TET_PASS;
38 const std::string VERT_SHADER_SOURCE = "myVertShaderSource";
40 const std::string VERT_SHADER_SOURCE2 =
42 "in vec3 aPosition;\n"
43 "in vec3 aTexCoord;\n"
44 "out vec2 vTexCoord;\n"
47 " gl_Position=aPosition;\n"
48 " vTexCoord = aTexCoord;\n"
51 const std::string FRAG_SHADER_SOURCE =
53 "uniform sampler2D sAlbedo;\n"
54 "uniform sampler2D sMetalRoughness;\n"
55 "uniform sampler2D sNormals;\n"
56 "uniform sampler2D sAmbientOcclusion;\n"
57 "uniform mediump vec3 lightDirection;\n"
58 "in mediump vec2 vTexCoord;\n"
61 " gl_fragColor = texture2d(sAlbedo, vTexCoord) + lightDirection*texture2d(sNormals, vTexCoord);\n"
64 const std::string FRAG_SHADER_SOURCE2 =
66 "uniform sampler2D sTextures[4];\n"
67 "uniform mediump vec3 lightDirection;\n"
68 "in mediump vec2 vTexCoord;\n"
71 " gl_fragColor = texture2d(sTextures[0], vTexCoord) + lightDirection*texture2d(sTextures[2], vTexCoord);\n"
74 } //anonymous namespace
76 int UtcDaliGraphicsProgram01(void)
78 TestGraphicsApplication app;
79 tet_infoline("UtcDaliProgram - check that right sampler uniforms are bound for textures");
81 Texture normals = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
82 Texture metalroughness = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
83 Texture ao = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
84 Texture albedo = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
86 TextureSet textureSet = TextureSet::New();
87 textureSet.SetTexture(0, albedo);
88 textureSet.SetTexture(1, metalroughness);
89 textureSet.SetTexture(2, normals);
90 textureSet.SetTexture(3, ao);
92 Actor actor = CreateRenderableActor2(textureSet, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
93 app.GetScene().Add(actor);
95 auto& gl = app.GetGlAbstraction();
96 auto& glUniformTrace = gl.GetSetUniformTrace();
97 glUniformTrace.Enable(true);
98 glUniformTrace.EnableLogging(true);
100 std::vector<ActiveUniform> activeUniforms{
101 {"sAlbedo", GL_SAMPLER_2D, 1},
102 {"sAmbientOcclusion", GL_SAMPLER_2D, 1},
103 {"sNormals", GL_SAMPLER_2D, 1},
104 {"sMetalRoughness", GL_SAMPLER_2D, 1}};
105 gl.SetActiveUniforms(activeUniforms);
107 app.SendNotification();
108 app.Render(16); // The above actor will get rendered and drawn once.
110 // Check what uniform values were set:
112 DALI_TEST_CHECK(gl.GetUniformValue("sAlbedo", value)); // First in frag shader
113 DALI_TEST_EQUALS(value, 0, TEST_LOCATION);
114 DALI_TEST_CHECK(gl.GetUniformValue("sAmbientOcclusion", value)); // 4th
115 DALI_TEST_EQUALS(value, 3, TEST_LOCATION);
116 DALI_TEST_CHECK(gl.GetUniformValue("sNormals", value)); // 3rd
117 DALI_TEST_EQUALS(value, 2, TEST_LOCATION);
118 DALI_TEST_CHECK(gl.GetUniformValue("sMetalRoughness", value)); // 2nd
119 DALI_TEST_EQUALS(value, 1, TEST_LOCATION);
124 int UtcDaliGraphicsProgram02(void)
126 TestGraphicsApplication app;
127 tet_infoline("UtcDaliProgram - check that sampler arrays are handled and bound to textures");
129 Texture normals = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
130 Texture metalroughness = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
131 Texture ao = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
132 Texture albedo = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
134 TextureSet textureSet = TextureSet::New();
135 textureSet.SetTexture(0, albedo);
136 textureSet.SetTexture(1, metalroughness);
137 textureSet.SetTexture(2, normals);
138 textureSet.SetTexture(3, ao);
140 Actor actor = CreateRenderableActor2(textureSet, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
141 app.GetScene().Add(actor);
143 auto& gl = app.GetGlAbstraction();
144 auto& glUniformTrace = gl.GetSetUniformTrace();
145 glUniformTrace.Enable(true);
146 glUniformTrace.EnableLogging(true);
147 gl.GetShaderTrace().Enable(true);
148 gl.GetShaderTrace().EnableLogging(true);
150 std::vector<ActiveUniform> activeUniforms{
151 {"uLightDir", GL_FLOAT_VEC4, 1},
152 {"sTextures[0]", GL_SAMPLER_2D, 4}}; // Array of 4 samplers
153 gl.SetActiveUniforms(activeUniforms);
155 app.SendNotification();
156 app.Render(16); // The above actor will get rendered and drawn once.
158 // Check what uniform values were set:
160 DALI_TEST_CHECK(gl.GetUniformValue("sTextures[0]", value)); // First in frag shader
161 DALI_TEST_EQUALS(value, 0, TEST_LOCATION);
162 DALI_TEST_CHECK(gl.GetUniformValue("sTextures[3]", value)); // 4th
163 DALI_TEST_EQUALS(value, 3, TEST_LOCATION);
164 DALI_TEST_CHECK(gl.GetUniformValue("sTextures[2]", value)); // 3rd
165 DALI_TEST_EQUALS(value, 2, TEST_LOCATION);
166 DALI_TEST_CHECK(gl.GetUniformValue("sTextures[1]", value)); // 2nd
167 DALI_TEST_EQUALS(value, 1, TEST_LOCATION);
172 int UtcDaliGraphicsShaderNew(void)
174 TestGraphicsApplication app;
175 tet_infoline("UtcDaliProgram - check that multiple shaders from same source only create 1 program");
177 Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
179 // Creates 3 Dali::Shaders
180 Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
181 Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
182 Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
184 app.GetScene().Add(actor1);
185 app.GetScene().Add(actor2);
186 app.GetScene().Add(actor3);
188 auto& gl = app.GetGlAbstraction();
189 auto& glShaderTrace = gl.GetShaderTrace();
190 glShaderTrace.Enable(true);
191 glShaderTrace.EnableLogging(true);
193 app.SendNotification();
194 app.Render(16); // The above actors will get rendered and drawn once, only 2 shaders should be created
196 DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 2, TEST_LOCATION);
201 int UtcDaliGraphicsShaderNew02(void)
203 TestGraphicsApplication app;
204 tet_infoline("UtcDaliProgram - check that mixed up multiple shaders from same source don't create dups");
206 Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
208 // Creates 3 Dali::Shaders
209 Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
210 Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE2);
211 Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
212 Actor actor4 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE);
214 app.GetScene().Add(actor1);
215 app.GetScene().Add(actor2);
216 app.GetScene().Add(actor3);
217 app.GetScene().Add(actor4);
219 auto& gl = app.GetGlAbstraction();
220 auto& glShaderTrace = gl.GetShaderTrace();
221 glShaderTrace.Enable(true);
222 glShaderTrace.EnableLogging(true);
224 app.SendNotification();
225 app.Render(16); // The above actors will get rendered and drawn once, only 2 shaders should be created
227 // Should only be 4 shaders, not 8.
228 DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 4, TEST_LOCATION);
233 int UtcDaliGraphicsShaderFlush(void)
235 TestGraphicsApplication app;
236 tet_infoline("UtcDaliProgram - check that unused shaders are flushed");
238 Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
239 auto& gl = app.GetGlAbstraction();
240 auto& glShaderTrace = gl.GetShaderTrace();
241 glShaderTrace.Enable(true);
242 glShaderTrace.EnableLogging(true);
245 // Creates 3 Dali::Shaders
246 Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
247 Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE2);
248 Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
249 Actor actor4 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE);
251 app.GetScene().Add(actor1);
252 app.GetScene().Add(actor2);
253 app.GetScene().Add(actor3);
254 app.GetScene().Add(actor4);
256 app.SendNotification();
257 app.Render(16); // The above actors will get rendered and drawn once
259 // Should only be 4 shaders, not 8.
260 DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 4, TEST_LOCATION);
262 UnparentAndReset(actor1);
263 UnparentAndReset(actor2);
264 UnparentAndReset(actor3);
265 UnparentAndReset(actor4);
268 for(int i = 0; i < 1199; ++i) // 3 flushes per frame
270 app.SendNotification();
272 DALI_TEST_EQUALS(glShaderTrace.CountMethod("DeleteShader"), 0, TEST_LOCATION);
274 app.SendNotification();
276 DALI_TEST_EQUALS(glShaderTrace.CountMethod("DeleteShader"), 4, TEST_LOCATION);