Merge "Add FreeReleasedBuffers method to NativeImageSourceQueue" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / tizen / native-image-source-queue-impl-tizen.cpp
index 107f4cd..b5d926b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
@@ -24,6 +24,7 @@
 #include <tbm_surface_internal.h>
 
 // INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/environment-variable.h>
 #include <dali/internal/adaptor/common/adaptor-impl.h>
 #include <dali/internal/graphics/common/egl-image-extensions.h>
 #include <dali/internal/graphics/gles/egl-graphics.h>
@@ -36,10 +37,6 @@ namespace Adaptor
 {
 namespace
 {
-#define TBM_SURFACE_QUEUE_SIZE 3
-
-const char* SAMPLER_TYPE    = "samplerExternalOES";
-
 // clang-format off
 int FORMATS_BLENDING_REQUIRED[] = {
   TBM_FORMAT_ARGB4444, TBM_FORMAT_ABGR4444,
@@ -54,7 +51,19 @@ int FORMATS_BLENDING_REQUIRED[] = {
 };
 // clang-format on
 
-const int NUM_FORMATS_BLENDING_REQUIRED = 18;
+const char* SAMPLER_TYPE = "samplerExternalOES";
+
+constexpr int32_t NUM_FORMATS_BLENDING_REQUIRED = 18;
+
+constexpr int32_t DEFAULT_TBM_SURFACE_QUEUE_SIZE = 3u;
+constexpr auto    TBM_SURFACE_QUEUE_SIZE         = "DALI_TBM_SURFACE_QUEUE_SIZE";
+
+int32_t GetTbmSurfaceQueueSize()
+{
+  static auto    queueSizeString = EnvironmentVariable::GetEnvironmentVariable(TBM_SURFACE_QUEUE_SIZE);
+  static int32_t queueSize       = queueSizeString ? std::atoi(queueSizeString) : DEFAULT_TBM_SURFACE_QUEUE_SIZE;
+  return queueSize;
+}
 
 } // namespace
 
@@ -83,7 +92,8 @@ NativeImageSourceQueueTizen::NativeImageSourceQueueTizen(uint32_t width, uint32_
   mEglImageExtensions(NULL),
   mOwnTbmQueue(false),
   mBlendingRequired(false),
-  mIsResized(false)
+  mIsResized(false),
+  mFreeRequest(false)
 {
   DALI_ASSERT_ALWAYS(Adaptor::IsAvailable());
 
@@ -124,19 +134,22 @@ void NativeImageSourceQueueTizen::Initialize(Dali::NativeImageSourceQueue::Color
 
     switch(colorFormat)
     {
-      case Dali::NativeImageSourceQueue::ColorFormat::RGBA8888:
+      case Dali::NativeImageSourceQueue::ColorFormat::RGBA8888: // TODO : Implement me after other codes fixed.
+      case Dali::NativeImageSourceQueue::ColorFormat::BGRA8888:
       {
         tbmFormat         = TBM_FORMAT_ARGB8888;
         mBlendingRequired = true;
         break;
       }
-      case Dali::NativeImageSourceQueue::ColorFormat::RGBX8888:
+      case Dali::NativeImageSourceQueue::ColorFormat::RGBX8888: // TODO : Implement me after other codes fixed.
+      case Dali::NativeImageSourceQueue::ColorFormat::BGRX8888:
       {
         tbmFormat         = TBM_FORMAT_XRGB8888;
         mBlendingRequired = false;
         break;
       }
-      case Dali::NativeImageSourceQueue::ColorFormat::RGB888:
+      case Dali::NativeImageSourceQueue::ColorFormat::RGB888: // TODO : Implement me after other codes fixed.
+      case Dali::NativeImageSourceQueue::ColorFormat::BGR888:
       {
         tbmFormat         = TBM_FORMAT_RGB888;
         mBlendingRequired = false;
@@ -149,7 +162,7 @@ void NativeImageSourceQueueTizen::Initialize(Dali::NativeImageSourceQueue::Color
       }
     }
 
-    mTbmQueue = tbm_surface_queue_create(TBM_SURFACE_QUEUE_SIZE, mWidth, mHeight, tbmFormat, 0);
+    mTbmQueue = tbm_surface_queue_create(GetTbmSurfaceQueueSize(), mWidth, mHeight, tbmFormat, 0);
     if(!mTbmQueue)
     {
       DALI_LOG_ERROR("NativeImageSourceQueueTizen::Initialize: tbm_surface_queue_create is failed! [%p]\n", mTbmQueue);
@@ -290,6 +303,12 @@ bool NativeImageSourceQueueTizen::EnqueueBuffer(uint8_t* buffer)
   return false;
 }
 
+void NativeImageSourceQueueTizen::FreeReleasedBuffers()
+{
+  Dali::Mutex::ScopedLock lock(mMutex);
+  mFreeRequest = true;
+}
+
 bool NativeImageSourceQueueTizen::CreateResource()
 {
   mEglImageExtensions = mEglGraphics->GetImageExtensions();
@@ -314,24 +333,37 @@ void NativeImageSourceQueueTizen::PrepareTexture()
 {
   Dali::Mutex::ScopedLock lock(mMutex);
 
-  tbm_surface_h oldSurface = mConsumeSurface;
+  bool updated = false;
 
-  if(tbm_surface_queue_can_acquire(mTbmQueue, 0))
+  do
   {
-    if(tbm_surface_queue_acquire(mTbmQueue, &mConsumeSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
-    {
-      DALI_LOG_ERROR("Failed to aquire a tbm_surface\n");
-      return;
-    }
+    tbm_surface_h oldSurface = mConsumeSurface;
 
-    if(oldSurface)
+    if(tbm_surface_queue_can_acquire(mTbmQueue, 0))
     {
-      if(tbm_surface_internal_is_valid(oldSurface))
+      if(tbm_surface_queue_acquire(mTbmQueue, &mConsumeSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
       {
-        tbm_surface_queue_release(mTbmQueue, oldSurface);
+        DALI_LOG_ERROR("Failed to aquire a tbm_surface\n");
+        return;
+      }
+
+      if(oldSurface)
+      {
+        if(tbm_surface_internal_is_valid(oldSurface))
+        {
+          tbm_surface_queue_release(mTbmQueue, oldSurface);
+        }
       }
+      updated = true;
     }
+    else
+    {
+      break;
+    }
+  } while(mFreeRequest); // Get the last one if buffer free was requested
 
+  if(updated)
+  {
     if(mIsResized)
     {
       ResetEglImageList(false);
@@ -364,6 +396,19 @@ void NativeImageSourceQueueTizen::PrepareTexture()
       }
     }
   }
+
+  if(mFreeRequest)
+  {
+    auto iter = std::remove_if(mEglImages.begin(), mEglImages.end(), [&](EglImagePair& eglImage) {
+        if(mConsumeSurface == eglImage.first) return false;
+        mEglImageExtensions->DestroyImageKHR(eglImage.second);
+        tbm_surface_internal_unref(eglImage.first);
+        return true; });
+    mEglImages.erase(iter, mEglImages.end());
+
+    tbm_surface_queue_free_flush(mTbmQueue);
+    mFreeRequest = false;
+  }
 }
 
 bool NativeImageSourceQueueTizen::ApplyNativeFragmentShader(std::string& shader)
@@ -415,7 +460,7 @@ void NativeImageSourceQueueTizen::ResetEglImageList(bool releaseConsumeSurface)
 
 bool NativeImageSourceQueueTizen::CheckBlending(int format)
 {
-  for(int i = 0; i < NUM_FORMATS_BLENDING_REQUIRED; ++i)
+  for(int32_t i = 0; i < NUM_FORMATS_BLENDING_REQUIRED; ++i)
   {
     if(format == FORMATS_BLENDING_REQUIRED[i])
     {