[dali_2.1.43] Merge branch 'devel/master' 63/282663/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 7 Oct 2022 11:24:14 +0000 (12:24 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 7 Oct 2022 11:24:14 +0000 (12:24 +0100)
Change-Id: I6f7f3f467446be624d32d67360f0d71e63e5678c

23 files changed:
automated-tests/src/dali-scene3d/utc-Dali-Model.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-TextureManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-scene3d/internal/controls/model/model-impl.cpp
dali-scene3d/internal/controls/model/model-impl.h
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.h
dali-scene3d/public-api/controls/model/model.cpp
dali-scene3d/public-api/controls/model/model.h
dali-scene3d/public-api/controls/scene-view/scene-view.h
dali-scene3d/public-api/loader/dli-loader.cpp
dali-toolkit/internal/texture-manager/texture-cache-manager.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-type.h
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index d6a73d8..c18924b 100644 (file)
@@ -20,6 +20,9 @@
 #include <stdlib.h>
 #include <iostream>
 
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+
 #include <dali-scene3d/public-api/controls/model/model.h>
 
 using namespace Dali;
@@ -37,6 +40,7 @@ void model_cleanup(void)
 
 namespace
 {
+const bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
 /**
  * For the AnimatedCube.gltf and its Assets
  * Donated by Norbert Nopper for glTF testing.
@@ -72,6 +76,14 @@ const char* TEST_DLI_FILE_NAME                 = TEST_RESOURCE_DIR "/arc.dli";
  */
 const char* TEST_DIFFUSE_TEXTURE  = TEST_RESOURCE_DIR "/forest_irradiance.ktx";
 const char* TEST_SPECULAR_TEXTURE = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+
+bool gTouchCallBackCalled = false;
+bool TestTouchCallback(Actor, const TouchEvent&)
+{
+  gTouchCallBackCalled = true;
+  return true;
+}
+
 } // namespace
 
 // Negative test case for a method
@@ -116,7 +128,7 @@ int UtcDaliModelDownCast(void)
   tet_infoline(" UtcDaliModelDownCast");
 
   Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
-  BaseHandle         handle(model);
+  BaseHandle     handle(model);
 
   Scene3D::Model model2 = Scene3D::Model::DownCast(handle);
   DALI_TEST_CHECK(model);
@@ -416,6 +428,165 @@ int UtcDaliModelImageBasedFactor(void)
   END_TEST;
 }
 
+int UtcDaliModelChildrenSensitive01(void)
+{
+  ToolkitTestApplication application;
+
+  Scene3D::Model view = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+  view.SetProperty(Dali::Actor::Property::SIZE, Vector3(100, 100, 100));
+  view.SetProperty(Dali::Actor::Property::POSITION, Vector3(0, 0, 0));
+  view.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  view.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+  // Get default vaule.
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), DEFAULT_MODEL_CHILDREN_SENSITIVE, TEST_LOCATION);
+
+  // Allow children actor's event before on scene.
+  view.SetChildrenSensitive(true);
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+  application.GetScene().Add(view);
+
+  application.SendNotification();
+  application.Render();
+
+  Actor meshActor = view.FindChildByName("AnimatedCube");
+  DALI_TEST_CHECK(meshActor);
+
+  // connect hit-test signal
+  gTouchCallBackCalled = false;
+  meshActor.TouchedSignal().Connect(TestTouchCallback);
+
+  Vector2 sceneSize = application.GetScene().GetSize();
+
+  // Try to touch center of scene.
+  Dali::Integration::Point point;
+  point.SetState(PointState::DOWN);
+  point.SetScreenPosition(sceneSize * 0.5f);
+  Dali::Integration::TouchEvent event;
+  event.AddPoint(point);
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  // Not touched yet.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+  application.ProcessEvent(event);
+  // Touched.
+  DALI_TEST_CHECK(gTouchCallBackCalled);
+
+  // Clear
+  gTouchCallBackCalled = false;
+
+  // Block children actor's event
+  view.SetChildrenSensitive(false);
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), false, TEST_LOCATION);
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  // Not touched yet.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+  application.ProcessEvent(event);
+  // Also not touched.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+
+  // Clear
+  gTouchCallBackCalled = false;
+
+  // Allow again
+  view.SetChildrenSensitive(true);
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  // Not touched yet.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+  application.ProcessEvent(event);
+  // Touched.
+  DALI_TEST_CHECK(gTouchCallBackCalled);
+
+  // Clear
+  gTouchCallBackCalled = false;
+
+  END_TEST;
+}
+
+int UtcDaliModelChildrenSensitive02(void)
+{
+  ToolkitTestApplication application;
+
+  Scene3D::Model view = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+  view.SetProperty(Dali::Actor::Property::SIZE, Vector3(100, 100, 100));
+  view.SetProperty(Dali::Actor::Property::POSITION, Vector3(0, 0, 0));
+  view.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  view.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+  // Get vaule.
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), DEFAULT_MODEL_CHILDREN_SENSITIVE, TEST_LOCATION);
+
+  // Block children actor's event before on scene.
+  view.SetChildrenSensitive(false);
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), false, TEST_LOCATION);
+
+  application.GetScene().Add(view);
+
+  application.SendNotification();
+  application.Render();
+
+  Actor meshActor = view.FindChildByName("AnimatedCube");
+  DALI_TEST_CHECK(meshActor);
+
+  // connect hit-test signal
+  gTouchCallBackCalled = false;
+  meshActor.TouchedSignal().Connect(TestTouchCallback);
+
+  Vector2 sceneSize = application.GetScene().GetSize();
+
+  // Try to touch center of scene.
+  Dali::Integration::Point point;
+  point.SetState(PointState::DOWN);
+  point.SetScreenPosition(sceneSize * 0.5f);
+  Dali::Integration::TouchEvent event;
+  event.AddPoint(point);
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  // Not touched yet.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+  application.ProcessEvent(event);
+  // Also not touched.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+
+  // Clear
+  gTouchCallBackCalled = false;
+
+  // Allow again
+  view.SetChildrenSensitive(true);
+  DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+  // flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  // Not touched yet.
+  DALI_TEST_CHECK(!gTouchCallBackCalled);
+  application.ProcessEvent(event);
+  // Touched.
+  DALI_TEST_CHECK(gTouchCallBackCalled);
+
+  // Clear
+  gTouchCallBackCalled = false;
+
+  END_TEST;
+}
+
 int UtcDaliModelAnimation01(void)
 {
   ToolkitTestApplication application;
@@ -473,25 +644,25 @@ int UtcDaliModelAnimation02(void)
 namespace
 {
 static bool gOnRelayoutCallBackCalled = false;
-void OnRelayoutCallback(Actor actor)
+void        OnRelayoutCallback(Actor actor)
 {
   gOnRelayoutCallBackCalled = true;
 }
 
 static bool gResourceReadyCalled = false;
-void OnResourceReady(Control control)
+void        OnResourceReady(Control control)
 {
   gResourceReadyCalled = true;
 }
-}
+} // namespace
 
 int UtcDaliModelResourceReady(void)
 {
   ToolkitTestApplication application;
 
   gOnRelayoutCallBackCalled = false;
-  gResourceReadyCalled = false;
-  Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_ANIMATION_TEST_FILE_NAME);
+  gResourceReadyCalled      = false;
+  Scene3D::Model model      = Scene3D::Model::New(TEST_GLTF_ANIMATION_TEST_FILE_NAME);
   model.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
   model.OnRelayoutSignal().Connect(OnRelayoutCallback);
   model.ResourceReadySignal().Connect(OnResourceReady);
index c80d1b5..f12b096 100644 (file)
@@ -56,6 +56,8 @@ namespace
 {
 const char* TEST_IMAGE_FILE_NAME   = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
 const char* TEST_IMAGE_2_FILE_NAME = TEST_RESOURCE_DIR "/icon-delete.png";
+const char* TEST_IMAGE_3_FILE_NAME = TEST_RESOURCE_DIR "/icon-edit.png";
+const char* TEST_IMAGE_4_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-20.png";
 const char* TEST_MASK_FILE_NAME    = TEST_RESOURCE_DIR "/mask.png";
 
 class TestObserver : public Dali::Toolkit::TextureUploadObserver
@@ -135,6 +137,55 @@ protected:
   TextureManager* mTextureManagerPtr; // Keep the pointer of texture manager.
 };
 
