[dali_2.0.37] Merge branch 'devel/master' 09/262009/1
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 30 Jul 2021 10:22:52 +0000 (11:22 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 30 Jul 2021 10:22:52 +0000 (11:22 +0100)
Change-Id: Ibf1aac6f086b36adbf4c74083a71a7e4b90f7449

54 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Controls-BridgeUp.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualUrl.cpp
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.h [new file with mode: 0644]
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-canvas-renderer.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp
automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp
automated-tests/src/dali-toolkit/utc-Dali-Image.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp
dali-toolkit/devel-api/controls/canvas-view/canvas-view.h
dali-toolkit/devel-api/controls/web-view/web-view.cpp
dali-toolkit/devel-api/controls/web-view/web-view.h
dali-toolkit/devel-api/image-loader/image-atlas.h
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp
dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h
dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.cpp [new file with mode: 0644]
dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.h [new file with mode: 0644]
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/controls/web-view/web-view-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/web-view/web-view-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/image-loader/async-image-loader-impl.cpp
dali-toolkit/internal/image-loader/image-atlas-impl.cpp
dali-toolkit/internal/image-loader/image-atlas-impl.h
dali-toolkit/internal/image-loader/image-load-thread.cpp
dali-toolkit/internal/image-loader/image-load-thread.h
dali-toolkit/internal/image-loader/image-url-impl.cpp
dali-toolkit/internal/image-loader/image-url-impl.h
dali-toolkit/internal/visuals/image-atlas-manager.cpp
dali-toolkit/internal/visuals/image-atlas-manager.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch-data.cpp
dali-toolkit/internal/visuals/npatch-data.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/texture-manager-impl.cpp
dali-toolkit/internal/visuals/texture-manager-impl.h
dali-toolkit/internal/visuals/visual-url.cpp
dali-toolkit/internal/visuals/visual-url.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/image-loader/image-url.cpp
dali-toolkit/public-api/image-loader/image-url.h
dali-toolkit/public-api/image-loader/image.cpp
dali-toolkit/public-api/image-loader/image.h
packaging/dali-toolkit.spec

index d50921c..c1b0ae6 100755 (executable)
@@ -80,6 +80,7 @@ SET(TEST_HARNESS_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/test-animation-data.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-application.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-button.cpp
+   ../dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-harness.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-graphics-sync-impl.cpp
index 6d47f06..5720b4e 100644 (file)
@@ -1081,12 +1081,13 @@ int UtcDaliAccessibilityCheckHighlight(void)
   parentButton.Add(buttonB);
   Wait(application);
 
-  // Move second child out of parent area
+  // Set highlight to first child (A) to enable movement tracking
   auto* accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonA));
   DALI_TEST_CHECK(accessible);
   accessible->GrabHighlight();
   Wait(application);
 
+  // Move first child (A) out of parent area through the parent's area top edge - single move outed event expected for A object and OUTGOING_TOP_LEFT direction
   buttonA.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, -200.0f) );
   Wait(application);
   // Need one more seding notificaiton to get correct updated position
@@ -1096,18 +1097,68 @@ int UtcDaliAccessibilityCheckHighlight(void)
   // Reset verdict data
   Dali::Accessibility::TestResetMoveOutedCalled();
 
-  // Move second child out of parent area
+  // Move first child (A) outside of parent area (both start and end position are outside of parent area) - no move outed event expected for A object
+  buttonA.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, -300.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Set highlight to second child (B) to enable movement tracking
   accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonB));
   DALI_TEST_CHECK(accessible);
   accessible->GrabHighlight();
   Wait(application);
 
+  // Move second child (B) inside of parent area (both start and end position are inside of parent area) - no move outed event expected for B object
+  // B: (0,100) --> (0, 50)
+  buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, 50.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Move second child (B) out of parent area through the parent's area right edge - single move outed event expected for B object and OUTGOING_BOTTOM_RIGHT direction
   buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(300.0f, 100.0f) );
   Wait(application);
   // Need one more seding notificaiton to get correct updated position
   application.SendNotification();
   DALI_TEST_EQUALS( true, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
 
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Move second child (B) back into parent area (start position is outside but end position is inside of parent area) - no move outed event expected for B object
+  // B: (300,100) --> (0, 100)
+  buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(0.0f, 100.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
+  // Reset verdict data
+  Dali::Accessibility::TestResetMoveOutedCalled();
+
+  // Disable movement tracking on B by giving highlight to A
+  accessible = dynamic_cast<DevelControl::AccessibleImpl*>(Dali::Accessibility::Accessible::Get(buttonA));
+  DALI_TEST_CHECK(accessible);
+  accessible->GrabHighlight();
+  Wait(application);
+
+  // Move B (untracked) out of parent area through the parent's area right edge - no move outed event expected for B object
+  // B: (0,100) --> (300, 100)
+  buttonB.SetProperty( Dali::Actor::Property::POSITION, Dali::Vector2(300.0f, 100.0f) );
+  Wait(application);
+  // Need one more seding notificaiton to get correct updated position
+  application.SendNotification();
+  DALI_TEST_EQUALS( false, Dali::Accessibility::TestGetMoveOutedCalled(), TEST_LOCATION );
+
   Dali::Accessibility::TestEnableSC( false );
   END_TEST;
 }
index 9098be8..04c51af 100644 (file)
@@ -26,6 +26,9 @@
 #include <dali-toolkit/internal/visuals/texture-upload-observer.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h> ///< For VisualFactory's member TextureManager.
+
+#include <test-encoded-image-buffer.h>
 
 #if defined(ELDBUS_ENABLED)
 #include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
@@ -147,6 +150,315 @@ int UtcTextureManagerGenerateHash(void)
   END_TEST;
 }
 
+int UtcTextureManagerEncodedImageBuffer(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcTextureManagerEncodedImageBuffer" );
+
+  auto  visualFactory  = Toolkit::VisualFactory::Get();
+  auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
+
+  // Get encoded raw-buffer image and generate url
+  EncodedImageBuffer buffer1 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
+  EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
+
+  std::string  url1 = textureManager.AddExternalEncodedImageBuffer(buffer1);
+  std::string  url2 = textureManager.AddExternalEncodedImageBuffer(buffer1);
+  std::string  url3 = VisualUrl::CreateBufferUrl(""); ///< Impossible Buffer URL. for coverage
+
+  // Check if same EncodedImageBuffer get same url
+  DALI_TEST_CHECK(url1 == url2);
+  // Reduce reference count
+  textureManager.RemoveExternalEncodedImageBuffer(url1);
+  // Check whethere url1 still valid
+  DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
+
+  url2 = textureManager.AddExternalEncodedImageBuffer(buffer2);
+  // Check if difference EncodedImageBuffer get difference url
+  DALI_TEST_CHECK(url1 != url2);
+
+  auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+  TestObserver observer1;
+  textureManager.RequestLoad(
+    url1,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::NO_ATLAS,
+    &observer1,
+    true, ///< orientationCorrection
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  DALI_TEST_EQUALS( observer1.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer1.mObserverCalled, false, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( observer1.mLoaded, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer1.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION );
+
+  TestObserver observer2;
+  // Syncload
+  Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
+    url2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    true, ///< synchronousLoading
+    &observer2,
+    true, ///< orientationCorrection
+    preMultiply);
+
+  DALI_TEST_CHECK( pixelBuffer );
+  DALI_TEST_EQUALS( observer2.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mObserverCalled, false, TEST_LOCATION );
+
+  // Asyncload
+  pixelBuffer = textureManager.LoadPixelBuffer(
+    url2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    false, ///< synchronousLoading
+    &observer2,
+    true, ///< orientationCorrection
+    preMultiply);
+
+  DALI_TEST_EQUALS( observer2.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mObserverCalled, false, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( observer2.mLoaded, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION );
+
+  textureManager.RemoveExternalEncodedImageBuffer(url1);
+  textureManager.RemoveExternalEncodedImageBuffer(url2);
+
+  // Now url1 and url2 is invalid type. mLoaded will return false
+
+  TestObserver observer3;
+  textureManager.RequestLoad(
+    url1,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::NO_ATLAS,
+    &observer3,
+    true, ///< orientationCorrection
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  // Load will be success because url1 is cached
+  DALI_TEST_EQUALS( observer3.mLoaded, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer3.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer3.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION );
+
+  TestObserver observer4;
+  textureManager.RequestLoad(
+    url2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::NO_ATLAS,
+    &observer4,
+    true, ///< orientationCorrection
+    TextureManager::ReloadPolicy::FORCED,
+    preMultiply);
+
+  DALI_TEST_EQUALS( observer4.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer4.mObserverCalled, false, TEST_LOCATION );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  // Load will be failed becuase reloadpolicy is forced
+  DALI_TEST_EQUALS( observer4.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer4.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer4.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION );
+
+  TestObserver observer5;
+  pixelBuffer = textureManager.LoadPixelBuffer(
+    url2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    true, ///< synchronousLoading
+    &observer5,
+    true, ///< orientationCorrection
+    preMultiply);
+
+  // Load will be faild because synchronousLoading doesn't use cached texture
+  DALI_TEST_CHECK( !pixelBuffer );
+  DALI_TEST_EQUALS( observer5.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer5.mObserverCalled, false, TEST_LOCATION );
+
+  TestObserver observer6;
+  pixelBuffer = textureManager.LoadPixelBuffer(
+    url3,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    false, ///< synchronousLoading
+    &observer6,
+    true, ///< orientationCorrection
+    preMultiply);
+
+  DALI_TEST_EQUALS( observer6.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer6.mObserverCalled, false, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  // Load will be failed because url3 is invalid URL
+  DALI_TEST_EQUALS( observer6.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer6.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer6.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcTextureManagerEncodedImageBufferReferenceCount(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcTextureManagerEncodedImageBuffer check reference count works well" );
+
+  auto  visualFactory  = Toolkit::VisualFactory::Get();
+  auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
+
+  // Get encoded raw-buffer image and generate url
+  EncodedImageBuffer buffer1 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
+  EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(TEST_IMAGE_FILE_NAME);
+
+  std::string  url1    = textureManager.AddExternalEncodedImageBuffer(buffer1);
+  std::string  url2    = textureManager.AddExternalEncodedImageBuffer(buffer1);
+
+  // Check if same EncodedImageBuffer get same url
+  DALI_TEST_CHECK(url1 == url2);
+
+  // Reduce reference count
+  textureManager.RemoveExternalEncodedImageBuffer(url1);
+  // Check whethere url1 still valid
+  DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
+
+  // Reduce reference count
+  textureManager.RemoveExternalEncodedImageBuffer(url1);
+  // Check whethere url1 is not valid anymore
+  DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1));
+
+  // UseExternalTexture doesn't create new buffer.
+  // So, reference count is still zero.
+  textureManager.UseExternalResource(url1);
+  DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1));
+
+  url1 = textureManager.AddExternalEncodedImageBuffer(buffer1);
+  // Check if difference EncodedImageBuffer get difference url
+  // Previous EncodedImageBuffer was deleted, so we get new url even same buffer.
+  DALI_TEST_CHECK(url1 != url2);
+
+  url2 = textureManager.AddExternalEncodedImageBuffer(buffer2);
+  // Check if difference EncodedImageBuffer get difference url
+  DALI_TEST_CHECK(url1 != url2);
+
+  auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+  // url1 load image by cache
+  TestObserver observer1;
+  textureManager.RequestLoad(
+    url1,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    TextureManager::NO_ATLAS,
+    &observer1,
+    true, ///< orientationCorrection
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  DALI_TEST_EQUALS( observer1.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer1.mObserverCalled, false, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( observer1.mLoaded, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer1.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION );
+
+  // LoadPixelBuffer doen't use cache. url2 will not be cached
+  TestObserver observer2;
+  Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer(
+    url2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    false, ///< synchronousLoading
+    &observer2,
+    true, ///< orientationCorrection
+    preMultiply);
+
+  DALI_TEST_EQUALS( observer2.mLoaded, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mObserverCalled, false, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( observer2.mLoaded, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mObserverCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( observer2.mCompleteType, TestObserver::CompleteType::LOAD_COMPLETE, TEST_LOCATION );
+
+  // Decrease each url's reference count.
+  textureManager.RemoveExternalEncodedImageBuffer(url1);
+  textureManager.RemoveExternalEncodedImageBuffer(url2);
+
+  // url1 buffer is still have 1 reference count because it is cached.
+  // But url2 not valid because it is not cached.
+  DALI_TEST_CHECK(textureManager.GetEncodedImageBuffer(url1));
+  DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url2));
+
+  // Check url1 buffer have 1 reference count because it is cached.
+  textureManager.RemoveExternalEncodedImageBuffer(url1);
+  DALI_TEST_CHECK(!textureManager.GetEncodedImageBuffer(url1));
+
+  END_TEST;
+}
+
+
 int UtcTextureManagerCachingForDifferentLoadingType(void)
 {
   ToolkitTestApplication application;
index c57ec89..767c1f8 100644 (file)
@@ -54,6 +54,18 @@ int UtcDaliVisualUrlConstructor(void)
   DALI_TEST_EQUALS( true, visualUrl4.IsValid(), TEST_LOCATION );
   DALI_TEST_EQUALS( visualUrl4.GetType(), VisualUrl::REGULAR_IMAGE, TEST_LOCATION );
   DALI_TEST_EQUALS( visualUrl4.GetProtocolType(), VisualUrl::TEXTURE, TEST_LOCATION );
+
+  VisualUrl visualUrl6("enbuf://0");
+  visualUrl6 = visualUrl;
+  DALI_TEST_EQUALS( true, visualUrl6.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl6.GetType(), VisualUrl::GIF, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl6.GetProtocolType(), VisualUrl::LOCAL, TEST_LOCATION );
+
+  VisualUrl visualUrl7("enbuf://1");
+  visualUrl6 = visualUrl7;
+  DALI_TEST_EQUALS( true, visualUrl6.IsValid(), TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl6.GetType(), VisualUrl::REGULAR_IMAGE, TEST_LOCATION );
+  DALI_TEST_EQUALS( visualUrl6.GetProtocolType(), VisualUrl::BUFFER, TEST_LOCATION );
   END_TEST;
 }
 
@@ -233,6 +245,15 @@ int UtcDaliVisualUrlLocationP(void)
   DALI_TEST_EQUALS( VisualUrl::TEXTURE, VisualUrl("dali://bar.org/foobar.svg").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::TEXTURE, VisualUrl("dali://bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
 
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://1234").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("ENBUF://1234").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://.gif").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://bar.org/foobar.gif").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://bar.org/foobar.png").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://bar.org/foobar.svg").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::BUFFER, VisualUrl("enbuf://bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -262,6 +283,8 @@ int UtcDaliVisualUrlLocationN(void)
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("ssh:a/bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("shh://bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("sss://bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("fsh://bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("stp://bar.org/foobar.9.png").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("http:/bar.org/foobar.gif").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("h1tps://bar.org/foobar.gif").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("ht2ps://bar.org/foobar.gif").GetProtocolType(), TEST_LOCATION );
@@ -280,6 +303,18 @@ int UtcDaliVisualUrlLocationN(void)
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("dali:5/1").GetProtocolType(), TEST_LOCATION );
   DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("dali:/61").GetProtocolType(), TEST_LOCATION );
 
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("eunki://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("enbu://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("eubnf://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("1nbuf://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("e2bun://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("en3uf://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("enb4f://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("enbu5://1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("enbuf6//1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("enbuf:7/1").GetProtocolType(), TEST_LOCATION );
+  DALI_TEST_EQUALS( VisualUrl::LOCAL, VisualUrl("enbuf:/81").GetProtocolType(), TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -367,6 +402,7 @@ int UtcDaliVisualUrlGetLocationP(void)
 
   DALI_TEST_EQUAL( "a", VisualUrl("http://a").GetLocation() );
   DALI_TEST_EQUAL( "1", VisualUrl("dali://1").GetLocation() );
+  DALI_TEST_EQUAL( "4", VisualUrl("enbuf://4").GetLocation() );
   DALI_TEST_EQUAL( "", VisualUrl("ftp://").GetLocation() );
   DALI_TEST_EQUAL( "http://", VisualUrl("http://http://").GetLocation() );
 
@@ -381,6 +417,7 @@ int UtcDaliVisualUrlGetLocationN(void)
   DALI_TEST_EQUAL( "a", VisualUrl("a").GetLocation() );
   DALI_TEST_EQUAL( "dali:/1", VisualUrl("dali:/1").GetLocation() );
   DALI_TEST_EQUAL( "dali//1", VisualUrl("dali//1").GetLocation() );
+  DALI_TEST_EQUAL( "enbuf:/2", VisualUrl("enbuf:/2").GetLocation() );
   DALI_TEST_EQUAL( "", VisualUrl("http:/http://").GetLocation() );
 
   END_TEST;
@@ -396,3 +433,14 @@ int UtcDaliVisualUrlCreateTextureUrl(void)
 
   END_TEST;
 }
+
+int UtcDaliVisualUrlCreateBufferUrl(void)
+{
+  tet_infoline( "UtcDaliVisualUrl CreateBufferUrl" );
+
+  DALI_TEST_EQUAL( "enbuf://a", VisualUrl::CreateBufferUrl( "a" ) );
+  DALI_TEST_EQUAL( "enbuf://1234", VisualUrl::CreateBufferUrl( "1234" ) );
+  DALI_TEST_EQUAL( "enbuf://", VisualUrl::CreateBufferUrl( "" ) );
+
+  END_TEST;
+}
index 0e984f0..b3c04d4 100755 (executable)
@@ -112,6 +112,7 @@ SET(TEST_HARNESS_SOURCES
   dali-toolkit-test-utils/test-animation-data.cpp
   dali-toolkit-test-utils/test-application.cpp
   dali-toolkit-test-utils/test-button.cpp
+  dali-toolkit-test-utils/test-encoded-image-buffer.cpp
   dali-toolkit-test-utils/test-harness.cpp
   dali-toolkit-test-utils/test-gesture-generator.cpp
   dali-toolkit-test-utils/test-gl-abstraction.cpp
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.cpp
new file mode 100644 (file)
index 0000000..e693098
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test-application.h"
+
+#include "test-encoded-image-buffer.h"
+
+namespace Dali
+{
+EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url)
+{
+  EncodedImageBuffer buffer;
+  FILE *fp;
+  fp = fopen(url, "rb");
+  if(fp != NULL)
+  {
+    fseek(fp, 0, SEEK_END);
+    size_t size = ftell(fp);
+    Dali::Vector<uint8_t> data;
+    data.Resize(size);
+    fseek(fp, 0, SEEK_SET);
+    fread(data.Begin(), size, sizeof(uint8_t), fp);
+    fclose(fp);
+    buffer = EncodedImageBuffer::New(data);
+  }
+  return buffer;
+}
+
+} // namespace Dali
diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-encoded-image-buffer.h
new file mode 100644 (file)
index 0000000..96fbe46
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef TEST_ENCODED_IMAGE_BUFFER_H
+#define TEST_ENCODED_IMAGE_BUFFER_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
+
+namespace Dali
+{
+
+// util function to convert local file to EncodedImageBuffer
+EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url);
+
+} // namespace Dali
+
+#endif // TEST_ENCODED_IMAGE_BUFFER_H
index 0d6b87e..f280f6f 100644 (file)
@@ -38,8 +38,10 @@ class CanvasRenderer: public Dali::BaseObject
 {
 public:
   CanvasRenderer( const Vector2& size )
-  : mPixelBuffer( Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888) ),
-    mSize(size)
+  : mDrawable(nullptr),
+    mPixelBuffer( Devel::PixelBuffer::New(size.width, size.height, Dali::Pixel::RGBA8888) ),
+    mSize(size),
+    mViewBox(size)
   {
   }
 
@@ -52,15 +54,49 @@ public:
      return true;
   }
 
+  bool IsCanvasChanged() const
+  {
+     return true;
+  }
+
+  bool Rasterize()
+  {
+     return true;
+  }
+
   bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
   {
     if (!drawable)
     {
       return false;
     }
+    mDrawable = &drawable;
     return true;
   }
 
+  bool RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable)
+  {
+    if (!drawable)
+    {
+      return false;
+    }
+    if (mDrawable == &drawable)
+    {
+      mDrawable = nullptr;
+      return true;
+    }
+    return false;
+  }
+
+  bool RemoveAllDrawables()
+  {
+    if (mDrawable)
+    {
+      return true;
+    }
+    return false;
+  }
+
   Devel::PixelBuffer GetPixelBuffer()
   {
     return mPixelBuffer;
@@ -84,10 +120,27 @@ public:
     return mSize;
   }
 
+  bool SetViewBox(const Vector2& viewBox)
+  {
+    mViewBox = viewBox;
+    // For negative test
+    if ( viewBox.width == -999 && viewBox.height == -999 )
+    {
+      return false;
+    }
+    return true;
+  }
+
+  const Vector2& GetViewBox()
+  {
+    return mViewBox;
+  }
 
 public:
+   Dali::CanvasRenderer::Drawable* mDrawable;
    Devel::PixelBuffer mPixelBuffer;
    Vector2 mSize;
+   Vector2 mViewBox;
 };
 
 inline CanvasRenderer& GetImplementation( Dali::CanvasRenderer& renderer )
@@ -138,6 +191,16 @@ bool CanvasRenderer::Commit()
   return Internal::Adaptor::GetImplementation(*this).Commit();
 }
 
+bool CanvasRenderer::IsCanvasChanged() const
+{
+  return Internal::Adaptor::GetImplementation(*this).IsCanvasChanged();
+}
+
+bool CanvasRenderer::Rasterize()
+{
+  return Internal::Adaptor::GetImplementation(*this).Rasterize();
+}
+
 Devel::PixelBuffer CanvasRenderer::GetPixelBuffer()
 {
   return Internal::Adaptor::GetImplementation(*this).GetPixelBuffer();
@@ -148,6 +211,16 @@ bool CanvasRenderer::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
   return Internal::Adaptor::GetImplementation(*this).AddDrawable(drawable);
 }
 
+bool CanvasRenderer::RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  return Internal::Adaptor::GetImplementation(*this).RemoveDrawable(drawable);
+}
+
+bool CanvasRenderer::RemoveAllDrawables()
+{
+  return Internal::Adaptor::GetImplementation(*this).RemoveAllDrawables();
+}
+
 bool CanvasRenderer::SetSize(const Vector2& size)
 {
   return Internal::Adaptor::GetImplementation(*this).SetSize(size);
@@ -158,5 +231,14 @@ const Vector2& CanvasRenderer::GetSize()
   return Internal::Adaptor::GetImplementation(*this).GetSize();
 }
 
