Asynchronous Load N-patch resource 56/221256/34
authorSeungho, Baek <sbsh.baek@samsung.com>
Mon, 30 Dec 2019 12:36:37 +0000 (21:36 +0900)
committerSeungho, Baek <sbsh.baek@samsung.com>
Mon, 17 Feb 2020 22:32:30 +0000 (07:32 +0900)
Change-Id: I1e0a25ca7599198ca5793a585af80e2b7d2e8f48
Signed-off-by: Seungho, Baek <sbsh.baek@samsung.com>
15 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/npatch-loader.cpp
dali-toolkit/internal/visuals/npatch-loader.h
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h
dali-toolkit/internal/visuals/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/internal/visuals/texture-upload-observer.h

index 823c7bb..21f6f7c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,6 +53,12 @@ public:
     mObserverCalled = true;
   }
 
     mObserverCalled = true;
   }
 
+  virtual void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied ) override
+  {
+    mLoaded = loadSuccess;
+    mObserverCalled = true;
+  }
+
   bool mLoaded;
   bool mObserverCalled;
 };
   bool mLoaded;
   bool mObserverCalled;
 };
index d1df2ac..b605cc6 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -2977,8 +2977,11 @@ int UtcDaliVisualSetTransform7(void)
   tet_infoline( "UtcDaliVisualSetTransform: NPatch visual" );
 
   VisualFactory factory = VisualFactory::Get();
   tet_infoline( "UtcDaliVisualSetTransform: NPatch visual" );
 
   VisualFactory factory = VisualFactory::Get();
-  Image image = ResourceImage::New(TEST_NPATCH_FILE_NAME, ImageDimensions(100, 200));
-  Visual::Base visual = factory.CreateVisual(image);
+  Property::Map propertyMap;
+  propertyMap[Toolkit::Visual::Property::TYPE] = Toolkit::Visual::IMAGE;
+  propertyMap[Toolkit::ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
+  propertyMap[Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING] = true;
+  Visual::Base visual = factory.CreateVisual(propertyMap);
   TestTransform( application, visual );
   TestMixColor( visual, Visual::Property::MIX_COLOR, Color::WHITE );
 
   TestTransform( application, visual );
   TestMixColor( visual, Visual::Property::MIX_COLOR, Color::WHITE );
 
@@ -3048,6 +3051,7 @@ int UtcDaliNPatchVisualCustomShader(void)
   properties[Visual::Property::MIX_COLOR] = Color::BLUE;
   properties[Visual::Property::SHADER]=shader;
   properties[ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
   properties[Visual::Property::MIX_COLOR] = Color::BLUE;
   properties[Visual::Property::SHADER]=shader;
   properties[ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
+  properties[ImageVisual::Property::SYNCHRONOUS_LOADING] = true;
 
   Visual::Base visual = factory.CreateVisual( properties );
   TestMixColor( visual, Visual::Property::MIX_COLOR, Color::BLUE );
 
   Visual::Base visual = factory.CreateVisual( properties );
   TestMixColor( visual, Visual::Property::MIX_COLOR, Color::BLUE );
index 69df067..df2d7be 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,6 +26,8 @@
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include "dummy-control.h"
 
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include "dummy-control.h"
 
+#include <dali/integration-api/debug.h>
+
 using namespace Dali;
 using namespace Dali::Toolkit;
 
 using namespace Dali;
 using namespace Dali::Toolkit;
 
@@ -84,6 +86,29 @@ void TestVisualRender( ToolkitTestApplication& application,
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
 }
 
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
 }
 
+void TestVisualAsynchronousRender( ToolkitTestApplication& application,
+                                   DummyControl& actor,
+                                   Visual::Base& visual )
+{
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+  actor.SetSize( 200.f, 200.f );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+}
+
 } // namespace
 
 
 } // namespace
 
 
@@ -439,10 +464,10 @@ int UtcDaliVisualFactoryDefaultOffsetsGradientVisual(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
-int UtcDaliVisualFactoryGetNPatchVisual1(void)
+int UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad1(void)
 {
   ToolkitTestApplication application;
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map" );
+  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad1: Request 9-patch visual with a Property::Map" );
 
   VisualFactory factory = VisualFactory::Get();
   DALI_TEST_CHECK( factory );
 
   VisualFactory factory = VisualFactory::Get();
   DALI_TEST_CHECK( factory );
@@ -453,6 +478,7 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void)
   Property::Map propertyMap;
   propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL, TEST_9_PATCH_FILE_NAME );
   Property::Map propertyMap;
   propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL, TEST_9_PATCH_FILE_NAME );
+  propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true );
   {
     tet_infoline( "whole grid" );
     Visual::Base visual = factory.CreateVisual( propertyMap );
   {
     tet_infoline( "whole grid" );
     Visual::Base visual = factory.CreateVisual( propertyMap );
@@ -495,10 +521,10 @@ int UtcDaliVisualFactoryGetNPatchVisual1(void)
   END_TEST;
 }
 
   END_TEST;
 }
 
-int UtcDaliVisualFactoryGetNPatchVisual2(void)
+int UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad2(void)
 {
   ToolkitTestApplication application;
 {
   ToolkitTestApplication application;
-  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map including border" );
+  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad2: Request 9-patch visual with a Property::Map including border" );
 
   VisualFactory factory = VisualFactory::Get();
   DALI_TEST_CHECK( factory );
 
   VisualFactory factory = VisualFactory::Get();
   DALI_TEST_CHECK( factory );
@@ -510,6 +536,7 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void)
   propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
   propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 2, 2, 2, 2 ) );
   propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
   propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 2, 2, 2, 2 ) );
+  propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true );
   {
     tet_infoline( "whole grid" );
     Visual::Base visual = factory.CreateVisual( propertyMap );
   {
     tet_infoline( "whole grid" );
     Visual::Base visual = factory.CreateVisual( propertyMap );
@@ -553,6 +580,147 @@ int UtcDaliVisualFactoryGetNPatchVisual2(void)
   propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
   propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 1, 1, 1, 1 ) );
   propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
   propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
   propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 1, 1, 1, 1 ) );