+class TestObserverWithCustomFunction : public TestObserver
+{
+public:
+  TestObserverWithCustomFunction()
+  : TestObserver(),
+    mSignals{},
+    mData{nullptr},
+    mKeepSignal{false}
+  {
+  }
+
+  virtual void LoadComplete(bool loadSuccess, TextureInformation textureInformation) override
+  {
+    if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE)
+    {
+      mCompleteType = CompleteType::UPLOAD_COMPLETE;
+    }
+    else
+    {
+      mCompleteType = CompleteType::LOAD_COMPLETE;
+    }
+    mLoaded         = loadSuccess;
+    mObserverCalled = true;
+    mTextureSet     = textureInformation.textureSet;
+
+    // Execute signals.
+    for(size_t i = 0; i < mSignals.size(); i++)
+    {
+      mSignals[i](mData);
+    }
+
+    // Clear signals.
+    if(!mKeepSignal)
+    {
+      mSignals.clear();
+    }
+  }
+
+  void ConnectFunction(std::function<void(void*)> signal)
+  {
+    mSignals.push_back(signal);
+  }
+
+public:
+  std::vector<std::function<void(void*)>> mSignals;
+  void*                                   mData;
+  bool                                    mKeepSignal;
+};
+
 } // namespace
 
 int UtcTextureManagerRequestLoad(void)
@@ -1376,3 +1427,252 @@ int UtcTextureManagerMaskCacheTest(void)
 
   END_TEST;
 }
+
+int UtcTextureManagerRemoveDuringGPUMasking(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcTextureManagerRemoveDuringGPUMasking");
+  tet_infoline("Request 3 different GPU masking image.");
+  tet_infoline("Control to mask image load last. and then, check execute result.");
+
+  TextureManager textureManager; // Create new texture manager
+
+  TestObserverWithCustomFunction observer1;
+  TestObserverWithCustomFunction observer2;
+  TestObserver                   observer3;
+  TestObserver                   observer4;
+
+  std::string filename1(TEST_IMAGE_FILE_NAME);
+  std::string filename2(TEST_IMAGE_2_FILE_NAME);
+  std::string filename3(TEST_IMAGE_3_FILE_NAME);
+  std::string filename4(TEST_IMAGE_4_FILE_NAME);
+
+  auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+  auto textureId2(TextureManager::INVALID_TEXTURE_ID);
+  auto textureId3(TextureManager::INVALID_TEXTURE_ID);
+  auto textureId4(TextureManager::INVALID_TEXTURE_ID);
+
+  std::string                        maskname(TEST_MASK_FILE_NAME);
+  TextureManager::MaskingDataPointer maskInfo[3] = {nullptr, nullptr, nullptr};
+  for(int i = 0; i < 3; i++)
+  {
+    maskInfo[i].reset(new TextureManager::MaskingData());
+    maskInfo[i]->mAlphaMaskUrl       = maskname;
+    maskInfo[i]->mAlphaMaskId        = TextureManager::INVALID_TEXTURE_ID;
+    maskInfo[i]->mCropToMask         = true;
+    maskInfo[i]->mPreappliedMasking  = false; // To make GPU masking
+    maskInfo[i]->mContentScaleFactor = 1.0f;
+  }
+  Vector4                       atlasRect(0.f, 0.f, 1.f, 1.f);
+  Dali::ImageDimensions         atlasRectSize(0, 0);
+  bool                          synchronousLoading(false);
+  bool                          atlasingStatus(false);
+  bool                          loadingStatus(false);
+  auto                          preMultiply         = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+  ImageAtlasManagerPtr          atlasManager        = nullptr;
+  Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
+
+  // Request image 1, 2, 3 with GPU masking
+  textureManager.LoadTexture(
+    filename1,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    maskInfo[0],
+    synchronousLoading,
+    textureId1,
+    atlasRect,
+    atlasRectSize,
+    atlasingStatus,
+    loadingStatus,
+    &observer1,
+    atlasUploadObserver,
+    atlasManager,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  textureManager.LoadTexture(
+    filename2,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    maskInfo[1],
+    synchronousLoading,
+    textureId2,
+    atlasRect,
+    atlasRectSize,
+    atlasingStatus,
+    loadingStatus,
+    &observer2,
+    atlasUploadObserver,
+    atlasManager,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  textureManager.LoadTexture(
+    filename3,
+    ImageDimensions(),
+    FittingMode::SCALE_TO_FILL,
+    SamplingMode::BOX_THEN_LINEAR,
+    maskInfo[2],
+    synchronousLoading,
+    textureId3,
+    atlasRect,
+    atlasRectSize,
+    atlasingStatus,
+    loadingStatus,
+    &observer3,
+    atlasUploadObserver,
+    atlasManager,
+    true,
+    TextureManager::ReloadPolicy::CACHED,
+    preMultiply);
+
+  DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
+  DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
+
+  // Check we use cached mask image
+  DALI_TEST_CHECK(maskInfo[0]->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID);
+  DALI_TEST_EQUALS(maskInfo[0]->mAlphaMaskId, maskInfo[1]->mAlphaMaskId, TEST_LOCATION);
+  DALI_TEST_EQUALS(maskInfo[0]->mAlphaMaskId, maskInfo[2]->mAlphaMaskId, TEST_LOCATION);
+
+  // Connect observer1 custom function
+  struct CustomData1
+  {
+    TextureManager*           textureManagerPtr{nullptr};
+    TextureManager::TextureId removeTextureId{TextureManager::INVALID_TEXTURE_ID};
+    TestObserver*             removeTextureObserver{nullptr};
+  };
+  CustomData1 data1;
+  data1.textureManagerPtr     = &textureManager;
+  data1.removeTextureId       = textureId3;
+  data1.removeTextureObserver = &observer3;
+
+  observer1.mData = &data1;
+  observer1.ConnectFunction(
+    [](void* data) {
+      DALI_TEST_CHECK(data);
+      CustomData1 data1 = *(CustomData1*)data;
+
+      DALI_TEST_CHECK(data1.textureManagerPtr);
+      DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID);
+      DALI_TEST_CHECK(data1.removeTextureObserver);
+
+      // Remove textureId3
+      data1.textureManagerPtr->Remove(data1.removeTextureId, data1.removeTextureObserver);
+    });
+
+  // Connect observer2 custom function
+  struct CustomData2
+  {
+    TextureManager*            textureManagerPtr{nullptr};
+    std::string                addTextureUrl{};
+    TextureManager::TextureId* addTextureIdPtr{nullptr};
+    TestObserver*              addTextureObserver{nullptr};
+  };
+  CustomData2 data2;
+  data2.textureManagerPtr  = &textureManager;
+  data2.addTextureUrl      = filename4;
+  data2.addTextureIdPtr    = &textureId4;
+  data2.addTextureObserver = &observer4;
+
+  observer2.mData = &data2;
+  observer2.ConnectFunction(
+    [](void* data) {
+      DALI_TEST_CHECK(data);
+      CustomData2 data2 = *(CustomData2*)data;
+
+      DALI_TEST_CHECK(data2.textureManagerPtr);
+      DALI_TEST_CHECK(!data2.addTextureUrl.empty());
+      DALI_TEST_CHECK(data2.addTextureIdPtr);
+      DALI_TEST_CHECK(data2.addTextureObserver);
+
+      auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+      // Load textureId4
+      (*data2.addTextureIdPtr) = data2.textureManagerPtr->RequestLoad(
+        data2.addTextureUrl,
+        ImageDimensions(),
+        FittingMode::SCALE_TO_FILL,
+        SamplingMode::BOX_THEN_LINEAR,
+        TextureManager::UseAtlas::NO_ATLAS,
+        data2.addTextureObserver,
+        true,
+        TextureManager::ReloadPolicy::CACHED,
+        preMultiply);
+    });
+
+  application.SendNotification();
+  application.Render();
+
+  tet_printf("Id info - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(maskInfo[0]->mAlphaMaskId), static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
+
+  // CAPTION : HARD-CODING.
+  {
+    // Complete async load 1, 2, 3.
+    std::vector<Devel::PixelBuffer> pixelBuffers;
+
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId1, pixelBuffers);
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId3, pixelBuffers);
+
+    DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
+
+    // Complete mask load.
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::L8));
+    textureManager.AsyncLoadComplete(maskInfo[0]->mAlphaMaskId, pixelBuffers);
+
+    tet_printf("Id info after observer notify - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(maskInfo[0]->mAlphaMaskId), static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
+
+    // Check observer 1 and 2 called, but 3 and 4 not called.
+    DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
+
+    // Check textureId4
+    DALI_TEST_CHECK(textureId4 != TextureManager::INVALID_TEXTURE_ID);
+
+    // Complete 4.
+    pixelBuffers.clear();
+    pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+    textureManager.AsyncLoadComplete(textureId4, pixelBuffers);
+
+    DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer4.mLoaded, true, TEST_LOCATION);
+    DALI_TEST_EQUALS(observer4.mObserverCalled, true, TEST_LOCATION);
+  }
+
+  END_TEST;
+}
\ No newline at end of file
index 09a4dd4..cdd58b4 100644 (file)
@@ -190,6 +190,7 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
   tet_infoline("UtcDaliVisualFactoryGetAnimatedVectorImageVisual04: Request animated vector image visual with a Property::Map");
 
   int             startFrame = 1, endFrame = 3;