+bool CanvasRenderer::SetViewBox(const Vector2& viewBox)
+{
+  return Internal::Adaptor::GetImplementation(*this).SetViewBox(viewBox);
+}
+
+const Vector2& CanvasRenderer::GetViewBox()
+{
+  return Internal::Adaptor::GetImplementation(*this).GetViewBox();
+}
 
 } // namespace Dali
index e6f47a8..c1d8700 100755 (executable)
@@ -84,6 +84,7 @@ bool OnFormPasswordAcquired();
 bool OnDownloadStarted();
 bool OnMimeOverridden();
 bool OnChangesWatch();
+bool OnPlainTextReceived();
 
 static void ConnectToGlobalSignal( bool ( *func )() )
 {
@@ -1532,6 +1533,15 @@ public:
     mContextMenuHiddenCallback = callback;
   }
 
+  void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
+  {
+    if (callback)
+    {
+      ConnectToGlobalSignal(&OnPlainTextReceived);
+      mPlainTextReceivedCallback = callback;
+    }
+  }
+
   std::string              mUrl;
   std::vector<std::string> mHistory;
   size_t                   mCurrentPlusOnePos;
@@ -1577,6 +1587,7 @@ public:
   Dali::WebEnginePlugin::VideoPlayingCallback                    mVideoPlayingCallback;
   Dali::WebEnginePlugin::GeolocationPermissionCallback           mGeolocationPermissionCallback;
   Dali::WebEnginePlugin::WebEngineHitTestCreatedCallback         mHitTestCreatedCallback;
+  Dali::WebEnginePlugin::PlainTextReceivedCallback               mPlainTextReceivedCallback;
 };
 
 
@@ -1884,6 +1895,17 @@ bool OnChangesWatch()
   return false;
 }
 
+bool OnPlainTextReceived()
+{
+  DisconnectFromGlobalSignal(&OnPlainTextReceived);
+  if (gInstance)
+  {
+    std::string dummyResultText;
+    gInstance->mPlainTextReceivedCallback(dummyResultText);
+  }
+  return false;
+}
+
 } // namespace
 
 inline WebEngine& GetImplementation( Dali::WebEngine& webEngine )
@@ -2391,5 +2413,10 @@ void WebEngine::RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngi
   Internal::Adaptor::GetImplementation( *this ).RegisterContextMenuHiddenCallback(callback);
 }
 
+void WebEngine::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
+{
+  Internal::Adaptor::GetImplementation(*this).GetPlainTextAsynchronously(callback);
+}
+
 } // namespace Dali;
 
index 1c5128e..36cf1df 100644 (file)
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <test-application.h>
+#include <dali/public-api/images/pixel-data.h>
+#include <toolkit-event-thread-callback.h>
 #include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
+#include <dali/devel-api/adaptor-framework/canvas-renderer.h>
 #include <dali/devel-api/adaptor-framework/canvas-renderer-shape.h>
-
+#include <dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -99,6 +102,15 @@ int UtcDaliCanvasViewNewP(void)
   END_TEST;
 }
 
+int UtcDaliCanvasViewNewWithoutViewboxP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New();
+
+  DALI_TEST_CHECK( canvasView );
+  END_TEST;
+}
+
 int UtcDaliCanvasViewDownCastP(void)
 {
   ToolkitTestApplication application;
@@ -155,6 +167,63 @@ int UtcDaliCanvasViewAddN(void)
   END_TEST;
 }
 
+int UtcDaliCanvasViewRemoveP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New();
+
+  canvasView.AddDrawable(shape);
+
+  DALI_TEST_CHECK( canvasView.RemoveDrawable(shape) );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRemoveN(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New();
+
+  DALI_TEST_CHECK( !canvasView.RemoveDrawable(shape) );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRemoveAllP(void)
+{
+  ToolkitTestApplication application;
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New();
+
+  canvasView.AddDrawable(shape);
+
+  canvasView.RemoveAllDrawables();
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRemoveAllN(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  canvasView.RemoveAllDrawables();
+
+  END_TEST;
+}
+
+
 int UtcDaliCanvasViewChangeSizeP(void)
 {
   ToolkitTestApplication application;
@@ -163,8 +232,6 @@ int UtcDaliCanvasViewChangeSizeP(void)
   DALI_TEST_CHECK( canvasView );
 
   application.GetScene().Add(canvasView);
-  application.SendNotification();
-  application.Render();
 
   canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
 
@@ -187,8 +254,6 @@ int UtcDaliCanvasViewSizeN(void)
   DALI_TEST_CHECK( canvasView );
 
   application.GetScene().Add(canvasView);
-  application.SendNotification();
-  application.Render();
 
   canvasView.SetProperty(Actor::Property::SIZE, Vector2(-999, -999));
 
@@ -202,3 +267,320 @@ int UtcDaliCanvasViewSizeN(void)
 
   END_TEST;
 }
+
+int UtcDaliCanvasViewRasterizeTaskP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeTaskGetCanvasViewP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  DALI_TEST_EQUALS( task->GetCanvasView(), dummyInternalCanvasView, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeTaskGetBufferSizeP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  //There is no rasterized buffer.
+  DALI_TEST_EQUALS( task->GetBufferSize(), Vector2(0, 0), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeTaskGetPixelDataP(void)
+{
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  DALI_TEST_EQUALS( task->GetPixelData(), PixelData(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeThreadP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeThreadAddTaskP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task2 = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task2 );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  dummyThread->AddTask(task);
+  dummyThread->AddTask(task2);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeThreadAddRemoveTaskP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  dummyThread->AddTask(task);
+
+  dummyThread->RemoveTask(dummyInternalCanvasView);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeThreadApplyRasterizedP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  dummyThread->AddTask(task);
+
+  dummyThread->ApplyRasterized();
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeThreadTerminateThreadP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  dummyThread->AddTask(task);
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread::TerminateThread(dummyThread);
+
+  END_TEST;
+}
+
+PixelData CreatePixelData( unsigned int width, unsigned int height )
+{
+  unsigned int bufferSize = width*height*Pixel::GetBytesPerPixel( Pixel::RGBA8888 );
+
+  unsigned char* buffer= reinterpret_cast<unsigned char*>( malloc( bufferSize ) );
+  PixelData pixelData = PixelData::New( buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE );
+
+  return pixelData;
+}
+
+int UtcDaliCanvasViewRasterizeThreadCallProcessP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  dummyThread->AddTask(task);
+
+  dummyThread->Process(false);
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewRasterizeThreadRasterizationCompletedSignalP(void)
+{
+  ToolkitTestApplication application;
+
+  Dali::Toolkit::Internal::CanvasView* dummyInternalCanvasView = new Dali::Toolkit::Internal::CanvasView(Vector2(100,100));
+  DALI_TEST_CHECK( dummyInternalCanvasView );
+
+  Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100));
+  DALI_TEST_CHECK( dummyCanvasRenderer );
+
+  IntrusivePtr<Dali::Toolkit::Internal::CanvasRendererRasterizingTask> task = new Dali::Toolkit::Internal::CanvasRendererRasterizingTask(dummyInternalCanvasView, dummyCanvasRenderer);
+  DALI_TEST_CHECK( task );
+
+  Dali::Toolkit::Internal::CanvasViewRasterizeThread *dummyThread = new Dali::Toolkit::Internal::CanvasViewRasterizeThread();
+  DALI_TEST_CHECK( dummyThread );
+
+  dummyThread->AddTask(task);
+
+  dummyThread->Process(false);
+
+  PixelData pixelData = CreatePixelData( 100, 100 );
+
+  dummyThread->RasterizationCompletedSignal().Connect(dummyInternalCanvasView, &Dali::Toolkit::Internal::CanvasView::ApplyRasterizedImage);
+  dummyThread->RasterizationCompletedSignal().Emit(pixelData);
+
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewSetSizeAndAddDrawable(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(100,100));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
+
+  application.SendNotification();
+  application.Render();
+
+  Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New();
+
+  shape.AddRect(Rect<float>(10, 10, 10, 10), Vector2(0, 0));
+
+  canvasView.AddDrawable(shape);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewViewBoxP(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(300, 300));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
+  canvasView.SetProperty(Toolkit::CanvasView::Property::VIEW_BOX, Vector2(100, 100));
+
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
+
+int UtcDaliCanvasViewViewBoxN(void)
+{
+  ToolkitTestApplication application;
+
+  CanvasView canvasView = CanvasView::New(Vector2(300, 300));
+  DALI_TEST_CHECK( canvasView );
+
+  application.GetScene().Add(canvasView);
+
+  canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300));
+  canvasView.SetProperty(Toolkit::CanvasView::Property::VIEW_BOX, Vector2(-999, -999));
+
+  application.SendNotification();
+  application.Render();
+
+  Vector2 viewBox = canvasView.GetProperty(Toolkit::CanvasView::Property::VIEW_BOX).Get<Vector2>();
+  DALI_TEST_EQUALS( viewBox, Vector2(-999, -999), TEST_LOCATION );
+
+  END_TEST;
+}
index 37e3b5e..b4b88b6 100644 (file)
@@ -122,3 +122,18 @@ int UtcDaliImageConvertNativeImageSourceToUrl(void)
 
   END_TEST;
 }
+
+int UtcDaliImageConvertEncodedImageBufferToUrl(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliImageConvertEncodedImageBufferToUrl" );
+
+  Dali::Vector<uint8_t> buffer;
+  buffer.PushBack(0x11);
+  buffer.PushBack(0x22);
+  buffer.PushBack(0x33);
+
+  DALI_TEST_CHECK( Dali::Toolkit::Image::GenerateUrl( EncodedImageBuffer::New(buffer) ).GetUrl().size() > 0u );
+
+  END_TEST;
+}
index 1cd3de5..0450040 100644 (file)
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 
 #include <test-native-image.h>
+#include <test-encoded-image-buffer.h>
 #include <sstream>
 #include <unistd.h>
 
@@ -534,8 +537,6 @@ int UtcDaliImageViewAsyncLoadingWithoutAltasing(void)
   const std::vector<GLuint>& textures2 = gl.GetBoundTextures();
   DALI_TEST_GREATER( textures2.size(), numTextures, TEST_LOCATION );
 
-
-
   END_TEST;
 }
 
