From: Heeyong Song Date: Thu, 1 Jun 2023 04:49:08 +0000 (+0900) Subject: Fix SVG crash issue X-Git-Tag: dali_2.2.29~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F36%2F293636%2F1;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Fix SVG crash issue Remove previous task before create a new task Change-Id: I77ef7d92e48d1ad256f9d2b07b6423e7b572ff5f --- diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt index 8ce883d..85a1439 100755 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -80,6 +80,7 @@ SET(TC_SOURCES utc-Dali-ToggleButton.cpp utc-Dali-ScrollViewEffect.cpp utc-Dali-SuperBlurView.cpp + utc-Dali-SvgVisual.cpp utc-Dali-Toolkit.cpp utc-Dali-Model3dView.cpp utc-Dali-Visual.cpp diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp index 02f3d8f..c85110a 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp @@ -18,15 +18,15 @@ #include "toolkit-event-thread-callback.h" // EXTERNAL INCLUDES -#include -#include #include -#include +#include +#include +#include #include +#include #include -#include +#include #include -#include namespace { @@ -34,23 +34,21 @@ namespace // triggers from multiple threads - they should all be created on // event thread. std::vector gEventThreadCallbacks; -} - +} // namespace namespace Dali { - struct EventThreadCallback::Impl { CallbackBase* callback; - sem_t mySemaphore; + sem_t mySemaphore; }; -EventThreadCallback::EventThreadCallback( CallbackBase* callback ) -: mImpl( new Impl() ) +EventThreadCallback::EventThreadCallback(CallbackBase* callback) +: mImpl(new Impl()) { mImpl->callback = callback; - sem_init( &(mImpl->mySemaphore), 0, 0 ); + sem_init(&(mImpl->mySemaphore), 0, 0); gEventThreadCallbacks.push_back(this); } @@ -59,7 +57,7 @@ EventThreadCallback::~EventThreadCallback() { std::vector::iterator iter = std::find(gEventThreadCallbacks.begin(), gEventThreadCallbacks.end(), this); - if( iter != gEventThreadCallbacks.end() ) + if(iter != gEventThreadCallbacks.end()) { gEventThreadCallbacks.erase(iter); } @@ -68,15 +66,15 @@ EventThreadCallback::~EventThreadCallback() void EventThreadCallback::Trigger() { - sem_post( &(mImpl->mySemaphore) ); + sem_post(&(mImpl->mySemaphore)); } // returns true if timed out rather than triggered bool EventThreadCallback::WaitingForTrigger() { struct timespec now; - clock_gettime( CLOCK_REALTIME, &now ); - if( now.tv_nsec < 999900000 ) // 999, 900, 000 + clock_gettime(CLOCK_REALTIME, &now); + if(now.tv_nsec < 999900000) // 999, 900, 000 now.tv_nsec += 1000; else { @@ -84,7 +82,7 @@ bool EventThreadCallback::WaitingForTrigger() now.tv_nsec = 0; } - int error = sem_timedwait( &(mImpl->mySemaphore), &now ); + int error = sem_timedwait(&(mImpl->mySemaphore), &now); return error != 0; // true if timeout } @@ -93,57 +91,59 @@ CallbackBase* EventThreadCallback::GetCallback() return mImpl->callback; } -} - +} // namespace Dali namespace Test { - -bool WaitForEventThreadTrigger( int triggerCount, int timeoutInSeconds ) +bool WaitForEventThreadTrigger(int triggerCount, int timeoutInSeconds, int executeCallbacks) { struct timespec startTime; struct timespec now; - clock_gettime( CLOCK_REALTIME, &startTime ); - now.tv_sec = startTime.tv_sec; + clock_gettime(CLOCK_REALTIME, &startTime); + now.tv_sec = startTime.tv_sec; now.tv_nsec = startTime.tv_nsec; // Round robin poll of each semaphore: - while ( triggerCount > 0 ) + while(triggerCount > 0) { - if( gEventThreadCallbacks.size() > 0 ) + if(gEventThreadCallbacks.size() > 0) { - for( std::vector::iterator iter = gEventThreadCallbacks.begin(); - iter != gEventThreadCallbacks.end(); ++iter ) + for(std::vector::iterator iter = gEventThreadCallbacks.begin(); + iter != gEventThreadCallbacks.end(); + ++iter) { Dali::EventThreadCallback* eventTrigger = (*iter); - Dali::CallbackBase* callback = eventTrigger->GetCallback(); - bool timedout = eventTrigger->WaitingForTrigger(); - if( ! timedout ) + Dali::CallbackBase* callback = eventTrigger->GetCallback(); + bool timedout = eventTrigger->WaitingForTrigger(); + if(!timedout) { - // Semaphore was unlocked - execute the trigger - Dali::CallbackBase::Execute( *callback ); + if(executeCallbacks) + { + // Semaphore was unlocked - execute the trigger + Dali::CallbackBase::Execute(*callback); + } triggerCount--; } - if( triggerCount <= 0 ) + if(triggerCount <= 0) { break; } } } - clock_gettime( CLOCK_REALTIME, &now ); - if( now.tv_sec - startTime.tv_sec > timeoutInSeconds ) + clock_gettime(CLOCK_REALTIME, &now); + if(now.tv_sec - startTime.tv_sec > timeoutInSeconds) { // Ensure we break out of the loop if elapsed time has passed break; } } - clock_gettime( CLOCK_REALTIME, &now ); - if( now.tv_sec > startTime.tv_sec + 1 ) + clock_gettime(CLOCK_REALTIME, &now); + if(now.tv_sec > startTime.tv_sec + 1) { - fprintf(stderr, "WaitForEventThreadTrigger took %ld seconds\n", now.tv_sec - startTime.tv_sec ); + fprintf(stderr, "WaitForEventThreadTrigger took %ld seconds\n", now.tv_sec - startTime.tv_sec); } return triggerCount == 0; } -} +} // namespace Test diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.h b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.h index 9693e6e..6541b3e 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.h +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_EVENT_THREAD_CALLBACK_H /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -25,12 +25,10 @@ namespace Dali { - class DALI_TOOLKIT_API EventThreadCallback { public: - - EventThreadCallback( CallbackBase* callback ); + EventThreadCallback(CallbackBase* callback); ~EventThreadCallback(); @@ -41,24 +39,21 @@ public: CallbackBase* GetCallback(); private: - // undefined copy constructor. - EventThreadCallback( const EventThreadCallback& ); + EventThreadCallback(const EventThreadCallback&); // undefined assignment operator - EventThreadCallback& operator=( const EventThreadCallback& ); + EventThreadCallback& operator=(const EventThreadCallback&); private: - struct Impl; Impl* mImpl; }; -} +} // namespace Dali namespace Test { - /** * Wait for the tested code to create an event trigger, then * wait for triggerCount Trigger calls to occur, and execute the trigger @@ -66,9 +61,8 @@ namespace Test * * Will wait for a maximum of 30s before failing the test and returning. */ -bool WaitForEventThreadTrigger( int triggerCount, int timeoutInSeconds=30 ); - -} +bool WaitForEventThreadTrigger(int triggerCount, int timeoutInSeconds = 30, int executeCallbacks = true); +} // namespace Test #endif // DALI_TOOLKIT_EVENT_THREAD_CALLBACK_H diff --git a/automated-tests/src/dali-toolkit/utc-Dali-SvgVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-SvgVisual.cpp new file mode 100644 index 0000000..48fd4ce --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-SvgVisual.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +using namespace Dali; +using namespace Dali::Toolkit; + +void dali_svg_visual_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void dali_svg_visual_cleanup(void) +{ + test_return_value = TET_PASS; +} + +namespace +{ +const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg"; +} // namespace + +int UtcDaliSvgVisualChageSize(void) +{ + tet_infoline("Test change transform"); + + ToolkitTestApplication application; + + TraceCallStack& textureTrace = application.GetGlAbstraction().GetTextureTrace(); + textureTrace.Enable(true); + + Visual::Base visual = VisualFactory::Get().CreateVisual(Property::Map().Add(ImageVisual::Property::URL, TEST_SVG_FILE_NAME)); + DALI_TEST_CHECK(visual); + + DummyControl control = DummyControl::New(); + DummyControlImpl& dummyImpl = static_cast(control.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + application.SendNotification(); + + // Wait for loading + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + control.SetProperty(Actor::Property::SIZE, Vector2(100, 100)); + application.GetScene().Add(control); + + visual.SetTransformAndSize(Property::Map(), Vector2(100, 100)); + + // Wait for rasterization but not execute the callback + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 30, false), true, TEST_LOCATION); + + // Change actor size before finishing rasterization + control.SetProperty(Actor::Property::SIZE, Vector2(300, 300)); + visual.SetTransformAndSize(Property::Map(), Vector2(300, 300)); + + application.SendNotification(); + + // Wait for rasterization + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + TraceCallStack::NamedParams params; + params["width"] << 300; + params["height"] << 300; + // Should be the final size + DALI_TEST_EQUALS(textureTrace.FindMethodAndParams("TexImage2D", params), true, TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/internal/visuals/svg/svg-visual.cpp b/dali-toolkit/internal/visuals/svg/svg-visual.cpp index 8fcbf52..2a1b09f 100644 --- a/dali-toolkit/internal/visuals/svg/svg-visual.cpp +++ b/dali-toolkit/internal/visuals/svg/svg-visual.cpp @@ -314,6 +314,13 @@ void SvgVisual::AddRasterizationTask(const Vector2& size) { if(mImpl->mRenderer) { + // Remove previous task + if(mRasterizingTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask); + mRasterizingTask.Reset(); + } + unsigned int width = static_cast(size.width); unsigned int height = static_cast(size.height);