+  propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true );
+  {
+    tet_infoline( "whole grid" );
+    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);
+    TestVisualRender( application, actor, visual );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+    Vector2 naturalSize( 0.0f, 0.0f );
+    visual.GetNaturalSize( naturalSize );
+    DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
+int UtcDaliVisualFactoryGetNPatchVisual1(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map" );
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  // Get actual size of test image
+  ImageDimensions imageSize = Dali::GetClosestImageSize( TEST_9_PATCH_FILE_NAME );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
+  propertyMap.Insert( ImageVisual::Property::URL, TEST_9_PATCH_FILE_NAME );
+  propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, false );
+  {
+    tet_infoline( "whole grid" );
+    Visual::Base visual = factory.CreateVisual( propertyMap );
+    DALI_TEST_CHECK( visual );
+
+    Vector2 naturalSize( 0.0f, 0.0f );
+    visual.GetNaturalSize( naturalSize );
+    DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+
+    TestGlAbstraction& gl = application.GetGlAbstraction();
+    TraceCallStack& textureTrace = gl.GetTextureTrace();
+    textureTrace.Enable(true);
+
+    DummyControl actor = DummyControl::New(true);
+    TestVisualAsynchronousRender( application, actor, visual );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+    visual.GetNaturalSize( naturalSize );
+    DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth() - 2.0f, imageSize.GetHeight() - 2.0f ), TEST_LOCATION );
+  }
+
+  propertyMap.Insert( ImageVisual::Property::BORDER_ONLY,  true );
+  {
+    tet_infoline( "border only" );
+    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);
+    TestVisualRender( application, actor, visual );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+    Vector2 naturalSize( 0.0f, 0.0f );
+    visual.GetNaturalSize( naturalSize );
+    DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth() - 2.0f, imageSize.GetHeight() - 2.0f ), TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
+int UtcDaliVisualFactoryGetNPatchVisual2(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual2: Request 9-patch visual with a Property::Map including border" );
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  // Get actual size of test image
+  ImageDimensions imageSize = Dali::GetClosestImageSize( gImage_34_RGBA );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
+  propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
+  propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 2, 2, 2, 2 ) );
+  {
+    tet_infoline( "whole grid" );
+    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);
+    TestVisualAsynchronousRender( application, actor, visual );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+    Vector2 naturalSize( 0.0f, 0.0f );
+    visual.GetNaturalSize( naturalSize );
+    DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+  }
+
+  propertyMap.Insert( ImageVisual::Property::BORDER_ONLY,  true );
+  {
+    tet_infoline( "border only" );
+    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);
+    TestVisualRender( application, actor, visual );
+
+    DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+    Vector2 naturalSize( 0.0f, 0.0f );
+    visual.GetNaturalSize( naturalSize );
+    DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+  }
+
+  propertyMap.Clear();
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
+  propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
+  propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 1, 1, 1, 1 ) );
   {
     tet_infoline( "whole grid" );
     Visual::Base visual = factory.CreateVisual( propertyMap );
   {
     tet_infoline( "whole grid" );
     Visual::Base visual = factory.CreateVisual( propertyMap );
@@ -598,7 +766,7 @@ int UtcDaliVisualFactoryGetNPatchVisual3(void)
     textureTrace.Enable(true);
 
     DummyControl actor = DummyControl::New(true);
     textureTrace.Enable(true);
 
     DummyControl actor = DummyControl::New(true);
-    TestVisualRender( application, actor, visual );
+    TestVisualAsynchronousRender( application, actor, visual );
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -652,9 +820,8 @@ int UtcDaliVisualFactoryGetNPatchVisual4(void)
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
   TestGlAbstraction& gl = application.GetGlAbstraction();
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
-
   DummyControl actor = DummyControl::New(true);
   DummyControl actor = DummyControl::New(true);
-  TestVisualRender( application, actor, visual );
+  TestVisualAsynchronousRender( application, actor, visual );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -698,7 +865,7 @@ int UtcDaliVisualFactoryGetNPatchVisual5(void)
   textureTrace.Enable(true);
 
   DummyControl actor = DummyControl::New(true);
   textureTrace.Enable(true);
 
   DummyControl actor = DummyControl::New(true);
-  TestVisualRender( application, actor, visual );
+  TestVisualAsynchronousRender( application, actor, visual );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -733,7 +900,7 @@ int UtcDaliVisualFactoryGetNPatchVisual6(void)
     textureTrace.Enable(true);
 
     DummyControl actor = DummyControl::New(true);
     textureTrace.Enable(true);
 
     DummyControl actor = DummyControl::New(true);
-    TestVisualRender( application, actor, visual );
+    TestVisualAsynchronousRender( application, actor, visual );
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -761,7 +928,7 @@ int UtcDaliVisualFactoryGetNPatchVisual6(void)
     textureTrace.Enable(true);
 
     DummyControl actor = DummyControl::New(true);
     textureTrace.Enable(true);
 
     DummyControl actor = DummyControl::New(true);
-    TestVisualRender( application, actor, visual );
+    TestVisualAsynchronousRender( application, actor, visual );
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
     DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -810,6 +977,12 @@ int UtcDaliNPatchVisualAuxiliaryImage(void)
   dummy.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
   dummy.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add(dummy);
   dummy.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
   dummy.SetParentOrigin(ParentOrigin::CENTER);
   Stage::GetCurrent().Add(dummy);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+
   application.SendNotification();
   application.Render();
 
   application.SendNotification();
   application.Render();
 
@@ -839,7 +1012,7 @@ int UtcDaliVisualFactoryGetNPatchVisualN1(void)
   textureTrace.Enable(true);
 
   DummyControl actor = DummyControl::New(true);
   textureTrace.Enable(true);
 
   DummyControl actor = DummyControl::New(true);
-  TestVisualRender( application, actor, visual );
+  TestVisualAsynchronousRender( application, actor, visual );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
@@ -870,7 +1043,7 @@ int UtcDaliVisualFactoryGetNPatchVisualN2(void)
   drawTrace.Enable(true);
 
   DummyControl actor = DummyControl::New(true);
   drawTrace.Enable(true);
 
   DummyControl actor = DummyControl::New(true);
-  TestVisualRender( application, actor, visual );
+  TestVisualAsynchronousRender( application, actor, visual );
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
 
   DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
 
index e64a51b..9acf1af 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -190,6 +190,17 @@ void FixedImageCache::UploadComplete(
   }
 }
 
   }
 }
 
+void FixedImageCache::LoadComplete(
+  bool loadSuccess,
+  Devel::PixelBuffer pixelBuffer,
+  const VisualUrl& url,
+  bool preMultiplied )
+{
+  // LoadComplete is called if this TextureUploadObserver requested to load
+  // an image that will be returned as a type of PixelBuffer by using a method
+  // TextureManager::LoadPixelBuffer.
+}
+
 } //namespace Internal
 } //namespace Toolkit
 } //namespace Internal
 } //namespace Toolkit
