X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=automated-tests%2Fsrc%2Fdali-toolkit%2Futc-Dali-ImageVisual.cpp;h=1fcd10d955122a52c441d631467c64da0680a8f4;hp=b36457ff2fb0740d0fee26c66a4a3af68e6d2931;hb=HEAD;hpb=340a0bbd8c7e93bc7a8e7c25b7ff44bb0b0af196 diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp index b36457f..319d4d4 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,15 @@ #include #include +#include +#include + #include +#include #include +#include +#include #include #include @@ -28,10 +34,13 @@ #include #include #include +#include #include #include #include +#include + #include "dummy-control.h" #include "test-encoded-image-buffer.h" #include "test-native-image-source.h" @@ -60,6 +69,31 @@ const char* TEST_INVALID_FILE_NAME = TEST_RESOURCE_DIR "/invalid.jpg"; const char* TEST_REMOTE_INVALID_FILE_NAME = "https://www.tizen.org/invalid.png"; const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png"; const char* TEST_ROTATED_IMAGE = TEST_RESOURCE_DIR "/keyboard-Landscape.jpg"; +const char* TEST_YUV420_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1-yuv420.jpg"; +const char* TEST_N_PATCH_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/heartsframe.9.png"; + +constexpr auto LOAD_IMAGE_YUV_PLANES_ENV = "DALI_LOAD_IMAGE_YUV_PLANES"; +constexpr auto ENABLE_DECODE_JPEG_TO_YUV_420_ENV = "DALI_ENABLE_DECODE_JPEG_TO_YUV_420"; + +constexpr auto DALI_DEBUG_IMAGE_VISUAL_SHADER_ENV = "DALI_DEBUG_IMAGE_VISUAL_SHADER"; + +constexpr auto DALI_DEBUG_IMAGE_VISUAL_SHADER_SCRIPT_FILE_NAME_ENV = "DALI_DEBUG_IMAGE_VISUAL_SHADER_SCRIPT_FILE_NAME"; + +const char* VALID_DEBUG_SHADER_SCRIPT = + "{\n" + " \"version\": \"1.0.0\",\n" + " \"maximumColorRate\": 0.5,\n" + " \"extraVaryings\": [\"mediump vec3 vDebug;\"],\n" + " \"extraUniforms\": \"mediump float uDebug;\",\n" + " \"applyVaryingsCode\": \"vDebug = gl_Position.xyz / gl_Position.w;\",\n" + " \"redChannelCodes\":\n" + " {\n" + " \"triggerCode\":[\"return\",\" false;\"],\n" + " \"ratioCode\":\"return 0.0;\"\n" + " }\n" + "}\n"; + +constexpr std::string_view THROW_EXCEPTION_STYLE_FILE_NAME = "throwException"; bool gResourceReadySignalFired = false; std::vector gReadyIds = {}; @@ -418,14 +452,18 @@ int UtcDaliImageVisualRemoteImageLoad(void) END_TEST; } -int UtcDaliImageVisualWithNativeImage(void) +int UtcDaliImageVisualWithFrameBufferPreMultipliedAlpha01(void) { ToolkitTestApplication application; - tet_infoline("Use Native Image as url"); + tet_infoline("Use FrameBuffer as url"); - NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); - ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource); - std::string url = imageUrl.GetUrl(); + uint32_t width(64); + uint32_t height(64); + FrameBuffer frameBuffer = Dali::FrameBuffer::New(width, height, FrameBuffer::Attachment::NONE); + + DALI_TEST_CHECK(frameBuffer); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(frameBuffer, Pixel::Format::RGBA8888, width, height); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); @@ -447,43 +485,40 @@ int UtcDaliImageVisualWithNativeImage(void) DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - Renderer renderer = actor.GetRendererAt(0); - Shader shader = renderer.GetShader(); - - Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); - DALI_TEST_CHECK(value.GetType() == Property::MAP); - const Property::Map* outMap = value.GetMap(); - std::string fragmentShader = (*outMap)["fragment"].Get(); + application.SendNotification(); + application.Render(16); - const char* fragmentPrefix = Dali::NativeImageSourceTest::GetCustomFragmentPrefix(); - size_t pos = fragmentShader.find(fragmentPrefix); + Renderer renderer = actor.GetRendererAt(0); - DALI_TEST_EQUALS(pos != std::string::npos, true, TEST_LOCATION); + // Check whether preMultipliedAlpha is true. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualWithNativeImageCustomShader(void) +int UtcDaliImageVisualWithFrameBufferPreMultipliedAlpha02(void) { ToolkitTestApplication application; - tet_infoline("Use Native Image as url and Use custom shader"); + tet_infoline("Use FrameBuffer as url"); - NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); - ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource); - std::string url = imageUrl.GetUrl(); + uint32_t width(64); + uint32_t height(64); + FrameBuffer frameBuffer = Dali::FrameBuffer::New(width, height, FrameBuffer::Attachment::NONE); + + DALI_TEST_CHECK(frameBuffer); + + Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height); + frameBuffer.AttachColorTexture(texture); + + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(frameBuffer, 0u); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); - Property::Map propertyMap; - Property::Map shaderMap; - const std::string customVertexShaderSource = "Foobar"; - const std::string customFragmentShaderSource = "Foobar"; - shaderMap[Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = customFragmentShaderSource; - shaderMap[Toolkit::Visual::Shader::Property::VERTEX_SHADER] = customVertexShaderSource; - + Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(Toolkit::Visual::Property::SHADER, shaderMap); propertyMap.Insert(ImageVisual::Property::URL, url); Visual::Base visual = factory.CreateVisual(propertyMap); @@ -493,9 +528,6 @@ int UtcDaliImageVisualWithNativeImageCustomShader(void) DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); application.GetScene().Add(actor); @@ -506,40 +538,30 @@ int UtcDaliImageVisualWithNativeImageCustomShader(void) application.Render(16); Renderer renderer = actor.GetRendererAt(0); - Shader shader = renderer.GetShader(); - - Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); - DALI_TEST_CHECK(value.GetType() == Property::MAP); - const Property::Map* outMap = value.GetMap(); - std::string fragmentShaderSource = (*outMap)["fragment"].Get(); - std::string vertexShaderSource = (*outMap)["vertex"].Get(); - - // Compare vertex shader is equal - DALI_TEST_EQUALS(customVertexShaderSource, vertexShaderSource, TEST_LOCATION); - // Check fragment shader changed - const char* fragmentPrefix = Dali::NativeImageSourceTest::GetCustomFragmentPrefix(); - size_t pos = fragmentShaderSource.find(fragmentPrefix); - - DALI_TEST_EQUALS(pos != std::string::npos, true, TEST_LOCATION); - - DALI_TEST_EQUALS(std::string(fragmentPrefix) + customFragmentShaderSource, fragmentShaderSource, TEST_LOCATION); + // Check whether preMultipliedAlpha is true. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualWithNativeImageRemoved(void) +int UtcDaliImageVisualWithPixelData(void) { ToolkitTestApplication application; - tet_infoline("Use Native Image as url"); + tet_infoline("Use PixelData as url"); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); - NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); - ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource); - std::string url = imageUrl.GetUrl(); + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); + + DALI_TEST_CHECK(pixelData); + + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); @@ -553,95 +575,95 @@ int UtcDaliImageVisualWithNativeImageRemoved(void) DummyControl actor = DummyControl::New(); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); application.GetScene().Add(actor); - application.SendNotification(); - application.Render(); DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - tet_infoline("No delete texture because reference count is not zero"); - imageUrl.Reset(); - application.GetScene().Remove(actor); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); application.SendNotification(); - application.Render(); - - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + application.Render(16); - tet_infoline("Delete texture because reference count is zero"); - visual.Reset(); - application.SendNotification(); - application.Render(); + Renderer renderer = actor.GetRendererAt(0); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + // Check whether preMultipliedAlpha is false. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualWithEncodedImageBuffer(void) +int UtcDaliImageVisualWithPixelDataPreMultipliedAlpha(void) { ToolkitTestApplication application; - tet_infoline("Use Encoded Image Buffer as url"); + tet_infoline("Use PixelData as url"); - EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_LARGE_IMAGE_FILE_NAME); - ImageUrl url = Dali::Toolkit::Image::GenerateUrl(rawBuffer); + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); + + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); + + DALI_TEST_CHECK(pixelData); + + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, url.GetUrl()); + propertyMap.Insert(ImageVisual::Property::URL, url); Visual::Base visual = factory.CreateVisual(propertyMap); DALI_TEST_CHECK(visual); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); - DummyControl actor = DummyControl::New(); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); application.GetScene().Add(actor); - application.SendNotification(); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); application.SendNotification(); - application.Render(); + application.Render(16); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0); - application.GetScene().Remove(actor); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + // Check whether preMultipliedAlpha is true. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualWithEncodedImageBufferRemoved(void) +int UtcDaliImageVisualWithPixelDataMasking(void) { ToolkitTestApplication application; - tet_infoline("Use Encoded Image Buffer as url"); + tet_infoline("Load external texture with mask"); TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_LARGE_IMAGE_FILE_NAME); - ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(rawBuffer); - std::string url = imageUrl.GetUrl(); + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); + + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); + + DALI_TEST_CHECK(pixelData); + + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); @@ -649,776 +671,836 @@ int UtcDaliImageVisualWithEncodedImageBufferRemoved(void) Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); propertyMap.Insert(ImageVisual::Property::URL, url); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); Visual::Base visual = factory.CreateVisual(propertyMap); DALI_TEST_CHECK(visual); + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + DummyControl actor = DummyControl::New(); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); application.GetScene().Add(actor); application.SendNotification(); - - // Wait for decode buffer and make texture. + application.Render(16); DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.SendNotification(); - application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - - tet_infoline("Delete texture because there is no actor to use decoded texture"); - imageUrl.Reset(); - application.GetScene().Remove(actor); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); - application.SendNotification(); - application.Render(); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualTextureReuse1(void) +int UtcDaliImageVisualWithPixelDataMasking02(void) { ToolkitTestApplication application; - tet_infoline("Request remote image visual with a Property::Map; request a second visual with the same property map - should reuse texture"); - - Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DETACHED); + tet_infoline("Load premultiplied external texture with mask"); TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - TraceCallStack& drawTrace = gl.GetDrawTrace(); - drawTrace.Enable(true); - Actor actor = CreateActorWithImageVisual(propertyMap); - application.GetScene().Add(actor); - application.SendNotification(); + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); - application.SendNotification(); - application.Render(); + DALI_TEST_CHECK(pixelData); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION); - textureTrace.Reset(); - drawTrace.Reset(); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true); + std::string url = imageUrl.GetUrl(); - Actor actor2 = CreateActorWithImageVisual(propertyMap); - application.GetScene().Add(actor2); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - application.SendNotification(); // Send messages to update - application.Render(); // process update and render - application.SendNotification(); // process any signals to event + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, url); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); - DALI_TEST_EQUALS(actor2.GetRendererCount(), 1u, TEST_LOCATION); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - // Testing for texture re-use in gl side is not relevant - we are not using actual graphics - // backend here, but test graphics backend. - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - DALI_TEST_EQUALS(drawTrace.CountMethod("DrawArrays"), 2, TEST_LOCATION); + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); - tet_infoline("Test that removing 1 actor doesn't delete the texture\n"); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - application.GetScene().Remove(actor); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); application.SendNotification(); - application.Render(); + application.Render(16); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); - tet_infoline("Test that removing last actor does delete the texture\n"); + Renderer renderer = actor.GetRendererAt(0); - application.GetScene().Remove(actor2); // Detaches remaining ImageVisual - application.SendNotification(); - application.Render(); + //Check visual property + DALI_TEST_EQUALS(*testMap.Find(Visual::Property::PREMULTIPLIED_ALPHA), Property::Value(true), TEST_LOCATION); - DALI_TEST_CHECK(actor2.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + // Check whether preMultipliedAlpha is true. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualTextureReuse2(void) +int UtcDaliImageVisualWithPixelDataMaskingSynchronously(void) { ToolkitTestApplication application; - tet_infoline("Request remote image visual with a Property::Map; request a second visual with the same url but different property map - should create new texture"); + tet_infoline("Load synchronously external texture with mask"); + + uint32_t width(64); + uint32_t height(64); + uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888); + + uint8_t* buffer = reinterpret_cast(malloc(bufferSize)); + PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE); + + DALI_TEST_CHECK(pixelData); + + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true); + std::string url = imageUrl.GetUrl(); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_REMOTE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::URL, url); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); - TraceCallStack& drawTrace = gl.GetDrawTrace(); - drawTrace.Enable(true); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - Actor actor = CreateActorWithImageVisual(propertyMap); - application.GetScene().Add(actor); - application.SendNotification(); + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - application.SendNotification(); - application.Render(); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION); - textureTrace.Reset(); - drawTrace.Reset(); - - propertyMap.Insert(ImageVisual::Property::SAMPLING_MODE, Dali::SamplingMode::NEAREST); - propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, 100); - propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, 100); - Actor actor2 = CreateActorWithImageVisual(propertyMap); - application.GetScene().Add(actor2); application.SendNotification(); + application.Render(16); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + END_TEST; +} - application.SendNotification(); - application.Render(); +int UtcDaliImageVisualWithNativeImage(void) +{ + ToolkitTestApplication application; + tet_infoline("Use Native Image as url"); - DALI_TEST_EQUALS(actor2.GetRendererCount(), 1u, TEST_LOCATION); + NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource); + std::string url = imageUrl.GetUrl(); - tet_infoline( - "Test that 2 draw calls occur with 1 new texture gen/bind, i.e. both " - "renderers are using different textures\n"); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(drawTrace.CountMethod("DrawArrays"), 2, TEST_LOCATION); - TraceCallStack::NamedParams tex1; - tex1["texture"] << 1; - TraceCallStack::NamedParams tex2; - tex2["texture"] << 2; - DALI_TEST_EQUALS(textureTrace.FindMethodAndParams("BindTexture", tex1), true, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethodAndParams("BindTexture", tex2), true, TEST_LOCATION); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, url); - tet_infoline("Test that removing 1 actor deletes it's texture\n"); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - application.GetScene().Remove(actor); - application.SendNotification(); - application.Render(); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - tet_infoline("Test that removing last actor deletes it's texture\n"); + application.GetScene().Add(actor); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - application.GetScene().Remove(actor2); application.SendNotification(); - application.Render(); + application.Render(16); - DALI_TEST_CHECK(actor2.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 2, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0); + Shader shader = renderer.GetShader(); + + Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); + DALI_TEST_CHECK(value.GetType() == Property::MAP); + const Property::Map* outMap = value.GetMap(); + std::string fragmentShader = (*outMap)["fragment"].Get(); + + const char* fragmentPrefix = Dali::NativeImageSourceTest::GetCustomFragmentPrefix(); + size_t pos = fragmentShader.find(fragmentPrefix); + + DALI_TEST_EQUALS(pos != std::string::npos, true, TEST_LOCATION); + + // Check whether preMultipliedAlpha is false. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualCustomWrapModePixelArea(void) +int UtcDaliImageVisualWithNativeImagePreMultipliedAlpha(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with a Property::Map, test custom wrap mode and pixel area with atlasing"); - - static std::vector customUniforms = - { - UniformData("pixelArea", Property::Type::VECTOR4), - UniformData("wrapMode", Property::Type::VECTOR2), - }; + tet_infoline("Use Native Image as url"); - TestGraphicsController& graphics = application.GetGraphicsController(); - graphics.AddCustomUniforms(customUniforms); + NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource, true); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); - // Test wrap mode with atlasing. Image with a size smaller than 512*512 will be uploaded as a part of the atlas. - const int width = 34; - const int height = 34; - const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); - Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_SMALL_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, width); - propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, height); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); - propertyMap.Insert(ImageVisual::Property::PIXEL_AREA, pixelArea); - propertyMap.Insert(ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT); - propertyMap.Insert(ImageVisual::Property::WRAP_MODE_V, WrapMode::REPEAT); - propertyMap.Insert(ImageVisual::Property::ATLASING, true); + propertyMap.Insert(ImageVisual::Property::URL, url); Visual::Base visual = factory.CreateVisual(propertyMap); DALI_TEST_CHECK(visual); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); - TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); - texParameterTrace.Enable(true); - DummyControl actor = DummyControl::New(); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); - actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - application.GetScene().Add(actor); - // loading started - application.SendNotification(); - application.Render(); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + application.GetScene().Add(actor); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - // WITH atlasing, the wrapping is handled manually in shader, so the following gl function should not be called - std::stringstream out; - out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; - DALI_TEST_CHECK(!texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); - out.str(""); - out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_REPEAT; - DALI_TEST_CHECK(!texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); + application.SendNotification(); + application.Render(16); - // test the uniforms which used to handle the wrap mode - Renderer renderer = actor.GetRendererAt(0u); - DALI_TEST_CHECK(renderer); + Renderer renderer = actor.GetRendererAt(0); + Shader shader = renderer.GetShader(); - Property::Value pixelAreaValue = renderer.GetProperty(renderer.GetPropertyIndex("pixelArea")); - DALI_TEST_EQUALS(pixelAreaValue.Get(), pixelArea, TEST_LOCATION); - Vector4 pixelAreaUniform; - DALI_TEST_CHECK(gl.GetUniformValue("pixelArea", pixelAreaUniform)); - DALI_TEST_EQUALS(pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); + Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); + DALI_TEST_CHECK(value.GetType() == Property::MAP); + const Property::Map* outMap = value.GetMap(); + std::string fragmentShader = (*outMap)["fragment"].Get(); - Property::Value wrapModeValue = renderer.GetProperty(renderer.GetPropertyIndex("wrapMode")); - Vector2 wrapMode(WrapMode::MIRRORED_REPEAT - 1, WrapMode::REPEAT - 1); - DALI_TEST_EQUALS(wrapModeValue.Get(), wrapMode, TEST_LOCATION); - Vector2 wrapModeUniform; - DALI_TEST_CHECK(gl.GetUniformValue("wrapMode", wrapModeUniform)); - DALI_TEST_EQUALS(wrapMode, wrapModeUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); + const char* fragmentPrefix = Dali::NativeImageSourceTest::GetCustomFragmentPrefix(); + size_t pos = fragmentShader.find(fragmentPrefix); - actor.Unparent(); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(pos != std::string::npos, true, TEST_LOCATION); + + // Check whether preMultipliedAlpha is true. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualCustomWrapModeNoAtlas(void) +int UtcDaliImageVisualWithNativeImageCustomShader(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with a Property::Map, test custom wrap mode and pixel area without atlasing"); - - static std::vector customUniforms = - { - UniformData("pixelArea", Property::Type::VECTOR4), - }; + tet_infoline("Use Native Image as url and Use custom shader"); - TestGraphicsController& graphics = application.GetGraphicsController(); - graphics.AddCustomUniforms(customUniforms); + NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource, true); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); - // Test wrap mode without atlasing. Image with a size bigger than 512*512 will NOT be uploaded as a part of the atlas. - const int width = 600; - const int height = 600; - const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); + Property::Map propertyMap; + Property::Map shaderMap; + const std::string customVertexShaderSource = "Foobar"; + const std::string customFragmentShaderSource = "Foobar"; + shaderMap[Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = customFragmentShaderSource; + shaderMap[Toolkit::Visual::Shader::Property::VERTEX_SHADER] = customVertexShaderSource; - Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, width); - propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, height); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); - propertyMap.Insert(ImageVisual::Property::PIXEL_AREA, pixelArea); - propertyMap.Insert(ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT); - propertyMap.Insert(ImageVisual::Property::WRAP_MODE_V, WrapMode::REPEAT); + propertyMap.Insert(Toolkit::Visual::Property::SHADER, shaderMap); + propertyMap.Insert(ImageVisual::Property::URL, url); Visual::Base visual = factory.CreateVisual(propertyMap); DALI_TEST_CHECK(visual); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); - textureTrace.EnableLogging(true); - TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); - texParameterTrace.Enable(true); - texParameterTrace.EnableLogging(true); - DummyControl actor = DummyControl::New(); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + application.GetScene().Add(actor); - // loading started - application.SendNotification(); - application.Render(); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + application.SendNotification(); + application.Render(16); - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + Renderer renderer = actor.GetRendererAt(0); + Shader shader = renderer.GetShader(); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + Property::Value value = shader.GetProperty(Shader::Property::PROGRAM); + DALI_TEST_CHECK(value.GetType() == Property::MAP); + const Property::Map* outMap = value.GetMap(); + std::string fragmentShaderSource = (*outMap)["fragment"].Get(); + std::string vertexShaderSource = (*outMap)["vertex"].Get(); - // WITHOUT atlasing, the wrapping is handled by setting gl texture parameters - std::stringstream out; - out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; - DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); - out.str(""); - out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_REPEAT; - DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); + // Compare vertex shader is equal + DALI_TEST_EQUALS(customVertexShaderSource, vertexShaderSource, TEST_LOCATION); - // test the uniforms which used to handle the wrap mode - Renderer renderer = actor.GetRendererAt(0u); - DALI_TEST_CHECK(renderer); + // Check fragment shader changed + const char* fragmentPrefix = Dali::NativeImageSourceTest::GetCustomFragmentPrefix(); + size_t pos = fragmentShaderSource.find(fragmentPrefix); - Property::Value pixelAreaValue = renderer.GetProperty(renderer.GetPropertyIndex("pixelArea")); - DALI_TEST_EQUALS(pixelAreaValue.Get(), pixelArea, TEST_LOCATION); - Vector4 pixelAreaUniform; - DALI_TEST_CHECK(gl.GetUniformValue("pixelArea", pixelAreaUniform)); - DALI_TEST_EQUALS(pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); + DALI_TEST_EQUALS(pos != std::string::npos, true, TEST_LOCATION); - Property::Index wrapModeIndex = renderer.GetPropertyIndex("wrapMode"); - DALI_TEST_CHECK(wrapModeIndex == Property::INVALID_INDEX); + DALI_TEST_EQUALS(std::string(fragmentPrefix) + customFragmentShaderSource, fragmentShaderSource, TEST_LOCATION); - actor.Unparent(); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + // Check whether preMultipliedAlpha is false. + // Note : We dont use preMultiplied alpha when app developer using custom shader. + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualAnimateMixColor(void) +int UtcDaliImageVisualWithNativeImageRemoved(void) { ToolkitTestApplication application; - tet_infoline("Animate mix color"); + tet_infoline("Use Native Image as url"); - static std::vector customUniforms = - { - UniformData("mixColor", Property::Type::VECTOR3), - }; + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - TestGraphicsController& graphics = application.GetGraphicsController(); - graphics.AddCustomUniforms(customUniforms); - - application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + NativeImageSourcePtr nativeImageSource = NativeImageSource::New(500, 500, NativeImageSource::COLOR_DEPTH_DEFAULT); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(nativeImageSource); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMap.Insert("mixColor", Color::BLUE); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, url); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); - actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - Renderer renderer = actor.GetRendererAt(0); + tet_infoline("No delete texture because reference count is not zero"); + imageUrl.Reset(); + application.GetScene().Remove(actor); + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + application.SendNotification(); + application.Render(); - // @todo Should we add API to make this code work again? - // Property::Index index = renderer.GetPropertyIndex( Visual::Property::MIX_COLOR ); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - Property::Value blendModeValue = renderer.GetProperty(Renderer::Property::BLEND_MODE); - DALI_TEST_EQUALS(blendModeValue.Get(), (int)BlendMode::AUTO, TEST_LOCATION); + tet_infoline("Delete texture because reference count is zero"); + visual.Reset(); + application.SendNotification(); + application.Render(); - const Vector4 TARGET_MIX_COLOR(1.0f, 0.0f, 0.0f, 0.5f); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); - Property::Map map; - map["target"] = "testVisual"; - map["property"] = "mixColor"; - map["initialValue"] = Color::MAGENTA; - map["targetValue"] = TARGET_MIX_COLOR; - map["animator"] = Property::Map() - .Add("alphaFunction", "LINEAR") - .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + END_TEST; +} - Dali::Toolkit::TransitionData transition = TransitionData::New(map); +int UtcDaliImageVisualWithEncodedImageBuffer(void) +{ + ToolkitTestApplication application; + tet_infoline("Use Encoded Image Buffer as url"); - Animation animation = dummyImpl.CreateTransition(transition); + EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_LARGE_IMAGE_FILE_NAME); + ImageUrl url = Dali::Toolkit::Image::GenerateUrl(rawBuffer); - animation.AnimateTo(Property(actor, Actor::Property::COLOR), Color::WHITE); - animation.Play(); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); - glAbstraction.EnableEnableDisableCallTrace(true); - TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); - std::ostringstream blendStr; - blendStr << std::hex << GL_BLEND; + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, url.GetUrl()); - application.SendNotification(); - application.Render(0); // Ensure animation starts - application.Render(2000u); // Halfway point - Vector3 testColor(1.0f, 0.0f, 0.5f); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - // uColor.a should be actor's alpha * mixColor.a. - DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("uColor", Vector4(0.5f, 0.5f, 0.5f, 0.75f)), true, TEST_LOCATION); - DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("mixColor", testColor), true, TEST_LOCATION); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - glEnableStack.Reset(); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + application.GetScene().Add(actor); application.SendNotification(); - application.Render(2000u); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); - application.SendNotification(); - - DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::COLOR), Color::WHITE, TEST_LOCATION); - DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("uColor", Vector4(1.0f, 1.0f, 1.0f, 0.5f)), true, TEST_LOCATION); - DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("mixColor", Vector3(TARGET_MIX_COLOR)), true, TEST_LOCATION); - // (Don't test for caching of capabilities, toolkit uses Test graphics backend, not actual backend) + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - TestMixColor(visual, Visual::Property::MIX_COLOR, TARGET_MIX_COLOR); + application.GetScene().Remove(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); END_TEST; } -int UtcDaliImageVisualAnimateOpacity(void) +int UtcDaliImageVisualWithEncodedImageBufferRemoved(void) { ToolkitTestApplication application; - tet_infoline("Animate image visual opacity"); + tet_infoline("Use Encoded Image Buffer as url"); - application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_LARGE_IMAGE_FILE_NAME); + ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(rawBuffer); + std::string url = imageUrl.GetUrl(); VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMap.Insert("opacity", 0.5f); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, url); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); - actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - actor.SetProperty(Actor::Property::COLOR, Color::BLACK); - application.GetScene().Add(actor); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + application.GetScene().Add(actor); + application.SendNotification(); - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); - glAbstraction.EnableEnableDisableCallTrace(true); - TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); - std::ostringstream blendStr; - blendStr << std::hex << GL_BLEND; + // Wait for decode buffer and make texture. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); - - { - tet_infoline("Test that the opacity can be increased to full via animation, and that the blend mode is set appropriately at the start and end of the animation."); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - Property::Map map; - map["target"] = "testVisual"; - map["property"] = "opacity"; - map["targetValue"] = 1.0f; - map["animator"] = Property::Map() - .Add("alphaFunction", "LINEAR") - .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + tet_infoline("Delete texture because there is no actor to use decoded texture"); + imageUrl.Reset(); + application.GetScene().Remove(actor); + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + application.SendNotification(); + application.Render(); - Dali::Toolkit::TransitionData transition = TransitionData::New(map); - Animation animation = dummyImpl.CreateTransition(transition); - animation.Play(); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); - glEnableStack.Reset(); + END_TEST; +} - application.SendNotification(); - application.Render(0); // Ensure animation starts - application.Render(2000u); // Halfway point through animation - application.SendNotification(); // Handle any signals +int UtcDaliImageVisualTextureReuse1(void) +{ + ToolkitTestApplication application; + tet_infoline("Request remote image visual with a Property::Map; request a second visual with the same property map - should reuse texture"); - Vector4 color; - DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); - DALI_TEST_EQUALS(color.a, 0.75f, TEST_LOCATION); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DETACHED); - application.Render(2001u); // end - application.SendNotification(); // ensure animation finished signal is sent + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& drawTrace = gl.GetDrawTrace(); + drawTrace.Enable(true); - DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); - DALI_TEST_EQUALS(color.a, 1.0f, TEST_LOCATION); + Actor actor = CreateActorWithImageVisual(propertyMap); + application.GetScene().Add(actor); + application.SendNotification(); - // (Don't test for caching of capabilities, toolkit uses Test graphics backend, not actual backend) - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Disable", blendStr.str())); - } + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - { - tet_infoline("Test that the opacity can be reduced via animation, and that the blend mode is set appropriately at the start and end of the animation."); + application.SendNotification(); + application.Render(); - Property::Map map; - map["target"] = "testVisual"; - map["property"] = Visual::Property::OPACITY; - map["targetValue"] = 0.1f; - map["animator"] = Property::Map() - .Add("alphaFunction", "LINEAR") - .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION); + textureTrace.Reset(); + drawTrace.Reset(); - Dali::Toolkit::TransitionData transition = TransitionData::New(map); - Animation animation = dummyImpl.CreateTransition(transition); - animation.Play(); + Actor actor2 = CreateActorWithImageVisual(propertyMap); + application.GetScene().Add(actor2); - glEnableStack.Reset(); + application.SendNotification(); // Send messages to update + application.Render(); // process update and render + application.SendNotification(); // process any signals to event - application.SendNotification(); - application.Render(0); // Ensure animation starts - application.Render(2000u); // Halfway point - application.SendNotification(); + DALI_TEST_EQUALS(actor2.GetRendererCount(), 1u, TEST_LOCATION); - Vector4 color; - DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); - DALI_TEST_EQUALS(color.a, 0.55f, TEST_LOCATION); + // Testing for texture re-use in gl side is not relevant - we are not using actual graphics + // backend here, but test graphics backend. + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawArrays"), 2, TEST_LOCATION); - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); + tet_infoline("Test that removing 1 actor doesn't delete the texture\n"); - glEnableStack.Reset(); + application.GetScene().Remove(actor); + application.SendNotification(); + application.Render(); - application.Render(2016u); // end - application.SendNotification(); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); - DALI_TEST_EQUALS(color.a, 0.1f, TEST_LOCATION); + tet_infoline("Test that removing last actor does delete the texture\n"); - // (Don't test for caching of capabilities, toolkit uses Test graphics backend, not actual backend) - DALI_TEST_CHECK(!glEnableStack.FindMethodAndParams("Disable", blendStr.str())); - } + application.GetScene().Remove(actor2); // Detaches remaining ImageVisual + application.SendNotification(); + application.Render(); + + DALI_TEST_CHECK(actor2.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualAnimateOpacity02(void) +int UtcDaliImageVisualTextureReuse2(void) { ToolkitTestApplication application; - tet_infoline("Animate image visual opacity"); - - application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + tet_infoline("Request remote image visual with a Property::Map; request a second visual with the same url but different property map - should create new texture"); - VisualFactory factory = VisualFactory::Get(); Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMap.Insert("opacity", 0.5f); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); - Visual::Base visual = factory.CreateVisual(propertyMap); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_REMOTE_IMAGE_FILE_NAME); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& drawTrace = gl.GetDrawTrace(); + drawTrace.Enable(true); - actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); - actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + Actor actor = CreateActorWithImageVisual(propertyMap); + application.GetScene().Add(actor); + application.SendNotification(); - tet_infoline("Test that the opacity doesn't animate when actor not staged"); + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - Property::Array array; + application.SendNotification(); + application.Render(); - Property::Map map; - map["target"] = "testVisual"; - map["property"] = "opacity"; - map["initialValue"] = 0.0f; - map["targetValue"] = 1.0f; - map["animator"] = Property::Map() - .Add("alphaFunction", "LINEAR") - .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION); + textureTrace.Reset(); + drawTrace.Reset(); - Property::Map map2; - map2["target"] = "testVisual"; - map2["property"] = "size"; - map2["targetValue"] = Vector2(1.0f, 1.0f); + propertyMap.Insert(ImageVisual::Property::SAMPLING_MODE, Dali::SamplingMode::NEAREST); + propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, 100); + propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, 100); + Actor actor2 = CreateActorWithImageVisual(propertyMap); + application.GetScene().Add(actor2); - array.Add(map).Add(map2); + application.SendNotification(); - Dali::Toolkit::TransitionData transition = TransitionData::New(array); - Animation animation = dummyImpl.CreateTransition(transition); + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.GetScene().Add(actor); application.SendNotification(); - application.Render(0); // Ensure animation starts + application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor2.GetRendererCount(), 1u, TEST_LOCATION); - Renderer renderer = actor.GetRendererAt(0); - Property::Value blendModeValue = renderer.GetProperty(Renderer::Property::BLEND_MODE); - DALI_TEST_EQUALS(blendModeValue.Get(), (int)BlendMode::AUTO, TEST_LOCATION); + tet_infoline( + "Test that 2 draw calls occur with 1 new texture gen/bind, i.e. both " + "renderers are using different textures\n"); - animation = dummyImpl.CreateTransition(transition); - animation.Play(); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawArrays"), 2, TEST_LOCATION); + TraceCallStack::NamedParams tex1; + tex1["texture"] << 1; + TraceCallStack::NamedParams tex2; + tex2["texture"] << 2; + DALI_TEST_EQUALS(textureTrace.FindMethodAndParams("BindTexture", tex1), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethodAndParams("BindTexture", tex2), true, TEST_LOCATION); - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); - glAbstraction.EnableEnableDisableCallTrace(true); - TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); - std::ostringstream blendStr; - blendStr << std::hex << GL_BLEND; + tet_infoline("Test that removing 1 actor deletes it's texture\n"); + application.GetScene().Remove(actor); application.SendNotification(); - application.Render(0); // Ensure animation starts - application.Render(2000u); // Halfway point through animation - application.SendNotification(); // Handle any signals - - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); - - Vector4 color; - DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); - DALI_TEST_EQUALS(color.a, 0.5f, TEST_LOCATION); + application.Render(); - glEnableStack.Reset(); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); - application.Render(2001u); // end - application.SendNotification(); // ensure animation finished signal is sent + tet_infoline("Test that removing last actor deletes it's texture\n"); - DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); - DALI_TEST_EQUALS(color.a, 1.0f, TEST_LOCATION); + application.GetScene().Remove(actor2); + application.SendNotification(); + application.Render(); - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Disable", blendStr.str())); + DALI_TEST_CHECK(actor2.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 2, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualAnimatePixelArea(void) +int UtcDaliImageVisualCustomWrapModePixelArea(void) { ToolkitTestApplication application; - tet_infoline("ImageVisual animate pixel area"); + tet_infoline("Request image visual with a Property::Map, test custom wrap mode and pixel area with atlasing"); static std::vector customUniforms = { UniformData("pixelArea", Property::Type::VECTOR4), + UniformData("wrapMode", Property::Type::VECTOR2), }; TestGraphicsController& graphics = application.GetGraphicsController(); graphics.AddCustomUniforms(customUniforms); - application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); - VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + // Test wrap mode with atlasing. Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + const int width = 34; + const int height = 34; + const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); + Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMap.Insert("mixColor", Color::BLUE); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_SMALL_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, width); + propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, height); propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + propertyMap.Insert(ImageVisual::Property::PIXEL_AREA, pixelArea); + propertyMap.Insert(ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT); + propertyMap.Insert(ImageVisual::Property::WRAP_MODE_V, WrapMode::REPEAT); + propertyMap.Insert(ImageVisual::Property::ATLASING, true); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); + texParameterTrace.Enable(true); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - actor.SetProperty(Actor::Property::COLOR, Color::BLACK); application.GetScene().Add(actor); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - - Renderer renderer = actor.GetRendererAt(0); - // @todo Implement this feature? - //Property::Index index = renderer.GetPropertyIndex( Visual::Property::MIX_COLOR ); - //tet_infoline("Test that the renderer has the mixColor property"); - //DALI_TEST_CHECK( index != Property::INVALID_INDEX ); + // loading started + application.SendNotification(); + application.Render(); - // TransitionData only takes string keys - Property::Map map; - map["target"] = "testVisual"; - map["property"] = "pixelArea"; - map["initialValue"] = Vector4(0, 0, 0, 1); - map["targetValue"] = Vector4(0, 0, 1, 1); // Animate width from zero to full - map["animator"] = Property::Map() - .Add("alphaFunction", "LINEAR") - .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); - Dali::Toolkit::TransitionData transition = TransitionData::New(map); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - Animation animation = dummyImpl.CreateTransition(transition); - animation.AnimateTo(Property(actor, Actor::Property::COLOR), Color::WHITE); - animation.Play(); + // WITH atlasing, the wrapping is handled manually in shader, so the following gl function should not be called + std::stringstream out; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; + DALI_TEST_CHECK(!texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_REPEAT; + DALI_TEST_CHECK(!texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); - application.SendNotification(); - application.Render(0); // Ensure animation starts - application.Render(2000u); // Halfway point + // test the uniforms which used to handle the wrap mode + Renderer renderer = actor.GetRendererAt(0u); + DALI_TEST_CHECK(renderer); - DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 0.5f, 1.0f)), true, TEST_LOCATION); + Property::Value pixelAreaValue = renderer.GetProperty(renderer.GetPropertyIndex("pixelArea")); + DALI_TEST_EQUALS(pixelAreaValue.Get(), pixelArea, TEST_LOCATION); + Vector4 pixelAreaUniform; + DALI_TEST_CHECK(gl.GetUniformValue("pixelArea", pixelAreaUniform)); + DALI_TEST_EQUALS(pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); - application.Render(2000u); // End of animation + Property::Value wrapModeValue = renderer.GetProperty(renderer.GetPropertyIndex("wrapMode")); + Vector2 wrapMode(WrapMode::MIRRORED_REPEAT - 1, WrapMode::REPEAT - 1); + DALI_TEST_EQUALS(wrapModeValue.Get(), wrapMode, TEST_LOCATION); + Vector2 wrapModeUniform; + DALI_TEST_CHECK(gl.GetUniformValue("wrapMode", wrapModeUniform)); + DALI_TEST_EQUALS(wrapMode, wrapModeUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); - DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 1.0f, 1.0f)), true, TEST_LOCATION); + actor.Unparent(); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); END_TEST; } -int UtcDaliImageVisualTextureCancelRemoteLoad(void) + +int UtcDaliImageVisualCustomWrapModePixelArea02(void) { ToolkitTestApplication application; - tet_infoline("Request remote image visual, then destroy visual to cancel load"); + tet_infoline("Request image visual with a Property::Map, test custom wrap mode and pixel area"); + + static std::vector customUniforms = + { + UniformData("pixelArea", Property::Type::VECTOR4), + UniformData("wrapMode", Property::Type::VECTOR2), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + // Test wrap mode with atlasing. Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + const int width = 34; + const int height = 34; + const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_REMOTE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::URL, TEST_SMALL_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, width); + propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, height); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, false); + propertyMap.Insert(ImageVisual::Property::PIXEL_AREA, pixelArea); + propertyMap.Insert(ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT); + propertyMap.Insert(ImageVisual::Property::WRAP_MODE_V, WrapMode::CLAMP_TO_EDGE); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - TraceCallStack& drawTrace = gl.GetDrawTrace(); - drawTrace.Enable(true); - - Actor actor = CreateActorWithImageVisual(propertyMap); + TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); + texParameterTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); application.GetScene().Add(actor); + + // loading started application.SendNotification(); + application.Render(); + + // Wait image load complete. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.GetScene().Remove(actor); application.SendNotification(); + application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), false, TEST_LOCATION); - DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), false, TEST_LOCATION); + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + + // Following gl function should not be called + std::stringstream out; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; + DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_CLAMP_TO_EDGE; + DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); + + // test the uniforms which used to handle the wrap mode + Renderer renderer = actor.GetRendererAt(0u); + DALI_TEST_CHECK(renderer); + + Property::Value pixelAreaValue = renderer.GetProperty(renderer.GetPropertyIndex("pixelArea")); + DALI_TEST_EQUALS(pixelAreaValue.Get(), pixelArea, TEST_LOCATION); + Vector4 pixelAreaUniform; + DALI_TEST_CHECK(gl.GetUniformValue("pixelArea", pixelAreaUniform)); + DALI_TEST_EQUALS(pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); + + actor.Unparent(); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); END_TEST; } -int UtcDaliImageVisualTextureCancelAsyncLoad(void) +int UtcDaliImageVisualCustomWrapModeNoAtlas(void) { ToolkitTestApplication application; - tet_infoline("Load image asynchronously, cancel loading, then load again"); + tet_infoline("Request image visual with a Property::Map, test custom wrap mode and pixel area without atlasing"); + + static std::vector customUniforms = + { + UniformData("pixelArea", Property::Type::VECTOR4), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); VisualFactory factory = VisualFactory::Get(); DALI_TEST_CHECK(factory); + // Test wrap mode without atlasing. Image with a size bigger than 512*512 will NOT be uploaded as a part of the atlas. + const int width = 600; + const int height = 600; + const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f); + Property::Map propertyMap; propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, width); + propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, height); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + propertyMap.Insert(ImageVisual::Property::PIXEL_AREA, pixelArea); + propertyMap.Insert(ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT); + propertyMap.Insert(ImageVisual::Property::WRAP_MODE_V, WrapMode::REPEAT); Visual::Base visual = factory.CreateVisual(propertyMap); DALI_TEST_CHECK(visual); @@ -1426,1319 +1508,2723 @@ int UtcDaliImageVisualTextureCancelAsyncLoad(void) TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - TraceCallStack& drawTrace = gl.GetDrawTrace(); - drawTrace.Enable(true); + textureTrace.EnableLogging(true); + TraceCallStack& texParameterTrace = gl.GetTexParameterTrace(); + texParameterTrace.Enable(true); + texParameterTrace.EnableLogging(true); DummyControl actor = DummyControl::New(); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::Property::BACKGROUND, visual); - + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); application.GetScene().Add(actor); - // Cancel loading - application.GetScene().Remove(actor); + // loading started + application.SendNotification(); + application.Render(); + application.SendNotification(); - application.GetScene().Add(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); - // Create another visual with the same image - visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - dummyImpl.RegisterVisual(Control::Property::BACKGROUND, visual); + // WITHOUT atlasing, the wrapping is handled by setting gl texture parameters + std::stringstream out; + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT; + DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); + out.str(""); + out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_REPEAT; + DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str())); - application.SendNotification(); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // test the uniforms which used to handle the wrap mode + Renderer renderer = actor.GetRendererAt(0u); + DALI_TEST_CHECK(renderer); - application.SendNotification(); - application.Render(); + Property::Value pixelAreaValue = renderer.GetProperty(renderer.GetPropertyIndex("pixelArea")); + DALI_TEST_EQUALS(pixelAreaValue.Get(), pixelArea, TEST_LOCATION); + Vector4 pixelAreaUniform; + DALI_TEST_CHECK(gl.GetUniformValue("pixelArea", pixelAreaUniform)); + DALI_TEST_EQUALS(pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION); + Property::Index wrapModeIndex = renderer.GetPropertyIndex("wrapMode"); + DALI_TEST_CHECK(wrapModeIndex == Property::INVALID_INDEX); + + actor.Unparent(); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); END_TEST; } -int UtcDaliImageVisualSetInvalidAsyncImage(void) +int UtcDaliImageVisualAnimateMixColor(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with invalid images - should draw broken.png"); + tet_infoline("Animate mix color"); - VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); + static std::vector customUniforms = + { + UniformData("mixColor", Property::Type::VECTOR3), + }; - Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_INVALID_FILE_NAME); + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert("mixColor", Color::BLUE); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + application.GetScene().Add(actor); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - application.GetScene().Add(actor); + Renderer renderer = actor.GetRendererAt(0); - application.SendNotification(); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // @todo Should we add API to make this code work again? + // Property::Index index = renderer.GetPropertyIndex( Visual::Property::MIX_COLOR ); - application.SendNotification(); - application.Render(); + Property::Value blendModeValue = renderer.GetProperty(Renderer::Property::BLEND_MODE); + DALI_TEST_EQUALS(blendModeValue.Get(), (int)BlendMode::AUTO, TEST_LOCATION); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + const Vector4 TARGET_MIX_COLOR(1.0f, 0.0f, 0.0f, 0.5f); - application.GetScene().Remove(actor); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + Property::Map map; + map["target"] = "testVisual"; + map["property"] = "mixColor"; + map["initialValue"] = Color::MAGENTA; + map["targetValue"] = TARGET_MIX_COLOR; + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); - END_TEST; -} + Dali::Toolkit::TransitionData transition = TransitionData::New(map); -int UtcDaliImageVisualSetInvalidSyncImage(void) -{ - ToolkitTestApplication application; - tet_infoline("Request image visual with invalid images - should draw broken.png"); + Animation animation = dummyImpl.CreateTransition(transition); - VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); + animation.AnimateTo(Property(actor, Actor::Property::COLOR), Color::WHITE); + animation.Play(); - Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_INVALID_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + glAbstraction.EnableEnableDisableCallTrace(true); + TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); + std::ostringstream blendStr; + blendStr << std::hex << GL_BLEND; - Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point + Vector3 testColor(1.0f, 0.0f, 0.5f); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + // uColor.a should be actor's alpha * mixColor.a. + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("uColor", Vector4(0.5f, 0.5f, 0.5f, 0.75f)), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("mixColor", testColor), true, TEST_LOCATION); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + glEnableStack.Reset(); - application.GetScene().Add(actor); + application.SendNotification(); + application.Render(2000u); application.SendNotification(); application.Render(); + application.SendNotification(); - // Check resource status - Visual::ResourceStatus status = actor.GetVisualResourceStatus(Control::CONTROL_PROPERTY_END_INDEX + 1); - DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetCurrentProperty(Actor::Property::COLOR), Color::WHITE, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("uColor", Vector4(1.0f, 1.0f, 1.0f, 0.5f)), true, TEST_LOCATION); + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("mixColor", Vector3(TARGET_MIX_COLOR)), true, TEST_LOCATION); - // The broken image should be shown. - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + // (Don't test for caching of capabilities, toolkit uses Test graphics backend, not actual backend) - application.GetScene().Remove(actor); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + TestMixColor(visual, Visual::Property::MIX_COLOR, TARGET_MIX_COLOR); END_TEST; } -int UtcDaliImageVisualSetInvalidRemoteImage(void) +int UtcDaliImageVisualAnimateOpacity(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with invalid images - should draw broken.png"); + tet_infoline("Animate image visual opacity"); - VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); - // Local invalid file, asynchronous loading + VisualFactory factory = VisualFactory::Get(); Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_REMOTE_INVALID_FILE_NAME); - + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert("opacity", 0.5f); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + application.GetScene().Add(actor); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + glAbstraction.EnableEnableDisableCallTrace(true); + TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); + std::ostringstream blendStr; + blendStr << std::hex << GL_BLEND; + + application.SendNotification(); + application.Render(); + + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); + + { + tet_infoline("Test that the opacity can be increased to full via animation, and that the blend mode is set appropriately at the start and end of the animation."); + + Property::Map map; + map["target"] = "testVisual"; + map["property"] = "opacity"; + map["targetValue"] = 1.0f; + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New(map); + Animation animation = dummyImpl.CreateTransition(transition); + animation.Play(); + + glEnableStack.Reset(); + + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point through animation + application.SendNotification(); // Handle any signals + + Vector4 color; + DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); + DALI_TEST_EQUALS(color.a, 0.75f, TEST_LOCATION); + + application.Render(2001u); // end + application.SendNotification(); // ensure animation finished signal is sent + + DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); + DALI_TEST_EQUALS(color.a, 1.0f, TEST_LOCATION); + + // (Don't test for caching of capabilities, toolkit uses Test graphics backend, not actual backend) + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Disable", blendStr.str())); + } + + { + tet_infoline("Test that the opacity can be reduced via animation, and that the blend mode is set appropriately at the start and end of the animation."); + + Property::Map map; + map["target"] = "testVisual"; + map["property"] = Visual::Property::OPACITY; + map["targetValue"] = 0.1f; + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New(map); + Animation animation = dummyImpl.CreateTransition(transition); + animation.Play(); + + glEnableStack.Reset(); + + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point + application.SendNotification(); + + Vector4 color; + DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); + DALI_TEST_EQUALS(color.a, 0.55f, TEST_LOCATION); + + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); + + glEnableStack.Reset(); + + application.Render(2016u); // end + application.SendNotification(); + + DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); + DALI_TEST_EQUALS(color.a, 0.1f, TEST_LOCATION); + + // (Don't test for caching of capabilities, toolkit uses Test graphics backend, not actual backend) + DALI_TEST_CHECK(!glEnableStack.FindMethodAndParams("Disable", blendStr.str())); + } + + END_TEST; +} + +int UtcDaliImageVisualAnimateOpacity02(void) +{ + ToolkitTestApplication application; + tet_infoline("Animate image visual opacity"); + + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert("opacity", 0.5f); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + Visual::Base visual = factory.CreateVisual(propertyMap); + + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + + tet_infoline("Test that the opacity doesn't animate when actor not staged"); + + Property::Array array; + + Property::Map map; + map["target"] = "testVisual"; + map["property"] = "opacity"; + map["initialValue"] = 0.0f; + map["targetValue"] = 1.0f; + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + + Property::Map map2; + map2["target"] = "testVisual"; + map2["property"] = "size"; + map2["targetValue"] = Vector2(1.0f, 1.0f); + + array.Add(map).Add(map2); + + Dali::Toolkit::TransitionData transition = TransitionData::New(array); + Animation animation = dummyImpl.CreateTransition(transition); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(0); // Ensure animation starts + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + + Renderer renderer = actor.GetRendererAt(0); + Property::Value blendModeValue = renderer.GetProperty(Renderer::Property::BLEND_MODE); + DALI_TEST_EQUALS(blendModeValue.Get(), (int)BlendMode::AUTO, TEST_LOCATION); + + animation = dummyImpl.CreateTransition(transition); + animation.Play(); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + glAbstraction.EnableEnableDisableCallTrace(true); + TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); + std::ostringstream blendStr; + blendStr << std::hex << GL_BLEND; + + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point through animation + application.SendNotification(); // Handle any signals + + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); + + Vector4 color; + DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); + DALI_TEST_EQUALS(color.a, 0.5f, TEST_LOCATION); + + glEnableStack.Reset(); + + application.Render(2001u); // end + application.SendNotification(); // ensure animation finished signal is sent + + DALI_TEST_CHECK(application.GetGlAbstraction().GetUniformValue("uColor", color)); + DALI_TEST_EQUALS(color.a, 1.0f, TEST_LOCATION); + + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Disable", blendStr.str())); + + END_TEST; +} + +int UtcDaliImageVisualAnimatePixelArea(void) +{ + ToolkitTestApplication application; + tet_infoline("ImageVisual animate pixel area"); + + static std::vector customUniforms = + { + UniformData("pixelArea", Property::Type::VECTOR4), + }; + + TestGraphicsController& graphics = application.GetGraphicsController(); + graphics.AddCustomUniforms(customUniforms); + + application.GetPlatform().SetClosestImageSize(Vector2(100, 100)); + + VisualFactory factory = VisualFactory::Get(); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert("mixColor", Color::BLUE); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + Visual::Base visual = factory.CreateVisual(propertyMap); + + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000)); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::COLOR, Color::BLACK); + application.GetScene().Add(actor); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + + Renderer renderer = actor.GetRendererAt(0); + // @todo Implement this feature? + //Property::Index index = renderer.GetPropertyIndex( Visual::Property::MIX_COLOR ); + //tet_infoline("Test that the renderer has the mixColor property"); + //DALI_TEST_CHECK( index != Property::INVALID_INDEX ); + + // TransitionData only takes string keys + Property::Map map; + map["target"] = "testVisual"; + map["property"] = "pixelArea"; + map["initialValue"] = Vector4(0, 0, 0, 1); + map["targetValue"] = Vector4(0, 0, 1, 1); // Animate width from zero to full + map["animator"] = Property::Map() + .Add("alphaFunction", "LINEAR") + .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 4.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New(map); + + Animation animation = dummyImpl.CreateTransition(transition); + animation.AnimateTo(Property(actor, Actor::Property::COLOR), Color::WHITE); + animation.Play(); + + application.SendNotification(); + application.Render(0); // Ensure animation starts + application.Render(2000u); // Halfway point + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 0.5f, 1.0f)), true, TEST_LOCATION); + + application.Render(2000u); // End of animation + + DALI_TEST_EQUALS(application.GetGlAbstraction().CheckUniformValue("pixelArea", Vector4(0.0f, 0.0f, 1.0f, 1.0f)), true, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualTextureCancelRemoteLoad(void) +{ + ToolkitTestApplication application; + tet_infoline("Request remote image visual, then destroy visual to cancel load"); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_REMOTE_IMAGE_FILE_NAME); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& drawTrace = gl.GetDrawTrace(); + drawTrace.Enable(true); + + Actor actor = CreateActorWithImageVisual(propertyMap); + application.GetScene().Add(actor); + application.SendNotification(); + + application.GetScene().Remove(actor); + application.SendNotification(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), false, TEST_LOCATION); + DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), false, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualTextureCancelAsyncLoad(void) +{ + ToolkitTestApplication application; + tet_infoline("Load image asynchronously, cancel loading, then load again"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + TraceCallStack& drawTrace = gl.GetDrawTrace(); + drawTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::Property::BACKGROUND, visual); + + application.GetScene().Add(actor); + + // Cancel loading + application.GetScene().Remove(actor); + + application.GetScene().Add(actor); + + // Create another visual with the same image + visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + dummyImpl.RegisterVisual(Control::Property::BACKGROUND, visual); + + application.SendNotification(); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(drawTrace.FindMethod("DrawArrays"), true, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualSetInvalidAsyncImage(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with invalid images - should draw broken.png"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_INVALID_FILE_NAME); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); + + application.SendNotification(); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + + application.GetScene().Remove(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + + END_TEST; +} + +int UtcDaliImageVisualSetInvalidSyncImage(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with invalid images - should draw broken.png"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_INVALID_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); + + application.SendNotification(); + application.Render(); + + // Check resource status + Visual::ResourceStatus status = actor.GetVisualResourceStatus(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(status, Visual::ResourceStatus::FAILED, TEST_LOCATION); + + // The broken image should be shown. + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + + application.GetScene().Remove(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + + END_TEST; +} + +int UtcDaliImageVisualSetInvalidRemoteImage(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with invalid images - should draw broken.png"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + // Local invalid file, asynchronous loading + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_REMOTE_INVALID_FILE_NAME); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); + + application.SendNotification(); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + + application.GetScene().Remove(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + + END_TEST; +} + +int UtcDaliImageVisualSetInvalidImageWithDisabledBroken(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with invalid images - should draw broken.png"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + // Load invalid file + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, "InvalidImage.png"); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); + + application.SendNotification(); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + + application.GetScene().Remove(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + textureTrace.Reset(); + + // Load invalid file with disabled broken + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, "InvalidImage.png"); + propertyMap.Insert(Toolkit::DevelImageVisual::Property::ENABLE_BROKEN_IMAGE, false); + + visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + actor = DummyControl::New(); + DummyControlImpl& dummyImpl2 = static_cast(actor.GetImplementation()); + dummyImpl2.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); + + application.SendNotification(); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), false, TEST_LOCATION); + + application.GetScene().Remove(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + + END_TEST; +} + +int UtcDaliImageVisualAlphaMask01(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualAlphaMask02(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + propertyMap.Insert(DevelImageVisual::Property::CROP_TO_MASK, false); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + DALI_TEST_EQUALS(*testMap.Find(DevelImageVisual::Property::MASKING_TYPE), Property::Value(DevelImageVisual::MaskingType::MASKING_ON_RENDERING), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0u); + TextureSet textures = renderer.GetTextures(); + DALI_TEST_CHECK(textures); + DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + auto index = renderer.GetPropertyIndex("maskTextureRatio"); + DALI_TEST_NOT_EQUALS(index, Property::INVALID_INDEX, 0.1f, TEST_LOCATION); + DALI_TEST_EQUALS(renderer.GetProperty(index), Vector2::ONE, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualAlphaMask03(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with fail case"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "dummy_path"); + propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0u); + TextureSet textures = renderer.GetTextures(); + DALI_TEST_CHECK(textures); + DALI_TEST_EQUALS(textures.GetTextureCount(), 1u, TEST_LOCATION); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualSynchronousLoadAlphaMask01(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask with synchronous loading"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Do not wait for any EventThreadTrigger in synchronous alpha mask. + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualSynchronousLoadAlphaMask02(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask for GPU with synchronous loading"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Do not wait for any EventThreadTrigger in synchronous alpha mask. + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + Renderer renderer = actor.GetRendererAt(0u); + TextureSet textures = renderer.GetTextures(); + DALI_TEST_CHECK(textures); + DALI_TEST_EQUALS(textures.GetTextureCount(), 2u, TEST_LOCATION); + + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualRemoteAlphaMask(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with a Property::Map containing an Alpha mask"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + const std::string MASK_IMAGE = TEST_REMOTE_IMAGE_FILE_NAME; + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, MASK_IMAGE); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(MASK_IMAGE), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualAlphaMaskCrop(void) +{ + ToolkitTestApplication application; + tet_infoline("Request image visual with an Alpha mask and scale/cropping"); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::MASK_CONTENT_SCALE, 1.6f); + propertyMap.Insert(ImageVisual::Property::CROP_TO_MASK, true); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + Property::Map testMap; + visual.CreatePropertyMap(testMap); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE), Property::Value(1.6f), TEST_LOCATION); + DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::CROP_TO_MASK), Property::Value(true), TEST_LOCATION); + + // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. + // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + + application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + Vector2 size; + visual.GetNaturalSize(size); + + DALI_TEST_EQUALS(size, Vector2(100.0f, 100.0f), 0.001f, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy01 Detached Policy, disabling visual with this policy deletes texture"); + + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DETACHED); + DALI_TEST_CHECK(imageVisual); + + // Set up debug trace + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visual with control and ensure it has the only handle"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + // Test renderer and texture created + tet_infoline("Confirm texture created"); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + tet_infoline("Disable visual causing the texture to be deleted"); + dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, false); + + application.SendNotification(); + application.Render(0); + // Test renderer and textures removed. + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy02(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy02 Destroyed Policy, Texture should be deleted when visual destroyed"); + + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + DALI_TEST_CHECK(imageVisual); + + // Setup debug trace + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visual with control and ensure it has the only handle"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + // Test renderer and texture created + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed"); + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); + application.Render(); + + // Test texture removed after visual destroyed. + tet_infoline("Ensure texture is deleted after visual destroyed"); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy03(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy03 Never Policy, texture should not be deleted after visual destroyed"); + + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER); + DALI_TEST_CHECK(imageVisual); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visual with control and ensure it has the only handle"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + // Test renderer and texture created + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed"); + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); + application.Render(); + + tet_infoline("Ensure texture is not deleted as policy is set to NEVER"); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy04(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy04 Two visuals with different policies sharing a texture"); + + tet_infoline("Create first visual with Never release policy"); + Visual::Base imageVisualNever = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER); + + tet_infoline("Create second visual with Destroyed release policy"); + Visual::Base imageVisualDestroyed = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visuals with control and ensure it has the only handles"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisualNever); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, imageVisualDestroyed); + imageVisualNever.Reset(); // reduce ref count so only the control keeps the visual alive. + imageVisualDestroyed.Reset(); // reduce ref count so only the control keeps the visual alive. + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + // Test initially zero renderers + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + tet_infoline("Ensure a texture is created, shared amongst both visuals. Each visual has its own renderer"); + DALI_TEST_EQUALS(actor.GetRendererCount(), 2u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + // Test renderer removed when visual destroyed + DALI_TEST_CHECK(actor.GetRendererCount() == 2u); + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL2); // TEST_VISUAL2 no longer requires the texture as release policy DESTROYED + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + application.SendNotification(); + application.Render(); + + // Test texture was not deleted as TEST_VISUAL release policy is NEVER so it is still required. + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); + application.Render(); + + tet_infoline("Ensure a texture is not deleted as second visual used the NEVER release policy"); + // Test texture was not deleted as TEST_VISUAL release policy is NEVER so it is still required. + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy05(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy05 Testing settung by string currents correct enum"); + + VisualFactory factory = VisualFactory::Get(); + + Property::Map propertyMapNeverReleasePolicy; + propertyMapNeverReleasePolicy.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMapNeverReleasePolicy.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMapNeverReleasePolicy.Insert(ImageVisual::Property::DESIRED_WIDTH, 20); + propertyMapNeverReleasePolicy.Insert(ImageVisual::Property::DESIRED_HEIGHT, 30); + propertyMapNeverReleasePolicy.Insert("releasePolicy", "never"); + + Visual::Base imageVisualNever = factory.CreateVisual(propertyMapNeverReleasePolicy); + + Property::Map resultMap; + imageVisualNever.CreatePropertyMap(resultMap); + DALI_TEST_CHECK(!resultMap.Empty()); + + DALI_TEST_EQUALS((resultMap.Find(ImageVisual::Property::RELEASE_POLICY))->Get(), (int)ImageVisual::ReleasePolicy::NEVER, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy06(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy06 Never Policy, texture should not be affected by Disabling and Enabling visual"); + + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER); + DALI_TEST_CHECK(imageVisual); TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + tet_infoline("Register visual with control and ensure it has the only handle"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); application.GetScene().Add(actor); + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + // Test renderer and texture created + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + textureTrace.Reset(); + + tet_infoline("Disable Visual and check texture not affected"); + dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, false); + application.SendNotification(); + application.Render(0); + tet_infoline("Check renderer is destroyed when visual off stage"); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + textureTrace.Reset(); + + tet_infoline("Re-enable Visual and check texture not affected"); + dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, true); + application.SendNotification(); + application.Render(0); + tet_infoline("Check texture not affected and renderer is destroyed when visual off stage"); + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy07(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy07 Two visuals with different policies sharing a texture DETACHED and DESTROYED"); + + tet_infoline("Create first visual with DESTROYED release policy"); + Visual::Base imageVisualDestroyed = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + + tet_infoline("Create second visual with DETACHED release policy"); + Visual::Base imageVisualDetached = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DETACHED); + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visuals with control and ensure it has the only handles"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisualDestroyed); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, imageVisualDetached); + imageVisualDestroyed.Reset(); // reduce ref count so only the control keeps the visual alive. + imageVisualDetached.Reset(); // reduce ref count so only the control keeps the visual alive. + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + // Test initially zero renderers application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Wait for image to load DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); + application.Render(0); + tet_infoline("Ensure a texture is created, shared amongst both visuals. Each visual has its own renderer"); + DALI_TEST_EQUALS(actor.GetRendererCount(), 2u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + // Test renderer removed when visual destroyed + DALI_TEST_CHECK(actor.GetRendererCount() == 2u); + dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL2, false); // TEST_VISUAL2 no longer requires the texture as release policy DETACHED + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + application.SendNotification(); + application.Render(); + + // Test texture was not deleted as TEST_VISUAL release policy is DESTROYED and is still required. + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + + dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, false); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); application.Render(); + tet_infoline("Ensure a texture is not deleted as second visual used the DESTROYED release policy"); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualReleasePolicy08(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualReleasePolicy08 Ensure TextureSet is same after detach/attach on stage when texture used the DESTROYED release policy"); + + tet_infoline("Create first visual with DESTROYED release policy"); + Visual::Base imageVisualDestroyed = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visuals with control and ensure it has the only handles"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisualDestroyed); + imageVisualDestroyed.Reset(); // reduce ref count so only the control keeps the visual alive. + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + // Test initially zero renderers + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + textureTrace.Reset(); + + application.GetScene().Add(actor); + + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + tet_infoline("Ensure a texture is created"); DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + textureTrace.Reset(); + // Ensure Texture is same after detach/attach on stage when texture used the DESTROYED release policy + // 1. Get Texture + Texture textureBefore = actor.GetRendererAt(0u).GetTextures().GetTexture(0u); + + // 2.Remove actor from stage. In this case, renderer also is deleted. + tet_infoline("Remove actor from stage"); application.GetScene().Remove(actor); DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); + application.Render(); + + tet_infoline("Ensure a texture is not deleted as visual used the DESTROYED release policy"); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + textureTrace.Reset(); + + // 3.Add actor in stage. In this case, renderer is created. + tet_infoline("Add actor in stage"); + application.GetScene().Add(actor); + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + application.SendNotification(); + application.Render(); + tet_infoline("Ensure a texture is not created again"); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); + textureTrace.Reset(); + + // 4.Compare Texture with before and after. texture need to be same because release policy is the DESTROYED. + tet_infoline("Ensure a texture is not deleted because it is used the DESTROYED release policy"); + Texture textureAfter = actor.GetRendererAt(0u).GetTextures().GetTexture(0u); + DALI_TEST_CHECK(textureBefore == textureAfter); + textureBefore.Reset(); + textureAfter.Reset(); + + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualAlphaMask(void) +int UtcDaliImageVisualReleasePolicy09(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with a Property::Map containing an Alpha mask"); + tet_infoline("UtcDaliImageVisualReleasePolicy09 Destroyed Policy with N-Patch, Texture should be deleted when visual destroyed"); + + Property::Map propertyMapNPatchReleasePolicy; + propertyMapNPatchReleasePolicy.Insert(Visual::Property::TYPE, Visual::N_PATCH); + propertyMapNPatchReleasePolicy.Insert(ImageVisual::Property::URL, TEST_N_PATCH_IMAGE_FILE_NAME); + propertyMapNPatchReleasePolicy.Insert(DevelImageVisual::Property::AUXILIARY_IMAGE, TEST_MASK_IMAGE_FILE_NAME); + propertyMapNPatchReleasePolicy.Insert(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA, 0.9f); + propertyMapNPatchReleasePolicy.Insert(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + VisualFactory factory = VisualFactory::Get(); + Visual::Base imageVisual = factory.CreateVisual(propertyMapNPatchReleasePolicy); + DALI_TEST_CHECK(imageVisual); + + // Setup debug trace + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Register visual with control and ensure it has the only handle"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + application.SendNotification(); + application.Render(0); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + application.GetScene().Add(actor); + + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(0); + // Test renderer and texture created + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed"); + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + DALI_TEST_CHECK(actor.GetRendererCount() == 0u); + application.SendNotification(); + application.Render(); + + // Test texture removed after visual destroyed. + tet_infoline("Ensure texture is deleted after visual destroyed"); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 2, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliImageVisualLoadPolicy01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualLoadPolicy01 Load a visual image before attaching to stage"); + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + tet_infoline("Create visual with IMMEDIATE load policy"); VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, 20); + propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, 30); + propertyMap.Insert("loadPolicy", ImageVisual::LoadPolicy::IMMEDIATE); - Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); + Visual::Base imageVisual = factory.CreateVisual(propertyMap); - Property::Map testMap; - visual.CreatePropertyMap(testMap); - DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + Property::Map resultMap; + imageVisual.CreatePropertyMap(resultMap); + DALI_TEST_CHECK(!resultMap.Empty()); + DALI_TEST_EQUALS((resultMap.Find(ImageVisual::Property::LOAD_POLICY))->Get(), (int)ImageVisual::LoadPolicy::IMMEDIATE, TEST_LOCATION); - // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. - // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + // Ensure texture has been uploaded + application.SendNotification(); + application.Render(); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + tet_infoline("Ensure texture loading starts after visual created"); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + textureTrace.Reset(); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); + tet_infoline("Register visuals with control and ensure it has the only handles"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); application.GetScene().Add(actor); + tet_infoline("Ensure nothing triggers another load as texure already loaded"); + const unsigned int TIME_OUT_3_SECONDS = 3; + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, TIME_OUT_3_SECONDS), false, TEST_LOCATION); + application.SendNotification(); application.Render(); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + + // Ensure texture is deleted when no longer needed (ref count was correct ) + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); application.SendNotification(); application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); - - dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualSynchronousLoadAlphaMask(void) +int UtcDaliImageVisualLoadPolicy02(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with a Property::Map containing an Alpha mask with synchronous loading"); - - VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); + tet_infoline("UtcDaliImageVisualLoadPolicy01 Load a visual image only after attached to stage"); - Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); + tet_infoline("Create visual with IMMEDIATE load policy"); + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::ATTACHED); - Property::Map testMap; - visual.CreatePropertyMap(testMap); - DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); + const unsigned int TIME_OUT_3_SECONDS = 3; + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, TIME_OUT_3_SECONDS), false, TEST_LOCATION); - // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. - // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + // Act on meeage queue even although nothing expected to load + application.SendNotification(); + application.Render(); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + tet_infoline("Ensure texture is not generated yet"); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + textureTrace.Reset(); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + tet_infoline("Register visuals with control and ensure it has the only handles"); + DummyControl actor = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); - application.GetScene().Add(actor); - - // Do not wait for any EventThreadTrigger in synchronous alpha mask. + tet_infoline("Allow image time to load"); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); + tet_infoline("Ensure texture generated and renderer created"); DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + + // Ensure texture is delete when no longer needed + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + + application.SendNotification(); + application.Render(); - dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1); DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualRemoteAlphaMask(void) +int UtcDaliImageVisualLoadPolicy03(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with a Property::Map containing an Alpha mask"); - - VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); - - const std::string MASK_IMAGE = TEST_REMOTE_IMAGE_FILE_NAME; - - Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, MASK_IMAGE); - - Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); - - Property::Map testMap; - visual.CreatePropertyMap(testMap); - - DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(MASK_IMAGE), TEST_LOCATION); + tet_infoline("UtcDaliImageVisualLoadPolicy03 Load a visual image and receive ResourceReady Signal when loaded"); - // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. - // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + const bool VISUAL_NOT_ENABLED(false); // Instead of just passing 'false' into an API. + // Set up trace debug TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - - DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); - + tet_infoline("Create a control and connect to resource ready signal without adding to stage"); + DummyControl actor = DummyControl::New(true); + actor.ResourceReadySignal().Connect(&ResourceReadySignal); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - application.GetScene().Add(actor); - application.SendNotification(); - application.Render(); + tet_infoline("Create visual with IMMEDIATE load policy"); + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + tet_infoline("Registering visual allows control to get a signal once loaded even if visual not enabled( not staged )"); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + tet_infoline("Allow image time to load resource"); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + // Ensure texture has been uploaded + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualAlphaMaskCrop(void) +int UtcDaliImageVisualLoadPolicy04(void) { ToolkitTestApplication application; - tet_infoline("Request image visual with an Alpha mask and scale/cropping"); - - VisualFactory factory = VisualFactory::Get(); - DALI_TEST_CHECK(factory); - - Property::Map propertyMap; - propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_LARGE_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::MASK_CONTENT_SCALE, 1.6f); - propertyMap.Insert(ImageVisual::Property::CROP_TO_MASK, true); - - Visual::Base visual = factory.CreateVisual(propertyMap); - DALI_TEST_CHECK(visual); - - Property::Map testMap; - visual.CreatePropertyMap(testMap); - DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION); - DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::MASK_CONTENT_SCALE), Property::Value(1.6f), TEST_LOCATION); - DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::CROP_TO_MASK), Property::Value(true), TEST_LOCATION); + tet_infoline("UtcDaliImageVisualLoadPolicy04 First part Load a visual image before attaching to stage"); + tet_infoline("Second part, Reuse the same image in aonther control and check resource ready signal fired"); - // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied. - // Image with a size smaller than 512*512 will be uploaded as a part of the atlas. + const bool VISUAL_NOT_ENABLED(false); // Instead of just passing false into an API. + // Set up trace debug TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - DummyControl actor = DummyControl::New(); - DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); - + tet_infoline("Create a control and connect to resource ready signal"); + DummyControl actor = DummyControl::New(true); + actor.ResourceReadySignal().Connect(&ResourceReadySignal); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), false, TEST_LOCATION); - application.GetScene().Add(actor); - application.SendNotification(); - application.Render(); + tet_infoline("Create visual with IMMEDIATE load policy"); + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + tet_infoline("Registering visual allows control to get a signal once loaded even if visual not enabled( staged )"); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + tet_infoline("Allow image time to load"); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); - Vector2 size; - visual.GetNaturalSize(size); + tet_infoline("Testing texture is loaded and resource ready signal fired"); + DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION); - DALI_TEST_EQUALS(size, Vector2(100.0f, 100.0f), 0.001f, TEST_LOCATION); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION); - DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + tet_infoline("Original control correctly signalled, now testing for signal with new Control reusing the image"); + + gResourceReadySignalFired = false; // Reset signal check ready for testing next Control + Visual::Base imageVisual2 = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); + DummyControl actor2 = DummyControl::New(true); + Impl::DummyControl& dummyImpl2 = static_cast(actor.GetImplementation()); + actor2.ResourceReadySignal().Connect(&ResourceReadySignal); + + tet_infoline("Registering visual this should trigger the loading signal as is already image loaded for previous control"); + dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2); + imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive. + actor2.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(0), true, TEST_LOCATION); // Not expecting any further loading as texture is being reused. + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualReleasePolicy01(void) +int UtcDaliImageVisualLoadPolicy05(void) { ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy01 Detached Policy, disabling visual with this policy deletes texture"); - - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DETACHED); - DALI_TEST_CHECK(imageVisual); - - // Set up debug trace - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); - - tet_infoline("Register visual with control and ensure it has the only handle"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); + tet_infoline("UtcDaliImageVisualLoadPolicy05 LoadPolicy::ATTACHED (default) First part Load a visual image before attaching to stage"); + tet_infoline("Second part, Reuse the same image in aonther control and check resource ready signal fired"); + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + tet_infoline("Create a control and connect to resource ready signal"); + DummyControl actor = DummyControl::New(true); + actor.ResourceReadySignal().Connect(&ResourceReadySignal); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor); - application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + tet_infoline("Create visual with ATTACHED load policy"); + Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::ATTACHED); - application.GetScene().Add(actor); + tet_infoline("Registering visual allows control to get a signal once loaded"); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. - // Wait for image to load + tet_infoline("Allow image time to load"); DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.SendNotification(); - application.Render(0); - // Test renderer and texture created - tet_infoline("Confirm texture created"); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + application.Render(); + + tet_infoline("Testing texture is loaded and resource ready signal fired"); DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); - tet_infoline("Disable visual causing the texture to be deleted"); - dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, false); + tet_infoline("Original control correctly signalled, now testing for signal with new Control reusing the image"); - application.SendNotification(); - application.Render(0); - // Test renderer and textures removed. - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + gResourceReadySignalFired = false; // Reset signal check ready for testing next Control + Visual::Base imageVisual2 = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::ATTACHED); + DummyControl actor2 = DummyControl::New(true); + Impl::DummyControl& dummyImpl2 = static_cast(actor.GetImplementation()); + actor2.ResourceReadySignal().Connect(&ResourceReadySignal); + + tet_infoline("Registering visual this should trigger the loading signal as is already image loaded for previous control"); + dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2); + imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive. + actor2.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(0), true, TEST_LOCATION); // Not expecting any further loading as texture is being reused. + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualReleasePolicy02(void) +int UtcDaliImageVisualOrientationCorrection(void) { ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy02 Destroyed Policy, Texture should be deleted when visual destroyed"); - - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); - DALI_TEST_CHECK(imageVisual); + tet_infoline("UtcDaliImageVisualOrientationCorrection Enabling OrientationCorrection should rotate an image with exif (90deg) orientation data with requested"); - // Setup debug trace - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + VisualFactory factory = VisualFactory::Get(); + tet_infoline("Create visual with Orientation correction set OFF"); + Property::Map propertyMap; + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_ROTATED_IMAGE); + propertyMap.Insert("orientationCorrection", false); + Visual::Base imageVisual = factory.CreateVisual(propertyMap); - tet_infoline("Register visual with control and ensure it has the only handle"); + tet_infoline("Create control for visual, need to loaded it"); DummyControl actor = DummyControl::New(true); Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + application.GetScene().Add(actor); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); + // Wait for image to load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + Vector2 originalImageSize; + tet_infoline("Get size of original visual to compare later with rotated image"); + imageVisual.GetNaturalSize(originalImageSize); + DALI_TEST_GREATER(originalImageSize.width, originalImageSize.height, TEST_LOCATION); // Width and Height must be different for this test. + imageVisual.Reset(); // remove handle so can unregister it and remove from cache + dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + application.Render(); - application.GetScene().Add(actor); + tet_infoline("Create visual with Orientation correction set ON "); + propertyMap.Clear(); + propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_ROTATED_IMAGE); + propertyMap.Insert(ImageVisual::Property::ORIENTATION_CORRECTION, true); + imageVisual = factory.CreateVisual(propertyMap); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); // Wait for image to load DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.SendNotification(); - application.Render(0); - // Test renderer and texture created - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + Vector2 rotatedImageSize; + imageVisual.GetNaturalSize(rotatedImageSize); + tet_infoline("Confirm that visual has rotated"); + DALI_TEST_EQUALS(originalImageSize.width, rotatedImageSize.height, TEST_LOCATION); + DALI_TEST_EQUALS(originalImageSize.height, rotatedImageSize.width, TEST_LOCATION); - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); - tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed"); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - application.SendNotification(); - application.Render(); + Property::Map resultMap; + imageVisual.CreatePropertyMap(resultMap); - // Test texture removed after visual destroyed. - tet_infoline("Ensure texture is deleted after visual destroyed"); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + // check the Property::ORIENTATION_CORRECTION value from the returned map + Property::Value* typeValue = resultMap.Find(ImageVisual::Property::ORIENTATION_CORRECTION, Property::BOOLEAN); + DALI_TEST_EQUALS(typeValue->Get(), true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualReleasePolicy03(void) +int UtcDaliImageVisualCustomShader(void) { ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy03 Never Policy, texture should not be deleted after visual destroyed"); + tet_infoline("UtcDaliImageVisualCustomShader Test custom shader"); - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER); - DALI_TEST_CHECK(imageVisual); + VisualFactory factory = VisualFactory::Get(); + Property::Map properties; + Property::Map shader; + const std::string vertexShader = "Foobar"; + const std::string fragmentShader = "Foobar"; + shader[Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader; + shader[Visual::Shader::Property::VERTEX_SHADER] = vertexShader; - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + properties[Visual::Property::TYPE] = Visual::IMAGE; + properties[Visual::Property::SHADER] = shader; + properties[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; - tet_infoline("Register visual with control and ensure it has the only handle"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + Visual::Base visual = factory.CreateVisual(properties); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + // trigger creation through setting on stage + DummyControl dummy = DummyControl::New(true); + Impl::DummyControl& dummyImpl = static_cast(dummy.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); - application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + dummy.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + dummy.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + application.GetScene().Add(dummy); - application.GetScene().Add(actor); + application.SendNotification(); + application.Render(); - // Wait for image to load DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.SendNotification(); - application.Render(0); - // Test renderer and texture created - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + Renderer renderer = dummy.GetRendererAt(0); + Shader shader2 = renderer.GetShader(); + Property::Value value = shader2.GetProperty(Shader::Property::PROGRAM); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK(map); + + Property::Value* fragment = map->Find("fragment"); // fragment key name from shader-impl.cpp + DALI_TEST_EQUALS(fragmentShader, fragment->Get(), TEST_LOCATION); + + Property::Value* vertex = map->Find("vertex"); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS(vertexShader, vertex->Get(), TEST_LOCATION); + + shader.Clear(); + + shader[Visual::Shader::Property::HINTS] = Shader::Hint::OUTPUT_IS_TRANSPARENT; + properties[Visual::Property::SHADER] = shader; + + Visual::Base visual1 = factory.CreateVisual(properties); + + // trigger creation through setting on stage + DummyControl dummy1 = DummyControl::New(true); + Impl::DummyControl& dummyImpl1 = static_cast(dummy1.GetImplementation()); + dummyImpl1.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual1); + dummy1.SetProperty(Actor::Property::SIZE, Vector2(200, 200)); + dummy1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + application.GetScene().Add(dummy1); + + TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); + glAbstraction.EnableEnableDisableCallTrace(true); - tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed"); - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); application.SendNotification(); application.Render(); - tet_infoline("Ensure texture is not deleted as policy is set to NEVER"); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); + std::ostringstream blendStr; + blendStr << std::hex << GL_BLEND; + DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); END_TEST; } -int UtcDaliImageVisualReleasePolicy04(void) +void ResourceReadyLoadNext(Control control) { - ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy04 Two visuals with different policies sharing a texture"); + static int callNumber = 0; - tet_infoline("Create first visual with Never release policy"); - Visual::Base imageVisualNever = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER); + gResourceReadySignalFired = true; + gReadyIds.push_back(control.GetProperty(Actor::Property::ID)); - tet_infoline("Create second visual with Destroyed release policy"); - Visual::Base imageVisualDestroyed = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + if(callNumber == 0) + { + DALI_TEST_EQUALS(control.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL), Toolkit::Visual::ResourceStatus::FAILED, TEST_LOCATION); - // Set up trace debug - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + tet_infoline("Create visual with loaded image from within the signal handler"); + VisualFactory factory = VisualFactory::Get(); + Visual::Base imageVisual = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions{20, 30}); - tet_infoline("Register visuals with control and ensure it has the only handles"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisualNever); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, imageVisualDestroyed); - imageVisualNever.Reset(); // reduce ref count so only the control keeps the visual alive. - imageVisualDestroyed.Reset(); // reduce ref count so only the control keeps the visual alive. + Impl::DummyControl& controlImpl = static_cast(control.GetImplementation()); + controlImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); // This should trigger another signal. + callNumber = 1; + } + else + { + tet_infoline("3rd signal called"); + DALI_TEST_CHECK(true); + } +} - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); +int UtcDaliImageVisualLoadReady01(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliImageVisualLoadReady01"); + tet_infoline("First part: Load an image visual for one resource, then another image visual for a second resource."); + tet_infoline("Second part, In the ready signal for the second image visual, add a 3rd visual with the first URL"); + tet_infoline("Should get a ready signal for all three visuals"); - // Test initially zero renderers - application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + ClearReadyIds(); + tet_infoline("Create a control and connect to resource ready signal"); + DummyControl actor = DummyControl::New(true); + int actor1Id = actor.GetProperty(Actor::Property::ID); + actor.ResourceReadySignal().Connect(&ResourceReadySignal); + Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); application.GetScene().Add(actor); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + tet_infoline("Create visual with IMMEDIATE load policy"); + Visual::Base imageVisual1 = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); - application.SendNotification(); - application.Render(0); - tet_infoline("Ensure a texture is created, shared amongst both visuals. Each visual has its own renderer"); - DALI_TEST_EQUALS(actor.GetRendererCount(), 2u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + tet_infoline("Registering visual allows control to get a signal once loaded even if visual not enabled( staged )"); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual1); - // Test renderer removed when visual destroyed - DALI_TEST_CHECK(actor.GetRendererCount() == 2u); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL2); // TEST_VISUAL2 no longer requires the texture as release policy DESTROYED - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + tet_infoline("Allow image time to load"); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); - // Test texture was not deleted as TEST_VISUAL release policy is NEVER so it is still required. - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + tet_infoline("Testing texture is loaded and resource ready signal fired"); + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + DALI_TEST_EQUALS(gReadyIds[0], actor1Id, TEST_LOCATION); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - application.SendNotification(); - application.Render(); + tet_infoline("Original control correctly signalled, now testing failing image"); - tet_infoline("Ensure a texture is not deleted as second visual used the NEVER release policy"); - // Test texture was not deleted as TEST_VISUAL release policy is NEVER so it is still required. - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + gResourceReadySignalFired = false; // Reset signal check ready for testing next Control + ClearReadyIds(); - END_TEST; -} + Visual::Base imageVisual2 = CreateVisualWithPolicy(TEST_BROKEN_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); -int UtcDaliImageVisualReleasePolicy05(void) -{ - ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy05 Testing settung by string currents correct enum"); + DummyControl actor2 = DummyControl::New(true); + int actor2Id = actor2.GetProperty(Actor::Property::ID); + Impl::DummyControl& dummyImpl2 = static_cast(actor2.GetImplementation()); + actor2.ResourceReadySignal().Connect(&ResourceReadyLoadNext); - VisualFactory factory = VisualFactory::Get(); + tet_infoline("Registering visual this should trigger the ready signal when the image fails to load"); + dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2); - Property::Map propertyMapNeverReleasePolicy; - propertyMapNeverReleasePolicy.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMapNeverReleasePolicy.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMapNeverReleasePolicy.Insert(ImageVisual::Property::DESIRED_WIDTH, 20); - propertyMapNeverReleasePolicy.Insert(ImageVisual::Property::DESIRED_HEIGHT, 30); - propertyMapNeverReleasePolicy.Insert("releasePolicy", "never"); + actor2.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor2); - Visual::Base imageVisualNever = factory.CreateVisual(propertyMapNeverReleasePolicy); + tet_infoline("Wait for loading thread to finish"); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); - Property::Map resultMap; - imageVisualNever.CreatePropertyMap(resultMap); - DALI_TEST_CHECK(!resultMap.Empty()); + DALI_TEST_EQUALS(gReadyIds[0], actor2Id, TEST_LOCATION); - DALI_TEST_EQUALS((resultMap.Find(ImageVisual::Property::RELEASE_POLICY))->Get(), (int)ImageVisual::ReleasePolicy::NEVER, TEST_LOCATION); + tet_infoline("Check for 3rd signal"); + application.SendNotification(); + DALI_TEST_EQUALS(gReadyIds.size(), 2, TEST_LOCATION); + DALI_TEST_EQUALS(gReadyIds[1], actor2Id, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualReleasePolicy06(void) +int UtcDaliImageVisualLoadImagePlanes01(void) { + EnvironmentVariable::SetTestEnvironmentVariable(LOAD_IMAGE_YUV_PLANES_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(ENABLE_DECODE_JPEG_TO_YUV_420_ENV, "1"); + ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy06 Never Policy, texture should not be affected by Disabling and Enabling visual"); - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::NEVER); - DALI_TEST_CHECK(imageVisual); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_YUV420_IMAGE_FILE_NAME); - tet_infoline("Register visual with control and ensure it has the only handle"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor); application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - - application.GetScene().Add(actor); + application.Render(); - // Wait for image to load DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.SendNotification(); - application.Render(0); - // Test renderer and texture created - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - textureTrace.Reset(); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - tet_infoline("Disable Visual and check texture not affected"); - dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, false); application.SendNotification(); - application.Render(0); - tet_infoline("Check renderer is destroyed when visual off stage"); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - textureTrace.Reset(); + application.Render(); - tet_infoline("Re-enable Visual and check texture not affected"); - dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, true); - application.SendNotification(); - application.Render(0); - tet_infoline("Check texture not affected and renderer is destroyed when visual off stage"); - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 3, TEST_LOCATION); + + Renderer renderer = actor.GetRendererAt(0); + auto preMultipliedAlpha = renderer.GetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA); + DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualReleasePolicy07(void) +int UtcDaliImageVisualLoadImagePlanes02(void) { - ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy07 Two visuals with different policies sharing a texture DETACHED and DESTROYED"); + EnvironmentVariable::SetTestEnvironmentVariable(LOAD_IMAGE_YUV_PLANES_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(ENABLE_DECODE_JPEG_TO_YUV_420_ENV, "1"); - tet_infoline("Create first visual with DESTROYED release policy"); - Visual::Base imageVisualDestroyed = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + ToolkitTestApplication application; - tet_infoline("Create second visual with DETACHED release policy"); - Visual::Base imageVisualDetached = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DETACHED); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - // Set up trace debug - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + // Alpha masking case - not support yuv planes + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_YUV420_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME); - tet_infoline("Register visuals with control and ensure it has the only handles"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisualDestroyed); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, imageVisualDetached); - imageVisualDestroyed.Reset(); // reduce ref count so only the control keeps the visual alive. - imageVisualDetached.Reset(); // reduce ref count so only the control keeps the visual alive. + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - - // Test initially zero renderers - application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - application.GetScene().Add(actor); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - - application.SendNotification(); - application.Render(0); - tet_infoline("Ensure a texture is created, shared amongst both visuals. Each visual has its own renderer"); - DALI_TEST_EQUALS(actor.GetRendererCount(), 2u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - - // Test renderer removed when visual destroyed - DALI_TEST_CHECK(actor.GetRendererCount() == 2u); - dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL2, false); // TEST_VISUAL2 no longer requires the texture as release policy DETACHED - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); application.SendNotification(); application.Render(); - // Test texture was not deleted as TEST_VISUAL release policy is DESTROYED and is still required. - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - dummyImpl.EnableVisual(DummyControl::Property::TEST_VISUAL, false); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); application.SendNotification(); application.Render(); - tet_infoline("Ensure a texture is not deleted as second visual used the DESTROYED release policy"); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualReleasePolicy08(void) +int UtcDaliImageVisualLoadImagePlanes03(void) { + EnvironmentVariable::SetTestEnvironmentVariable(LOAD_IMAGE_YUV_PLANES_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(ENABLE_DECODE_JPEG_TO_YUV_420_ENV, "1"); + ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualReleasePolicy08 Ensure TextureSet is same after detach/attach on stage when texture used the DESTROYED release policy"); - tet_infoline("Create first visual with DESTROYED release policy"); - Visual::Base imageVisualDestroyed = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - // Set up trace debug TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - tet_infoline("Register visuals with control and ensure it has the only handles"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisualDestroyed); - imageVisualDestroyed.Reset(); // reduce ref count so only the control keeps the visual alive. - - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - - // Test initially zero renderers - application.SendNotification(); - application.Render(0); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - textureTrace.Reset(); - - application.GetScene().Add(actor); - - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - - application.SendNotification(); - application.Render(0); - tet_infoline("Ensure a texture is created"); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - textureTrace.Reset(); - - // Ensure TextureSet is same after detach/attach on stage when texture used the DESTROYED release policy - // 1. Get TextureSet - TextureSet textureSetBefore = actor.GetRendererAt(0u).GetTextures(); - - // 2.Remove actor from stage. In this case, renderer also is deleted. - tet_infoline("Remove actor from stage"); - application.GetScene().Remove(actor); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); - application.SendNotification(); - application.Render(); - - tet_infoline("Ensure a texture is not deleted as visual used the DESTROYED release policy"); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION); - textureTrace.Reset(); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_YUV420_IMAGE_FILE_NAME); + propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, true); - // 3.Add actor in stage. In this case, renderer is created. - tet_infoline("Add actor in stage"); - application.GetScene().Add(actor); - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); - application.SendNotification(); - application.Render(); - tet_infoline("Ensure a texture is not created again"); - DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); - textureTrace.Reset(); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - // 4.Compare Texture with before and after. textureSet need to be same because release policy is the DESTROYED. - tet_infoline("Ensure a textureSet is not deleted because it is used the DESTROYED release policy"); - TextureSet textureSetAfter = actor.GetRendererAt(0u).GetTextures(); - DALI_TEST_CHECK(textureSetBefore == textureSetAfter); - textureSetBefore.Reset(); - textureSetAfter.Reset(); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor); - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); - DALI_TEST_CHECK(actor.GetRendererCount() == 0u); application.SendNotification(); application.Render(); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 3, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualLoadPolicy01(void) +int UtcDaliImageVisualLoadFastTrackImage01(void) { + tet_infoline("Test worker thread uploading with Local URL"); ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualLoadPolicy01 Load a visual image before attaching to stage"); - // Set up trace debug - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + Test::TextureUploadManager::InitalizeGraphicsController(application.GetGraphicsController()); - tet_infoline("Create visual with IMMEDIATE load policy"); VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, 20); - propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, 30); - propertyMap.Insert("loadPolicy", ImageVisual::LoadPolicy::IMMEDIATE); + // Pair of filename - expect GenTextures count. + std::vector> testCases = { + {TEST_IMAGE_FILE_NAME, 1}, + {TEST_REMOTE_IMAGE_FILE_NAME, 1}, + {TEST_INVALID_FILE_NAME, 0}, + }; - Visual::Base imageVisual = factory.CreateVisual(propertyMap); + for(auto&& tc : testCases) + { + auto& filename = tc.first; + auto& expectValue = tc.second; - Property::Map resultMap; - imageVisual.CreatePropertyMap(resultMap); - DALI_TEST_CHECK(!resultMap.Empty()); - DALI_TEST_EQUALS((resultMap.Find(ImageVisual::Property::LOAD_POLICY))->Get(), (int)ImageVisual::LoadPolicy::IMMEDIATE, TEST_LOCATION); + tet_printf("Test %s\n", filename.c_str()); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, filename.c_str()); + propertyMap.Insert(DevelImageVisual::Property::FAST_TRACK_UPLOADING, true); - // Ensure texture has been uploaded - application.SendNotification(); - application.Render(); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - tet_infoline("Ensure texture loading starts after visual created"); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - textureTrace.Reset(); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - tet_infoline("Register visuals with control and ensure it has the only handles"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - application.GetScene().Add(actor); - tet_infoline("Ensure nothing triggers another load as texure already loaded"); - const unsigned int TIME_OUT_3_SECONDS = 3; - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, TIME_OUT_3_SECONDS), false, TEST_LOCATION); + application.GetScene().Add(actor); - application.SendNotification(); - application.Render(); + application.SendNotification(); + application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); + // EventThread without callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 30, false), true, TEST_LOCATION); - // Ensure texture is deleted when no longer needed (ref count was correct ) - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); - application.SendNotification(); - application.Render(); + { + // TODO : There is no way to flush TextureUploadManager in test-application's Render() now. + // How can we make it? Should it be integration-api? + auto textureUploadManager = Dali::Devel::TextureUploadManager::Get(); + DALI_TEST_EQUALS(textureUploadManager.ResourceUpload(), expectValue > 0, TEST_LOCATION); + } + // Render only without SendNotification(). And check whether glTexImage2D called or not. + application.Render(); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), expectValue, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + textureTrace.Reset(); + } END_TEST; } -int UtcDaliImageVisualLoadPolicy02(void) +int UtcDaliImageVisualLoadFastTrackImage02(void) { + tet_infoline("Test worker thread uploading with Local URL"); ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualLoadPolicy01 Load a visual image only after attached to stage"); - // Set up trace debug - TestGlAbstraction& gl = application.GetGlAbstraction(); - TraceCallStack& textureTrace = gl.GetTextureTrace(); - textureTrace.Enable(true); + Test::TextureUploadManager::InitalizeGraphicsController(application.GetGraphicsController()); - tet_infoline("Create visual with IMMEDIATE load policy"); - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::ATTACHED); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - const unsigned int TIME_OUT_3_SECONDS = 3; - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, TIME_OUT_3_SECONDS), false, TEST_LOCATION); + { + auto filename = std::string(TEST_IMAGE_FILE_NAME); + auto expectValue = 1; - // Act on meeage queue even although nothing expected to load - application.SendNotification(); - application.Render(); + tet_printf("Test %s\n", filename.c_str()); - tet_infoline("Ensure texture is not generated yet"); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION); - textureTrace.Reset(); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, filename.c_str()); + propertyMap.Insert("fastTrackUploading", true); - tet_infoline("Register visuals with control and ensure it has the only handles"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - application.GetScene().Add(actor); - tet_infoline("Allow image time to load"); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - application.SendNotification(); - application.Render(); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - tet_infoline("Ensure texture generated and renderer created"); - DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); + application.GetScene().Add(actor); - // Ensure texture is delete when no longer needed - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); + application.SendNotification(); + application.Render(); - application.SendNotification(); - application.Render(); + // EventThread without callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 30, false), true, TEST_LOCATION); - DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION); - DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); + + { + // TODO : There is no way to flush TextureUploadManager in test-application's Render() now. + // How can we make it? Should it be integration-api? + auto textureUploadManager = Dali::Devel::TextureUploadManager::Get(); + DALI_TEST_EQUALS(textureUploadManager.ResourceUpload(), expectValue > 0, TEST_LOCATION); + } + // Render only without SendNotification(). And check whether glTexImage2D called or not. + application.Render(); + + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), expectValue, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + textureTrace.Reset(); + } END_TEST; } -int UtcDaliImageVisualLoadPolicy03(void) +int UtcDaliImageVisualLoadFastTrackImageResourceReady(void) { + tet_infoline("Test worker thread uploading with Local URL"); ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualLoadPolicy03 Load a visual image and receive ResourceReady Signal when loaded"); - const bool VISUAL_NOT_ENABLED(false); // Instead of just passing 'false' into an API. + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert(DevelImageVisual::Property::FAST_TRACK_UPLOADING, true); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - // Set up trace debug TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - tet_infoline("Create a control and connect to resource ready signal without adding to stage"); - DummyControl actor = DummyControl::New(true); - actor.ResourceReadySignal().Connect(&ResourceReadySignal); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - - tet_infoline("Create visual with IMMEDIATE load policy"); - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); + application.GetScene().Add(actor); - tet_infoline("Registering visual allows control to get a signal once loaded even if visual not enabled( not staged )"); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + application.SendNotification(); + application.Render(); - tet_infoline("Allow image time to load resource"); + // EventThread with callback DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + // Check resource ready comes after application.SendNotification(); application.Render(); - // Ensure texture has been uploaded - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualLoadPolicy04(void) +int UtcDaliImageVisualLoadFastTrackImageReload(void) { + tet_infoline("Test worker thread uploading with Local URL"); ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualLoadPolicy04 First part Load a visual image before attaching to stage"); - tet_infoline("Second part, Reuse the same image in aonther control and check resource ready signal fired"); - const bool VISUAL_NOT_ENABLED(false); // Instead of just passing false into an API. + Test::TextureUploadManager::InitalizeGraphicsController(application.GetGraphicsController()); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert(DevelImageVisual::Property::FAST_TRACK_UPLOADING, true); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - // Set up trace debug TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - tet_infoline("Create a control and connect to resource ready signal"); - DummyControl actor = DummyControl::New(true); - actor.ResourceReadySignal().Connect(&ResourceReadySignal); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor); - tet_infoline("Create visual with IMMEDIATE load policy"); - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); + application.SendNotification(); + application.Render(); - tet_infoline("Registering visual allows control to get a signal once loaded even if visual not enabled( staged )"); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual, VISUAL_NOT_ENABLED); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. + // EventThread without callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 30, false), true, TEST_LOCATION); - tet_infoline("Allow image time to load"); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - application.SendNotification(); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); + + { + // TODO : There is no way to flush TextureUploadManager in test-application's Render() now. + // How can we make it? Should it be integration-api? + auto textureUploadManager = Dali::Devel::TextureUploadManager::Get(); + DALI_TEST_EQUALS(textureUploadManager.ResourceUpload(), true, TEST_LOCATION); + } + // Render only without SendNotification(). And check whether glTexImage2D called or not. application.Render(); - tet_infoline("Testing texture is loaded and resource ready signal fired"); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION); - tet_infoline("Original control correctly signalled, now testing for signal with new Control reusing the image"); + // Reload + Property::Map attributes; + DevelControl::DoAction(actor, Control::CONTROL_PROPERTY_END_INDEX + 1, DevelImageVisual::Action::RELOAD, attributes); - gResourceReadySignalFired = false; // Reset signal check ready for testing next Control - Visual::Base imageVisual2 = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); - DummyControl actor2 = DummyControl::New(true); - Impl::DummyControl& dummyImpl2 = static_cast(actor.GetImplementation()); - actor2.ResourceReadySignal().Connect(&ResourceReadySignal); + // EventThread with callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - tet_infoline("Registering visual this should trigger the loading signal as is already image loaded for previous control"); - dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2); - imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive. - actor2.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(0), true, TEST_LOCATION); // Not expecting any further loading as texture is being reused. - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + // Check resource ready comes after + application.SendNotification(); + application.Render(); + + // Check whether renderer count is 1 or not. + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); END_TEST; } -int UtcDaliImageVisualLoadPolicy05(void) +int UtcDaliImageVisualLoadFastTrackImagePlanes01(void) { + EnvironmentVariable::SetTestEnvironmentVariable(LOAD_IMAGE_YUV_PLANES_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(ENABLE_DECODE_JPEG_TO_YUV_420_ENV, "1"); + ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualLoadPolicy05 LoadPolicy::ATTACHED (default) First part Load a visual image before attaching to stage"); - tet_infoline("Second part, Reuse the same image in aonther control and check resource ready signal fired"); - // Set up trace debug + + Test::TextureUploadManager::InitalizeGraphicsController(application.GetGraphicsController()); + + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); + + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_YUV420_IMAGE_FILE_NAME); + propertyMap.Insert(DevelImageVisual::Property::FAST_TRACK_UPLOADING, true); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + TestGlAbstraction& gl = application.GetGlAbstraction(); TraceCallStack& textureTrace = gl.GetTextureTrace(); textureTrace.Enable(true); - tet_infoline("Create a control and connect to resource ready signal"); - DummyControl actor = DummyControl::New(true); - actor.ResourceReadySignal().Connect(&ResourceReadySignal); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); application.GetScene().Add(actor); - tet_infoline("Create visual with ATTACHED load policy"); - Visual::Base imageVisual = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::ATTACHED); - - tet_infoline("Registering visual allows control to get a signal once loaded"); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive. - - tet_infoline("Allow image time to load"); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); application.SendNotification(); application.Render(); - tet_infoline("Testing texture is loaded and resource ready signal fired"); - DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION); - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + // EventThread without callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 30, false), true, TEST_LOCATION); - tet_infoline("Original control correctly signalled, now testing for signal with new Control reusing the image"); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); - gResourceReadySignalFired = false; // Reset signal check ready for testing next Control - Visual::Base imageVisual2 = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::ATTACHED); - DummyControl actor2 = DummyControl::New(true); - Impl::DummyControl& dummyImpl2 = static_cast(actor.GetImplementation()); - actor2.ResourceReadySignal().Connect(&ResourceReadySignal); + { + // TODO : There is no way to flush TextureUploadManager in test-application's Render() now. + // How can we make it? Should it be integration-api? + auto textureUploadManager = Dali::Devel::TextureUploadManager::Get(); + textureUploadManager.ResourceUpload(); + application.Render(); + } + // Render only without SendNotification(). And check whether glTexImage2D called or not. + application.Render(); - tet_infoline("Registering visual this should trigger the loading signal as is already image loaded for previous control"); - dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2); - imageVisual2.Reset(); // reduce ref count so only the control keeps the visual alive. - actor2.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(0), true, TEST_LOCATION); // Not expecting any further loading as texture is being reused. - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 3, TEST_LOCATION); + + application.SendNotification(); + application.Render(); END_TEST; } -int UtcDaliImageVisualOrientationCorrection(void) +int UtcDaliImageVisualLoadFastTrackImagePlanes02(void) { + EnvironmentVariable::SetTestEnvironmentVariable(LOAD_IMAGE_YUV_PLANES_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(ENABLE_DECODE_JPEG_TO_YUV_420_ENV, "1"); + ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualOrientationCorrection Enabling OrientationCorrection should rotate an image with exif (90deg) orientation data with requested"); + + Test::TextureUploadManager::InitalizeGraphicsController(application.GetGraphicsController()); VisualFactory factory = VisualFactory::Get(); - tet_infoline("Create visual with Orientation correction set OFF"); + DALI_TEST_CHECK(factory); + Property::Map propertyMap; - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_ROTATED_IMAGE); - propertyMap.Insert("orientationCorrection", false); - Visual::Base imageVisual = factory.CreateVisual(propertyMap); + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + propertyMap.Insert(DevelImageVisual::Property::FAST_TRACK_UPLOADING, true); - tet_infoline("Create control for visual, need to loaded it"); - DummyControl actor = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); - application.GetScene().Add(actor); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + + application.GetScene().Add(actor); - Vector2 originalImageSize; - tet_infoline("Get size of original visual to compare later with rotated image"); - imageVisual.GetNaturalSize(originalImageSize); - DALI_TEST_GREATER(originalImageSize.width, originalImageSize.height, TEST_LOCATION); // Width and Height must be different for this test. - imageVisual.Reset(); // remove handle so can unregister it and remove from cache - dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL); application.SendNotification(); application.Render(); - tet_infoline("Create visual with Orientation correction set ON "); - propertyMap.Clear(); - propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE); - propertyMap.Insert(ImageVisual::Property::URL, TEST_ROTATED_IMAGE); - propertyMap.Insert(ImageVisual::Property::ORIENTATION_CORRECTION, true); - imageVisual = factory.CreateVisual(propertyMap); + // EventThread without callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 30, false), true, TEST_LOCATION); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); - // Wait for image to load - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); - Vector2 rotatedImageSize; - imageVisual.GetNaturalSize(rotatedImageSize); - tet_infoline("Confirm that visual has rotated"); - DALI_TEST_EQUALS(originalImageSize.width, rotatedImageSize.height, TEST_LOCATION); - DALI_TEST_EQUALS(originalImageSize.height, rotatedImageSize.width, TEST_LOCATION); + { + // TODO : There is no way to flush TextureUploadManager in test-application's Render() now. + // How can we make it? Should it be integration-api? + auto textureUploadManager = Dali::Devel::TextureUploadManager::Get(); + textureUploadManager.ResourceUpload(); + application.Render(); + } + // Render only without SendNotification(). And check whether glTexImage2D called or not. + application.Render(); - Property::Map resultMap; - imageVisual.CreatePropertyMap(resultMap); + DALI_TEST_GREATER(textureTrace.CountMethod("GenTextures"), 0, TEST_LOCATION); - // check the Property::ORIENTATION_CORRECTION value from the returned map - Property::Value* typeValue = resultMap.Find(ImageVisual::Property::ORIENTATION_CORRECTION, Property::BOOLEAN); - DALI_TEST_EQUALS(typeValue->Get(), true, TEST_LOCATION); + application.SendNotification(); + application.Render(); END_TEST; } -int UtcDaliImageVisualCustomShader(void) +int UtcDaliImageVisualDebugImageVisualShaderP1(void) { - ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualCustomShader Test custom shader"); + EnvironmentVariable::SetTestEnvironmentVariable(DALI_DEBUG_IMAGE_VISUAL_SHADER_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(DALI_DEBUG_IMAGE_VISUAL_SHADER_SCRIPT_FILE_NAME_ENV, "validFile"); // Try to load not exist file. - VisualFactory factory = VisualFactory::Get(); - Property::Map properties; - Property::Map shader; - const std::string vertexShader = "Foobar"; - const std::string fragmentShader = "Foobar"; - shader[Visual::Shader::Property::FRAGMENT_SHADER] = fragmentShader; - shader[Visual::Shader::Property::VERTEX_SHADER] = vertexShader; + // Set valid script file + Test::StyleMonitor::SetThemeFileOutput("validFile", VALID_DEBUG_SHADER_SCRIPT); - properties[Visual::Property::TYPE] = Visual::IMAGE; - properties[Visual::Property::SHADER] = shader; - properties[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + ToolkitTestApplication application; - Visual::Base visual = factory.CreateVisual(properties); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - // trigger creation through setting on stage - DummyControl dummy = DummyControl::New(true); - Impl::DummyControl& dummyImpl = static_cast(dummy.GetImplementation()); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - dummy.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - dummy.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - application.GetScene().Add(dummy); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor); application.SendNotification(); application.Render(); DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - Renderer renderer = dummy.GetRendererAt(0); - Shader shader2 = renderer.GetShader(); - Property::Value value = shader2.GetProperty(Shader::Property::PROGRAM); - Property::Map* map = value.GetMap(); - DALI_TEST_CHECK(map); - - Property::Value* fragment = map->Find("fragment"); // fragment key name from shader-impl.cpp - DALI_TEST_EQUALS(fragmentShader, fragment->Get(), TEST_LOCATION); - - Property::Value* vertex = map->Find("vertex"); // vertex key name from shader-impl.cpp - DALI_TEST_EQUALS(vertexShader, vertex->Get(), TEST_LOCATION); - - shader.Clear(); - - shader[Visual::Shader::Property::HINTS] = Shader::Hint::OUTPUT_IS_TRANSPARENT; - properties[Visual::Property::SHADER] = shader; - - Visual::Base visual1 = factory.CreateVisual(properties); - - // trigger creation through setting on stage - DummyControl dummy1 = DummyControl::New(true); - Impl::DummyControl& dummyImpl1 = static_cast(dummy1.GetImplementation()); - dummyImpl1.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual1); - dummy1.SetProperty(Actor::Property::SIZE, Vector2(200, 200)); - dummy1.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); - application.GetScene().Add(dummy1); - - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); - glAbstraction.EnableEnableDisableCallTrace(true); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); application.SendNotification(); application.Render(); - TraceCallStack& glEnableStack = glAbstraction.GetEnableDisableTrace(); - std::ostringstream blendStr; - blendStr << std::hex << GL_BLEND; - DALI_TEST_CHECK(glEnableStack.FindMethodAndParams("Enable", blendStr.str())); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION); END_TEST; } -void ResourceReadyLoadNext(Control control) +int UtcDaliImageVisualDebugImageVisualShaderN1(void) { - static int callNumber = 0; + EnvironmentVariable::SetTestEnvironmentVariable(DALI_DEBUG_IMAGE_VISUAL_SHADER_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(DALI_DEBUG_IMAGE_VISUAL_SHADER_SCRIPT_FILE_NAME_ENV, "notJsonFile"); // Try to load exist file, but not a json - gResourceReadySignalFired = true; - gReadyIds.push_back(control.GetProperty(Actor::Property::ID)); - - if(callNumber == 0) - { - DALI_TEST_EQUALS(control.GetVisualResourceStatus(DummyControl::Property::TEST_VISUAL), Toolkit::Visual::ResourceStatus::FAILED, TEST_LOCATION); + // Set invalid script file + Test::StyleMonitor::SetThemeFileOutput("notJsonFile", "1"); - tet_infoline("Create visual with loaded image from within the signal handler"); - VisualFactory factory = VisualFactory::Get(); - Visual::Base imageVisual = factory.CreateVisual(TEST_IMAGE_FILE_NAME, ImageDimensions{20, 30}); + ToolkitTestApplication application; - Impl::DummyControl& controlImpl = static_cast(control.GetImplementation()); - controlImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual); // This should trigger another signal. - callNumber = 1; - } - else - { - tet_infoline("3rd signal called"); - DALI_TEST_CHECK(true); - } -} + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); -int UtcDaliImageVisualLoadReady01(void) -{ - ToolkitTestApplication application; - tet_infoline("UtcDaliImageVisualLoadReady01"); - tet_infoline("First part: Load an image visual for one resource, then another image visual for a second resource."); - tet_infoline("Second part, In the ready signal for the second image visual, add a 3rd visual with the first URL"); - tet_infoline("Should get a ready signal for all three visuals"); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); - ClearReadyIds(); + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); - tet_infoline("Create a control and connect to resource ready signal"); - DummyControl actor = DummyControl::New(true); - int actor1Id = actor.GetProperty(Actor::Property::ID); - actor.ResourceReadySignal().Connect(&ResourceReadySignal); - Impl::DummyControl& dummyImpl = static_cast(actor.GetImplementation()); + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); application.GetScene().Add(actor); - tet_infoline("Create visual with IMMEDIATE load policy"); - Visual::Base imageVisual1 = CreateVisualWithPolicy(TEST_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); - - tet_infoline("Registering visual allows control to get a signal once loaded even if visual not enabled( staged )"); - dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual1); + application.SendNotification(); + application.Render(); - tet_infoline("Allow image time to load"); DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); + application.SendNotification(); application.Render(); - tet_infoline("Testing texture is loaded and resource ready signal fired"); - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); - DALI_TEST_EQUALS(gReadyIds[0], actor1Id, TEST_LOCATION); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION); - tet_infoline("Original control correctly signalled, now testing failing image"); + END_TEST; +} - gResourceReadySignalFired = false; // Reset signal check ready for testing next Control - ClearReadyIds(); +int UtcDaliImageVisualDebugImageVisualShaderN2(void) +{ + EnvironmentVariable::SetTestEnvironmentVariable(DALI_DEBUG_IMAGE_VISUAL_SHADER_ENV, "1"); + EnvironmentVariable::SetTestEnvironmentVariable(DALI_DEBUG_IMAGE_VISUAL_SHADER_SCRIPT_FILE_NAME_ENV, std::string(THROW_EXCEPTION_STYLE_FILE_NAME).c_str()); // Try to load file that throw some exception - Visual::Base imageVisual2 = CreateVisualWithPolicy(TEST_BROKEN_IMAGE_FILE_NAME, ImageVisual::Property::LOAD_POLICY, ImageVisual::LoadPolicy::IMMEDIATE); + // Set throw exception script file + Test::StyleMonitor::SetThemeFileOutput(std::string(THROW_EXCEPTION_STYLE_FILE_NAME), "1"); - DummyControl actor2 = DummyControl::New(true); - int actor2Id = actor2.GetProperty(Actor::Property::ID); - Impl::DummyControl& dummyImpl2 = static_cast(actor2.GetImplementation()); - actor2.ResourceReadySignal().Connect(&ResourceReadyLoadNext); + ToolkitTestApplication application; - tet_infoline("Registering visual this should trigger the ready signal when the image fails to load"); - dummyImpl2.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual2); + VisualFactory factory = VisualFactory::Get(); + DALI_TEST_CHECK(factory); - actor2.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); - application.GetScene().Add(actor2); + Property::Map propertyMap; + propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE); + propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME); + + Visual::Base visual = factory.CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual); + actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f)); + application.GetScene().Add(actor); + + application.SendNotification(); + application.Render(); - tet_infoline("Wait for loading thread to finish"); DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION); - DALI_TEST_EQUALS(gReadyIds[0], actor2Id, TEST_LOCATION); + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable(true); - tet_infoline("Check for 3rd signal"); application.SendNotification(); - DALI_TEST_EQUALS(gReadyIds.size(), 2, TEST_LOCATION); - DALI_TEST_EQUALS(gReadyIds[1], actor2Id, TEST_LOCATION); + application.Render(); + + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); + DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION); + DALI_TEST_EQUALS(textureTrace.CountMethod("GenTextures"), 1, TEST_LOCATION); END_TEST; -} +} \ No newline at end of file