+ DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+
+ END_TEST;
+}
+
+int UtcDaliRendererAddDrawCommands(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test adding draw commands to the renderer");
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ glAbstraction.EnableEnableDisableCallTrace(true);
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ renderer.SetProperty(Renderer::Property::BLEND_MODE, Dali::BlendMode::ON);
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ actor.SetProperty(Actor::Property::COLOR, Vector4(1.0f, 0.0f, 1.0f, 1.0f));
+ application.GetScene().Add(actor);
+
+ // Expect delivering a single draw call
+ auto& drawTrace = glAbstraction.GetDrawTrace();
+ drawTrace.Reset();
+ drawTrace.Enable(true);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
+
+ tet_infoline("\n\nTesting extension draw commands\n");
+ auto drawCommand1 = DevelRenderer::DrawCommand{};
+ drawCommand1.drawType = DevelRenderer::DrawType::INDEXED;
+ drawCommand1.firstIndex = 0;
+ drawCommand1.elementCount = 2;
+ drawCommand1.queue = DevelRenderer::RENDER_QUEUE_OPAQUE;
+
+ auto drawCommand2 = DevelRenderer::DrawCommand{};
+ drawCommand2.drawType = DevelRenderer::DrawType::INDEXED;
+ drawCommand2.firstIndex = 2;
+ drawCommand2.elementCount = 2;
+ drawCommand2.queue = DevelRenderer::RENDER_QUEUE_TRANSPARENT;
+
+ auto drawCommand3 = DevelRenderer::DrawCommand{};
+ drawCommand3.drawType = DevelRenderer::DrawType::ARRAY;
+ drawCommand3.firstIndex = 2;
+ drawCommand3.elementCount = 2;
+ drawCommand3.queue = DevelRenderer::RENDER_QUEUE_OPAQUE;
+
+ DevelRenderer::AddDrawCommand(renderer, drawCommand1);
+ DevelRenderer::AddDrawCommand(renderer, drawCommand2);
+ DevelRenderer::AddDrawCommand(renderer, drawCommand3);
+
+ drawTrace.Reset();
+ drawTrace.Enable(true);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 3, TEST_LOCATION);
+ END_TEST;
+}
+int UtcDaliRendererSetGeometryNegative(void)
+{
+ TestApplication application;
+ Dali::Renderer instance;
+ try
+ {
+ Dali::Geometry arg1;
+ instance.SetGeometry(arg1);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliRendererSetTexturesNegative(void)
+{
+ TestApplication application;
+ Dali::Renderer instance;
+ try
+ {
+ Dali::TextureSet arg1;
+ instance.SetTextures(arg1);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliRendererSetShaderNegative(void)
+{
+ TestApplication application;
+ Dali::Renderer instance;
+ try
+ {
+ Dali::Shader arg1;
+ instance.SetShader(arg1);
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliRendererGetGeometryNegative(void)
+{
+ TestApplication application;
+ Dali::Renderer instance;
+ try
+ {
+ instance.GetGeometry();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliRendererGetTexturesNegative(void)
+{
+ TestApplication application;
+ Dali::Renderer instance;
+ try
+ {
+ instance.GetTextures();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliRendererGetShaderNegative(void)
+{
+ TestApplication application;
+ Dali::Renderer instance;
+ try
+ {
+ instance.GetShader();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true); // We expect an assert
+ }
+ END_TEST;
+}
+
+int UtcDaliRendererCheckTextureBindingP(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test adding draw commands to the renderer");
+
+ TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+ glAbstraction.EnableEnableDisableCallTrace(true);
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ renderer.SetProperty(Renderer::Property::BLEND_MODE, Dali::BlendMode::ON);
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ actor.SetProperty(Actor::Property::COLOR, Vector4(1.0f, 0.0f, 1.0f, 1.0f));
+ application.GetScene().Add(actor);
+
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ TraceCallStack& cmdBufCallstack = graphics.mCommandBufferCallStack;
+ cmdBufCallstack.Enable(true);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(!cmdBufCallstack.FindMethod("BindTextures"));
+
+ Texture image0 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGB888, 64, 64);
+ TextureSet textureSet0 = CreateTextureSet(image0);
+ renderer.SetTextures(textureSet0);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(cmdBufCallstack.FindMethod("BindTextures"));
+ END_TEST;
+}
+
+int UtcDaliRendererPreparePipeline(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that rendering an actor binds the attributes locs from the reflection");
+
+ Property::Map vf = CreateModelVertexFormat();
+ Geometry modelGeometry = CreateModelGeometry(vf);
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(modelGeometry, shader);
+ Actor actor = Actor::New();
+
+ // Change the order up to get a fair test
+ Property::Map modelVF;
+ modelVF["aBoneIndex[0]"] = Property::INTEGER;
+ modelVF["aBoneIndex[1]"] = Property::INTEGER;
+ modelVF["aBoneIndex[2]"] = Property::INTEGER;
+ modelVF["aBoneIndex[3]"] = Property::INTEGER;
+ modelVF["aBoneWeights[0]"] = Property::FLOAT;
+ modelVF["aBoneWeights[1]"] = Property::FLOAT;
+ modelVF["aBoneWeights[2]"] = Property::FLOAT;
+ modelVF["aBoneWeights[3]"] = Property::FLOAT;
+ modelVF["aPosition"] = Property::VECTOR3;
+ modelVF["aNormal"] = Property::VECTOR3;
+ modelVF["aTexCoord1"] = Property::VECTOR3;
+ modelVF["aTexCoord2"] = Property::VECTOR3;
+
+ Property::Array vfs;
+ vfs.PushBack(modelVF);
+ TestGraphicsController& graphics = application.GetGraphicsController();
+ graphics.SetVertexFormats(vfs);
+
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
+ application.GetScene().Add(actor);
+
+ TraceCallStack& cmdBufCallstack = graphics.mCommandBufferCallStack;
+ TraceCallStack& graphicsCallstack = graphics.mCallStack;
+ cmdBufCallstack.Enable(true);
+ graphicsCallstack.Enable(true);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(graphicsCallstack.FindMethod("SubmitCommandBuffers"));
+ std::vector<Graphics::SubmitInfo>& submissions = graphics.mSubmitStack;
+ DALI_TEST_CHECK(submissions.size() > 0);
+
+ TestGraphicsCommandBuffer* cmdBuf = static_cast<TestGraphicsCommandBuffer*>((submissions.back().cmdBuffer[0]));
+
+ auto result = cmdBuf->GetChildCommandsByType(0 | CommandType::BIND_PIPELINE);
+ auto pipeline = result[0]->data.bindPipeline.pipeline;
+
+ if(pipeline)
+ {
+ DALI_TEST_EQUALS(pipeline->vertexInputState.attributes.size(), 12, TEST_LOCATION);
+ DALI_TEST_EQUALS(pipeline->vertexInputState.attributes[3].location, // 4th requested attr: aTexCoord2
+ 11,
+ TEST_LOCATION);
+ DALI_TEST_EQUALS(pipeline->vertexInputState.attributes[3].format, // 4th requested attr: aTexCoord2
+ Graphics::VertexInputFormat::FVECTOR3,
+ TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliRendererUniformArrayOfStruct(void)
+{
+ TestApplication application;
+ tet_infoline("Test that uniforms that are elements of arrays of structs can be accessed");
+
+ std::vector<UniformData> customUniforms{{"arrayof[10].color", Property::VECTOR4},
+ {"arrayof[10].position", Property::VECTOR2},
+ {"arrayof[10].normal", Property::VECTOR3}};
+
+ application.GetGraphicsController().AddCustomUniforms(customUniforms);
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(geometry, shader);
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor[Actor::Property::SIZE] = Vector2(120, 120);
+ application.GetScene().Add(actor);
+
+ // Define some properties to match the custom uniforms.
+ // Ensure they can be written & read back from the abstraction.
+
+ struct UniformIndexPair
+ {
+ Property::Index index;
+ std::string name;
+ UniformIndexPair(Property::Index index, std::string name)
+ : index(index),
+ name(name)
+ {
+ }
+ };
+ std::vector<UniformIndexPair> uniformIndices;
+
+ std::ostringstream oss;
+ for(int i = 0; i < 10; ++i)
+ {
+ Property::Index index;
+ oss << "arrayof[" << i << "].color";
+ Vector4 color = Color::WHITE;
+ color.r = 25.5f * i;
+ index = renderer.RegisterProperty(oss.str(), color);
+ uniformIndices.emplace_back(index, oss.str());
+
+ oss.str("");
+ oss.clear();
+ oss << "arrayof[" << i << "].position";
+ Vector2 pos(i, 10 + i * 5);
+ index = renderer.RegisterProperty(oss.str(), pos);
+ uniformIndices.emplace_back(index, oss.str());
+
+ oss.str("");
+ oss.clear();
+ oss << "arrayof[" << i << "].normal";
+ Vector3 normal(i, i * 10, i * 100);
+ index = renderer.RegisterProperty(oss.str(), normal);
+ uniformIndices.emplace_back(index, oss.str());
+ oss.str("");
+ oss.clear();
+ }
+ auto& gl = application.GetGlAbstraction();
+ TraceCallStack& callStack = gl.GetSetUniformTrace();
+ gl.EnableSetUniformCallTrace(true);
+
+ application.SendNotification();
+ application.Render();
+
+ // Check that the uniforms match.
+ TraceCallStack::NamedParams params;
+ for(auto& uniformInfo : uniformIndices)
+ {
+ Property::Value value = renderer.GetProperty(uniformInfo.index);
+ switch(value.GetType())
+ {
+ case Property::VECTOR2:
+ {
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniformInfo.name, params));
+ Vector2 setValue;
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector2>(uniformInfo.name.c_str(), setValue));
+ DALI_TEST_EQUALS(value.Get<Vector2>(), setValue, 0.001f, TEST_LOCATION);
+ break;
+ }
+ case Property::VECTOR3:
+ {
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniformInfo.name, params));
+ Vector3 setValue;
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector3>(uniformInfo.name.c_str(), setValue));
+ DALI_TEST_EQUALS(value.Get<Vector3>(), setValue, 0.001f, TEST_LOCATION);
+ break;
+ }
+ case Property::VECTOR4:
+ {
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniformInfo.name, params));
+ Vector4 setValue;
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector4>(uniformInfo.name.c_str(), setValue));
+ DALI_TEST_EQUALS(value.Get<Vector4>(), setValue, 0.001f, TEST_LOCATION);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ // There is a hash in the property name's uniform map: check this in debugger
+ // There is a hash in the reflection. Check this in the debugger.
+
+ // Check that the reflection contains individual locs for each array entry's struct element
+ // and that it hashes the whole string
+
+ // Ensure that the property name's hash is also for the whole string.