Merge "Fix svace issue for image-operator" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 21 Feb 2023 12:51:51 +0000 (12:51 +0000)
committerGerrit Code Review <gerrit@review>
Tue, 21 Feb 2023 12:51:51 +0000 (12:51 +0000)
22 files changed:
automated-tests/resources/jpg_ycck_173x120.jpg [new file with mode: 0755]
automated-tests/src/dali-adaptor/utc-Dali-ImageLoading.cpp
dali/devel-api/adaptor-framework/accessibility.cpp
dali/internal/accessibility/bridge/dbus/dbus-tizen.cpp [changed mode: 0644->0755]
dali/internal/adaptor/common/combined-update-render-controller.cpp
dali/internal/adaptor/common/combined-update-render-controller.h
dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.cpp
dali/internal/drag-and-drop/tizen-wayland/drag-and-drop-impl-ecore-wl2.h
dali/internal/graphics/gles-impl/gles-context.cpp
dali/internal/graphics/gles-impl/gles-graphics-pipeline-cache.cpp [changed mode: 0644->0755]
dali/internal/graphics/gles-impl/gles-graphics-texture.cpp
dali/internal/graphics/gles/egl-implementation.cpp
dali/internal/graphics/tizen/egl-image-extensions-tizen.cpp
dali/internal/imaging/common/loader-jpeg-turbo.cpp
dali/internal/input/common/key-impl.cpp
dali/internal/system/common/configuration-manager.cpp
dali/internal/text/text-abstraction/plugin/font-client-utils.cpp
dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp
dali/internal/window-system/windows/platform-implement-win.cpp
dali/internal/window-system/x11/window-base-x.cpp
dali/public-api/dali-adaptor-version.cpp
packaging/dali-adaptor.spec

diff --git a/automated-tests/resources/jpg_ycck_173x120.jpg b/automated-tests/resources/jpg_ycck_173x120.jpg
new file mode 100755 (executable)
index 0000000..547f0af
Binary files /dev/null and b/automated-tests/resources/jpg_ycck_173x120.jpg differ
index 2e4a8b5..83e5321 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -35,6 +35,9 @@ const char* IMAGE_128_RGB = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
 // resolution: 2000*2560, pixel format: RGB888
 const char* IMAGE_LARGE_EXIF3_RGB = TEST_RESOURCE_DIR "/f-large-exif-3.jpg";
 
+// resolution: 173*120, jpg color space: TJCS_CMYK, pixel format: RGB888
+const char* IMAGE_TJCS_CMYK = TEST_RESOURCE_DIR "/jpg_ycck_173x120.jpg";
+
 // resolution: 128*128, pixel format: RGB888, YUV411
 const char* IMAGE_128_YUV_411 = TEST_RESOURCE_DIR "/gallery-small-1-yuv411.jpg";
 // resolution: 128*128, pixel format: RGB888, YUV420
@@ -131,6 +134,12 @@ int UtcDaliLoadImageP(void)
   DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 2560u, TEST_LOCATION);
   DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
 
+  pixelBufferJpeg = Dali::LoadImageFromFile(IMAGE_TJCS_CMYK);
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 173u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 120u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+
   Devel::PixelBuffer BufferJpeg1 = Dali::LoadImageFromFile(IMAGE_WIDTH_ODD_EXIF1_RGB);
   DALI_TEST_CHECK(BufferJpeg1);
   DALI_TEST_EQUALS(BufferJpeg1.GetWidth(), 55u, TEST_LOCATION);
@@ -272,6 +281,12 @@ int UtcDaliLoadImageFromBufferP(void)
   DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 2560u, TEST_LOCATION);
   DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
 
+  pixelBufferJpeg = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_TJCS_CMYK));
+  DALI_TEST_CHECK(pixelBufferJpeg);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetWidth(), 173u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetHeight(), 120u, TEST_LOCATION);
+  DALI_TEST_EQUALS(pixelBufferJpeg.GetPixelFormat(), Pixel::RGB888, TEST_LOCATION);
+
   Devel::PixelBuffer BufferJpeg1 = Dali::LoadImageFromBuffer(FileToMemory(IMAGE_WIDTH_ODD_EXIF1_RGB));
   DALI_TEST_CHECK(BufferJpeg1);
   DALI_TEST_EQUALS(BufferJpeg1.GetWidth(), 55u, TEST_LOCATION);
index b058328..1139607 100644 (file)
@@ -366,7 +366,7 @@ public:
       return false;
     }
 