+  int             desiredWidth = 100, desiredHeight = 150;
   float           cornerRadius     = 22.0f;
   float           borderlineWidth  = 2.0f;
   Vector4         borderlineColor  = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
@@ -210,7 +211,8 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
     .Add("borderlineWidth", borderlineWidth)
     .Add("borderlineColor", borderlineColor)
     .Add("borderlineOffset", borderlineOffset)
-    .Add("synchronousLoading", true);
+    .Add("desiredWidth", desiredWidth)
+    .Add("desiredHeight", desiredHeight);
 
   Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
   DALI_TEST_CHECK(visual);
@@ -286,6 +288,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), borderlineOffset, TEST_LOCATION);
 
+  value = resultMap.Find(ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<int>(), desiredWidth, TEST_LOCATION);
+
+  value = resultMap.Find(ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<int>(), desiredHeight, TEST_LOCATION);
+
   actor.Unparent();
   DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
 
@@ -298,6 +308,7 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   tet_infoline("UtcDaliAnimatedVectorImageVisualGetPropertyMap01");
 
   int             startFrame = 1, endFrame = 3;
+  int             desiredWidth = 100, desiredHeight = 150;
   Vector4         cornerRadius(50.0f, 22.0f, 0.0f, 3.0f);
   float           borderlineWidth  = 2.3f;
   Vector4         borderlineColor  = Vector4(0.3f, 0.3f, 1.0f, 1.0f);
@@ -316,7 +327,9 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
     .Add(DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth)
     .Add(DevelVisual::Property::BORDERLINE_COLOR, borderlineColor)
     .Add(DevelVisual::Property::BORDERLINE_OFFSET, borderlineOffset)
-    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false)
+    .Add(ImageVisual::Property::DESIRED_WIDTH, desiredWidth)
+    .Add(ImageVisual::Property::DESIRED_HEIGHT, desiredHeight);
 
   // request AnimatedVectorImageVisual with a property map
   VisualFactory factory = VisualFactory::Get();
@@ -397,6 +410,14 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<float>(), borderlineOffset, TEST_LOCATION);
 
+  value = resultMap.Find(ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<int>(), desiredWidth, TEST_LOCATION);
+
+  value = resultMap.Find(ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_EQUALS(value->Get<int>(), desiredHeight, TEST_LOCATION);
+
   // request AnimatedVectorImageVisual with an URL
   Visual::Base visual2 = factory.CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions());
 
@@ -1978,3 +1999,68 @@ int UtcDaliAnimatedVectorImageVisualDynamicProperty(void)
 
   END_TEST;
 }
+
+int UtcDaliAnimatedVectorImageVisualDesiredSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualDesiredSize");
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  int                desiredWidth = 150, desiredHeight = 200;
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight));
+  DALI_TEST_CHECK(visual);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - resource ready
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  textureTrace.Enable(true);
+
+  application.SendNotification();
+  application.Render();
+
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  // Unparent to make next trigger
+  actor.Unparent();
+
+  application.SendNotification();
+  application.Render();
+
+  // Set visual size
+  actor.SetProperty(Actor::Property::SIZE, Vector2(300.0f, 300.0f));
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - resource ready
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  textureTrace.Reset();
+
+  application.SendNotification();
+  application.Render();
+
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); // The size should not be changed
+  }
+
+  END_TEST;
+}
index 34aa8a3..dd400db 100644 (file)
@@ -1274,6 +1274,74 @@ int UtcDaliImageViewReplaceImage(void)
   END_TEST;
 }
 
+int UtcDaliImageViewReloadAlphaMaskImage(void)
+{
+  ToolkitTestApplication application;
+
+  gResourceReadySignalFired = false;
+
+  ImageView     dummy     = ImageView::New();
+  ImageView     imageView = ImageView::New();
+  Property::Map propertyMap;
+
+  // To keep alpha mask cached, scene on some dummy image.
+  // Note : If we don't cache alpha mask image, the reference count of mask image become zero.
+  // In this case, we might need to wait mask image loading, which is not neccesary & can be changed behavior.
+  propertyMap[ImageVisual::Property::URL]            = gImage_600_RGB;
+  propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+  dummy.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+  application.GetScene().Add(dummy);
+
+  application.SendNotification();
+  application.Render(16);
+
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(16);
+
+  propertyMap.Clear();
+  propertyMap[ImageVisual::Property::URL]            = gImage_34_RGBA;
+  propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+  imageView.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+  DALI_TEST_EQUALS(imageView.IsResourceReady(), false, TEST_LOCATION);
+
+  imageView.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+  application.GetScene().Add(imageView);
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Load image and use cached mask. Now we try to apply masking.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION);
+
+  // Cancel apply masking.
+  imageView.Unparent();
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Reload same image again.
+  application.GetScene().Add(imageView);
+
+  application.SendNotification();
+  application.Render(16);
+
+  // Finish apply masking.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION);
+
+  END_TEST;
+}
+
 void OnRelayoutOverride(Size size)
 {
   gNaturalSize = size; // Size Relayout is using
@@ -3177,6 +3245,66 @@ int UtcDaliImageViewTVGLoading(void)
   END_TEST;
 }
 
+int UtcDaliImageViewSvgDesiredSize01(void)
+{
+  ToolkitTestApplication application;
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  int       desiredWidth = 100, desiredHeight = 150;
+  ImageView imageView = ImageView::New(TEST_SVG_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight));
+
+  application.GetScene().Add(imageView);
+
+  application.SendNotification();
+
+  // Wait for loading & rasterization
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(16);
+
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  END_TEST;
+}
+
+int UtcDaliImageViewSvgDesiredSize02(void)
+{
+  ToolkitTestApplication application;
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  int       desiredWidth = 150, desiredHeight = 100;
+  ImageView imageView                   = ImageView::New();
+  imageView[ImageView::Property::IMAGE] = Property::Map().Add("url", TEST_SVG_FILE_NAME).Add("desiredWidth", desiredWidth).Add("desiredHeight", desiredHeight);
+  application.GetScene().Add(imageView);
+
+  application.SendNotification();
+
+  // Wait for loading & rasterization
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(16);
+
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+    DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  END_TEST;
+}
+
 int UtcDaliImageViewImageLoadFailure01(void)
 {
   ToolkitTestApplication application;
index ed5d3bd..24e7af5 100644 (file)
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali/devel-api/actors/actor-devel.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
 #include <filesystem>
 
 // INTERNAL INCLUDES
-#include <dali-scene3d/public-api/controls/model/model.h>
 #include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
+#include <dali-scene3d/public-api/controls/model/model.h>
 #include <dali-scene3d/public-api/loader/animation-definition.h>
 #include <dali-scene3d/public-api/loader/camera-parameters.h>
 #include <dali-scene3d/public-api/loader/cube-map-loader.h>
@@ -65,6 +66,8 @@ static constexpr uint32_t OFFSET_FOR_SPECULAR_CUBE_TEXTURE = 1u;
 
 static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f);
 
+static constexpr bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
+
 static constexpr std::string_view KTX_EXTENSION  = ".ktx";
 static constexpr std::string_view OBJ_EXTENSION  = ".obj";
 static constexpr std::string_view GLTF_EXTENSION = ".gltf";
@@ -179,6 +182,7 @@ Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUr
   mNaturalSize(Vector3::ZERO),
   mModelPivot(AnchorPoint::CENTER),
   mIblScaleFactor(1.0f),
+  mModelChildrenSensitive(DEFAULT_MODEL_CHILDREN_SENSITIVE),
   mModelResourceReady(false),
   mIBLResourceReady(true)
 {
@@ -206,9 +210,26 @@ const Actor Model::GetModelRoot() const
   return mModelRoot;
 }
 
+void Model::SetChildrenSensitive(bool enable)
+{
+  if(mModelChildrenSensitive != enable)
+  {
+    mModelChildrenSensitive = enable;
+    if(mModelRoot)
+    {
+      mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
+    }
+  }
+}
+
+bool Model::GetChildrenSensitive() const
+{
+  return mModelChildrenSensitive;
+}
+
 void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
 {
-  mIBLResourceReady = false;
+  mIBLResourceReady       = false;
   Texture diffuseTexture  = Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl);
   Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specularUrl);
   SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
@@ -237,7 +258,6 @@ void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Textur
       mIblScaleFactor = scaleFactor;
       UpdateImageBasedLightScaleFactor();
     }
-
   }
 }
 
@@ -483,6 +503,8 @@ void Model::LoadModel()
   FitModelPosition();
   ScaleModel();
 
+  mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
+
   Self().Add(mModelRoot);
 
   Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
index 7e97977..3db9c57 100644 (file)
@@ -22,8 +22,8 @@
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali/public-api/actors/layer.h>
 #include <dali/public-api/animation/animation.h>
-#include <dali/public-api/rendering/texture.h>
 #include <dali/public-api/object/weak-handle.h>
+#include <dali/public-api/rendering/texture.h>
 
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/controls/model/model.h>
@@ -58,6 +58,16 @@ public:
   const Actor GetModelRoot() const;
 
   /**
+   * @copydoc Model::SetChildrenSensitive()
+   */
+  void SetChildrenSensitive(bool enable);
+
+  /**
+   * @copydoc Model::GetChildrenSensitive()
+   */
+  bool GetChildrenSensitive() const;
+
+  /**
    * @copydoc Model::SetImageBasedLightSource()
    */
   void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor);
@@ -182,6 +192,7 @@ private:
   Vector3       mNaturalSize;
   Vector3       mModelPivot;
   float         mIblScaleFactor;
+  bool          mModelChildrenSensitive;
   bool          mModelResourceReady;
   bool          mIBLResourceReady;
 };
index 08afa17..2f3fbf3 100644 (file)
@@ -25,6 +25,8 @@
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/public-api/image-loader/image-url.h>
 #include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali/devel-api/actors/camera-actor-devel.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/object/type-registry-helper.h>
@@ -55,12 +57,14 @@ BaseHandle Create()
 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::SceneView, Toolkit::Control, Create);
 DALI_TYPE_REGISTRATION_END()
 
-Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1;
+Property::Index   RENDERING_BUFFER    = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1;
+constexpr int32_t DEFAULT_ORIENTATION = 0;
 
 } // anonymous namespace
 
 SceneView::SceneView()
-: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT))
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+  mWindowOrientation(DEFAULT_ORIENTATION)
 {
 }
 
@@ -188,7 +192,7 @@ void SceneView::UnregisterModel(Scene3D::Model model)
 
 void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
 {
-  mIBLResourceReady = false;
+  mIBLResourceReady      = false;
   Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl);
   if(diffuseTexture)
   {
@@ -252,12 +256,25 @@ void SceneView::OnSceneConnection(int depth)
 {
   UpdateRenderTask();
 
+  Window window = DevelWindow::Get(Self());
+  if(window)
+  {
+    window.ResizeSignal().Connect(this, &SceneView::OnWindowResized);
+  }
+
   Control::OnSceneConnection(depth);
 }
 
 void SceneView::OnSceneDisconnection()
 {
   mModels.clear();
+
+  Window window = DevelWindow::Get(Self());
+  if(window)
+  {
+    window.ResizeSignal().Disconnect(this, &SceneView::OnWindowResized);
+  }
+
   Control::OnSceneDisconnection();
 }
 
@@ -354,14 +371,14 @@ void SceneView::UpdateRenderTask()
       mRenderTask.SetCameraActor(mSelectedCamera);
     }
 
-    Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+    Vector3     size        = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
     const float aspectRatio = size.width / size.height;
     mSelectedCamera.SetAspectRatio(aspectRatio);
-    const float halfHeight = mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE];
-    const float halfWidth = aspectRatio * halfHeight;
+    const float halfHeight                                              = mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE];
+    const float halfWidth                                               = aspectRatio * halfHeight;
     mSelectedCamera[Dali::CameraActor::Property::LEFT_PLANE_DISTANCE]   = -halfWidth;
     mSelectedCamera[Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE]  = halfWidth;
-    mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE]    = halfHeight; // Top is +ve to keep consistency with orthographic values
+    mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE]    = halfHeight;  // Top is +ve to keep consistency with orthographic values
     mSelectedCamera[Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE] = -halfHeight; // Bottom is -ve to keep consistency with orthographic values
     if(mUseFrameBuffer)
     {
@@ -409,6 +426,26 @@ void SceneView::UpdateRenderTask()
         mTexture.Reset();
       }
     }
+
+    RotateCamera();
+  }
+}
+
+void SceneView::OnWindowResized(Window window, Window::WindowSize size)
+{
+  mWindowOrientation = DevelWindow::GetPhysicalOrientation(window);
+  RotateCamera();
+}
+
+void SceneView::RotateCamera()
+{
+  if(mUseFrameBuffer)
+  {
+    DevelCameraActor::RotateProjection(mSelectedCamera, DEFAULT_ORIENTATION);
+  }
+  else
+  {
+    DevelCameraActor::RotateProjection(mSelectedCamera, mWindowOrientation);
   }
 }
 
index ddd7319..548bfee 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/actors/layer.h>
+#include <dali/public-api/adaptor-framework/window.h>
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/render-tasks/render-task.h>
@@ -30,8 +31,8 @@
 #include <dali/public-api/rendering/texture.h>
 
 // INTERNAL INCLUDES
-#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
 #include <dali-scene3d/public-api/controls/model/model.h>
+#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
 
 namespace Dali
 {
@@ -204,6 +205,16 @@ private:
    */
   void UpdateRenderTask();
 
+  /**
+   * @brief Callback that will be called when window is resized.
+   */
+  void OnWindowResized(Window window, Window::WindowSize size);
+
+  /**
+   * @brief Update camera's projection orientation according to the screen orientation.
+   */
+  void RotateCamera();
+
 private:
   Toolkit::Visual::Base mVisual;
 
@@ -216,8 +227,8 @@ private:
   Dali::FrameBuffer           mRenderTarget;
   Dali::Texture               mTexture;
   Dali::RenderTask            mRenderTask;
-
-  Layer mRootLayer;
+  Layer                       mRootLayer;
+  int32_t                     mWindowOrientation;
 
   Dali::Texture mSpecularTexture;
   Dali::Texture mDiffuseTexture;
index e315cb9..69029d9 100644 (file)
@@ -67,6 +67,16 @@ const Actor Model::GetModelRoot() const
   return GetImpl(*this).GetModelRoot();
 }
 
+void Model::SetChildrenSensitive(bool enable)
+{
+  GetImpl(*this).SetChildrenSensitive(enable);
+}
+
+bool Model::GetChildrenSensitive() const
+{
+  return GetImpl(*this).GetChildrenSensitive();
+}
+
 void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
 {
   GetImpl(*this).SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
index 6678d9f..104e054 100644 (file)
@@ -23,8 +23,8 @@
 
 // EXTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>
-#include <dali/public-api/rendering/texture.h>
 #include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/rendering/texture.h>
 
 namespace Dali
 {
@@ -50,6 +50,7 @@ class Model;
  *
  * By default, The loaded model has its own position and size which are defined in vertex buffer regardless of the Control size.
  *
+ * @SINCE_2_1.41
  * @code
  *
  * Model model = Model::New(modelUrl);
@@ -69,6 +70,8 @@ class DALI_SCENE3D_API Model : public Dali::Toolkit::Control
 public:
   /**
    * @brief Create an initialized Model.
+   *
+   * @SINCE_2_1.41
    * @param[in] modelUrl model file path.(e.g., glTF, and DLI).
    * @param[in] resourceDirectoryUrl resource file path that includes binary, image etc.
    * @note If resourceDirectoryUrl is empty, the parent directory path of modelUrl is used for resource path.
@@ -81,6 +84,8 @@ public:
    *
    * Only derived versions can be instantiated. Calling member
    * functions with an uninitialized Dali::Object is not allowed.
+   *
+   * @SINCE_2_1.41
    */
   Model();
 
@@ -88,11 +93,15 @@ public:
    * @brief Destructor.
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   *
+   * @SINCE_2_1.41
    */
   ~Model();
 
   /**
    * @brief Copy constructor.
+   *
+   * @SINCE_2_1.41
    * @param[in] model Handle to an object
    */
   Model(const Model& model);
@@ -100,12 +109,15 @@ public:
   /**
    * @brief Move constructor
    *
+   * @SINCE_2_1.41
    * @param[in] rhs A reference to the moved handle
    */
   Model(Model&& rhs);
 
   /**
    * @brief Assignment operator.
+   *
+   * @SINCE_2_1.41
    * @param[in] model Handle to an object
    * @return reference to this
    */
@@ -114,6 +126,7 @@ public:
   /**
    * @brief Move assignment
    *
+   * @SINCE_2_1.41
    * @param[in] rhs A reference to the moved handle
    * @return A reference to this
    */
@@ -125,6 +138,7 @@ public:
    * If handle points to a Model, the downcast produces valid handle.
    * If not, the returned handle is left uninitialized.
    *
+   * @SINCE_2_1.41
    * @param[in] handle Handle to an object
    * @return Handle to a Model or an uninitialized handle
    */
@@ -132,12 +146,40 @@ public:
 
   /**
    * @brief Retrieves model root Actor.
+   *
+   * @SINCE_2_1.41
    * @return Root Actor of the model.
    */
   const Actor GetModelRoot() const;
 
   /**
+   * @brief Whether allow this model's children actor to use events.
+   *
+   * Usually, 3D Model might have a lot of actors. And most of them don't need to check events.
+   * To optimize traversal, we need to setup some flag that this model don't allow (or allow) to traversal
+   * children so that child can use events.
+   *
+   * @SINCE_2_1.43
+   * @note Even if we set children sensitive as false, model itself's sensitive
+   * is depend on it's property.
+   * @note If we don't call this API, default is false. (Allow to traversal model's children during hit-test)
+   *
+   * @param[in] enable True to enable model's children can use events.
+   */
+  void SetChildrenSensitive(bool enable);
+
+  /**
+   * @brief Gets whether this Model allow model's children actor to use events or not.
+   *
+   * @SINCE_2_1.43
+   * @return bool True if this Model allow model children sensitive.
+   */
+  bool GetChildrenSensitive() const;
+
+  /**
    * @brief Changes Image Based Light as the input textures.
+   *
+   * @SINCE_2_1.41
    * @param[in] diffuseUrl cube map that can be used as a diffuse IBL source.
    * @param[in] specularUrl cube map that can be used as a specular IBL source.
    * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
@@ -147,6 +189,7 @@ public:
   /**
    * @brief Sets Image Based Light Texture.
    *
+   * @SINCE_2_1.41
    * @param[in] diffuseTexture cube map texture that can be used as a diffuse IBL source.
    * @param[in] specularTexture cube map texture that can be used as a specular IBL source.
    * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
@@ -158,6 +201,7 @@ public:
   /**
    * @brief Sets Scale Factor of Image Based Light Source.
    *
+   * @SINCE_2_1.41
    * @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overrided.
    *
    * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
@@ -168,12 +212,15 @@ public:
    * @brief Gets Scale Factor of Image Based Light Source.
    * Default value is 1.0f.
    *
+   * @SINCE_2_1.41
    * @return scale factor that controls light source intensity.
    */
   float GetImageBasedLightScaleFactor() const;
 
   /**
    * @brief Gets number of animations those loaded from model file.
+   *
+   * @SINCE_2_1.41
    * @return The number of loaded animations.
    * @note This method should be called after Model load finished.
    */
@@ -181,6 +228,8 @@ public:
 
   /**
    * @brief Gets animation at the index.
+   *
+   * @SINCE_2_1.41
    * @param[in] index Index of animation to be retrieved.
    * @return Animation at the index.
    * @note This method should be called after Model load finished.
@@ -189,6 +238,8 @@ public:
 
   /**
    * @brief Retrieves animation with the given name.
+   *
+   * @SINCE_2_1.41
    * @param[in] name string name of animation to be retrieved.
    * @return Animation that has the given name.
    * @note This method should be called after Model load finished.
index b1923c3..fce3b19 100644 (file)
@@ -85,6 +85,7 @@ class SceneView;
  *
  * And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window.
  *
+ * @SINCE_2_1.38
  * @code
  *
  * Dali::Scene3D::SceneView sceneView = Dali::Scene3D::SceneView::New();
@@ -104,6 +105,8 @@ class DALI_SCENE3D_API SceneView : public Dali::Toolkit::Control
 public:
   /**
    * @brief Create an initialized SceneView.
+   *
+   * @SINCE_2_1.38
    * @return A handle to a newly allocated Dali resource
    */
   static SceneView New();
@@ -113,6 +116,8 @@ public:
    *
    * Only derived versions can be instantiated. Calling member
    * functions with an uninitialized Dali::Object is not allowed.
+   *
+   * @SINCE_2_1.38
    */
   SceneView();
 
@@ -120,11 +125,15 @@ public:
    * @brief Destructor.
    *
    * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   *
+   * @SINCE_2_1.38
    */
   ~SceneView();
 
   /**
    * @brief Copy constructor.
+   *
+   * @SINCE_2_1.38
    * @param[in] sceneView Handle to an object
    */
   SceneView(const SceneView& sceneView);
@@ -132,12 +141,15 @@ public:
   /**
    * @brief Move constructor
    *
+   * @SINCE_2_1.38
    * @param[in] rhs A reference to the moved handle
    */
   SceneView(SceneView&& rhs);
 
   /**
    * @brief Assignment operator.
+   *
+   * @SINCE_2_1.38
    * @param[in] sceneView Handle to an object
    * @return reference to this
    */
@@ -146,6 +158,7 @@ public:
   /**
    * @brief Move assignment
    *
+   * @SINCE_2_1.38
    * @param[in] rhs A reference to the moved handle
    * @return A reference to this
    */
@@ -157,6 +170,7 @@ public:
    * If handle points to a SceneView, the downcast produces valid handle.
    * If not, the returned handle is left uninitialized.
    *
+   * @SINCE_2_1.38
    * @param[in] handle Handle to an object
    * @return Handle to a SceneView or an uninitialized handle
    */
@@ -166,6 +180,7 @@ public:
    * @brief Adds a CameraActor to the SceneView
    * The CameraActor can be used as a selected camera to render the scene by using SelectCamera(uint32_t) or SelectCamera(std::string)
    *
+   * @SINCE_2_1.38
    * @note
    * AspectRatio property of CameraActor will be changed depending on the Size of this SceneView.
    *
@@ -183,6 +198,8 @@ public:
 
   /**
    * @brief Removes a CameraActor from this SceneView.
+   *
+   * @SINCE_2_1.38
    * @note If removed CameraActor is selected CameraActor,
    * first camera in the list is set to selected CameraActor.
    *
@@ -193,6 +210,7 @@ public:
   /**
    * @brief Retrieves the number of cameras.
    *
+   * @SINCE_2_1.38
    * @return Number of cameras those currently the SceneView contains.
    */
   uint32_t GetCameraCount() const;
@@ -200,6 +218,7 @@ public:
   /**
    * @brief Retrieves selected CameraActor.
    *
+   * @SINCE_2_1.38
    * @return CameraActor currently used in SceneView as a selected CameraActor
    */
   CameraActor GetSelectedCamera() const;
@@ -207,6 +226,7 @@ public:
   /**
    * @brief Retrieves a CameraActor of the index.
    *
+   * @SINCE_2_1.38
    * @param[in] index Index of CameraActor to be retrieved.
    *
    * @return CameraActor of the index
@@ -216,6 +236,7 @@ public:
   /**
    * @brief Retrieves a CameraActor of the name.
    *
+   * @SINCE_2_1.38
    * @param[in] name string keyword of CameraActor to be retrieved.
    *
    * @return CameraActor that has the name as a Dali::Actor::Property::NAME
@@ -225,6 +246,7 @@ public:
   /**
    * @brief Makes SceneView use a CameraActor of index as a selected camera.
    *
+   * @SINCE_2_1.38
    * @param[in] index Index of CameraActor to be used as a selected camera.
    */
   void SelectCamera(uint32_t index);
@@ -232,6 +254,7 @@ public:
   /**
    * @brief Makes SceneView use a CameraActor of a name as a selected camera.
    *
+   * @SINCE_2_1.38
    * @param[in] name string keyword of CameraActor to be used as a selected camera.
    */
   void SelectCamera(const std::string& name);
@@ -239,6 +262,7 @@ public:
   /**
    * @brief Sets Image Based Light Source to apply it on the all Models those added on this SceneView.
    *
+   * @SINCE_2_1.38
    * @note If any Models already have IBL, they are batch-overridden with the SceneView's IBL.
    * If SceneView has IBL, IBL of newly added Model is also overridden.
    * To set indivisual IBL for each Model, the Model's IBL should be set after the SceneView's IBL.
@@ -252,6 +276,7 @@ public:
   /**
    * @brief Sets Scale Factor of Image Based Light Source.
    *
+   * @SINCE_2_1.41
    * @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overriden.
    * @note Default value is 1.0f.
    *
@@ -263,6 +288,7 @@ public:
    * @brief Gets Scale Factor of Image Based Light Source.
    * Default value is 1.0f.
    *
+   * @SINCE_2_1.41
    * @return scale factor that controls light source intensity.
    */
   float GetImageBasedLightScaleFactor() const;
@@ -273,6 +299,7 @@ public:
    * If useFramebuffer is false, each item in SceneView is rendered on window directly.
    * Default is false.
    *
+   * @SINCE_2_1.38
    * @note If useFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
    * If useFramebuffer is false, performance is become better but SceneView is rendered on top of the other 2D Actors regardless tree order.
    *
@@ -283,6 +310,7 @@ public:
   /**
    * @brief Gets whether this SceneView uses Framebuffer or not.
    *
+   * @SINCE_2_1.38
    * @return bool True if this SceneView uses Framebuffer.
    */
   bool IsUsingFramebuffer() const;
index 96555f2..8eb596d 100644 (file)
@@ -1195,19 +1195,25 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
         ReadArcField(eRenderable, *arcNode);
       }
 
-      if(renderable) // process common properties of all renderables + register payload
+      if(renderable && eRenderable != nullptr) // process common properties of all renderables + register payload
       {
         // shader
         renderable->mShaderIdx = 0;
         auto eShader           = eRenderable->GetChild("shader");
-        resourceIds.push_back({ResourceType::Shader, eShader, renderable->mShaderIdx});
+        if(eShader)
+        {
+          resourceIds.push_back({ResourceType::Shader, eShader, renderable->mShaderIdx});
+        }
 
         // color
         if(modelNode)
         {
           modelNode->mMaterialIdx = 0; // must offer default of 0
           auto eMaterial          = eRenderable->GetChild("material");
-          resourceIds.push_back({ResourceType::Material, eMaterial, modelNode->mMaterialIdx});
+          if(eMaterial)
+          {
+            resourceIds.push_back({ResourceType::Material, eMaterial, modelNode->mMaterialIdx});
+          }
 
           if(!ReadColorCodeOrColor(eRenderable, modelNode->mColor, params.input.mConvertColorCode))
           {
index c0e7ac1..fc3ffde 100644 (file)
@@ -43,6 +43,7 @@ extern Debug::Filter* gTextureManagerLogFilter; ///< Define at texture-manager-i
   loadState == TextureManagerType::LoadState::MASK_APPLIED     ? "MASK_APPLIED"     : \
   loadState == TextureManagerType::LoadState::UPLOADED         ? "UPLOADED"         : \
   loadState == TextureManagerType::LoadState::CANCELLED        ? "CANCELLED"        : \
+  loadState == TextureManagerType::LoadState::MASK_CANCELLED   ? "MASK_CANCELLED"   : \
   loadState == TextureManagerType::LoadState::LOAD_FAILED      ? "LOAD_FAILED"      : \
                                                                  "Unknown"
 // clang-format on
@@ -169,7 +170,7 @@ TextureCacheManager::LoadState TextureCacheManager::GetTextureStateInternal(cons
 
 Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex)
 {
-  Texture        texture; // empty handle
+  Texture           texture; // empty handle
   TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
 
   switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
@@ -645,8 +646,8 @@ TextureCacheManager::TextureCacheIndex TextureCacheManager::AppendCache(const Te
 
 void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureInfo)
 {
-  TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
-  bool removeTextureInfo = false;
+  TextureCacheIndex textureInfoIndex  = GetCacheIndexFromId(textureInfo.textureId);
+  bool              removeTextureInfo = false;
 
   DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::Remove(textureId:%d) url:%s\n  cacheIdx:%d loadState:%s reference count = %d\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), textureInfoIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState), textureInfo.referenceCount);
 
@@ -665,12 +666,18 @@ void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureI
       }
       removeTextureInfo = true;
     }
-    else if(textureInfo.loadState == LoadState::LOADING || textureInfo.loadState == LoadState::MASK_APPLYING)
+    else if(textureInfo.loadState == LoadState::LOADING)
     {
       // We mark the textureInfo for removal.
       // Once the load has completed, this method will be called again.
       textureInfo.loadState = LoadState::CANCELLED;
     }
+    else if(textureInfo.loadState == LoadState::MASK_APPLYING)
+    {
+      // We mark the textureInfo for removal.
+      // Once the load has completed, this method will be called again.
+      textureInfo.loadState = LoadState::MASK_CANCELLED;
+    }
     else
     {
       // In other states, we are not waiting for a load so we are safe to remove the TextureInfo data.
index ab237a3..643fced 100644 (file)
@@ -92,6 +92,7 @@ Debug::Filter* gTextureManagerLogFilter = Debug::Filter::New(Debug::NoLogging, f
   loadState == TextureManagerType::LoadState::MASK_APPLIED     ? "MASK_APPLIED"     : \
   loadState == TextureManagerType::LoadState::UPLOADED         ? "UPLOADED"         : \
   loadState == TextureManagerType::LoadState::CANCELLED        ? "CANCELLED"        : \
+  loadState == TextureManagerType::LoadState::MASK_CANCELLED   ? "MASK_CANCELLED"   : \
   loadState == TextureManagerType::LoadState::LOAD_FAILED      ? "LOAD_FAILED"      : \
                                                                  "Unknown"
 // clang-format on
@@ -551,7 +552,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // Update preMultiplyOnLoad value. It should be changed according to preMultiplied value of the cached info.
     preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
   }
 
   if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
@@ -563,7 +564,7 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // Cache new texutre, and get cacheIndex.
     cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex, loadYuvPlanes));
 
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, preMultiply);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, preMultiply);
   }
 
   // The below code path is common whether we are using the cache or not.