-} //namespace Dali
+} //namespace Dali
\ No newline at end of file
index ceb9fff..72484a4 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_FIXED_IMAGE_CACHE_H
 
 /*
 #define DALI_TOOLKIT_INTERNAL_FIXED_IMAGE_CACHE_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -96,7 +96,13 @@ protected:
     TextureSet     textureSet,
     bool           useAtlasing,
     const Vector4& atlasRect,
     TextureSet     textureSet,
     bool           useAtlasing,
     const Vector4& atlasRect,
-    bool           premultiplied) override;
+    bool           premultiplied ) override;
+
+  void LoadComplete(
+    bool loadSuccess,
+    Devel::PixelBuffer pixelBuffer,
+    const VisualUrl& url,
+    bool preMultiplied ) override;
 
 private:
   std::vector<UrlStore>& mImageUrls;
 
 private:
   std::vector<UrlStore>& mImageUrls;
index c39be7e..b7b45ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -231,6 +231,17 @@ void RollingImageCache::UploadComplete(
   LOG_CACHE;
 }
 
   LOG_CACHE;
 }
 
+void RollingImageCache::LoadComplete(
+  bool loadSuccess,
+  Devel::PixelBuffer pixelBuffer,
+  const VisualUrl& url,
+  bool preMultiplied )
+{
+  // LoadComplete is called if this TextureUploadObserver requested to load
+  // an image that will be returned as a type of PixelBuffer by using a method
+  // TextureManager::LoadPixelBuffer.
+}
+
 } //namespace Internal
 } //namespace Toolkit
 } //namespace Dali
 } //namespace Internal
 } //namespace Toolkit
 } //namespace Dali
index c5650cf..a0d734d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_ROLLING_IMAGE_CACHE_H
 
 /*
 #define DALI_TOOLKIT_INTERNAL_ROLLING_IMAGE_CACHE_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -114,6 +114,12 @@ protected:
     const Vector4& atlasRect,
     bool           preMultiplied ) override;
 
     const Vector4& atlasRect,
     bool           preMultiplied ) override;
 
+  void LoadComplete(
+    bool loadSuccess,
+    Devel::PixelBuffer pixelBuffer,
+    const VisualUrl& url,
+    bool preMultiplied ) override;
+
 private:
   /**
    * Secondary class to hold readiness and index into url
 private:
   /**
    * Secondary class to hold readiness and index into url
index dcd76f6..ea46680 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
 
 /*
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -271,6 +271,14 @@ public:
 private:
 
   /**
 private:
 
   /**
+   * @copydoc TextureUploadObserver::LoadComplete
+   *
+   * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+   * This callback is the place to add the renderer as it would be called once the PixelBuffer loading is finished.
+   */
+  void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied ) override {}
+
+  /**
    * Allocate the mask data when a masking property is defined in the property map
    */
   void AllocateMaskData();
    * Allocate the mask data when a masking property is defined in the property map
    */
   void AllocateMaskData();