@@ -713,6 +714,150 @@ int UtcDaliImageViewSyncLoading02(void)
   END_TEST;
 }
 
+int UtcDaliImageViewAsyncLoadingEncodedBuffer(void)
+{
+  ToolkitTestApplication application;
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  const std::vector<GLuint>& textures = gl.GetBoundTextures();
+  size_t numTextures = textures.size();
+
+  // Get encoded raw-buffer image and generate url
+  EncodedImageBuffer buffer = ConvertFileToEncodedImageBuffer(gImage_600_RGB);
+  ImageUrl           url    = Toolkit::Image::GenerateUrl(buffer);
+
+  // Async loading, no atlasing for big size image
+  ImageView imageView = ImageView::New(url.GetUrl());
+
+  // By default, Aysnc loading is used
+  application.GetScene().Add(imageView);
+  imageView.SetProperty( Actor::Property::SIZE, Vector2(100, 100) );
+  imageView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render(16);
+  application.SendNotification();
+
+  const std::vector<GLuint>& textures2 = gl.GetBoundTextures();
+  DALI_TEST_GREATER( textures2.size(), numTextures, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageViewAsyncLoadingEncodedBufferWithAtlasing(void)
+{
+  ToolkitTestApplication application;
+
+  // Get encoded raw-buffer image and generate url
+  EncodedImageBuffer buffer = ConvertFileToEncodedImageBuffer(gImage_600_RGB);
+  ImageUrl           url    = Toolkit::Image::GenerateUrl(buffer);
+  ImageUrl           url2   = Toolkit::Image::GenerateUrl(buffer);
+
+  // Generate url is not equal to url2
+  // NOTE : This behavior may changed when ImageUrl compare operator changed.
+  DALI_TEST_CHECK(url != url2);
+  // Generate url's string is equal to url2's string
+  DALI_TEST_CHECK(url.GetUrl() == url2.GetUrl());
+
+  EncodedImageBuffer buffer2 = ConvertFileToEncodedImageBuffer(gImage_600_RGB);
+  url2 = Toolkit::Image::GenerateUrl(buffer2);
+
+  // Check whethere two url are not equal
+  DALI_TEST_CHECK(url.GetUrl() != url2.GetUrl());
+
+  // Async loading, automatic atlasing for small size image
+  TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+  callStack.Reset();
+  callStack.Enable(true);
+
+  Property::Map imageMap;
+
+  imageMap[ ImageVisual::Property::URL ] = url.GetUrl();
+  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 offScene
+
+  application.GetScene().Add( imageView );
+  application.SendNotification();
+  application.Render(16);
+  application.Render(16);
+  application.SendNotification();
+
+  // Change url to url2
+  imageMap[ ImageVisual::Property::URL ] = url2.GetUrl();
+  imageView.SetProperty( ImageView::Property::IMAGE, imageMap );
+
+  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"] << 34;
+  params["height"] << 34;
+  DALI_TEST_EQUALS( callStack.FindMethodAndParams( "TexSubImage2D", params ), true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliImageViewSyncLoadingEncodedBuffer(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline("ImageView Testing sync loading from EncodedImageBuffer");
+
+  // Get encoded raw-buffer image and generate url
+  EncodedImageBuffer buffer = ConvertFileToEncodedImageBuffer(gImage_34_RGBA);
+  ImageUrl           url    = Toolkit::Image::GenerateUrl(buffer);
+
+  // Sync loading, automatic atlasing for small size image
+  {
+    TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+    callStack.Reset();
+    callStack.Enable(true);
+
+    ImageView imageView = ImageView::New( );
+
+    // Sync loading is used
+    Property::Map syncLoadingMap;
+    syncLoadingMap[ "url" ] = url.GetUrl();
+    syncLoadingMap[ "desiredHeight" ] = 34;
+    syncLoadingMap[ "desiredWidth" ] = 34;
+    syncLoadingMap[ "synchronousLoading" ] = true;
+    syncLoadingMap[ "atlasing" ] = true;
+    imageView.SetProperty( ImageView::Property::IMAGE, syncLoadingMap );
+
+    application.GetScene().Add( imageView );
+    application.SendNotification();
+    application.Render(16);
+
+    TraceCallStack::NamedParams params;
+    params["width"] << 34;
+    params["height"] << 34;
+    DALI_TEST_EQUALS( callStack.FindMethodAndParams( "TexSubImage2D", params ),
+                      true, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
 int UtcDaliImageViewAddedTexture(void)
 {
   ToolkitTestApplication application;
index 40ca439..1dbb737 100644 (file)
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
 #include <dali-toolkit/public-api/image-loader/image-url.h>
 #include <dali-toolkit/dali-toolkit.h>
+
+#include <test-encoded-image-buffer.h>
 #include "dummy-control.h"
 
 using namespace Dali;
@@ -520,6 +523,106 @@ int UtcDaliImageVisualWithNativeImageRemoved(void)
   END_TEST;
 }
 
+int UtcDaliImageVisualWithEncodedImageBuffer(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Use Encoded Image Buffer as url" );
+
+  EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_LARGE_IMAGE_FILE_NAME);
+  ImageUrl url = Dali::Toolkit::Image::GenerateUrl(rawBuffer);
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::IMAGE );
+  propertyMap.Insert( ImageVisual::Property::URL, url.GetUrl() );
+
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
+  actor.SetProperty( Actor::Property::SIZE, Vector2( 200.f, 200.f ) );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+  application.GetScene().Add( actor );
+  application.SendNotification();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+  application.GetScene().Remove( actor );
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  END_TEST;
+}
+
+int UtcDaliImageVisualWithEncodedImageBufferRemoved(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Use Encoded Image Buffer as url" );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_LARGE_IMAGE_FILE_NAME);
+  ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(rawBuffer);
+  std::string url = imageUrl.GetUrl();
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Toolkit::Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( ImageVisual::Property::URL,  url );
+
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(  DummyControl::Property::TEST_VISUAL, visual );
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+  application.GetScene().Add( actor );
+  application.SendNotification();
+
+  // Wait for decode buffer and make texture.
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( textureTrace.CountMethod("DeleteTextures"), 0, TEST_LOCATION );
+
+  tet_infoline( "Delete texture because there is no actor to use decoded texture" );
+  imageUrl.Reset();
+  application.GetScene().Remove( actor );
+  dummyImpl.UnregisterVisual( DummyControl::Property::TEST_VISUAL );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( textureTrace.CountMethod("DeleteTextures"), 1, TEST_LOCATION );
+
+  END_TEST;
+}
+
 int UtcDaliImageVisualTextureReuse1(void)
 {
   ToolkitTestApplication application;
index 4f7d8fa..16518da 100755 (executable)
@@ -102,6 +102,7 @@ static int gContextMenuHiddenCallbackCalled = 0;
 static std::unique_ptr<Dali::WebEngineContextMenu> gContextMenuHiddenInstance = nullptr;
 static int gHitTestCreatedCallbackCalled = 0;
 static int gCookieManagerChangsWatchCallbackCalled = 0;
+static int gPlainTextReceivedCallbackCalled = 0;
 
 struct CallbackFunctor
 {
@@ -154,6 +155,12 @@ static bool OnHitTestCreated(std::unique_ptr<Dali::WebEngineHitTest> test)
   return true;
 }
 
+static bool OnPlainTextReceived(const std::string& plainText)
+{
+  gPlainTextReceivedCallbackCalled++;
+  return true;
+}
+
 static void OnPageLoadError(std::unique_ptr<Dali::WebEngineLoadError> error)
 {
   gPageLoadErrorCallbackCalled++;
@@ -2294,3 +2301,19 @@ int UtcDaliWebSettingsSetExtraFeature(void)
   END_TEST;
 }
 
+int UtcDaliWebViewGetPlainText(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK(view);
+
+  view.LoadUrl(TEST_URL1);
+
+  view.GetPlainTextAsynchronously(&OnPlainTextReceived);
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS(gPlainTextReceivedCallbackCalled, 1, TEST_LOCATION);
+
+  END_TEST;
+}
+
index 839e96d..4fc8493 100644 (file)
 
 #include <dali-toolkit/public-api/text/text-enumerations.h>
 
+#include <dali-toolkit/public-api/transition/fade.h>
+#include <dali-toolkit/public-api/transition/transition.h>
+#include <dali-toolkit/public-api/transition/transition-set.h>
+
 #include <dali-toolkit/public-api/visuals/border-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/gradient-visual-properties.h>
index d6ebc63..a00cd35 100644 (file)
@@ -51,6 +51,12 @@ CanvasView::~CanvasView()
 {
 }
 
+CanvasView CanvasView::New()
+{
+  CanvasView canvasView = Internal::CanvasView::New(Vector2::ZERO);
+  return canvasView;
+}
+
 CanvasView CanvasView::New(const Vector2& viewBox)
 {
   CanvasView canvasView = Internal::CanvasView::New(viewBox);
@@ -67,6 +73,16 @@ void CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
   Dali::Toolkit::GetImpl(*this).AddDrawable(drawable);
 }
 
+bool CanvasView::RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  return Dali::Toolkit::GetImpl(*this).RemoveDrawable(drawable);
+}
+
+void CanvasView::RemoveAllDrawables()
+{
+  Dali::Toolkit::GetImpl(*this).RemoveAllDrawables();
+}
+
 CanvasView::CanvasView(Internal::CanvasView& implementation)
 : Control(implementation)
 {
index 9e59722..64e1397 100644 (file)
@@ -51,12 +51,42 @@ class CanvasView;
  *    myCanvasView.AddDrawable( shape );
  * @endcode
  *
+ * @section CanvasViewProperties Properties
+ * |%Property enum                    |String name          |Type            |Writable|Animatable|
+ * |----------------------------------|---------------------|----------------|--------|----------|
+ * | Property::VIEW_BOX               | viewBox             |  Vector2       | O      | X        |
  *
  */
 class DALI_TOOLKIT_API CanvasView : public Control
 {
 public:
   /**
+   * @brief The start and end property ranges for this control.
+   */
+  enum PropertyRange
+  {
+    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+  };
+
+  /**
+   * @brief An enumeration of properties belonging to the CanvasView class.
+   */
+  struct Property
+  {
+    /**
+     * @brief An enumeration of properties belonging to the CanvasView class.
+     */
+    enum
+    {
+      /**
+       * @brief the viewbox of the CanvasView.
+       * @details Name "viewBox", type Property::VECTOR2.
+       */
+      VIEW_BOX = PROPERTY_START_INDEX,
+    };
+  };
+public:
+  /**
    * @brief Creates an uninitialized CanvasView.
    */
   CanvasView();
@@ -64,6 +94,13 @@ public:
   /**
    * @brief Creates an initialized CanvasView
    *
+   * @return A handle to a newly allocated CanvasView
+   */
+  static CanvasView New();
+
+  /**
+   * @brief Creates an initialized CanvasView
+   *
    * @param [in] viewBox The width and height.
    * @return A handle to a newly allocated CanvasView
    */
@@ -120,9 +157,23 @@ public:
   /**
    * @brief Add drawable object to the CanvasView.
    * This method is similar to registration. The added shape is drawn on the inner canvas.
+   * @param[in] drawable the drawable object.
    */
   void AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
 
+  /**
+   * @brief Remove drawable object to the CanvasView.
+   * This method is similar to deregistration.
+   * @param[in] drawable the drawable object.
+   * @return Returns True when it's successful. False otherwise.
+   */
+  bool RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable);
+
+  /**
+   * @brief Remove all drawable objects added to the CanvasView.
+   */
+  void RemoveAllDrawables();
+
 public: // Not intended for application developers
   /// @cond internal
   /**
index bfa5502..7fff902 100755 (executable)
@@ -394,6 +394,11 @@ void WebView::RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngine
   Dali::Toolkit::GetImpl(*this).RegisterContextMenuHiddenCallback(callback);
 }
 
+void WebView::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
+{
+  Dali::Toolkit::GetImpl(*this).GetPlainTextAsynchronously(callback);
+}
+
 WebView::WebView(Internal::WebView& implementation)
 : Control(implementation)
 {
index b4e7688..fa8cee3 100755 (executable)
@@ -733,6 +733,13 @@ public:
    */
   void RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngineContextMenuHiddenCallback callback);
 
+  /**
+   * @brief Get a plain text of current web page asynchronously.
+   *
+   * @param[in] callback The callback function called asynchronously.
+   */
+  void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback);
+
 public: // Not intended for application developers
   /// @cond internal
   /**
index af3cc41..a1a3c49 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_TOOLKIT_IMAGE_ATLAS_H
 #define DALI_TOOLKIT_IMAGE_ATLAS_H
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -157,7 +157,7 @@ public:
    * @param [in] size The width and height to fit the loaded image to.
    * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
    * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
-   * @param[in] atlasUploadObserver The observer to observe the upload state inside the ImageAtlas.
+   * @param [in] atlasUploadObserver The observer to observe the upload state inside the ImageAtlas.
    * @return True if there is enough space to fit this image in,false otherwise.
    * @note The valid callback function here is required to have the signature of void( void ).
    */
index 6d310cf..c04a730 100644 (file)
@@ -25,8 +25,8 @@
 #include <dali/public-api/object/type-registry.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/canvas-view/canvas-view.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
@@ -45,6 +45,7 @@ BaseHandle Create()
 }
 // Setup properties, signals and actions using the type-registry.
 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CanvasView, Toolkit::Control, Create);
+DALI_PROPERTY_REGISTRATION(Toolkit, CanvasView, "viewBox", VECTOR2, VIEW_BOX)
 DALI_TYPE_REGISTRATION_END()
 } // anonymous namespace
 
@@ -54,12 +55,21 @@ CanvasView::CanvasView(const Vector2& viewBox)
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
   mCanvasRenderer(CanvasRenderer::New(viewBox)),
   mTexture(),
-  mChanged(false)
+  mTextureSet(),
+  mSize(viewBox),
+  mCanvasViewRasterizeThread(nullptr)
 {
 }
 
 CanvasView::~CanvasView()
 {
+  if(mCanvasViewRasterizeThread)
+  {
+    mCanvasViewRasterizeThread->RemoveTask(this);
+
+    CanvasViewRasterizeThread::TerminateThread(mCanvasViewRasterizeThread);
+  }
+
   if(Adaptor::IsAvailable())
   {
     Adaptor::Get().UnregisterProcessor(*this);
@@ -97,12 +107,11 @@ void CanvasView::OnInitialize()
 void CanvasView::OnRelayout(const Vector2& size, RelayoutContainer& container)
 {
   if(!mCanvasRenderer ||
-     mCanvasRenderer.GetSize() == size ||
      !mCanvasRenderer.SetSize(size))
   {
     return;
   }
-  mChanged = true;
+  mSize = size;
 }
 
 void CanvasView::OnSizeSet(const Vector3& targetSize)
@@ -110,58 +119,127 @@ void CanvasView::OnSizeSet(const Vector3& targetSize)
   Control::OnSizeSet(targetSize);
 
   if(!mCanvasRenderer ||
-     mCanvasRenderer.GetSize() == Vector2(targetSize) ||
      !mCanvasRenderer.SetSize(Vector2(targetSize)))
   {
     return;
   }
-  mChanged = true;
+  mSize.width  = targetSize.width;
+  mSize.height = targetSize.height;
 }
 
-void CanvasView::Process(bool postProcessor)
+void CanvasView::SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value)
 {
-  if(!mCanvasRenderer)
+  Toolkit::CanvasView canvasView = Toolkit::CanvasView::DownCast(Dali::BaseHandle(object));
+  if(canvasView)
   {
-    return;
+    CanvasView& canvasViewImpl(GetImpl(canvasView));
+
+    switch(propertyIndex)
+    {
+      case Toolkit::CanvasView::Property::VIEW_BOX:
+      {
+        Vector2 valueVector2;
+        if(value.Get(valueVector2))
+        {
+          canvasViewImpl.SetViewBox(valueVector2);
+        }
+        break;
+      }
+    }
   }
-  Commit();
 }
 
-void CanvasView::Commit()
+Property::Value CanvasView::GetProperty(BaseObject* object, Property::Index propertyIndex)
 {
-  if(mCanvasRenderer && mCanvasRenderer.Commit())
+  Property::Value value;
+
+  Toolkit::CanvasView canvasView = Toolkit::CanvasView::DownCast(Dali::BaseHandle(object));
+
+  if(canvasView)
   {
-    Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer();
-    auto               width  = pixbuf.GetWidth();
-    auto               height = pixbuf.GetHeight();
+    CanvasView& canvasViewImpl(GetImpl(canvasView));
 
-    Dali::PixelData pixelData = Devel::PixelBuffer::Convert(pixbuf);
-    if(!pixelData)
+    switch(propertyIndex)
     {
-      return;
+      case Toolkit::CanvasView::Property::VIEW_BOX:
+      {
+        value = canvasViewImpl.GetViewBox();
+        break;
+      }
     }
+  }
+  return value;
+}
 
-    if(!mTexture || mChanged)
-    {
-      mTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, width, height);
-      mTexture.Upload(pixelData);
-      TextureSet textureSet = TextureSet::New();
-      textureSet.SetTexture(0, mTexture);
-      Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
-      Shader   shader   = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
-      Renderer renderer = Renderer::New(geometry, shader);
-      renderer.SetTextures(textureSet);
-      renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
-
-      Self().AddRenderer(renderer);
-      mChanged = false;
-    }
-    else
+void CanvasView::Process(bool postProcessor)
+{
+  if(mCanvasRenderer && mCanvasRenderer.IsCanvasChanged() && mSize.width > 0 && mSize.height > 0)
+  {
+    AddRasterizationTask();
+  }
+}
+
+void CanvasView::AddRasterizationTask()
+{
+  CanvasRendererRasterizingTaskPtr newTask = new CanvasRendererRasterizingTask(this, mCanvasRenderer);
+
+  if(!mCanvasViewRasterizeThread)
+  {
+    mCanvasViewRasterizeThread = new CanvasViewRasterizeThread();
+    mCanvasViewRasterizeThread->RasterizationCompletedSignal().Connect(this, &CanvasView::ApplyRasterizedImage);
+    mCanvasViewRasterizeThread->Start();
+  }
+
+  if(mCanvasRenderer.Commit())
+  {
+    mCanvasViewRasterizeThread->AddTask(newTask);
+  }
+}
+
+void CanvasView::ApplyRasterizedImage(PixelData rasterizedPixelData)
+{
+  if(rasterizedPixelData)
+  {
+    auto rasterizedPixelDataWidth  = rasterizedPixelData.GetWidth();
+    auto rasterizedPixelDataHeight = rasterizedPixelData.GetHeight();
+
+    if(rasterizedPixelDataWidth > 0 && rasterizedPixelDataHeight > 0)
     {
-      //Update texture
-      mTexture.Upload(pixelData);
+      if(!mTexture || mTexture.GetWidth() != rasterizedPixelDataWidth || mTexture.GetHeight() != rasterizedPixelDataHeight)
+      {
+        mTexture = Texture::New(TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, rasterizedPixelDataWidth, rasterizedPixelDataHeight);
+        mTexture.Upload(rasterizedPixelData);
+
+        if(!mTextureSet)
+        {
+          mTextureSet       = TextureSet::New();
+          Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
+          Shader   shader   = Shader::New(SHADER_CANVAS_VIEW_VERT, SHADER_CANVAS_VIEW_FRAG);
+          Renderer renderer = Renderer::New(geometry, shader);
+          renderer.SetTextures(mTextureSet);
+          renderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true);
+
+          Actor actor = Self();
+          if(actor)
+          {
+            actor.AddRenderer(renderer);
+          }
+        }
+        mTextureSet.SetTexture(0, mTexture);
+      }
+      else
+      {
+        //Update texture
+        mTexture.Upload(rasterizedPixelData);
+      }
     }
   }
