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-ImageView.cpp;h=965e258c8e2cc8f244524125c868cfa8ddaef474;hp=12c3f1742ec5b67e765f4c546fa0df0e1c95a394;hb=4019119f94f02948f2dc26a8495d44d1143c684a;hpb=1ff26466c5458cda1de2997cd4e27b014ff0275a diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 12c3f17..965e258 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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,15 +18,23 @@ // Need to override adaptor classes for toolkit test harness, so include // test harness headers before dali headers. #include -#include #include #include #include -#include +#include +#include +#include +#include +#include +#include #include #include +#include + + +#include "dummy-control.h" using namespace Dali; using namespace Toolkit; @@ -75,11 +83,17 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( const char* TEST_IMAGE_FILE_NAME = "gallery_image_01.jpg"; const char* TEST_IMAGE_FILE_NAME2 = "gallery_image_02.jpg"; +const char* TEST_IMAGE_1 = TEST_RESOURCE_DIR "/TB-gloss.png"; +const char* TEST_IMAGE_2 = TEST_RESOURCE_DIR "/tb-norm.png"; + // resolution: 34*34, pixel format: RGBA8888 static const char* gImage_34_RGBA = TEST_RESOURCE_DIR "/icon-edit.png"; // resolution: 600*600, pixel format: RGB888 static const char* gImage_600_RGB = TEST_RESOURCE_DIR "/test-image-600.jpg"; +// resolution: 50*50, frame count: 4, frame delay: 0.2 second for each frame +const char* TEST_GIF_FILE_NAME = TEST_RESOURCE_DIR "/anim.gif"; + void TestImage( ImageView imageView, BufferImage image ) { Property::Value value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); @@ -340,7 +354,7 @@ int UtcDaliImageViewSetGetProperty03(void) Property::Value value = renderer.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); bool enable; DALI_TEST_CHECK( value.Get( enable ) ); - DALI_TEST_CHECK( !enable ); + DALI_TEST_CHECK( enable ); // pre-multiplied alpha blending imageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true ); @@ -354,7 +368,7 @@ int UtcDaliImageViewSetGetProperty03(void) DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE ); DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA ); DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE ); - DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA ); value = renderer.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); DALI_TEST_CHECK( value.Get( enable ) ); @@ -363,28 +377,291 @@ int UtcDaliImageViewSetGetProperty03(void) END_TEST; } +int UtcDaliImageViewPreMultipliedAlphaPng(void) +{ + ToolkitTestApplication application; + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable( true ); + + Property::Map imageMap; + imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ ImageVisual::Property::RELEASE_POLICY] = ImageVisual::ReleasePolicy::NEVER; // To keep the texture cache + + ImageView imageView1 = ImageView::New(); + imageView1.SetProperty( ImageView::Property::IMAGE, imageMap ); + + Stage::GetCurrent().Add( imageView1 ); + + Property::Value value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA ); + bool enable; + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( enable ); // Default value is true + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(); + + value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( enable ); // Keep true + + // conventional alpha blending + Renderer renderer1 = imageView1.GetRendererAt( 0 ); + value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( enable ); + + int srcFactorRgb = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB ); + int destFactorRgb = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB ); + int srcFactorAlpha = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA ); + int destFactorAlpha = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA ); + DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA ); + DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); // A new texture should be generated. + textureTrace.Reset(); + + // Disable pre-multiplied alpha blending + imageView1.SetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA, false ); + + // Reload the image + Property::Map attributes; + DevelControl::DoAction( imageView1, ImageView::Property::IMAGE, DevelImageVisual::Action::RELOAD, attributes ); + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(); + + value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( !enable ); + + // conventional alpha blending + value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( !enable ); + + srcFactorRgb = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB ); + destFactorRgb = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB ); + srcFactorAlpha = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA ); + destFactorAlpha = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA ); + DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA ); + DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA ); + DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); // A new texture should be generated. + textureTrace.Reset(); + + // Make a new ImageView using the same image + ImageView imageView2 = ImageView::New(); + imageView2.SetProperty( ImageView::Property::IMAGE, imageMap ); + + Stage::GetCurrent().Add( imageView2 ); + + application.SendNotification(); + application.Render(); + + Renderer renderer2 = imageView2.GetRendererAt( 0 ); + value = renderer2.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( enable ); + + srcFactorRgb = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB ); + destFactorRgb = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB ); + srcFactorAlpha = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA ); + destFactorAlpha = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA ); + DALI_TEST_CHECK( srcFactorRgb == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA ); + DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION ); // The cached texture should be used. + + END_TEST; +} + +int UtcDaliImageViewPreMultipliedAlphaJpg(void) +{ + ToolkitTestApplication application; + + // Set up trace debug + TestGlAbstraction& gl = application.GetGlAbstraction(); + TraceCallStack& textureTrace = gl.GetTextureTrace(); + textureTrace.Enable( true ); + + Property::Map imageMap; + imageMap[ ImageVisual::Property::URL ] = gImage_600_RGB; + imageMap[ ImageVisual::Property::RELEASE_POLICY] = ImageVisual::ReleasePolicy::NEVER; // To keep the texture cache + + ImageView imageView1 = ImageView::New(); + imageView1.SetProperty( ImageView::Property::IMAGE, imageMap ); + + Stage::GetCurrent().Add( imageView1 ); + + Property::Value value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA ); + bool enable; + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( enable ); // Default value is true + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(); + + value = imageView1.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( !enable ); // Should be false after loading + + // conventional alpha blending + Renderer renderer1 = imageView1.GetRendererAt( 0 ); + value = renderer1.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( !enable ); + + int srcFactorRgb = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB ); + int destFactorRgb = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB ); + int srcFactorAlpha = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA ); + int destFactorAlpha = renderer1.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA ); + DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA ); + DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA ); + DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION ); // A new texture should be generated. + textureTrace.Reset(); + + ImageView imageView2 = ImageView::New(); + imageView2.SetProperty( ImageView::Property::IMAGE, imageMap ); + + // Disable pre-multiplied alpha blending + imageView2.SetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA, false ); + + Stage::GetCurrent().Add( imageView2 ); + + application.SendNotification(); + application.Render(); + + value = imageView2.GetProperty( ImageView::Property::PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( !enable ); + + // conventional alpha blending + Renderer renderer2 = imageView2.GetRendererAt( 0 ); + value = renderer2.GetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA ); + DALI_TEST_CHECK( value.Get( enable ) ); + DALI_TEST_CHECK( !enable ); + + srcFactorRgb = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB ); + destFactorRgb = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB ); + srcFactorAlpha = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA ); + destFactorAlpha = renderer2.GetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA ); + DALI_TEST_CHECK( srcFactorRgb == BlendFactor::SRC_ALPHA ); + DALI_TEST_CHECK( destFactorRgb == BlendFactor::ONE_MINUS_SRC_ALPHA ); + DALI_TEST_CHECK( srcFactorAlpha == BlendFactor::ONE ); + DALI_TEST_CHECK( destFactorAlpha == BlendFactor::ONE_MINUS_SRC_ALPHA ); + + DALI_TEST_EQUALS( textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION ); // The cached texture should be used. + + END_TEST; +} + +int UtcDaliImageViewPixelArea(void) +{ + // Test pixel area property + ToolkitTestApplication application; + + // Gif image, use AnimatedImageVisual internally + // Atlasing is applied to pack multiple frames, use custom wrap mode + ImageView gifView = ImageView::New(); + const Vector4 pixelAreaVisual( 0.f, 0.f, 2.f, 2.f ); + gifView.SetProperty( ImageView::Property::IMAGE, + Property::Map().Add( ImageVisual::Property::URL, TEST_GIF_FILE_NAME ) + .Add( ImageVisual::Property::PIXEL_AREA, pixelAreaVisual ) ); + + // Add to stage + Stage stage = Stage::GetCurrent(); + stage.Add( gifView ); + + // loading started + application.SendNotification(); + application.Render(16); + DALI_TEST_CHECK( gifView.GetRendererCount() == 1u ); + + const Vector4 fullTextureRect( 0.f, 0.f, 1.f, 1.f ); + // test that the pixel area value defined in the visual property map is registered on renderer + Renderer renderer = gifView.GetRendererAt(0); + Property::Value pixelAreaValue = renderer.GetProperty( renderer.GetPropertyIndex( "pixelArea" ) ); + DALI_TEST_EQUALS( pixelAreaValue.Get(), pixelAreaVisual, TEST_LOCATION ); + + // test that the shader has the default pixel area value registered. + Shader shader = renderer.GetShader(); + pixelAreaValue = shader.GetProperty( shader.GetPropertyIndex( "pixelArea" ) ); + DALI_TEST_EQUALS( pixelAreaValue.Get(), fullTextureRect, TEST_LOCATION ); + + // test that the uniform uses the pixelArea property on the renderer. + TestGlAbstraction& gl = application.GetGlAbstraction(); + Vector4 pixelAreaUniform; + DALI_TEST_CHECK( gl.GetUniformValue( "pixelArea", pixelAreaUniform ) ); + DALI_TEST_EQUALS( pixelAreaVisual, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + // set the pixelArea property on the control + const Vector4 pixelAreaControl( -1.f, -1.f, 3.f, 3.f ); + gifView.SetProperty( ImageView::Property::PIXEL_AREA, pixelAreaControl ); + application.SendNotification(); + application.Render(16); + + // check the pixelArea property on the control + pixelAreaValue = gifView.GetProperty( gifView.GetPropertyIndex( "pixelArea" ) ); + DALI_TEST_EQUALS( pixelAreaValue.Get(), pixelAreaControl, TEST_LOCATION ); + // test that the uniform uses the pixelArea property on the control. + DALI_TEST_CHECK( gl.GetUniformValue( "pixelArea", pixelAreaUniform ) ); + DALI_TEST_EQUALS( pixelAreaControl, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION ); + + + END_TEST; +} + int UtcDaliImageViewAsyncLoadingWithoutAltasing(void) { ToolkitTestApplication application; + TestGlAbstraction& gl = application.GetGlAbstraction(); + const std::vector& textures = gl.GetBoundTextures(); + size_t numTextures = textures.size(); // Async loading, no atlasing for big size image ImageView imageView = ImageView::New( gImage_600_RGB ); // By default, Aysnc loading is used Stage::GetCurrent().Add( imageView ); + imageView.SetSize(100, 100); + imageView.SetParentOrigin( ParentOrigin::CENTER ); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + application.SendNotification(); application.Render(16); - application.Render(16); application.SendNotification(); - // BitmapLoader is not used - BitmapLoader loader = BitmapLoader::GetLatestCreated(); - DALI_TEST_CHECK( !loader ); + const std::vector& textures2 = gl.GetBoundTextures(); + DALI_TEST_GREATER( textures2.size(), numTextures, TEST_LOCATION ); + + END_TEST; } -int UtcDaliImageViewAsyncLoadingWithAltasing(void) +int UtcDaliImageViewAsyncLoadingWithAtlasing(void) { ToolkitTestApplication application; @@ -393,13 +670,19 @@ int UtcDaliImageViewAsyncLoadingWithAltasing(void) callStack.Reset(); callStack.Enable(true); - BitmapLoader::ResetLatestCreated(); - ImageView imageView = ImageView::New( gImage_34_RGBA, ImageDimensions( 34, 34 ) ); + Property::Map imageMap; + + imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 34; + imageMap[ ImageVisual::Property::DESIRED_WIDTH ] = 34; + imageMap[ ImageVisual::Property::ATLASING] = true; + + ImageView imageView = ImageView::New(); + imageView.SetProperty( ImageView::Property::IMAGE, imageMap ); + imageView.SetProperty( Toolkit::Control::Property::PADDING, Extents( 10u, 10u, 10u, 10u ) ); // By default, Aysnc loading is used // loading is not started if the actor is offStage - BitmapLoader loader = BitmapLoader::GetLatestCreated(); - DALI_TEST_CHECK( !loader ); Stage::GetCurrent().Add( imageView ); application.SendNotification(); @@ -407,20 +690,55 @@ int UtcDaliImageViewAsyncLoadingWithAltasing(void) application.Render(16); application.SendNotification(); - // loading started - loader = BitmapLoader::GetLatestCreated(); - DALI_TEST_CHECK( loader ); + imageView.SetProperty( Dali::Actor::Property::LAYOUT_DIRECTION, Dali::LayoutDirection::RIGHT_TO_LEFT ); + application.SendNotification(); + application.Render(16); + application.Render(16); + application.SendNotification(); + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + callStack.Enable(false); + + TraceCallStack::NamedParams params; + params["width"] = ToString(34); + params["height"] = ToString(34); + DALI_TEST_EQUALS( callStack.FindMethodAndParams( "TexSubImage2D", params ), true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewAsyncLoadingWithAtlasing02(void) +{ + ToolkitTestApplication application; + + //Async loading, automatic atlasing for small size image + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); - // worker thread is created - EventThreadCallback* eventTrigger = EventThreadCallback::Get(); - DALI_TEST_CHECK( eventTrigger ); + Property::Map asyncLoadingMap; + asyncLoadingMap[ "url" ] = gImage_34_RGBA; + asyncLoadingMap[ "desiredHeight" ] = 34; + asyncLoadingMap[ "desiredWidth" ] = 34; + asyncLoadingMap[ "synchronousLoading" ] = false; + asyncLoadingMap[ "atlasing" ] = true; + + ImageView imageView = ImageView::New(); + imageView.SetProperty( ImageView::Property::IMAGE, asyncLoadingMap ); - loader.WaitForLoading();// waiting until the image to be loaded - DALI_TEST_CHECK( loader.IsLoaded() ); + Stage::GetCurrent().Add( imageView ); + application.SendNotification(); + application.Render(16); + application.Render(16); + application.SendNotification(); - eventTrigger->WaitingForTrigger( 1 ); - CallbackBase* callback = eventTrigger->GetCallback(); - CallbackBase::Execute( *callback ); + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); application.SendNotification(); application.Render(16); @@ -439,8 +757,11 @@ int UtcDaliImageViewSyncLoading(void) { ToolkitTestApplication application; + tet_infoline("ImageView Testing sync loading and size using index key property map"); + Property::Map syncLoadingMap; - syncLoadingMap[ "synchronousLoading" ] = true; + syncLoadingMap[ ImageVisual::Property::SYNCHRONOUS_LOADING ] = true; + syncLoadingMap[ ImageVisual::Property::ATLASING ] = true; // Sync loading, no atlasing for big size image { @@ -449,33 +770,57 @@ int UtcDaliImageViewSyncLoading(void) // Sync loading is used syncLoadingMap[ ImageVisual::Property::URL ] = gImage_600_RGB; imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap ); - - // BitmapLoader is used, and the loading is started immediately even the actor is not on stage. - BitmapLoader loader = BitmapLoader::GetLatestCreated(); - DALI_TEST_CHECK( loader ); } // Sync loading, automatic atlasing for small size image { - BitmapLoader::ResetLatestCreated(); TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); callStack.Reset(); callStack.Enable(true); ImageView imageView = ImageView::New( ); + // Sync loading is used syncLoadingMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; syncLoadingMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 34; syncLoadingMap[ ImageVisual::Property::DESIRED_WIDTH ] = 34; imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap ); - // loading is started even if the actor is offStage - BitmapLoader loader = BitmapLoader::GetLatestCreated(); - DALI_TEST_CHECK( loader ); + Stage::GetCurrent().Add( imageView ); + application.SendNotification(); + application.Render(16); + + TraceCallStack::NamedParams params; + params["width"] = ToString(34); + params["height"] = ToString(34); + DALI_TEST_EQUALS( callStack.FindMethodAndParams( "TexSubImage2D", params ), + true, TEST_LOCATION ); + } + END_TEST; +} + +int UtcDaliImageViewSyncLoading02(void) +{ + ToolkitTestApplication application; + + tet_infoline("ImageView Testing sync loading and size using string key property map"); + + // Sync loading, automatic atlasing for small size image + { + TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace(); + callStack.Reset(); + callStack.Enable(true); - loader.WaitForLoading(); + ImageView imageView = ImageView::New( ); - DALI_TEST_CHECK( loader.IsLoaded() ); + // Sync loading is used + Property::Map syncLoadingMap; + syncLoadingMap[ "url" ] = gImage_34_RGBA; + syncLoadingMap[ "desiredHeight" ] = 34; + syncLoadingMap[ "desiredWidth" ] = 34; + syncLoadingMap[ "synchronousLoading" ] = true; + syncLoadingMap[ "atlasing" ] = true; + imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap ); Stage::GetCurrent().Add( imageView ); application.SendNotification(); @@ -490,6 +835,30 @@ int UtcDaliImageViewSyncLoading(void) END_TEST; } +int UtcDaliImageViewAddedTexture(void) +{ + ToolkitTestApplication application; + + tet_infoline("ImageView Testing image view with texture provided manager url"); + + ImageView imageView = ImageView::New(); + + // empty texture is ok, though pointless from app point of view + TextureSet empty; + std::string url = TextureManager::AddTexture(empty); + DALI_TEST_CHECK(url.size() > 0u); + + Property::Map propertyMap; + propertyMap[ImageVisual::Property::URL] = url; + imageView.SetProperty(ImageView::Property::IMAGE, propertyMap); + + Stage::GetCurrent().Add( imageView ); + application.SendNotification(); + application.Render(); + + END_TEST; +} + int UtcDaliImageViewSizeWithBackground(void) { ToolkitTestApplication application; @@ -667,7 +1036,8 @@ int UtcDaliImageViewSetImageOnstageN(void) DALI_TEST_CHECK( !value.Get( url ) ); Property::Map map; - DALI_TEST_CHECK( !value.Get( map ) ); + value.Get( map ); + DALI_TEST_CHECK( map.Empty() ); END_TEST; } @@ -696,6 +1066,47 @@ int UtcDaliImageViewSetImageOffstageP(void) END_TEST; } +bool gResourceReadySignalFired = false; +Vector3 gNaturalSize; + +void ResourceReadySignal( Control control ) +{ + gResourceReadySignalFired = true; +} + +int UtcDaliImageViewCheckResourceReady(void) +{ + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + + int width = 100; + int height = 200; + Image image = CreateBufferImage( width, height, Vector4(1.f, 1.f, 1.f, 1.f) ); + + // Check ImageView with background and main image, to ensure both visuals are marked as loaded + ImageView imageView = ImageView::New( TEST_GIF_FILE_NAME ); + + imageView.SetBackgroundImage( image ); + + DALI_TEST_EQUALS( imageView.IsResourceReady(), false, TEST_LOCATION ); + + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(16); + + + DALI_TEST_EQUALS( imageView.IsResourceReady(), true, TEST_LOCATION ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + int UtcDaliImageViewSetImageOffstageN(void) { ToolkitTestApplication application; @@ -721,7 +1132,8 @@ int UtcDaliImageViewSetImageOffstageN(void) DALI_TEST_CHECK( !value.Get( url ) ); Property::Map map; - DALI_TEST_CHECK( !value.Get( map ) ); + value.Get( map ); + DALI_TEST_CHECK( map.Empty() ); END_TEST; } @@ -741,7 +1153,8 @@ int UtcDaliImageViewSetImageN(void) DALI_TEST_CHECK( !value.Get( url ) ); Property::Map map; - DALI_TEST_CHECK( !value.Get( map ) ); + value.Get( map ); + DALI_TEST_CHECK( map.Empty() ); std::string resource_url; Property::Value val = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); @@ -755,43 +1168,122 @@ int UtcDaliImageViewSetImageTypeChangesP(void) ToolkitTestApplication application; ImageView imageView = ImageView::New(); + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( imageView ); + Stage::GetCurrent().Add( imageView ); std::string url; Property::Map map; + Toolkit::Visual::Base visual; Property::Value value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + + application.SendNotification(); + application.Render( 16 ); + DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty - DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty + value.Get( map ); + DALI_TEST_CHECK( map.Empty() ); // Value should be empty + DALI_TEST_CHECK( ! visual ); // Visual should be invalid // Set a URL imageView.SetImage( "TEST_URL" ); - value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); - DALI_TEST_CHECK( value.Get( url ) ); // Value should NOT be empty + application.SendNotification(); + application.Render( 16 ); + + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + + DALI_TEST_CHECK( value.Get( url ) ); // Value should NOT be empty DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty + DALI_TEST_CHECK( visual ); // Visual should be valid // Set an empty Image imageView.SetImage( Image() ); + + application.SendNotification(); + application.Render( 16 ); + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty - DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty + value.Get( map ); + DALI_TEST_CHECK( map.Empty() ); // Value should be empty + DALI_TEST_CHECK( ! visual ); // Visual should be invalid // Set an Image ResourceImage image1 = ResourceImage::New( TEST_IMAGE_FILE_NAME ); imageView.SetImage( image1 ); + + application.SendNotification(); + application.Render( 16 ); + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty DALI_TEST_CHECK( value.Get( map ) ); // Value should NOT be empty + DALI_TEST_CHECK( visual ); // Visual should be valid // Set an empty URL imageView.SetImage( "" ); + + application.SendNotification(); + application.Render( 16 ); + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty - DALI_TEST_CHECK( ! value.Get( map ) ); // Value should be empty + value.Get( map ); + DALI_TEST_CHECK( map.Empty() ); // Value should be empty + DALI_TEST_CHECK( ! visual ); // Visual should be invalid + + // Set a URL in property map + Property::Map propertyMap; + propertyMap[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + imageView.SetProperty( ImageView::Property::IMAGE, propertyMap ); + + application.SendNotification(); + application.Render( 16 ); + + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + + DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty + DALI_TEST_CHECK( value.Get( map ) ); // Value should NOT be empty + DALI_TEST_CHECK( visual ); // Visual should be valid + + // Set a URL in property map again + propertyMap[ImageVisual::Property::URL] = gImage_34_RGBA; + imageView.SetProperty( ImageView::Property::IMAGE, propertyMap ); + + application.SendNotification(); + application.Render( 16 ); + + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + + DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty + DALI_TEST_CHECK( value.Get( map ) ); // Value should NOT be empty + DALI_TEST_CHECK( visual ); // Visual should be valid + + // Set an empty URL in property map + propertyMap[ImageVisual::Property::URL] = std::string(); + imageView.SetProperty( ImageView::Property::IMAGE, propertyMap ); + + application.SendNotification(); + application.Render( 16 ); + + value = imageView.GetProperty( imageView.GetPropertyIndex( "image" ) ); + visual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + + DALI_TEST_CHECK( ! value.Get( url ) ); // Value should be empty + DALI_TEST_CHECK( value.Get( map ) ); // Value should NOT be empty + DALI_TEST_CHECK( ! visual ); // Visual should be invalid END_TEST; } @@ -869,7 +1361,7 @@ int UtcDaliImageViewSetImageNativeImage(void) DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") ); std::stringstream params; - params << GL_TEXTURE_2D << ", " << 23; + params << GL_TEXTURE_EXTERNAL_OES << ", " << 23; DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) ); END_TEST; @@ -919,7 +1411,7 @@ int UtcDaliImageViewSetImageBufferImageToNativeImage(void) DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") ); std::stringstream nextTextureParams; - nextTextureParams << GL_TEXTURE_2D << ", " << 24; + nextTextureParams << GL_TEXTURE_EXTERNAL_OES << ", " << 24; DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", nextTextureParams.str()) ); END_TEST; @@ -951,7 +1443,7 @@ int UtcDaliImageViewSetImageNativeImageToBufferImage(void) DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") ); std::stringstream params; - params << GL_TEXTURE_2D << ", " << 23; + params << GL_TEXTURE_EXTERNAL_OES << ", " << 23; DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) ); width = 200; @@ -1018,7 +1510,7 @@ int UtcDaliImageViewSetImageNativeImageWithCustomShader(void) DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") ); std::stringstream params; - params << GL_TEXTURE_2D << ", " << 23; + params << GL_TEXTURE_EXTERNAL_OES << ", " << 23; DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", params.str()) ); END_TEST; @@ -1083,7 +1575,7 @@ int UtcDaliImageViewSetImageBufferImageWithCustomShaderToNativeImage(void) DALI_TEST_CHECK( gl.GetTextureTrace().FindMethod("BindTexture") ); std::stringstream nativeImageParams; - nativeImageParams << GL_TEXTURE_2D << ", " << 24; + nativeImageParams << GL_TEXTURE_EXTERNAL_OES << ", " << 24; DALI_TEST_CHECK( gl.GetTextureTrace().FindMethodAndParams("BindTexture", nativeImageParams.str()) ); @@ -1131,3 +1623,745 @@ int UtcDaliImageViewGetImageN(void) END_TEST; } + + +int UtcDaliImageViewReplaceImage(void) +{ + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + int width = 100; + int height = 200; + Image image = CreateBufferImage( width, height, Vector4(1.f, 1.f, 1.f, 1.f) ); + + // Check ImageView with background and main image, to ensure both visuals are marked as loaded + ImageView imageView = ImageView::New( TEST_IMAGE_1 ); + + DALI_TEST_EQUALS( imageView.IsResourceReady(), false, TEST_LOCATION ); + + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(16); + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + DALI_TEST_EQUALS( imageView.GetRendererCount(), 1u, TEST_LOCATION ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + gResourceReadySignalFired = false; + + imageView.SetImage(TEST_IMAGE_2); + + application.SendNotification(); + application.Render(16); + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + DALI_TEST_EQUALS( imageView.GetRendererCount(), 1u, TEST_LOCATION ); + + DALI_TEST_EQUALS( imageView.IsResourceReady(), true, TEST_LOCATION ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +void OnRelayoutOverride( Size size ) +{ + gNaturalSize = size; // Size Relayout is using +} + +int UtcDaliImageViewReplaceImageAndGetNaturalSize(void) +{ + ToolkitTestApplication application; + + // Check ImageView with background and main image, to ensure both visuals are marked as loaded + ImageView imageView = ImageView::New( TEST_IMAGE_1 ); + imageView.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); + + DummyControl dummyControl = DummyControl::New( true ); + Impl::DummyControl& dummyImpl = static_cast(dummyControl.GetImplementation()); + dummyControl.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS ); + + dummyControl.Add( imageView ); + dummyImpl.SetRelayoutCallback( &OnRelayoutOverride ); + Stage::GetCurrent().Add( dummyControl ); + + application.SendNotification(); + application.Render(); + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + DALI_TEST_EQUALS( gNaturalSize.width, 1024.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( gNaturalSize.height, 1024.0f, TEST_LOCATION ); + + gNaturalSize = Vector3::ZERO; + + imageView.SetImage(gImage_600_RGB); + + // Waiting for resourceReady so SendNotifcation not called here. + + // loading started, this waits for the loader thread for max 30 seconds + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + // Trigger a potential relayout + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( gNaturalSize.width, 600.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( gNaturalSize.height, 600.0f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewResourceReadySignalWithImmediateLoad(void) +{ + tet_infoline("Test Setting Image with IMMEDIATE load and receving ResourceReadySignal before staged."); + + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + Property::Map imageMap; + + imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ ImageVisual::Property::LOAD_POLICY ] = ImageVisual::LoadPolicy::IMMEDIATE; + + tet_infoline("Creating ImageView without URL so image does not start loading"); + ImageView imageView = ImageView::New(); + tet_infoline("Connect to image loaded signal before setting image"); + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + tet_infoline("Setting Image with IMMEDIATE load, signal already connected so will be triggered."); + imageView.SetProperty( ImageView::Property::IMAGE, imageMap ); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewResourceReadySignalWithReusedImage(void) +{ + tet_infoline("Test Setting Image that was already loaded by another ImageView and still getting ResourceReadySignal."); + + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + Property::Map imageMap; + + imageMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ ImageVisual::Property::LOAD_POLICY ] = ImageVisual::LoadPolicy::IMMEDIATE; + + ImageView imageView = ImageView::New(); + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + imageView.SetProperty( ImageView::Property::IMAGE, imageMap ); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + gResourceReadySignalFired = false; + + ImageView imageViewWithExistingImage = ImageView::New(); + imageViewWithExistingImage.ResourceReadySignal().Connect( &ResourceReadySignal); + imageViewWithExistingImage.SetProperty( ImageView::Property::IMAGE, imageMap ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewResourceReadySignalWithReusedImage02(void) +{ + tet_infoline("Test Setting Image that was already loaded by another ImageView and still getting ResourceReadySignal when staged."); + + ToolkitTestApplication application; + + gResourceReadySignalFired = false; + + Property::Map imageImmediateLoadingMap; + imageImmediateLoadingMap[ ImageVisual::Property::URL ] = gImage_34_RGBA; + imageImmediateLoadingMap[ ImageVisual::Property::LOAD_POLICY ] = ImageVisual::LoadPolicy::IMMEDIATE; + + tet_infoline("Immediate load an image"); + ImageView imageView = ImageView::New(); + imageView.ResourceReadySignal().Connect( &ResourceReadySignal); + imageView.SetProperty( ImageView::Property::IMAGE, imageImmediateLoadingMap ); + + // loading started, this waits for the loader thread + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + application.SendNotification(); + application.Render(16); + + tet_infoline("Check image loaded"); + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + gResourceReadySignalFired = false; + + tet_infoline("Create another ImageView with the same URL"); + ImageView imageViewWithExistingImage = ImageView::New( gImage_34_RGBA ); + tet_infoline("Connect to ResourceReady signal for second ImageView, it should still fire as resource is ready"); + imageViewWithExistingImage.ResourceReadySignal().Connect( &ResourceReadySignal); + + Stage::GetCurrent().Add( imageViewWithExistingImage ); + + DALI_TEST_EQUALS( gResourceReadySignalFired, true, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewPaddingProperty(void) +{ + ToolkitTestApplication application; + + ImageView imageView = ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = TEST_RESOURCE_DIR "/gallery-small-1.jpg" ; + imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = 128; + imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 128; + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE , imagePropertyMap ); + imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + imageView.SetParentOrigin( ParentOrigin::TOP_LEFT ); + imageView.SetProperty( Control::Property::PADDING, Extents( 15, 10, 5, 10 ) ); + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( imageView.GetProperty( Control::Property::PADDING ), Extents( 15, 10, 5, 10 ), TEST_LOCATION ); + + ImageView childImage = ImageView::New(); + childImage.SetBackgroundColor( Color::BLACK ); + childImage.SetSize( 10.f, 10.f ); + imageView.Add( childImage ); + + application.SendNotification(); + application.Render(); + + // Child ImageView should be positioned dependinig on Parent ImageView's Padding value + DALI_TEST_EQUALS( childImage.GetProperty( Dali::Actor::Property::POSITION ), Vector3( 15, 5, 0 ), TEST_LOCATION ); + + // Check whether Image Visual transforms on ImageVieiw::OnRelayout() + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( imageView ); + Toolkit::Visual::Base imageVisual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + Property::Map resultMap; + imageVisual.CreatePropertyMap( resultMap ); + + Property::Value* transformValue = resultMap.Find( Visual::Property::TRANSFORM ); + DALI_TEST_CHECK( transformValue ); + Property::Map* retMap = transformValue->GetMap(); + DALI_TEST_CHECK( retMap ); + + // Image Visual should be positioned depending on ImageView's padding + DALI_TEST_EQUALS( retMap->Find( Visual::Transform::Property::OFFSET )->Get< Vector2 >(), Vector2( 15, 5 ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewPaddingProperty02(void) +{ + ToolkitTestApplication application; + + ImageView imageView = ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = TEST_RESOURCE_DIR "/Kid1.svg" ; + imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = 128; + imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 128; + imagePropertyMap[ DevelVisual::Property::VISUAL_FITTING_MODE ] = Toolkit::DevelVisual::FIT_KEEP_ASPECT_RATIO; + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE , imagePropertyMap ); + imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + imageView.SetParentOrigin( ParentOrigin::TOP_LEFT ); + imageView.SetProperty( Control::Property::PADDING, Extents( 15, 10, 5, 10 ) ); + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( imageView.GetProperty( Control::Property::PADDING ), Extents( 15, 10, 5, 10 ), TEST_LOCATION ); + + // Check whether Image Visual transforms on ImageVieiw::OnRelayout() + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( imageView ); + Toolkit::Visual::Base imageVisual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + Property::Map resultMap; + imageVisual.CreatePropertyMap( resultMap ); + + Property::Value* transformValue = resultMap.Find( Visual::Property::TRANSFORM ); + DALI_TEST_CHECK( transformValue ); + Property::Map* retMap = transformValue->GetMap(); + DALI_TEST_CHECK( retMap ); + + // Image Visual should be positioned depending on ImageView's padding + DALI_TEST_EQUALS( retMap->Find( Visual::Transform::Property::OFFSET )->Get< Vector2 >(), Vector2( 15, 5 ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewPaddingProperty03(void) +{ + tet_infoline("Test Setting Image Padding then removing it."); + + ToolkitTestApplication application; + + ImageView imageView = ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = TEST_RESOURCE_DIR "/Kid1.svg" ; + imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = 128; + imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 128; + imagePropertyMap[ DevelVisual::Property::VISUAL_FITTING_MODE ] = Toolkit::DevelVisual::FIT_KEEP_ASPECT_RATIO; + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE , imagePropertyMap ); + imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + imageView.SetParentOrigin( ParentOrigin::TOP_LEFT ); + imageView.SetProperty( Control::Property::PADDING, Extents( 15, 10, 5, 10 ) ); + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( imageView.GetProperty( Control::Property::PADDING ), Extents( 15, 10, 5, 10 ), TEST_LOCATION ); + + tet_infoline("Remove Padding and test Visual is position correctly"); + + imageView.SetProperty( Control::Property::PADDING, Extents( 0, 0, 0, 0 ) ); + + application.SendNotification(); + application.Render(); + + // Check whether Image Visual transforms on ImageVieiw::OnRelayout() + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( imageView ); + Toolkit::Visual::Base imageVisual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + Property::Map resultMap; + imageVisual.CreatePropertyMap( resultMap ); + + Property::Value* transformValue = resultMap.Find( Visual::Property::TRANSFORM ); + DALI_TEST_CHECK( transformValue ); + Property::Map* retMap = transformValue->GetMap(); + DALI_TEST_CHECK( retMap ); + + // Image Visual should be positioned depending on ImageView's padding + DALI_TEST_EQUALS( retMap->Find( Visual::Transform::Property::OFFSET )->Get< Vector2 >(), Vector2( 0, 0 ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewPaddingProperty04(void) +{ + tet_infoline("Test Setting Image Padding then removing it. Visual Fitting Mode as Fill"); + + ToolkitTestApplication application; + + ImageView imageView = ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = TEST_RESOURCE_DIR "/Kid1.svg" ; + imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = 128; + imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = 128; + imagePropertyMap[ DevelVisual::Property::VISUAL_FITTING_MODE ] = Toolkit::DevelVisual::FILL; + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE , imagePropertyMap ); + imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + imageView.SetParentOrigin( ParentOrigin::TOP_LEFT ); + imageView.SetProperty( Control::Property::PADDING, Extents( 15, 10, 5, 10 ) ); + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( imageView.GetProperty( Control::Property::PADDING ), Extents( 15, 10, 5, 10 ), TEST_LOCATION ); + + tet_infoline("Remove Padding and test Visual is position correctly"); + + imageView.SetProperty( Control::Property::PADDING, Extents( 0, 0, 0, 0 ) ); + + application.SendNotification(); + application.Render(); + + // Check whether Image Visual transforms on ImageVieiw::OnRelayout() + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( imageView ); + Toolkit::Visual::Base imageVisual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + Property::Map resultMap; + imageVisual.CreatePropertyMap( resultMap ); + + Property::Value* transformValue = resultMap.Find( Visual::Property::TRANSFORM ); + DALI_TEST_CHECK( transformValue ); + Property::Map* retMap = transformValue->GetMap(); + DALI_TEST_CHECK( retMap ); + + // Image Visual should be positioned depending on ImageView's padding + DALI_TEST_EQUALS( retMap->Find( Visual::Transform::Property::OFFSET )->Get< Vector2 >(), Vector2( 0, 0 ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewTransformTest01(void) +{ + tet_infoline("Test Setting a offset transform on the ImageView"); + + ToolkitTestApplication application; + + ImageView imageView = ImageView::New(); + Property::Map imagePropertyMap; + imagePropertyMap.Add( Toolkit::Visual::Property::TYPE,Toolkit::Visual::IMAGE ) + .Add( Toolkit::ImageVisual::Property::URL,TEST_RESOURCE_DIR "/Kid1.svg" ) + .Add( ImageVisual::Property::DESIRED_WIDTH,120 ) + .Add( ImageVisual::Property::DESIRED_HEIGHT,120 ) + .Add( DevelVisual::Property::VISUAL_FITTING_MODE, Toolkit::DevelVisual::FILL ) + .Add( Visual::Property::TRANSFORM, + Property::Map().Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY, + Vector2( Visual::Transform::Policy::ABSOLUTE, Visual::Transform::Policy::ABSOLUTE ) ) + .Add( Toolkit::Visual::Transform::Property::OFFSET, Vector2( 8, 8 ) ) ); + + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE , imagePropertyMap ); + imageView.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + imageView.SetParentOrigin( ParentOrigin::TOP_LEFT ); + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + // Check whether Image Visual transforms on ImageVieiw::OnRelayout() + Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( imageView ); + Toolkit::Visual::Base imageVisual = DevelControl::GetVisual( controlImpl, ImageView::Property::IMAGE ); + Property::Map resultMap; + imageVisual.CreatePropertyMap( resultMap ); + + Property::Value* transformValue = resultMap.Find( Visual::Property::TRANSFORM ); + DALI_TEST_CHECK( transformValue ); + Property::Map* retMap = transformValue->GetMap(); + DALI_TEST_CHECK( retMap ); + + // Image Visual should be positioned depending on ImageView's padding + DALI_TEST_EQUALS( retMap->Find( Visual::Transform::Property::OFFSET )->Get< Vector2 >(), Vector2( 8, 8 ), TEST_LOCATION ); + DALI_TEST_EQUALS( retMap->Find( Visual::Transform::Property::OFFSET_POLICY )->Get< Vector2 >(), Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewUsingAtlasAndGetNaturalSize(void) +{ + ToolkitTestApplication application; + + // Check ImageView with background and main image, to ensure both visuals are marked as loaded + ImageView imageView = ImageView::New(); + Property::Map imageMap; + imageMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imageMap[ Toolkit::ImageVisual::Property::URL ] = gImage_34_RGBA; + imageMap[ Toolkit::ImageVisual::Property::ATLASING ] = true; + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap ); + Stage::GetCurrent().Add( imageView ); + + // Trigger a potential relayout + application.SendNotification(); + application.Render(); + + Vector3 naturalSize = imageView.GetNaturalSize(); + + DALI_TEST_EQUALS( naturalSize.width, 34.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( naturalSize.height, 34.0f, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliImageViewFillMode(void) +{ + ToolkitTestApplication application; + + tet_infoline( "Create an ImageVisual without padding and set the fill-mode to fill" ); + tet_infoline( " There should be no need to change the transform, our size-policy should be relative and size should be [1,1]"); + + ImageView imageView = ImageView::New(); + Property::Map imageMap; + imageMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE ); + imageMap.Add( Toolkit::ImageVisual::Property::URL, gImage_600_RGB ); + imageMap.Add( DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FittingMode::FILL ); + + imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap ); + + Stage::GetCurrent().Add( imageView ); + + // Trigger a potential relayout + application.SendNotification(); + application.Render(); + + Toolkit::Visual::Base visual = DevelControl::GetVisual( Toolkit::Internal::GetImplementation( imageView ), Toolkit::ImageView::Property::IMAGE ); + Property::Map returnedMap; + visual.CreatePropertyMap( returnedMap ); + + Property::Value* value = returnedMap.Find( Toolkit::Visual::Property::TRANSFORM ); + DALI_TEST_CHECK( value ); + Property::Map* map = value->GetMap(); + DALI_TEST_CHECK( map ); + + // If there's + value = map->Find( Toolkit::Visual::Transform::Property::SIZE ); + DALI_TEST_CHECK( value ); + DALI_TEST_EQUALS( value->Get< Vector2 >(), Vector2::ONE, TEST_LOCATION ); // Relative size so will take up 100% + + value = map->Find( Toolkit::Visual::Transform::Property::SIZE_POLICY ); + DALI_TEST_CHECK( value ); + DALI_TEST_CHECK( value->Get< int >() == Toolkit::Visual::Transform::Policy::RELATIVE ); + + END_TEST; +} + +int UtcDaliImageViewCustomShader(void) +{ + ToolkitTestApplication application; + + // Set a custom shader with an image url + { + 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; + + properties[Visual::Property::TYPE] = Visual::IMAGE; + properties[Visual::Property::SHADER] = shader; + properties[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + + ImageView imageView = ImageView::New(); + imageView.SetProperty( ImageView::Property::IMAGE, properties ); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = imageView.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< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + } + + // Set a custom shader after setting an image url + { + 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; + + properties[Visual::Property::SHADER] = shader; + + ImageView imageView = ImageView::New( TEST_IMAGE_FILE_NAME ); + imageView.SetProperty( ImageView::Property::IMAGE, properties ); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = imageView.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< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + } + + // Set a custom shader before setting an image url + { + 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; + + properties[Visual::Property::SHADER] = shader; + + ImageView imageView = ImageView::New(); + imageView.SetProperty( ImageView::Property::IMAGE, properties ); + imageView.SetProperty( ImageView::Property::IMAGE, TEST_IMAGE_FILE_NAME ); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = imageView.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< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + } + + // Set a custom shader after setting a property map + { + 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; + + properties[Visual::Property::SHADER] = shader; + + Property::Map properties1; + properties1[Visual::Property::TYPE] = Visual::IMAGE; + properties1[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + + ImageView imageView = ImageView::New(); + imageView.SetProperty( ImageView::Property::IMAGE, properties1 ); + imageView.SetProperty( ImageView::Property::IMAGE, properties ); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = imageView.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< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + } + + // Set a custom shader before setting a property map + { + 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; + + properties[Visual::Property::SHADER] = shader; + + Property::Map properties1; + properties1[Visual::Property::TYPE] = Visual::IMAGE; + properties1[ImageVisual::Property::URL] = TEST_IMAGE_FILE_NAME; + + ImageView imageView = ImageView::New(); + imageView.SetProperty( ImageView::Property::IMAGE, properties ); + imageView.SetProperty( ImageView::Property::IMAGE, properties1 ); + + Stage::GetCurrent().Add( imageView ); + + application.SendNotification(); + application.Render(); + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + + Renderer renderer = imageView.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< std::string >(), TEST_LOCATION ); + + Property::Value* vertex = map->Find( "vertex" ); // vertex key name from shader-impl.cpp + DALI_TEST_EQUALS( vertexShader, vertex->Get< std::string >(), TEST_LOCATION ); + } + + END_TEST; +} + + +namespace +{ +static int gFailCounter = 0; +const int MAX_RETRIES(3); + +void ReloadImage(ImageView imageView) +{ + Property::Map imageImmediateLoadingMap; + imageImmediateLoadingMap[ ImageVisual::Property::URL ] = "Non-existant-image.jpg"; + imageImmediateLoadingMap[ ImageVisual::Property::LOAD_POLICY ] = ImageVisual::LoadPolicy::IMMEDIATE; + + tet_infoline("Immediate load an image"); + imageView.SetProperty( ImageView::Property::IMAGE, imageImmediateLoadingMap ); +} + +void ResourceFailedReload( Control control ) +{ + gFailCounter++; + if( gFailCounter < MAX_RETRIES ) + { + ReloadImage(ImageView::DownCast(control)); + } +} +} + +int UtcDaliImageViewReloadFailedOnResourceReadySignal(void) +{ + tet_infoline("Test reloading failed image from within signal handler."); + + ToolkitTestApplication application; + + gFailCounter = 0; + + ImageView imageView = ImageView::New(); + imageView.ResourceReadySignal().Connect( &ResourceFailedReload ); + DALI_TEST_EQUALS( gFailCounter, 0, TEST_LOCATION ); + ReloadImage(imageView); + + // loading started, this waits for the loader thread to complete + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + application.SendNotification(); + + DALI_TEST_EQUALS( gFailCounter, 1, TEST_LOCATION ); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + application.SendNotification(); + + DALI_TEST_EQUALS( gFailCounter, 2, TEST_LOCATION ); + + DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION ); + application.SendNotification(); + DALI_TEST_EQUALS( gFailCounter, 3, TEST_LOCATION ); + + END_TEST; +}