Fix rarely crash if NativeImage discarded after draw occured 94/320294/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 26 Feb 2025 07:36:50 +0000 (16:36 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 26 Feb 2025 08:44:57 +0000 (17:44 +0900)
It is possible s.t. DiscardNativeImage called before EndRenderPass called.

Until now, we remove the container directly. If this case,
the count of native texture dependency might be zero, so EndRenderPass logic
might be skipped!

To avoid this case, let we don't touch the contianer itself, and just mark
it as synced.

Change-Id: I3171493c0d72ccd58b7bdcacac47876ea32ed1d9
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/graphics/gles-impl/gles-texture-dependency-checker.cpp

index c6cf7b0933f422e1315e232307d767c43380b5b0..b925acab3cbd1a70563fd5a8eca0c85ee5f56581 100644 (file)
@@ -231,29 +231,25 @@ void TextureDependencyChecker::DiscardNativeTexture(const GLES::Texture* texture
   {
     for(uint32_t nativeIndex = 0u; nativeIndex < 2u; ++nativeIndex)
     {
-      for(auto iter = mNativeTextureDependencies[nativeIndex].begin(); iter != mNativeTextureDependencies[nativeIndex].end();)
+      for(auto iter = mNativeTextureDependencies[nativeIndex].begin(); iter != mNativeTextureDependencies[nativeIndex].end(); ++iter)
       {
         auto& nativeTextureDependency = *iter;
 
-        bool isErased = false;
-
         auto jter = nativeTextureDependency.textures.find(texture);
         if(jter != nativeTextureDependency.textures.end())
         {
           nativeTextureDependency.textures.erase(jter);
           if(nativeTextureDependency.textures.empty())
           {
+            DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::DiscardNativeTexture() invalidate sync object\n");
             mController.GetSyncPool().FreeSyncObject(nativeTextureDependency.agingSyncObjectId);
-            iter = mNativeTextureDependencies[nativeIndex].erase(iter);
+            nativeTextureDependency.agingSyncObjectId = INVALID_SYNC_OBJECT_ID;
+            nativeTextureDependency.synced            = true;
 
-            isErased = true;
+            // DevNote : Do not remove iter from mNativeTextureDependencies[nativeIndex].
+            // It might break logic if nativeIndex == mCurrentNativeTextureDependencyIndex
           }
         }
-
-        if(!isErased)
-        {
-          ++iter;
-        }
       }
     }
   }
@@ -281,7 +277,9 @@ void TextureDependencyChecker::CreateNativeTextureSync(const GLES::Context* curr
   // TODO : Optimize here. For now, we don't have too much EndPass call. So just keep this logic.
   for(auto& nativeTextureDependency : mNativeTextureDependencies[mCurrentNativeTextureDependencyIndex])
   {
-    if(nativeTextureDependency.writeContext == currentContext && nativeTextureDependency.agingSyncObjectId == INVALID_SYNC_OBJECT_ID)
+    if(nativeTextureDependency.writeContext == currentContext &&
+       DALI_LIKELY(!nativeTextureDependency.synced) &&
+       nativeTextureDependency.agingSyncObjectId == INVALID_SYNC_OBJECT_ID)
     {
       DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CreateNativeTextureSync(%p) Allocating sync object\n", currentContext);
       nativeTextureDependency.agingSyncObjectId = mController.GetSyncPool().AllocateSyncObject(currentContext, SyncPool::SyncContext::EGL);