index e89ebcb..6745adf 100644 (file)
@@ -1,5 +1,5 @@
  /*
  /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
 
 // EXTERNAL HEADER
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 
 // EXTERNAL HEADER
 #include <dali/devel-api/adaptor-framework/image-loading.h>
-#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/common/hash.h>
 #include <dali/integration-api/debug.h>
 
 #include <dali/devel-api/common/hash.h>
 #include <dali/integration-api/debug.h>
 
@@ -248,6 +247,35 @@ void ParseBorders( Devel::PixelBuffer& pixelBuffer, NPatchLoader::Data* data  )
   }
 }
 
   }
 }
 
+void SetLoadedNPatchData( NPatchLoader::Data* data, Devel::PixelBuffer& pixelBuffer )
+{
+  if( data->border == Rect< int >( 0, 0, 0, 0 ) )
+  {
+    NPatchBuffer::ParseBorders( pixelBuffer, data );
+
+    // Crop the image
+    pixelBuffer.Crop( 1, 1, pixelBuffer.GetWidth() - 2, pixelBuffer.GetHeight() - 2 );
+  }
+  else
+  {
+    data->stretchPixelsX.PushBack( Uint16Pair( data->border.left, ( (pixelBuffer.GetWidth() >= static_cast< unsigned int >( data->border.right )) ? pixelBuffer.GetWidth() - data->border.right : 0 ) ) );
+    data->stretchPixelsY.PushBack( Uint16Pair( data->border.top, ( (pixelBuffer.GetHeight() >= static_cast< unsigned int >( data->border.bottom )) ? pixelBuffer.GetHeight() - data->border.bottom : 0 ) ) );
+  }
+
+  data->croppedWidth = pixelBuffer.GetWidth();
+  data->croppedHeight = pixelBuffer.GetHeight();
+
+  PixelData pixels = Devel::PixelBuffer::Convert( pixelBuffer ); // takes ownership of buffer
+
+  Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
+  texture.Upload( pixels );
+
+  data->textureSet = TextureSet::New();
+  data->textureSet.SetTexture( 0u, texture );
+
+  data->loadCompleted = true;
+}
+
 } // namespace NPatchBuffer
 
 NPatchLoader::NPatchLoader()
 } // namespace NPatchBuffer
 
 NPatchLoader::NPatchLoader()
@@ -258,12 +286,13 @@ NPatchLoader::~NPatchLoader()
 {
 }
 
 {
 }
 
-std::size_t NPatchLoader::Load( const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad )
+std::size_t NPatchLoader::Load( TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading )
 {
   std::size_t hash = CalculateHash( url );
   OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
   const OwnerContainer< Data* >::SizeType count = mCache.Count();
   int cachedIndex = -1;
 {
   std::size_t hash = CalculateHash( url );
   OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
   const OwnerContainer< Data* >::SizeType count = mCache.Count();
   int cachedIndex = -1;
+  Data* data;
 
   for( ; index < count; ++index )
   {
 
   for( ; index < count; ++index )
   {
@@ -275,92 +304,85 @@ std::size_t NPatchLoader::Load( const std::string& url, const Rect< int >& borde
         // Use cached data
         if( mCache[ index ]->border == border )
         {
         // Use cached data
         if( mCache[ index ]->border == border )
         {
-          return index+1u; // valid indices are from 1 onwards
+          if( mCache[ index ]->loadCompleted )
+          {
+            return index + 1u; // valid indices are from 1 onwards
+          }
+          data = mCache[ index ];
+          cachedIndex = index + 1u; // valid indices are from 1 onwards
+          break;
         }
         else
         {
         }
         else
         {
-          cachedIndex = index;
-        }
-      }
-    }
-  }
+          if( mCache[ index ]->loadCompleted )
+          {
+            // Same url but border is different - use the existing texture
+            Data* data = new Data();
+            data->hash = hash;
+            data->url = url;
+            data->croppedWidth = mCache[ index ]->croppedWidth;
+            data->croppedHeight = mCache[ index ]->croppedHeight;
 
 
-  if( cachedIndex != -1 )
-  {
-    // Same url but border is different - use the existing texture
-    Data* data = new Data();
-    data->hash = hash;
-    data->url = url;
-    data->croppedWidth = mCache[ cachedIndex ]->croppedWidth;
-    data->croppedHeight = mCache[ cachedIndex ]->croppedHeight;
+            data->textureSet = mCache[ index ]->textureSet;
 
 
-    data->textureSet = mCache[ cachedIndex ]->textureSet;
+            StretchRanges stretchRangesX;
+            stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
 
 
-    StretchRanges stretchRangesX;
-    stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
+            StretchRanges stretchRangesY;
+            stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
 
 
-    StretchRanges stretchRangesY;
-    stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
+            data->stretchPixelsX = stretchRangesX;
+            data->stretchPixelsY = stretchRangesY;
+            data->border = border;
 
 
-    data->stretchPixelsX = stretchRangesX;
-    data->stretchPixelsY = stretchRangesY;
-    data->border = border;
+            data->loadCompleted = mCache[ index ]->loadCompleted;
 
 
-    mCache.PushBack( data );
+            mCache.PushBack( data );
 
 
-    return mCache.Count(); // valid ids start from 1u
+            return mCache.Count(); // valid ids start from 1u
+          }
+        }
+      }
+    }
   }
 
   }
 
-  // got to the end so no match, decode N patch and append new item to cache
-  Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
-  if( pixelBuffer )
+  if( cachedIndex == -1 )
   {
   {
-    Data* data = new Data();
+    data = new Data();
+    data->loadCompleted = false;
     data->hash = hash;
     data->url = url;
     data->hash = hash;
     data->url = url;
+    data->border = border;
 
 
-    if( border == Rect< int >( 0, 0, 0, 0 ) )
-    {
-      NPatchBuffer::ParseBorders( pixelBuffer, data );
-
-      data->border = Rect< int >( 0, 0, 0, 0 );
-
-      // Crop the image
-      pixelBuffer.Crop( 1, 1, pixelBuffer.GetWidth() - 2, pixelBuffer.GetHeight() - 2 );
-    }
-    else
-    {
-      data->stretchPixelsX.PushBack( Uint16Pair( border.left, ( (pixelBuffer.GetWidth() >= static_cast< unsigned int >( border.right )) ? pixelBuffer.GetWidth() - border.right : 0 ) ) );
-      data->stretchPixelsY.PushBack( Uint16Pair( border.top, ( (pixelBuffer.GetHeight() >= static_cast< unsigned int >( border.bottom )) ? pixelBuffer.GetHeight() - border.bottom : 0 ) ) );
-      data->border = border;
-    }
-
-    data->croppedWidth = pixelBuffer.GetWidth();
-    data->croppedHeight = pixelBuffer.GetHeight();
+    mCache.PushBack( data );
 
 
-    if( preMultiplyOnLoad && Pixel::HasAlpha( pixelBuffer.GetPixelFormat() ) )
-    {
-      pixelBuffer.MultiplyColorByAlpha();
-    }
-    else
-    {
-      preMultiplyOnLoad = false;
-    }
+    cachedIndex = mCache.Count();
+  }
 
 
-    PixelData pixels = Devel::PixelBuffer::Convert( pixelBuffer ); // takes ownership of buffer
+  auto preMultiplyOnLoading = preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+                                                : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+  Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer( url, Dali::ImageDimensions(), FittingMode::DEFAULT,
+                                                                   SamplingMode::BOX_THEN_LINEAR, synchronousLoading,
+                                                                   textureObserver, true, preMultiplyOnLoading );
 
 
-    Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
-    texture.Upload( pixels );
+  if( pixelBuffer )
+  {
+    NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer );
+    preMultiplyOnLoad = ( preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ) ? true : false;
+  }
 
 
-    data->textureSet = TextureSet::New();
-    data->textureSet.SetTexture( 0u, texture );
+  return cachedIndex;
+}
 
 
-    mCache.PushBack( data );
+void NPatchLoader::SetNPatchData( std::size_t id, Devel::PixelBuffer& pixelBuffer )
+{
+  Data* data;
+  data = mCache[ id - 1u ];
 
 
-    return mCache.Count(); // valid ids start from 1u
+  if( !data->loadCompleted )
+  {
+    NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer );
   }
   }
-
-  return 0u;
 }
 
 bool NPatchLoader::GetNPatchData( std::size_t id, const Data*& data )
 }
 
 bool NPatchLoader::GetNPatchData( std::size_t id, const Data*& data )
index 8c75477..0d39d0d 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_NPATCH_LOADER_H
 
 /*
 #define DALI_TOOLKIT_NPATCH_LOADER_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali/public-api/math/uint-16-pair.h>
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali/public-api/math/uint-16-pair.h>
 #include <dali/devel-api/common/owner-container.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
 
 namespace Dali
 {
 
 namespace Dali
 {
@@ -61,6 +65,10 @@ public:
 
   struct Data
   {
 
   struct Data
   {
+    Data()
+    : loadCompleted( false )
+    {}
+
     std::string url;                              ///< Url of the N-Patch
     TextureSet textureSet;                        ///< Texture containing the cropped image
     StretchRanges stretchPixelsX;                 ///< X stretch pixels
     std::string url;                              ///< Url of the N-Patch
     TextureSet textureSet;                        ///< Texture containing the cropped image
     StretchRanges stretchPixelsX;                 ///< X stretch pixels
@@ -69,6 +77,7 @@ public:
     uint32_t croppedWidth;                        ///< Width of the cropped middle part of N-patch
     uint32_t croppedHeight;                       ///< Height of the cropped middle part of N-patch
     Rect< int > border;                           ///< The size of the border
     uint32_t croppedWidth;                        ///< Width of the cropped middle part of N-patch
     uint32_t croppedHeight;                       ///< Height of the cropped middle part of N-patch
     Rect< int > border;                           ///< The size of the border
+    bool loadCompleted;                           ///< True if the data loading is completed
   };
 
 public:
   };
 
 public:
@@ -86,13 +95,24 @@ public:
   /**
    * @brief Retrieve a texture matching the n-patch url.
    *
   /**
    * @brief Retrieve a texture matching the n-patch url.
    *
+   * @param [in] textureManager that will be used to loading image
+   * @param [in] textureObserver The NPatchVisual that requested loading.
    * @param [in] url to retrieve
    * @param [in] border The border size of the image
    * @param [in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
    *                                   image has no alpha channel
    * @param [in] url to retrieve
    * @param [in] border The border size of the image
    * @param [in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
    *                                   image has no alpha channel
+   * @param [in] synchronousLoading True if the image will be loaded in synchronous time.
    * @return id of the texture.
    */
    * @return id of the texture.
    */
-  std::size_t Load( const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad );
+  std::size_t Load( TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading );
+
+  /**
+   * @brief Set loaded PixelBuffer and its information
+   *
+   * @param [in] id cache data id
+   * @param [in] pixelBuffer of loaded image
+   */
+  void SetNPatchData( std::size_t id, Devel::PixelBuffer& pixelBuffer );
 
   /**
    * @brief Retrieve N patch data matching to an id
 
   /**
    * @brief Retrieve N patch data matching to an id
index 85fc08c..af09393 100755 (executable)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@ const char * const BORDER_ONLY( "borderOnly" );
 const char * const BORDER( "border" );
 const char * const AUXILIARY_IMAGE_NAME( "auxiliaryImage" );
 const char * const AUXILIARY_IMAGE_ALPHA_NAME( "auxiliaryImageAlpha" );
 const char * const BORDER( "border" );
 const char * const AUXILIARY_IMAGE_NAME( "auxiliaryImage" );
 const char * const AUXILIARY_IMAGE_ALPHA_NAME( "auxiliaryImageAlpha" );
+const char * const SYNCHRONOUS_LOADING( "synchronousLoading" );
 
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
 
 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
@@ -288,20 +289,28 @@ NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, NinePatchIm
 
 void NPatchVisual::LoadImages()
 {
 
 void NPatchVisual::LoadImages()
 {
+  TextureManager& textureManager = mFactoryCache.GetTextureManager();
+  bool synchronousLoading = mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+
   if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocalResource() )
   {
     bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
   if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocalResource() )
   {
     bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
+    mId = mLoader.Load( textureManager, this, mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad, synchronousLoading );
 
 
-    mId = mLoader.Load( mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad );
-
-    EnablePreMultipliedAlpha( preMultiplyOnLoad );
+    const NPatchLoader::Data* data;
+    if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
+    {
+      EnablePreMultipliedAlpha( preMultiplyOnLoad );
+    }
   }
 
   }
 
-  if( ! mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && mAuxiliaryUrl.IsLocalResource() )
+  if( !mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && mAuxiliaryUrl.IsLocalResource() )
   {
   {
-    // Load the auxiliary image synchronously
-    mAuxiliaryPixelBuffer = Dali::LoadImageFromFile( mAuxiliaryUrl.GetUrl(), ImageDimensions(),
-                                                     FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+    // Load the auxiliary image
+    auto preMultiplyOnLoading = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+    mAuxiliaryPixelBuffer = textureManager.LoadPixelBuffer( mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT,
+                                                            SamplingMode::BOX_THEN_LINEAR, synchronousLoading,
+                                                            this, true, preMultiplyOnLoading );
   }
 }
 
   }
 }
 
@@ -311,14 +320,24 @@ void NPatchVisual::GetNaturalSize( Vector2& naturalSize )
   naturalSize.y = 0u;
 
   // load now if not already loaded
   naturalSize.y = 0u;
 
   // load now if not already loaded
-  LoadImages();
-
   const NPatchLoader::Data* data;
   const NPatchLoader::Data* data;
-  if( mLoader.GetNPatchData( mId, data ) )
+  if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
   {
     naturalSize.x = data->croppedWidth;
     naturalSize.y = data->croppedHeight;
   }
   {
     naturalSize.x = data->croppedWidth;
     naturalSize.y = data->croppedHeight;
   }
+  else
+  {
+    if( mImageUrl.IsValid() )
+    {
+      ImageDimensions dimensions = Dali::GetOriginalImageSize( mImageUrl.GetUrl() );
+      if( dimensions != ImageDimensions( 0, 0 ) )
+      {
+        naturalSize.x = dimensions.GetWidth();
+        naturalSize.y = dimensions.GetHeight();
+      }
+    }
+  }
 
   if( mAuxiliaryPixelBuffer )
   {
 
   if( mAuxiliaryPixelBuffer )
   {
@@ -366,6 +385,21 @@ void NPatchVisual::DoSetProperties( const Property::Map& propertyMap )
   {
     auxImageAlpha->Get( mAuxiliaryImageAlpha );
   }
   {
     auxImageAlpha->Get( mAuxiliaryImageAlpha );
   }
+
+  Property::Value* synchronousLoading = propertyMap.Find( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, SYNCHRONOUS_LOADING );
+  if( synchronousLoading )
+  {
+    bool sync = false;
+    synchronousLoading->Get( sync );
+    if( sync )
+    {
+      mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+    }
+    else
+    {
+      mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+    }
+  }
 }
 
 void NPatchVisual::DoSetOnStage( Actor& actor )
 }
 
 void NPatchVisual::DoSetOnStage( Actor& actor )
@@ -373,22 +407,32 @@ void NPatchVisual::DoSetOnStage( Actor& actor )
   // load when first go on stage
   LoadImages();
 
   // load when first go on stage
   LoadImages();
 
-  Geometry geometry = CreateGeometry();
-  Shader shader = CreateShader();
-  mImpl->mRenderer = Renderer::New( geometry, shader );
+  const NPatchLoader::Data* data;
+  if( mLoader.GetNPatchData( mId, data ) )
+  {
+    Geometry geometry = CreateGeometry();
+    Shader shader = CreateShader();
 
 
-  ApplyTextureAndUniforms();
+    mImpl->mRenderer = Renderer::New( geometry, shader );
 
 
-  actor.AddRenderer( mImpl->mRenderer );
+    mPlacementActor = actor;
+    if( data->loadCompleted )
+    {
+      ApplyTextureAndUniforms();
+      actor.AddRenderer( mImpl->mRenderer );
+      mPlacementActor.Reset();
 
 
-  // npatch loaded and ready to display
-  ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+      // npatch loaded and ready to display
+      ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+    }
+  }
 }
 
 void NPatchVisual::DoSetOffStage( Actor& actor )
 {
   actor.RemoveRenderer( mImpl->mRenderer );
   mImpl->mRenderer.Reset();
 }
 
 void NPatchVisual::DoSetOffStage( Actor& actor )
 {
   actor.RemoveRenderer( mImpl->mRenderer );
   mImpl->mRenderer.Reset();
+  mPlacementActor.Reset();
 }
 
 void NPatchVisual::OnSetTransform()
 }
 
 void NPatchVisual::OnSetTransform()
@@ -425,6 +469,7 @@ void NPatchVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
 
 NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache, Visual::FittingMode::FILL ),
 
 NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache, Visual::FittingMode::FILL ),
+  mPlacementActor(),
   mLoader( factoryCache.GetNPatchLoader() ),
   mImageUrl(),
   mAuxiliaryUrl(),
   mLoader( factoryCache.GetNPatchLoader() ),
   mImageUrl(),
   mAuxiliaryUrl(),
@@ -444,7 +489,7 @@ Geometry NPatchVisual::CreateGeometry()
 {
   Geometry geometry;
   const NPatchLoader::Data* data;
 {
   Geometry geometry;
   const NPatchLoader::Data* data;
-  if( mLoader.GetNPatchData( mId, data ) )
+  if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
   {
     if( data->stretchPixelsX.Size() == 1 && data->stretchPixelsY.Size() == 1 )
     {
   {
     if( data->stretchPixelsX.Size() == 1 && data->stretchPixelsY.Size() == 1 )
     {
@@ -556,7 +601,7 @@ void NPatchVisual::ApplyTextureAndUniforms()
   const NPatchLoader::Data* data;
   TextureSet textureSet;
 
   const NPatchLoader::Data* data;
   TextureSet textureSet;
 
-  if( mLoader.GetNPatchData( mId, data ) )
+  if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
   {
     textureSet = data->textureSet;
 
   {
     textureSet = data->textureSet;
 
@@ -773,6 +818,56 @@ Geometry NPatchVisual::CreateBorderGeometry( Uint16Pair gridSize )
   return GenerateGeometry( vertices, indices );
 }
 
   return GenerateGeometry( vertices, indices );
 }
 
+void NPatchVisual::SetResource()
+{
+  const NPatchLoader::Data* data;
+  if( mLoader.GetNPatchData( mId, data ) )
+  {
+    Geometry geometry = CreateGeometry();
+    Shader shader = CreateShader();
+
+    mImpl->mRenderer.SetGeometry( geometry );
+    mImpl->mRenderer.SetShader( shader );
+
+    Actor actor = mPlacementActor.GetHandle();
+    if( actor )
+    {
+      ApplyTextureAndUniforms();
+      actor.AddRenderer( mImpl->mRenderer );
+      mPlacementActor.Reset();
+
+      // npatch loaded and ready to display
+      ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+    }
+  }
+}
+
+void NPatchVisual::LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied )
+{
+  if( url.GetUrl() == mAuxiliaryUrl.GetUrl() )
+  {
+    mAuxiliaryPixelBuffer = pixelBuffer;
+    const NPatchLoader::Data* data;
+    if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
+    {
+      SetResource();
+    }
+  }
+  else
+  {
+    if( loadSuccess )
+    {
+      mLoader.SetNPatchData( mId, pixelBuffer );
+      EnablePreMultipliedAlpha( preMultiplied );
+    }
+
+    if( mAuxiliaryPixelBuffer || !mAuxiliaryUrl.IsValid() )
+    {
+      SetResource();
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
 } // namespace Internal
 
 } // namespace Toolkit
index a761628..7816e84 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_N_PATCH_VISUAL_H
 
 /*
 #define DALI_TOOLKIT_INTERNAL_N_PATCH_VISUAL_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/sampler.h>
 #include <dali/public-api/rendering/shader.h>
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/sampler.h>
 #include <dali/public-api/rendering/shader.h>
+#include <dali/public-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/texture-upload-observer.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/visual-url.h>
 
@@ -56,7 +58,7 @@ typedef IntrusivePtr< NPatchVisual > NPatchVisualPtr;
  * | auxiliaryImage           | STRING           |
  * | auxiliaryImageAlpha      | FLOAT            |
  */
  * | auxiliaryImage           | STRING           |
  * | auxiliaryImageAlpha      | FLOAT            |
  */
-class NPatchVisual: public Visual::Base
+class NPatchVisual: public Visual::Base, public TextureUploadObserver
 {
 public:
 
 {
 public:
 
@@ -206,8 +208,32 @@ private:
    */
   Geometry CreateBorderGeometry( Uint16Pair gridSize );
 
    */
   Geometry CreateBorderGeometry( Uint16Pair gridSize );
 
+  /**
+   * @brief Creates a renderer by using loaded resource.
+   */
+  void SetResource();
+
+private:
+
+  /**
+   * @copydoc TextureUploadObserver::UploadCompleted
+   *
+   * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+   * This callback is the place to add the renderer as it would be called once the loading is finished.
+   */
+  void UploadComplete( bool loadSuccess, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect, bool preMultiplied ) override {}
+
+  /**
+   * @copydoc TextureUploadObserver::LoadComplete
+   *
+   * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+   * This callback is the place to add the renderer as it would be called once the loading is finished.
+   */
+  void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied ) override;
+
 private:
 
 private:
 
+  WeakHandle<Actor>  mPlacementActor;       ///< Weakhandle to contain Actor during texture loading
   NPatchLoader&      mLoader;               ///< reference to N patch loader for fast access
   VisualUrl          mImageUrl;             ///< The url to the N patch to load
   VisualUrl          mAuxiliaryUrl;         ///< An auxiliary image that can be displayed on top of the N-Patch
   NPatchLoader&      mLoader;               ///< reference to N patch loader for fast access
   VisualUrl          mImageUrl;             ///< The url to the N patch to load
   VisualUrl          mAuxiliaryUrl;         ///< An auxiliary image that can be displayed on top of the N-Patch
index bf78d25..b34b9f1 100644 (file)
@@ -144,6 +144,32 @@ TextureManager::~TextureManager()
   }
 }
 
   }
 }
 
+Devel::PixelBuffer TextureManager::LoadPixelBuffer(
+  const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode, bool synchronousLoading, TextureUploadObserver* textureObserver, bool orientationCorrection, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
+{
+  Devel::PixelBuffer pixelBuffer;
+  if( synchronousLoading )
+  {
+    if( url.IsValid() )
+    {
+      pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode,
+                                       orientationCorrection  );
+      if( pixelBuffer && preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD )
+      {
+        PreMultiply( pixelBuffer, preMultiplyOnLoad );
+      }
+    }
+  }
+  else
+  {
+    RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS,
+                         false, KEEP_PIXEL_BUFFER, textureObserver, orientationCorrection, TextureManager::ReloadPolicy::FORCED,
+                         preMultiplyOnLoad, true );
+  }
+
+  return pixelBuffer;
+}
+
 TextureSet TextureManager::LoadTexture(
   const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
   Dali::SamplingMode::Type samplingMode, MaskingDataPointer& maskInfo,
 TextureSet TextureManager::LoadTexture(
   const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
   Dali::SamplingMode::Type samplingMode, MaskingDataPointer& maskInfo,
@@ -311,7 +337,7 @@ TextureManager::TextureId TextureManager::RequestLoad(
 {
   return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas,
                               false, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy,
 {
   return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas,
                               false, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy,
-                              preMultiplyOnLoad );
+                              preMultiplyOnLoad, false );
 }
 
 TextureManager::TextureId TextureManager::RequestLoad(
 }
 
 TextureManager::TextureId TextureManager::RequestLoad(
@@ -330,7 +356,7 @@ TextureManager::TextureId TextureManager::RequestLoad(
 {
   return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas,
                               cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy,
 {
   return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas,
                               cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy,
-                              preMultiplyOnLoad );
+                              preMultiplyOnLoad, false );
 }
 
 TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl )
 }
 
 TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl )
@@ -339,7 +365,7 @@ TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& mask
   auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
   return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL,
                               SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true,
   auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
   return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL,
                               SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true,
-                              TextureManager::ReloadPolicy::CACHED, preMultiply );
+                              TextureManager::ReloadPolicy::CACHED, preMultiply, false );
 }
 
 TextureManager::TextureId TextureManager::RequestLoadInternal(
 }
 
 TextureManager::TextureId TextureManager::RequestLoadInternal(
@@ -355,7 +381,8 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
   TextureUploadObserver*          observer,
   bool                            orientationCorrection,
   TextureManager::ReloadPolicy    reloadPolicy,
   TextureUploadObserver*          observer,
   bool                            orientationCorrection,
   TextureManager::ReloadPolicy    reloadPolicy,
-  TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
+  TextureManager::MultiplyOnLoad& preMultiplyOnLoad,
+  bool                            loadPixelBuffer )
 {
   // First check if the requested Texture is cached.
   const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas,
 {
   // First check if the requested Texture is cached.
   const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas,
@@ -393,7 +420,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     mTextureInfoContainer.push_back( TextureInfo( textureId, maskTextureId, url.GetUrl(),
                                                   desiredSize, contentScale, fittingMode, samplingMode,
                                                   false, cropToMask, useAtlas, textureHash, orientationCorrection,
     mTextureInfoContainer.push_back( TextureInfo( textureId, maskTextureId, url.GetUrl(),
                                                   desiredSize, contentScale, fittingMode, samplingMode,
                                                   false, cropToMask, useAtlas, textureHash, orientationCorrection,
-                                                  preMultiply ) );
+                                                  preMultiply, loadPixelBuffer ) );
     cacheIndex = mTextureInfoContainer.size() - 1u;
 
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n",
     cacheIndex = mTextureInfoContainer.size() - 1u;
 
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n",
@@ -459,7 +486,11 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
       break;
     }
     case TextureManager::LOAD_FINISHED:
       break;
     }
     case TextureManager::LOAD_FINISHED:
-      // Loading has already completed. Do nothing.
+      // Loading has already completed.
+      if( observer && textureInfo.loadPixelBuffer )
+      {
+        LoadOrQueueTexture( textureInfo, observer );
+      }
       break;
   }
 
       break;
   }
 
@@ -755,6 +786,10 @@ void TextureManager::ProcessQueuedTextures()
                                            textureInfo.useAtlas, textureInfo.atlasRect,
                                            textureInfo.preMultiplied );
       }
                                            textureInfo.useAtlas, textureInfo.atlasRect,
                                            textureInfo.preMultiplied );
       }
+      else if ( textureInfo.loadState == LOAD_FINISHED && textureInfo.loadPixelBuffer )
+      {
+        element.mObserver->LoadComplete( true, textureInfo.pixelBuffer, textureInfo.url, textureInfo.preMultiplied );
+      }
       else
       {
         LoadTexture( textureInfo, element.mObserver );
       else
       {
         LoadTexture( textureInfo, element.mObserver );
@@ -820,6 +855,7 @@ void TextureManager::PostLoad( TextureInfo& textureInfo, Devel::PixelBuffer& pix
   {
     // No atlas support for now
     textureInfo.useAtlas = NO_ATLAS;
   {
     // No atlas support for now
     textureInfo.useAtlas = NO_ATLAS;
+    textureInfo.preMultiplied = pixelBuffer.IsAlphaPreMultiplied();
 
     if( textureInfo.storageType == UPLOAD_TO_TEXTURE )
     {
 
     if( textureInfo.storageType == UPLOAD_TO_TEXTURE )
     {
@@ -860,6 +896,10 @@ void TextureManager::PostLoad( TextureInfo& textureInfo, Devel::PixelBuffer& pix
       textureInfo.pixelBuffer = pixelBuffer; // Store the pixel data
       textureInfo.loadState = LOAD_FINISHED;
 
       textureInfo.pixelBuffer = pixelBuffer; // Store the pixel data
       textureInfo.loadState = LOAD_FINISHED;
 
+      if( textureInfo.loadPixelBuffer )
+      {
+        NotifyObservers( textureInfo, true );
+      }
       // Check if there was another texture waiting for this load to complete
       // (e.g. if this was an image mask, and its load is on a different thread)
       CheckForWaitingTexture( textureInfo );
       // Check if there was another texture waiting for this load to complete
       // (e.g. if this was an image mask, and its load is on a different thread)
       CheckForWaitingTexture( textureInfo );
@@ -976,8 +1016,16 @@ void TextureManager::NotifyObservers( TextureInfo& textureInfo, bool success )
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "NotifyObservers() url:%s loadState:%s\n",
                    textureInfo.url.GetUrl().c_str(), GET_LOAD_STATE_STRING(textureInfo.loadState ) );
 
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "NotifyObservers() url:%s loadState:%s\n",
                    textureInfo.url.GetUrl().c_str(), GET_LOAD_STATE_STRING(textureInfo.loadState ) );
 
-    observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect,
-                              info->preMultiplied );
+    if( info->loadPixelBuffer )
+    {
+      observer->LoadComplete( success, info->pixelBuffer, info->url, info->preMultiplied );
+    }
+    else
+    {
+      observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect,
+                                info->preMultiplied );
+    }
+
     observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed );
 
     // Get the textureInfo from the container again as it may have been invalidated.
     observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed );
 
     // Get the textureInfo from the container again as it may have been invalidated.
@@ -1001,6 +1049,11 @@ void TextureManager::NotifyObservers( TextureInfo& textureInfo, bool success )
 
   mQueueLoadFlag = false;
   ProcessQueuedTextures();
 
   mQueueLoadFlag = false;
   ProcessQueuedTextures();
+
+  if( info->loadPixelBuffer && info->observerList.Count() == 0 )
+  {
+    Remove( info->textureId, nullptr );
+  }
 }
 
 TextureManager::TextureId TextureManager::GenerateUniqueTextureId()
 }
 
 TextureManager::TextureId TextureManager::GenerateUniqueTextureId()
index 7d66256..5146991 100755 (executable)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
 
 /*
 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
 
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -163,6 +163,36 @@ public:
   // TextureManager Main API:
 
   /**
   // TextureManager Main API:
 
   /**
+   * @brief Requests an image load of the given URL to get PixelBuffer.
+   *
+   * The parameters are used to specify how the image is loaded.
+   * The observer has the LoadComplete method called when the load is ready.
+   *
+   * @param[in] url                   The URL of the image to load
+   * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
+   * @param[in] fittingMode           The FittingMode to use
+   * @param[in] samplingMode          The SamplingMode to use
+   * @param[in] synchronousLoading    true if the URL should be loaded synchronously
+   * @param[in] textureObserver       The client object should inherit from this and provide the "UploadCompleted" virtual.
+   *                                  This is called when an image load completes (or fails).
+   * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
+   * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
+   *                                  image has no alpha channel
+   *
+   * @return                          The pixel buffer containing the image, or empty if still loading.
+   */
+
+  Devel::PixelBuffer LoadPixelBuffer( const VisualUrl& url,
+                                      Dali::ImageDimensions desiredSize,
+                                      Dali::FittingMode::Type fittingMode,
+                                      Dali::SamplingMode::Type samplingMode,
+                                      bool synchronousLoading,
+                                      TextureUploadObserver* textureObserver,
+                                      bool orientationCorrection,
+                                      TextureManager::MultiplyOnLoad& preMultiplyOnLoad );
+
+
+  /**
    * @brief Requests an image load of the given URL.
    *
    * The parameters are used to specify how the image is loaded.
    * @brief Requests an image load of the given URL.
    *
    * The parameters are used to specify how the image is loaded.
@@ -415,7 +445,8 @@ private:
     TextureUploadObserver*              observer,
     bool                                orientationCorrection,
     TextureManager::ReloadPolicy        reloadPolicy,
     TextureUploadObserver*              observer,
     bool                                orientationCorrection,
     TextureManager::ReloadPolicy        reloadPolicy,
-    MultiplyOnLoad&                     preMultiplyOnLoad );
+    MultiplyOnLoad&                     preMultiplyOnLoad,
+    bool                                loadPixelBuffer );
 
   /**
    * @brief Get the current state of a texture
 
   /**
    * @brief Get the current state of a texture
@@ -446,7 +477,8 @@ private:
                  UseAtlas useAtlas,
                  TextureManager::TextureHash hash,
                  bool orientationCorrection,
                  UseAtlas useAtlas,
                  TextureManager::TextureHash hash,
                  bool orientationCorrection,
-                 bool preMultiplyOnLoad )
+                 bool preMultiplyOnLoad,
+                 bool loadPixelBuffer )
     : url( url ),
       desiredSize( desiredSize ),
       useSize( desiredSize ),
     : url( url ),
       desiredSize( desiredSize ),
       useSize( desiredSize ),
@@ -465,7 +497,8 @@ private:
       cropToMask( cropToMask ),
       orientationCorrection( true ),
       preMultiplyOnLoad( preMultiplyOnLoad ),
       cropToMask( cropToMask ),
       orientationCorrection( true ),
       preMultiplyOnLoad( preMultiplyOnLoad ),
-      preMultiplied( false )
+      preMultiplied( false ),
+      loadPixelBuffer( loadPixelBuffer )
     {
     }
 
     {
     }
 
@@ -498,6 +531,7 @@ private:
     bool orientationCorrection:1;  ///< true if the image should be rotated to match exif orientation data
     bool preMultiplyOnLoad:1;      ///< true if the image's color should be multiplied by it's alpha
     bool preMultiplied:1;          ///< true if the image's color was multiplied by it's alpha
     bool orientationCorrection:1;  ///< true if the image should be rotated to match exif orientation data
     bool preMultiplyOnLoad:1;      ///< true if the image's color should be multiplied by it's alpha
     bool preMultiplied:1;          ///< true if the image's color was multiplied by it's alpha
+    bool loadPixelBuffer:1;        ///< true if the image is needed to be returned as PixelBuffer
   };
 
   /**
   };
 
   /**
index 1bf9944..b00722c 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXTURE_UPLOAD_OBSERVER_H
 
 /*
 #define DALI_TOOLKIT_INTERNAL_TEXTURE_UPLOAD_OBSERVER_H
 
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
  *
  */
 
-#include <dali-toolkit/public-api/dali-toolkit-common.h>
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/public-api/signals/dali-signal.h>
 
 #include <dali/public-api/signals/dali-signal.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
+
 namespace Dali
 {
 
 namespace Dali
 {
 
@@ -67,6 +72,17 @@ public:
                                const Vector4& atlasRect, bool preMultiplied ) = 0;
 
   /**
                                const Vector4& atlasRect, bool preMultiplied ) = 0;
 
   /**
+   * The action to be taken once the async load has finished.
+   * This should be overridden by the deriving class.
+   *
+   * @param[in] loadSuccess   True if the image load was successful (i.e. the resource is available). If false, then the resource failed to load.
+   * @param[in] pixelBuffer   The PixelBuffer of the loaded image.
+   * @param[in] url           The url address of the loaded image.
+   * @param[in] preMultiplied True if the image had pre-multiplied alpha applied
+   */
+  virtual void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const Internal::VisualUrl& url, bool preMultiplied ) = 0;
+
+  /**
    * @brief Returns the destruction signal.
    * This is emitted when the observer is destroyed.
    * This is used by the observer notifier to mark this observer as destroyed (IE. It no longer needs notifying).
    * @brief Returns the destruction signal.
    * This is emitted when the observer is destroyed.
    * This is used by the observer notifier to mark this observer as destroyed (IE. It no longer needs notifying).