Make PixelData flag that we release buffer after texture upload 58/303858/2
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 8 Jan 2024 01:02:08 +0000 (10:02 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Mon, 8 Jan 2024 13:32:24 +0000 (22:32 +0900)
Let we support to release pixel data memory automatically after upload finished.

Change-Id: I809289ca5124ba5672a5f87ba1f5772511b5054b
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.cpp
automated-tests/src/dali/utc-Dali-PixelData.cpp
automated-tests/src/dali/utc-Dali-Texture.cpp
dali/integration-api/pixel-data-integ.cpp
dali/integration-api/pixel-data-integ.h
dali/internal/event/images/pixel-data-impl.cpp
dali/internal/event/images/pixel-data-impl.h
dali/public-api/images/pixel-data.cpp

index 30a759d..4950bbd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -15,6 +15,7 @@
  */
 
 #include "test-graphics-texture.h"
+#include <dali/integration-api/pixel-data-integ.h>
 #include <iostream>
 #include <sstream>
 
@@ -935,26 +936,74 @@ void TestGraphicsTexture::Update(Graphics::TextureUpdateInfo updateInfo, Graphic
                         updateInfo.srcExtent2D.width != (mCreateInfo.size.width / (1 << updateInfo.level)) ||
                         updateInfo.srcExtent2D.height != (mCreateInfo.size.height / (1 << updateInfo.level)));
 
+  uint8_t* pixels        = nullptr;
+  bool     releasePixels = false;
+
+  switch(source.sourceType)
+  {
+    case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA:
+    {
+      auto pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(source.pixelDataSource.pixelData);
+
+      pixels        = pixelDataBuffer.buffer;
+      releasePixels = Dali::Integration::IsPixelDataReleaseAfterUpload(source.pixelDataSource.pixelData) && updateInfo.srcOffset == 0u;
+      break;
+    }
+    case Graphics::TextureUpdateSourceInfo::Type::MEMORY:
+    {
+      pixels        = reinterpret_cast<uint8_t*>(source.memorySource.memory);
+      releasePixels = true;
+      break;
+    }
+    default:
+    {
+      // TODO : Implement here
+      break;
+    }
+  }
+
   if(!isSubImage)
   {
     if(!mIsCompressed)
     {
-      mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, source.memorySource.memory);
+      mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, pixels);
     }
     else
     {
-      mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, source.memorySource.memory);
+      mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, pixels);
     }
   }
   else
   {
     if(!mIsCompressed)
     {
-      mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, source.memorySource.memory);
+      mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, pixels);
     }
     else
     {
-      mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, source.memorySource.memory);
+      mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, pixels);
+    }
+  }
+
+  if(releasePixels && pixels != nullptr)
+  {
+    switch(source.sourceType)
+    {
+      case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA:
+      {
+        Dali::Integration::ReleasePixelDataBuffer(source.pixelDataSource.pixelData);
+        break;
+      }
+      case Graphics::TextureUpdateSourceInfo::Type::MEMORY:
+      {
+        free(reinterpret_cast<void*>(pixels));
+        break;
+      }
+      default:
+      {
+        // TODO : Implement here
+        break;
+      }
     }
   }
 }
index 5454954..8786291 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -239,7 +239,7 @@ int UtcDaliPixelDataGetHeightNegative(void)
   END_TEST;
 }
 
-int UtcDaliPixelDataReleasePixelDataBuffer(void)
+int UtcDaliPixelDataGetPixelDataBuffer(void)
 {
   TestApplication application;
 
@@ -258,20 +258,17 @@ int UtcDaliPixelDataReleasePixelDataBuffer(void)
   DALI_TEST_CHECK(pixelData.GetStride() == stride);
   DALI_TEST_CHECK(pixelData.GetPixelFormat() == Pixel::L8);
 
-  Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::ReleasePixelDataBuffer(pixelData);
+  Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
 
-  DALI_TEST_CHECK(!pixelData);
+  DALI_TEST_CHECK(pixelData);
 
   DALI_TEST_EQUALS(pixelDataBuffer.bufferSize, bufferSize, TEST_LOCATION);
   DALI_TEST_EQUALS(pixelDataBuffer.buffer[0], static_cast<uint8_t>('a'), TEST_LOCATION);
 
-  // Release memory by our self.
-  delete[] pixelDataBuffer.buffer;
-
   END_TEST;
 }
 
-int UtcDaliPixelDataGetPixelDataBuffer(void)
+int UtcDaliPixelDataReleasePixelDataBuffer(void)
 {
   TestApplication application;
 
@@ -290,9 +287,36 @@ int UtcDaliPixelDataGetPixelDataBuffer(void)
   DALI_TEST_CHECK(pixelData.GetStride() == stride);
   DALI_TEST_CHECK(pixelData.GetPixelFormat() == Pixel::L8);
 
+  Dali::Integration::ReleasePixelDataBuffer(pixelData);
+
   Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
 
+  DALI_TEST_CHECK(pixelDataBuffer.buffer == nullptr);
+
+  END_TEST;
+}
+
+int UtcDaliPixelDataNewPixelDataWithReleaseAfterUpload(void)
+{
+  TestApplication application;
+
+  uint32_t width      = 10u;
+  uint32_t height     = 10u;
+  uint32_t stride     = 12u;
+  uint32_t bufferSize = stride * height * Pixel::GetBytesPerPixel(Pixel::L8);
+  uint8_t* buffer     = new uint8_t[bufferSize];
+  buffer[0]           = 'a';
+
+  PixelData pixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(buffer, bufferSize, width, height, stride, Pixel::L8, PixelData::DELETE_ARRAY);
+
   DALI_TEST_CHECK(pixelData);
+  DALI_TEST_CHECK(pixelData.GetWidth() == width);
+  DALI_TEST_CHECK(pixelData.GetHeight() == height);
+  DALI_TEST_CHECK(pixelData.GetStride() == stride);
+  DALI_TEST_CHECK(pixelData.GetPixelFormat() == Pixel::L8);
+  DALI_TEST_EQUALS(Dali::Integration::IsPixelDataReleaseAfterUpload(pixelData), true, TEST_LOCATION);
+
+  Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
 
   DALI_TEST_EQUALS(pixelDataBuffer.bufferSize, bufferSize, TEST_LOCATION);
   DALI_TEST_EQUALS(pixelDataBuffer.buffer[0], static_cast<uint8_t>('a'), TEST_LOCATION);
index 1043cdc..8bbbdaa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -17,6 +17,7 @@
 
 #include <dali-test-suite-utils.h>
 #include <dali/devel-api/rendering/texture-devel.h>
+#include <dali/integration-api/pixel-data-integ.h>
 #include <dali/integration-api/texture-integ.h>
 #include <dali/public-api/dali-core.h>
 #include <test-native-image.h>
@@ -755,6 +756,57 @@ int UtcDaliTextureUpload08(void)
   END_TEST;
 }
 
+int UtcDaliTextureUpload09(void)
+{
+  TestApplication application;
+
+  //Create the texture
+  uint32_t width(64u);
+  uint32_t height(64u);
+  Texture  texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+
+  application.GetGlAbstraction().EnableTextureCallTrace(true);
+
+  application.SendNotification();
+  application.Render();
+
+  TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+
+  //Upload data to the texture
+  callStack.Reset();
+
+  uint32_t bufferSize(width * height * 4u);
+  uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  buffer[0]       = 'a';
+
+  PixelData pixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(buffer, bufferSize, width, height, 0u, Pixel::RGBA8888, PixelData::FREE);
+  DALI_TEST_CHECK(pixelData);
+
+  Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+
+  DALI_TEST_EQUALS(pixelDataBuffer.bufferSize, bufferSize, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelDataBuffer.buffer[0], static_cast<uint8_t>('a'), TEST_LOCATION);
+
+  texture.Upload(pixelData);
+
+  application.SendNotification();
+  application.Render();
+
+  //TexImage2D should be called to upload the data
+  {
+    std::stringstream out;
+    out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
+    DALI_TEST_CHECK(callStack.FindMethodAndParams("TexImage2D", out.str().c_str()));
+  }
+
+  // Check whether the buffer become nullptr after texture uploaded.
+  pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+
+  DALI_TEST_CHECK(pixelDataBuffer.buffer == nullptr);
+
+  END_TEST;
+}
+
 int UtcDaliTextureUploadSubPixelData01(void)
 {
   TestApplication application;
index 2e7888c..5853eb7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
 
 namespace Dali::Integration
 {
-PixelDataBuffer ReleasePixelDataBuffer(Dali::PixelData& pixelData)
+void ReleasePixelDataBuffer(Dali::PixelData pixelData)
 {
-  Internal::PixelData& pixelDataImpl   = GetImplementation(pixelData);
-  PixelDataBuffer      pixelDataBuffer = pixelDataImpl.ReleasePixelDataBuffer();
-  pixelData.Reset();
-  return pixelDataBuffer;
+  Internal::PixelData& pixelDataImpl = GetImplementation(pixelData);
+  pixelDataImpl.ReleasePixelDataBuffer();
 }
 
 PixelDataBuffer GetPixelDataBuffer(const Dali::PixelData& pixelData)
@@ -37,4 +35,22 @@ PixelDataBuffer GetPixelDataBuffer(const Dali::PixelData& pixelData)
   PixelDataBuffer            pixelDataBuffer = pixelDataImpl.GetPixelDataBuffer();
   return pixelDataBuffer;
 }
+
+Dali::PixelData NewPixelDataWithReleaseAfterUpload(uint8_t*                   buffer,
+                                                   uint32_t                   bufferSize,
+                                                   uint32_t                   width,
+                                                   uint32_t                   height,
+                                                   uint32_t                   stride,
+                                                   Pixel::Format              pixelFormat,
+                                                   PixelData::ReleaseFunction releaseFunction)
+{
+  IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction, true);
+  return PixelData(internal.Get());
+}
+
+bool IsPixelDataReleaseAfterUpload(const Dali::PixelData& pixelData)
+{
+  const Internal::PixelData& pixelDataImpl = GetImplementation(pixelData);
+  return pixelDataImpl.IsPixelDataReleaseAfterUpload();
+}
 } // namespace Dali::Integration
index cd7358f..0f7898b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_PIXEL_DATA_INTEG_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.
@@ -36,27 +36,31 @@ namespace Dali::Integration
  */
 struct PixelDataBuffer
 {
-  uint8_t*                         buffer;
-  uint32_t                         bufferSize;
-  Dali::PixelData::ReleaseFunction releaseFunction;
+  uint8_t* buffer;
+  uint32_t bufferSize;
+  uint32_t width;
+  uint32_t height;
+  uint32_t stride;
 
-  PixelDataBuffer(uint8_t*                         buffer,
-                  uint32_t                         bufferSize,
-                  Dali::PixelData::ReleaseFunction releaseFunction)
+  PixelDataBuffer(uint8_t* buffer,
+                  uint32_t bufferSize,
+                  uint32_t width,
+                  uint32_t height,
+                  uint32_t stride = 0)
   : buffer(buffer),
     bufferSize(bufferSize),
-    releaseFunction(releaseFunction)
+    width(width),
+    height(height),
+    stride(stride)
   {
   }
 };
 
 /**
- * Get the buffer from a pixel data object, zero it in the pixel data object
- * and release the handle.
- * @param[in,out] pixelData The pixel data object to take the buffer from
- * @return the buffer and the data release mechanism
+ * Release the buffer from a pixel data object, zero it in the pixel data object.
+ * @param[in] pixelData The pixel data object to take the buffer from
  */
-DALI_CORE_API PixelDataBuffer ReleasePixelDataBuffer(Dali::PixelData& pixelData);
+DALI_CORE_API void ReleasePixelDataBuffer(Dali::PixelData pixelData);
 
 /**
  * Get the buffer from a pixel data object.
@@ -65,6 +69,26 @@ DALI_CORE_API PixelDataBuffer ReleasePixelDataBuffer(Dali::PixelData& pixelData)
  */
 DALI_CORE_API PixelDataBuffer GetPixelDataBuffer(const Dali::PixelData& pixelData);
 
+/**
+ * Creates a PixelData object which will release the buffer automatically after upload to texture.
+ * @return The pixel data object.
+ */
+DALI_CORE_API Dali::PixelData NewPixelDataWithReleaseAfterUpload(uint8_t*                   buffer,
+                                                                 uint32_t                   bufferSize,
+                                                                 uint32_t                   width,
+                                                                 uint32_t                   height,
+                                                                 uint32_t                   stride,
+                                                                 Pixel::Format              pixelFormat,
+                                                                 PixelData::ReleaseFunction releaseFunction);
+
+/**
+ * Get whether we need to release pixel data after texture upload or not.
+ * @note This function can be called from another thread. Be careful about thread safety.
+ * @param[in] pixelData The pixel data object to get the release policy.
+ * @return True if we need to release pixel data after texture upload. False otherwise.
+ */
+DALI_CORE_API bool IsPixelDataReleaseAfterUpload(const Dali::PixelData& pixelData);
+
 } // namespace Dali::Integration
 
 #endif // DALI_PIXEL_DATA_INTEG_H
index 4dc28bf..577c9b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -39,14 +39,16 @@ PixelData::PixelData(uint8_t*                         buffer,
                      uint32_t                         height,
                      uint32_t                         stride,
                      Pixel::Format                    pixelFormat,
-                     Dali::PixelData::ReleaseFunction releaseFunction)
+                     Dali::PixelData::ReleaseFunction releaseFunction,
+                     bool                             releaseAfterUpload)
 : mBuffer(buffer),
   mBufferSize(bufferSize),
   mWidth(width),
   mHeight(height),
   mStride(stride),
   mPixelFormat(pixelFormat),
-  mReleaseFunction(releaseFunction)
+  mReleaseFunction(releaseFunction),
+  mReleaseAfterUpload(releaseAfterUpload)
 {
   DALI_LOG_INFO(gPixelDataLogFilter, Debug::Concise, "Allocated PixelData of size %u\n", bufferSize);
 #if defined(DEBUG_ENABLED)
@@ -56,20 +58,7 @@ PixelData::PixelData(uint8_t*                         buffer,
 
 PixelData::~PixelData()
 {
-  if(mBuffer)
-  {
-    if(mReleaseFunction == Dali::PixelData::FREE)
-    {
-      free(mBuffer);
-    }
-    else
-    {
-      delete[] mBuffer;
-    }
-#if defined(DEBUG_ENABLED)
-    gPixelDataAllocationTotal -= mBufferSize;
-#endif
-  }
+  ReleasePixelDataBuffer();
 }
 
 PixelDataPtr PixelData::New(uint8_t*                         buffer,
@@ -78,9 +67,10 @@ PixelDataPtr PixelData::New(uint8_t*                         buffer,
                             uint32_t                         height,
                             uint32_t                         stride,
                             Pixel::Format                    pixelFormat,
-                            Dali::PixelData::ReleaseFunction releaseFunction)
+                            Dali::PixelData::ReleaseFunction releaseFunction,
+                            bool                             releaseAfterUpload)
 {
-  return new PixelData(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction);
+  return new PixelData(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction, releaseAfterUpload);
 }
 
 uint32_t PixelData::GetWidth() const
@@ -108,16 +98,28 @@ uint32_t PixelData::GetBufferSize() const
   return mBufferSize;
 }
 
-Dali::Integration::PixelDataBuffer PixelData::ReleasePixelDataBuffer()
+void PixelData::ReleasePixelDataBuffer()
 {
-  Dali::Integration::PixelDataBuffer pixelDataBuffer(mBuffer, mBufferSize, mReleaseFunction);
-  mBuffer = nullptr;
-  return pixelDataBuffer;
+  if(mBuffer)
+  {
+    if(mReleaseFunction == Dali::PixelData::FREE)
+    {
+      free(mBuffer);
+    }
+    else
+    {
+      delete[] mBuffer;
+    }
+    mBuffer = nullptr;
+#if defined(DEBUG_ENABLED)
+    gPixelDataAllocationTotal -= mBufferSize;
+#endif
+  }
 }
 
 Dali::Integration::PixelDataBuffer PixelData::GetPixelDataBuffer() const
 {
-  Dali::Integration::PixelDataBuffer pixelDataBuffer(mBuffer, mBufferSize, mReleaseFunction);
+  Dali::Integration::PixelDataBuffer pixelDataBuffer(mBuffer, mBufferSize, mWidth, mHeight, mStride);
   return pixelDataBuffer;
 }
 
index a5b26c5..2672a80 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_PIXEL_DATA_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.
@@ -44,6 +44,7 @@ public:
    * @param [in] stride           Buffer stride in pixels, 0 means the buffer is tightly packed
    * @param [in] pixelFormat      The pixel format
    * @param [in] releaseFunction  The function used to release the memory.
+   * @param [in] releaseAfterUpload Whether we release buffer after texture upload or not.
    */
   static PixelDataPtr New(uint8_t*                         buffer,
                           uint32_t                         bufferSize,
@@ -51,18 +52,20 @@ public:
                           uint32_t                         height,
                           uint32_t                         stride,
                           Pixel::Format                    pixelFormat,
-                          Dali::PixelData::ReleaseFunction releaseFunction);
+                          Dali::PixelData::ReleaseFunction releaseFunction,
+                          bool                             releaseAfterUpload);
 
   /**
    * @brief Constructor.
    *
-   * @param [in] buffer           The raw pixel data.
-   * @param [in] bufferSize       The size of the buffer in bytes
-   * @param [in] width            Buffer width in pixels
-   * @param [in] height           Buffer height in pixels
-   * @param [in] stride           Buffer stride in pixels, 0 means the buffer is tightly packed
-   * @param [in] pixelFormat      The pixel format
-   * @param [in] releaseFunction  The function used to release the memory.
+   * @param [in] buffer             The raw pixel data.
+   * @param [in] bufferSize         The size of the buffer in bytes
+   * @param [in] width              Buffer width in pixels
+   * @param [in] height             Buffer height in pixels
+   * @param [in] stride             Buffer stride in pixels, 0 means the buffer is tightly packed
+   * @param [in] pixelFormat        The pixel format
+   * @param [in] releaseFunction    The function used to release the memory.
+   * @param [in] releaseAfterUpload Whether we release buffer after texture upload or not.
    */
   PixelData(uint8_t*                         buffer,
             uint32_t                         bufferSize,
@@ -70,7 +73,8 @@ public:
             uint32_t                         height,
             uint32_t                         stride,
             Pixel::Format                    pixelFormat,
-            Dali::PixelData::ReleaseFunction releaseFunction);
+            Dali::PixelData::ReleaseFunction releaseFunction,
+            bool                             releaseAfterUpload);
 
 protected:
   /**
@@ -112,10 +116,9 @@ public:
   uint32_t GetBufferSize() const;
 
   /**
-   * Return the buffer pointer and reset the internal buffer to zero.
-   * @return The buffer pointer and associated data.
+   * Release the buffer data and reset the internal buffer to zero.
    */
-  Dali::Integration::PixelDataBuffer ReleasePixelDataBuffer();
+  void ReleasePixelDataBuffer();
 
   /**
    * Return the buffer pointer.
@@ -124,6 +127,16 @@ public:
   Dali::Integration::PixelDataBuffer GetPixelDataBuffer() const;
 
   /**
+   * Get whether we need to release pixel data after texture upload or not.
+   * @note This function can be called from another thread. Be careful.
+   * @return True if we need to release pixel data after texture upload. False otherwise.
+   */
+  bool IsPixelDataReleaseAfterUpload() const
+  {
+    return mReleaseAfterUpload;
+  }
+
+  /**
    * @copydoc PixelData::GetStride()
    */
   uint32_t GetStride() const;
@@ -160,6 +173,8 @@ private:
   Pixel::Format                    mPixelFormat;     ///< Pixel format
   Dali::PixelData::ReleaseFunction mReleaseFunction; ///< Function for releasing memory
 
+  const bool mReleaseAfterUpload;
+
 #if defined(DEBUG_ENABLED)
   static uint32_t gPixelDataAllocationTotal;
 #endif
index e69ccf4..3900849 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 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.
@@ -30,7 +30,7 @@ PixelData PixelData::New(uint8_t*        buffer,
                          Pixel::Format   pixelFormat,
                          ReleaseFunction releaseFunction)
 {
-  IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, 0, pixelFormat, releaseFunction);
+  IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, 0, pixelFormat, releaseFunction, false);
   return PixelData(internal.Get());
 }
 
@@ -42,7 +42,7 @@ PixelData PixelData::New(uint8_t*        buffer,
                          Pixel::Format   pixelFormat,
                          ReleaseFunction releaseFunction)
 {
-  IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction);
+  IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction, false);
   return PixelData(internal.Get());
 }