+
+  //If there are accumulated changes to CanvasRenderer during Rasterize, Rasterize once again.
+  if(mCanvasRenderer && mCanvasRenderer.IsCanvasChanged())
+  {
+    AddRasterizationTask();
+  }
 }
 
 bool CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
@@ -172,6 +250,42 @@ bool CanvasView::AddDrawable(Dali::CanvasRenderer::Drawable& drawable)
   }
   return false;
 }
+
+bool CanvasView::RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable)
+{
+  if(mCanvasRenderer && mCanvasRenderer.RemoveDrawable(drawable))
+  {
+    return true;
+  }
+  return false;
+}
+
+bool CanvasView::RemoveAllDrawables()
+{
+  if(mCanvasRenderer && mCanvasRenderer.RemoveAllDrawables())
+  {
+    return true;
+  }
+  return false;
+}
+
+bool CanvasView::SetViewBox(const Vector2& viewBox)
+{
+  if(mCanvasRenderer && mCanvasRenderer.SetViewBox(viewBox))
+  {
+    return true;
+  }
+  return false;
+}
+
+const Vector2& CanvasView::GetViewBox()
+{
+  if(mCanvasRenderer)
+  {
+    return mCanvasRenderer.GetViewBox();
+  }
+  return Vector2::ZERO;
+}
 } // namespace Internal
 } // namespace Toolkit
 } // namespace Dali