@@ -582,9 +583,10 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
      TextureManager::LoadState::WAITING_FOR_MASK != textureInfo.loadState &&
      TextureManager::LoadState::MASK_APPLYING != textureInfo.loadState &&
      TextureManager::LoadState::MASK_APPLIED != textureInfo.loadState &&
-     TextureManager::LoadState::CANCELLED != textureInfo.loadState)
+     TextureManager::LoadState::CANCELLED != textureInfo.loadState &&
+     TextureManager::LoadState::MASK_CANCELLED != textureInfo.loadState)
   {
-    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId);
+    DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId);
 
     textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
   }
@@ -625,6 +627,14 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
         ObserveTexture(textureInfo, observer);
         break;
       }
+      case TextureManager::LoadState::MASK_CANCELLED:
+      {
+        // A cancelled texture hasn't finished mask applying yet. Treat as a mask applying texture
+        // (it's ref count has already been incremented, above)
+        textureInfo.loadState = TextureManager::LoadState::MASK_APPLYING;
+        ObserveTexture(textureInfo, observer);
+        break;
+      }
       case TextureManager::LoadState::LOAD_FINISHED:
       {
         // Loading has already completed.
@@ -711,8 +721,8 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
     {
       TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
       TextureInfo&              textureInfo(mTextureCacheManager[textureCacheIndex]);
-      // We only need to consider maskTextureId when texture's loadState is not CANCELLED. Because it is already deleted.
-      if(textureInfo.loadState != LoadState::CANCELLED)
+      // We only need to consider maskTextureId when texture's loadState is not cancelled. Because it is already deleted.
+      if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
       {
         if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
         {
@@ -720,6 +730,8 @@ void TextureManager::Remove(const TextureManager::TextureId& textureId, TextureU
         }
       }
 
+      DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d observer=%p ) cacheIndex:%d removal maskTextureId=%d, loadingQueueTextureId=%d, loadState=%s\n", textureId, observer, textureCacheIndex.GetIndex(), maskTextureId, mLoadingQueueTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
+
       // the case that LoadingQueue is working.
       if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
       {
@@ -861,6 +873,7 @@ void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo
     }
     case LoadState::LOADING:
     case LoadState::CANCELLED:
+    case LoadState::MASK_CANCELLED:
     case LoadState::LOAD_FINISHED:
     case LoadState::WAITING_FOR_MASK:
     case LoadState::MASK_APPLYING:
@@ -974,7 +987,7 @@ void TextureManager::AsyncLoadComplete(const TextureManager::TextureId& textureI
 
     DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "  textureId:%d Url:%s CacheIndex:%d LoadState: %s\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
 
-    if(textureInfo.loadState != LoadState::CANCELLED)
+    if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
     {
       // textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
       PostLoad(textureInfo, pixelBuffers);
@@ -1117,6 +1130,8 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
     UploadTextures(pixelBuffers, maskTextureInfo);
   }
 
+  DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): maskTextureId=%d, maskTextureUrl=%s\n", maskTextureInfo.textureId, maskTextureInfo.url.GetUrl().c_str());
+
   // Search the cache, checking if any texture has this texture id as a maskTextureId
   const std::size_t size = mTextureCacheManager.size();
 
@@ -1149,10 +1164,18 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
           pixelBuffers.push_back(textureInfo.pixelBuffer);
           UploadTextures(pixelBuffers, textureInfo);
 
+          // Increase reference counts for notify required textureId.
+          // Now we can assume that we don't remove & re-assign this textureId
+          // during NotifyObserver signal emit.
+          maskTextureInfo.referenceCount++;
+          textureInfo.referenceCount++;
+
+          DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
           notifyRequiredTextureIds.push_back(textureInfo.textureId);
         }
       }
-      else
+      else // maskTextureInfo.loadState == LoadState::LOAD_FAILED
       {
         // Url texture load success, But alpha mask texture load failed. Run as normal image upload.
         DALI_LOG_ERROR("Alpha mask image loading failed! Image will not be masked\n");
@@ -1160,6 +1183,14 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
         pixelBuffers.push_back(textureInfo.pixelBuffer);
         UploadTextures(pixelBuffers, textureInfo);
 
+        // Increase reference counts for notify required textureId.
+        // Now we can assume that we don't remove & re-assign this textureId
+        // during NotifyObserver signal emit.
+        maskTextureInfo.referenceCount++;
+        textureInfo.referenceCount++;
+
+        DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
         notifyRequiredTextureIds.push_back(textureInfo.textureId);
       }
     }
@@ -1175,6 +1206,12 @@ void TextureManager::CheckForWaitingTexture(TextureManager::TextureInfo& maskTex
       NotifyObservers(textureInfo, true);
     }
   }
+
+  // Decrease reference count
+  for(const auto textureId : notifyRequiredTextureIds)
+  {
+    Remove(textureId, nullptr);
+  }
 }
 
 void TextureManager::ApplyMask(TextureManager::TextureInfo& textureInfo, const TextureManager::TextureId& maskTextureId)
index adffcf9..74057fc 100644 (file)
@@ -201,6 +201,7 @@ enum class LoadState
   MASK_APPLIED,     ///< Loading has finished, Mask is applyied by GPU
   UPLOADED,         ///< Uploaded and ready. (For GPU upload only)
   CANCELLED,        ///< Removed before loading completed
+  MASK_CANCELLED,   ///< Removed before mask applying completed
   LOAD_FAILED       ///< Async loading failed, e.g. connection problem
 };
 
index 006554d..ca3b93d 100644 (file)
@@ -70,20 +70,20 @@ Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging,
 
 AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties)
 {
-  AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl));
+  AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl, ImageDimensions{}));
   visual->SetProperties(properties);
   visual->Initialize();
   return visual;
 }
 
-AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
 {
-  AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl));
+  AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl, size));
   visual->Initialize();
   return visual;
 }
 
-AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
 : Visual::Base(factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE)),
   mUrl(imageUrl),
   mAnimationData(),
@@ -91,6 +91,7 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory
   mImageVisualShaderFactory(shaderFactory),
   mVisualSize(),
   mVisualScale(Vector2::ONE),
+  mDesiredSize(size),
   mPlacementActor(),
   mPlayState(DevelImageVisual::PlayState::STOPPED),
   mEventCallback(nullptr),
@@ -132,7 +133,12 @@ void AnimatedVectorImageVisual::VectorAnimationManagerDestroyed()
 
 void AnimatedVectorImageVisual::GetNaturalSize(Vector2& naturalSize)
 {
-  if(mVisualSize != Vector2::ZERO)
+  if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+  {
+    naturalSize.x = mDesiredSize.GetWidth();
+    naturalSize.y = mDesiredSize.GetHeight();
+  }
+  else if(mVisualSize != Vector2::ZERO)
   {
     naturalSize = mVisualSize;
   }
@@ -194,6 +200,10 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap(Property::Map& map) const
   Property::Map layerInfo;
   mVectorAnimationTask->GetLayerInfo(layerInfo);
   map.Insert(Toolkit::DevelImageVisual::Property::CONTENT_INFO, layerInfo);
+
+  map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired());
+  map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
+  map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -246,6 +256,14 @@ void AnimatedVectorImageVisual::DoSetProperties(const Property::Map& propertyMap
       {
         DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second);
       }
+      else if(keyValue.first == IMAGE_DESIRED_WIDTH)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second);
+      }
+      else if(keyValue.first == IMAGE_DESIRED_HEIGHT)
+      {
+        DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second);
+      }
     }
   }
 
@@ -321,6 +339,25 @@ void AnimatedVectorImageVisual::DoSetProperty(Property::Index index, const Prope
       }
       break;
     }
+    case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
+    {
+      int32_t desiredWidth = 0;
+      if(value.Get(desiredWidth))
+      {
+        mDesiredSize.SetWidth(desiredWidth);
+      }
+      break;
+    }
+
+    case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
+    {
+      int32_t desiredHeight = 0;
+      if(value.Get(desiredHeight))
+      {
+        mDesiredSize.SetHeight(desiredHeight);
+      }
+      break;
+    }
   }
 }
 
@@ -611,8 +648,17 @@ void AnimatedVectorImageVisual::SendAnimationData()
 
 void AnimatedVectorImageVisual::SetVectorImageSize()
 {
-  uint32_t width  = static_cast<uint32_t>(mVisualSize.width * mVisualScale.width);
-  uint32_t height = static_cast<uint32_t>(mVisualSize.height * mVisualScale.height);
+  uint32_t width, height;
+  if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+  {
+    width  = mDesiredSize.GetWidth();
+    height = mDesiredSize.GetHeight();
+  }
+  else
+  {
+    width  = static_cast<uint32_t>(mVisualSize.width * mVisualScale.width);
+    height = static_cast<uint32_t>(mVisualSize.height * mVisualScale.height);
+  }
 
   if(mAnimationData.width != width || mAnimationData.height != height)
   {
index 72c8e60..b0a7569 100644 (file)
@@ -73,9 +73,10 @@ public:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
    * @param[in] imageUrl The URL to an animated vector image to use
+   * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
    * @return A smart-pointer to the newly allocated visual.
    */
-  static AnimatedVectorImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+  static AnimatedVectorImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions());
 
 public: // from Visual
   /**
@@ -111,8 +112,9 @@ protected:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
    * @param[in] imageUrl The URL to an animated vector image to use
+   * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
    */
-  AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+  AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size);
 
   /**
    * @brief A reference counted object may only be deleted by calling Unreference().
@@ -243,6 +245,7 @@ private:
   PropertyNotification               mSizeNotification;
   Vector2                            mVisualSize;
   Vector2                            mVisualScale;
+  Dali::ImageDimensions              mDesiredSize{};
   WeakHandle<Actor>                  mPlacementActor;
   DevelImageVisual::PlayState::Type  mPlayState;
   CallbackBase*                      mEventCallback; // Not owned
index da12c4f..2fcf2a9 100644 (file)
@@ -318,7 +318,7 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va
 
     case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
     {
-      float desiredWidth = 0.0f;
+      int32_t desiredWidth = 0;
       if(value.Get(desiredWidth))
       {
         mDesiredSize.SetWidth(desiredWidth);
@@ -332,7 +332,7 @@ void ImageVisual::DoSetProperty(Property::Index index, const Property::Value& va
 
     case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
     {
-      float desiredHeight = 0.0f;
+      int32_t desiredHeight = 0;
       if(value.Get(desiredHeight))
       {
         mDesiredSize.SetHeight(desiredHeight);
index a0ced87..cd59107 100644 (file)
@@ -48,20 +48,20 @@ const Dali::Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
 SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties)
 {
-  SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl));
+  SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl, ImageDimensions{}));
   svgVisual->SetProperties(properties);
   svgVisual->Initialize();
   return svgVisual;
 }
 
-SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
 {
-  SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl));
+  SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl, size));
   svgVisual->Initialize();
   return svgVisual;
 }
 
-SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
 : Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::SVG),
   mImageVisualShaderFactory(shaderFactory),
   mAtlasRect(FULL_TEXTURE_RECT),
@@ -71,6 +71,7 @@ SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory&
   mDefaultHeight(0),
   mPlacementActor(),
   mRasterizedSize(Vector2::ZERO),
+  mDesiredSize(size),
   mLoadFailed(false),
   mAttemptAtlasing(false)
 {
@@ -122,6 +123,14 @@ void SvgVisual::DoSetProperties(const Property::Map& propertyMap)
     {
       DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second);
     }
+    else if(keyValue.first == IMAGE_DESIRED_WIDTH)
+    {
+      DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second);
+    }
+    else if(keyValue.first == IMAGE_DESIRED_HEIGHT)
+    {
+      DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second);
+    }
   }
 }
 
@@ -154,6 +163,24 @@ void SvgVisual::DoSetProperty(Property::Index index, const Property::Value& valu
       }
       break;
     }
+    case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
+    {
+      int32_t desiredWidth = 0;
+      if(value.Get(desiredWidth))
+      {
+        mDesiredSize.SetWidth(desiredWidth);
+      }
+      break;
+    }
+    case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
+    {
+      int32_t desiredHeight = 0;
+      if(value.Get(desiredHeight))
+      {
+        mDesiredSize.SetHeight(desiredHeight);
+      }
+      break;
+    }
   }
 }
 
@@ -202,7 +229,12 @@ void SvgVisual::DoSetOffScene(Actor& actor)
 
 void SvgVisual::GetNaturalSize(Vector2& naturalSize)
 {
-  if(mLoadFailed && mImpl->mRenderer)
+  if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+  {
+    naturalSize.x = mDesiredSize.GetWidth();
+    naturalSize.y = mDesiredSize.GetHeight();
+  }
+  else if(mLoadFailed && mImpl->mRenderer)
   {
     // Load failed, use broken image size
     auto textureSet = mImpl->mRenderer.GetTextures();
@@ -234,6 +266,8 @@ void SvgVisual::DoCreatePropertyMap(Property::Map& map) const
     map.Insert(Toolkit::ImageVisual::Property::ATLASING, mAttemptAtlasing);
   }
   map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired());
+  map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
+  map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
 }
 
 void SvgVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -367,14 +401,24 @@ void SvgVisual::ApplyRasterizedImage(PixelData rasterizedPixelData, bool success
 
 void SvgVisual::OnSetTransform()
 {
-  Vector2 visualSize = mImpl->mTransform.GetVisualSize(mImpl->mControlSize);
-
   if(IsOnScene() && !mLoadFailed)
   {
-    if(visualSize != mRasterizedSize || mDefaultWidth == 0 || mDefaultHeight == 0)
+    Vector2 size;
+    if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+    {
+      // Use desired size
+      size = Vector2(mDesiredSize.GetWidth(), mDesiredSize.GetHeight());
+    }
+    else
+    {
+      // Use visual size
+      size = mImpl->mTransform.GetVisualSize(mImpl->mControlSize);
+    }
+
+    if(size != mRasterizedSize || mDefaultWidth == 0 || mDefaultHeight == 0)
     {
-      mRasterizedSize = visualSize;
-      AddRasterizationTask(visualSize);
+      mRasterizedSize = size;
+      AddRasterizationTask(size);
     }
   }
 
index 5c606f1..93decde 100644 (file)
@@ -72,9 +72,10 @@ public:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
    * @param[in] imageUrl The URL to svg resource to use
+   * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
    * @return A smart-pointer to the newly allocated visual.
    */
-  static SvgVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+  static SvgVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions());
 
 public: // from Visual
   /**
@@ -104,8 +105,9 @@ protected:
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
    * @param[in] imageUrl The URL to svg resource to use
+   * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
    */
-  SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+  SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size);
 
   /**
    * @brief A reference counted object may only be deleted by calling Unreference().
@@ -186,6 +188,7 @@ private:
   uint32_t                  mDefaultHeight;
   WeakHandle<Actor>         mPlacementActor;
   Vector2                   mRasterizedSize;
+  Dali::ImageDimensions     mDesiredSize{};
   bool                      mLoadFailed;
   bool                      mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
 };
index 57290a1..60fb25e 100644 (file)
@@ -332,7 +332,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageD
       case VisualUrl::TVG:
       case VisualUrl::SVG:
       {
-        visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
+        visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
         break;
       }
       case VisualUrl::GIF:
@@ -343,7 +343,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageD
       }
       case VisualUrl::JSON:
       {
-        visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
+        visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
         break;
       }
       case VisualUrl::REGULAR_IMAGE:
index 33fb992..2340cb6 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 42;
+const unsigned int TOOLKIT_MICRO_VERSION = 43;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 7635931..8bfe522 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.1.42
+Version:    2.1.43
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT