From: Eunki Hong Date: Wed, 17 Apr 2024 06:36:26 +0000 (+0000) Subject: Merge "Remove BaseHandle / BaseObject TypeTraits is trivialgit" into devel/master X-Git-Tag: dali_2.3.20~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=66a4dc29b695c3a9fd6e6b5eab5472fcb05e8c1c;hp=9f4609c99a5ed97a5f92b413eb5bb144a2e6b0c0;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Merge "Remove BaseHandle / BaseObject TypeTraits is trivialgit" into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Accessible.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Accessible.cpp index f76c4a0..eee08a7 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Accessible.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Accessible.cpp @@ -19,12 +19,13 @@ // test harness headers before dali headers. #include -#include #include #include +#include +#include -#include #include +#include #include #include @@ -45,10 +46,10 @@ int utcDaliAccessibilityCheckBoxButtonGetStates(void) ToolkitTestApplication application; auto check_box_button = Toolkit::CheckBoxButton::New(); - auto q = Dali::Accessibility::Accessible::Get( check_box_button ); - DALI_TEST_CHECK( q ); + auto q = Dali::Accessibility::Accessible::Get(check_box_button); + DALI_TEST_CHECK(q); auto states = q->GetStates(); - DALI_TEST_EQUALS( (int) states[ Dali::Accessibility::State::SELECTABLE ], (int) true, TEST_LOCATION ); + DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SELECTABLE], (int)true, TEST_LOCATION); END_TEST; } @@ -60,9 +61,9 @@ int utcDaliAccessibilityCheckLabelText(void) auto check_box_button = Toolkit::CheckBoxButton::New(); //check_box_button.SetLabelText( "button" ); check_box_button.SetProperty(Toolkit::Button::Property::LABEL, "button"); - auto q = Dali::Accessibility::Accessible::Get( check_box_button ); - DALI_TEST_CHECK( q ); - DALI_TEST_EQUALS( q->GetName(), "button", TEST_LOCATION ); + auto q = Dali::Accessibility::Accessible::Get(check_box_button); + DALI_TEST_CHECK(q); + DALI_TEST_EQUALS(q->GetName(), "button", TEST_LOCATION); END_TEST; } @@ -77,7 +78,7 @@ int UtcDaliAccessibilityCheckShowingState(void) parentButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); parentButton.SetProperty(Actor::Property::POSITION, Dali::Vector2(0.0f, 0.0f)); parentButton.SetProperty(Actor::Property::SIZE, Dali::Vector2(200.0f, 200.0f)); - application.GetScene().Add( parentButton ); + application.GetScene().Add(parentButton); // Toatally inside of parent auto buttonA = Toolkit::PushButton::New(); @@ -99,7 +100,7 @@ int UtcDaliAccessibilityCheckShowingState(void) auto buttonC = Toolkit::PushButton::New(); buttonC.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); buttonC.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); - buttonC.SetProperty(Actor::Property::POSITION, Dali::Vector2(100.0f,100.0f)); + buttonC.SetProperty(Actor::Property::POSITION, Dali::Vector2(100.0f, 100.0f)); buttonC.SetProperty(Actor::Property::SIZE, Dali::Vector2(200.0f, 200.0f)); parentButton.Add(buttonC); @@ -109,17 +110,17 @@ int UtcDaliAccessibilityCheckShowingState(void) auto q = Dali::Accessibility::Accessible::Get(buttonA); DALI_TEST_CHECK(q); auto states = q->GetStates(); - DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) true, TEST_LOCATION); + DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)true, TEST_LOCATION); q = Dali::Accessibility::Accessible::Get(buttonB); DALI_TEST_CHECK(q); states = q->GetStates(); - DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) true, TEST_LOCATION); + DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)true, TEST_LOCATION); q = Dali::Accessibility::Accessible::Get(buttonC); DALI_TEST_CHECK(q); states = q->GetStates(); - DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) true, TEST_LOCATION); + DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)true, TEST_LOCATION); // Make SHOWING object invisible buttonC.SetProperty(Actor::Property::VISIBLE, false); @@ -128,7 +129,7 @@ int UtcDaliAccessibilityCheckShowingState(void) application.Render(16); states = q->GetStates(); - DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) false, TEST_LOCATION); + DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)false, TEST_LOCATION); // Make SHOWING parent invisible parentButton.SetProperty(Actor::Property::VISIBLE, false); @@ -139,7 +140,7 @@ int UtcDaliAccessibilityCheckShowingState(void) q = Dali::Accessibility::Accessible::Get(buttonA); DALI_TEST_CHECK(q); states = q->GetStates(); - DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) false, TEST_LOCATION); + DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)false, TEST_LOCATION); END_TEST; } @@ -206,3 +207,70 @@ int utcDaliAutomationId(void) END_TEST; } + +int utcDaliImgSrc(void) +{ + ToolkitTestApplication application; + const std::string imageSrcKey = "imgSrc"; + // Check that imgSrc is NOT added for non-image view w/ no additional property + { + const auto checkBoxButton = Toolkit::CheckBoxButton::New(); + const auto controlAccessible = Dali::Accessibility::Accessible::Get(checkBoxButton); + auto attributes = controlAccessible->GetAttributes(); + DALI_TEST_CHECK(attributes.find(imageSrcKey) == attributes.end()); + } + + // Check that imgSrc is NOT added for non-image view w/ additional properties + { + const auto textLabel = Toolkit::TextLabel::New("Hello"); + const auto controlAccessible = Dali::Accessibility::Accessible::Get(textLabel); + auto attributes = controlAccessible->GetAttributes(); + DALI_TEST_CHECK(attributes.find(imageSrcKey) == attributes.end()); + } + + // Check that imgSrc is added for image view w/ Url + { + const std::string imagePath = "gallery-small-1.jpg"; + const auto imageView = Toolkit::ImageView::New(imagePath); + const auto controlAccessible = Dali::Accessibility::Accessible::Get(imageView); + auto attributes = controlAccessible->GetAttributes(); + DALI_TEST_CHECK(attributes.find(imageSrcKey) != attributes.end()); + DALI_TEST_EQUALS(attributes[imageSrcKey], imagePath, TEST_LOCATION); + } + + // Check that imgSrc is added for image view w/ imageMap; single url case + { + const std::string imagePathForImageMap = "icon-edit.png"; + Property::Map imageMap; + imageMap[Toolkit::ImageVisual::Property::URL] = imagePathForImageMap; + imageMap[Toolkit::ImageVisual::Property::RELEASE_POLICY] = Toolkit::ImageVisual::ReleasePolicy::DETACHED; + + auto imageView = Toolkit::ImageView::New(); + imageView.SetProperty(Toolkit::ImageView::Property::IMAGE, imageMap); + + const auto controlAccessible = Dali::Accessibility::Accessible::Get(imageView); + auto attributes = controlAccessible->GetAttributes(); + DALI_TEST_CHECK(attributes.find(imageSrcKey) != attributes.end()); + DALI_TEST_EQUALS(attributes[imageSrcKey], imagePathForImageMap, TEST_LOCATION); + } + + // Check that imgSrc is added for image view w/ imageMap; url array returns first element + { + const std::string image1 = "application-icon-20.png"; + const std::string image2 = "application-icon-21.png"; + Property::Map imageMap; + Property::Array urls{image1, image2}; + imageMap[Toolkit::ImageVisual::Property::URL] = urls; + imageMap[Toolkit::ImageVisual::Property::RELEASE_POLICY] = Toolkit::ImageVisual::ReleasePolicy::DETACHED; + + auto imageView = Toolkit::ImageView::New(); + imageView.SetProperty(Toolkit::ImageView::Property::IMAGE, imageMap); + + const auto controlAccessible = Dali::Accessibility::Accessible::Get(imageView); + auto attributes = controlAccessible->GetAttributes(); + DALI_TEST_CHECK(attributes.find(imageSrcKey) != attributes.end()); + DALI_TEST_EQUALS(attributes[imageSrcKey], image1, TEST_LOCATION); + } + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h index 49c344a..6a69f93 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h @@ -71,6 +71,8 @@ public: void RemoveIdle(CallbackBase* callback); void RunIdles(); + void RequestUpdateOnce(); + static Integration::Scene GetScene(Dali::Window window); Dali::RenderSurfaceInterface& GetSurface(); diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp index 4d77310..40c73ae 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp @@ -139,6 +139,19 @@ void Adaptor::RunIdles() mReturnCallbacks.Swap(reusedCallbacks); } +void Adaptor::RequestUpdateOnce() +{ + if(mTestApplication) + { + auto scene = mTestApplication->GetScene(); + if(scene) + { + tet_printf("Adaptor::RequestUpdateOnce()\n"); + scene.KeepRendering(0.0f); + } + } +} + Dali::RenderSurfaceInterface& Adaptor::GetSurface() { DALI_ASSERT_ALWAYS(!mWindows.empty()); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp index 08921c9..55891b8 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp @@ -69,6 +69,100 @@ void VisualEventSignal(Control control, Dali::Property::Index visualIndex, Dali: } } +/** + * @brief Retry function to get playrange until expect values comes. + * @note This function might consume EventThreadTrigger. + * + * @param[in] dummyControl The control for test. + * @param[in] expectStartFrame Expect start frame. + * @param[in] expectEndFrame Expect end frame. + * @param[in] retrialFrames Retry required frame value list. + * @param[in] testLocation Location info of UTC. It will be used when UTC failed. + */ +void CheckAndRetryPlayRange(DummyControl dummyControl, int expectStartFrame, int expectEndFrame, std::vector> retrialFrames, const char* testLocation) +{ + int tryCount = 0; + int tryCountMax = 25; + while(++tryCount <= tryCountMax) + { + Property::Map resultMap = dummyControl.GetProperty(DummyControl::Property::TEST_VISUAL); + + Property::Value* value = resultMap.Find(DevelImageVisual::Property::PLAY_RANGE, Property::ARRAY); + DALI_TEST_CHECK(value); + + Property::Array* result = value->GetArray(); + DALI_TEST_CHECK(result); + DALI_TEST_EQUALS(result->Count(), 2, TEST_LOCATION); + + bool tryAgain = false; + for(auto& framePair : retrialFrames) + { + if(result->GetElementAt(0).Get() == framePair.first && result->GetElementAt(1).Get() == framePair.second) + { + tryAgain = true; + break; + } + } + if(tryAgain) + { + tet_printf("Retry to get value again! [%d]\n", tryCount); + // Dummy sleep 1 second. + Test::WaitForEventThreadTrigger(1, 1); + continue; + } + + DALI_TEST_EQUALS(result->GetElementAt(0).Get(), expectStartFrame, testLocation); + DALI_TEST_EQUALS(result->GetElementAt(1).Get(), expectEndFrame, testLocation); + break; + } + DALI_TEST_CHECK(tryCount <= tryCountMax); +} + +/** + * @brief Retry function to get current frame until expect values comes. + * @note This function might consume EventThreadTrigger. + * + * @param[in] dummyControl The control for test. + * @param[in] expectCurrentFrame Expect current frame. + * @param[in] retrialFrames Retry required frame value list. + * @param[in] testLocation Location info of UTC. It will be used when UTC failed. + */ +void CheckAndRetryCurrentFrame(DummyControl dummyControl, int expectCurrentFrame, std::vector retrialFrames, const char* testLocation) +{ + int tryCount = 0; + int tryCountMax = 25; + while(++tryCount <= tryCountMax) + { + Property::Map resultMap = dummyControl.GetProperty(DummyControl::Property::TEST_VISUAL); + + Property::Value* value = resultMap.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER, Property::INTEGER); + DALI_TEST_CHECK(value); + + int32_t result = value->Get(); + + bool tryAgain = false; + for(auto& frame : retrialFrames) + { + if(result == frame) + { + tryAgain = true; + break; + } + } + if(tryAgain) + { + tet_printf("Retry to get value again! [%d]\n", tryCount); + // Dummy sleep 1 second. + Test::WaitForEventThreadTrigger(1, 1); + continue; + } + + DALI_TEST_EQUALS(result, expectCurrentFrame, testLocation); + break; + } + DALI_TEST_CHECK(tryCount <= tryCountMax); +} + } // namespace int UtcDaliVisualFactoryGetAnimatedVectorImageVisual01(void) @@ -174,8 +268,17 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual03(void) // Trigger count is 2 - load & render a frame DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + // There might be 1 event triggered if start frame is not 0, and render frame spend long time. + // if ForceRenderOnce triggered before render complete, renderer count could be zero. + // Consume it if required. + if(actor.GetRendererCount() == 0) + { + tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n"); + Test::WaitForEventThreadTrigger(1, 1); + } + // renderer is added to actor - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); @@ -208,13 +311,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void) .Add("stopBehavior", DevelImageVisual::StopBehavior::FIRST_FRAME) .Add("loopingMode", DevelImageVisual::LoopingMode::AUTO_REVERSE) .Add("redrawInScalingDown", false) + .Add("enableFrameCache", false) + .Add("notifyAfterRasterization", false) .Add("cornerRadius", cornerRadius) .Add("borderlineWidth", borderlineWidth) .Add("borderlineColor", borderlineColor) .Add("borderlineOffset", borderlineOffset) .Add("desiredWidth", desiredWidth) - .Add("desiredHeight", desiredHeight) - .Add("useFixedCache", false); + .Add("desiredHeight", desiredHeight); Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap); DALI_TEST_CHECK(visual); @@ -231,8 +335,17 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void) // Trigger count is 1 - render a frame DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // There might be 1 event triggered if start frame is not 0, and render frame spend long time. + // if ForceRenderOnce triggered before render complete, renderer count could be zero. + // Consume it if required. + if(actor.GetRendererCount() == 0) + { + tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n"); + Test::WaitForEventThreadTrigger(1, 1); + } + // renderer is added to actor - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); @@ -270,6 +383,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void) DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == false); + value = resultMap.Find(DevelImageVisual::Property::ENABLE_FRAME_CACHE, Property::BOOLEAN); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == false); + + value = resultMap.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, Property::BOOLEAN); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == false); + value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4); DALI_TEST_CHECK(value); DALI_TEST_EQUALS(value->Get(), Vector4(cornerRadius, cornerRadius, cornerRadius, cornerRadius), TEST_LOCATION); @@ -395,6 +516,10 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void) DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == false); // Check default value + value = resultMap.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, Property::BOOLEAN); + DALI_TEST_CHECK(value); + DALI_TEST_CHECK(value->Get() == false); // Check default value + value = resultMap.Find(DevelImageVisual::Property::REDRAW_IN_SCALING_DOWN, Property::BOOLEAN); DALI_TEST_CHECK(value); DALI_TEST_CHECK(value->Get() == true); // Check default value @@ -703,7 +828,7 @@ int UtcDaliAnimatedVectorImageVisualLoopCount(void) DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); // renderer is added to actor - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); @@ -747,8 +872,17 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) // Trigger count is 2 - load & render a frame DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + // There might be 1 event triggered if start frame is not 0, and render frame spend long time. + // if ForceRenderOnce triggered before render complete, renderer count could be zero. + // Consume it if required. + if(actor.GetRendererCount() == 0) + { + tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n"); + Test::WaitForEventThreadTrigger(1, 1); + } + // renderer is added to actor - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); @@ -767,7 +901,7 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) // Set invalid play range array.Clear(); array.PushBack(1); - array.PushBack(100); + array.PushBack(totalFrameNumber + 100); attributes.Clear(); attributes.Add(DevelImageVisual::Property::PLAY_RANGE, array); @@ -781,15 +915,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); - value = map.Find(DevelImageVisual::Property::PLAY_RANGE); - - result = value->GetArray(); - result->GetElementAt(0).Get(resultStartFrame); - result->GetElementAt(1).Get(resultEndFrame); - - DALI_TEST_EQUALS(resultStartFrame, 1, TEST_LOCATION); - DALI_TEST_EQUALS(resultEndFrame, totalFrameNumber - 1, TEST_LOCATION); // Should be clamped + // Should be clamped. + CheckAndRetryPlayRange(actor, 1, totalFrameNumber - 1, {{startFrame, endFrame}}, TEST_LOCATION); DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, Property::Map()); @@ -798,17 +925,14 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3); - // To make event trigger - actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f)); - application.SendNotification(); application.Render(); + // Jump to action when paused, will make one or more event trigger DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); - value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER); - DALI_TEST_EQUALS(value->Get(), 3, TEST_LOCATION); + // Test whether current frame is 3. + CheckAndRetryCurrentFrame(actor, 3, {0, 1}, TEST_LOCATION); array.Clear(); array.PushBack(0); @@ -819,23 +943,16 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes); // To make event trigger - actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); + actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f)); application.SendNotification(); application.Render(); DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); - value = map.Find(DevelImageVisual::Property::PLAY_RANGE); - - result = value->GetArray(); - result->GetElementAt(0).Get(resultStartFrame); - result->GetElementAt(1).Get(resultEndFrame); - - DALI_TEST_EQUALS(0, resultStartFrame, TEST_LOCATION); - DALI_TEST_EQUALS(2, resultEndFrame, TEST_LOCATION); + CheckAndRetryPlayRange(actor, 0, 2, {{1, totalFrameNumber - 1}}, TEST_LOCATION); + map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER); DALI_TEST_EQUALS(value->Get(), 2, TEST_LOCATION); // CURRENT_FRAME_NUMBER should be changed also. @@ -878,8 +995,17 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void) // Trigger count is 2 - load & render a frame DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + // There might be 1 event triggered if start frame is not 0, and render frame spend long time. + // if ForceRenderOnce triggered before render complete, renderer count could be zero. + // Consume it if required. + if(actor.GetRendererCount() == 0) + { + tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n"); + Test::WaitForEventThreadTrigger(1, 1); + } + // renderer is added to actor - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); @@ -1008,7 +1134,7 @@ int UtcDaliAnimatedVectorImageVisualMarkerInfo(void) DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); // renderer is added to actor - DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION); Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); @@ -1100,10 +1226,10 @@ int UtcDaliAnimatedVectorImageVisualMarkerInfoFromInvalid(void) END_TEST; } -int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void) +int UtcDaliAnimatedVectorImageVisualEnableFrameCache(void) { ToolkitTestApplication application; - tet_infoline("UtcDaliAnimatedVectorImageVisualUsedFixedCache"); + tet_infoline("UtcDaliAnimatedVectorImageVisualEnableFrameCache"); Property::Map propertyMap; propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE) @@ -1117,13 +1243,12 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void) DummyControl actor = DummyControl::New(true); DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); - //actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); application.GetScene().Add(actor); application.SendNotification(); application.Render(); - // Trigger count is 1 - render a frame + // Trigger count is 1 - load DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); Vector2 controlSize(200.f, 200.f); @@ -1132,7 +1257,7 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void) application.SendNotification(); application.Render(); - // Trigger count is 1 - load + // Trigger count is 1 - render a frame DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); // renderer is added to actor @@ -1147,10 +1272,10 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void) END_TEST; } -int UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed(void) +int UtcDaliAnimatedVectorImageVisualEnableFrameCacheFailed(void) { ToolkitTestApplication application; - tet_infoline("UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed"); + tet_infoline("UtcDaliAnimatedVectorImageVisualEnableFrameCacheFailed"); Property::Map propertyMap; propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE) @@ -1194,6 +1319,100 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed(void) END_TEST; } +int UtcDaliAnimatedVectorImageVisualNotifyAfterRasterization(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliAnimatedVectorImageVisualNotifyAfterRasterization"); + + Property::Map propertyMap; + propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE) + .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME) + .Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, true) + .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false); + + Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(true); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + application.GetScene().Add(actor); + + application.SendNotification(); + application.Render(); + + // Trigger count is 1 - load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + Vector2 controlSize(200.f, 200.f); + actor.SetProperty(Actor::Property::SIZE, controlSize); + + application.SendNotification(); + application.Render(); + + // Trigger count is 1 - render a frame + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + // Play animation + Property::Map attributes; + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes); + + application.SendNotification(); + application.Render(); + + // There might be 1 event triggered if render frame spend long time. + // if ForceRenderOnce triggered before render complete, renderer count could be zero. + // Consume it if required. + if(actor.GetRendererCount() == 0) + { + tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n"); + Test::WaitForEventThreadTrigger(1, 1); + } + + // renderer is added to actor + DALI_TEST_CHECK(actor.GetRendererCount() == 1u); + Renderer renderer = actor.GetRendererAt(0u); + DALI_TEST_CHECK(renderer); + + // Check renderer behavior + DALI_TEST_CHECK(renderer.GetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::IF_REQUIRED); + + Property::Map map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + Property::Value* value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION); + DALI_TEST_CHECK(value->Get() == true); + + propertyMap.Clear(); + propertyMap.Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, false); + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap); + + application.SendNotification(); + application.Render(); + + // Check renderer behavior again + DALI_TEST_CHECK(renderer.GetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::CONTINUOUSLY); + + map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION); + DALI_TEST_CHECK(value->Get() == false); + + propertyMap.Clear(); + propertyMap.Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, true); + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap); + + application.SendNotification(); + application.Render(); + + // Check renderer behavior again + DALI_TEST_CHECK(renderer.GetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::IF_REQUIRED); + + map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION); + DALI_TEST_CHECK(value->Get() == true); + + END_TEST; +} + int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void) { ToolkitTestApplication application; @@ -1278,12 +1497,10 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void) DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 2); - // To make event trigger - actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); - application.SendNotification(); application.Render(); + // Trigger count is 1 - Jump to during stopped DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); Property::Map map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); @@ -1303,7 +1520,7 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void) DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3); // To make event trigger - actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f)); + actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); application.SendNotification(); application.Render(); @@ -1334,19 +1551,16 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void) // Wait for animation finish DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); - // EventThread will be triggered after animation finished (For render forcibly). - // TODO : Is this logic will works well on server-side? - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + // Note : AnimationFinished will occure force-render, and it might required another trigger. Test one more trigger now. + Test::WaitForEventThreadTrigger(1, 1); // Jump to 3 DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3); - // To make event trigger - actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f)); - application.SendNotification(); application.Render(); + // Trigger count is 1 - Jump to during stopped. DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); @@ -1420,8 +1634,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void) Property::Array* result = value->GetArray(); DALI_TEST_CHECK(result); - DALI_TEST_CHECK(result->GetElementAt(0).Get() == startFrame); - DALI_TEST_CHECK(result->GetElementAt(1).Get() == endFrame); + DALI_TEST_EQUALS(result->GetElementAt(0).Get(), startFrame, TEST_LOCATION); + DALI_TEST_EQUALS(result->GetElementAt(1).Get(), endFrame, TEST_LOCATION); playRange.Clear(); playRange.PushBack(0); @@ -1449,8 +1663,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void) result = value->GetArray(); DALI_TEST_CHECK(result); - DALI_TEST_CHECK(result->GetElementAt(0).Get() == 0); - DALI_TEST_CHECK(result->GetElementAt(1).Get() == 2); + // Ensure that vector data sended well. + CheckAndRetryPlayRange(actor, 0, 2, {{startFrame, endFrame}}, TEST_LOCATION); attributes.Clear(); @@ -1476,8 +1690,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void) result = value->GetArray(); DALI_TEST_CHECK(result); - DALI_TEST_CHECK(result->GetElementAt(0).Get() == startFrame); - DALI_TEST_CHECK(result->GetElementAt(1).Get() == endFrame); + // Ensure that vector data sended well. + CheckAndRetryPlayRange(actor, startFrame, endFrame, {{0, 2}}, TEST_LOCATION); // Play and update property attributes.Clear(); @@ -2391,45 +2605,6 @@ int UtcDaliAnimatedVectorImageVisualFlushAction(void) application.GetScene().Add(dummyControl); - // Retry function to get playrange until expect values comes. - auto CheckAndRetryPlayRange = [&](int expectStartFrame, int expectEndFrame, std::vector> retrialFrames) { - int tryCount = 0; - int tryCountMax = 30; - while(++tryCount <= tryCountMax) - { - Property::Map resultMap = dummyControl.GetProperty(DummyControl::Property::TEST_VISUAL); - - Property::Value* value = resultMap.Find(DevelImageVisual::Property::PLAY_RANGE, Property::ARRAY); - DALI_TEST_CHECK(value); - - Property::Array* result = value->GetArray(); - DALI_TEST_CHECK(result); - DALI_TEST_EQUALS(result->Count(), 2, TEST_LOCATION); - - bool tryAgain = false; - for(auto& framePair : retrialFrames) - { - if(result->GetElementAt(0).Get() == framePair.first && result->GetElementAt(1).Get() == framePair.second) - { - tryAgain = true; - break; - } - } - if(tryAgain) - { - tet_printf("Retry to get value again! [%d]\n", tryCount); - // Dummy sleep 1 second. - Test::WaitForEventThreadTrigger(1, 1); - continue; - } - - DALI_TEST_EQUALS(result->GetElementAt(0).Get(), expectStartFrame, TEST_LOCATION); - DALI_TEST_EQUALS(result->GetElementAt(1).Get(), expectEndFrame, TEST_LOCATION); - break; - } - DALI_TEST_CHECK(tryCount <= tryCountMax); - }; - tet_printf("Pause lottie first.\n"); Property::Map attributes; @@ -2448,7 +2623,7 @@ int UtcDaliAnimatedVectorImageVisualFlushAction(void) } while(totalFrameCount == 0); // Ensure that vector data sended well. - CheckAndRetryPlayRange(startFrame, endFrame, {{0, 0}, {0, totalFrameCount - 1}}); + CheckAndRetryPlayRange(dummyControl, startFrame, endFrame, {{0, 0}, {0, totalFrameCount - 1}}, TEST_LOCATION); resultMap = dummyControl.GetProperty(DummyControl::Property::TEST_VISUAL); @@ -2493,7 +2668,7 @@ int UtcDaliAnimatedVectorImageVisualFlushAction(void) application.Render(16); // Ensure that vector data sended well. - CheckAndRetryPlayRange(changedStartFrame2, changedEndFrame2, {{changedStartFrame1, changedEndFrame1}, {startFrame, endFrame}}); + CheckAndRetryPlayRange(dummyControl, changedStartFrame2, changedEndFrame2, {{changedStartFrame1, changedEndFrame1}, {startFrame, endFrame}}, TEST_LOCATION); resultMap = dummyControl.GetProperty(DummyControl::Property::TEST_VISUAL); diff --git a/dali-toolkit/devel-api/controls/control-accessible.cpp b/dali-toolkit/devel-api/controls/control-accessible.cpp index 8788ade..4aef1f0 100644 --- a/dali-toolkit/devel-api/controls/control-accessible.cpp +++ b/dali-toolkit/devel-api/controls/control-accessible.cpp @@ -25,11 +25,13 @@ #include #include +#include #include // INTERNAL INCLUDES #include #include +#include #include #include #include @@ -39,7 +41,9 @@ namespace Dali::Toolkit::DevelControl { namespace { -static std::string GetLocaleText(std::string string, const char* domain = "dali-toolkit") +constexpr const char* ATTR_IMG_SRC_KEY = "imgSrc"; + +std::string GetLocaleText(std::string string, const char* domain = "dali-toolkit") { #ifdef DGETTEXT_ENABLED /*TODO: currently non-localized string is used as a key for translation lookup. In case the lookup key formatting is forced @@ -50,7 +54,7 @@ static std::string GetLocaleText(std::string string, const char* domain = "dali- #endif } -static Dali::Actor CreateHighlightIndicatorActor() +Dali::Actor CreateHighlightIndicatorActor() { std::string focusBorderImagePath(AssetManager::GetDaliImagePath()); focusBorderImagePath += "/keyboard_focus.9.png"; @@ -65,6 +69,45 @@ static Dali::Actor CreateHighlightIndicatorActor() return actor; } + +std::string FetchImageSrcFromMap(const Dali::Property::Map& imageMap) +{ + auto urlVal = imageMap.Find(Toolkit::ImageVisual::Property::URL); + if(urlVal) + { + if(urlVal->GetType() == Dali::Property::STRING) + { + return urlVal->Get(); + } + else if(urlVal->GetType() == Dali::Property::ARRAY) + { + auto urlArray = urlVal->GetArray(); + if(urlArray && !urlArray->Empty()) + { + // Returns first element if url is an array + return (*urlArray)[0].Get(); + } + } + } + return {}; +} + +std::string FetchImageSrc(const Toolkit::ImageView& imageView) +{ + const auto imageUrl = imageView.GetProperty(Toolkit::ImageView::Property::IMAGE); + if(!imageUrl.empty()) + { + return imageUrl; + } + + const auto imageMap = imageView.GetProperty(Toolkit::ImageView::Property::IMAGE); + if(!imageMap.Empty()) + { + return FetchImageSrcFromMap(imageMap); + } + return {}; +} + } // unnamed namespace ControlAccessible::ControlAccessible(Dali::Actor self) @@ -235,6 +278,15 @@ Dali::Accessibility::Attributes ControlAccessible::GetAttributes() const result.emplace(automationIdKey, std::move(automationId)); } + if(auto imageView = Toolkit::ImageView::DownCast(Self())) + { + auto imageSrc = FetchImageSrc(imageView); + if(!imageSrc.empty()) + { + result.emplace(ATTR_IMG_SRC_KEY, std::move(imageSrc)); + } + } + // Add "class" if not present already if(result.find(classKey) == result.end()) { diff --git a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h index a5e135c..90e868e 100644 --- a/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h +++ b/dali-toolkit/devel-api/visuals/image-visual-properties-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_PROPERTIES_DEVEL_H /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -193,13 +193,24 @@ enum Type /** * @brief Whether to AnimatedVectorImageVisual fixed cache or not. - * @details Name "EnableFrameCache", type Property::BOOLEAN. + * @details Name "enableFrameCache", type Property::BOOLEAN. * If this property is true, AnimatedVectorImageVisual enable frame cache for loading and keeps loaded frame * until the visual is removed. It reduces CPU cost when the animated image will be looping. * But it can spend a lot of memory if the resource has high resolution image or many frame count. - * @note It is used in the AnimatedImageVisual. The default is false + * @note It is used in the AnimatedVectorImageVisual. The default is false */ - ENABLE_FRAME_CACHE = ORIENTATION_CORRECTION + 16 + ENABLE_FRAME_CACHE = ORIENTATION_CORRECTION + 16, + + /** + * @brief Whether notify AnimatedVectorImageVisual to render thread after every rasterization or not. + * @details Name "notifyAfterRasterization", type Property::BOOLEAN. + * If this property is true, AnimatedVectorImageVisual send notify to render thread after every rasterization. + * If false, AnimatedVectorImageVisual set Renderer's Behaviour as Continouly (mean, always update the render thread.) + * + * This flag is useful if given resource has low fps, so we don't need to render every frame. + * @note It is used in the AnimatedVectorImageVisual. The default is false. + */ + NOTIFY_AFTER_RASTERIZATION = ORIENTATION_CORRECTION + 17 }; } //namespace Property diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index b23f066..238de79 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -103,7 +104,8 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory mCoreShutdown(false), mRedrawInScalingDown(true), mEnableFrameCache(false), - mUseNativeImage(false) + mUseNativeImage(false), + mNotifyAfterRasterization(false) { // the rasterized image is with pre-multiplied alpha format mImpl->mFlags |= Visual::Base::Impl::IS_PREMULTIPLIED_ALPHA; @@ -221,6 +223,7 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap(Property::Map& map) const map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth()); map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight()); map.Insert(Toolkit::DevelImageVisual::Property::ENABLE_FRAME_CACHE, mEnableFrameCache); + map.Insert(Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, mNotifyAfterRasterization); } void AnimatedVectorImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const @@ -285,6 +288,10 @@ void AnimatedVectorImageVisual::DoSetProperties(const Property::Map& propertyMap { DoSetProperty(Toolkit::DevelImageVisual::Property::ENABLE_FRAME_CACHE, keyValue.second); } + else if(keyValue.first == NOTIFY_AFTER_RASTERIZATION) + { + DoSetProperty(Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, keyValue.second); + } } } @@ -404,6 +411,22 @@ void AnimatedVectorImageVisual::DoSetProperty(Property::Index index, const Prope } break; } + + case Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION: + { + bool notifyAfterRasterization = false; + if(value.Get(notifyAfterRasterization)) + { + if(mNotifyAfterRasterization != notifyAfterRasterization) + { + mNotifyAfterRasterization = notifyAfterRasterization; + + mAnimationData.notifyAfterRasterization = mNotifyAfterRasterization; + mAnimationData.resendFlag |= VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION; + } + } + break; + } } } @@ -411,7 +434,6 @@ void AnimatedVectorImageVisual::OnInitialize(void) { mVectorAnimationTask->ResourceReadySignal().Connect(this, &AnimatedVectorImageVisual::OnResourceReady); mVectorAnimationTask->SetAnimationFinishedCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnAnimationFinished)); - mVectorAnimationTask->SetForceRenderOnceCallback(MakeCallback(this, &AnimatedVectorImageVisual::OnForceRendering)); EncodedImageBuffer encodedImageBuffer; @@ -719,20 +741,12 @@ void AnimatedVectorImageVisual::OnAnimationFinished(uint32_t playStateId) } } - if(mImpl->mRenderer) + if(!mNotifyAfterRasterization && mImpl->mRenderer) { mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED); } } -void AnimatedVectorImageVisual::OnForceRendering(uint32_t playStateId) -{ - if(!mCoreShutdown) - { - Stage::GetCurrent().KeepRendering(0.0f); // Trigger event processing - } -} - void AnimatedVectorImageVisual::SendAnimationData() { if(mAnimationData.resendFlag) @@ -746,14 +760,18 @@ void AnimatedVectorImageVisual::SendAnimationData() } mVectorAnimationTask->SetAnimationData(mAnimationData); - if(mImpl->mRenderer) + if(mImpl->mRenderer && + ((mAnimationData.resendFlag & VectorAnimationTask::RESEND_PLAY_STATE) || + (mAnimationData.resendFlag & VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION))) { - if(mAnimationData.playState == DevelImageVisual::PlayState::PLAYING) + if(!mNotifyAfterRasterization && mPlayState == DevelImageVisual::PlayState::PLAYING) { + // Make rendering behaviour if we don't notify after rasterization, but animation playing. mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY); } else { + // Otherwise, notify will be sended after rasterization. Make behaviour as required. mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED); } } diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h index 7e7b04d..a1e7480 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h @@ -188,13 +188,6 @@ private: void OnAnimationFinished(uint32_t playStateId); /** - * @brief Event callback from rasterize thread. This is called when we want to ensure rendering next frame. - * - * @param[in] argument Not using arguments - */ - void OnForceRendering(uint32_t argument); - - /** * @brief Send animation data to the rasterize thread. */ void SendAnimationData(); @@ -267,6 +260,7 @@ private: bool mRedrawInScalingDown : 1; bool mEnableFrameCache : 1; bool mUseNativeImage : 1; + bool mNotifyAfterRasterization : 1; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index 423d3fc..ac448c0 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@ -108,6 +108,7 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache) mLayerInfoCached(false), mMarkerInfoCached(false), mEnableFrameCache(false), + mNotifyAfterRasterization(false), mSizeUpdated(false) { mVectorRenderer.UploadCompletedSignal().Connect(this, &VectorAnimationTask::OnUploadCompleted); @@ -139,11 +140,6 @@ void VectorAnimationTask::Finalize() mVectorAnimationThread.RemoveEventTriggerCallbacks(mAnimationFinishedCallback.get()); mAnimationFinishedCallback.reset(); } - if(mForceRenderOnceCallback) - { - mVectorAnimationThread.RemoveEventTriggerCallbacks(mForceRenderOnceCallback.get()); - mForceRenderOnceCallback.reset(); - } if(mLoadCompletedCallback) { mVectorAnimationThread.RemoveEventTriggerCallbacks(mLoadCompletedCallback.get()); @@ -395,12 +391,6 @@ void VectorAnimationTask::SetAnimationFinishedCallback(CallbackBase* callback) mAnimationFinishedCallback = std::unique_ptr(callback); } -void VectorAnimationTask::SetForceRenderOnceCallback(CallbackBase* callback) -{ - Mutex::ScopedLock lock(mMutex); - mForceRenderOnceCallback = std::unique_ptr(callback); -} - void VectorAnimationTask::SetLoopCount(int32_t count) { if(mLoopCount != count) @@ -747,13 +737,10 @@ bool VectorAnimationTask::Rasterize() } // Forcely trigger render once if need. - if(mNeedForceRenderOnceTrigger) + if(mNotifyAfterRasterization || mNeedForceRenderOnceTrigger) { Mutex::ScopedLock lock(mMutex); - if(mForceRenderOnceCallback) - { - mVectorAnimationThread.AddEventTriggerCallback(mForceRenderOnceCallback.get(), mAppliedPlayStateId); - } + mVectorAnimationThread.RequestForceRenderOnce(); mNeedForceRenderOnceTrigger = false; } @@ -891,6 +878,11 @@ void VectorAnimationTask::ApplyAnimationData() SetCurrentFrameNumber(animationData.currentFrame); } + if(animationData.resendFlag & VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION) + { + mNotifyAfterRasterization = animationData.notifyAfterRasterization; + } + if(animationData.resendFlag & VectorAnimationTask::RESEND_NEED_RESOURCE_READY) { mVectorRenderer.InvalidateBuffer(); diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h index 46976a5..c741be1 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h @@ -67,15 +67,16 @@ public: */ enum ResendFlags { - RESEND_PLAY_RANGE = 1 << 0, - RESEND_LOOP_COUNT = 1 << 1, - RESEND_STOP_BEHAVIOR = 1 << 2, - RESEND_LOOPING_MODE = 1 << 3, - RESEND_CURRENT_FRAME = 1 << 4, - RESEND_SIZE = 1 << 5, - RESEND_PLAY_STATE = 1 << 6, - RESEND_NEED_RESOURCE_READY = 1 << 7, - RESEND_DYNAMIC_PROPERTY = 1 << 8 + RESEND_PLAY_RANGE = 1 << 0, + RESEND_LOOP_COUNT = 1 << 1, + RESEND_STOP_BEHAVIOR = 1 << 2, + RESEND_LOOPING_MODE = 1 << 3, + RESEND_CURRENT_FRAME = 1 << 4, + RESEND_SIZE = 1 << 5, + RESEND_PLAY_STATE = 1 << 6, + RESEND_NEED_RESOURCE_READY = 1 << 7, + RESEND_DYNAMIC_PROPERTY = 1 << 8, + RESEND_NOTIFY_AFTER_RASTERIZATION = 1 << 9, }; /** @@ -94,22 +95,24 @@ public: width(0), height(0), loopCount(-1), - playStateId(0) + playStateId(0), + notifyAfterRasterization(false) { } AnimationData& operator=(const AnimationData& rhs) { resendFlag |= rhs.resendFlag; // OR resend flag - playRange = rhs.playRange; - playState = rhs.playState; - stopBehavior = rhs.stopBehavior; - loopingMode = rhs.loopingMode; - currentFrame = rhs.currentFrame; - width = rhs.width; - height = rhs.height; - loopCount = rhs.loopCount; - playStateId = rhs.playStateId; + playRange = rhs.playRange; + playState = rhs.playState; + stopBehavior = rhs.stopBehavior; + loopingMode = rhs.loopingMode; + currentFrame = rhs.currentFrame; + width = rhs.width; + height = rhs.height; + loopCount = rhs.loopCount; + playStateId = rhs.playStateId; + notifyAfterRasterization = rhs.notifyAfterRasterization; dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end()); return *this; } @@ -125,6 +128,7 @@ public: uint32_t height; int32_t loopCount; uint32_t playStateId; + bool notifyAfterRasterization; }; /** @@ -179,12 +183,6 @@ public: void SetAnimationFinishedCallback(CallbackBase* callback); /** - * @brief This callback is called when we want to force render next frame. - * @param[in] callback The force render once callback - */ - void SetForceRenderOnceCallback(CallbackBase* callback); - - /** * @brief Gets the playing range in frame number. * @param[out] startFrame The frame number to specify minimum progress. * @param[out] endFrame The frame number to specify maximum progress. @@ -263,6 +261,16 @@ public: */ bool IsAnimating(); + void KeepRasterizedBuffer(bool enableFrameCache) + { + mEnableFrameCache = enableFrameCache; + } + + bool IsKeptRasterizedBuffer() const + { + return mEnableFrameCache; + } + public: // Implementation of AsyncTask /** * @copydoc Dali::AsyncTask::Process() @@ -282,16 +290,6 @@ public: // Implementation of AsyncTask return "VectorAnimationTask"; } - void KeepRasterizedBuffer(bool enableFrameCache) - { - mEnableFrameCache = enableFrameCache; - } - - bool IsKeptRasterizedBuffer() - { - return mEnableFrameCache; - } - private: /** * @brief Loads the animation file. @@ -399,7 +397,6 @@ private: Mutex mMutex; ResourceReadySignalType mResourceReadySignal; std::unique_ptr mAnimationFinishedCallback{}; - std::unique_ptr mForceRenderOnceCallback{}; std::unique_ptr mLoadCompletedCallback{}; mutable Property::Map mCachedLayerInfo; mutable Property::Map mCachedMarkerInfo; @@ -433,6 +430,7 @@ private: mutable bool mLayerInfoCached : 1; mutable bool mMarkerInfoCached : 1; bool mEnableFrameCache : 1; + bool mNotifyAfterRasterization : 1; bool mSizeUpdated : 1; }; diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp index b07ba5b..5638ec3 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp @@ -46,10 +46,12 @@ VectorAnimationThread::VectorAnimationThread() mSleepThread(MakeCallback(this, &VectorAnimationThread::OnAwakeFromSleep)), mConditionalWait(), mEventTriggerMutex(), + mLogFactory(Dali::Adaptor::Get().GetLogFactory()), + mTraceFactory(Dali::Adaptor::Get().GetTraceFactory()), mNeedToSleep(false), mDestroyThread(false), - mLogFactory(Dali::Adaptor::Get().GetLogFactory()), - mTraceFactory(Dali::Adaptor::Get().GetTraceFactory()) + mEventTriggered(false), + mForceRenderOnce(false) { mAsyncTaskManager = Dali::AsyncTaskManager::Get(); mSleepThread.Start(); @@ -184,6 +186,21 @@ void VectorAnimationThread::RemoveEventTriggerCallbacks(CallbackBase* callback) } } +void VectorAnimationThread::RequestForceRenderOnce() +{ + Mutex::ScopedLock lock(mEventTriggerMutex); + if(!mDestroyThread) + { + mForceRenderOnce = true; + + if(!mEventTriggered) + { + mEventTrigger->Trigger(); + mEventTriggered = true; + } + } +} + void VectorAnimationThread::Run() { SetThreadName("VectorAnimationThread"); @@ -285,6 +302,18 @@ void VectorAnimationThread::OnEventCallbackTriggered() } CallbackBase::Execute(*callbackPair.first, callbackPair.second); } + // Request update once if we need. + { + Mutex::ScopedLock lock(mEventTriggerMutex); + if(!mDestroyThread && mForceRenderOnce) + { + mForceRenderOnce = false; + if(Dali::Adaptor::IsAvailable()) + { + Dali::Adaptor::Get().UpdateOnce(); + } + } + } } std::pair VectorAnimationThread::GetNextEventCallback() diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.h index b1f608a..8b820cc 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.h @@ -90,6 +90,11 @@ public: */ void RemoveEventTriggerCallbacks(CallbackBase* callback); + /** + * @brief Request to event callback from rasterize thread. This is called when we want to ensure rendering next frame. + */ + void RequestForceRenderOnce(); + protected: /** * @brief The entry function of the animation thread. @@ -149,8 +154,9 @@ private: std::chrono::time_point mSleepTimePoint; const Dali::LogFactoryInterface& mLogFactory; const Dali::TraceFactoryInterface& mTraceFactory; - bool mNeedToSleep; - bool mDestroyThread; + + bool mNeedToSleep : 1; + bool mDestroyThread : 1; }; private: @@ -169,12 +175,14 @@ private: ConditionalWait mConditionalWait; Mutex mEventTriggerMutex; std::unique_ptr mEventTrigger{}; - bool mNeedToSleep; - bool mDestroyThread; - bool mEventTriggered{false}; const Dali::LogFactoryInterface& mLogFactory; const Dali::TraceFactoryInterface& mTraceFactory; Dali::AsyncTaskManager mAsyncTaskManager; + + bool mNeedToSleep : 1; + bool mDestroyThread : 1; + bool mEventTriggered : 1; + bool mForceRenderOnce : 1; }; } // namespace Internal diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index 6d89342..ae39540 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -212,6 +212,7 @@ const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio"); const char* const FAST_TRACK_UPLOADING_NAME("fastTrackUploading"); const char* const ENABLE_BROKEN_IMAGE("enableBrokenImage"); const char* const ENABLE_FRAME_CACHE("enableFrameCache"); +const char* const NOTIFY_AFTER_RASTERIZATION("notifyAfterRasterization"); // Text visual const char* const TEXT_PROPERTY("text"); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.h b/dali-toolkit/internal/visuals/visual-string-constants.h index cc97413..9835299 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.h +++ b/dali-toolkit/internal/visuals/visual-string-constants.h @@ -114,6 +114,7 @@ extern const char* const MASK_TEXTURE_RATIO_NAME; extern const char* const FAST_TRACK_UPLOADING_NAME; extern const char* const ENABLE_BROKEN_IMAGE; extern const char* const ENABLE_FRAME_CACHE; +extern const char* const NOTIFY_AFTER_RASTERIZATION; // Text visual extern const char* const TEXT_PROPERTY;