index b2d5775..6b6cf93 100644 (file)
@@ -33,10 +33,11 @@ namespace Dali
 {
 namespace Toolkit
 {
-class CanvasView;
-
 namespace Internal
 {
+class CanvasView;
+class CanvasViewRasterizeThread;
+
 class CanvasView : public Control, public Integration::Processor
 {
 public:
@@ -62,6 +63,32 @@ public:
    */
   bool AddDrawable(Dali::CanvasRenderer::Drawable& drawable);
 
+  /**
+   * Called when a property of an object of this type is set.
+   * @param[in] object The object whose property is set.
+   * @param[in] propertyIndex The property index.
+   * @param[in] value The new property value.
+   */
+  static void SetProperty(BaseObject* object, Property::Index propertyIndex, const Property::Value& value);
+
+  /**
+   * Called to retrieve a property of an object of this type.
+   * @param[in] object The object whose property is to be retrieved.
+   * @param[in] propertyIndex The property index.
+   * @return The current value of the property.
+   */
+  static Property::Value GetProperty(BaseObject* object, Property::Index propertyIndex);
+
+  /**
+   * @copydoc Toolkit::Control::CanvasView::RemoveDrawable
+   */
+  bool RemoveDrawable(Dali::CanvasRenderer::Drawable& drawable);
+
+  /**
+   * @copydoc Toolkit::Control::CanvasView::RemoveAllDrawables
+   */
+  bool RemoveAllDrawables();
+
 private: // From Control
   /**
    * @copydoc Control::OnRelayout
@@ -78,27 +105,50 @@ private: // From Control
    */
   void OnInitialize() override;
 
-protected: // Implementation of Processor
+  /**
+   * @brief This is the viewbox of the Canvas.
+   * @param[in] viewBox The size of viewbox.
+   * @return Returns True when it's successful. False otherwise.
+   */
+  bool SetViewBox(const Vector2& viewBox);
+
+  /**
+   * @brief This is the viewbox of the Canvas.
+   * @return Returns The size of viewbox.
+   */
+  const Vector2& GetViewBox();
+
+  /**
+   * @bried Rasterize the canvas, and add it to the view.
+   *
+   * @param[in] size The target size of the canvas view rasterization.
+   */
+  void AddRasterizationTask();
+
+protected:
   /**
    * @copydoc Dali::Integration::Processor::Process()
    */
   void Process(bool postProcessor) override;
 
-private:
+public:
   /**
-   * @brief Draw drawables added to CanvasView on inner canvas.
-   * Then make that buffer into a texture and add it to renderer.
+   * @bried Apply the rasterized image to the canvas view
+   *
+   * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
    */
-  void Commit();
+  void ApplyRasterizedImage(PixelData rasterizedPixelData);
 
 private:
   CanvasView(const CanvasView&) = delete;
   CanvasView& operator=(const CanvasView&) = delete;
 
 private:
-  CanvasRenderer mCanvasRenderer;
-  Dali::Texture  mTexture;
-  bool           mChanged;
+  CanvasRenderer             mCanvasRenderer;
+  Dali::Texture              mTexture;
+  TextureSet                 mTextureSet;
+  Vector2                    mSize;
+  CanvasViewRasterizeThread* mCanvasViewRasterizeThread;
 };
 
 } // namespace Internal
diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.cpp b/dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.cpp
new file mode 100644 (file)
index 0000000..97835c5
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "canvas-view-rasterize-thread.h"
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/thread-settings.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+CanvasRendererRasterizingTask::CanvasRendererRasterizingTask(CanvasView* canvasView, CanvasRenderer canvasRenderer)
+: mCanvasView(canvasView),
+  mCanvasRenderer(canvasRenderer),
+  mPixelData(PixelData()),
+  mBufferSize(0, 0)
+{
+}
+
+bool CanvasRendererRasterizingTask::Rasterize()
+{
+  if(mCanvasRenderer && mCanvasRenderer.Rasterize())
+  {
+    Devel::PixelBuffer pixbuf = mCanvasRenderer.GetPixelBuffer();
+    auto               width  = pixbuf.GetWidth();
+    auto               height = pixbuf.GetHeight();
+    if(width > 0 && height > 0)
+    {
+      mBufferSize.width  = width;
+      mBufferSize.height = height;
+
+      mPixelData = Devel::PixelBuffer::Convert(pixbuf);
+      return true;
+    }
+  }
+  return false;
+}
+
+CanvasView* CanvasRendererRasterizingTask::GetCanvasView() const
+{
+  return mCanvasView.Get();
+}
+
+PixelData CanvasRendererRasterizingTask::GetPixelData() const
+{
+  return mPixelData;
+}
+
+Vector2 CanvasRendererRasterizingTask::GetBufferSize() const
+{
+  return mBufferSize;
+}
+
+CanvasViewRasterizeThread::CanvasViewRasterizeThread()
+: mTrigger(new EventThreadCallback(MakeCallback(this, &CanvasViewRasterizeThread::ApplyRasterized))),
+  mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
+  mProcessorRegistered(false),
+  mRasterizationCompletedSignal()
+{
+}
+
+CanvasViewRasterizeThread::~CanvasViewRasterizeThread()
+{
+  if(mProcessorRegistered && Adaptor::IsAvailable())
+  {
+    Adaptor::Get().UnregisterProcessor(*this);
+  }
+}
+
+void CanvasViewRasterizeThread::TerminateThread(CanvasViewRasterizeThread*& thread)
+{
+  if(thread)
+  {
+    // add an empty task would stop the thread from conditional wait.
+    thread->AddTask(CanvasRendererRasterizingTaskPtr());
+    // stop the thread
+    thread->Join();
+    // delete the thread
+    delete thread;
+    thread = NULL;
+  }
+}
+
+void CanvasViewRasterizeThread::AddTask(CanvasRendererRasterizingTaskPtr task)
+{
+  bool wasEmpty = false;
+
+  {
+    // Lock while adding task to the queue
+    ConditionalWait::ScopedLock lock(mConditionalWait);
+    wasEmpty = mRasterizeTasks.empty();
+    if(!wasEmpty && task != NULL)
+    {
+      // Remove the tasks with the same renderer.
+      // Older task which waiting to rasterize and apply the svg to the same renderer is expired.
+      for(std::vector<CanvasRendererRasterizingTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
+      {
+        if((*it) && (*it)->GetCanvasView() == task->GetCanvasView()) //Need
+        {
+          mRasterizeTasks.erase(it);
+          break;
+        }
+      }
+    }
+    mRasterizeTasks.push_back(task);
+
+    if(!mProcessorRegistered && Adaptor::IsAvailable())
+    {
+      Adaptor::Get().RegisterProcessor(*this);
+      mProcessorRegistered = true;
+    }
+  }
+
+  if(wasEmpty)
+  {
+    // wake up the image loading thread
+    mConditionalWait.Notify();
+  }
+}
+
+CanvasRendererRasterizingTaskPtr CanvasViewRasterizeThread::NextCompletedTask()
+{
+  // Lock while popping task out from the queue
+  Mutex::ScopedLock lock(mMutex);
+
+  if(mCompletedTasks.empty())
+  {
+    return CanvasRendererRasterizingTaskPtr();
+  }
+
+  std::vector<CanvasRendererRasterizingTaskPtr>::iterator next     = mCompletedTasks.begin();
+  CanvasRendererRasterizingTaskPtr                        nextTask = *next;
+  mCompletedTasks.erase(next);
+
+  return nextTask;
+}
+
+void CanvasViewRasterizeThread::RemoveTask(CanvasView* canvasView)
+{
+  // Lock while remove task from the queue
+  ConditionalWait::ScopedLock lock(mConditionalWait);
+  if(!mRasterizeTasks.empty())
+  {
+    for(std::vector<CanvasRendererRasterizingTaskPtr>::iterator it = mRasterizeTasks.begin(), endIt = mRasterizeTasks.end(); it != endIt; ++it)
+    {
+      if((*it) && (*it)->GetCanvasView() == canvasView)
+      {
+        mRasterizeTasks.erase(it);
+        break;
+      }
+    }
+  }
+
+  UnregisterProcessor();
+}
+
+CanvasRendererRasterizingTaskPtr CanvasViewRasterizeThread::NextTaskToProcess()
+{
+  // Lock while popping task out from the queue
+  ConditionalWait::ScopedLock lock(mConditionalWait);
+
+  // conditional wait
+  while(mRasterizeTasks.empty())
+  {
+    mConditionalWait.Wait(lock);
+  }
+
+  // pop out the next task from the queue
+  std::vector<CanvasRendererRasterizingTaskPtr>::iterator next     = mRasterizeTasks.begin();
+  CanvasRendererRasterizingTaskPtr                        nextTask = *next;
+  mRasterizeTasks.erase(next);
+
+  return nextTask;
+}
+
+void CanvasViewRasterizeThread::AddCompletedTask(CanvasRendererRasterizingTaskPtr task)
+{
+  // Lock while adding task to the queue
+  Mutex::ScopedLock lock(mMutex);
+  mCompletedTasks.push_back(task);
+
+  // wake up the main thread
+  mTrigger->Trigger();
+}
+
+void CanvasViewRasterizeThread::Run()
+{
+  SetThreadName("CanvasViewThread");
+  mLogFactory.InstallLogFunction();
+
+  while(CanvasRendererRasterizingTaskPtr task = NextTaskToProcess())
+  {
+    if(task->Rasterize())
+    {
+      AddCompletedTask(task);
+    }
+  }
+}
+
+void CanvasViewRasterizeThread::ApplyRasterized()
+{
+  while(CanvasRendererRasterizingTaskPtr task = NextCompletedTask())
+  {
+    RasterizationCompletedSignal().Emit(task->GetPixelData());
+  }
+
+  UnregisterProcessor();
+}
+
+void CanvasViewRasterizeThread::Process(bool postProcessor)
+{
+  ApplyRasterized();
+}
+
+CanvasViewRasterizeThread::RasterizationCompletedSignalType& CanvasViewRasterizeThread::RasterizationCompletedSignal()
+{
+  return mRasterizationCompletedSignal;
+}
+
+void CanvasViewRasterizeThread::UnregisterProcessor()
+{
+  if(mProcessorRegistered)
+  {
+    if(mRasterizeTasks.empty() && mCompletedTasks.empty() && Adaptor::IsAvailable())
+    {
+      Adaptor::Get().UnregisterProcessor(*this);
+      mProcessorRegistered = false;
+    }
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.h b/dali-toolkit/internal/controls/canvas-view/canvas-view-rasterize-thread.h
new file mode 100644 (file)
index 0000000..0c16fd9
--- /dev/null
@@ -0,0 +1,230 @@
+#ifndef DALI_TOOLKIT_CANVAS_VIEW_RASTERIZE_THREAD_H
+#define DALI_TOOLKIT_CANVAS_VIEW_RASTERIZE_THREAD_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/canvas-renderer.h>
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
+#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/threading/thread.h>
+#include <dali/integration-api/adaptor-framework/log-factory-interface.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/images/pixel-data.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/rendering/texture-set.h>
+#include <memory>
+#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+using CanvasViewPtr = IntrusivePtr<CanvasView>;
+class CanvasRendererRasterizingTask;
+using CanvasRendererRasterizingTaskPtr = IntrusivePtr<CanvasRendererRasterizingTask>;
+
+/**
+ * The canvasview rasterizing tasks to be processed in the worker thread.
+ *
+ * Life cycle of a rasterizing task is as follows:
+ * 1. Created by CanvasView in the main thread
+ * 2. Queued in the worked thread waiting to be processed.
+ * 3. If this task gets its turn to do the rasterization, it triggers main thread to apply the rasterized image to material then been deleted in main thread call back.
+ *    Or if this task is been removed before its turn to be processed, it then been deleted in the worker thread.
+ */
+class CanvasRendererRasterizingTask : public RefObject
+{
+public:
+  /**
+   * Constructor
+   * @param[in] canvasRenderer The renderer which the rasterized canvas to be applied.
+   */
+  CanvasRendererRasterizingTask(CanvasView* canvasView, CanvasRenderer canvasRenderer);
+
+  /**
+   * Destructor.
+   */
+  ~CanvasRendererRasterizingTask() = default;
+
+  /**
+   * Do the rasterization with the mRasterizer.
+   * @return Returns True when it's successful. False otherwise.
+   */
+  bool Rasterize();
+
+  /**
+   * Get the CanvasView
+   * @return The CanvasView pointer.
+   */
+  CanvasView* GetCanvasView() const;
+
+  /**
+   * Get the rasterization result.
+   * @return The pixel data with the rasterized pixels.
+   */
+  PixelData GetPixelData() const;
+
+  /**
+   * Get size of rasterization result.
+   * @return The size of the pixel data.
+   */
+  Vector2 GetBufferSize() const;
+
+private:
+  // Undefined
+  CanvasRendererRasterizingTask(const CanvasRendererRasterizingTask& task);
+
+  // Undefined
+  CanvasRendererRasterizingTask& operator=(const CanvasRendererRasterizingTask& task);
+
+private:
+  CanvasViewPtr  mCanvasView;
+  CanvasRenderer mCanvasRenderer;
+  PixelData      mPixelData;
+  Vector2        mBufferSize;
+};
+
+/**
+ * The worker thread for CanvasView rasterization.
+ */
+class CanvasViewRasterizeThread : public Thread, Integration::Processor
+{
+public:
+  /// @brief ApplyRasterizedImage Event signal type
+  using RasterizationCompletedSignalType = Signal<void(PixelData)>;
+
+public:
+  /**
+   * Constructor.
+   *
+   * @param[in] trigger The trigger to wake up the main thread.
+   */
+  CanvasViewRasterizeThread();
+
+  /**
+   * Terminate the CanvasView rasterize thread, join and delete.
+   *
+   * @param[in] thread The rasterize thread.
+   */
+  static void TerminateThread(CanvasViewRasterizeThread*& thread);
+
+  /**
+   * Add a rasterization task into the waiting queue, called by main thread.
+   *
+   * @param[in] task The task added to the queue.
+   */
+  void AddTask(CanvasRendererRasterizingTaskPtr task);
+
+  /**
+   * Remove the task with the given CanvasView from the waiting queue, called by main thread.
+   *
+   * Typically called when the actor is put off stage, so the renderer is not needed anymore.
+   *
+   * @param[in] canvasView The CanvasView pointer.
+   */
+  void RemoveTask(CanvasView* canvasView);
+
+  /**
+   * Applies the rasterized image to material
+   */
+  void ApplyRasterized();
+
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process(bool postProcessor) override;
+
+  /**
+   * @brief This signal is emitted when rasterized image is applied.
+   *
+   * @return The signal to connect to
+   */
+  RasterizationCompletedSignalType& RasterizationCompletedSignal();
+
+private:
+  /**
+   * Pop the next task out from the queue.
+   *
+   * @return The next task to be processed.
+   */
+  CanvasRendererRasterizingTaskPtr NextTaskToProcess();
+
+  /**
+   * Pop the next task out from the completed queue, called by main thread.
+   *
+   * @return The next task in the completed queue.
+   */
+  CanvasRendererRasterizingTaskPtr NextCompletedTask();
+
+  /**
+   * Add a task in to the queue
+   *
+   * @param[in] task The task added to the queue.
+   */
+  void AddCompletedTask(CanvasRendererRasterizingTaskPtr task);
+
+  /**
+   * @brief Unregister a previously registered processor
+   *
+   */
+  void UnregisterProcessor();
+
+protected:
+  /**
+   * Destructor.
+   */
+  ~CanvasViewRasterizeThread() override;
+
+  /**
+   * The entry function of the worker thread.
+   * It fetches task from the Queue, rasterizes the image and apply to the renderer.
+   */
+  void Run() override;
+
+private:
+  // Undefined
+  CanvasViewRasterizeThread(const CanvasViewRasterizeThread& thread);
+
+  // Undefined
+  CanvasViewRasterizeThread& operator=(const CanvasViewRasterizeThread& thread);
+
+private:
+  std::vector<CanvasRendererRasterizingTaskPtr> mRasterizeTasks; //The queue of the tasks waiting to rasterize the CanvasView.
+  std::vector<CanvasRendererRasterizingTaskPtr> mCompletedTasks; //The queue of the tasks with the SVG rasterization completed
+
+  ConditionalWait                      mConditionalWait;
+  Dali::Mutex                          mMutex;
+  std::unique_ptr<EventThreadCallback> mTrigger;
+  const Dali::LogFactoryInterface&     mLogFactory;
+  bool                                 mProcessorRegistered;
+  RasterizationCompletedSignalType     mRasterizationCompletedSignal;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_CANVAS_VIEW_RASTERIZE_THREAD_H
index 8fd35e0..ced845a 100644 (file)
@@ -439,6 +439,11 @@ Dali::Rect<> GetShowingGeometry(Dali::Rect<> rect, Dali::Toolkit::DevelControl::
   return rect;
 }
 
+static bool IsShowingGeometryOnScreen(Dali::Rect<> rect)
+{
+  return rect.width > 0 && rect.height > 0;
+}
+
 } // unnamed namespace
 
 // clang-format off
@@ -547,45 +552,63 @@ const Control::Impl& Control::Impl::Get(const Internal::Control& internalControl
   return *internalControl.mImpl;
 }
 
-void Control::Impl::CheckHighlightedObjectGeometry(PropertyNotification& propertyNotification)
+void Control::Impl::CheckHighlightedObjectGeometry()
 {
   auto accessibleImpl = dynamic_cast<Dali::Toolkit::DevelControl::AccessibleImpl*>(mAccessibilityObject.get());
-  auto lastPosition   = accessibleImpl->GetLastPosition();
-  auto accessibleRect = accessibleImpl->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
-
-  if(lastPosition.x == accessibleRect.x && lastPosition.y == accessibleRect.y)
+  if(!accessibleImpl)
   {
+    DALI_LOG_ERROR("accessibleImpl is not a pointer to a DevelControl::AccessibleImpl type");
     return;
   }
 
+  auto lastPosition   = accessibleImpl->GetLastPosition();
+  auto accessibleRect = accessibleImpl->GetExtents(Dali::Accessibility::CoordinateType::WINDOW);
   auto rect = GetShowingGeometry(accessibleRect, accessibleImpl);
 
-  // MoveOuted is sent already, no need to send it again
-  if(mAccessibilityMovedOutOfScreenDirection != Dali::Accessibility::MovedOutOfScreenType::NONE)
+  switch(mAccessibilityLastScreenRelativeMoveType)
   {
-    if(rect.width > 0 && rect.height > 0)
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE:
     {
-      // flick next does not use MoveOuted - ScrollToSelf makes object show, so reset for sending MoveOuted next
-      mAccessibilityMovedOutOfScreenDirection = Dali::Accessibility::MovedOutOfScreenType::NONE;
+      if(IsShowingGeometryOnScreen(rect))
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
+      }
+      break;
+    }
+    case Dali::Accessibility::ScreenRelativeMoveType::INSIDE:
+    {
+      if(rect.width < 0 && accessibleRect.x != lastPosition.x)
+      {
+        mAccessibilityLastScreenRelativeMoveType = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
+      }
+      if(rect.height < 0 && accessibleRect.y != lastPosition.y)
+      {
+        mAccessibilityLastScreenRelativeMoveType = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT : Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT;
+      }
+      // notify AT-clients on outgoing moves only
+      if(mAccessibilityLastScreenRelativeMoveType != Dali::Accessibility::ScreenRelativeMoveType::INSIDE)
+      {
+        mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityLastScreenRelativeMoveType);
+      }
+      break;
+    }
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_TOP_LEFT:
+    case Dali::Accessibility::ScreenRelativeMoveType::OUTGOING_BOTTOM_RIGHT:
+    {
+      if(IsShowingGeometryOnScreen(rect))
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::INSIDE;
+      }
+      else
+      {
+        mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
+      }
+      break;
+    }
+    default:
+    {
+      break;
     }
-    return;
-  }
-
-  if(rect.width < 0)
-  {
-    mAccessibilityMovedOutOfScreenDirection = (accessibleRect.x < lastPosition.x) ? Dali::Accessibility::MovedOutOfScreenType::TOP_LEFT : Dali::Accessibility::MovedOutOfScreenType::BOTTOM_RIGHT;
-  }
-
-  if(rect.height < 0)
-  {
-    mAccessibilityMovedOutOfScreenDirection = (accessibleRect.y < lastPosition.y) ? Dali::Accessibility::MovedOutOfScreenType::TOP_LEFT : Dali::Accessibility::MovedOutOfScreenType::BOTTOM_RIGHT;
-  }
-
-  if(mAccessibilityMovedOutOfScreenDirection != Dali::Accessibility::MovedOutOfScreenType::NONE)
-  {
-    mAccessibilityObject.get()->EmitMovedOutOfScreen(mAccessibilityMovedOutOfScreenDirection);
-    accessibleImpl->SetLastPosition(Vector2(0.0f, 0.0f));
-    return;
   }
 
   accessibleImpl->SetLastPosition(Vector2(accessibleRect.x, accessibleRect.y));
@@ -597,11 +620,13 @@ void Control::Impl::RegisterAccessibilityPositionPropertyNotification()
   {
     return;
   }
-
-  mAccessibilityMovedOutOfScreenDirection = Dali::Accessibility::MovedOutOfScreenType::NONE;
-  mAccessibilityPositionNotification      = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
+  // set default value until first move of object is detected
+  mAccessibilityLastScreenRelativeMoveType = Dali::Accessibility::ScreenRelativeMoveType::OUTSIDE;
+  // recalculate mAccessibilityLastScreenRelativeMoveType accordingly to the initial position
+  CheckHighlightedObjectGeometry();
+  mAccessibilityPositionNotification       = mControlImpl.Self().AddPropertyNotification(Actor::Property::WORLD_POSITION, StepCondition(1.0f, 1.0f));
   mAccessibilityPositionNotification.SetNotifyMode(PropertyNotification::NOTIFY_ON_CHANGED);
-  mAccessibilityPositionNotification.NotifySignal().Connect(this, &Control::Impl::CheckHighlightedObjectGeometry);
+  mAccessibilityPositionNotification.NotifySignal().Connect(this, [this](PropertyNotification&){ CheckHighlightedObjectGeometry(); });
   mIsAccessibilityPositionPropertyNotificationSet = true;
 }
 
index 4c480a0..73b12e0 100644 (file)
@@ -470,9 +470,8 @@ private:
 
   /**
    * @brief Checks highlighted object geometry if it is showing or not
-   * @param[in] propertyNotification PropertyNotification
    */
-  void CheckHighlightedObjectGeometry(Dali::PropertyNotification& propertyNotification);
+  void CheckHighlightedObjectGeometry();
 
   /**
    * @brief Register property notification to check highlighted object position
@@ -495,17 +494,17 @@ public:
   int mUpFocusableActorId;    ///< Actor ID of Up focusable control.
   int mDownFocusableActorId;  ///< Actor ID of Down focusable control.
 
-  RegisteredVisualContainer                                      mVisuals; ///< Stores visuals needed by the control, non trivial type so std::vector used.
-  std::string                                                    mStyleName;
-  Vector4                                                        mBackgroundColor;    ///< The color of the background visual
-  Vector3*                                                       mStartingPinchScale; ///< The scale when a pinch gesture starts, TODO: consider removing this
-  Extents                                                        mMargin;             ///< The margin values
-  Extents                                                        mPadding;            ///< The padding values
-  Toolkit::Control::KeyEventSignalType                           mKeyEventSignal;
-  Toolkit::Control::KeyInputFocusSignalType                      mKeyInputFocusGainedSignal;
-  Toolkit::Control::KeyInputFocusSignalType                      mKeyInputFocusLostSignal;
-  Toolkit::Control::ResourceReadySignalType                      mResourceReadySignal;
-  DevelControl::VisualEventSignalType                            mVisualEventSignal;
+  RegisteredVisualContainer                 mVisuals; ///< Stores visuals needed by the control, non trivial type so std::vector used.
+  std::string                               mStyleName;
+  Vector4                                   mBackgroundColor;    ///< The color of the background visual
+  Vector3*                                  mStartingPinchScale; ///< The scale when a pinch gesture starts, TODO: consider removing this
+  Extents                                   mMargin;             ///< The margin values
+  Extents                                   mPadding;            ///< The padding values
+  Toolkit::Control::KeyEventSignalType      mKeyEventSignal;
+  Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
+  Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
+  Toolkit::Control::ResourceReadySignalType mResourceReadySignal;
+  DevelControl::VisualEventSignalType       mVisualEventSignal;
 
   // Accessibility
   Toolkit::DevelControl::AccessibilityActivateSignalType         mAccessibilityActivateSignal;
@@ -515,15 +514,15 @@ public:
   Toolkit::DevelControl::AccessibilityReadingCancelledSignalType mAccessibilityReadingCancelledSignal;
   Toolkit::DevelControl::AccessibilityReadingStoppedSignalType   mAccessibilityReadingStoppedSignal;
 
-  Toolkit::DevelControl::AccessibilityGetNameSignalType          mAccessibilityGetNameSignal;
-  Toolkit::DevelControl::AccessibilityGetDescriptionSignalType   mAccessibilityGetDescriptionSignal;
-  Toolkit::DevelControl::AccessibilityDoGestureSignalType        mAccessibilityDoGestureSignal;
+  Toolkit::DevelControl::AccessibilityGetNameSignalType        mAccessibilityGetNameSignal;
+  Toolkit::DevelControl::AccessibilityGetDescriptionSignalType mAccessibilityGetDescriptionSignal;
+  Toolkit::DevelControl::AccessibilityDoGestureSignalType      mAccessibilityDoGestureSignal;
 
   std::string mAccessibilityName;
   std::string mAccessibilityDescription;
   std::string mAccessibilityTranslationDomain;
-  bool        mAccessibilityNameSet = false;
-  bool        mAccessibilityDescriptionSet = false;
+  bool        mAccessibilityNameSet              = false;
+  bool        mAccessibilityDescriptionSet       = false;
   bool        mAccessibilityTranslationDomainSet = false;
 
   bool mAccessibilityHighlightable    = false;
@@ -581,9 +580,9 @@ public:
 
 private:
   // Accessibility - notification for highlighted object to check if it is showing.
-  bool                                      mIsAccessibilityPositionPropertyNotificationSet{false};
-  Dali::PropertyNotification                mAccessibilityPositionNotification;
-  Dali::Accessibility::MovedOutOfScreenType mAccessibilityMovedOutOfScreenDirection;
+  bool                                        mIsAccessibilityPositionPropertyNotificationSet{false};
+  Dali::PropertyNotification                  mAccessibilityPositionNotification;
+  Dali::Accessibility::ScreenRelativeMoveType mAccessibilityLastScreenRelativeMoveType{Accessibility::ScreenRelativeMoveType::OUTSIDE};
 };
 
 } // namespace Internal
old mode 100755 (executable)
new mode 100644 (file)
index 170495c..e336f2c
@@ -766,6 +766,14 @@ void WebView::RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngine
   }
 }
 
+void WebView::GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback)
+{
+  if(mWebEngine)
+  {
+    mWebEngine.GetPlainTextAsynchronously(callback);
+  }
+}
+
 void WebView::OnFrameRendered()
 {
   if(mFrameRenderedCallback)
index c2d6742..15f3ce3 100755 (executable)
@@ -392,6 +392,11 @@ public:
    */
   void RegisterContextMenuHiddenCallback(Dali::WebEnginePlugin::WebEngineContextMenuHiddenCallback callback);
 
+  /**
+   * @copydoc Dali::Toolkit::WebView::GetPlainTextAsynchronously()
+   */
+  void GetPlainTextAsynchronously(Dali::WebEnginePlugin::PlainTextReceivedCallback callback);
+
 public: // Properties
   /**
    * @brief Called when a property of an object of this type is set.
index a661176..33b594a 100644 (file)
@@ -62,6 +62,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/controls/buttons/radio-button-impl.cpp
    ${toolkit_src_dir}/controls/buttons/toggle-button-impl.cpp
    ${toolkit_src_dir}/controls/canvas-view/canvas-view-impl.cpp
+   ${toolkit_src_dir}/controls/canvas-view/canvas-view-rasterize-thread.cpp
    ${toolkit_src_dir}/controls/control/control-data-impl.cpp
    ${toolkit_src_dir}/controls/control/control-debug.cpp
    ${toolkit_src_dir}/controls/control/control-renderers.cpp
index 412eda7..ea10924 100644 (file)
@@ -21,6 +21,9 @@
 // EXTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/adaptor.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -71,7 +74,24 @@ uint32_t AsyncImageLoader::Load(const VisualUrl&                         url,
     mLoadThread.Start();
     mIsLoadThreadStarted = true;
   }
-  mLoadThread.AddTask(new LoadingTask(++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad));
+  if(url.IsBufferResource())
+  {
+    auto visualFactory = Toolkit::VisualFactory::Get();
+    if(visualFactory)
+    {
+      // Get EncodedImageBuffer from texturemanager
+      // and make new LoadingTask with buffer
+      auto& textureManager = GetImplementation(visualFactory).GetTextureManager();
+
+      const EncodedImageBuffer& encodedBuffer = textureManager.GetEncodedImageBuffer(url.GetUrl());
+
+      mLoadThread.AddTask(new LoadingTask(++mLoadTaskId, encodedBuffer, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad));
+    }
+  }
+  else
+  {
+    mLoadThread.AddTask(new LoadingTask(++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad));
+  }
 
   return mLoadTaskId;
 }
index 8c4dba6..31c3351 100644 (file)
@@ -24,6 +24,9 @@
 #include <dali/public-api/signals/callback.h>
 #include <string.h>
 
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -130,7 +133,7 @@ void ImageAtlas::SetBrokenImage(const std::string& brokenImageUrl)
 }
 
 bool ImageAtlas::Upload(Vector4&             textureRect,
-                        const std::string&   url,
+                        const VisualUrl&     url,
                         ImageDimensions      size,
                         FittingMode::Type    fittingMode,
                         bool                 orientationCorrection,
@@ -140,7 +143,7 @@ bool ImageAtlas::Upload(Vector4&             textureRect,
   ImageDimensions zero;
   if(size == zero) // image size not provided
   {
-    dimensions = Dali::GetClosestImageSize(url);
+    dimensions = Dali::GetClosestImageSize(url.GetUrl());
     if(dimensions == zero) // Fail to read the image & broken image file exists
     {
       if(!mBrokenImageUrl.empty())
@@ -159,7 +162,7 @@ bool ImageAtlas::Upload(Vector4&             textureRect,
   unsigned int packPositionY = 0;
   if(mPacker.Pack(dimensions.GetWidth(), dimensions.GetHeight(), packPositionX, packPositionY))
   {
-    unsigned short loadId = mAsyncLoader.Load(url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection);
+    unsigned short loadId = GetImplementation(mAsyncLoader).Load(url, size, fittingMode, SamplingMode::BOX_THEN_LINEAR, orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad::OFF);
     mLoadingTaskInfoContainer.PushBack(new LoadingTaskInfo(loadId, packPositionX, packPositionY, dimensions.GetWidth(), dimensions.GetHeight(), atlasUploadObserver));
     // apply the half pixel correction
     textureRect.x = (static_cast<float>(packPositionX) + 0.5f) / mWidth;                      // left
index 49dd3ef..eab1551 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
 #include <dali-toolkit/internal/image-loader/atlas-packer.h>
 #include <dali-toolkit/public-api/image-loader/async-image-loader.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -78,7 +79,7 @@ public:
    * @copydoc Toolkit::ImageAtlas::Upload( Vector4&, const std::string&, ImageDimensions,FittingMode::Type, bool )
    */
   bool Upload(Vector4&             textureRect,
-              const std::string&   url,
+              const VisualUrl&     url,
               ImageDimensions      size,
               FittingMode::Type    fittingMode,
               bool                 orientationCorrection,
index 7fc344f..43b0707 100644 (file)
@@ -19,6 +19,7 @@
 #include "image-load-thread.h"
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/adaptor-framework/thread-settings.h>
 #include <dali/integration-api/adaptor-framework/adaptor.h>
@@ -33,6 +34,7 @@ namespace Internal
 LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLoading, uint32_t frameIndex)
 : pixelBuffer(),
   url(),
+  encodedImageBuffer(),
   id(id),
   dimensions(),
   fittingMode(),
@@ -51,6 +53,26 @@ LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLo
 LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 : pixelBuffer(),
   url(url),
+  encodedImageBuffer(),
+  id(id),
+  dimensions(dimensions),
+  fittingMode(fittingMode),
+  samplingMode(samplingMode),
+  orientationCorrection(orientationCorrection),
+  preMultiplyOnLoad(preMultiplyOnLoad),
+  isMaskTask(false),
+  maskPixelBuffer(),
+  contentScale(1.0f),
+  cropToMask(false),
+  animatedImageLoading(),
+  frameIndex(0u)
+{
+}
+
+LoadingTask::LoadingTask(uint32_t id, const EncodedImageBuffer& encodedImageBuffer, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
+: pixelBuffer(),
+  url(),
+  encodedImageBuffer(encodedImageBuffer),
   id(id),
   dimensions(dimensions),
   fittingMode(fittingMode),
@@ -69,6 +91,7 @@ LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dime
 LoadingTask::LoadingTask(uint32_t id, Devel::PixelBuffer pixelBuffer, Devel::PixelBuffer maskPixelBuffer, float contentScale, bool cropToMask, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 : pixelBuffer(pixelBuffer),
   url(""),
+  encodedImageBuffer(),
   id(id),
   dimensions(),
   fittingMode(),
@@ -90,11 +113,15 @@ void LoadingTask::Load()
   {
     pixelBuffer = animatedImageLoading.LoadFrame(frameIndex);
   }
-  else if(url.IsLocalResource())
+  else if(encodedImageBuffer)
+  {
+    pixelBuffer = Dali::LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), dimensions, fittingMode, samplingMode, orientationCorrection);
+  }
+  else if(url.IsValid() && url.IsLocalResource())
   {
     pixelBuffer = Dali::LoadImageFromFile(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection);
   }
-  else
+  else if(url.IsValid())
   {
     pixelBuffer = Dali::DownloadImageSynchronously(url.GetUrl(), dimensions, fittingMode, samplingMode, orientationCorrection);
   }
index 9505b17..95ec260 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 
 namespace Dali
 {
@@ -72,6 +73,24 @@ struct LoadingTask
   /**
    * Constructor.
    * @param [in] id of the task
+   * @param [in] encodedImageBuffer The encoded buffer of the image to load.
+   * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image
+   * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+   * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
+   * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
+   * @param [in] preMultiplyOnLoad ON if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
+   */
+  LoadingTask(uint32_t                                 id,
+              const EncodedImageBuffer&                encodedImageBuffer,
+              ImageDimensions                          dimensions,
+              FittingMode::Type                        fittingMode,
+              SamplingMode::Type                       samplingMode,
+              bool                                     orientationCorrection,
+              DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
+
+  /**
+   * Constructor.
+   * @param [in] id of the task
    * @param [in] pixelBuffer of the to be masked image
    * @param [in] maskPixelBuffer of the mask image
    * @param [in] contentScale The factor to scale the content
@@ -111,6 +130,7 @@ public:
   Devel::PixelBuffer pixelBuffer;                                     ///< pixelBuffer handle after successful load
                                                                       ///< or pixelBuffer to be masked image in the mask task
   VisualUrl                                url;                       ///< url of the image to load
+  EncodedImageBuffer                       encodedImageBuffer;        ///< encoded buffer of the image to load
   uint32_t                                 id;                        ///< The unique id associated with this task.
   ImageDimensions                          dimensions;                ///< dimensions to load
   FittingMode::Type                        fittingMode;               ///< fitting options
index 055738f..52ba6c4 100644 (file)
  */
 
 // CLASS HEADER
-#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/internal/image-loader/image-url-impl.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include <dali-toolkit/internal/visuals/visual-factory-impl.h>
+#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -26,14 +31,39 @@ namespace Toolkit
 namespace Internal
 {
 ImageUrl::ImageUrl(Texture& texture)
-: mUrl("")
 {
   mUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
 }
 
+ImageUrl::ImageUrl(const EncodedImageBuffer& encodedImageBuffer)
+: mUrl("")
+{
+  auto visualFactory = Dali::Toolkit::VisualFactory::Get();
+  if(visualFactory)
+  {
+    auto& textureManager = GetImplementation(visualFactory).GetTextureManager();
+    mUrl = textureManager.AddExternalEncodedImageBuffer(encodedImageBuffer);
+  }
+}
+
 ImageUrl::~ImageUrl()
 {
-  Dali::Toolkit::TextureManager::RemoveTexture(mUrl);
+  if(mUrl.size() > 0)
+  {
+    auto visualFactory = Dali::Toolkit::VisualFactory::Get();
+    if(visualFactory)
+    {
+      auto& textureManager = GetImplementation(visualFactory).GetTextureManager();
+      if(VisualUrl::TEXTURE == VisualUrl::GetProtocolType(mUrl))
+      {
+        textureManager.RemoveExternalTexture(mUrl);
+      }
+      else if(VisualUrl::BUFFER == VisualUrl::GetProtocolType(mUrl))
+      {
+        textureManager.RemoveExternalEncodedImageBuffer(mUrl);
+      }
+    }
+  }
 }
 
 ImageUrlPtr ImageUrl::New(Texture& texture)
@@ -42,6 +72,12 @@ ImageUrlPtr ImageUrl::New(Texture& texture)
   return imageUrlPtr;
 }
 
+ImageUrlPtr ImageUrl::New(const EncodedImageBuffer& encodedImageBuffer)
+{
+  ImageUrlPtr imageUrlPtr = new ImageUrl(encodedImageBuffer);
+  return imageUrlPtr;
+}
+
 const std::string& ImageUrl::GetUrl() const
 {
   return mUrl;
index 45981b2..99616bf 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/base-object.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 #include <string>
 
 // INTERNAL INCLUDES
@@ -43,11 +44,21 @@ public:
   ImageUrl(Texture& texture);
 
   /**
+   * @brief Constructor.
+   */
+  ImageUrl(const EncodedImageBuffer& encodedImageBuffer);
+
+  /**
    * @copydoc Dali::Toolkit::ImageUrl::New
    */
   static ImageUrlPtr New(Texture& texture);
 
   /**
+   * @copydoc Dali::Toolkit::ImageUrl::New
+   */
+  static ImageUrlPtr New(const EncodedImageBuffer& encodedImageBuffer);
+
+  /**
    * @copydoc Dali::Toolkit::ImageUrl::GetUrl
    */
   const std::string& GetUrl() const;
index 1f634e1..a8de5a8 100644 (file)
@@ -21,6 +21,9 @@
 // EXTERNAL HEADER
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
+
 namespace Dali
 {
 namespace Toolkit
@@ -44,7 +47,7 @@ ImageAtlasManager::~ImageAtlasManager()
 }
 
 TextureSet ImageAtlasManager::Add(Vector4&             textureRect,
-                                  const std::string&   url,
+                                  const VisualUrl&     url,
                                   ImageDimensions&     size,
                                   FittingMode::Type    fittingMode,
                                   bool                 orientationCorrection,
@@ -54,7 +57,7 @@ TextureSet ImageAtlasManager::Add(Vector4&             textureRect,
   ImageDimensions zero;
   if(size == zero)
   {
-    dimensions = Dali::GetClosestImageSize(url);
+    dimensions = Dali::GetClosestImageSize(url.GetUrl());
   }
 
   // big image, atlasing is not applied
@@ -67,7 +70,7 @@ TextureSet ImageAtlasManager::Add(Vector4&             textureRect,
   unsigned int i = 0;
   for(AtlasContainer::iterator iter = mAtlasList.begin(); iter != mAtlasList.end(); ++iter)
   {
-    if((*iter).Upload(textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver))
+    if(GetImplementation(*iter).Upload(textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver))
     {
       return mTextureSetList[i];
     }
@@ -75,7 +78,7 @@ TextureSet ImageAtlasManager::Add(Vector4&             textureRect,
   }
 
   CreateNewAtlas();
-  mAtlasList.back().Upload(textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver);
+  GetImplementation(mAtlasList.back()).Upload(textureRect, url, size, fittingMode, orientationCorrection, atlasUploadObserver);
   return mTextureSetList.back();
 }
 
index 3c2f52c..b8f5a11 100644 (file)
@@ -25,6 +25,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -67,7 +68,7 @@ public:
    * @return The texture set containing the image.
    */
   TextureSet Add(Vector4&             textureRect,
-                 const std::string&   url,
+                 const VisualUrl&     url,
                  ImageDimensions&     size,
                  FittingMode::Type    fittingMode           = FittingMode::DEFAULT,
                  bool                 orientationCorrection = true,
index bbbab23..16a4a4a 100644 (file)
@@ -595,7 +595,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te
 
 bool ImageVisual::AttemptAtlasing()
 {
-  return (!mImpl->mCustomShader && mImageUrl.GetProtocolType() == VisualUrl::LOCAL && mAttemptAtlasing);
+  return (!mImpl->mCustomShader && (mImageUrl.IsLocalResource() || mImageUrl.IsBufferResource()) && mAttemptAtlasing);
 }
 
 void ImageVisual::InitializeRenderer()
index 45cb99f..cb144b8 100644 (file)
@@ -85,12 +85,12 @@ uint32_t NPatchData::GetObserverCount() const
   return mObserverList.Count();
 }
 
-void NPatchData::SetUrl(const std::string url)
+void NPatchData::SetUrl(const VisualUrl& url)
 {
   mUrl = url;
 }
 
-std::string NPatchData::GetUrl() const
+VisualUrl NPatchData::GetUrl() const
 {
   return mUrl;
 }
index a807d39..7a052c4 100644 (file)
@@ -25,6 +25,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/utility/npatch-utilities.h>
 #include <dali-toolkit/internal/visuals/texture-manager-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -100,14 +101,14 @@ public:
    *
    * @param [in] url NPatch image url
    */
-  void SetUrl(const std::string url);
+  void SetUrl(const VisualUrl& url);
 
   /**
    * @brief Retrieve the image url.
    *
    * @return Return the image url.
    */
-  std::string GetUrl() const;
+  VisualUrl GetUrl() const;
 
   /**
    * @brief Set texture set on the cache data
@@ -274,7 +275,7 @@ private:
 
   NPatchDataId                 mId;
   ObserverListType             mObserverList;      ///< Container used to store all observer clients of this Texture
-  std::string                  mUrl;               ///< Url of the N-Patch
+  VisualUrl                    mUrl;               ///< Url of the N-Patch
   TextureSet                   mTextureSet;        ///< Texture containing the cropped image
   NPatchUtility::StretchRanges mStretchPixelsX;    ///< X stretch pixels
   NPatchUtility::StretchRanges mStretchPixelsY;    ///< Y stretch pixels
index a7734da..5f8ddff 100644 (file)
@@ -52,9 +52,9 @@ NPatchData::NPatchDataId NPatchLoader::GenerateUniqueNPatchDataId()
   return mCurrentNPatchDataId++;
 }
 
-std::size_t NPatchLoader::Load(TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect<int>& border, bool& preMultiplyOnLoad, bool synchronousLoading)
+std::size_t NPatchLoader::Load(TextureManager& textureManager, TextureUploadObserver* textureObserver, const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad, bool synchronousLoading)
 {
-  std::size_t                                 hash  = CalculateHash(url);
+  std::size_t                                 hash  = CalculateHash(url.GetUrl());
   OwnerContainer<NPatchData*>::SizeType       index = UNINITIALIZED_ID;
   const OwnerContainer<NPatchData*>::SizeType count = mCache.Count();
 
@@ -63,7 +63,7 @@ std::size_t NPatchLoader::Load(TextureManager& textureManager, TextureUploadObse
     if(mCache[index]->GetHash() == hash)
     {
       // hash match, check url as well in case of hash collision
-      if(mCache[index]->GetUrl() == url)
+      if(mCache[index]->GetUrl().GetUrl() == url.GetUrl())
       {
         // Use cached data
         if(mCache[index]->GetBorder() == border)
index 50c24d3..dd7f022 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/devel-api/utility/npatch-utilities.h>
 #include <dali-toolkit/internal/visuals/npatch-data.h>
 #include <dali-toolkit/internal/visuals/texture-manager-impl.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
 
 namespace Dali
 {
@@ -68,7 +69,7 @@ public:
    * @param [in] synchronousLoading True if the image will be loaded in synchronous time.
    * @return id of the texture.
    */
-  std::size_t Load(TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect<int>& border, bool& preMultiplyOnLoad, bool synchronousLoading);
+  std::size_t Load(TextureManager& textureManager, TextureUploadObserver* textureObserver, const VisualUrl& url, const Rect<int>& border, bool& preMultiplyOnLoad, bool synchronousLoading);
 
   /**
    * @brief Set loaded PixelBuffer and its information
index bbee1d4..d9c26aa 100644 (file)
@@ -153,10 +153,10 @@ void NPatchVisual::LoadImages()
   TextureManager& textureManager     = mFactoryCache.GetTextureManager();
   bool            synchronousLoading = mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
 
-  if(mId == NPatchData::INVALID_NPATCH_DATA_ID && mImageUrl.IsLocalResource())
+  if(mId == NPatchData::INVALID_NPATCH_DATA_ID && (mImageUrl.IsLocalResource() || mImageUrl.IsBufferResource()))
   {
     bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
-    mId                    = mLoader.Load(textureManager, this, mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad, synchronousLoading);
+    mId                    = mLoader.Load(textureManager, this, mImageUrl, mBorder, preMultiplyOnLoad, synchronousLoading);
 
     const NPatchData* data;
     if(mLoader.GetNPatchData(mId, data) && data->GetLoadingState() == NPatchData::LoadingState::LOAD_COMPLETE)
@@ -165,7 +165,7 @@ void NPatchVisual::LoadImages()
     }
   }
 
-  if(!mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && mAuxiliaryUrl.IsLocalResource())
+  if(!mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
   {
     // Load the auxiliary image
     auto preMultiplyOnLoading = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
index b225d8d..dbb1230 100644 (file)
@@ -30,6 +30,7 @@
 #include <string>
 
 // INTERNAL HEADERS
+#include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
 #include <dali-toolkit/internal/image-loader/image-atlas-impl.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/rendering-addon.h>
@@ -199,7 +200,18 @@ Devel::PixelBuffer TextureManager::LoadPixelBuffer(
   {
     if(url.IsValid())
     {
-      pixelBuffer = LoadImageFromFile(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+      if(url.IsBufferResource())
+      {
+        const EncodedImageBuffer& encodedImageBuffer = GetEncodedImageBuffer(url.GetUrl());
+        if(encodedImageBuffer)
+        {
+          pixelBuffer = LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+        }
+      }
+      else
+      {
+        pixelBuffer = LoadImageFromFile(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+      }
       if(pixelBuffer && preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
       {
         PreMultiply(pixelBuffer, preMultiplyOnLoad);
@@ -244,7 +256,19 @@ TextureSet TextureManager::LoadTexture(
     PixelData data;
     if(url.IsValid())
     {
-      Devel::PixelBuffer pixelBuffer = LoadImageFromFile(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+      Devel::PixelBuffer pixelBuffer;
+      if(url.IsBufferResource())
+      {
+        const EncodedImageBuffer& encodedImageBuffer = GetEncodedImageBuffer(url.GetUrl());
+        if(encodedImageBuffer)
+        {
+          pixelBuffer = LoadImageFromBuffer(encodedImageBuffer.GetRawBuffer(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+        }
+      }
+      else
+      {
+        pixelBuffer = LoadImageFromFile(url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection);
+      }
       if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
       {
         Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true);
@@ -433,12 +457,35 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId);
   }
 
+  // Check if the requested Texture exist in Encoded Buffer
+  // This mean, that buffer is not cached, and need to be decoded.
+  if(textureId == INVALID_TEXTURE_ID && VisualUrl::BUFFER == url.GetProtocolType())
+  {
+    std::string location = url.GetLocation();
+    if(location.size() > 0u)
+    {
+      TextureId                 targetId           = std::stoi(location);
+      const EncodedImageBuffer& encodedImageBuffer = GetEncodedImageBuffer(targetId);
+      if(encodedImageBuffer)
+      {
+        textureId = targetId;
+        // Insert this buffer at mTextureInfoContainer.
+        // This buffer will decode at ImageLoaderThread.
+        bool preMultiply = (preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
+        mTextureInfoContainer.push_back(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex));
+        cacheIndex = mTextureInfoContainer.size() - 1u;
+
+        DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New buffered texture, cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId);
+      }
+    }
+  }
+
   if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
   {
     // We need a new Texture.
     textureId        = GenerateUniqueTextureId();
     bool preMultiply = (preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
-    mTextureInfoContainer.push_back(TextureInfo(textureId, maskTextureId, url.GetUrl(), desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex));
+    mTextureInfoContainer.push_back(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex));
     cacheIndex = mTextureInfoContainer.size() - 1u;
 
     DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId);
@@ -655,6 +702,35 @@ TextureSet TextureManager::GetTextureSet(TextureId textureId)
   return textureSet;
 }
 
+EncodedImageBuffer TextureManager::GetEncodedImageBuffer(TextureId textureId)
+{
+  EncodedImageBuffer encodedImageBuffer; // empty handle
+  for(auto&& elem : mEncodedBufferTextures)
+  {
+    if(elem.textureId == textureId)
+    {
+      encodedImageBuffer = elem.encodedImageBuffer;
+      break;
+    }
+  }
+  return encodedImageBuffer;
+}
+
+EncodedImageBuffer TextureManager::GetEncodedImageBuffer(const std::string& url)
+{
+  EncodedImageBuffer encodedImageBuffer; // empty handle
+  if(url.size() > 0 && VisualUrl::BUFFER == VisualUrl::GetProtocolType(url))
+  {
+    std::string location = VisualUrl::GetLocation(url);
+    if(location.size() > 0u)
+    {
+      TextureId targetId = std::stoi(location);
+      return GetEncodedImageBuffer(targetId);
+    }
+  }
+  return encodedImageBuffer;
+}
+
 std::string TextureManager::AddExternalTexture(TextureSet& textureSet)
 {
   TextureManager::ExternalTextureInfo info;
@@ -665,13 +741,30 @@ std::string TextureManager::AddExternalTexture(TextureSet& textureSet)
   return VisualUrl::CreateTextureUrl(std::to_string(info.textureId));
 }
 
+std::string TextureManager::AddExternalEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer)
+{
+  // Duplication check
+  for(auto&& elem : mEncodedBufferTextures)
+  {
+    if(elem.encodedImageBuffer == encodedImageBuffer)
+    {
+      // If same buffer added, increase reference count and return.
+      elem.referenceCount++;
+      return VisualUrl::CreateBufferUrl(std::to_string(elem.textureId));;
+    }
+  }
+  TextureManager::EncodedBufferTextureInfo info(GenerateUniqueTextureId(), encodedImageBuffer);
+  mEncodedBufferTextures.emplace_back(info);
+  return VisualUrl::CreateBufferUrl(std::to_string(info.textureId));
+}
+
 TextureSet TextureManager::RemoveExternalTexture(const std::string& url)
 {
   if(url.size() > 0u)
   {
-    // get the location from the Url
     if(VisualUrl::TEXTURE == VisualUrl::GetProtocolType(url))
     {
+      // get the location from the Url
       std::string location = VisualUrl::GetLocation(url);
       if(location.size() > 0u)
       {
@@ -695,7 +788,37 @@ TextureSet TextureManager::RemoveExternalTexture(const std::string& url)
   return TextureSet();
 }
 
-void TextureManager::UseExternalTexture(const VisualUrl& url)
+EncodedImageBuffer TextureManager::RemoveExternalEncodedImageBuffer(const std::string& url)
+{
+  if(url.size() > 0u)
+  {
+    if(VisualUrl::BUFFER == VisualUrl::GetProtocolType(url))
+    {
+      // get the location from the Url
+      std::string location = VisualUrl::GetLocation(url);
+      if(location.size() > 0u)
+      {
+        TextureId id = std::stoi(location);
+        const auto end = mEncodedBufferTextures.end();
+        for(auto iter = mEncodedBufferTextures.begin(); iter != end; ++iter)
+        {
+          if(iter->textureId == id)
+          {
+            auto encodedImageBuffer = iter->encodedImageBuffer;
+            if(--(iter->referenceCount) <= 0)
+            {
+              mEncodedBufferTextures.erase(iter);
+            }
+            return encodedImageBuffer;
+          }
+        }
+      }
+    }
+  }
+  return EncodedImageBuffer();
+}
+
+void TextureManager::UseExternalResource(const VisualUrl& url)
 {
   if(VisualUrl::TEXTURE == url.GetProtocolType())
   {
@@ -713,6 +836,22 @@ void TextureManager::UseExternalTexture(const VisualUrl& url)
       }
     }
   }
+  else if(VisualUrl::BUFFER == url.GetProtocolType())
+  {
+    std::string location = url.GetLocation();
+    if(location.size() > 0u)
+    {
+      TextureId id = std::stoi(location);
+      for(auto&& elem : mEncodedBufferTextures)
+      {
+        if(elem.textureId == id)
+        {
+          elem.referenceCount++;
+          return;
+        }
+      }
+    }
+  }
 }
 
 void TextureManager::AddObserver(TextureManager::LifecycleObserver& observer)
@@ -796,7 +935,7 @@ void TextureManager::LoadTexture(TextureInfo& textureInfo, TextureUploadObserver
   textureInfo.loadState = LoadState::LOADING;
   if(!textureInfo.loadSynchronously)
   {
-    auto& loadersContainer  = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
+    auto& loadersContainer  = (textureInfo.url.IsLocalResource() || textureInfo.url.IsBufferResource()) ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
     auto  loadingHelperIt   = loadersContainer.GetNext();
     auto  premultiplyOnLoad = (textureInfo.preMultiplyOnLoad && textureInfo.maskTextureId == INVALID_TEXTURE_ID) ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
     DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
@@ -995,7 +1134,7 @@ void TextureManager::ApplyMask(TextureInfo& textureInfo, TextureId maskTextureId
     DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::ApplyMask(): url:%s sync:%s\n", textureInfo.url.GetUrl().c_str(), textureInfo.loadSynchronously ? "T" : "F");
 
     textureInfo.loadState   = LoadState::MASK_APPLYING;
-    auto& loadersContainer  = textureInfo.url.IsLocalResource() ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
+    auto& loadersContainer  = (textureInfo.url.IsLocalResource() || textureInfo.url.IsBufferResource()) ? mAsyncLocalLoaders : mAsyncRemoteLoaders;
     auto  loadingHelperIt   = loadersContainer.GetNext();
     auto  premultiplyOnLoad = textureInfo.preMultiplyOnLoad ? DevelAsyncImageLoader::PreMultiplyOnLoad::ON : DevelAsyncImageLoader::PreMultiplyOnLoad::OFF;
     DALI_ASSERT_ALWAYS(loadingHelperIt != loadersContainer.End());
@@ -1267,7 +1406,7 @@ void TextureManager::AsyncLoadingHelper::LoadAnimatedImage(TextureId
                                                            uint32_t                   frameIndex)
 {
   mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
-  auto id                             = DevelAsyncImageLoader::LoadAnimatedImage(mLoader, animatedImageLoading, frameIndex);
+  auto id                             = GetImplementation(mLoader).LoadAnimatedImage(animatedImageLoading, frameIndex);
   mLoadingInfoContainer.back().loadId = id;
 }
 
@@ -1280,7 +1419,7 @@ void TextureManager::AsyncLoadingHelper::Load(TextureId
                                               DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
   mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
-  auto id                             = DevelAsyncImageLoader::Load(mLoader, url.GetUrl(), desiredSize, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad);
+  auto id                             = GetImplementation(mLoader).Load(url, desiredSize, fittingMode, samplingMode, orientationCorrection, preMultiplyOnLoad);
   mLoadingInfoContainer.back().loadId = id;
 }
 
@@ -1292,7 +1431,7 @@ void TextureManager::AsyncLoadingHelper::ApplyMask(TextureId
                                                    DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad)
 {
   mLoadingInfoContainer.push_back(AsyncLoadingInfo(textureId));
-  auto id                             = DevelAsyncImageLoader::ApplyMask(mLoader, pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad);
+  auto id                             = GetImplementation(mLoader).ApplyMask(pixelBuffer, maskPixelBuffer, contentScale, cropToMask, preMultiplyOnLoad);
   mLoadingInfoContainer.back().loadId = id;
 }
 
index c9618a9..48eea78 100644 (file)
@@ -20,6 +20,7 @@
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/common/owner-container.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/rendering/geometry.h>
@@ -389,6 +390,20 @@ public:
   TextureSet GetTextureSet(TextureId textureId);
 
   /**
+   * @brief Get the encoded image buffer
+   * @param[in] textureId The textureId to look up
+   * @return the encoded image buffer, or an empty handle if textureId is not valid
+   */
+  EncodedImageBuffer GetEncodedImageBuffer(TextureId textureId);
+
+  /**
+   * @brief Get the encoded image buffer by VisualUrl
+   * @param[in] url The url to look up
+   * @return the encoded image buffer, or an empty handle if url is not buffer resource or buffer is not valid
+   */
+  EncodedImageBuffer GetEncodedImageBuffer(const std::string& url);
+
+  /**
    * Adds an external texture to the texture manager
    * @param[in] texture The texture to add
    * @return string containing the URL for the texture
@@ -396,6 +411,13 @@ public:
   std::string AddExternalTexture(TextureSet& texture);
 
   /**
+   * Adds an external encoded image buffer to the texture manager
+   * @param[in] encodedImageBuffer The image buffer to add
+   * @return string containing the URL for the texture
+   */
+  std::string AddExternalEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer);
+
+  /**
    * Removes an external texture from texture manager
    * @param[in] url The string containing the texture to remove
    * @return handle to the texture
@@ -403,10 +425,17 @@ public:
   TextureSet RemoveExternalTexture(const std::string& url);
 
   /**
-   * @brief Notify that external textures are used.
+   * Removes an external encoded image buffer from texture manager
+   * @param[in] url The string containing the encoded image buffer to remove
+   * @return handle to the encoded image buffer
+   */
+  EncodedImageBuffer RemoveExternalEncodedImageBuffer(const std::string& url);
+
+  /**
+   * @brief Notify that external textures or external encoded image buffers are used.
    * @param[in] url The URL of the texture to use.
    */
-  void UseExternalTexture(const VisualUrl& url);
+  void UseExternalResource(const VisualUrl& url);
 
   /**
    * Add an observer to the object.
@@ -859,6 +888,20 @@ private:
     int16_t    referenceCount{1};
   };
 
+  struct EncodedBufferTextureInfo
+  {
+    EncodedBufferTextureInfo(TextureId                 textureId,
+                             const EncodedImageBuffer& encodedImageBuffer)
+    : textureId(textureId),
+      encodedImageBuffer(encodedImageBuffer),
+      referenceCount(1u)
+    {
+    }
+    TextureId          textureId;
+    EncodedImageBuffer encodedImageBuffer;
+    int16_t            referenceCount;
+  };
+
 private:
   /**
    * Deleted copy constructor.
@@ -877,15 +920,16 @@ private:
    */
   void ObserverDestroyed(TextureUploadObserver* observer);
 
-private:                                                             // Member Variables:
-  TextureInfoContainerType                    mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
-  RoundRobinContainerView<AsyncLoadingHelper> mAsyncLocalLoaders;    ///< The Asynchronous image loaders used to provide all local async loads
-  RoundRobinContainerView<AsyncLoadingHelper> mAsyncRemoteLoaders;   ///< The Asynchronous image loaders used to provide all remote async loads
-  std::vector<ExternalTextureInfo>            mExternalTextures;     ///< Externally provided textures
-  Dali::Vector<LifecycleObserver*>            mLifecycleObservers;   ///< Lifecycle observers of texture manager
-  Dali::Vector<LoadQueueElement>              mLoadQueue;            ///< Queue of textures to load after NotifyObservers
-  TextureId                                   mCurrentTextureId;     ///< The current value used for the unique Texture Id generation
-  bool                                        mQueueLoadFlag;        ///< Flag that causes Load Textures to be queued.
+private:                                                              // Member Variables:
+  TextureInfoContainerType                    mTextureInfoContainer;  ///< Used to manage the life-cycle and caching of Textures
+  RoundRobinContainerView<AsyncLoadingHelper> mAsyncLocalLoaders;     ///< The Asynchronous image loaders used to provide all local async loads
+  RoundRobinContainerView<AsyncLoadingHelper> mAsyncRemoteLoaders;    ///< The Asynchronous image loaders used to provide all remote async loads
+  std::vector<ExternalTextureInfo>            mExternalTextures;      ///< Externally provided textures
+  std::vector<EncodedBufferTextureInfo>       mEncodedBufferTextures; ///< Externally encoded buffer textures
+  Dali::Vector<LifecycleObserver*>            mLifecycleObservers;    ///< Lifecycle observers of texture manager
+  Dali::Vector<LoadQueueElement>              mLoadQueue;             ///< Queue of textures to load after NotifyObservers
+  TextureId                                   mCurrentTextureId;      ///< The current value used for the unique Texture Id generation
+  bool                                        mQueueLoadFlag;         ///< Flag that causes Load Textures to be queued.
 };
 
 } // namespace Internal
index 1979f78..70c6dc2 100644 (file)
@@ -38,15 +38,28 @@ VisualUrl::ProtocolType ResolveLocation(const std::string& url)
   const uint32_t length  = url.size();
   if((length > 7) && urlCStr[5] == ':' && urlCStr[6] == '/' && urlCStr[7] == '/')
   {
-    // https://
-    if(('h' == tolower(urlCStr[0])) &&
-       ('t' == tolower(urlCStr[1])) &&
-       ('t' == tolower(urlCStr[2])) &&
-       ('p' == tolower(urlCStr[3])) &&
-       ('s' == tolower(urlCStr[4])))
+    // https:// or enbuf://
+    const char hOre = tolower(urlCStr[0]);
+    const char tOrn = tolower(urlCStr[1]);
+    const char tOrb = tolower(urlCStr[2]);
+    const char pOru = tolower(urlCStr[3]);
+    const char sOrf = tolower(urlCStr[4]);
+    if(('h' == hOre) &&
+       ('t' == tOrn) &&
+       ('t' == tOrb) &&
+       ('p' == pOru) &&
+       ('s' == sOrf))
     {
       return VisualUrl::REMOTE;
     }
+    if(('e' == hOre) &&
+       ('n' == tOrn) &&
+       ('b' == tOrb) &&
+       ('u' == pOru) &&
+       ('f' == sOrf))
+    {
+      return VisualUrl::BUFFER;
+    }
   }
   else if((length > 6) && urlCStr[4] == ':' && urlCStr[5] == '/' && urlCStr[6] == '/')
   {
@@ -73,18 +86,20 @@ VisualUrl::ProtocolType ResolveLocation(const std::string& url)
   else if((length > 5) && urlCStr[3] == ':' && urlCStr[4] == '/' && urlCStr[5] == '/')
   {
     // ftp:// or ssh://
-    const char fOrS = tolower(urlCStr[0]);
-    if(('f' == fOrS) || ('s' == fOrS))
+    const char fOrs = tolower(urlCStr[0]);
+    const char tOrs = tolower(urlCStr[1]);
+    const char pOrh = tolower(urlCStr[2]);
+    if(('f' == fOrs) &&
+       ('t' == tOrs) &&
+       ('p' == pOrh))
     {
-      const char tOrs = tolower(urlCStr[1]);
-      if(('t' == tOrs) || ('s' == tOrs))
-      {
-        const char pOrh = tolower(urlCStr[2]);
-        if(('p' == pOrh) || ('h' == pOrh))
-        {
-          return VisualUrl::REMOTE;
-        }
-      }
+      return VisualUrl::REMOTE;
+    }
+    if(('s' == fOrs) &&
+       ('s' == tOrs) &&
+       ('h' == pOrh))
+    {
+      return VisualUrl::REMOTE;
     }
   }
   return VisualUrl::LOCAL;
@@ -208,9 +223,9 @@ VisualUrl::VisualUrl(const std::string& url)
   if(!url.empty())
   {
     mLocation = ResolveLocation(url);
-    if(VisualUrl::TEXTURE != mLocation)
+    if(VisualUrl::TEXTURE != mLocation && VisualUrl::BUFFER != mLocation)
     {
-      // TEXTURE location url doesn't need type resolving, REGULAR_IMAGE is fine
+      // TEXTURE and BUFFER location url doesn't need type resolving, REGULAR_IMAGE is fine
       mType = ResolveType(url);
     }
     else
@@ -218,7 +233,7 @@ VisualUrl::VisualUrl(const std::string& url)
       Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
       if(factory)
       {
-        GetImplementation(factory).GetTextureManager().UseExternalTexture(*this);
+        GetImplementation(factory).GetTextureManager().UseExternalResource(*this);
       }
     }
   }
@@ -229,12 +244,12 @@ VisualUrl::VisualUrl(const VisualUrl& url)
   mType(url.mType),
   mLocation(url.mLocation)
 {
-  if(VisualUrl::TEXTURE == mLocation)
+  if(VisualUrl::TEXTURE == mLocation || VisualUrl::BUFFER == mLocation)
   {
     Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
     if(factory)
     {
-      GetImplementation(factory).GetTextureManager().UseExternalTexture(*this);
+      GetImplementation(factory).GetTextureManager().UseExternalResource(*this);
     }
   }
 }
@@ -249,6 +264,14 @@ VisualUrl::~VisualUrl()
       GetImplementation(factory).GetTextureManager().RemoveExternalTexture(mUrl);
     }
   }
+  else if(VisualUrl::BUFFER == mLocation)
+  {
+    Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+    if(factory)
+    {
+      GetImplementation(factory).GetTextureManager().RemoveExternalEncodedImageBuffer(mUrl);
+    }
+  }
 }
 
 VisualUrl& VisualUrl::operator=(const VisualUrl& url)
@@ -263,17 +286,25 @@ VisualUrl& VisualUrl::operator=(const VisualUrl& url)
         GetImplementation(factory).GetTextureManager().RemoveExternalTexture(mUrl);
       }
     }
+    else if(VisualUrl::BUFFER == mLocation)
+    {
+      Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
+      if(factory)
+      {
+        GetImplementation(factory).GetTextureManager().RemoveExternalEncodedImageBuffer(mUrl);
+      }
+    }
 
     mUrl      = url.mUrl;
     mType     = url.mType;
     mLocation = url.mLocation;
 
-    if(VisualUrl::TEXTURE == mLocation)
+    if(VisualUrl::TEXTURE == mLocation || VisualUrl::BUFFER == mLocation)
     {
       Toolkit::VisualFactory factory = Toolkit::VisualFactory::Get();
       if(factory)
       {
-        GetImplementation(factory).GetTextureManager().UseExternalTexture(*this);
+        GetImplementation(factory).GetTextureManager().UseExternalResource(*this);
       }
     }
   }
@@ -305,6 +336,11 @@ bool VisualUrl::IsLocalResource() const
   return mLocation == VisualUrl::LOCAL;
 }
 
+bool VisualUrl::IsBufferResource() const
+{
+  return mLocation == VisualUrl::BUFFER;
+}
+
 std::string VisualUrl::GetLocation() const
 {
   return GetLocation(mUrl);
@@ -315,6 +351,11 @@ std::string VisualUrl::CreateTextureUrl(const std::string& location)
   return "dali://" + location;
 }
 
+std::string VisualUrl::CreateBufferUrl(const std::string& location)
+{
+  return "enbuf://" + location;
+}
+
 VisualUrl::ProtocolType VisualUrl::GetProtocolType(const std::string& url)
 {
   return ResolveLocation(url);
@@ -330,7 +371,6 @@ std::string VisualUrl::GetLocation(const std::string& url)
   return url;
 }
 
-
 } // namespace Internal
 
 } // namespace Toolkit
index a772bd1..555e383 100644 (file)
@@ -45,7 +45,8 @@ public:
   {
     LOCAL,   ///< file in local file system
     TEXTURE, ///< texture uploaded to texture manager
-    REMOTE   ///< remote image
+    REMOTE,  ///< remote image
+    BUFFER   ///< encoded image buffer
   };
 
   /**
@@ -111,6 +112,11 @@ public:
   bool IsLocalResource() const;
 
   /**
+   * @return true if the location is BUFFER, i.e. may contain EncodedImageBuffer
+   */
+  bool IsBufferResource() const;
+
+  /**
    * @return the location part of the url
    */
   std::string GetLocation() const;
@@ -123,6 +129,13 @@ public:
   static std::string CreateTextureUrl(const std::string& location);
 
   /**
+   * Helper to create a URL of type BUFFER
+   * @param location the location of the texture
+   * @return the Url
+   */
+  static std::string CreateBufferUrl(const std::string& location);
+
+  /**
    * Helper to get a ProtocolType from url
    * @param url the url of the texture
    * @return the protocol type
@@ -135,6 +148,7 @@ public:
    * @return the location
    */
   static std::string GetLocation(const std::string& url);
+
 private:
   std::string  mUrl;
   Type         mType;
index eefc529..b805a2c 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 0;
-const unsigned int TOOLKIT_MICRO_VERSION = 36;
+const unsigned int TOOLKIT_MICRO_VERSION = 37;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 65b9601..f936fdc 100644 (file)
@@ -38,6 +38,12 @@ ImageUrl ImageUrl::New(Texture& texture)
   return ImageUrl(internal.Get());
 }
 
+ImageUrl ImageUrl::New(const EncodedImageBuffer& encodedImageBuffer)
+{
+  Toolkit::Internal::ImageUrlPtr internal = Toolkit::Internal::ImageUrl::New(encodedImageBuffer);
+  return ImageUrl(internal.Get());
+}
+
 ImageUrl ImageUrl::DownCast(BaseHandle handle)
 {
   return ImageUrl(dynamic_cast<Toolkit::Internal::ImageUrl*>(handle.GetObjectPtr()));
index 819198b..976f179 100644 (file)
@@ -20,6 +20,7 @@
 // EXTERNAL INCLUDES
 #include <string>
 #include <dali/public-api/rendering/texture.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/dali-toolkit-common.h>
@@ -39,6 +40,7 @@ class ImageUrl;
  * Application can get url from ImageUrl.
  * When application does not use this anymore, the destructor of the ImageUrl is called.
  * At this time, the buffer is deleted from the texture manager.
+ * @note Visual also have reference of the buffer. In this case, buffer will be deleted after visual is deleted.
  */
 class DALI_TOOLKIT_API ImageUrl : public BaseHandle
 {
@@ -63,6 +65,14 @@ public:
   static ImageUrl New(Texture& texture);
 
   /**
+   * @brief Create an initialized ImageUrl.
+   *
+   * @param[in] encodedImageBuffer The encoded image buffer url is got from external buffer.
+   * @return A handle to a newly allocated Dali resource.
+   */
+  static ImageUrl New(const EncodedImageBuffer& encodedImageBuffer);
+
+  /**
    * @brief Downcast an Object handle to ImageUrl handle.
    *
    * If handle points to a ImageUrl object the downcast produces valid
index b44061e..7b91059 100644 (file)
@@ -60,6 +60,11 @@ Dali::Toolkit::ImageUrl GenerateUrl(const Dali::NativeImageSourcePtr nativeImage
   return imageUrl;
 }
 
+Dali::Toolkit::ImageUrl GenerateUrl(const Dali::EncodedImageBuffer encodedImageBuffer)
+{
+  return Dali::Toolkit::ImageUrl::New(encodedImageBuffer);
+}
+
 } // namespace Image
 
 } // namespace Toolkit
index ad2f56e..6db6e7e 100644 (file)
@@ -19,6 +19,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/adaptor-framework/native-image-source.h>
+#include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
 #include <dali/public-api/images/pixel-data.h>
 #include <dali/public-api/rendering/frame-buffer.h>
 
@@ -78,6 +79,15 @@ DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::PixelData pixel
  */
 DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::NativeImageSourcePtr nativeImageSource);
 
+/**
+ * @brief Generate a Url from encoded image buffer.
+ * This Url can be used in visuals to render the image.
+ * @note This method does not check for duplicates, If same encoded image buffer is entered multiple times, a different URL is returned each time.
+ * @param[in] encodedImageBuffer the encoded image buffer to converted to Url
+ * @return the ImageUrl representing this encoded image buffer
+ */
+DALI_TOOLKIT_API Dali::Toolkit::ImageUrl GenerateUrl(const Dali::EncodedImageBuffer encodedImageBuffer);
+
 } // namespace Image
 
 } // namespace Toolkit
index d3df7ab..632815e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.0.36
+Version:    2.0.37
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT