[Scene3D] Let we allow to release PixelData memory after upload for 3D cache 14/303914/3
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 8 Jan 2024 04:35:28 +0000 (13:35 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Mon, 8 Jan 2024 14:16:50 +0000 (23:16 +0900)
Since we use PixelData as key of cached Texture, it might make some
CPU memory allocated even if we upload finished.

To avoid this behavior, let we make PixelData release memory
after upload to Texture for Scene3D case.

Change-Id: Id43e92d5b4a816fe76890c7ca58f6c43b6dab761
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-texture.cpp
dali-scene3d/internal/common/image-resource-loader.cpp
dali-scene3d/internal/common/image-resource-loader.h
dali-scene3d/internal/controls/model/model-impl.cpp
dali-scene3d/internal/controls/model/model-impl.h
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-scene3d/internal/model-components/model-primitive-impl.cpp
dali-scene3d/public-api/loader/environment-map-loader.cpp
dali-scene3d/public-api/loader/ktx-loader.cpp
dali-scene3d/public-api/loader/material-definition.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 99b7ed5..3403cfa 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.
 #include <dali-scene3d/internal/common/image-resource-loader.h>
 
 // EXTERNAL INCLUDES
-#include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
 #include <dali/devel-api/common/hash.h>
 #include <dali/devel-api/common/map-wrapper.h>
 #include <dali/devel-api/threading/mutex.h>
 #include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/pixel-data-integ.h>
 #include <dali/public-api/adaptor-framework/timer.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/object/base-object.h>
@@ -48,6 +50,41 @@ constexpr uint32_t GC_PERIOD_MILLISECONDS                     = 1000u;
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_IMAGE_RESOURCE_LOADER");
 #endif
 
+bool SupportPixelDataCache(Dali::PixelData pixelData)
+{
+  // Check given pixelData support to release data after upload.
+  // This is cause we need to reduce CPU memory usage.
+  if(Dali::Integration::IsPixelDataReleaseAfterUpload(pixelData))
+  {
+    return true;
+  }
+
+  // Check given pixelData is default pixelData.
+  if(pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGB() ||
+     pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGBA() ||
+     pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisRGB() ||
+     pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisAndAlphaRGBA())
+  {
+    return true;
+  }
+  return false;
+}
+
+bool SupportPixelDataListCache(const std::vector<std::vector<Dali::PixelData>>& pixelDataList)
+{
+  for(const auto& pixelDataListLevel0 : pixelDataList)
+  {
+    for(const auto& pixelData : pixelDataListLevel0)
+    {
+      if(!SupportPixelDataCache(pixelData))
+      {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
 struct ImageInformation
 {
   ImageInformation(const std::string           url,
@@ -132,9 +169,17 @@ std::size_t GenerateHash(const std::vector<std::vector<Dali::PixelData>>& pixelD
 
 // Item Creation functor list
 
-Dali::PixelData CreatePixelDataFromImageInfo(const ImageInformation& info, bool /* Not used */)
+Dali::PixelData CreatePixelDataFromImageInfo(const ImageInformation& info, bool releasePixelData)
 {
-  return Dali::Toolkit::SyncImageLoader::Load(info.mUrl, info.mDimensions, info.mFittingMode, info.mSamplingMode, info.mOrientationCorrection);
+  Dali::PixelData pixelData;
+
+  // Load the image synchronously (block the thread here).
+  Dali::Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile(info.mUrl, info.mDimensions, info.mFittingMode, info.mSamplingMode, info.mOrientationCorrection);
+  if(pixelBuffer)
+  {
+    pixelData = Dali::Devel::PixelBuffer::Convert(pixelBuffer, releasePixelData);
+  }
+  return pixelData;
 }
 
 Dali::Texture CreateTextureFromPixelData(const Dali::PixelData& pixelData, bool mipmapRequired)
@@ -439,12 +484,13 @@ public: // Can be called by worker thread
    * @brief Try to get cached pixel data, or newly create if there is no pixel data that already cached.
    *
    * @param[in] info The informations of image to load.
+   * @param[in] releasePixelData Whether we need to release pixel data after upload, or not.
    * @return Texture that has been cached. Or empty handle if we fail to found cached item.
    */
-  Dali::PixelData GetOrCreateCachedPixelData(const ImageInformation& info)
+  Dali::PixelData GetOrCreateCachedPixelData(const ImageInformation& info, bool releasePixelData)
   {
     auto hashValue = GenerateHash(info);
-    return GetOrCreateCachedItem<true, ImageInformation, Dali::PixelData, CreatePixelDataFromImageInfo>(mPixelDataCache, hashValue, info, false, mPixelDataContainerUpdated);
+    return GetOrCreateCachedItem<true, ImageInformation, Dali::PixelData, CreatePixelDataFromImageInfo>(mPixelDataCache, hashValue, info, releasePixelData, mPixelDataContainerUpdated);
   }
 
 private: // Called by main thread
@@ -532,12 +578,6 @@ namespace Dali::Scene3D::Internal
 namespace ImageResourceLoader
 {
 // Called by main thread..
-Dali::PixelData GetEmptyPixelDataWhiteRGB()
-{
-  static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
-  return emptyPixelData;
-}
-
 Dali::Texture GetEmptyTextureWhiteRGB()
 {
   if(!gEmptyTextureWhiteRGB)
@@ -551,12 +591,26 @@ Dali::Texture GetEmptyTextureWhiteRGB()
 
 Dali::Texture GetCachedTexture(Dali::PixelData pixelData, bool mipmapRequired)
 {
-  return GetCacheImpl()->GetOrCreateCachedTexture(pixelData, mipmapRequired);
+  if(SupportPixelDataCache(pixelData))
+  {
+    return GetCacheImpl()->GetOrCreateCachedTexture(pixelData, mipmapRequired);
+  }
+  else
+  {
+    return CreateTextureFromPixelData(pixelData, mipmapRequired);
+  }
 }
 
 Dali::Texture GetCachedCubeTexture(const std::vector<std::vector<Dali::PixelData>>& pixelDataList, bool mipmapRequired)
 {
-  return GetCacheImpl()->GetOrCreateCachedCubeTexture(pixelDataList, mipmapRequired);
+  if(SupportPixelDataListCache(pixelDataList))
+  {
+    return GetCacheImpl()->GetOrCreateCachedCubeTexture(pixelDataList, mipmapRequired);
+  }
+  else
+  {
+    return CreateCubeTextureFromPixelDataList(pixelDataList, mipmapRequired);
+  }
 }
 
 void RequestGarbageCollect(bool fullCollect)
@@ -570,6 +624,30 @@ void EnsureResourceLoaderCreated()
 }
 
 // Can be called by worker thread.
+Dali::PixelData GetEmptyPixelDataWhiteRGB()
+{
+  static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
+  return emptyPixelData;
+}
+
+Dali::PixelData GetEmptyPixelDataWhiteRGBA()
+{
+  static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[4]{0xff, 0xff, 0xff, 0xff}, 4, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY);
+  return emptyPixelData;
+}
+
+Dali::PixelData GetEmptyPixelDataZAxisRGB()
+{
+  static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[3]{0x7f, 0x7f, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
+  return emptyPixelData;
+}
+
+Dali::PixelData GetEmptyPixelDataZAxisAndAlphaRGBA()
+{
+  static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[4]{0x7f, 0x7f, 0xff, 0xff}, 4, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY);
+  return emptyPixelData;
+}
+
 Dali::PixelData GetCachedPixelData(const std::string& url)
 {
   return GetCachedPixelData(url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true);
@@ -589,7 +667,7 @@ Dali::PixelData GetCachedPixelData(const std::string& url,
   }
   else
   {
-    return GetCacheImpl()->GetOrCreateCachedPixelData(info);
+    return GetCacheImpl()->GetOrCreateCachedPixelData(info, true);
   }
 }
 } // namespace ImageResourceLoader
index ee6d048..df0d9e7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_SCENE3D_IMAGE_RESOURCE_LOADER_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.
@@ -83,6 +83,24 @@ void EnsureResourceLoaderCreated();
 Dali::PixelData GetEmptyPixelDataWhiteRGB();
 
 /**
+ * @brief Get cached pixelData handle filled as white with RGBA8888 format.
+ * @return A PixelData object containing the white RGBA8888 color.
+ */
+Dali::PixelData GetEmptyPixelDataWhiteRGBA();
+
+/**
+ * @brief Get cached pixelData handle that will be used for Z-Axis with RGB8888 format.
+ * @return A PixelData object containing the Z-Axis RGB8888 color.
+ */
+Dali::PixelData GetEmptyPixelDataZAxisRGB();
+
+/**
+ * @brief Get cached pixelData handle that will be used for Z-Axis and 1.0 alpha with RGBA8888 format.
+ * @return A PixelData object containing the Z-Axis and 1.0 alpha RGBA8888 color.
+ */
+Dali::PixelData GetEmptyPixelDataZAxisAndAlphaRGBA();
+
+/**
  * @brief Get cached image, or loads an image synchronously.
  * @note If cache handler is not created yet, or destroyed due to app terminated, it will load image synchronously without cache.
  * @param[in] url The URL of the image file to load
index 78cc718..e3e5b91 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.
@@ -235,6 +235,16 @@ void UpdateShadowMapTextureRecursively(Scene3D::ModelNode node, Dali::Texture sh
   }
 }
 
+void ResetResourceTask(IntrusivePtr<AsyncTask>&& asyncTask)
+{
+  if(!asyncTask)
+  {
+    return;
+  }
+  Dali::AsyncTaskManager::Get().RemoveTask(asyncTask);
+  asyncTask.Reset();
+}
+
 } // anonymous namespace
 
 Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl)
@@ -446,6 +456,9 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s
     mDiffuseTexture.Reset();
     mSpecularTexture.Reset();
     UpdateImageBasedLightTexture();
+
+    // Request image resource GC
+    Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
   }
   else
   {
@@ -455,6 +468,9 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s
       mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblDiffuseLoadComplete));
       Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask);
       mIblDiffuseDirty = false;
+
+      // Request image resource GC
+      Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
     }
 
     if(isOnScene && mIblSpecularDirty)
@@ -463,6 +479,9 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s
       mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblSpecularLoadComplete));
       Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask);
       mIblSpecularDirty = false;
+
+      // Request image resource GC
+      Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
     }
   }
 
@@ -1203,16 +1222,6 @@ void Model::ResetResourceTasks()
   ResetResourceTask(mIblSpecularLoadTask);
 }
 
-void Model::ResetResourceTask(IntrusivePtr<AsyncTask> asyncTask)
-{
-  if(!asyncTask)
-  {
-    return;
-  }
-  Dali::AsyncTaskManager::Get().RemoveTask(asyncTask);
-  asyncTask.Reset();
-}
-
 void Model::NotifyResourceReady()
 {
   if(!IsResourceReady())
index 2e78f78..5a9633b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_SCENE3D_INTERNAL_MODEL_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.
@@ -371,11 +371,6 @@ private:
   void ResetResourceTasks();
 
   /**
-   * @brief Reset a Resource loading task.
-   */
-  void ResetResourceTask(IntrusivePtr<AsyncTask> asyncTask);
-
-  /**
    * @brief Notify Resource Ready signal.
    */
   void NotifyResourceReady();
index 2b4b498..190cd49 100644 (file)
@@ -37,6 +37,7 @@
 #include <string_view>
 
 // INTERNAL INCLUDES
+#include <dali-scene3d/internal/common/image-resource-loader.h>
 #include <dali-scene3d/internal/controls/model/model-impl.h>
 #include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
 #include <dali-scene3d/internal/light/light-impl.h>
@@ -325,6 +326,9 @@ SceneView::~SceneView()
       Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask);
       mSkyboxLoadTask.Reset();
     }
+
+    // Request image resource GC
+    Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
   }
 }
 
@@ -507,6 +511,9 @@ void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const st
 
     mSpecularMipmapLevels = 1u;
     NotifyImageBasedLightTextureChange();
+
+    // Request image resource GC
+    Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
   }
   else
   {
@@ -516,6 +523,9 @@ void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const st
       {
         Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
         mIblDiffuseLoadTask.Reset();
+
+        // Request image resource GC
+        Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
       }
       mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &SceneView::OnIblDiffuseLoadComplete));
       Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask);
@@ -528,6 +538,9 @@ void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const st
       {
         Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
         mIblSpecularLoadTask.Reset();
+
+        // Request image resource GC
+        Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
       }
       mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &SceneView::OnIblSpecularLoadComplete));
       Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask);
@@ -1238,6 +1251,9 @@ void SceneView::UpdateSkybox(const std::string& skyboxUrl, Scene3D::EnvironmentM
 
     mSkyboxDirty         = false;
     mSkyboxResourceReady = true;
+
+    // Request image resource GC
+    Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
   }
   else
   {
@@ -1247,6 +1263,9 @@ void SceneView::UpdateSkybox(const std::string& skyboxUrl, Scene3D::EnvironmentM
       {
         Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask);
         mSkyboxLoadTask.Reset();
+
+        // Request image resource GC
+        Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
       }
 
       mSkyboxLoadTask = new EnvironmentMapLoadTask(mSkyboxUrl, mSkyboxEnvironmentMapType, MakeCallback(this, &SceneView::OnSkyboxLoadComplete));
index 27c8170..12bbf6e 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.
@@ -406,7 +406,7 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
       environmentMapData.mPixelData.resize(6);
       for(auto& face : environmentMapData.mPixelData)
       {
-        face.push_back(PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY));
+        face.push_back(Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGB());
       }
       environmentMapData.SetEnvironmentMapType(Dali::Scene3D::EnvironmentMapType::CUBEMAP);
       Texture iblTexture = environmentMapData.GetTexture();
index 4a7c820..f7f998e 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.
@@ -110,7 +110,8 @@ PixelData GetCubeFace(Dali::PixelData cubePixelData, uint32_t faceIndex, CubeTyp
       uint32_t finalFaceWidth  = (xOffset + static_cast<uint32_t>(faceWidth) < imageWidth) ? static_cast<uint32_t>(faceWidth) : imageWidth - xOffset;
       uint32_t finalFaceHeight = (yOffset + static_cast<uint32_t>(faceHeight) < imageHeight) ? static_cast<uint32_t>(faceHeight) : imageHeight - yOffset;
       uint8_t* tempImageBuffer = GetCroppedBuffer(imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, finalFaceWidth, finalFaceHeight);
-      cubeFacePixelData        = PixelData::New(tempImageBuffer, finalFaceWidth * finalFaceHeight * bytesPerPixel, finalFaceWidth, finalFaceHeight, imagePixelFormat, PixelData::FREE);
+
+      cubeFacePixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(tempImageBuffer, finalFaceWidth * finalFaceHeight * bytesPerPixel, finalFaceWidth, finalFaceHeight, 0u, imagePixelFormat, PixelData::FREE);
     }
   }
   return cubeFacePixelData;
index 66e15e2..010dc89 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.
@@ -19,6 +19,7 @@
 #include <dali-scene3d/public-api/loader/ktx-loader.h>
 
 // EXTERNAL INCLUDES
+#include <dali/integration-api/pixel-data-integ.h>
 #include <dali/public-api/rendering/texture.h>
 #include <fstream>
 #include <memory>
@@ -248,7 +249,7 @@ bool LoadKtxData(const std::string& path, EnvironmentMapData& environmentMapData
         {
           return false;
         }
-        environmentMapData.mPixelData[face][mipmapLevel] = PixelData::New(img.release(), byteSize, header.pixelWidth, header.pixelHeight, daliformat, PixelData::DELETE_ARRAY);
+        environmentMapData.mPixelData[face][mipmapLevel] = Dali::Integration::NewPixelDataWithReleaseAfterUpload(img.release(), byteSize, header.pixelWidth, header.pixelHeight, 0u, daliformat, PixelData::DELETE_ARRAY);
       }
     }
 
index 2e6ef5f..eb83f23 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.
@@ -21,6 +21,8 @@
 // EXTERNAL INCLUDES
 #include <dali-toolkit/devel-api/builder/base64-encoding.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/pixel-data-integ.h>
 
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/common/image-resource-loader.h>
@@ -107,7 +109,7 @@ Dali::PixelData LoadImageResource(const std::string& resourcePath,
       Dali::Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromBuffer(reinterpret_cast<uint8_t*>(buffer.data()), bufferSize, textureDefinition.mMinImageDimensions, fittingMode, textureDefinition.mSamplingMode, orientationCorrection);
       if(pixelBuffer)
       {
-        pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
+        pixelData = Dali::Devel::PixelBuffer::Convert(pixelBuffer, true);
       }
     }
   }
@@ -216,9 +218,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
     }
     else // single value normal-roughness
     {
-      const auto bufferSize = 4;
-      uint8_t*   buffer     = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff, 0xff}; // normal of (0, 0, 1), roughness of 1
-      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+      raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisAndAlphaRGBA(), GetSingleValueSampler()});
     }
   }
   else
@@ -252,7 +252,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
       buffer[0] = static_cast<uint8_t>(mColor.r * 255.f);
       buffer[1] = static_cast<uint8_t>(mColor.g * 255.f);
       buffer[2] = static_cast<uint8_t>(mColor.b * 255.f);
-      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, format, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+      raw.mTextures.push_back({Dali::Integration::NewPixelDataWithReleaseAfterUpload(buffer, bufferSize, 1, 1, 0, format, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
     }
 
     // If we have transparency, or an image based albedo map, we will have to continue with separate metallicRoughness + normal.
@@ -266,9 +266,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
     {
       // NOTE: we want to set both metallic and roughness to 1.0; dli uses the R & A channels,
       // glTF2 uses B & G, so we might as well just set all components to 1.0.
-      const auto bufferSize = 4;
-      uint8_t*   buffer     = new uint8_t[bufferSize]{0xff, 0xff, 0xff, 0xff};
-      raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+      raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGBA(), GetSingleValueSampler()});
     }
 
     if(checkStage(NORMAL))
@@ -280,15 +278,11 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath)
     {
       if(createMetallicRoughnessAndNormal)
       {
-        const auto bufferSize = 3;
-        uint8_t*   buffer     = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff}; // normal of (0, 0, 1)
-        raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+        raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisRGB(), GetSingleValueSampler()});
       }
       else // single-value normal-roughness
       {
-        const auto bufferSize = 4;
-        uint8_t*   buffer     = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff, 0xff}; // normal of (0, 0, 1), roughness of 1.0
-        raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+        raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisAndAlphaRGBA(), GetSingleValueSampler()});
       }
     }
   }