(ParticleSystem) Do not change VertexBufferUpdateCallback during terminate 54/323854/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 8 May 2025 06:13:55 +0000 (15:13 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Thu, 8 May 2025 11:20:53 +0000 (20:20 +0900)
Since ClearVertexBufferUpdateCallback and SetVertexBufferUpdateCallback
don't use message process, (instead we use atomic mutex here)

It will have problem if application call this API at event thread
during app terminating (mean, Render::VertexBuffer already destroyed)

Let we guard this case.

Change-Id: Iaa8343e9860da019c5799dde72dcd3cf7378294a
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/utc-Dali-ParticleSystem.cpp
dali-toolkit/internal/particle-system/particle-renderer-impl.cpp

index eb7ba1d35835dd5f814210c4803f02d41fbe68e2..58b2b9ac1a6b5c4c908d2646195037716d8e0057 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
@@ -15,7 +15,7 @@
  *
  */
 
-#include <dali-test-suite-utils.h>
+#include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/public-api/particle-system/particle-domain.h>
 #include <dali-toolkit/public-api/particle-system/particle-emitter.h>
 #include <dali-toolkit/public-api/particle-system/particle-list.h>
@@ -66,6 +66,8 @@ std::chrono::milliseconds ParticleEmitter::GetCurrentTimeMillis() const
 
 using ParticleEmitterWrapper = Dali::Toolkit::ParticleSystem::Internal::ParticleEmitter;
 
+namespace
+{
 Texture CreateTexture()
 {
   Texture   texture   = Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGBA8888, 100, 100);
@@ -147,7 +149,7 @@ public:
       [[maybe_unused]] auto& col  = particle.Get<Vector4>(ParticleStream::COLOR_STREAM_BIT);
       [[maybe_unused]] auto& vel  = particle.Get<Vector3>(ParticleStream::VELOCITY_STREAM_BIT);
       [[maybe_unused]] auto& sca  = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
-      //auto& basePos = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
+      // auto& basePos = particle.Get<Vector3>(ParticleStream::SCALE_STREAM_BIT);
     }
 
     return count;
@@ -278,9 +280,12 @@ ParticleEmitter CreateEmitter(EmitterGroup* output = nullptr)
 
   return emitter;
 }
+} // namespace
 
 int UtcDaliParticleSystemEmitterNew(void)
 {
+  ToolkitTestApplication application;
+
   // create particle emitter
   auto emitter = ParticleEmitter::New();
 
@@ -322,6 +327,8 @@ int UtcDaliParticleSystemEmitterNew(void)
 
 int UtcDaliParticleSystemEmitterNew2(void)
 {
+  ToolkitTestApplication application;
+
   // create particle emitter
   auto emitter = ParticleEmitter::New();
 
@@ -374,6 +381,8 @@ int UtcDaliParticleSystemEmitterNew2(void)
 
 int UtcDaliParticleSystemEmitterDefaultStreams(void)
 {
+  ToolkitTestApplication application;
+
   // create particle emitter
   auto emitter = ParticleEmitter::New();
 
@@ -425,6 +434,8 @@ int UtcDaliParticleSystemEmitterDefaultStreams(void)
 
 int UtcDaliParticleSystemEmitterModifierStack(void)
 {
+  ToolkitTestApplication application;
+
   // create particle emitter
   auto emitter = ParticleEmitter::New();
 
@@ -478,7 +489,7 @@ int UtcDaliParticleSystemEmitterModifierStack(void)
 
 int UtcDaliParticleSystemTest(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
@@ -549,7 +560,7 @@ int UtcDaliParticleSystemTest(void)
 
 int UtcDaliParticleSystemTestWithTextureScreen(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
@@ -627,7 +638,7 @@ int UtcDaliParticleSystemTestWithTextureScreen(void)
 
 int UtcDaliParticleSystemTestWithTextureAdd(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
@@ -705,7 +716,7 @@ int UtcDaliParticleSystemTestWithTextureAdd(void)
 
 int UtcDaliParticleSystemTestInitialSetup(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
@@ -795,7 +806,7 @@ int UtcDaliParticleSystemTestInitialSetup(void)
 
 int UtcDaliParticleSystemTestMT(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
@@ -880,7 +891,7 @@ int UtcDaliParticleSystemTestMT(void)
 
 int UtcDaliParticleSystemTestParticleSource(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
@@ -979,7 +990,7 @@ int UtcDaliParticleSystemTestParticleSource(void)
 
 int UtcDaliParticleSystemReplaceEmitter(void)
 {
-  TestApplication application;
+  ToolkitTestApplication application;
 
   // Create actor to be used with emitter
   Actor actor = Actor::New();
index aad839f660210ac12eb88a5d3829b811a4ed0e1f..a800eba04cff2b7090d652cb7a24fbcf90f44ba7 100644 (file)
  *
  */
 
-#include <dali-toolkit/internal/particle-system/particle-emitter-impl.h>
-#include <dali-toolkit/internal/particle-system/particle-list-impl.h>
+// CLASS HEADER
 #include <dali-toolkit/internal/particle-system/particle-renderer-impl.h>
-#include <dali/devel-api/rendering/renderer-devel.h>
 
+// EXTERNAL HEADERS
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/common/capabilities.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/graphics-api/graphics-buffer.h>
 #include <dali/graphics-api/graphics-controller.h>
 #include <dali/graphics-api/graphics-program.h>
 #include <dali/graphics-api/graphics-shader.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/particle-system/particle-emitter-impl.h>
+#include <dali-toolkit/internal/particle-system/particle-list-impl.h>
 
 namespace Dali::Toolkit::ParticleSystem::Internal
 {
@@ -233,7 +239,11 @@ void ParticleRenderer::CreateShader()
   mStreamBuffer.SetData(data.Begin(), mEmitter->GetParticleList().GetCapacity() * NUMBER_OF_VERTEX_ELEMENTS_PER_PARTICLE); // needed to initialize
 
   // Sets up callback
-  mStreamBuffer.SetVertexBufferUpdateCallback(std::move(mStreamBufferUpdateCallback));
+  if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+  {
+    // Note : MUST NOT call this API during app terminating
+    mStreamBuffer.SetVertexBufferUpdateCallback(std::move(mStreamBufferUpdateCallback));
+  }
 
   mRenderer = Renderer::New(mGeometry, mShader);
 
@@ -347,8 +357,7 @@ uint32_t ParticleRenderer::OnStreamBufferUpdate(void* streamData, size_t maxByte
       const auto count = i == workerCount - 1 ? particleCount - index : partial;
 
       tasks.emplace_back(*this, list, index, count, dst + (elementByte * NUMBER_OF_VERTEX_ELEMENTS_PER_PARTICLE) * index);
-      taskQueue.emplace_back([&t = tasks.back()](uint32_t threadId)
-                             { t.Update(); });
+      taskQueue.emplace_back([&t = tasks.back()](uint32_t threadId) { t.Update(); });
     }
 
     // Execute worker tasks
@@ -430,8 +439,9 @@ bool ParticleRenderer::Initialize()
 
 void ParticleRenderer::PrepareToDie()
 {
-  if(mStreamBuffer)
+  if(DALI_LIKELY(Dali::Adaptor::IsAvailable()) && mStreamBuffer)
   {
+    // Note : MUST NOT call this API during app terminating
     mStreamBuffer.ClearVertexBufferUpdateCallback();
   }
 }