-    auto self = Self();
+    auto self                = Self();
     auto oldHighlightedActor = GetCurrentlyHighlightedActor();
     if(self == oldHighlightedActor)
     {
@@ -385,7 +385,7 @@ public:
 
     SetCurrentlyHighlightedActor(self);
 
-    auto window                                 = Dali::DevelWindow::Get(self);
+    auto                             window     = Dali::DevelWindow::Get(self);
     Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
     windowImpl.EmitAccessibilityHighlightSignal(true);
 
@@ -413,7 +413,7 @@ public:
 
     SetCurrentlyHighlightedActor({});
 
-    auto window                                 = Dali::DevelWindow::Get(self);
+    auto                             window     = Dali::DevelWindow::Get(self);
     Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
     windowImpl.EmitAccessibilityHighlightSignal(false);
 
@@ -453,7 +453,7 @@ public:
 
     if(mRoot)
     {
-      Dali::Window window                         = Dali::DevelWindow::Get(Self());
+      Dali::Window                     window     = Dali::DevelWindow::Get(Self());
       Dali::Internal::Adaptor::Window& windowImpl = Dali::GetImplementation(window);
       attributes["resID"]                         = windowImpl.GetNativeResourceId();
     }
@@ -479,7 +479,11 @@ public:
 using AdaptorAccessiblesType = std::unordered_map<const Dali::RefObject*, std::unique_ptr<AdaptorAccessible> >;
 
 // Save RefObject from an Actor in Accessible::Get()
-AdaptorAccessiblesType gAdaptorAccessibles;
+AdaptorAccessiblesType& GetAdaptorAccessibles()
+{
+  static AdaptorAccessiblesType gAdaptorAccessibles;
+  return gAdaptorAccessibles;
+}
 
 std::function<Accessible*(Dali::Actor)> convertingFunctor = [](Dali::Actor) -> Accessible* {
   return nullptr;
@@ -492,7 +496,7 @@ void Accessible::SetObjectRegistry(ObjectRegistry registry)
 {
   objectRegistry = registry;
   objectRegistry.ObjectDestroyedSignal().Connect([](const Dali::RefObject* obj) {
-    gAdaptorAccessibles.erase(obj);
+    GetAdaptorAccessibles().erase(obj);
   });
 }
 
@@ -511,11 +515,11 @@ Accessible* Accessible::Get(Dali::Actor actor)
   auto accessible = convertingFunctor(actor);
   if(!accessible)
   {
-    auto pair = gAdaptorAccessibles.emplace(&actor.GetBaseObject(), nullptr);
+    auto pair = GetAdaptorAccessibles().emplace(&actor.GetBaseObject(), nullptr);
     if(pair.second)
     {
-      bool isRoot                    = false;
-      Dali::Integration::Scene scene = Dali::Integration::Scene::Get(actor);
+      bool                     isRoot = false;
+      Dali::Integration::Scene scene  = Dali::Integration::Scene::Get(actor);
       if(scene)
       {
         isRoot = (actor == scene.GetRootLayer());
old mode 100644 (file)
new mode 100755 (executable)
index 52014da..baab45a
@@ -110,8 +110,7 @@ DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::str
   else
     connectionState->connection = conn;
 
-
-  if (!connectionState->connection)
+  if(!connectionState->connection)
   {
     DALI_LOG_ERROR("DBusClient connection is not ready\n");
     return;
@@ -525,7 +524,7 @@ struct DefaultDBusWrapper : public DBusWrapper
     }
 
     auto p = eldbus_connection_get(eldbusType);
-    if (!p)
+    if(!p)
     {
       DALI_LOG_ERROR("cannot get dbus connection\n");
       return NULL;
@@ -579,25 +578,51 @@ struct DefaultDBusWrapper : public DBusWrapper
     DBusWrapper::ConnectionWeakPtr connection;
   };
 
-  static std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<Implementation>> globalEntries;
-  static std::mutex                                                                           globalEntriesMutex;
-
-#undef EINA_FALSE
-#undef EINA_TRUE
-#define EINA_FALSE static_cast<Eina_Bool>(0)
-#define EINA_TRUE static_cast<Eina_Bool>(1)
-
-  static Eina_Bool property_get_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message, Eldbus_Message** error)
+  struct GlobalEntries
   {
-    Implementation* impl = nullptr;
+    static GlobalEntries& Get()
+    {
+      static GlobalEntries instance;
+      return instance;
+    }
+
+    Implementation* Find(const Eldbus_Service_Interface* iface)
     {
+      Implementation*             impl = nullptr;
       std::lock_guard<std::mutex> lock(globalEntriesMutex);
       auto                        it = globalEntries.find(iface);
       if(it != globalEntries.end())
       {
         impl = it->second.get();
       }
+      return impl;
     }
+
+    void Add(const Eldbus_Service_Interface* iface, std::unique_ptr<Implementation> impl)
+    {
+      std::lock_guard<std::mutex> lock(globalEntriesMutex);
+      globalEntries[iface] = std::move(impl);
+    }
+
+    void Erase(const Eldbus_Service_Interface* iface)
+    {
+      std::lock_guard<std::mutex> lock(globalEntriesMutex);
+      globalEntries.erase(iface);
+    }
+
+  private:
+    std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<Implementation>> globalEntries;
+    std::mutex                                                                           globalEntriesMutex;
+  };
+
+#undef EINA_FALSE
+#undef EINA_TRUE
+#define EINA_FALSE static_cast<Eina_Bool>(0)
+#define EINA_TRUE static_cast<Eina_Bool>(1)
+
+  static Eina_Bool property_get_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message, Eldbus_Message** error)
+  {
+    Implementation* impl = GlobalEntries::Get().Find(iface);
     if(!impl)
     {
       return EINA_FALSE;
@@ -631,15 +656,7 @@ struct DefaultDBusWrapper : public DBusWrapper
 
   static Eldbus_Message* property_set_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message)
   {
-    Implementation* impl = nullptr;
-    {
-      std::lock_guard<std::mutex> lock(globalEntriesMutex);
-      auto                        it = globalEntries.find(iface);
-      if(it != globalEntries.end())
-      {
-        impl = it->second.get();
-      }
-    }
+    Implementation* impl = GlobalEntries::Get().Find(iface);
     if(!impl)
     {
       auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
@@ -675,13 +692,7 @@ struct DefaultDBusWrapper : public DBusWrapper
 
   static Eldbus_Message* method_callback(const Eldbus_Service_Interface* iface, const Eldbus_Message* message)
   {
-    Implementation* impl = nullptr;
-    {
-      std::lock_guard<std::mutex> lock(globalEntriesMutex);
-      auto                        it = globalEntries.find(iface);
-      if(it != globalEntries.end())
-        impl = it->second.get();
-    }
+    Implementation* impl = GlobalEntries::Get().Find(iface);
     if(!impl)
     {
       auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
@@ -793,21 +804,15 @@ struct DefaultDBusWrapper : public DBusWrapper
       std::move(signalsMap),
       connection});
 
-    {
-      std::lock_guard<std::mutex> lock(globalEntriesMutex);
-      auto                        v = fallback ? eldbus_service_interface_fallback_register(get(connection), pathName.c_str(), &impl->dsc) : eldbus_service_interface_register(get(connection), pathName.c_str(), &impl->dsc);
-      assert(v);
-      globalEntries[v] = std::move(impl);
-      DBUS_DEBUG("registering interface %p (%d)", v, fallback ? 1 : 0);
-      destructors.push_back([=]() {
-        DBUS_DEBUG("unregistering interface %p", v);
-        {
-          std::lock_guard<std::mutex> lock(globalEntriesMutex);
-          globalEntries.erase(v);
-        }
-        eldbus_service_interface_unregister(v);
-      });
-    }
+    auto v = fallback ? eldbus_service_interface_fallback_register(get(connection), pathName.c_str(), &impl->dsc) : eldbus_service_interface_register(get(connection), pathName.c_str(), &impl->dsc);
+    DALI_ASSERT_ALWAYS(v && "Eldbus register failed!");
+    GlobalEntries::Get().Add(v, std::move(impl));
+    DBUS_DEBUG("registering interface %p (%d)", v, fallback ? 1 : 0);
+    destructors.push_back([=]() {
+      DBUS_DEBUG("unregistering interface %p", v);
+      GlobalEntries::Get().Erase(v);
+      eldbus_service_interface_unregister(v);
+    });
   }
 
   static void listenerEventChangedCallback(void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event)
@@ -838,9 +843,6 @@ struct DefaultDBusWrapper : public DBusWrapper
   }
 };
 
-std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<DefaultDBusWrapper::Implementation>> DefaultDBusWrapper::globalEntries;
-std::mutex                                                                                               DefaultDBusWrapper::globalEntriesMutex;
-
 DBusWrapper* DBusWrapper::Installed()
 {
   if(!InstalledWrapper)
index 53514de..4cc78b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -91,6 +91,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController(AdaptorInternalSe
   mEventThreadSemaphore(0),
   mSurfaceSemaphore(0),
   mUpdateRenderThreadWaitCondition(),
+  mPostRenderWaitCondition(),
   mAdaptorInterfaces(adaptorInterfaces),
   mPerformanceInterface(adaptorInterfaces.GetPerformanceInterface()),
   mCore(adaptorInterfaces.GetCore()),
@@ -307,8 +308,7 @@ void CombinedUpdateRenderController::ReplaceSurface(Dali::RenderSurfaceInterface
     // Start replacing the surface.
     {
       ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
-      mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will replace the surface now
-      mNewSurface    = newSurface;
+      mNewSurface = newSurface;
       mUpdateRenderThreadWaitCondition.Notify(lock);
     }
 
@@ -330,7 +330,6 @@ void CombinedUpdateRenderController::DeleteSurface(Dali::RenderSurfaceInterface*
     // Start replacing the surface.
     {
       ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
-      mPostRendering  = FALSE; // Clear the post-rendering flag as Update/Render thread will delete the surface now
       mDeletedSurface = surface;
       mUpdateRenderThreadWaitCondition.Notify(lock);
     }
@@ -366,7 +365,6 @@ void CombinedUpdateRenderController::ResizeSurface()
 
   {
     ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
-    mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will resize the surface now
     // Surface is resized and the surface resized count is increased.
     mSurfaceResized++;
     mUpdateRenderThreadWaitCondition.Notify(lock);
@@ -966,9 +964,9 @@ void CombinedUpdateRenderController::AddPerformanceMarker(PerformanceInterface::
 
 void CombinedUpdateRenderController::PostRenderComplete()
 {
-  ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
+  ConditionalWait::ScopedLock lock(mPostRenderWaitCondition);
   mPostRendering = FALSE;
-  mUpdateRenderThreadWaitCondition.Notify(lock);
+  mPostRenderWaitCondition.Notify(lock);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -977,19 +975,19 @@ void CombinedUpdateRenderController::PostRenderComplete()
 
 void CombinedUpdateRenderController::PostRenderStarted()
 {
-  ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
+  ConditionalWait::ScopedLock lock(mPostRenderWaitCondition);
   mPostRendering = TRUE;
 }
 
 void CombinedUpdateRenderController::PostRenderWaitForCompletion()
 {
-  ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
+  ConditionalWait::ScopedLock lock(mPostRenderWaitCondition);
   while(mPostRendering &&
         !mNewSurface &&     // We should NOT wait if we're replacing the surface
         !mDeletedSurface && // We should NOT wait if we're deleting the surface
         !mDestroyUpdateRenderThread)
   {
-    mUpdateRenderThreadWaitCondition.Wait(lock);
+    mPostRenderWaitCondition.Wait(lock);
   }
 }
 
index 8902875..3c4f29b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_COMBINED_UPDATE_RENDER_CONTROLLER_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -340,6 +340,7 @@ private:
   Semaphore<>     mSurfaceSemaphore;       ///< Used by the event thread to ensure the surface has been deleted or replaced.
 
   ConditionalWait mUpdateRenderThreadWaitCondition; ///< The wait condition for the update-render-thread.
+  ConditionalWait mPostRenderWaitCondition;         ///< The wait condition for the post render.
 
   AdaptorInternalServices&  mAdaptorInterfaces;    ///< The adaptor internal interface
   PerformanceInterface*     mPerformanceInterface; ///< The performance logging interface
index ca895f1..1a773af 100644 (file)
@@ -228,10 +228,18 @@ bool DragAndDropEcoreWl::AddListener(Dali::Actor target, Dali::DragAndDrop::Drag
     }
   }
 
+  auto parent = Dali::DevelWindow::Get(target);
+  Ecore_Wl2_Window*  parentWindow = AnyCast<Ecore_Wl2_Window*>(parent.GetNativeHandle());
+  if(parentWindow == nullptr)
+  {
+    return false;
+  }
+
   DropTarget targetData;
   targetData.target   = target;
   targetData.callback = callback;
   targetData.inside   = false;
+  targetData.parentWindowId = ecore_wl2_window_id_get(parentWindow);
 
   mDropTargets.push_back(targetData);
 
@@ -343,6 +351,11 @@ bool DragAndDropEcoreWl::CalculateDragEvent(void* event)
 
   for(std::size_t i = 0; i < mDropTargets.size(); i++)
   {
+    if(ev->win != mDropTargets[i].parentWindowId)
+    {
+      continue;
+    }
+
     Vector2 position      = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::POSITION);
     Vector2 size          = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::SIZE);
     bool    currentInside = IsIntersection(ev->x, ev->y, position.x, position.y, size.width, size.height);
@@ -389,6 +402,11 @@ bool DragAndDropEcoreWl::CalculateViewRegion(void* event)
 
   for(std::size_t i = 0; i < mDropTargets.size(); i++)
   {
+    if(ev->win != mDropTargets[i].parentWindowId)
+    {
+      continue;
+    }
+
     Vector2 position = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::POSITION);
     Vector2 size     = mDropTargets[i].target.GetProperty<Vector2>(Dali::Actor::Property::SIZE);
     // If the drop position is in the target object region, request drop data to the source object
index 162c3d0..0b1b286 100644 (file)
@@ -35,6 +35,7 @@ struct DropTarget
   Dali::Actor                            target;
   Dali::DragAndDrop::DragAndDropFunction callback;
   bool                                   inside;
+  int                                    parentWindowId;
 };
 
 /**
index 47d5f5d..32f490d 100644 (file)
@@ -34,6 +34,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <map>
+#include <unordered_map>
 
 namespace Dali::Graphics::GLES
 {
@@ -53,7 +54,7 @@ struct Context::Impl
    * that VertexInputState has been set correctly for the pipeline.
    *
    */
-  void BindProgramVAO(GLES::ProgramImpl* program, const VertexInputState& vertexInputState)
+  void BindProgramVAO(const GLES::ProgramImpl* program, const VertexInputState& vertexInputState)
   {
     // Calculate attributes location hash unordered.
     std::size_t hash = 0;
@@ -62,24 +63,26 @@ struct Context::Impl
       hash ^= std::hash<uint32_t>{}(attr.location);
     }
 
-    auto key = std::make_pair(program, hash);
-
     auto& gl   = *mController.GetGL();
-    auto  iter = mProgramVAOMap.find(key);
+    auto  iter = mProgramVAOMap.find(program);
     if(iter != mProgramVAOMap.end())
     {
-      if(mProgramVAOCurrentState != iter->second)
+      auto attributeIter = iter->second.find(hash);
+      if(attributeIter != iter->second.end())
       {
-        mProgramVAOCurrentState = iter->second;
-        gl.BindVertexArray(iter->second);
+        if(mProgramVAOCurrentState != attributeIter->second)
+        {
+          mProgramVAOCurrentState = attributeIter->second;
+          gl.BindVertexArray(attributeIter->second);
+        }
+        return;
       }
-      return;
     }
 
     uint32_t vao;
     gl.GenVertexArrays(1, &vao);
     gl.BindVertexArray(vao);
-    mProgramVAOMap[key] = vao;
+    mProgramVAOMap[program][hash] = vao;
     for(const auto& attr : vertexInputState.attributes)
     {
       gl.EnableVertexAttribArray(attr.location);
@@ -215,9 +218,9 @@ struct Context::Impl
   const GLES::RenderPass*   mCurrentRenderPass{nullptr};
 
   // Each context must have own VAOs as they cannot be shared
-  std::map<std::pair<GLES::ProgramImpl*, std::size_t>, uint32_t> mProgramVAOMap;              ///< GL program-VAO map
-  uint32_t                                                       mProgramVAOCurrentState{0u}; ///< Currently bound VAO
-  GLStateCache                                                   mGlStateCache{};             ///< GL status cache
+  std::unordered_map<const GLES::ProgramImpl*, std::map<std::size_t, uint32_t>> mProgramVAOMap;              ///< GL program-VAO map
+  uint32_t                                                                      mProgramVAOCurrentState{0u}; ///< Currently bound VAO
+  GLStateCache                                                                  mGlStateCache{};             ///< GL status cache
 
   bool mGlContextCreated{false}; ///< True if the OpenGL context has been created
 
@@ -1018,6 +1021,34 @@ void Context::InvalidateCachedPipeline(GLES::Pipeline* pipeline)
   {
     mImpl->mCurrentPipeline = nullptr;
   }
+
+  // Remove cached VAO map
+  auto* gl = mImpl->mController.GetGL();
+  if(gl)
+  {
+    const auto* program = pipeline->GetCreateInfo().programState->program;
+    if(program)
+    {
+      const auto* programImpl = static_cast<const GLES::Program*>(program)->GetImplementation();
+      if(programImpl)
+      {
+        auto iter = mImpl->mProgramVAOMap.find(programImpl);
+        if(iter != mImpl->mProgramVAOMap.end())
+        {
+          for(auto& attributeHashPair : iter->second)
+          {
+            auto vao = attributeHashPair.second;
+            gl->DeleteVertexArrays(1, &vao);
+            if(mImpl->mProgramVAOCurrentState == vao)
+            {
+              mImpl->mProgramVAOCurrentState = 0u;
+            }
+          }
+          mImpl->mProgramVAOMap.erase(iter);
+        }
+      }
+    }
+  }
 }
 
 void Context::PrepareForNativeRendering()
old mode 100644 (file)
new mode 100755 (executable)
index f9a7d16..69f45b7
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -133,85 +133,88 @@ operator==(const Dali::Graphics::VertexInputState::Binding& lhs, const Dali::Gra
 using PipelineStateCompateFunctionType = bool(const Graphics::PipelineCreateInfo*,
                                               const Graphics::PipelineCreateInfo*);
 
-static std::vector<PipelineStateCompateFunctionType*> STATE_COMPARE_FUNC_TABLE{};
+static std::vector<PipelineStateCompateFunctionType*>& GetStateCompareFuncTable()
+{
+  static std::vector<PipelineStateCompateFunctionType*> stateCompareFuncTable{};
+  return stateCompareFuncTable;
+}
 
 /**
  * @brief Initialises compare function lookup table
  */
 void InitialiseStateCompareLookupTable()
 {
-  STATE_COMPARE_FUNC_TABLE = {
-    [](const auto* lhs, const auto* rhs) -> bool // colorBlendState
-    {
-      const auto& lcb = *lhs->colorBlendState;
-      const auto& rcb = *rhs->colorBlendState;
-      return lcb.logicOpEnable == rcb.logicOpEnable &&
-             lcb.logicOp == rcb.logicOp &&
-             cmpf(lcb.blendConstants[0], rcb.blendConstants[0]) &&
-             cmpf(lcb.blendConstants[1], rcb.blendConstants[1]) &&
-             cmpf(lcb.blendConstants[2], rcb.blendConstants[2]) &&
-             cmpf(lcb.blendConstants[3], rcb.blendConstants[3]) &&
-             lcb.blendEnable == rcb.blendEnable &&
-             lcb.srcColorBlendFactor == rcb.srcColorBlendFactor &&
-             lcb.dstColorBlendFactor == rcb.dstColorBlendFactor &&
-             lcb.colorBlendOp == rcb.colorBlendOp &&
-             lcb.srcAlphaBlendFactor == rcb.srcAlphaBlendFactor &&
-             lcb.dstAlphaBlendFactor == rcb.dstAlphaBlendFactor &&
-             lcb.alphaBlendOp == rcb.alphaBlendOp &&
-             lcb.colorComponentWriteBits == rcb.colorComponentWriteBits;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // viewport state
-    {
-      const auto& lvp = *lhs->viewportState;
-      const auto& rvp = *rhs->viewportState;
-      return lvp.viewport == rvp.viewport &&
-             lvp.scissor == rvp.scissor &&
-             lvp.scissorTestEnable == rvp.scissorTestEnable;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // basePipeline
-    {
-      return lhs->basePipeline == rhs->basePipeline;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // depthStencilState
-    {
-      const auto& lds = *lhs->depthStencilState;
-      const auto& rds = *rhs->depthStencilState;
-      return lds.depthTestEnable == rds.depthTestEnable &&
-             lds.depthWriteEnable == rds.depthWriteEnable &&
-             lds.depthCompareOp == rds.depthCompareOp &&
-             lds.stencilTestEnable == rds.stencilTestEnable &&
-             lds.front == rds.front &&
-             lds.back == rds.back;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // rasterizationState
-    {
-      const auto& lrs = *lhs->rasterizationState;
-      const auto& rrs = *rhs->rasterizationState;
-      return lrs.cullMode == rrs.cullMode &&
-             lrs.polygonMode == rrs.polygonMode &&
-             lrs.frontFace == rrs.frontFace;
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // vertexInputState
-    {
-      const auto& lvi = *lhs->vertexInputState;
-      const auto& rvi = *rhs->vertexInputState;
-      return lvi.bufferBindings.size() == rvi.bufferBindings.size() &&
-             lvi.attributes.size() == rvi.attributes.size() &&
-             std::equal(lvi.bufferBindings.begin(), lvi.bufferBindings.end(), rvi.bufferBindings.begin(), [](const auto& lhs, const auto& rhs) {
-               return operator==(lhs, rhs);
-             }) &&
-             std::equal(lvi.attributes.begin(), lvi.attributes.end(), rvi.attributes.begin(), [](const auto& lhs, const auto& rhs) {
-               return operator==(lhs, rhs);
-             });
-    },
-    [](const auto* lhs, const auto* rhs) -> bool // inputAssemblyState
-    {
-      const auto& lia = *lhs->inputAssemblyState;
-      const auto& ria = *rhs->inputAssemblyState;
-      return lia.topology == ria.topology &&
-             lia.primitiveRestartEnable == ria.primitiveRestartEnable;
-    },
-  };
+  GetStateCompareFuncTable().clear();
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // colorBlendState
+                                       {
+                                         const auto& lcb = *lhs->colorBlendState;
+                                         const auto& rcb = *rhs->colorBlendState;
+                                         return lcb.logicOpEnable == rcb.logicOpEnable &&
+                                                lcb.logicOp == rcb.logicOp &&
+                                                cmpf(lcb.blendConstants[0], rcb.blendConstants[0]) &&
+                                                cmpf(lcb.blendConstants[1], rcb.blendConstants[1]) &&
+                                                cmpf(lcb.blendConstants[2], rcb.blendConstants[2]) &&
+                                                cmpf(lcb.blendConstants[3], rcb.blendConstants[3]) &&
+                                                lcb.blendEnable == rcb.blendEnable &&
+                                                lcb.srcColorBlendFactor == rcb.srcColorBlendFactor &&
+                                                lcb.dstColorBlendFactor == rcb.dstColorBlendFactor &&
+                                                lcb.colorBlendOp == rcb.colorBlendOp &&
+                                                lcb.srcAlphaBlendFactor == rcb.srcAlphaBlendFactor &&
+                                                lcb.dstAlphaBlendFactor == rcb.dstAlphaBlendFactor &&
+                                                lcb.alphaBlendOp == rcb.alphaBlendOp &&
+                                                lcb.colorComponentWriteBits == rcb.colorComponentWriteBits;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // viewport state
+                                       {
+                                         const auto& lvp = *lhs->viewportState;
+                                         const auto& rvp = *rhs->viewportState;
+                                         return lvp.viewport == rvp.viewport &&
+                                                lvp.scissor == rvp.scissor &&
+                                                lvp.scissorTestEnable == rvp.scissorTestEnable;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // basePipeline
+                                       {
+                                         return lhs->basePipeline == rhs->basePipeline;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // depthStencilState
+                                       {
+                                         const auto& lds = *lhs->depthStencilState;
+                                         const auto& rds = *rhs->depthStencilState;
+                                         return lds.depthTestEnable == rds.depthTestEnable &&
+                                                lds.depthWriteEnable == rds.depthWriteEnable &&
+                                                lds.depthCompareOp == rds.depthCompareOp &&
+                                                lds.stencilTestEnable == rds.stencilTestEnable &&
+                                                lds.front == rds.front &&
+                                                lds.back == rds.back;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // rasterizationState
+                                       {
+                                         const auto& lrs = *lhs->rasterizationState;
+                                         const auto& rrs = *rhs->rasterizationState;
+                                         return lrs.cullMode == rrs.cullMode &&
+                                                lrs.polygonMode == rrs.polygonMode &&
+                                                lrs.frontFace == rrs.frontFace;
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // vertexInputState
+                                       {
+                                         const auto& lvi = *lhs->vertexInputState;
+                                         const auto& rvi = *rhs->vertexInputState;
+                                         return lvi.bufferBindings.size() == rvi.bufferBindings.size() &&
+                                                lvi.attributes.size() == rvi.attributes.size() &&
+                                                std::equal(lvi.bufferBindings.begin(), lvi.bufferBindings.end(), rvi.bufferBindings.begin(), [](const auto& lhs, const auto& rhs) {
+                                                  return operator==(lhs, rhs);
+                                                }) &&
+                                                std::equal(lvi.attributes.begin(), lvi.attributes.end(), rvi.attributes.begin(), [](const auto& lhs, const auto& rhs) {
+                                                  return operator==(lhs, rhs);
+                                                });
+                                       });
+  GetStateCompareFuncTable().push_back([](const auto* lhs, const auto* rhs) -> bool // inputAssemblyState
+                                       {
+                                         const auto& lia = *lhs->inputAssemblyState;
+                                         const auto& ria = *rhs->inputAssemblyState;
+                                         return lia.topology == ria.topology &&
+                                                lia.primitiveRestartEnable == ria.primitiveRestartEnable;
+                                       });
 }
 
 /**
@@ -341,7 +344,7 @@ PipelineImpl* PipelineCache::FindPipelineImpl(const PipelineCreateInfo& info)
         // Test only set states
         if((entry.stateBitmask & (1 << i)))
         {
-          if(!STATE_COMPARE_FUNC_TABLE[i](&info, &cacheInfo))
+          if(!(GetStateCompareFuncTable()[i](&info, &cacheInfo)))
           {
             break;
           }
@@ -483,4 +486,4 @@ void PipelineCache::FlushCache()
   //       killing the program (if program isn't in use anymore)
 }
 
-} // namespace Dali::Graphics::GLES
\ No newline at end of file
+} // namespace Dali::Graphics::GLES
index f7a2aef..9b997c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -91,8 +91,12 @@ inline std::vector<uint8_t> ConvertRGB32ToRGBA32(const void* pData, uint32_t siz
 /**
  * Format conversion table
  */
-static const std::vector<ColorConversion> COLOR_CONVERSION_TABLE = {
-  {Format::R8G8B8_UNORM, Format::R8G8B8A8_UNORM, ConvertRGB32ToRGBA32, WriteRGB32ToRGBA32}};
+const std::vector<ColorConversion>& GetColorConversionTable()
+{
+  static const std::vector<ColorConversion> COLOR_CONVERSION_TABLE = {
+    {Format::R8G8B8_UNORM, Format::R8G8B8A8_UNORM, ConvertRGB32ToRGBA32, WriteRGB32ToRGBA32}};
+  return COLOR_CONVERSION_TABLE;
+}
 
 /**
  * Constructor
@@ -399,12 +403,12 @@ bool Texture::TryConvertPixelData(const void* pData, Graphics::Format srcFormat,
     return false;
   }
 
-  auto it = std::find_if(COLOR_CONVERSION_TABLE.begin(), COLOR_CONVERSION_TABLE.end(), [&](auto& item) {
+  auto it = std::find_if(GetColorConversionTable().begin(), GetColorConversionTable().end(), [&](auto& item) {
     return item.srcFormat == srcFormat && item.destFormat == destFormat;
   });
 
   // No suitable format, return empty array
-  if(it == COLOR_CONVERSION_TABLE.end())
+  if(it == GetColorConversionTable().end())
   {
     return false;
   }
index 09d8867..e389671 100644 (file)
 
 namespace
 {
-const uint32_t    THRESHOLD_SWAPBUFFER_COUNT              = 5;
-const uint32_t    CHECK_EXTENSION_NUMBER                  = 4;
-const uint32_t    EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT = 15;
-const std::string EGL_KHR_SURFACELESS_CONTEXT             = "EGL_KHR_surfaceless_context";
-const std::string EGL_KHR_CREATE_CONTEXT                  = "EGL_KHR_create_context";
-const std::string EGL_KHR_PARTIAL_UPDATE                  = "EGL_KHR_partial_update";
-const std::string EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE        = "EGL_KHR_swap_buffers_with_damage";
+const uint32_t THRESHOLD_SWAPBUFFER_COUNT              = 5;
+const uint32_t CHECK_EXTENSION_NUMBER                  = 4;
+const uint32_t EGL_VERSION_SUPPORT_SURFACELESS_CONTEXT = 15;
+const char*    EGL_KHR_SURFACELESS_CONTEXT             = "EGL_KHR_surfaceless_context";
+const char*    EGL_KHR_CREATE_CONTEXT                  = "EGL_KHR_create_context";
+const char*    EGL_KHR_PARTIAL_UPDATE                  = "EGL_KHR_partial_update";
+const char*    EGL_KHR_SWAP_BUFFERS_WITH_DAMAGE        = "EGL_KHR_swap_buffers_with_damage";
 
 // Threshold time in miliseconds
 constexpr auto PERFORMANCE_LOG_THRESHOLD_TIME_ENV = "DALI_EGL_PERFORMANCE_LOG_THRESHOLD_TIME";
index cf79bdb..785f933 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -46,8 +46,8 @@ PFNEGLCREATEIMAGEKHRPROC            eglCreateImageKHRProc            = 0;
 PFNEGLDESTROYIMAGEKHRPROC           eglDestroyImageKHRProc           = 0;
 PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOESProc = 0;
 
-const std::string EGL_TIZEN_IMAGE_NATIVE_SURFACE = "EGL_TIZEN_image_native_surface";
-const std::string EGL_EXT_IMAGE_DMA_BUF_IMPORT   = "EGL_EXT_image_dma_buf_import";
+const char* EGL_TIZEN_IMAGE_NATIVE_SURFACE = "EGL_TIZEN_image_native_surface";
+const char* EGL_EXT_IMAGE_DMA_BUF_IMPORT   = "EGL_EXT_image_dma_buf_import";
 
 } // unnamed namespace
 
index 5af46e6..2911341 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -46,7 +46,7 @@ namespace
 {
 using Dali::Vector;
 namespace Pixel                     = Dali::Pixel;
-using PixelArray                    = unsigned char*;
+using PixelArray                    = uint8_t*;
 const unsigned int DECODED_L8       = 1;
 const unsigned int DECODED_RGB888   = 3;
 const unsigned int DECODED_RGBA8888 = 4;
@@ -166,7 +166,7 @@ ExifHandle MakeNullExifData()
   return ExifHandle{nullptr, exif_data_free};
 }
 
-ExifHandle MakeExifDataFromData(unsigned char* data, unsigned int size)
+ExifHandle MakeExifDataFromData(uint8_t* data, unsigned int size)
 {
   return ExifHandle{exif_data_new_from_data(data, size), exif_data_free};
 }
@@ -184,7 +184,7 @@ JpegHandle MakeJpegDecompressor()
   return JpegHandle{tjInitDecompress(), tjDestroy};
 }
 
-using JpegMemoryHandle = std::unique_ptr<unsigned char, decltype(tjFree)*>;
+using JpegMemoryHandle = std::unique_ptr<uint8_t, decltype(tjFree)*>;
 
 JpegMemoryHandle MakeJpegMemory()
 {
@@ -547,7 +547,7 @@ void GetJpegPixelFormat(int jpegColorspace, TJPF& pixelLibJpegType, Pixel::Forma
     case TJCS_YCCK:
     {
       pixelLibJpegType = TJPF_CMYK;
-      pixelFormat      = Pixel::RGBA8888;
+      pixelFormat      = Pixel::RGB888;
       break;
     }
     default:
@@ -692,7 +692,7 @@ bool LoadJpegFile(const Dali::ImageLoader::Input& input, Vector<uint8_t>& jpegBu
     DALI_LOG_ERROR("Could not allocate temporary memory to hold JPEG file of size %uMB.\n", jpegBufferSize / 1048576U);
     return false;
   }
-  unsigned char* const jpegBufferPtr = jpegBuffer.Begin();
+  uint8_t* const jpegBufferPtr = jpegBuffer.Begin();
 
   // Pull the compressed JPEG image bytes out of a file and into memory:
   if(DALI_UNLIKELY(fread(jpegBufferPtr, 1, jpegBufferSize, fp) != jpegBufferSize))
@@ -710,6 +710,32 @@ bool LoadJpegFile(const Dali::ImageLoader::Input& input, Vector<uint8_t>& jpegBu
   return true;
 }
 
+/**
+ * @brief Helper function to convert from Turbo Jpeg Pixel Format as TJPF_CMYK to RGB888 by naive method.
+ *
+ * @param[in] cmykBuffer buffer of cmyk.
+ * @param[in] rgbBuffer buffer of Pixel::RGB888
+ * @param[in] width width of image.
+ * @param[in] height height of image.
+ */
+void ConvertTjpfCMYKToRGB888(PixelArray __restrict__ cmykBuffer, PixelArray __restrict__ rgbBuffer, int32_t width, int32_t height)
+{
+  const int32_t pixelCount = width * height;
+  const uint8_t cmykBpp    = 4u;
+  const uint8_t bpp        = 3u;
+
+  const PixelArray cmykBufferEnd = cmykBuffer + pixelCount * cmykBpp;
+  // Convert every pixel
+  while(cmykBuffer != cmykBufferEnd)
+  {
+    const uint8_t channelK = *(cmykBuffer + 3u);
+    *(rgbBuffer + 0u)      = Dali::Internal::Platform::MultiplyAndNormalizeColor(*(cmykBuffer + 0u), channelK);
+    *(rgbBuffer + 1u)      = Dali::Internal::Platform::MultiplyAndNormalizeColor(*(cmykBuffer + 1u), channelK);
+    *(rgbBuffer + 2u)      = Dali::Internal::Platform::MultiplyAndNormalizeColor(*(cmykBuffer + 2u), channelK);
+    cmykBuffer += cmykBpp;
+    rgbBuffer += bpp;
+  }
+}
 } // namespace
 
 namespace Dali
@@ -851,14 +877,14 @@ bool DecodeJpeg(const Dali::ImageLoader::Input& input, std::vector<Dali::Devel::
   // Check decoding format
   if(decodeToYuv && IsSubsamplingFormatEnabled(chrominanceSubsampling) && transform == JpegTransform::NONE)
   {
-    unsigned char* planes[3];
+    uint8_t* planes[3];
 
     // Allocate buffers for each plane and decompress the jpeg buffer into the buffers
     for(int i = 0; i < 3; i++)
     {
       auto planeSize = tjPlaneSizeYUV(i, scaledPostXformWidth, 0, scaledPostXformHeight, chrominanceSubsampling);
 
-      unsigned char* buffer = static_cast<unsigned char*>(malloc(planeSize));
+      uint8_t* buffer = static_cast<uint8_t*>(malloc(planeSize));
       if(!buffer)
       {
         DALI_LOG_ERROR("Buffer allocation is failed [%d]\n", planeSize);
@@ -894,8 +920,8 @@ bool DecodeJpeg(const Dali::ImageLoader::Input& input, std::vector<Dali::Devel::
 
     const int flags = 0;
 
-    int decodeResult = tjDecompressToYUVPlanes(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<unsigned char**>(&planes), scaledPostXformWidth, nullptr, scaledPostXformHeight, flags);
-    if(decodeResult == -1 && IsJpegDecodingFailed())
+    int decodeResult = tjDecompressToYUVPlanes(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<uint8_t**>(&planes), scaledPostXformWidth, nullptr, scaledPostXformHeight, flags);
+    if(DALI_UNLIKELY(decodeResult == -1 && IsJpegDecodingFailed()))
     {
       pixelBuffers.clear();
       return false;
@@ -939,10 +965,31 @@ bool DecodeJpeg(const Dali::ImageLoader::Input& input, std::vector<Dali::Devel::
     auto      bitmapPixelBuffer = bitmap.GetBuffer();
     const int flags             = 0;
 
-    int decodeResult = tjDecompress2(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<unsigned char*>(bitmapPixelBuffer), scaledPreXformWidth, 0, scaledPreXformHeight, pixelLibJpegType, flags);
-    if(decodeResult == -1 && IsJpegDecodingFailed())
+    int decodeResult = -1;
+    if(pixelLibJpegType == TJPF_CMYK)
     {
-      return false;
+      // Currently we support only for 4 bytes per each CMYK pixel.
+      const uint8_t cmykBytesPerPixel = 4u;
+
+      uint8_t* cmykBuffer = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * scaledPostXformWidth * scaledPostXformHeight * cmykBytesPerPixel));
+
+      decodeResult = tjDecompress2(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<uint8_t*>(cmykBuffer), scaledPreXformWidth, 0, scaledPreXformHeight, pixelLibJpegType, flags);
+      if(DALI_UNLIKELY(decodeResult == -1 && IsJpegDecodingFailed()))
+      {
+        free(cmykBuffer);
+        return false;
+      }
+      ConvertTjpfCMYKToRGB888(cmykBuffer, bitmapPixelBuffer, scaledPostXformWidth, scaledPostXformHeight);
+
+      free(cmykBuffer);
+    }
+    else
+    {
+      decodeResult = tjDecompress2(jpeg.get(), jpegBufferPtr, jpegBufferSize, reinterpret_cast<uint8_t*>(bitmapPixelBuffer), scaledPreXformWidth, 0, scaledPreXformHeight, pixelLibJpegType, flags);
+      if(DALI_UNLIKELY(decodeResult == -1 && IsJpegDecodingFailed()))
+      {
+        return false;
+      }
     }
     pixelBuffers.push_back(bitmap);
 
@@ -953,9 +1000,9 @@ bool DecodeJpeg(const Dali::ImageLoader::Input& input, std::vector<Dali::Devel::
   return result;
 }
 
-bool EncodeToJpeg(const unsigned char* const pixelBuffer, Vector<unsigned char>& encodedPixels, const std::size_t width, const std::size_t height, const Pixel::Format pixelFormat, unsigned quality)
+bool EncodeToJpeg(const uint8_t* const pixelBuffer, Vector<uint8_t>& encodedPixels, const std::size_t width, const std::size_t height, const Pixel::Format pixelFormat, unsigned quality)
 {
-  if(!pixelBuffer)
+  if(DALI_UNLIKELY(!pixelBuffer))
   {
     DALI_LOG_ERROR("Null input buffer\n");
     return false;
@@ -1021,7 +1068,7 @@ bool EncodeToJpeg(const unsigned char* const pixelBuffer, Vector<unsigned char>&
     const int     flags         = 0;
 
     if(DALI_UNLIKELY(tjCompress2(jpeg.get(),
-                                 const_cast<unsigned char*>(pixelBuffer),
+                                 const_cast<uint8_t*>(pixelBuffer),
                                  width,
                                  0,
                                  height,
@@ -1215,8 +1262,8 @@ bool TransformSize(int requiredWidth, int requiredHeight, FittingMode::Type fitt
 
 ExifHandle LoadExifData(FILE* fp)
 {
-  auto          exifData = MakeNullExifData();
-  unsigned char dataBuffer[1024];
+  auto    exifData = MakeNullExifData();
+  uint8_t dataBuffer[1024];
 
   if(DALI_UNLIKELY(fseek(fp, 0, SEEK_SET)))
   {
@@ -1286,7 +1333,7 @@ bool LoadJpegHeader(const Dali::ImageLoader::Input& input, unsigned int& width,
       int postXformImageHeight = headerHeight;
 
       success = TransformSize(requiredWidth, requiredHeight, input.scalingParameters.scalingMode, input.scalingParameters.samplingMode, transform, preXformImageWidth, preXformImageHeight, postXformImageWidth, postXformImageHeight);
-      if(success)
+      if(DALI_LIKELY(success))
       {
         headerWidth  = postXformImageWidth;
         headerHeight = postXformImageHeight;
index bcfd43c..623c689 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -271,29 +271,33 @@ private:
   bool   mIsLookupTableInitialized;          ///< flag for basic lookup table initialization
   bool   mIsExtensionLookupTableInitialized; ///< flag for extension lookup table initialization
 };
-KeyMap globalKeyLookup;
 
+KeyMap& GetKeyMap()
+{
+  static KeyMap globalKeyLookup;
+  return globalKeyLookup;
+}
 } // namespace
 
 bool IsKey(const Dali::KeyEvent& keyEvent, Dali::KEY daliKey)
 {
-  int key = globalKeyLookup.GetDaliKeyEnum(keyEvent.GetKeyName().c_str());
+  int key = GetKeyMap().GetDaliKeyEnum(keyEvent.GetKeyName().c_str());
   return daliKey == key;
 }
 
 bool IsDeviceButton(const char* keyName)
 {
-  return globalKeyLookup.IsDeviceButton(keyName);
+  return GetKeyMap().IsDeviceButton(keyName);
 }
 
 const char* GetKeyName(Dali::KEY daliKey)
 {
-  return globalKeyLookup.GetKeyName(daliKey);
+  return GetKeyMap().GetKeyName(daliKey);
 }
 
 int GetDaliKeyCode(const char* keyName)
 {
-  return globalKeyLookup.GetDaliKeyEnum(keyName);
+  return GetKeyMap().GetDaliKeyEnum(keyName);
 }
 
 } // namespace KeyLookup
index 0515b46..ff77416 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -37,11 +37,11 @@ namespace Adaptor
 {
 namespace
 {
-const std::string SYSTEM_CACHE_FILE                           = "gpu-environment.conf";
-const std::string DALI_ENV_MULTIPLE_WINDOW_SUPPORT            = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT";
-const std::string DALI_BLEND_EQUATION_ADVANCED_SUPPORT        = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT";
-const std::string DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT = "DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT";
-const std::string DALI_GLSL_VERSION                           = "DALI_GLSL_VERSION";
+const char* SYSTEM_CACHE_FILE                           = "gpu-environment.conf";
+const char* DALI_ENV_MULTIPLE_WINDOW_SUPPORT            = "DALI_ENV_MULTIPLE_WINDOW_SUPPORT";
+const char* DALI_BLEND_EQUATION_ADVANCED_SUPPORT        = "DALI_BLEND_EQUATION_ADVANCED_SUPPORT";
+const char* DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT = "DALI_MULTISAMPLED_RENDER_TO_TEXTURE_SUPPORT";
+const char* DALI_GLSL_VERSION                           = "DALI_GLSL_VERSION";
 
 } // unnamed namespace
 
index 445e026..2ca3b1c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -131,10 +131,10 @@ const FontSlant::Type IntToSlantType(int slant)
   return static_cast<FontSlant::Type>(ValueToIndex(slant, FONT_SLANT_TYPE_TO_INT, NUM_FONT_SLANT_TYPE - 1u));
 }
 
-const std::string DEFAULT_FONT_FAMILY_NAME("Tizen");
-const int         DEFAULT_FONT_WIDTH(100);
-const int         DEFAULT_FONT_WEIGHT(80);
-const int         DEFAULT_FONT_SLANT(0);
+const char* DEFAULT_FONT_FAMILY_NAME("Tizen");
+const int   DEFAULT_FONT_WIDTH(100);
+const int   DEFAULT_FONT_WEIGHT(80);
+const int   DEFAULT_FONT_SLANT(0);
 
 const std::string_view DefaultFontFamily()
 {
index ef2e530..c70bc4b 100644 (file)
@@ -37,7 +37,7 @@ namespace Adaptor
 {
 namespace
 {
-const std::string            DEFAULT_DEVICE_NAME     = "";
+const char*                  DEFAULT_DEVICE_NAME     = "";
 const Device::Class::Type    DEFAULT_DEVICE_CLASS    = Device::Class::NONE;
 const Device::Subclass::Type DEFAULT_DEVICE_SUBCLASS = Device::Subclass::NONE;
 
index 658c64c..2716f90 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2021 Samsung Electronics Co., Ltd.
+* Copyright (c) 2023 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.
@@ -48,7 +48,7 @@ LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
 namespace
 {
-const std::string DALI_WINDOW_CLASS_NAME = "DaliWindow";
+const char* DALI_WINDOW_CLASS_NAME = "DaliWindow";
 
 uint32_t sNumWindows = 0;
 
index 3f803f7..be48605 100644 (file)
@@ -39,7 +39,7 @@ namespace Adaptor
 {
 namespace
 {
-const std::string            DEFAULT_DEVICE_NAME     = "";
+const char*                  DEFAULT_DEVICE_NAME     = "";
 const Device::Class::Type    DEFAULT_DEVICE_CLASS    = Device::Class::NONE;
 const Device::Subclass::Type DEFAULT_DEVICE_SUBCLASS = Device::Subclass::NONE;
 
index b934fed..b2c3776 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const unsigned int ADAPTOR_MAJOR_VERSION = 2;
 const unsigned int ADAPTOR_MINOR_VERSION = 2;
-const unsigned int ADAPTOR_MICRO_VERSION = 12;
+const unsigned int ADAPTOR_MICRO_VERSION = 14;
 const char* const  ADAPTOR_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index dd93087..b17bb49 100644 (file)
@@ -17,7 +17,7 @@
 
 Name:       dali2-adaptor
 Summary:    The DALi Tizen Adaptor
-Version:    2.2.12
+Version:    2.2.14
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT