Merge "CanvasRenderer::Drawable: Add GetBoundingBox api" into devel/master
authorjunsu choi <jsuya.choi@samsung.com>
Tue, 25 May 2021 01:43:05 +0000 (01:43 +0000)
committerGerrit Code Review <gerrit@review>
Tue, 25 May 2021 01:43:05 +0000 (01:43 +0000)
78 files changed:
build/tizen/deps-check.cmake
build/tizen/profiles/common-profile.cmake
build/tizen/profiles/mobile-profile.cmake
build/tizen/profiles/tv-profile.cmake
build/tizen/profiles/ubuntu-profile.cmake
dali/devel-api/adaptor-framework/accessibility-impl.cpp
dali/devel-api/adaptor-framework/accessibility-impl.h
dali/devel-api/adaptor-framework/offscreen-window.cpp
dali/devel-api/adaptor-framework/offscreen-window.h
dali/devel-api/adaptor-framework/web-engine-plugin.h
dali/devel-api/adaptor-framework/web-engine.cpp [changed mode: 0644->0755]
dali/devel-api/adaptor-framework/web-engine.h [changed mode: 0644->0755]
dali/devel-api/file.list
dali/devel-api/text-abstraction/hyphenation.cpp [new file with mode: 0644]
dali/devel-api/text-abstraction/hyphenation.h [new file with mode: 0644]
dali/devel-api/text-abstraction/text-abstraction-definitions.h
dali/devel-api/text-abstraction/text-abstraction.h
dali/integration-api/adaptor-framework/native-render-surface.h
dali/internal/accessibility/bridge/accessibility-common.h
dali/internal/accessibility/bridge/bridge-base.cpp
dali/internal/accessibility/bridge/bridge-base.h
dali/internal/accessibility/bridge/bridge-impl.cpp
dali/internal/accessibility/bridge/bridge-object.cpp
dali/internal/accessibility/bridge/dummy-atspi.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.h
dali/internal/graphics/gles-impl/gles-graphics-program.cpp
dali/internal/graphics/gles-impl/gles-graphics-reflection.cpp
dali/internal/graphics/gles-impl/gles-graphics-shader.cpp
dali/internal/graphics/gles-impl/gles-graphics-texture.cpp
dali/internal/graphics/gles/egl-graphics.h
dali/internal/graphics/gles/gl-implementation.h
dali/internal/imaging/android/native-image-source-impl-android.cpp
dali/internal/imaging/common/image-loader.cpp
dali/internal/imaging/common/loader-webp.cpp [new file with mode: 0644]
dali/internal/imaging/common/loader-webp.h [new file with mode: 0644]
dali/internal/imaging/common/webp-loading.cpp
dali/internal/imaging/file.list
dali/internal/imaging/tizen/native-image-source-impl-tizen.cpp
dali/internal/imaging/tizen/native-image-source-impl-tizen.h
dali/internal/imaging/tizen/native-image-source-queue-impl-tizen.cpp
dali/internal/imaging/tizen/native-image-source-queue-impl-tizen.h
dali/internal/offscreen/common/offscreen-window-impl.cpp
dali/internal/offscreen/common/offscreen-window-impl.h
dali/internal/system/common/environment-variables.h
dali/internal/text/file.list
dali/internal/text/text-abstraction/hyphenation-impl.cpp [new file with mode: 0644]
dali/internal/text/text-abstraction/hyphenation-impl.h [new file with mode: 0644]
dali/internal/web-engine/common/web-engine-impl.cpp [changed mode: 0644->0755]
dali/internal/web-engine/common/web-engine-impl.h
dali/internal/window-system/android/window-base-android.cpp
dali/internal/window-system/android/window-base-android.h
dali/internal/window-system/common/gl-window-impl.cpp
dali/internal/window-system/common/gl-window-impl.h
dali/internal/window-system/common/gl-window-render-thread.cpp
dali/internal/window-system/common/gl-window-render-thread.h
dali/internal/window-system/common/window-base.cpp
dali/internal/window-system/common/window-base.h
dali/internal/window-system/common/window-impl.cpp
dali/internal/window-system/common/window-impl.h
dali/internal/window-system/common/window-render-surface.cpp
dali/internal/window-system/macos/window-base-mac.h
dali/internal/window-system/macos/window-base-mac.mm
dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp
dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.h
dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp
dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h
dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp
dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h
dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp
dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h
dali/internal/window-system/windows/window-base-win.cpp
dali/internal/window-system/windows/window-base-win.h
dali/public-api/adaptor-framework/window-enumerations.h
dali/public-api/adaptor-framework/window.cpp
dali/public-api/adaptor-framework/window.h
dali/public-api/dali-adaptor-version.cpp
packaging/dali-adaptor.spec

index 8dee1e7..449d848 100644 (file)
@@ -74,6 +74,7 @@ CHECK_MODULE_AND_SET( LIBEXIF libexif [] )
 CHECK_MODULE_AND_SET( LIBDRM libdrm [] )
 CHECK_MODULE_AND_SET( LIBCURL libcurl [] )
 CHECK_MODULE_AND_SET( HARFBUZZ harfbuzz [] )
+CHECK_MODULE_AND_SET( HYPHEN libhyphen [] )
 CHECK_MODULE_AND_SET( FRIBIDI fribidi [] )
 CHECK_MODULE_AND_SET( CAIRO cairo [] )
 CHECK_MODULE_AND_SET( EVAS evas [] )
@@ -299,6 +300,13 @@ IF (NOT APPLE)
     -lturbojpeg
     -ljpeg
   )
+
+if( NOT ANDROID_PROFILE )
+  SET( DALI_LDFLAGS ${DALI_LDFLAGS}
+    -lhyphen
+  )
+ENDIF()
+
 ENDIF()
 
 # Android includes pthread with android lib
index 408643d..f2bcbc1 100755 (executable)
@@ -79,3 +79,26 @@ IF( COMPONENT_APPLICATION_SUPPORT )
       )
 ENDIF()
 
+# Set the linker flags
+SET(REQUIRED_LIBS
+  -lhyphen
+)
+
+FIND_LIBRARY( HYPHEN_LIBRARY NAMES hyphen )
+IF (${HYPHEN_LIBRARY} MATCHES "HYPHEN_LIBRARY-NOTFOUND")
+  UNSET (HYPHEN_LIBRARY_AVAILABLE)
+ELSE()
+  SET (HYPHEN_LIBRARY_AVAILABLE "HYPHEN_LIBRARY_AVAILABLE")
+  ADD_DEFINITIONS(-DHYPHEN_LIBRARY_AVAILABLE="${HYPHEN_LIBRARY_AVAILABLE}")
+
+  #The path of hyphen library dictionary
+  IF (NOT "${HYPHEN_DIC}")
+  FIND_PATH(HYPHEN_DIC hyph_en_US.dic HINTS "/usr/local/share/hyphen" "/usr/share/hyphen" )
+  IF ( NOT HYPHEN_DIC MATCHES  "HYPHEN_DIC-NOTFOUND")
+    ADD_DEFINITIONS(-DHYPHEN_DIC="${HYPHEN_DIC}")
+  ENDIF()
+  ENDIF()
+  MESSAGE (HYPHEN_DIC: "${HYPHEN_DIC}")
+
+ENDIF()
+
index 7726cc0..ef877a4 100755 (executable)
@@ -79,3 +79,25 @@ IF( COMPONENT_APPLICATION_SUPPORT )
       )
 ENDIF()
 
+# Set the linker flags
+SET(REQUIRED_LIBS
+  -lhyphen
+)
+
+FIND_LIBRARY( HYPHEN_LIBRARY NAMES hyphen )
+IF (${HYPHEN_LIBRARY} MATCHES "HYPHEN_LIBRARY-NOTFOUND")
+  UNSET (HYPHEN_LIBRARY_AVAILABLE)
+ELSE()
+  SET (HYPHEN_LIBRARY_AVAILABLE "HYPHEN_LIBRARY_AVAILABLE")
+  ADD_DEFINITIONS(-DHYPHEN_LIBRARY_AVAILABLE="${HYPHEN_LIBRARY_AVAILABLE}")
+
+  #The path of hyphen library dictionary
+  IF (NOT "${HYPHEN_DIC}")
+  FIND_PATH(HYPHEN_DIC hyph_en_US.dic HINTS "/usr/local/share/hyphen" "/usr/share/hyphen" )
+  IF ( NOT HYPHEN_DIC MATCHES  "HYPHEN_DIC-NOTFOUND")
+    ADD_DEFINITIONS(-DHYPHEN_DIC="${HYPHEN_DIC}")
+  ENDIF()
+  ENDIF()
+  MESSAGE (HYPHEN_DIC: "${HYPHEN_DIC}")
+
+ENDIF()
index b7858ed..5f8e8e1 100755 (executable)
@@ -79,3 +79,26 @@ IF( COMPONENT_APPLICATION_SUPPORT )
       )
 ENDIF()
 
+# Set the linker flags
+SET(REQUIRED_LIBS
+  -lhyphen
+)
+
+FIND_LIBRARY( HYPHEN_LIBRARY NAMES hyphen )
+IF (${HYPHEN_LIBRARY} MATCHES "HYPHEN_LIBRARY-NOTFOUND")
+  UNSET (HYPHEN_LIBRARY_AVAILABLE)
+ELSE()
+  SET (HYPHEN_LIBRARY_AVAILABLE "HYPHEN_LIBRARY_AVAILABLE")
+  ADD_DEFINITIONS(-DHYPHEN_LIBRARY_AVAILABLE="${HYPHEN_LIBRARY_AVAILABLE}")
+
+  #The path of hyphen library dictionary
+  IF (NOT "${HYPHEN_DIC}")
+  FIND_PATH(HYPHEN_DIC hyph_en_US.dic HINTS "/usr/local/share/hyphen" "/usr/share/hyphen" )
+  IF ( NOT HYPHEN_DIC MATCHES  "HYPHEN_DIC-NOTFOUND")
+    ADD_DEFINITIONS(-DHYPHEN_DIC="${HYPHEN_DIC}")
+  ENDIF()
+  ENDIF()
+  MESSAGE (HYPHEN_DIC: "${HYPHEN_DIC}")
+
+ENDIF()
+
index 6e35138..26abe3e 100755 (executable)
@@ -147,4 +147,25 @@ SET(REQUIRED_LIBS ${ECORE_LDFLAGS}
   -lpthread
   -lturbojpeg
   -ljpeg
+  -lhyphen
 )
+
+
+FIND_LIBRARY( HYPHEN_LIBRARY NAMES hyphen )
+IF (${HYPHEN_LIBRARY} MATCHES "HYPHEN_LIBRARY-NOTFOUND")
+  UNSET (HYPHEN_LIBRARY_AVAILABLE)
+ELSE()
+  SET (HYPHEN_LIBRARY_AVAILABLE "HYPHEN_LIBRARY_AVAILABLE")
+  ADD_DEFINITIONS(-DHYPHEN_LIBRARY_AVAILABLE="${HYPHEN_LIBRARY_AVAILABLE}")
+
+  #The path of hyphen library dictionary
+  IF (NOT "${HYPHEN_DIC}")
+  FIND_PATH(HYPHEN_DIC hyph_en_US.dic HINTS "/usr/local/share/hyphen" "/usr/share/hyphen" )
+  IF ( NOT HYPHEN_DIC MATCHES  "HYPHEN_DIC-NOTFOUND")
+    ADD_DEFINITIONS(-DHYPHEN_DIC="${HYPHEN_DIC}")
+  ENDIF()
+  ENDIF()
+  MESSAGE (HYPHEN_DIC: "${HYPHEN_DIC}")
+
+ENDIF()
+
index 3db97a8..826ba37 100644 (file)
@@ -730,7 +730,7 @@ public:
     Dali::TypeInfo type;
     Self().GetTypeInfo(type);
     return {
-      {"t", type.GetName()},
+      {"class", type.GetName()},
     };
   }
 
index 31226a6..c2741d2 100644 (file)
@@ -294,9 +294,6 @@ struct DALI_ADAPTOR_API Bridge
   /**
    * @brief Re-enables auto-initialization of AT-SPI bridge
    *
-   * @param topLevelWindow Accessible object for Scene::GetRootLayer()
-   * @param applicationName Application name
-   *
    * Normal applications do not have to call this function. GetCurrentBridge() tries to
    * initialize the AT-SPI bridge when it is called for the first time.
    *
@@ -304,7 +301,7 @@ struct DALI_ADAPTOR_API Bridge
    * @see Dali::Accessibility::Bridge::AddTopLevelWindow
    * @see Dali::Accessibility::Bridge::SetApplicationName
    */
-  static void EnableAutoInit(Accessible* topLevelWindow, const std::string& applicationName);
+  static void EnableAutoInit();
 
 protected:
   struct Data
index 020eca4..42cc8eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -103,9 +103,9 @@ Uint16Pair OffscreenWindow::GetDpi() const
   return Internal::GetImplementation(*this).GetDpi();
 }
 
-OffscreenWindow::PostRenderSignalType& OffscreenWindow::PostRenderSignal()
+void OffscreenWindow::SetPostRenderCallback(CallbackBase* callback)
 {
-  return Internal::GetImplementation(*this).PostRenderSignal();
+  Internal::GetImplementation(*this).SetPostRenderCallback(callback);
 }
 
 OffscreenWindow::OffscreenWindow(Internal::OffscreenWindow* window)
index 5e2b502..1c2e144 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_OFFSCREEN_WINDOW_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -22,7 +22,6 @@
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/math/uint-16-pair.h>
 #include <dali/public-api/object/any.h>
-#include <dali/public-api/signals/dali-signal.h>
 
 // INTERNAL INCLUDES
 #include <dali/public-api/dali-adaptor-common.h>
@@ -44,8 +43,7 @@ class OffscreenWindow;
 class DALI_ADAPTOR_API OffscreenWindow : public Dali::BaseHandle
 {
 public:
-  using WindowSize           = Uint16Pair;
-  using PostRenderSignalType = Signal<void(OffscreenWindow, Any)>;
+  using WindowSize = Uint16Pair;
 
 public:
   /**
@@ -176,13 +174,18 @@ public:
    */
   Uint16Pair GetDpi() const;
 
-public: // Signals
   /**
-   * @brief This signal is emitted when the OffscreenWindow is rendered.
+   * @brief Sets the PostRenderCallback of the OffscreenWindow.
+   *
+   * @param[in] callback The PostRenderCallback function
+   * @code
+   *   void MyFunction( OffscreenWindow window, Any nativeSurface );
+   * @endcode
+   *
+   * @note Ownership of the callback is passed onto this class.
    *
-   * @return The signal
    */
-  PostRenderSignalType& PostRenderSignal();
+  void SetPostRenderCallback(CallbackBase* callback);
 
 public: // Not intended for application developers
   /**
index ec8cde0..421ca6f 100755 (executable)
@@ -159,9 +159,9 @@ public:
   using WebEngineFrameRenderedSignalType = Signal<void(void)>;
 
   /**
-   * @brief WebView signal type related with policy would be decided.
+   * @brief WebView signal type related with response policy would be decided.
    */
-  using WebEnginePolicyDecisionSignalType = Signal<void(std::shared_ptr<Dali::WebEnginePolicyDecision>)>;
+  using WebEngineResponsePolicyDecisionSignalType = Signal<void(std::shared_ptr<Dali::WebEnginePolicyDecision>)>;
 
   /**
    * @brief Hit test callback called after hit test is created asynchronously.
@@ -819,11 +819,11 @@ public:
   virtual WebEngineConsoleMessageSignalType& ConsoleMessageSignal() = 0;
 
   /**
-   * @brief Connect to this signal to be notified when new policy would be decided.
+   * @brief Connect to this signal to be notified when response policy would be decided.
    *
    * @return A signal object to connect with.
    */
-  virtual WebEnginePolicyDecisionSignalType& PolicyDecisionSignal() = 0;
+  virtual WebEngineResponsePolicyDecisionSignalType& ResponsePolicyDecisionSignal() = 0;
 
   /**
    * @brief Connect to this signal to be notified when certificate need be confirmed.
old mode 100644 (file)
new mode 100755 (executable)
index 21806f7..c273867
@@ -527,9 +527,9 @@ Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& WebEngine::ConsoleMess
   return GetImplementation(*this).ConsoleMessageSignal();
 }
 
-Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& WebEngine::PolicyDecisionSignal()
+Dali::WebEnginePlugin::WebEngineResponsePolicyDecisionSignalType& WebEngine::ResponsePolicyDecisionSignal()
 {
-  return GetImplementation(*this).PolicyDecisionSignal();
+  return GetImplementation(*this).ResponsePolicyDecisionSignal();
 }
 
 Dali::WebEnginePlugin::WebEngineCertificateSignalType& WebEngine::CertificateConfirmSignal()
old mode 100644 (file)
new mode 100755 (executable)
index f461e46..99cc150
@@ -702,11 +702,11 @@ public:
   Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& ConsoleMessageSignal();
 
   /**
-   * @brief Connect to this signal to be notified when new policy would be decided.
+   * @brief Connect to this signal to be notified when response policy would be decided.
    *
    * @return A signal object to connect with.
    */
-  Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& PolicyDecisionSignal();
+  Dali::WebEnginePlugin::WebEngineResponsePolicyDecisionSignalType& ResponsePolicyDecisionSignal();
 
   /**
    * @brief Connect to this signal to be notified when certificate need be confirmed.
index edf8862..9564cc7 100755 (executable)
@@ -135,6 +135,7 @@ SET( devel_api_text_abstraction_src_files
    ${adaptor_devel_api_dir}/text-abstraction/shaping.cpp
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer.cpp
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.cpp
+   ${adaptor_devel_api_dir}/text-abstraction/hyphenation.cpp
 )
 
 
@@ -152,4 +153,5 @@ SET( text_abstraction_header_files
    ${adaptor_devel_api_dir}/text-abstraction/text-abstraction-definitions.h
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer.h
    ${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.h
+   ${adaptor_devel_api_dir}/text-abstraction/hyphenation.h
 )
diff --git a/dali/devel-api/text-abstraction/hyphenation.cpp b/dali/devel-api/text-abstraction/hyphenation.cpp
new file mode 100644 (file)
index 0000000..40a0da4
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/devel-api/text-abstraction/hyphenation.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/text/text-abstraction/hyphenation-impl.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+Hyphenation::Hyphenation()
+{
+}
+
+Hyphenation::~Hyphenation()
+{
+}
+
+Hyphenation::Hyphenation(Internal::Hyphenation* impl)
+: BaseHandle(impl)
+{
+}
+
+Hyphenation Hyphenation::Get()
+{
+  return Internal::Hyphenation::Get();
+}
+
+const char* Hyphenation::GetDictionaryEncoding(const char* lang)
+{
+  return GetImplementation(*this).GetDictionaryEncoding(lang);
+}
+
+Vector<bool> Hyphenation::GetWordHyphens(const char* word,
+                                         Length      wordSize,
+                                         const char* lang)
+{
+  return GetImplementation(*this).GetWordHyphens(word,
+                                                 wordSize,
+                                                 lang);
+}
+
+} // namespace TextAbstraction
+
+} // namespace Dali
diff --git a/dali/devel-api/text-abstraction/hyphenation.h b/dali/devel-api/text-abstraction/hyphenation.h
new file mode 100644 (file)
index 0000000..b8d5cfe
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef DALI_PLATFORM_TEXT_ABSTRACTION_HYPHENATION_H
+#define DALI_PLATFORM_TEXT_ABSTRACTION_HYPHENATION_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
+#include <dali/public-api/dali-adaptor-common.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace Internal DALI_INTERNAL
+{
+class Hyphenation;
+
+} // namespace DALI_INTERNAL
+
+/**
+ * @brief Hyphenation provides an interface to retrieve possible hyphenation of the text.
+ *
+ * This module get the hyphen positions for a word.
+ * To get the hyphen positions it needs to load the dictionary for the word language.
+ * also it need the word to be send using the correct encoding which can be known using
+ *
+ * @code
+ * Hyphenation hyphenation = Hyphenation::Get();
+ *
+ * Character* text = "Hyphenation";
+ *
+ * // get a vector of booleans that indicates possible hyphen locations.
+ * Vector<bool> *hyphens = hyphenation.GetWordHyphens(text, 11, "en_US");
+ *
+ * @endcode
+ */
+class DALI_ADAPTOR_API Hyphenation : public BaseHandle
+{
+public:
+  /**
+   * @brief Create an uninitialized Hyphenation handle.
+   *
+   */
+  Hyphenation();
+
+  /**
+   * @brief Destructor
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   */
+  ~Hyphenation();
+
+  /**
+   * @brief This constructor is used by Hyphenation::Get().
+   *
+   * @param[in] implementation A pointer to the internal hyphenation object.
+   */
+  explicit DALI_INTERNAL Hyphenation(Internal::Hyphenation* implementation);
+
+  /**
+   * @brief Retrieve a handle to the Hyphenation instance.
+   *
+   * @return A handle to the Hyphenation.
+   */
+  static Hyphenation Get();
+
+  /**
+   *
+   * Gets the encoding of the dictionary for the given language
+   *
+   * @param[in] lang language to get encoding for (en_US).
+   *
+   * @return The encoding of the language (UTF-32).
+   */
+  const char* GetDictionaryEncoding(const char* lang);
+
+  /**
+   * Gets a vector booleans that indicates possible hyphen locations.
+   *
+   * @param[in] word the word to get possible hyphens for.
+   * @param[in] wordSize the word size in bytes.
+   * @param[in] lang the language for the word
+   *
+   * @return vector of boolean, true if possible to hyphenate at this character position.
+   */
+  Vector<bool> GetWordHyphens(const char* word,
+                              Length      wordSize,
+                              const char* lang);
+};
+
+} // namespace TextAbstraction
+
+} // namespace Dali
+
+#endif // DALI_PLATFORM_TEXT_ABSTRACTION_HYPHENATION_H
index 9159653..e100ef8 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEXT_ABSTRACTION_DEFINITIONS_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -43,9 +43,12 @@ typedef uint32_t ColorIndex;         ///< An index into an array of colors.
  */
 enum
 {
-  LINE_MUST_BREAK  = 0u, ///< Text must be broken into a new line.
-  LINE_ALLOW_BREAK = 1u, ///< Is possible to break the text into a new line.
-  LINE_NO_BREAK    = 2u  ///< Text can't be broken into a new line.
+  LINE_MUST_BREAK        = 0u, ///< Text must be broken into a new line.
+  LINE_ALLOW_BREAK       = 1u, ///< Is possible to break the text into a new line.
+  LINE_NO_BREAK          = 2u, ///< Text can't be broken into a new line.
+  LINE_INSIDEACHAR       = 3u, ///< A UTF-8/16 sequence is unfinished.
+  LINE_INDETERMINATE     = 4u, ///< End of input on a non-EOL char.
+  LINE_HYPHENATION_BREAK = 5u  ///< Text can be broken with adding hyphen.
 };
 
 /**
index 3a9309e..9361f17 100755 (executable)
@@ -26,5 +26,6 @@
 #include <dali/devel-api/text-abstraction/script.h>
 #include <dali/devel-api/text-abstraction/segmentation.h>
 #include <dali/devel-api/text-abstraction/shaping.h>
+#include <dali/devel-api/text-abstraction/hyphenation.h>
 
 #endif // DALI_TEXT_ABSTRACTION_H
index c15f139..c55be78 100644 (file)
@@ -44,12 +44,6 @@ public:
 
 public: // API
   /**
-   * @brief Get the render surface the adaptor is using to render to.
-   * @return reference to current render surface
-   */
-  virtual Any GetDrawable() = 0;
-
-  /**
    * @brief Sets the render notification trigger to call when render thread is completed a frame
    * @param renderNotification to use
    */
@@ -67,11 +61,6 @@ private: // from NativeRenderSurface
    */
   virtual void CreateNativeRenderable() = 0;
 
-  /**
-   * @brief Release a drawable
-   */
-  virtual void ReleaseDrawable() = 0;
-
 protected:
   // Undefined
   NativeRenderSurface(const NativeRenderSurface&) = delete;
index cdb92e1..d9165f6 100644 (file)
@@ -34,6 +34,8 @@
 #define A11yDbusPath "/org/a11y/bus"
 #define A11yDbusStatusInterface "org.a11y.Status"
 #define AtspiDbusNameRegistry "org.a11y.atspi.Registry"
+#define AtspiDbusPathRegistry "/org/a11y/atspi/registry"
+#define AtspiDbusInterfaceRegistry "org.a11y.atspi.Registry"
 #define AtspiDbusPathRoot "/org/a11y/atspi/accessible/root"
 #define AtspiDbusInterfaceSocket "org.a11y.atspi.Socket"
 #define AtspiPath "/org/a11y/atspi/accessible"
index 9f1da75..dcca27b 100644 (file)
@@ -88,6 +88,29 @@ bool BridgeBase::tickFilteredEvents()
   return !filteredEvents.empty();
 }
 
+void BridgeBase::RegisteredEventsUpdate()
+{
+  using ReturnType = std::vector<std::tuple<std::string, std::string>>;
+  registry.method<DBus::ValueOrError<ReturnType>()>( "GetRegisteredEvents" ).asyncCall([this](DBus::ValueOrError<ReturnType> msg) {
+    if(!msg)
+    {
+      LOG() << "Get registered events failed";
+      return;
+    }
+
+    allowObjectBoundsChangedEvent = false;
+
+    ReturnType values = std::get<ReturnType>(msg.getValues());
+    for(long unsigned int i = 0; i < values.size(); i++)
+    {
+      if (!std::get<1>(values[i]).compare("Object:BoundsChanged"))
+      {
+        allowObjectBoundsChangedEvent = true;
+      }
+    }
+  });
+}
+
 BridgeBase::ForceUpResult BridgeBase::ForceUp()
 {
   if(Bridge::ForceUp() == ForceUpResult::ALREADY_UP)
@@ -117,12 +140,25 @@ BridgeBase::ForceUpResult BridgeBase::ForceUp()
     dbusServer.addInterface(AtspiPath, desc);
   }
 
+  registry = {AtspiDbusNameRegistry, AtspiDbusPathRegistry, AtspiDbusInterfaceRegistry, con};
+
+  RegisteredEventsUpdate();
+
+  registry.addSignal<void(void)>("EventListenerRegistered", [this](void) {
+    RegisteredEventsUpdate();
+  });
+
+  registry.addSignal<void(void)>("EventListenerDeregistered", [this](void) {
+    RegisteredEventsUpdate();
+  });
+
   return ForceUpResult::JUST_STARTED;
 }
 
 void BridgeBase::ForceDown()
 {
   Bridge::ForceDown();
+  registry   = {};
   dbusServer = {};
   con        = {};
 }
index e14f864..7361181 100644 (file)
@@ -275,6 +275,7 @@ protected:
 private:
   void IdSet(int id);
   int  IdGet();
+  void RegisteredEventsUpdate();
 
   using CacheElementType = std::tuple<
     Dali::Accessibility::Address,
@@ -299,6 +300,8 @@ protected:
   DBus::DBusServer           dbusServer;
   DBusWrapper::ConnectionPtr con;
   int                        id = 0;
+  DBus::DBusClient           registry;
+  bool                       allowObjectBoundsChangedEvent{false};
 };
 
 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_BASE_H
index 49b2edc..216b89b 100644 (file)
@@ -18,6 +18,8 @@
 // CLASS HEADER
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/layer.h>
+#include <dali/devel-api/common/stage.h>
 #include <dali/integration-api/debug.h>
 #include <iostream>
 #include <unordered_map>
 #include <dali/internal/accessibility/bridge/bridge-text.h>
 #include <dali/internal/accessibility/bridge/bridge-value.h>
 #include <dali/internal/accessibility/bridge/dummy-atspi.h>
+#include <dali/internal/adaptor/common/adaptor-impl.h>
 #include <dali/internal/system/common/environment-variables.h>
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 
 using namespace Dali::Accessibility;
 
@@ -370,6 +374,14 @@ Bridge* Bridge::GetCurrentBridge()
   else if (autoInitState == AutoInitState::ENABLED)
   {
     bridge = CreateBridge();
+
+    /* check environment variable for suppressing screen-reader */
+    const char *envSuppressScreenReader = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_SUPPRESS_SCREEN_READER);
+    if (envSuppressScreenReader && std::atoi(envSuppressScreenReader) != 0)
+    {
+      bridge->SuppressScreenReader(true);
+    }
+
     return bridge;
   }
 
@@ -386,7 +398,7 @@ void Bridge::DisableAutoInit()
   autoInitState = AutoInitState::DISABLED;
 }
 
-void Bridge::EnableAutoInit(Accessible* topLevelWindow, const std::string& applicationName)
+void Bridge::EnableAutoInit()
 {
   autoInitState = AutoInitState::ENABLED;
 
@@ -395,8 +407,17 @@ void Bridge::EnableAutoInit(Accessible* topLevelWindow, const std::string& appli
     return;
   }
 
+  auto rootLayer = Dali::Stage::GetCurrent().GetRootLayer();
+  auto window = Dali::DevelWindow::Get(rootLayer);
+  auto applicationName = Dali::Internal::Adaptor::Adaptor::GetApplicationPackageName();
+
   auto* bridge = Bridge::GetCurrentBridge();
-  bridge->AddTopLevelWindow(topLevelWindow);
+  bridge->AddTopLevelWindow(Dali::Accessibility::Accessible::Get(rootLayer, true));
   bridge->SetApplicationName(applicationName);
   bridge->Initialize();
+
+  if(window && window.IsVisible())
+  {
+    bridge->ApplicationShown();
+  }
 }
index e91f2e8..06bb80d 100644 (file)
@@ -496,6 +496,8 @@ void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue1,
 
 void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
 {
+  if(!allowObjectBoundsChangedEvent) return;
+
   auto        addr       = obj->GetAddress();
   const auto  prefixPath = "/org/a11y/atspi/accessible/";
   const auto  nullPath   = "/org/a11y/atspi/null";
index cd7dbec..d63b02a 100644 (file)
@@ -79,7 +79,7 @@ void Accessibility::Bridge::DisableAutoInit()
 {
 }
 
-void Accessibility::Bridge::EnableAutoInit(Accessible*, const std::string&)
+void Accessibility::Bridge::EnableAutoInit()
 {
 }
 
index 8fe7b73..4ec725d 100644 (file)
@@ -88,6 +88,9 @@ T0* CastObject(T1* apiObject)
   return static_cast<T0*>(apiObject);
 }
 
+// Maximum size of texture upload buffer.
+const uint32_t TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB = 1;
+
 } // namespace
 
 EglGraphicsController::~EglGraphicsController() = default;
@@ -398,6 +401,8 @@ void EglGraphicsController::UpdateTextures(const std::vector<TextureUpdateInfo>&
                   reinterpret_cast<char*>(source.memorySource.memory) + info.srcSize,
                   stagingBuffer);
 
+        mTextureUploadTotalCPUMemoryUsed += info.srcSize;
+
         // store staging buffer
         source.memorySource.memory = stagingBuffer;
         break;
@@ -414,6 +419,13 @@ void EglGraphicsController::UpdateTextures(const std::vector<TextureUpdateInfo>&
       }
     }
   }
+
+  // If upload buffer exceeds maximum size, flush.
+  if( mTextureUploadTotalCPUMemoryUsed > TEXTURE_UPLOAD_MAX_BUFER_SIZE_MB*1024 )
+  {
+    Flush();
+    mTextureUploadTotalCPUMemoryUsed = 0;
+  }
 }
 
 Graphics::UniquePtr<Memory> EglGraphicsController::MapBufferRange(const MapBufferInfo& mapInfo)
index 8317fd8..6886380 100644 (file)
@@ -562,6 +562,8 @@ private:
 
   std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
 
+  uint32_t mTextureUploadTotalCPUMemoryUsed {0u};
+
   bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
 };
 
index 484f400..64de708 100644 (file)
@@ -82,8 +82,14 @@ bool ProgramImpl::Destroy()
 bool ProgramImpl::Create()
 {
   // Create and link new program
-  auto& gl      = *mImpl->controller.GetGL();
-  auto  program = gl.CreateProgram();
+  auto gl = mImpl->controller.GetGL();
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return false;
+  }
+
+  auto program = gl->CreateProgram();
 
   const auto& info = mImpl->createInfo;
   for(const auto& state : *info.shaderState)
@@ -93,23 +99,23 @@ bool ProgramImpl::Create()
     // Compile shader first (ignored when compiled)
     if(shader->Compile())
     {
-      gl.AttachShader(program, shader->GetGLShader());
+      gl->AttachShader(program, shader->GetGLShader());
     }
   }
-  gl.LinkProgram(program);
+  gl->LinkProgram(program);
 
   GLint status{0};
-  gl.GetProgramiv(program, GL_LINK_STATUS, &status);
+  gl->GetProgramiv(program, GL_LINK_STATUS, &status);
   if(status != GL_TRUE)
   {
     char    output[4096];
     GLsizei size{0u};
-    gl.GetProgramInfoLog(program, 4096, &size, output);
+    gl->GetProgramInfoLog(program, 4096, &size, output);
 
     // log on error
     // TODO: un-printf-it
     printf("Log: %s\n", output);
-    gl.DeleteProgram(program);
+    gl->DeleteProgram(program);
     return false;
   }
 
index 20be64f..86a26b7 100644 (file)
@@ -16,6 +16,8 @@
  */
 
 #include "gles-graphics-reflection.h"
+
+#include <dali/integration-api/debug.h>
 #include <dali/integration-api/gl-abstraction.h>
 #include <dali/integration-api/gl-defines.h>
 
@@ -114,6 +116,11 @@ void Reflection::BuildVertexAttributeReflection()
   char*  name;
 
   auto gl = mController.GetGL();
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return;
+  }
 
   gl->GetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
   gl->GetProgramiv(glProgram, GL_ACTIVE_ATTRIBUTES, &nAttribs);
@@ -149,6 +156,11 @@ void Reflection::BuildUniformReflection()
   int numUniforms = 0;
 
   auto gl = mController.GetGL();
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return;
+  }
 
   gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
   gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
@@ -253,6 +265,13 @@ void Reflection::BuildUniformBlockReflection()
   auto gl               = mController.GetGL();
   auto glProgram        = mProgram.GetGlProgram();
   int  numUniformBlocks = 0;
+
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return;
+  }
+
   gl->GetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
 
   mUniformBlocks.clear();
@@ -514,17 +533,24 @@ std::vector<Dali::Graphics::UniformInfo> Reflection::GetSamplers() const
 
 Graphics::ShaderLanguage Reflection::GetLanguage() const
 {
+  auto version = Graphics::ShaderLanguage::GLSL_3_2;
+
   auto gl = mController.GetGL();
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return version;
+  }
 
   int majorVersion, minorVersion;
   gl->GetIntegerv(GL_MAJOR_VERSION, &majorVersion);
   gl->GetIntegerv(GL_MINOR_VERSION, &minorVersion);
-  printf("GL Version (integer) : %d.%d\n", majorVersion, minorVersion);
-  printf("GLSL Version : %s\n", gl->GetString(GL_SHADING_LANGUAGE_VERSION));
+  DALI_LOG_RELEASE_INFO("GL Version (integer) : %d.%d\n", majorVersion, minorVersion);
+  DALI_LOG_RELEASE_INFO("GLSL Version : %s\n", gl->GetString(GL_SHADING_LANGUAGE_VERSION));
 
   // TODO: the language version is hardcoded for now, but we may use what we get
   // from GL_SHADING_LANGUAGE_VERSION?
-  return Graphics::ShaderLanguage::GLSL_3_2;
+  return version;
 }
 
 } // namespace Dali::Graphics::GLES
index 46a2968..60f9a34 100644 (file)
@@ -19,6 +19,7 @@
 #include "gles-graphics-shader.h"
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
 #include "egl-graphics-controller.h"
 
 namespace Dali::Graphics::GLES
@@ -52,7 +53,13 @@ Shader::~Shader() = default;
 
 bool Shader::Compile() const
 {
-  auto& gl = *GetController().GetGL();
+  auto gl = GetController().GetGL();
+
+  if(!gl)
+  {
+    return false;
+  }
+
   if(!mImpl->glShader)
   {
     GLenum pipelineStage{0u};
@@ -96,22 +103,22 @@ bool Shader::Compile() const
 
     if(pipelineStage)
     {
-      auto       shader = gl.CreateShader(pipelineStage);
+      auto       shader = gl->CreateShader(pipelineStage);
       const auto src    = reinterpret_cast<const char*>(GetCreateInfo().sourceData);
       GLint      size   = GetCreateInfo().sourceSize;
-      gl.ShaderSource(shader, 1, const_cast<const char**>(&src), &size);
-      gl.CompileShader(shader);
+      gl->ShaderSource(shader, 1, const_cast<const char**>(&src), &size);
+      gl->CompileShader(shader);
 
       GLint status{0};
-      gl.GetShaderiv(shader, GL_COMPILE_STATUS, &status);
+      gl->GetShaderiv(shader, GL_COMPILE_STATUS, &status);
       if(status != GL_TRUE)
       {
         char    output[4096];
         GLsizei size{0u};
-        gl.GetShaderInfoLog(shader, 4096, &size, output);
-        printf("Code: %s\n", reinterpret_cast<const char*>(GetCreateInfo().sourceData));
-        printf("Log: %s\n", output);
-        gl.DeleteShader(shader);
+        gl->GetShaderInfoLog(shader, 4096, &size, output);
+        DALI_LOG_RELEASE_INFO("Code: %s\n", reinterpret_cast<const char*>(GetCreateInfo().sourceData));
+        DALI_LOG_RELEASE_INFO("Log: %s\n", output);
+        gl->DeleteShader(shader);
         return false;
       }
 
@@ -146,4 +153,4 @@ void Shader::DiscardResource()
   GetController().DiscardResource(this);
 }
 
-} // namespace Dali::Graphics::GLES
\ No newline at end of file
+} // namespace Dali::Graphics::GLES
index 738e02c..cf91080 100644 (file)
@@ -73,6 +73,12 @@ bool Texture::InitializeNativeImage()
   auto   gl = mController.GetGL();
   GLuint texture{0};
 
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return false;
+  }
+
   NativeImageInterfacePtr nativeImage = mCreateInfo.nativeImagePtr;
   bool                    created     = nativeImage->CreateResource();
   mGlTarget                           = nativeImage->GetTextureTarget();
@@ -113,6 +119,11 @@ bool Texture::InitializeNativeImage()
 bool Texture::InitializeTexture()
 {
   auto gl = mController.GetGL();
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return false;
+  }
 
   GLuint texture{0};
 
@@ -189,6 +200,11 @@ void Texture::DiscardResource()
 void Texture::Bind(const TextureBinding& binding) const
 {
   auto gl = mController.GetGL();
+  if(!gl)
+  {
+    // Do nothing during shutdown
+    return;
+  }
 
   gl->ActiveTexture(GL_TEXTURE0 + binding.binding);
   gl->BindTexture(mGlTarget, mTextureId);
index a278d43..30f6e58 100644 (file)
@@ -180,6 +180,11 @@ public:
     return mGLES->GetShadingLanguageVersion();
   }
 
+  const char* GetEglImageExtensionString()
+  {
+    return mGLES->GetEglImageExtensionString();
+  }
+
   void CacheConfigurations(ConfigurationManager& configurationManager) override;
 
 private:
index bcc8c86..40d764d 100644 (file)
@@ -40,19 +40,23 @@ namespace Adaptor
 {
 namespace
 {
-const int32_t INITIAL_GLES_VERSION                         = 30;
-const int32_t GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
-const char*   KHR_BLEND_EQUATION_ADVANCED                  = "GL_KHR_blend_equation_advanced";
+static constexpr int32_t     INITIAL_GLES_VERSION                         = 30;
+static constexpr int32_t     GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED = 32;
+static constexpr const char* KHR_BLEND_EQUATION_ADVANCED                  = "GL_KHR_blend_equation_advanced";
 
-const char* FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX =
+static constexpr const char* FRAGMENT_SHADER_ADVANCED_BLEND_EQUATION_PREFIX =
   "#extension GL_KHR_blend_equation_advanced : enable\n"
 
   "#if GL_KHR_blend_equation_advanced==1 || __VERSION__>=320\n"
   "  layout(blend_support_all_equations) out;\n"
   "#endif\n";
 
-const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING =
+static constexpr const char* FRAGMENT_SHADER_OUTPUT_COLOR_STRING =
   "out mediump vec4 fragColor;\n";
+
+static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING = "#extension GL_OES_EGL_image_external:require\n";
+
+static constexpr const char* OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3 = "#extension GL_OES_EGL_image_external_essl3:require\n";
 } // namespace
 
 /**
@@ -96,10 +100,14 @@ public:
   {
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
 
-    GLint majorVersion, minorVersion;
-    glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
-    glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
-    mGlesVersion = majorVersion * 10 + minorVersion;
+    // Only change gles version for the device that support above gles 3.0.
+    if(mGlesVersion >= INITIAL_GLES_VERSION)
+    {
+      GLint majorVersion, minorVersion;
+      glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
+      glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
+      mGlesVersion = majorVersion * 10 + minorVersion;
+    }
 
     if(mGlesVersion >= GLES_VERSION_SUPPORT_BLEND_EQUATION_ADVANCED)
     {
@@ -349,6 +357,23 @@ public:
     return mShadingLanguageVersion;
   }
 
+  const char* GetEglImageExtensionString()
+  {
+    ConditionalWait::ScopedLock lock(mContextCreatedWaitCondition);
+    if(!mIsContextCreated)
+    {
+      mContextCreatedWaitCondition.Wait(lock);
+    }
+    if(mShadingLanguageVersion < 300)
+    {
+      return OES_EGL_IMAGE_EXTERNAL_STRING;
+    }
+    else
+    {
+      return OES_EGL_IMAGE_EXTERNAL_STRING_ESSL3;
+    }
+  }
+
   /* OpenGL ES 2.0 */
 
   void ActiveTexture(GLenum texture) override
index c3f8493..0754ecf 100644 (file)
 #include <dali/internal/graphics/common/egl-image-extensions.h>
 #include <dali/internal/graphics/gles/egl-graphics.h>
 
-namespace
-{
-const char* FRAGMENT_PREFIX = "#extension GL_OES_EGL_image_external:require\n";
-const char* SAMPLER_TYPE    = "samplerExternalOES";
-} // namespace
-
 namespace Dali
 {
 namespace Internal
index f0ace20..dbf492c 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/internal/imaging/common/loader-astc.h>
 #include <dali/internal/imaging/common/loader-bmp.h>
 #include <dali/internal/imaging/common/loader-gif.h>
+#include <dali/internal/imaging/common/loader-webp.h>
 #include <dali/internal/imaging/common/loader-ico.h>
 #include <dali/internal/imaging/common/loader-jpeg.h>
 #include <dali/internal/imaging/common/loader-ktx.h>
@@ -61,6 +62,7 @@ enum FileFormats
   FORMAT_JPEG,
   FORMAT_BMP,
   FORMAT_GIF,
+  FORMAT_WEBP,
   FORMAT_KTX,
   FORMAT_ASTC,
   FORMAT_ICO,
@@ -82,6 +84,7 @@ const Dali::ImageLoader::BitmapLoader BITMAP_LOADER_LOOKUP_TABLE[FORMAT_TOTAL_CO
     {Jpeg::MAGIC_BYTE_1, Jpeg::MAGIC_BYTE_2, LoadBitmapFromJpeg, LoadJpegHeader, Bitmap::BITMAP_2D_PACKED_PIXELS},
     {Bmp::MAGIC_BYTE_1,  Bmp::MAGIC_BYTE_2,  LoadBitmapFromBmp,  LoadBmpHeader,  Bitmap::BITMAP_2D_PACKED_PIXELS},
     {Gif::MAGIC_BYTE_1,  Gif::MAGIC_BYTE_2,  LoadBitmapFromGif,  LoadGifHeader,  Bitmap::BITMAP_2D_PACKED_PIXELS},
+    {Webp::MAGIC_BYTE_1, Webp::MAGIC_BYTE_2, LoadBitmapFromWebp, LoadWebpHeader, Bitmap::BITMAP_2D_PACKED_PIXELS},
     {Ktx::MAGIC_BYTE_1,  Ktx::MAGIC_BYTE_2,  LoadBitmapFromKtx,  LoadKtxHeader,  Bitmap::BITMAP_COMPRESSED      },
     {Astc::MAGIC_BYTE_1, Astc::MAGIC_BYTE_2, LoadBitmapFromAstc, LoadAstcHeader, Bitmap::BITMAP_COMPRESSED      },
     {Ico::MAGIC_BYTE_1,  Ico::MAGIC_BYTE_2,  LoadBitmapFromIco,  LoadIcoHeader,  Bitmap::BITMAP_2D_PACKED_PIXELS},
@@ -107,6 +110,7 @@ const FormatExtension FORMAT_EXTENSIONS[] =
     {".jpg",  FORMAT_JPEG},
     {".bmp",  FORMAT_BMP },
     {".gif",  FORMAT_GIF },
+    {".webp", FORMAT_WEBP },
     {".ktx",  FORMAT_KTX },
     {".astc", FORMAT_ASTC},
     {".ico",  FORMAT_ICO },
diff --git a/dali/internal/imaging/common/loader-webp.cpp b/dali/internal/imaging/common/loader-webp.cpp
new file mode 100644 (file)
index 0000000..37404dd
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/internal/imaging/common/loader-webp.h>
+
+// EXTERNAL INCLUDES
+#ifdef DALI_WEBP_AVAILABLE
+#include <webp/decode.h>
+#include <webp/demux.h>
+
+#if WEBP_DEMUX_ABI_VERSION > 0x0101
+#define DALI_ANIMATED_WEBP_ENABLED 1
+#endif
+#endif
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/debug.h>
+#include <cstring>
+#include <memory>
+
+typedef unsigned char WebPByteType;
+
+namespace Dali
+{
+namespace TizenPlatform
+{
+#ifdef DALI_ANIMATED_WEBP_ENABLED
+bool ReadWebPInformation(FILE* const fp, WebPData& webPData)
+{
+  if(fp == NULL)
+  {
+    return false;
+  }
+
+  if(fseek(fp, 0, SEEK_END) <= -1)
+  {
+    return false;
+  }
+  WebPDataInit(&webPData);
+  webPData.size = ftell(fp);
+
+  if((!fseek(fp, 0, SEEK_SET)))
+  {
+    unsigned char* WebPDataBuffer;
+    WebPDataBuffer = reinterpret_cast<WebPByteType*>(malloc(sizeof(WebPByteType) * webPData.size));
+    webPData.size  = fread(WebPDataBuffer, sizeof(WebPByteType), webPData.size, fp);
+    webPData.bytes = WebPDataBuffer;
+  }
+  else
+  {
+    return false;
+  }
+  return true;
+}
+
+void ReleaseResource(WebPData& webPData, WebPAnimDecoder* webPAnimDecoder)
+{
+  free((void*)webPData.bytes);
+  webPData.bytes = nullptr;
+  WebPDataInit(&webPData);
+  if(webPAnimDecoder)
+  {
+    WebPAnimDecoderDelete(webPAnimDecoder);
+  }
+}
+
+#endif
+
+bool LoadWebpHeader(const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height)
+{
+  FILE* const fp = input.file;
+  if(fp == NULL)
+  {
+    return false;
+  }
+
+  if(fseek(fp, 0, SEEK_END) <= -1)
+  {
+    return false;
+  }
+
+  // If the image is non-animated webp
+#ifdef DALI_WEBP_AVAILABLE
+  size_t webPSize = ftell(fp);
+  if((!fseek(fp, 0, SEEK_SET)))
+  {
+    std::vector<uint8_t> encodedImage;
+    encodedImage.resize(webPSize, 0);
+    size_t readCount = fread(&encodedImage[0], sizeof(uint8_t), encodedImage.size(), fp);
+    if(readCount != encodedImage.size())
+    {
+      return false;
+    }
+    int32_t imageWidth, imageHeight;
+    if(WebPGetInfo(&encodedImage[0], encodedImage.size(), &imageWidth, &imageHeight))
+    {
+      width  = static_cast<uint32_t>(imageWidth);
+      height = static_cast<uint32_t>(imageHeight);
+      return true;
+    }
+  }
+#endif
+
+  // If the image is animated webp
+#ifdef DALI_ANIMATED_WEBP_ENABLED
+  WebPData         webPData;
+  WebPAnimDecoder* webPAnimDecoder;
+  WebPAnimInfo     webPAnimInfo;
+  if(ReadWebPInformation(fp, webPData))
+  {
+    WebPAnimDecoderOptions webPAnimDecoderOptions;
+    WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions);
+    webPAnimDecoderOptions.color_mode = MODE_RGBA;
+    webPAnimDecoder                   = WebPAnimDecoderNew(&webPData, &webPAnimDecoderOptions);
+    if(webPAnimDecoder != nullptr)
+    {
+      WebPAnimDecoderGetInfo(webPAnimDecoder, &webPAnimInfo);
+      width  = webPAnimInfo.canvas_width;
+      height = webPAnimInfo.canvas_height;
+      return true;
+    }
+  }
+  ReleaseResource(webPData, webPAnimDecoder);
+#endif
+  DALI_LOG_ERROR("WebP file open failed.\n");
+  return false;
+}
+
+bool LoadBitmapFromWebp(const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap)
+{
+  FILE* const fp = input.file;
+  if(fp == NULL)
+  {
+    return false;
+  }
+
+  if(fseek(fp, 0, SEEK_END) <= -1)
+  {
+    return false;
+  }
+
+  // If the image is non-animated webp
+#ifdef DALI_WEBP_AVAILABLE
+  size_t webPSize = ftell(fp);
+  if((!fseek(fp, 0, SEEK_SET)))
+  {
+    std::vector<uint8_t> encodedImage;
+    encodedImage.resize(webPSize, 0);
+    size_t readCount = fread(&encodedImage[0], sizeof(uint8_t), encodedImage.size(), fp);
+    if(readCount != encodedImage.size())
+    {
+      DALI_LOG_ERROR("WebP image loading failed.\n");
+      return false;
+    }
+
+    int32_t width, height;
+    if(!WebPGetInfo(&encodedImage[0], encodedImage.size(), &width, &height))
+    {
+      DALI_LOG_ERROR("Cannot retrieve WebP image size information.\n");
+      return false;
+    }
+
+    WebPBitstreamFeatures features;
+    if(VP8_STATUS_NOT_ENOUGH_DATA == WebPGetFeatures(&encodedImage[0], encodedImage.size(), &features))
+    {
+      DALI_LOG_ERROR("Cannot retrieve WebP image features.\n");
+      return false;
+    }
+
+    uint32_t      channelNumber = (features.has_alpha) ? 4 : 3;
+    Pixel::Format pixelFormat   = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
+    bitmap                      = Dali::Devel::PixelBuffer::New(width, height, pixelFormat);
+    uint8_t* frameBuffer        = nullptr;
+    if(channelNumber == 4)
+    {
+      frameBuffer = WebPDecodeRGBA(&encodedImage[0], encodedImage.size(), &width, &height);
+    }
+    else
+    {
+      frameBuffer = WebPDecodeRGB(&encodedImage[0], encodedImage.size(), &width, &height);
+    }
+
+    if(frameBuffer != nullptr)
+    {
+      const int32_t bufferSize = width * height * sizeof(uint8_t) * channelNumber;
+      memcpy(bitmap.GetBuffer(), frameBuffer, bufferSize);
+      free((void*)frameBuffer);
+      return true;
+    }
+  }
+#endif
+
+  // If the image is animated webp
+#ifdef DALI_ANIMATED_WEBP_ENABLED
+  WebPData         webPData;
+  WebPAnimDecoder* webPAnimDecoder;
+  WebPAnimInfo     webPAnimInfo;
+  if(ReadWebPInformation(fp, webPData))
+  {
+    WebPAnimDecoderOptions webPAnimDecoderOptions;
+    WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions);
+    webPAnimDecoderOptions.color_mode = MODE_RGBA;
+    webPAnimDecoder                   = WebPAnimDecoderNew(&webPData, &webPAnimDecoderOptions);
+    if(webPAnimDecoder != nullptr)
+    {
+      uint8_t* frameBuffer;
+      int      timestamp;
+      WebPAnimDecoderGetInfo(webPAnimDecoder, &webPAnimInfo);
+      WebPAnimDecoderReset(webPAnimDecoder);
+      WebPAnimDecoderGetNext(webPAnimDecoder, &frameBuffer, &timestamp);
+
+      bitmap                   = Dali::Devel::PixelBuffer::New(webPAnimInfo.canvas_width, webPAnimInfo.canvas_height, Dali::Pixel::RGBA8888);
+      const int32_t bufferSize = webPAnimInfo.canvas_width * webPAnimInfo.canvas_height * sizeof(uint32_t);
+      memcpy(bitmap.GetBuffer(), frameBuffer, bufferSize);
+      return true;
+    }
+  }
+  ReleaseResource(webPData, webPAnimDecoder);
+#endif
+
+  DALI_LOG_ERROR("WebP image loading failed.\n");
+  return false;
+}
+
+} // namespace TizenPlatform
+
+} // namespace Dali
diff --git a/dali/internal/imaging/common/loader-webp.h b/dali/internal/imaging/common/loader-webp.h
new file mode 100644 (file)
index 0000000..55d3278
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef DALI_TIZEN_PLATFORM_LOADER_WEBP_H
+#define DALI_TIZEN_PLATFORM_LOADER_WEBP_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/devel-api/adaptor-framework/image-loader-input.h>
+#include <cstdio>
+
+namespace Dali
+{
+namespace Devel
+{
+class PixelBuffer;
+}
+
+namespace TizenPlatform
+{
+class ResourceLoadingClient;
+
+namespace Webp
+{
+const unsigned char MAGIC_BYTE_1 = 0x52;
+const unsigned char MAGIC_BYTE_2 = 0x49;
+} // namespace Webp
+
+/**
+ * Loads the header of a Webp file and fills in the width and height appropriately.
+ * @param[in]  input   Information about the input image (including file pointer)
+ * @param[out] width   Is set with the width of the image
+ * @param[out] height  Is set with the height of the image
+ * @return true if the file's header was read successully, false otherwise
+ */
+bool LoadWebpHeader(const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height);
+
+/**
+ * Loads the bitmap from a Webp file.  This function checks the header first
+ * and if it is not a Webp file, then it returns straight away.
+ * @note For animated Webps, only the first image is displayed
+ * @param[in]  input  Information about the input image (including file pointer)
+ * @param[out] bitmap The bitmap class where the decoded image will be stored
+ * @return  true if file decoded successfully, false otherwise
+ */
+bool LoadBitmapFromWebp(const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap);
+
+} // namespace TizenPlatform
+
+} // namespace Dali
+
+#endif // DALI_TIZEN_PLATFORM_LOADER_WEBP_H
index 7e4511c..dc758fa 100644 (file)
@@ -24,7 +24,7 @@
 #include <webp/demux.h>
 
 #if WEBP_DEMUX_ABI_VERSION > 0x0101
-#define DALI_WEBP_ENABLED 1
+#define DALI_ANIMATED_WEBP_ENABLED 1
 #endif
 
 #endif
@@ -40,6 +40,9 @@
 #include <unistd.h>
 #include <cstring>
 
+// INTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/image-loading.h>
+
 typedef unsigned char WebPByteType;
 
 namespace Dali
@@ -63,34 +66,56 @@ struct WebPLoading::Impl
 public:
   Impl(const std::string& url, bool isLocalResource)
   : mUrl(url),
-    mLoadSucceeded(true),
-    mMutex()
+    mFrameCount(1u),
+    mMutex(),
+    mBuffer(nullptr),
+    mBufferSize(0u),
+    mImageSize(),
+    mLoadSucceeded(true)
   {
-#ifdef DALI_WEBP_ENABLED
+    // mFrameCount will be 1 if the input image is non-animated image or animated image with single frame.
     if(ReadWebPInformation(isLocalResource))
     {
+#ifdef DALI_ANIMATED_WEBP_ENABLED
+      WebPDataInit(&mWebPData);
+      mWebPData.size  = mBufferSize;
+      mWebPData.bytes = mBuffer;
       WebPAnimDecoderOptions webPAnimDecoderOptions;
       WebPAnimDecoderOptionsInit(&webPAnimDecoderOptions);
       webPAnimDecoderOptions.color_mode = MODE_RGBA;
       mWebPAnimDecoder                  = WebPAnimDecoderNew(&mWebPData, &webPAnimDecoderOptions);
       WebPAnimDecoderGetInfo(mWebPAnimDecoder, &mWebPAnimInfo);
       mTimeStamp.assign(mWebPAnimInfo.frame_count, 0);
+      mFrameCount = mWebPAnimInfo.frame_count;
+      mImageSize  = ImageDimensions(mWebPAnimInfo.canvas_width, mWebPAnimInfo.canvas_height);
+#elif DALI_WEBP_AVAILABLE
+      int32_t imageWidth, imageHeight;
+      if(WebPGetInfo(mBuffer, mBufferSize, &imageWidth, &imageHeight))
+      {
+        mImageSize = ImageDimensions(imageWidth, imageHeight);
+      }
+#endif
+#ifndef DALI_WEBP_AVAILABLE
+      // If the system doesn't support webp, loading will be failed.
+      mFrameCount    = 0u;
+      mLoadSucceeded = false;
+#endif
     }
     else
     {
+      mFrameCount    = 0u;
       mLoadSucceeded = false;
+      DALI_LOG_ERROR("Image loading failed for: \"%s\".\n", mUrl.c_str());
     }
-#endif
   }
 
   bool ReadWebPInformation(bool isLocalResource)
   {
-#ifdef DALI_WEBP_ENABLED
-    WebPDataInit(&mWebPData);
+    FILE* fp = nullptr;
     if(isLocalResource)
     {
       Internal::Platform::FileReader fileReader(mUrl);
-      FILE*                          fp = fileReader.GetFile();
+      fp = fileReader.GetFile();
       if(fp == NULL)
       {
         return false;
@@ -101,17 +126,12 @@ public:
         return false;
       }
 
-      mWebPData.size = ftell(fp);
-      if((!fseek(fp, 0, SEEK_SET)))
-      {
-        unsigned char* WebPDataBuffer;
-        WebPDataBuffer  = reinterpret_cast<WebPByteType*>(malloc(sizeof(WebPByteType) * mWebPData.size));
-        mWebPData.size  = fread(WebPDataBuffer, sizeof(WebPByteType), mWebPData.size, fp);
-        mWebPData.bytes = WebPDataBuffer;
-      }
-      else
+      mBufferSize = ftell(fp);
+      if(!fseek(fp, 0, SEEK_SET))
       {
-        return false;
+        mBuffer     = reinterpret_cast<WebPByteType*>(malloc(sizeof(WebPByteType) * mBufferSize));
+        mBufferSize = fread(mBuffer, sizeof(WebPByteType), mBufferSize, fp);
+        return true;
       }
     }
     else
@@ -124,37 +144,25 @@ public:
       succeeded = TizenPlatform::Network::DownloadRemoteFileIntoMemory(mUrl, dataBuffer, dataSize, MAXIMUM_DOWNLOAD_IMAGE_SIZE);
       if(succeeded)
       {
-        size_t blobSize = dataBuffer.Size();
-        if(blobSize > 0U)
+        mBufferSize = dataBuffer.Size();
+        if(mBufferSize > 0U)
         {
           // Open a file handle on the memory buffer:
-          Dali::Internal::Platform::FileReader fileReader(dataBuffer, blobSize);
-          FILE* const                          fp = fileReader.GetFile();
-          if(NULL != fp)
+          Internal::Platform::FileReader fileReader(dataBuffer, mBufferSize);
+          fp = fileReader.GetFile();
+          if(fp != nullptr)
           {
-            if((!fseek(fp, 0, SEEK_SET)))
+            if(!fseek(fp, 0, SEEK_SET))
             {
-              unsigned char* WebPDataBuffer;
-              WebPDataBuffer  = reinterpret_cast<WebPByteType*>(malloc(sizeof(WebPByteType) * blobSize));
-              mWebPData.size  = fread(WebPDataBuffer, sizeof(WebPByteType), mWebPData.size, fp);
-              mWebPData.bytes = WebPDataBuffer;
+              mBuffer     = reinterpret_cast<WebPByteType*>(malloc(sizeof(WebPByteType) * mBufferSize));
+              mBufferSize = fread(mBuffer, sizeof(WebPByteType), mBufferSize, fp);
+              return true;
             }
-            else
-            {
-              DALI_LOG_ERROR("Error seeking within file\n");
-            }
-          }
-          else
-          {
-            DALI_LOG_ERROR("Error reading file\n");
           }
         }
       }
     }
-    return true;
-#else
     return false;
-#endif
   }
 
   // Moveable but not copyable
@@ -166,10 +174,9 @@ public:
 
   ~Impl()
   {
-#ifdef DALI_WEBP_ENABLED
+#ifdef DALI_ANIMATED_WEBP_ENABLED
     if(&mWebPData != NULL)
     {
-      free((void*)mWebPData.bytes);
       mWebPData.bytes = nullptr;
       WebPDataInit(&mWebPData);
     }
@@ -178,15 +185,22 @@ public:
       WebPAnimDecoderDelete(mWebPAnimDecoder);
     }
 #endif
+    free((void*)mBuffer);
+    mBuffer = nullptr;
   }
 
   std::string           mUrl;
   std::vector<uint32_t> mTimeStamp;
   uint32_t              mLoadingFrame{0};
-  bool                  mLoadSucceeded;
+  uint32_t              mFrameCount;
   Mutex                 mMutex;
+  // For the case the system doesn't support DALI_ANIMATED_WEBP_ENABLED
+  unsigned char*  mBuffer;
+  uint32_t        mBufferSize;
+  ImageDimensions mImageSize;
+  bool            mLoadSucceeded;
 
-#ifdef DALI_WEBP_ENABLED
+#ifdef DALI_ANIMATED_WEBP_ENABLED
   WebPData         mWebPData{0};
   WebPAnimDecoder* mWebPAnimDecoder{nullptr};
   WebPAnimInfo     mWebPAnimInfo{0};
@@ -195,7 +209,7 @@ public:
 
 AnimatedImageLoadingPtr WebPLoading::New(const std::string& url, bool isLocalResource)
 {
-#ifndef DALI_WEBP_ENABLED
+#ifndef DALI_ANIMATED_WEBP_ENABLED
   DALI_LOG_ERROR("The system does not support Animated WebP format.\n");
 #endif
   return AnimatedImageLoadingPtr(new WebPLoading(url, isLocalResource));
@@ -213,64 +227,64 @@ WebPLoading::~WebPLoading()
 
 bool WebPLoading::LoadNextNFrames(uint32_t frameStartIndex, int count, std::vector<Dali::PixelData>& pixelData)
 {
-#ifdef DALI_WEBP_ENABLED
-  Mutex::ScopedLock lock(mImpl->mMutex);
-  if(frameStartIndex >= mImpl->mWebPAnimInfo.frame_count || !mImpl->mLoadSucceeded)
+  for(int i = 0; i < count; ++i)
   {
-    return false;
+    Dali::Devel::PixelBuffer pixelBuffer = LoadFrame((frameStartIndex + i) % mImpl->mFrameCount);
+    Dali::PixelData          imageData   = Devel::PixelBuffer::Convert(pixelBuffer);
+    pixelData.push_back(imageData);
   }
-
-  DALI_LOG_INFO(gWebPLoadingLogFilter, Debug::Concise, "LoadNextNFrames( frameStartIndex:%d, count:%d )\n", frameStartIndex, count);
-
-  if(mImpl->mLoadingFrame > frameStartIndex)
+  if(pixelData.size() != static_cast<uint32_t>(count))
   {
-    mImpl->mLoadingFrame = 0;
-    WebPAnimDecoderReset(mImpl->mWebPAnimDecoder);
+    return false;
   }
+  return true;
+}
 
-  for(; mImpl->mLoadingFrame < frameStartIndex; ++mImpl->mLoadingFrame)
-  {
-    uint8_t* frameBuffer;
-    int      timestamp;
-    WebPAnimDecoderGetNext(mImpl->mWebPAnimDecoder, &frameBuffer, &timestamp);
-    mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp;
-  }
+Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex)
+{
+  Dali::Devel::PixelBuffer pixelBuffer;
 
-  for(int i = 0; i < count; ++i)
+  // WebPDecodeRGBA is faster than to use demux API for loading non-animated image.
+  // If frame count is 1, use WebPDecodeRGBA api.
+#ifdef DALI_WEBP_AVAILABLE
+  if(mImpl->mFrameCount == 1)
   {
-    const int bufferSize = mImpl->mWebPAnimInfo.canvas_width * mImpl->mWebPAnimInfo.canvas_height * sizeof(uint32_t);
-    uint8_t*  frameBuffer;
-    int       timestamp;
-    WebPAnimDecoderGetNext(mImpl->mWebPAnimDecoder, &frameBuffer, &timestamp);
+    int32_t width, height;
+    if(!WebPGetInfo(mImpl->mBuffer, mImpl->mBufferSize, &width, &height))
+    {
+      return pixelBuffer;
+    }
 
-    auto pixelBuffer = new uint8_t[bufferSize];
-    memcpy(pixelBuffer, frameBuffer, bufferSize);
-    mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp;
+    WebPBitstreamFeatures features;
+    if(VP8_STATUS_NOT_ENOUGH_DATA == WebPGetFeatures(mImpl->mBuffer, mImpl->mBufferSize, &features))
+    {
+      return pixelBuffer;
+    }
 
-    if(pixelBuffer)
+    uint32_t      channelNumber = (features.has_alpha) ? 4 : 3;
+    Pixel::Format pixelFormat   = (channelNumber == 4) ? Pixel::RGBA8888 : Pixel::RGB888;
+    pixelBuffer                 = Dali::Devel::PixelBuffer::New(width, height, pixelFormat);
+    uint8_t* frameBuffer        = nullptr;
+    if(channelNumber == 4)
+    {
+      frameBuffer = WebPDecodeRGBA(mImpl->mBuffer, mImpl->mBufferSize, &width, &height);
+    }
+    else
     {
-      pixelData.push_back(Dali::PixelData::New(pixelBuffer, bufferSize, mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height, Dali::Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY));
+      frameBuffer = WebPDecodeRGB(mImpl->mBuffer, mImpl->mBufferSize, &width, &height);
     }
 
-    mImpl->mLoadingFrame++;
-    if(mImpl->mLoadingFrame >= mImpl->mWebPAnimInfo.frame_count)
+    if(frameBuffer != nullptr)
     {
-      mImpl->mLoadingFrame = 0;
-      WebPAnimDecoderReset(mImpl->mWebPAnimDecoder);
+      const int32_t imageBufferSize = width * height * sizeof(uint8_t) * channelNumber;
+      memcpy(pixelBuffer.GetBuffer(), frameBuffer, imageBufferSize);
+      free((void*)frameBuffer);
+      return pixelBuffer;
     }
   }
-
-  return true;
-#else
-  return false;
 #endif
-}
 
-Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex)
-{
-  Dali::Devel::PixelBuffer pixelBuffer;
-
-#ifdef DALI_WEBP_ENABLED
+#ifdef DALI_ANIMATED_WEBP_ENABLED
   Mutex::ScopedLock lock(mImpl->mMutex);
   if(frameIndex >= mImpl->mWebPAnimInfo.frame_count || !mImpl->mLoadSucceeded)
   {
@@ -314,20 +328,12 @@ Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex)
 
 ImageDimensions WebPLoading::GetImageSize() const
 {
-#ifdef DALI_WEBP_ENABLED
-  return ImageDimensions(mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height);
-#else
-  return ImageDimensions();
-#endif
+  return mImpl->mImageSize;
 }
 
 uint32_t WebPLoading::GetImageCount() const
 {
-#ifdef DALI_WEBP_ENABLED
-  return mImpl->mWebPAnimInfo.frame_count;
-#else
-  return 0u;
-#endif
+  return mImpl->mFrameCount;
 }
 
 uint32_t WebPLoading::GetFrameInterval(uint32_t frameIndex) const
index b5f0894..4dcda76 100644 (file)
@@ -17,6 +17,7 @@ SET( adaptor_imaging_common_src_files
     ${adaptor_imaging_dir}/common/loader-ktx.cpp
     ${adaptor_imaging_dir}/common/loader-png.cpp
     ${adaptor_imaging_dir}/common/loader-wbmp.cpp
+    ${adaptor_imaging_dir}/common/loader-webp.cpp
     ${adaptor_imaging_dir}/common/pixel-manipulation.cpp
     ${adaptor_imaging_dir}/common/gif-loading.cpp
     ${adaptor_imaging_dir}/common/webp-loading.cpp
index 8fe3953..1e455d5 100644 (file)
@@ -38,7 +38,6 @@ namespace Adaptor
 {
 namespace
 {
-const char* FRAGMENT_PREFIX = "#extension GL_OES_EGL_image_external:require\n";
 const char* SAMPLER_TYPE    = "samplerExternalOES";
 
 // clang-format off
@@ -75,7 +74,8 @@ NativeImageSourceTizen* NativeImageSourceTizen::New(uint32_t width, uint32_t hei
 }
 
 NativeImageSourceTizen::NativeImageSourceTizen(uint32_t width, uint32_t height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource)
-: mWidth(width),
+: mCustomFragmentPrefix(),
+  mWidth(width),
   mHeight(height),
   mOwnTbmSurface(false),
   mTbmSurface(NULL),
@@ -94,6 +94,8 @@ NativeImageSourceTizen::NativeImageSourceTizen(uint32_t width, uint32_t height,
   GraphicsInterface* graphics = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface());
   mEglGraphics                = static_cast<EglGraphics*>(graphics);
 
+  mCustomFragmentPrefix = mEglGraphics->GetEglImageExtensionString();
+
   mTbmSurface = GetSurfaceFromAny(nativeImageSource);
 
   if(mTbmSurface != NULL)
@@ -458,7 +460,7 @@ void NativeImageSourceTizen::PrepareTexture()
 
 const char* NativeImageSourceTizen::GetCustomFragmentPrefix() const
 {
-  return FRAGMENT_PREFIX;
+  return mCustomFragmentPrefix;
 }
 
 const char* NativeImageSourceTizen::GetCustomSamplerTypename() const
index 7f48b92..2fa10a8 100644 (file)
@@ -190,9 +190,10 @@ private:
   void DestroySurface();
 
 private:
-  uint32_t                            mWidth;         ///< image width
-  uint32_t                            mHeight;        ///< image height
-  bool                                mOwnTbmSurface; ///< Whether we created pixmap or not
+  const char*                         mCustomFragmentPrefix; ///< Prefix for CustomFragment
+  uint32_t                            mWidth;                ///< image width
+  uint32_t                            mHeight;               ///< image height
+  bool                                mOwnTbmSurface;        ///< Whether we created pixmap or not
   tbm_surface_h                       mTbmSurface;
   tbm_format                          mTbmFormat;
   bool                                mBlendingRequired;   ///< Whether blending is required
index 8028efd..689741c 100644 (file)
@@ -38,7 +38,6 @@ namespace
 {
 #define TBM_SURFACE_QUEUE_SIZE 3
 
-const char* FRAGMENT_PREFIX = "#extension GL_OES_EGL_image_external:require\n";
 const char* SAMPLER_TYPE    = "samplerExternalOES";
 
 // clang-format off
@@ -73,7 +72,8 @@ NativeImageSourceQueueTizen* NativeImageSourceQueueTizen::New(uint32_t width, ui
 }
 
 NativeImageSourceQueueTizen::NativeImageSourceQueueTizen(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue)
-: mMutex(),
+: mCustomFragmentPrefix(),
+  mMutex(),
   mWidth(width),
   mHeight(height),
   mTbmQueue(NULL),
@@ -89,6 +89,8 @@ NativeImageSourceQueueTizen::NativeImageSourceQueueTizen(uint32_t width, uint32_
   GraphicsInterface* graphics = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface());
   mEglGraphics                = static_cast<EglGraphics*>(graphics);
 
+  mCustomFragmentPrefix = mEglGraphics->GetEglImageExtensionString();
+
   mTbmQueue = GetSurfaceFromAny(nativeImageSourceQueue);
 
   if(mTbmQueue != NULL)
@@ -280,7 +282,7 @@ void NativeImageSourceQueueTizen::PrepareTexture()
 
 const char* NativeImageSourceQueueTizen::GetCustomFragmentPrefix() const
 {
-  return FRAGMENT_PREFIX;
+  return mCustomFragmentPrefix;
 }
 
 const char* NativeImageSourceQueueTizen::GetCustomSamplerTypename() const
index 4f86eb4..5702eaf 100644 (file)
@@ -171,16 +171,17 @@ private:
 private:
   typedef std::pair<tbm_surface_h, void*> EglImagePair;
 
-  Dali::Mutex               mMutex;              ///< Mutex
-  uint32_t                  mWidth;              ///< image width
-  uint32_t                  mHeight;             ///< image height
-  tbm_surface_queue_h       mTbmQueue;           ///< Tbm surface queue handle
-  tbm_surface_h             mConsumeSurface;     ///< The current tbm surface
-  std::vector<EglImagePair> mEglImages;          ///< EGL Image vector
-  EglGraphics*              mEglGraphics;        ///< EGL Graphics
-  EglImageExtensions*       mEglImageExtensions; ///< The EGL Image Extensions
-  bool                      mOwnTbmQueue;        ///< Whether we created tbm queue
-  bool                      mBlendingRequired;   ///< Whether blending is required
+  const char*               mCustomFragmentPrefix; ///< Prefix for CustomFragment
+  Dali::Mutex               mMutex;                ///< Mutex
+  uint32_t                  mWidth;                ///< image width
+  uint32_t                  mHeight;               ///< image height
+  tbm_surface_queue_h       mTbmQueue;             ///< Tbm surface queue handle
+  tbm_surface_h             mConsumeSurface;       ///< The current tbm surface
+  std::vector<EglImagePair> mEglImages;            ///< EGL Image vector
+  EglGraphics*              mEglGraphics;          ///< EGL Graphics
+  EglImageExtensions*       mEglImageExtensions;   ///< The EGL Image Extensions
+  bool                      mOwnTbmQueue;          ///< Whether we created tbm queue
+  bool                      mBlendingRequired;     ///< Whether blending is required
 };
 
 } // namespace Adaptor
index ed34e15..d85bdd3 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
 #include <dali/integration-api/adaptor-framework/native-render-surface.h>
 #include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
+#include <dali/integration-api/debug.h>
 #include <dali/internal/offscreen/common/offscreen-application-impl.h>
 
 namespace Dali
@@ -49,31 +50,11 @@ void OffscreenWindow::Initialize(bool isDefaultWindow)
 {
   if(isDefaultWindow)
   {
-    Initialize();
     return;
   }
 
   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder(this);
   Dali::Adaptor::Get().AddWindow(sceneHolderHandler);
-
-  Initialize();
-}
-
-void OffscreenWindow::Initialize()
-{
-  // Connect callback to be notified when the surface is rendered
-  TriggerEventFactory triggerEventFactory;
-
-  mRenderNotification = std::unique_ptr<TriggerEventInterface>(triggerEventFactory.CreateTriggerEvent(MakeCallback(this, &OffscreenWindow::OnPostRender), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER));
-
-  NativeRenderSurface* surface = GetNativeRenderSurface();
-
-  if(!surface)
-  {
-    return;
-  }
-
-  surface->SetRenderNotification(mRenderNotification.get());
 }
 
 OffscreenWindow::~OffscreenWindow()
@@ -112,6 +93,28 @@ Dali::Any OffscreenWindow::GetNativeHandle() const
   return surface->GetNativeRenderable();
 }
 
+void OffscreenWindow::SetPostRenderCallback(CallbackBase* callback)
+{
+  // Connect callback to be notified when the surface is rendered
+  mPostRenderCallback = std::unique_ptr<CallbackBase>(callback);
+  TriggerEventFactory triggerEventFactory;
+
+  if(!mRenderNotification)
+  {
+    mRenderNotification = std::unique_ptr<TriggerEventInterface>(triggerEventFactory.CreateTriggerEvent(MakeCallback(this, &OffscreenWindow::OnPostRender), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER));
+  }
+
+  NativeRenderSurface* surface = GetNativeRenderSurface();
+
+  if(!surface)
+  {
+    DALI_LOG_ERROR("NativeRenderSurface is null.");
+    return;
+  }
+
+  surface->SetRenderNotification(mRenderNotification.get());
+}
+
 NativeRenderSurface* OffscreenWindow::GetNativeRenderSurface() const
 {
   return dynamic_cast<NativeRenderSurface*>(mSurface.get());
@@ -119,13 +122,18 @@ NativeRenderSurface* OffscreenWindow::GetNativeRenderSurface() const
 
 void OffscreenWindow::OnPostRender()
 {
+  NativeRenderSurface* surface = GetNativeRenderSurface();
+
+  if(!surface)
+  {
+    DALI_LOG_ERROR("NativeRenderSurface is null.");
+    return;
+  }
+
   Dali::OffscreenWindow handle(this);
-  mPostRenderSignal.Emit(handle, GetNativeHandle());
-}
+  CallbackBase::Execute(*mPostRenderCallback, handle, surface->GetNativeRenderable());
 
-OffscreenWindow::PostRenderSignalType& OffscreenWindow::PostRenderSignal()
-{
-  return mPostRenderSignal;
+  surface->ReleaseLock();
 }
 
 } // namespace Internal
index ee564e9..e45cf49 100644 (file)
@@ -20,7 +20,6 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/intrusive-ptr.h>
-#include <dali/public-api/signals/connection-tracker.h>
 #include <memory>
 
 // INTERNAL INCLUDES
@@ -39,12 +38,10 @@ namespace Internal
 /**
  * Implementation of the OffscreenWindow class.
  */
-class OffscreenWindow : public Dali::Internal::Adaptor::SceneHolder,
-                        public ConnectionTracker
+class OffscreenWindow : public Dali::Internal::Adaptor::SceneHolder
 {
 public:
-  using WindowSize           = Dali::OffscreenWindow::WindowSize;
-  using PostRenderSignalType = Dali::OffscreenWindow::PostRenderSignalType;
+  using WindowSize = Dali::OffscreenWindow::WindowSize;
 
   /**
    * @brief Create a new OffscreenWindow
@@ -84,18 +81,17 @@ public:
    */
   Any GetNativeHandle() const override;
 
+  /**
+   * @copydoc Dali::OffscreenWindow::SetPostRenderCallback
+   */
+  void SetPostRenderCallback(CallbackBase* callback);
+
   /*
    * @brief Initialize the OffscreenWindow
    * @param[in] isDefaultWindow Whether the OffscreenWindow is a default one or not
    */
   void Initialize(bool isDefaultWindow);
 
-public: // Signals
-  /**
-   * @copydoc Dali::OffscreenWindow::PostRenderSignal
-   */
-  PostRenderSignalType& PostRenderSignal();
-
 private:
   /**
    * This function is called after drawing by dali.
@@ -123,14 +119,9 @@ private:
   OffscreenWindow(const OffscreenWindow&);
   OffscreenWindow& operator=(OffscreenWindow&);
 
-  /*
-   * @brief Initialize the OffscreenWindow (for internal use)
-   */
-  void Initialize();
-
 private:
   std::unique_ptr<TriggerEventInterface> mRenderNotification;
-  PostRenderSignalType                   mPostRenderSignal;
+  std::unique_ptr<CallbackBase>          mPostRenderCallback;
 };
 
 inline OffscreenWindow& GetImplementation(Dali::OffscreenWindow& offscreenWindow)
index 094c16e..ab3f1b9 100644 (file)
@@ -139,6 +139,8 @@ namespace Adaptor
 
 #define DALI_ENV_DISABLE_ATSPI "DALI_DISABLE_ATSPI"
 
+#define DALI_ENV_SUPPRESS_SCREEN_READER "DALI_SUPPRESS_SCREEN_READER"
+
 } // namespace Adaptor
 
 } // namespace Internal
index 8530a7b..1a420de 100644 (file)
@@ -1,13 +1,14 @@
 
 # module: text, backend: common
-SET( adaptor_text_common_src_files 
-    ${adaptor_text_dir}/text-abstraction/bidirectional-support-impl.cpp 
-    ${adaptor_text_dir}/text-abstraction/cairo-renderer.cpp 
-    ${adaptor_text_dir}/text-abstraction/font-client-helper.cpp 
-    ${adaptor_text_dir}/text-abstraction/font-client-impl.cpp 
-    ${adaptor_text_dir}/text-abstraction/font-client-plugin-impl.cpp 
-    ${adaptor_text_dir}/text-abstraction/segmentation-impl.cpp 
-    ${adaptor_text_dir}/text-abstraction/shaping-impl.cpp 
+SET( adaptor_text_common_src_files
+    ${adaptor_text_dir}/text-abstraction/bidirectional-support-impl.cpp
+    ${adaptor_text_dir}/text-abstraction/cairo-renderer.cpp
+    ${adaptor_text_dir}/text-abstraction/font-client-helper.cpp
+    ${adaptor_text_dir}/text-abstraction/font-client-impl.cpp
+    ${adaptor_text_dir}/text-abstraction/font-client-plugin-impl.cpp
+    ${adaptor_text_dir}/text-abstraction/segmentation-impl.cpp
+    ${adaptor_text_dir}/text-abstraction/shaping-impl.cpp
     ${adaptor_text_dir}/text-abstraction/text-renderer-impl.cpp
+    ${adaptor_text_dir}/text-abstraction/hyphenation-impl.cpp
 )
 
diff --git a/dali/internal/text/text-abstraction/hyphenation-impl.cpp b/dali/internal/text/text-abstraction/hyphenation-impl.cpp
new file mode 100644 (file)
index 0000000..bc460ee
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS  HEADER
+#include <dali/internal/text/text-abstraction/hyphenation-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+#include <dali/devel-api/common/singleton-service.h>
+
+// EXTERNAL INCLUDES
+#ifdef HYPHEN_LIBRARY_AVAILABLE
+#include <hyphen.h>
+#else
+#define HyphenDict void
+#endif
+
+#ifndef HYPHEN_DIC
+#define HYPHEN_DIC "abc"
+#endif
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Dali::Integration::Log::Filter* gLogFilter = Dali::Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_HYPHENATION");
+#endif
+
+} // namespace
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace Internal
+{
+const char* const  DEFAULT_LANGUAGE        = "en_US";
+const unsigned int DEFAULT_LANGUAGE_LENGTH = 5u;
+
+struct Hyphenation::HyphenDictionary
+{
+  HyphenDictionary(std::string lang, HyphenDict* dict)
+  {
+    mLanguage   = lang;
+    mDictionary = dict;
+  }
+
+  ~HyphenDictionary()
+  {
+  }
+
+  std::string mLanguage;
+  HyphenDict* mDictionary;
+};
+
+struct Hyphenation::Plugin
+{
+  Plugin()
+  : mHyphenDictionary()
+  {
+  }
+
+  ~Plugin()
+  {
+#ifdef HYPHEN_LIBRARY_AVAILABLE
+    for(auto&& it : mHyphenDictionary)
+    {
+      hnj_hyphen_free(it.mDictionary);
+    }
+#endif
+  }
+
+  std::string GetPathForLanguage(const char* lang)
+  {
+    std::string path    = HYPHEN_DIC;
+    std::string filName = "/hyph_";
+    filName.append(lang);
+    filName.append(".dic");
+    path.append(filName);
+
+    return path; // must be ..../hyph_en_US.dic
+  }
+
+  HyphenDict* LoadDictionary(const char* language)
+  {
+#ifdef HYPHEN_LIBRARY_AVAILABLE
+    const char* lang = (language ? language : DEFAULT_LANGUAGE);
+
+    for(auto&& it : mHyphenDictionary)
+    {
+      if(!it.mLanguage.compare(lang))
+      {
+        return it.mDictionary;
+      }
+    }
+
+    std::string path = GetPathForLanguage(lang);
+    HyphenDict* dict = hnj_hyphen_load(path.c_str());
+    if(!dict)
+    {
+      DALI_LOG_ERROR("Couldn't load hyphen dictionary:%s\n", lang);
+    }
+    else
+    {
+      mHyphenDictionary.push_back(HyphenDictionary(lang, dict));
+    }
+
+    return dict;
+#else
+    return nullptr;
+#endif
+  }
+
+  const char* GetDictionaryEncoding(const char* lang)
+  {
+#ifdef HYPHEN_LIBRARY_AVAILABLE
+    HyphenDict* dict = LoadDictionary(lang);
+    if(!dict)
+    {
+      return nullptr;
+    }
+
+    return dict->cset;
+#else
+    return "UTF_32";
+#endif
+  }
+
+  Vector<bool> GetWordHyphens(const char* word,
+                              Length      wordLength,
+                              const char* lang)
+  {
+    Vector<bool> hyphensList;
+
+#ifdef HYPHEN_LIBRARY_AVAILABLE
+    char*       hyphens = nullptr;
+    char**      rep     = nullptr;
+    int*        pos     = nullptr;
+    int*        cut     = nullptr;
+    HyphenDict* dict;
+
+    if((!word) || (wordLength < 1))
+    {
+      return hyphensList;
+    }
+
+    dict = LoadDictionary(lang);
+    if(!dict)
+    {
+      return hyphensList;
+    }
+
+    hyphens = (char*)malloc(wordLength + 5);
+    if(hyphens)
+    {
+      hnj_hyphen_hyphenate2(dict, (char*)(word), wordLength, hyphens, NULL, &rep, &pos, &cut);
+
+      hyphensList.PushBack(false);
+
+      for(Length i = 0; i < wordLength - 1; i++)
+      {
+        hyphensList.PushBack((bool)(hyphens[i + 1] & 1));
+      }
+
+      free(hyphens);
+    }
+#endif
+
+    return hyphensList;
+  }
+
+  std::vector<HyphenDictionary> mHyphenDictionary;
+};
+
+Hyphenation::Hyphenation()
+: mPlugin(nullptr)
+{
+}
+
+Hyphenation::~Hyphenation()
+{
+}
+
+TextAbstraction::Hyphenation Hyphenation::Get()
+{
+  TextAbstraction::Hyphenation hyphenationHandle;
+
+  SingletonService service(SingletonService::Get());
+  if(service)
+  {
+    // Check whether the singleton is already created
+    Dali::BaseHandle handle = service.GetSingleton(typeid(TextAbstraction::Hyphenation));
+    if(handle)
+    {
+      // If so, downcast the handle
+      Hyphenation* impl = dynamic_cast<Internal::Hyphenation*>(handle.GetObjectPtr());
+      hyphenationHandle = TextAbstraction::Hyphenation(impl);
+    }
+    else // create and register the object
+    {
+      hyphenationHandle = TextAbstraction::Hyphenation(new Hyphenation);
+      service.Register(typeid(hyphenationHandle), hyphenationHandle);
+    }
+  }
+
+  return hyphenationHandle;
+}
+
+const char* Hyphenation::GetDictionaryEncoding(const char* lang)
+{
+  CreatePlugin();
+
+  return mPlugin->GetDictionaryEncoding(lang);
+}
+
+Vector<bool> Hyphenation::GetWordHyphens(const char* word,
+                                         Length      wordLength,
+                                         const char* lang)
+{
+  CreatePlugin();
+
+  return mPlugin->GetWordHyphens(word, wordLength, lang);
+}
+
+void Hyphenation::CreatePlugin()
+{
+  if(!mPlugin)
+  {
+    mPlugin = std::make_unique<Plugin>();
+  }
+}
+
+} // namespace Internal
+
+} // namespace TextAbstraction
+
+} // namespace Dali
diff --git a/dali/internal/text/text-abstraction/hyphenation-impl.h b/dali/internal/text/text-abstraction/hyphenation-impl.h
new file mode 100644 (file)
index 0000000..53bc059
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef DALI_INTERNAL_TEXT_ABSTRACTION_HYPHENATION_IMPL_H
+#define DALI_INTERNAL_TEXT_ABSTRACTION_HYPHENATION_IMPL_H
+
+/*
+ * Copyright (c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/hyphenation.h>
+#include <dali/public-api/common/dali-vector.h>
+
+namespace Dali
+{
+namespace TextAbstraction
+{
+namespace Internal
+{
+/**
+ * Implementation of the Hyphenation
+ */
+class Hyphenation : public BaseObject
+{
+public:
+  /**
+   * Constructor
+   */
+  Hyphenation();
+
+  /**
+   * Destructor
+   */
+  ~Hyphenation();
+
+  /**
+   * @copydoc Dali::Hyphenation::Get()
+   */
+  static TextAbstraction::Hyphenation Get();
+
+  /**
+   * @copydoc Dali::Hyphenation::GetDictionaryEncoding()
+   */
+  const char* GetDictionaryEncoding(const char* lang);
+
+  /**
+   * @copydoc Dali::Hyphenation::GetWordHyphens()
+   */
+  Vector<bool> GetWordHyphens(const char* word,
+                              Length      wordLength,
+                              const char* lang);
+
+private:
+  /**
+   * Helper for lazy initialization.
+   */
+  void CreatePlugin();
+
+private:
+  // Undefined copy constructor.
+  Hyphenation(const Hyphenation&);
+
+  // Undefined assignment constructor.
+  Hyphenation& operator=(const Hyphenation&);
+
+  struct HyphenDictionary;
+  struct Plugin;
+  std::unique_ptr<Plugin> mPlugin;
+
+}; // class Hyphenation
+
+} // namespace Internal
+
+} // namespace TextAbstraction
+
+inline static TextAbstraction::Internal::Hyphenation& GetImplementation(TextAbstraction::Hyphenation& hyphenation)
+{
+  DALI_ASSERT_ALWAYS(hyphenation && "hyphenation handle is empty");
+  BaseObject& handle = hyphenation.GetBaseObject();
+  return static_cast<TextAbstraction::Internal::Hyphenation&>(handle);
+}
+
+inline static const TextAbstraction::Internal::Hyphenation& GetImplementation(const TextAbstraction::Hyphenation& hyphenation)
+{
+  DALI_ASSERT_ALWAYS(hyphenation && "hyphenation handle is empty");
+  const BaseObject& handle = hyphenation.GetBaseObject();
+  return static_cast<const TextAbstraction::Internal::Hyphenation&>(handle);
+}
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_TEXT_ABSTRACTION_HYPHENATION_IMPL_H
old mode 100644 (file)
new mode 100755 (executable)
index a9b483c..dd1a7d1
@@ -621,9 +621,9 @@ Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& WebEngine::ConsoleMess
   return mPlugin->ConsoleMessageSignal();
 }
 
-Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& WebEngine::PolicyDecisionSignal()
+Dali::WebEnginePlugin::WebEngineResponsePolicyDecisionSignalType& WebEngine::ResponsePolicyDecisionSignal()
 {
-  return mPlugin->PolicyDecisionSignal();
+  return mPlugin->ResponsePolicyDecisionSignal();
 }
 
 Dali::WebEnginePlugin::WebEngineCertificateSignalType& WebEngine::CertificateConfirmSignal()
index 505feb3..c730049 100755 (executable)
@@ -505,9 +505,9 @@ public:
   Dali::WebEnginePlugin::WebEngineConsoleMessageSignalType& ConsoleMessageSignal();
 
   /**
-   @copydoc Dali::WebEngine::PolicyDecisionSignal()
+   @copydoc Dali::WebEngine::ResponsePolicyDecisionSignal()
    */
-  Dali::WebEnginePlugin::WebEnginePolicyDecisionSignalType& PolicyDecisionSignal();
+  Dali::WebEnginePlugin::WebEngineResponsePolicyDecisionSignalType& ResponsePolicyDecisionSignal();
 
   /**
    * @copydoc Dali::WebEngine::CertificateConfirmSignal()
index 8ce440b..352e8c1 100644 (file)
@@ -250,9 +250,9 @@ void WindowBaseAndroid::SetType(Dali::WindowType type)
 {
 }
 
-bool WindowBaseAndroid::SetNotificationLevel(Dali::WindowNotificationLevel level)
+Dali::WindowOperationResult WindowBaseAndroid::SetNotificationLevel(Dali::WindowNotificationLevel level)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 Dali::WindowNotificationLevel WindowBaseAndroid::GetNotificationLevel() const
@@ -264,9 +264,9 @@ void WindowBaseAndroid::SetOpaqueState(bool opaque)
 {
 }
 
-bool WindowBaseAndroid::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+Dali::WindowOperationResult WindowBaseAndroid::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 WindowScreenOffMode WindowBaseAndroid::GetScreenOffMode() const
@@ -274,9 +274,9 @@ WindowScreenOffMode WindowBaseAndroid::GetScreenOffMode() const
   return WindowScreenOffMode::TIMEOUT;
 }
 
-bool WindowBaseAndroid::SetBrightness(int brightness)
+Dali::WindowOperationResult WindowBaseAndroid::SetBrightness(int brightness)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 int WindowBaseAndroid::GetBrightness() const
index 1dd4cd6..7cabb85 100644 (file)
@@ -266,7 +266,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel()
    */
-  bool SetNotificationLevel(Dali::WindowNotificationLevel level) override;
+  Dali::WindowOperationResult SetNotificationLevel(Dali::WindowNotificationLevel level) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel()
@@ -281,7 +281,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
+  Dali::WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode()
@@ -291,7 +291,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness()
    */
-  bool SetBrightness(int brightness) override;
+  Dali::WindowOperationResult SetBrightness(int brightness) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness()
index 89d4398..b491bc7 100644 (file)
@@ -74,8 +74,6 @@ GlWindow::GlWindow()
   mOpaqueState(false),
   mResizeEnabled(false),
   mVisible(false),
-  mIsRotated(false),
-  mIsWindowRotated(false),
   mIsTouched(false),
   mIsEGLInitialized(false),
   mDepth(false),
@@ -149,6 +147,7 @@ void GlWindow::Initialize(const PositionSize& positionSize, const std::string& n
   mWindowBase = windowFactory->CreateWindowBase(mPositionSize, surface, (mIsTransparent ? true : false));
   mWindowBase->IconifyChangedSignal().Connect(this, &GlWindow::OnIconifyChanged);
   mWindowBase->FocusChangedSignal().Connect(this, &GlWindow::OnFocusChanged);
+  mWindowBase->OutputTransformedSignal().Connect(this, &GlWindow::OnOutputTransformed);
 
   if(Dali::Adaptor::IsAvailable())
   {
@@ -385,11 +384,16 @@ void GlWindow::SetPositionSize(PositionSize positionSize)
   }
 
   // If window's size or position is changed, the signal will be emitted to user.
-  if((needToMove) || (needToResize))
+  if(needToMove || needToResize)
   {
     Uint16Pair     newSize(mPositionSize.width, mPositionSize.height);
     Dali::GlWindow handle(this);
     mResizeSignal.Emit(newSize);
+
+    if(mGlWindowRenderThread)
+    {
+      mGlWindowRenderThread->RequestWindowResize(mPositionSize.width, mPositionSize.height);
+    }
   }
 }
 
@@ -461,26 +465,12 @@ void GlWindow::OnFocusChanged(bool focusIn)
 
 void GlWindow::OnOutputTransformed()
 {
-  int screenRotationAngle = mWindowBase->GetScreenRotationAngle();
-  if(screenRotationAngle != mScreenRotationAngle)
-  {
-    mScreenRotationAngle = screenRotationAngle;
-    mTotalRotationAngle  = (mWindowRotationAngle + mScreenRotationAngle) % 360;
-
-    if(mTotalRotationAngle == 90 || mTotalRotationAngle == 270)
-    {
-      mWindowWidth  = mPositionSize.height;
-      mWindowHeight = mPositionSize.width;
-    }
-    else
-    {
-      mWindowWidth  = mPositionSize.width;
-      mWindowHeight = mPositionSize.height;
-    }
+  int newScreenRotationAngle = mWindowBase->GetScreenRotationAngle();
+  DALI_LOG_RELEASE_INFO("GlWindow::OnOutputTransformed(), screen rotation occurs, old[%d], new[%d\n", mScreenRotationAngle, newScreenRotationAngle);
 
-    // Emit Resize signal
-    Dali::GlWindow handle(this);
-    mResizeSignal.Emit(Dali::Uint16Pair(mWindowWidth, mWindowHeight));
+  if(newScreenRotationAngle != mScreenRotationAngle)
+  {
+    UpdateScreenRotation(newScreenRotationAngle);
   }
 }
 
@@ -537,13 +527,16 @@ void GlWindow::OnRotation(const RotationEvent& rotation)
     mWindowHeight = mPositionSize.height;
   }
 
-  mIsRotated       = true;
-  mIsWindowRotated = true;
   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), OnRotation(): resize signal emit [%d x %d]\n", this, mNativeWindowId, mWindowWidth, mWindowHeight);
 
   // Emit Resize signal
   Dali::GlWindow handle(this);
   mResizeSignal.Emit(Dali::Uint16Pair(mWindowWidth, mWindowHeight));
+
+  if(mGlWindowRenderThread)
+  {
+    mGlWindowRenderThread->RequestWindowRotate(mWindowRotationAngle);
+  }
 }
 
 void GlWindow::RecalculateTouchPosition(Integration::Point& point)
@@ -823,6 +816,14 @@ void GlWindow::InitializeGraphics()
     mGlWindowRenderThread->SetOnDemandRenderMode(onDemand);
 
     mIsEGLInitialized = true;
+
+    // Check screen rotation
+    int newScreenRotationAngle = mWindowBase->GetScreenRotationAngle();
+    DALI_LOG_RELEASE_INFO("GlWindow::InitializeGraphics(), GetScreenRotationAngle(): %d\n", mScreenRotationAngle);
+    if(newScreenRotationAngle != 0)
+    {
+      UpdateScreenRotation(newScreenRotationAngle);
+    }
   }
 }
 
@@ -830,6 +831,33 @@ void GlWindow::OnDamaged(const DamageArea& area)
 {
 }
 
+void GlWindow::UpdateScreenRotation(int newAngle)
+{
+  mScreenRotationAngle = newAngle;
+  mTotalRotationAngle  = (mWindowRotationAngle + mScreenRotationAngle) % 360;
+
+  if(mTotalRotationAngle == 90 || mTotalRotationAngle == 270)
+  {
+    mWindowWidth  = mPositionSize.height;
+    mWindowHeight = mPositionSize.width;
+  }
+  else
+  {
+    mWindowWidth  = mPositionSize.width;
+    mWindowHeight = mPositionSize.height;
+  }
+
+  // Emit Resize signal
+  Dali::GlWindow handle(this);
+  mResizeSignal.Emit(Dali::Uint16Pair(mWindowWidth, mWindowHeight));
+
+  if(mGlWindowRenderThread)
+  {
+    DALI_LOG_RELEASE_INFO("GlWindow::UpdateScreenRotation(), RequestScreenRotatem(), mScreenRotationAngle: %d\n", mScreenRotationAngle);
+    mGlWindowRenderThread->RequestScreenRotate(mScreenRotationAngle);
+  }
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 4102736..954e297 100644 (file)
@@ -332,6 +332,13 @@ private: // From Dali::Internal::Adaptor::DamageObserver
    */
   void OnDamaged(const DamageArea& area);
 
+  /**
+   * @brief Updates screen rotation value and screen rotation works.
+   *
+   * @param[in] newAngle new screen rotation angle
+   */
+  void UpdateScreenRotation(int newAngle);
+
 public: // Signals
   /**
    * @copydoc Dali::GlWindow::FocusChangeSignal()
@@ -388,7 +395,6 @@ private:
   bool                                     mOpaqueState : 1;
   bool                                     mResizeEnabled : 1;
   bool                                     mVisible : 1;
-  bool                                     mIsRotated : 1;
   bool                                     mIsWindowRotated : 1;
   bool                                     mIsTouched : 1;
   bool                                     mIsEGLInitialized : 1;
index 55010ce..e6390cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
  *
  */
 
+// EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/thread-settings.h>
 
+// INTERNAL INCLUDES
 #include <dali/internal/adaptor/common/adaptor-impl.h>
 #include <dali/internal/system/common/time-service.h>
 #include <dali/internal/window-system/common/gl-window-render-thread.h>
@@ -29,17 +31,20 @@ namespace Adaptor
 {
 namespace
 {
-const unsigned int NANOSECONDS_PER_SECOND(1e+9);
+constexpr unsigned int NANOSECONDS_PER_SECOND(1e+9);
 
 // The following values will get calculated at compile time
-const float    DEFAULT_FRAME_DURATION_IN_SECONDS(1.0f / 60.0f);
-const uint64_t DEFAULT_FRAME_DURATION_IN_NANOSECONDS(DEFAULT_FRAME_DURATION_IN_SECONDS* NANOSECONDS_PER_SECOND);
+constexpr float    DEFAULT_FRAME_DURATION_IN_SECONDS(1.0f / 60.0f);
+constexpr uint64_t DEFAULT_FRAME_DURATION_IN_NANOSECONDS(DEFAULT_FRAME_DURATION_IN_SECONDS* NANOSECONDS_PER_SECOND);
+constexpr uint64_t REFRESH_RATE(1u);
 
+constexpr int MINIMUM_DIMENSION_CHANGE(1);
 } // namespace
 
 GlWindowRenderThread::GlWindowRenderThread(PositionSize positionSize, ColorDepth colorDepth)
 : mGraphics(nullptr),
   mWindowBase(nullptr),
+  mWindowRotationTrigger(),
   mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
   mPositionSize(positionSize),
   mColorDepth(colorDepth),
@@ -53,14 +58,17 @@ GlWindowRenderThread::GlWindowRenderThread(PositionSize positionSize, ColorDepth
   mIsEGLInitialize(false),
   mGLESVersion(30), //Default GLES version 30
   mMSAA(0),
+  mWindowRotationAngle(0),
+  mScreenRotationAngle(0),
   mRenderThreadWaitCondition(),
   mDestroyRenderThread(0),
   mPauseRenderThread(0),
   mRenderingMode(0),
-  mRequestRenderOnce(0)
+  mRequestRenderOnce(0),
+  mSurfaceStatus(0),
+  mPostRendering(0),
+  mDefaultFrameDurationNanoseconds(REFRESH_RATE * DEFAULT_FRAME_DURATION_IN_NANOSECONDS)
 {
-  unsigned int refrashRate         = 1u;
-  mDefaultFrameDurationNanoseconds = uint64_t(refrashRate) * DEFAULT_FRAME_DURATION_IN_NANOSECONDS;
 }
 
 GlWindowRenderThread::~GlWindowRenderThread()
@@ -136,13 +144,83 @@ void GlWindowRenderThread::RenderOnce()
   mRenderThreadWaitCondition.Notify(lock);
 }
 
+void GlWindowRenderThread::RequestWindowResize(int width, int height)
+{
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+  // Check resizing
+  if((fabs(width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
+     (fabs(height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE))
+  {
+    mSurfaceStatus |= static_cast<unsigned int>(SurfaceStatus::RESIZED); // Set bit for window resized
+    mPositionSize.width  = width;
+    mPositionSize.height = height;
+
+    DALI_LOG_RELEASE_INFO("GlWindowRenderThread::RequestWindowResize(), width:%d, height:%d\n", width, height);
+    mRenderThreadWaitCondition.Notify(lock);
+  }
+}
+
+void GlWindowRenderThread::RequestWindowRotate(int windowAngle)
+{
+  if(!mWindowRotationTrigger)
+  {
+    mWindowRotationTrigger = std::unique_ptr<TriggerEventInterface>(TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &GlWindowRenderThread::WindowRotationCompleted),
+                                                                                                            TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER));
+  }
+
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+  if(mWindowRotationAngle != windowAngle)
+  {
+    mSurfaceStatus |= static_cast<unsigned int>(SurfaceStatus::WINDOW_ROTATED); // Set bit for window rotation
+    mWindowRotationAngle = windowAngle;
+    DALI_LOG_RELEASE_INFO("GlWindowRenderThread::RequestWindowRotate(): %d\n", windowAngle);
+    mRenderThreadWaitCondition.Notify(lock);
+  }
+}
+
+void GlWindowRenderThread::RequestScreenRotate(int screenAngle)
+{
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+  if(mScreenRotationAngle != screenAngle)
+  {
+    mSurfaceStatus |= static_cast<unsigned int>(SurfaceStatus::SCREEN_ROTATED); // Set bit for screen rotation
+    mScreenRotationAngle = screenAngle;
+    DALI_LOG_RELEASE_INFO("GlWindowRenderThread::RequestScreenRotate(): %d\n", screenAngle);
+    mRenderThreadWaitCondition.Notify(lock);
+  }
+}
+
+void GlWindowRenderThread::WindowRotationCompleted()
+{
+  mWindowBase->WindowRotationCompleted(mWindowRotationAngle, mPositionSize.width, mPositionSize.height);
+
+  PostRenderFinish();
+}
+
+unsigned int GlWindowRenderThread::GetSurfaceStatus(int& windowRotationAngle, int& screenRotationAngle)
+{
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+
+  // Get the surface status and reset that.
+  unsigned int status = mSurfaceStatus;
+  mSurfaceStatus      = static_cast<unsigned int>(SurfaceStatus::NO_CHANGED);
+
+  windowRotationAngle = mWindowRotationAngle;
+  screenRotationAngle = mScreenRotationAngle;
+
+  return status;
+}
+
 void GlWindowRenderThread::Run()
 {
   Dali::SetThreadName("GlWindowRenderThread");
   mLogFactory.InstallLogFunction();
 
   int          renderFrameResult = 0;
-  EglGraphics* eglGraphics       = static_cast<EglGraphics*>(mGraphics);
+  unsigned int isSurfaceChanged  = 0;
+  bool         isWindowResized = false, isWindowRotated = false, isScreenRotated = false;
+  int          windowRotationAngle = 0, screenRotationAngle = 0, totalAngle = 0;
+  EglGraphics* eglGraphics = static_cast<EglGraphics*>(mGraphics);
 
   Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
 
@@ -164,8 +242,58 @@ void GlWindowRenderThread::Run()
 
     if(mGLRenderFrameCallback)
     {
+      // PreRender
+      isSurfaceChanged = GetSurfaceStatus(windowRotationAngle, screenRotationAngle);
+      if(DALI_UNLIKELY(isSurfaceChanged))
+      {
+        isWindowResized = (isSurfaceChanged & static_cast<unsigned int>(SurfaceStatus::RESIZED)) ? true : false;
+        isWindowRotated = (isSurfaceChanged & static_cast<unsigned int>(SurfaceStatus::WINDOW_ROTATED)) ? true : false;
+        isScreenRotated = (isSurfaceChanged & static_cast<unsigned int>(SurfaceStatus::SCREEN_ROTATED)) ? true : false;
+        totalAngle      = (windowRotationAngle + screenRotationAngle) % 360;
+
+        if(isWindowRotated || isScreenRotated)
+        {
+          mWindowBase->SetEglWindowBufferTransform(totalAngle);
+          if(isWindowRotated)
+          {
+            mWindowBase->SetEglWindowTransform(windowRotationAngle);
+          }
+        }
+
+        if(isWindowResized)
+        {
+          Dali::PositionSize positionSize;
+          positionSize.x = mPositionSize.x;
+          positionSize.y = mPositionSize.y;
+          if(totalAngle == 0 || totalAngle == 180)
+          {
+            positionSize.width  = mPositionSize.width;
+            positionSize.height = mPositionSize.height;
+          }
+          else
+          {
+            positionSize.width  = mPositionSize.height;
+            positionSize.height = mPositionSize.width;
+          }
+          mWindowBase->ResizeEglWindow(positionSize);
+        }
+      }
+
+      // Render
       renderFrameResult = CallbackBase::ExecuteReturn<int>(*mGLRenderFrameCallback);
 
+      // PostRender
+      if(DALI_UNLIKELY(isWindowRotated))
+      {
+        PostRenderStart();
+
+        mWindowRotationTrigger->Trigger();
+
+        PostRenderWaitForFinished();
+        isWindowRotated = false;
+      }
+
+      // buffer commit
       if(renderFrameResult)
       {
         eglImpl.SwapBuffers(mEGLSurface);
@@ -253,7 +381,7 @@ void GlWindowRenderThread::InitializeGraphics(EglGraphics* eglGraphics)
 bool GlWindowRenderThread::RenderReady(uint64_t& timeToSleepUntil)
 {
   ConditionalWait::ScopedLock updateLock(mRenderThreadWaitCondition);
-  while((!mDestroyRenderThread && mRenderingMode && !mRequestRenderOnce) || mPauseRenderThread)
+  while((!mDestroyRenderThread && mRenderingMode && !mRequestRenderOnce && !mSurfaceStatus) || mPauseRenderThread)
   {
     timeToSleepUntil = 0;
     mRenderThreadWaitCondition.Wait(updateLock);
@@ -264,6 +392,28 @@ bool GlWindowRenderThread::RenderReady(uint64_t& timeToSleepUntil)
   return !mDestroyRenderThread;
 }
 
+void GlWindowRenderThread::PostRenderStart()
+{
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+  mPostRendering = false;
+}
+
+void GlWindowRenderThread::PostRenderFinish()
+{
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+  mPostRendering = true;
+  mRenderThreadWaitCondition.Notify(lock);
+}
+
+void GlWindowRenderThread::PostRenderWaitForFinished()
+{
+  ConditionalWait::ScopedLock lock(mRenderThreadWaitCondition);
+  while(!mPostRendering && !mDestroyRenderThread)
+  {
+    mRenderThreadWaitCondition.Wait(lock);
+  }
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index 8111d69..8283c30 100644 (file)
@@ -29,6 +29,7 @@
 namespace Dali
 {
 class Adaptor;
+class TriggerEventInterface;
 
 namespace Internal
 {
@@ -61,6 +62,19 @@ class GlWindowRenderThread : public Dali::Thread
 {
 public:
   /**
+   * @brief Enumeration for GlWindow Surface status type
+   * It has the status as resized, window is rotated and screen is rotated.
+   *
+   */
+  enum class SurfaceStatus
+  {
+    NO_CHANGED     = 0x00, ///< no changed,
+    RESIZED        = 0x01, ///< When surface is resized,
+    WINDOW_ROTATED = 0x02, ///< When window is rotated,
+    SCREEN_ROTATED = 0x04  ///< When screen is rotated,
+  };
+
+  /**
    * Constructor
    *
    * @param[in] positionSize The position and size of the physical window
@@ -141,6 +155,28 @@ public:
    */
   void RenderOnce();
 
+  /**
+   * Requests the window resize to GlWindow's render thread.
+   *
+   * @param[in] width new width.
+   * @param[in] height new height.
+   */
+  void RequestWindowResize(int width, int height);
+
+  /**
+   * Requests the window rotation to GlWindow's render thread.
+   *
+   * @param[in] windowAngle the window rotation's angle as 0, 90, 180 and 270.
+   */
+  void RequestWindowRotate(int windowAngle);
+
+  /**
+   * Requests the screen rotation to GlWindow's render thread.
+   *
+   * @param[in] screenAngle the screen rotation's angle as 0, 90, 180 and 270.
+   */
+  void RequestScreenRotate(int screenAngle);
+
 protected:
   /**
    * The Render thread loop. This thread will be destroyed on exit from this function.
@@ -161,9 +197,53 @@ private:
    */
   bool RenderReady(uint64_t& timeToSleepUntil);
 
+  /**
+   * In the Tizen world, when GlWindow rotation is finished in client side,
+   * the completed message should be sent to display server.
+   * This function should be called in the event thread after buffer is committed.
+   */
+  void WindowRotationCompleted();
+
+  /**
+   * Gets window's current surface status
+   *
+   * @brief This function return window's current surface status.
+   * The status has the  the information of window resized, window rotated and screen rotated.
+   * After called, the status value is reset
+   *
+   * @[output] windowRotationAngle return current window rotation angle.
+   * @[output] screenRotationAngle return current screen rotation angle.
+   * @return the window's current surface status.
+   */
+  unsigned int GetSurfaceStatus(int& windowRotationAngle, int& screenRotationAngle);
+
+  /**
+   * Starts post rendering process
+   *
+   * @brief Starts post rendering process for window rotation
+   * It is to pause the render thread until maint thread finishes the window rotation work.
+   */
+  void PostRenderStart();
+
+  /**
+   * Finishs post rendering process
+   *
+   * @brief Finishes post rendering process for window rotation
+   * It set the resume flag for resume the render thread.
+   */
+  void PostRenderFinish();
+
+  /**
+   * Pauses the render thread unitil post rendering process
+   *
+   * @brief Pauses the render thread until main thread works window rotation.
+   */
+  void PostRenderWaitForFinished();
+
 private:
-  GraphicsInterface* mGraphics; ///< Graphics interface
-  WindowBase*        mWindowBase;
+  GraphicsInterface*                     mGraphics; ///< Graphics interface
+  WindowBase*                            mWindowBase;
+  std::unique_ptr<TriggerEventInterface> mWindowRotationTrigger;
 
   const Dali::LogFactoryInterface& mLogFactory;
 
@@ -181,13 +261,17 @@ private:
   bool                          mIsEGLInitialize : 1;
   int                           mGLESVersion;
   int                           mMSAA;
+  int                           mWindowRotationAngle; ///< The angle of window rotation angle
+  int                           mScreenRotationAngle; ///< The angle of screen rotation angle
 
   // To manage the render/main thread
-  ConditionalWait       mRenderThreadWaitCondition; ///< The wait condition for the update-render-thread.
-  volatile unsigned int mDestroyRenderThread;       ///< Stop render thread. It means this rendter thread will be destoried.
-  volatile unsigned int mPauseRenderThread;         ///< Sleep render thread by pause.
-  volatile unsigned int mRenderingMode;             ///< Rendering Mode, 0: continuous, 1:OnDemad
-  volatile unsigned int mRequestRenderOnce;         ///< Request rendering once
+  ConditionalWait                 mRenderThreadWaitCondition; ///< The wait condition for the update-render-thread.
+  volatile unsigned int           mDestroyRenderThread;       ///< Stop render thread. It means this rendter thread will be destoried.
+  volatile unsigned int           mPauseRenderThread;         ///< Sleep render thread by pause.
+  volatile unsigned int           mRenderingMode;             ///< Rendering Mode, 0: continuous, 1:OnDemad
+  volatile unsigned int           mRequestRenderOnce;         ///< Request rendering once
+  volatile unsigned int           mSurfaceStatus;             ///< When surface is changed as resized or rotated, this flag is set. 0: No changed, 1:resized, 2:window rotation, 4:screen rotation
+  volatile unsigned int           mPostRendering;             ///< Whether post-rendering is taking place (set by the event & render threads, read by the render-thread).
 
   uint64_t mDefaultFrameDurationNanoseconds; ///< Default duration of a frame (used for sleeping if not enough time elapsed). Not protected by lock, but written to rarely so not worth adding a lock when reading.
 
index 867b72a..659ad2c 100644 (file)
@@ -39,7 +39,8 @@ WindowBase::WindowBase()
   mStyleChangedSignal(),
   mAccessibilitySignal(),
   mTransitionEffectEventSignal(),
-  mKeyboardRepeatSettingsChangedSignal()
+  mKeyboardRepeatSettingsChangedSignal(),
+  mUpdatePositionSizeSignal()
 {
 }
 
@@ -127,6 +128,12 @@ WindowBase::WindowRedrawRequestSignalType& WindowBase::WindowRedrawRequestSignal
   return mWindowRedrawRequestSignal;
 }
 
+WindowBase::UpdatePositionSizeType& WindowBase::UpdatePositionSizeSignal()
+{
+  return mUpdatePositionSizeSignal;
+}
+
+
 } // namespace Adaptor
 
 } // namespace Internal
index 62a70ed..ddb2993 100644 (file)
@@ -72,6 +72,7 @@ public:
   typedef Signal<void(WindowEffectState, WindowEffectType)> TransitionEffectEventSignalType;
   typedef Signal<void()>                                    KeyboardRepeatSettingsChangedSignalType;
   typedef Signal<void()>                                    WindowRedrawRequestSignalType;
+  typedef Signal<void(Dali::PositionSize&)>                 UpdatePositionSizeType;
 
   // Input events
   typedef Signal<void(Integration::Point&, uint32_t)> TouchEventSignalType;
@@ -251,7 +252,7 @@ public:
   /**
    * @copydoc Dali::Window::SetNotificationLevel()
    */
-  virtual bool SetNotificationLevel(Dali::WindowNotificationLevel level) = 0;
+  virtual Dali::WindowOperationResult SetNotificationLevel(Dali::WindowNotificationLevel level) = 0;
 
   /**
    * @copydoc Dali::Window::GetNotificationLevel()
@@ -266,7 +267,7 @@ public:
   /**
    * @copydoc Dali::Window::SetScreenOffMode()
    */
-  virtual bool SetScreenOffMode(WindowScreenOffMode screenOffMode) = 0;
+  virtual Dali::WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) = 0;
 
   /**
    * @copydoc Dali::Window::GetScreenOffMode()
@@ -276,7 +277,7 @@ public:
   /**
    * @copydoc Dali::Window::SetBrightness()
    */
-  virtual bool SetBrightness(int brightness) = 0;
+  virtual Dali::WindowOperationResult SetBrightness(int brightness) = 0;
 
   /**
    * @copydoc Dali::Window::GetBrightness()
@@ -435,6 +436,11 @@ public:
    */
   WindowRedrawRequestSignalType& WindowRedrawRequestSignal();
 
+  /**
+   * @brief This signal is emitted when the window is resized or moved by display server.
+   */
+  UpdatePositionSizeType& UpdatePositionSizeSignal();
+
 protected:
   // Undefined
   WindowBase(const WindowBase&) = delete;
@@ -459,6 +465,8 @@ protected:
   TransitionEffectEventSignalType         mTransitionEffectEventSignal;
   KeyboardRepeatSettingsChangedSignalType mKeyboardRepeatSettingsChangedSignal;
   WindowRedrawRequestSignalType           mWindowRedrawRequestSignal;
+  UpdatePositionSizeType                  mUpdatePositionSizeSignal;
+
 };
 
 } // namespace Adaptor
index fe37203..a5917bd 100644 (file)
@@ -79,7 +79,6 @@ Window::Window()
   mIsFocusAcceptable(true),
   mIconified(false),
   mOpaqueState(false),
-  mResizeEnabled(false),
   mType(WindowType::NORMAL),
   mParentWindow(NULL),
   mPreferredAngle(static_cast<int>(WindowOrientation::NO_ORIENTATION_PREFERENCE)),
@@ -132,14 +131,11 @@ void Window::Initialize(Any surface, const PositionSize& positionSize, const std
   mWindowBase->TransitionEffectEventSignal().Connect(this, &Window::OnTransitionEffectEvent);
   mWindowBase->KeyboardRepeatSettingsChangedSignal().Connect(this, &Window::OnKeyboardRepeatSettingsChanged);
   mWindowBase->WindowRedrawRequestSignal().Connect(this, &Window::OnWindowRedrawRequest);
+  mWindowBase->UpdatePositionSizeSignal().Connect(this, &Window::OnUpdatePositionSize);
 
   mWindowSurface->OutputTransformedSignal().Connect(this, &Window::OnOutputTransformed);
 
-  if(!positionSize.IsEmpty())
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
+  AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
 
   SetClass(name, className);
 
@@ -515,12 +511,12 @@ WindowType Window::GetType() const
   return mType;
 }
 
-bool Window::SetNotificationLevel(WindowNotificationLevel level)
+WindowOperationResult Window::SetNotificationLevel(WindowNotificationLevel level)
 {
   if(mType != WindowType::NOTIFICATION)
   {
     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType);
-    return false;
+    return WindowOperationResult::INVALID_OPERATION;
   }
 
   return mWindowBase->SetNotificationLevel(level);
@@ -551,7 +547,7 @@ bool Window::IsOpaqueState() const
   return mOpaqueState;
 }
 
-bool Window::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+WindowOperationResult Window::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
   return mWindowBase->SetScreenOffMode(screenOffMode);
 }
@@ -561,12 +557,12 @@ WindowScreenOffMode Window::GetScreenOffMode() const
   return mWindowBase->GetScreenOffMode();
 }
 
-bool Window::SetBrightness(int brightness)
+WindowOperationResult Window::SetBrightness(int brightness)
 {
   if(brightness < 0 || brightness > 100)
   {
     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness);
-    return false;
+    return WindowOperationResult::INVALID_OPERATION;
   }
 
   return mWindowBase->SetBrightness(brightness);
@@ -579,12 +575,6 @@ int Window::GetBrightness() const
 
 void Window::SetSize(Dali::Window::WindowSize size)
 {
-  if(!mResizeEnabled)
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
-
   PositionSize oldRect = mSurface->GetPositionSize();
 
   mWindowSurface->MoveResize(PositionSize(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
@@ -620,12 +610,6 @@ Dali::Window::WindowSize Window::GetSize() const
 
 void Window::SetPosition(Dali::Window::WindowPosition position)
 {
-  if(!mResizeEnabled)
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
-
   PositionSize oldRect = mSurface->GetPositionSize();
 
   mWindowSurface->MoveResize(PositionSize(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
@@ -642,12 +626,6 @@ Dali::Window::WindowPosition Window::GetPosition() const
 
 void Window::SetPositionSize(PositionSize positionSize)
 {
-  if(!mResizeEnabled)
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
-
   PositionSize oldRect = mSurface->GetPositionSize();
 
   mWindowSurface->MoveResize(positionSize);
@@ -796,6 +774,11 @@ void Window::OnWindowRedrawRequest()
   mAdaptor->RenderOnce();
 }
 
+void Window::OnUpdatePositionSize(Dali::PositionSize& positionSize)
+{
+  SetPositionSize(positionSize);
+}
+
 void Window::OnTouchPoint(Dali::Integration::Point& point, int timeStamp)
 {
   FeedTouchPoint(point, timeStamp);
index cb27eb1..6e3b382 100644 (file)
@@ -221,7 +221,7 @@ public:
   /**
    * @copydoc Dali::Window::SetNotificationLevel()
    */
-  bool SetNotificationLevel(WindowNotificationLevel level);
+  WindowOperationResult SetNotificationLevel(WindowNotificationLevel level);
 
   /**
    * @copydoc Dali::Window::GetNotificationLevel()
@@ -241,7 +241,7 @@ public:
   /**
    * @copydoc Dali::Window::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode);
+  WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode);
 
   /**
    * @copydoc Dali::Window::GetScreenOffMode()
@@ -251,7 +251,7 @@ public:
   /**
    * @copydoc Dali::Window::SetBrightness()
    */
-  bool SetBrightness(int brightness);
+  WindowOperationResult SetBrightness(int brightness);
 
   /**
    * @copydoc Dali::Window::GetBrightness()
@@ -434,6 +434,13 @@ private:
   void OnWindowRedrawRequest();
 
   /**
+   * @brief Called when the window is resized or moved by display server.
+   *
+   * @param positionSize the updated window's position and size.
+   */
+  void OnUpdatePositionSize(Dali::PositionSize& positionSize);
+
+  /**
    * @brief Set available orientation to window base.
    */
   void SetAvailableAnlges(const std::vector<int>& angles);
@@ -566,7 +573,6 @@ private:
   bool                 mIsFocusAcceptable : 1;
   bool                 mIconified : 1;
   bool                 mOpaqueState : 1;
-  bool                 mResizeEnabled : 1;
   WindowType           mType;
   Dali::Window         mParentWindow;
 
index b5fffa8..7f6c29f 100644 (file)
@@ -79,6 +79,45 @@ void InsertRects(WindowRenderSurface::DamagedRectsContainer& damagedRectsList, c
   }
 }
 
+Rect<int32_t> RecalculateRect0(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  return rect;
+}
+
+Rect<int32_t> RecalculateRect90(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  Rect<int32_t> newRect;
+  newRect.x      = surfaceSize.height - (rect.y + rect.height);
+  newRect.y      = rect.x;
+  newRect.width  = rect.height;
+  newRect.height = rect.width;
+  return newRect;
+}
+
+Rect<int32_t> RecalculateRect180(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  Rect<int32_t> newRect;
+  newRect.x      = surfaceSize.width - (rect.x + rect.width);
+  newRect.y      = surfaceSize.height - (rect.y + rect.height);
+  newRect.width  = rect.width;
+  newRect.height = rect.height;
+  return newRect;
+}
+
+Rect<int32_t> RecalculateRect270(Rect<int32_t>& rect, const Rect<int32_t>& surfaceSize)
+{
+  Rect<int32_t> newRect;
+  newRect.x      = rect.y;
+  newRect.y      = surfaceSize.width - (rect.x + rect.width);
+  newRect.width  = rect.height;
+  newRect.height = rect.width;
+  return newRect;
+}
+
+using RecalculateRectFunction = Rect<int32_t> (*)(Rect<int32_t>&, const Rect<int32_t>&);
+
+RecalculateRectFunction RecalculateRect[4] = {RecalculateRect0, RecalculateRect90, RecalculateRect180, RecalculateRect270};
+
 } // unnamed namespace
 
 WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any surface, bool isTransparent)
@@ -344,15 +383,15 @@ void WindowRenderSurface::MoveResize(Dali::PositionSize positionSize)
   bool needToResize = false;
 
   // Check moving
-  if((fabs(positionSize.x - mPositionSize.x) > MINIMUM_DIMENSION_CHANGE) ||
-     (fabs(positionSize.y - mPositionSize.y) > MINIMUM_DIMENSION_CHANGE))
+  if((fabs(positionSize.x - mPositionSize.x) >= MINIMUM_DIMENSION_CHANGE) ||
+     (fabs(positionSize.y - mPositionSize.y) >= MINIMUM_DIMENSION_CHANGE))
   {
     needToMove = true;
   }
 
   // Check resizing
-  if((fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
-     (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE))
+  if((fabs(positionSize.width - mPositionSize.width) >= MINIMUM_DIMENSION_CHANGE) ||
+     (fabs(positionSize.height - mPositionSize.height) >= MINIMUM_DIMENSION_CHANGE))
   {
     needToResize = true;
   }
@@ -738,8 +777,16 @@ void WindowRenderSurface::SetBufferDamagedRects(const std::vector<Rect<int>>& da
       return;
     }
 
-    std::vector<Rect<int>> damagedRegion;
-    damagedRegion.push_back(clippingRect);
+    std::vector<Rect<int>>   damagedRegion;
+    Dali::Integration::Scene scene = mScene.GetHandle();
+    if(scene)
+    {
+      damagedRegion.push_back(RecalculateRect[std::min(scene.GetCurrentSurfaceOrientation() / 90, 3)](clippingRect, scene.GetCurrentSurfaceRect()));
+    }
+    else
+    {
+      damagedRegion.push_back(clippingRect);
+    }
 
     eglImpl.SetDamageRegion(mEGLSurface, damagedRegion);
   }
@@ -750,7 +797,15 @@ void WindowRenderSurface::SwapBuffers(const std::vector<Rect<int>>& damagedRects
   auto eglGraphics = static_cast<EglGraphics*>(mGraphics);
   if(eglGraphics)
   {
-    Rect<int> surfaceRect(0, 0, mPositionSize.width, mPositionSize.height);
+    Rect<int32_t> surfaceRect;
+    int32_t       orientation = 0;
+
+    Dali::Integration::Scene scene = mScene.GetHandle();
+    if(scene)
+    {
+      surfaceRect = scene.GetCurrentSurfaceRect();
+      orientation = std::min(scene.GetCurrentSurfaceOrientation() / 90, 3);
+    }
 
     Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
 
@@ -796,7 +851,7 @@ void WindowRenderSurface::SwapBuffers(const std::vector<Rect<int>>& damagedRects
     {
       if(!mergedRects[i].IsEmpty())
       {
-        mergedRects[j++] = mergedRects[i];
+        mergedRects[j++] = RecalculateRect[orientation](mergedRects[i], surfaceRect);
       }
     }
 
index dc0ee59..1637f36 100644 (file)
@@ -195,7 +195,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel()
    */
-  bool SetNotificationLevel(WindowNotificationLevel level) override;
+  WindowOperationResult SetNotificationLevel(WindowNotificationLevel level) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel()
@@ -210,7 +210,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
+  WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode()
@@ -220,7 +220,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness()
    */
-  bool SetBrightness(int brightness) override;
+  WindowOperationResult SetBrightness(int brightness) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness()
index b98f8a6..7015c2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -535,9 +535,9 @@ void WindowBaseCocoa::SetType( Dali::WindowType type )
 {
 }
 
-bool WindowBaseCocoa::SetNotificationLevel( WindowNotificationLevel level )
+WindowOperationResult WindowBaseCocoa::SetNotificationLevel( WindowNotificationLevel level )
 {
-  return false;
+  return WindowOperationResult::NOT_SUPPORTED;
 }
 
 WindowNotificationLevel WindowBaseCocoa::GetNotificationLevel() const
@@ -549,9 +549,9 @@ void WindowBaseCocoa::SetOpaqueState( bool opaque )
 {
 }
 
-bool WindowBaseCocoa::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+WindowOperationResult WindowBaseCocoa::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
-  return false;
+  return WindowOperationResult::NOT_SUPPORTED;
 }
 
 WindowScreenOffMode WindowBaseCocoa::GetScreenOffMode() const
@@ -559,9 +559,9 @@ WindowScreenOffMode WindowBaseCocoa::GetScreenOffMode() const
   return WindowScreenOffMode::TIMEOUT;
 }
 
-bool WindowBaseCocoa::SetBrightness( int brightness )
+WindowOperationResult WindowBaseCocoa::SetBrightness( int brightness )
 {
-  return false;
+  return WindowOperationResult::NOT_SUPPORTED;
 }
 
 int WindowBaseCocoa::GetBrightness() const
index 3a07b04..c177432 100644 (file)
@@ -1565,7 +1565,7 @@ void WindowBaseEcoreWl::SetType(Dali::WindowType type)
   ecore_wl_window_type_set(mEcoreWindow, windowType);
 }
 
-bool WindowBaseEcoreWl::SetNotificationLevel(Dali::WindowNotificationLevel level)
+Dali::WindowOperationResult WindowBaseEcoreWl::SetNotificationLevel(Dali::WindowNotificationLevel level)
 {
   while(!mTizenPolicy)
   {
@@ -1626,17 +1626,17 @@ bool WindowBaseEcoreWl::SetNotificationLevel(Dali::WindowNotificationLevel level
   if(!mNotificationLevelChangeDone)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetNotificationLevel: Level change is failed [%d, %d]\n", level, mNotificationChangeState);
-    return false;
+    return Dali::WindowOperationResult::UNKNOWN_ERROR;
   }
   else if(mNotificationChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetNotificationLevel: Permission denied! [%d]\n", level);
-    return false;
+    return Dali::WindowOperationResult::PERMISSION_DENIED;
   }
 
   DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetNotificationLevel: Level is changed [%d]\n", mNotificationLevel);
 
-  return true;
+  return Dali::WindowOperationResult::SUCCEED;
 }
 
 Dali::WindowNotificationLevel WindowBaseEcoreWl::GetNotificationLevel() const
@@ -1713,7 +1713,7 @@ void WindowBaseEcoreWl::SetOpaqueState(bool opaque)
   tizen_policy_set_opaque_state(mTizenPolicy, ecore_wl_window_surface_get(mEcoreWindow), (opaque ? 1 : 0));
 }
 
-bool WindowBaseEcoreWl::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+Dali::WindowOperationResult WindowBaseEcoreWl::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
   while(!mTizenPolicy)
   {
@@ -1753,17 +1753,17 @@ bool WindowBaseEcoreWl::SetScreenOffMode(WindowScreenOffMode screenOffMode)
   if(!mScreenOffModeChangeDone)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetScreenOffMode: Screen mode change is failed [%d, %d]\n", screenOffMode, mScreenOffModeChangeState);
-    return false;
+    return Dali::WindowOperationResult::UNKNOWN_ERROR;
   }
   else if(mScreenOffModeChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetScreenOffMode: Permission denied! [%d]\n", screenOffMode);
-    return false;
+    return Dali::WindowOperationResult::PERMISSION_DENIED;
   }
 
   DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetScreenOffMode: Screen mode is changed [%d]\n", mScreenOffMode);
 
-  return true;
+  return Dali::WindowOperationResult::SUCCEED;
 }
 
 WindowScreenOffMode WindowBaseEcoreWl::GetScreenOffMode() const
@@ -1809,7 +1809,7 @@ WindowScreenOffMode WindowBaseEcoreWl::GetScreenOffMode() const
   return screenMode;
 }
 
-bool WindowBaseEcoreWl::SetBrightness(int brightness)
+Dali::WindowOperationResult WindowBaseEcoreWl::SetBrightness(int brightness)
 {
   while(!mTizenDisplayPolicy)
   {
@@ -1833,17 +1833,17 @@ bool WindowBaseEcoreWl::SetBrightness(int brightness)
   if(!mBrightnessChangeDone)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetBrightness: Brightness change is failed [%d, %d]\n", brightness, mBrightnessChangeState);
-    return false;
+    return Dali::WindowOperationResult::UNKNOWN_ERROR;
   }
   else if(mBrightnessChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetBrightness: Permission denied! [%d]\n", brightness);
-    return false;
+    return Dali::WindowOperationResult::PERMISSION_DENIED;
   }
 
   DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::SetBrightness: Brightness is changed [%d]\n", mBrightness);
 
-  return true;
+  return Dali::WindowOperationResult::SUCCEED;
 }
 
 int WindowBaseEcoreWl::GetBrightness() const
index 8726cd4..7c3bdd7 100644 (file)
@@ -333,7 +333,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel()
    */
-  bool SetNotificationLevel(Dali::WindowNotificationLevel level) override;
+  Dali::WindowOperationResult SetNotificationLevel(Dali::WindowNotificationLevel level) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel()
@@ -348,7 +348,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
+  Dali::WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode()
@@ -358,7 +358,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness()
    */
-  bool SetBrightness(int brightness) override;
+  Dali::WindowOperationResult SetBrightness(int brightness) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness()
index 4c91c35..7587ece 100644 (file)
@@ -1004,10 +1004,40 @@ void WindowBaseEcoreWl2::OnConfiguration(void* data, int type, void* event)
 {
   Ecore_Wl2_Event_Window_Configure* ev(static_cast<Ecore_Wl2_Event_Window_Configure*>(event));
 
-  if(ev->win == static_cast<unsigned int>(ecore_wl2_window_id_get(mEcoreWindow)))
+  if(ev && ev->win == static_cast<unsigned int>(ecore_wl2_window_id_get(mEcoreWindow)))
   {
     // Note: To comply with the wayland protocol, Dali should make an ack_configure
     // by calling ecore_wl2_window_commit
+
+    int tempWidth  = static_cast<int>(ev->w);
+    int tempHeight = static_cast<int>(ev->h);
+
+    // Initialize with previous size for skip resize when new size is 0.
+    // When window is just moved or window is resized by client application,
+    // The configure notification event's size will be 0.
+    // If new size is 0, the resized work should be skip.
+    int newWidth = mWindowPositionSize.width;
+    int newHeight = mWindowPositionSize.height;
+    bool windowMoved = false, windowResized = false;
+
+    if(ev->x != mWindowPositionSize.x || ev->y != mWindowPositionSize.y)
+    {
+      windowMoved = true;
+    }
+
+    if(tempWidth != 0 && tempHeight != 0 && (tempWidth != mWindowPositionSize.width || tempHeight != mWindowPositionSize.height))
+    {
+      windowResized = true;
+      newWidth = tempWidth;
+      newHeight = tempHeight;
+    }
+
+    if(windowMoved || windowResized)
+    {
+      Dali::PositionSize newPositionSize(ev->x, ev->y, newWidth, newHeight);
+      mUpdatePositionSizeSignal.Emit(newPositionSize);
+    }
+
     ecore_wl2_window_commit(mEcoreWindow, EINA_FALSE);
   }
 }
@@ -1849,7 +1879,7 @@ void WindowBaseEcoreWl2::SetType(Dali::WindowType type)
   ecore_wl2_window_type_set(mEcoreWindow, windowType);
 }
 
-bool WindowBaseEcoreWl2::SetNotificationLevel(Dali::WindowNotificationLevel level)
+Dali::WindowOperationResult WindowBaseEcoreWl2::SetNotificationLevel(Dali::WindowNotificationLevel level)
 {
   while(!mTizenPolicy)
   {
@@ -1910,17 +1940,17 @@ bool WindowBaseEcoreWl2::SetNotificationLevel(Dali::WindowNotificationLevel leve
   if(!mNotificationLevelChangeDone)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: Level change is failed [%d, %d]\n", level, mNotificationChangeState);
-    return false;
+    Dali::WindowOperationResult::UNKNOWN_ERROR;
   }
   else if(mNotificationChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: Permission denied! [%d]\n", level);
-    return false;
+    return Dali::WindowOperationResult::PERMISSION_DENIED;
   }
 
   DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: Level is changed [%d]\n", mNotificationLevel);
 
-  return true;
+  return Dali::WindowOperationResult::SUCCEED;
 }
 
 Dali::WindowNotificationLevel WindowBaseEcoreWl2::GetNotificationLevel() const
@@ -1997,7 +2027,7 @@ void WindowBaseEcoreWl2::SetOpaqueState(bool opaque)
   tizen_policy_set_opaque_state(mTizenPolicy, ecore_wl2_window_surface_get(mEcoreWindow), (opaque ? 1 : 0));
 }
 
-bool WindowBaseEcoreWl2::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+Dali::WindowOperationResult WindowBaseEcoreWl2::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
   while(!mTizenPolicy)
   {
@@ -2037,17 +2067,17 @@ bool WindowBaseEcoreWl2::SetScreenOffMode(WindowScreenOffMode screenOffMode)
   if(!mScreenOffModeChangeDone)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetScreenOffMode: Screen mode change is failed [%d, %d]\n", screenOffMode, mScreenOffModeChangeState);
-    return false;
+    return Dali::WindowOperationResult::UNKNOWN_ERROR;
   }
   else if(mScreenOffModeChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetScreenOffMode: Permission denied! [%d]\n", screenOffMode);
-    return false;
+    return Dali::WindowOperationResult::PERMISSION_DENIED;
   }
 
   DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetScreenOffMode: Screen mode is changed [%d]\n", mScreenOffMode);
 
-  return true;
+  return Dali::WindowOperationResult::SUCCEED;
 }
 
 WindowScreenOffMode WindowBaseEcoreWl2::GetScreenOffMode() const
@@ -2093,7 +2123,7 @@ WindowScreenOffMode WindowBaseEcoreWl2::GetScreenOffMode() const
   return screenMode;
 }
 
-bool WindowBaseEcoreWl2::SetBrightness(int brightness)
+Dali::WindowOperationResult WindowBaseEcoreWl2::SetBrightness(int brightness)
 {
   while(!mTizenDisplayPolicy)
   {
@@ -2117,17 +2147,17 @@ bool WindowBaseEcoreWl2::SetBrightness(int brightness)
   if(!mBrightnessChangeDone)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetBrightness: Brightness change is failed [%d, %d]\n", brightness, mBrightnessChangeState);
-    return false;
+    return Dali::WindowOperationResult::UNKNOWN_ERROR;
   }
   else if(mBrightnessChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED)
   {
     DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetBrightness: Permission denied! [%d]\n", brightness);
-    return false;
+    return Dali::WindowOperationResult::PERMISSION_DENIED;
   }
 
   DALI_LOG_INFO(gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetBrightness: Brightness is changed [%d]\n", mBrightness);
 
-  return true;
+  return Dali::WindowOperationResult::SUCCEED;
 }
 
 int WindowBaseEcoreWl2::GetBrightness() const
index 66582a8..338d234 100644 (file)
@@ -364,7 +364,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel()
    */
-  bool SetNotificationLevel(Dali::WindowNotificationLevel level) override;
+  Dali::WindowOperationResult SetNotificationLevel(Dali::WindowNotificationLevel level) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel()
@@ -379,7 +379,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
+  Dali::WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode()
@@ -389,7 +389,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness()
    */
-  bool SetBrightness(int brightness) override;
+  Dali::WindowOperationResult SetBrightness(int brightness) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness()
index ce439ba..ecdc4e2 100644 (file)
@@ -59,7 +59,6 @@ NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl(SurfaceSize surfaceSize,
   mEGLContext(nullptr),
   mOwnSurface(false),
   mTbmQueue(NULL),
-  mConsumeSurface(NULL),
   mThreadSynchronization(NULL)
 {
   Dali::Internal::Adaptor::WindowSystem::Initialize();
@@ -95,8 +94,6 @@ NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl()
   // release the surface if we own one
   if(mOwnSurface)
   {
-    ReleaseDrawable();
-
     if(mTbmQueue)
     {
       tbm_surface_queue_destroy(mTbmQueue);
@@ -108,11 +105,6 @@ NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl()
   Dali::Internal::Adaptor::WindowSystem::Shutdown();
 }
 
-Any NativeRenderSurfaceEcoreWl::GetDrawable()
-{
-  return mConsumeSurface;
-}
-
 void NativeRenderSurfaceEcoreWl::SetRenderNotification(TriggerEventInterface* renderNotification)
 {
   mRenderNotification = renderNotification;
@@ -242,54 +234,21 @@ void NativeRenderSurfaceEcoreWl::PostRender(bool renderToFbo, bool replacingSurf
     eglImpl.SwapBuffers(mEGLSurface, damagedRects);
   }
 
-  //TODO: Move calling tbm_surface_queue_acruie to OffscreenWindow and Scene in EvasPlugin
-  if(mOwnSurface)
+  if(mRenderNotification)
   {
     if(mThreadSynchronization)
     {
       mThreadSynchronization->PostRenderStarted();
     }
 
-    if(tbm_surface_queue_can_acquire(mTbmQueue, 1))
-    {
-      if(tbm_surface_queue_acquire(mTbmQueue, &mConsumeSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
-      {
-        DALI_LOG_ERROR("Failed to acquire a tbm_surface\n");
-        return;
-      }
-    }
-
-    if(mConsumeSurface)
-    {
-      tbm_surface_internal_ref(mConsumeSurface);
-    }
-
-    // create damage for client applications which wish to know the update timing
-    if(mRenderNotification)
-    {
-      // use notification trigger
-      // Tell the event-thread to render the tbm_surface
-      mRenderNotification->Trigger();
-    }
+    // Tell the event-thread to render the tbm_surface
+    mRenderNotification->Trigger();
 
     if(mThreadSynchronization)
     {
       // wait until the event-thread completed to use the tbm_surface
       mThreadSynchronization->PostRenderWaitForCompletion();
     }
-
-    // release the consumed surface after post render was completed
-    ReleaseDrawable();
-  }
-  else
-  {
-    // create damage for client applications which wish to know the update timing
-    if(mRenderNotification)
-    {
-      // use notification trigger
-      // Tell the event-thread to render the tbm_surface
-      mRenderNotification->Trigger();
-    }
   }
 }
 
@@ -354,18 +313,4 @@ void NativeRenderSurfaceEcoreWl::CreateNativeRenderable()
   }
 }
 
-void NativeRenderSurfaceEcoreWl::ReleaseDrawable()
-{
-  if(mConsumeSurface)
-  {
-    tbm_surface_internal_unref(mConsumeSurface);
-
-    if(tbm_surface_internal_is_valid(mConsumeSurface))
-    {
-      tbm_surface_queue_release(mTbmQueue, mConsumeSurface);
-    }
-    mConsumeSurface = NULL;
-  }
-}
-
 } // namespace Dali
index 9561801..da93899 100644 (file)
@@ -55,11 +55,6 @@ public:
 
 public: // from WindowRenderSurface
   /**
-   * @copydoc Dali::NativeRenderSurface::GetSurface()
-   */
-  Any GetDrawable() override;
-
-  /**
    * @copydoc Dali::NativeRenderSurface::SetRenderNotification()
    */
   void SetRenderNotification(TriggerEventInterface* renderNotification) override;
@@ -166,11 +161,6 @@ private:
    */
   void CreateNativeRenderable() override;
 
-  /**
-   * @copydoc Dali::NativeRenderSurface::ReleaseDrawable()
-   */
-  void ReleaseDrawable() override;
-
 private: // Data
   SurfaceSize                           mSurfaceSize;
   TriggerEventInterface*                mRenderNotification;
@@ -183,7 +173,6 @@ private: // Data
   bool                                  mOwnSurface;
 
   tbm_surface_queue_h             mTbmQueue;
-  tbm_surface_h                   mConsumeSurface;
   ThreadSynchronizationInterface* mThreadSynchronization; ///< A pointer to the thread-synchronization
 };
 
index b12f37e..0eea078 100644 (file)
@@ -768,9 +768,9 @@ void WindowBaseEcoreX::SetType(Dali::WindowType type)
 {
 }
 
-bool WindowBaseEcoreX::SetNotificationLevel(Dali::WindowNotificationLevel level)
+Dali::WindowOperationResult WindowBaseEcoreX::SetNotificationLevel(Dali::WindowNotificationLevel level)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 Dali::WindowNotificationLevel WindowBaseEcoreX::GetNotificationLevel() const
@@ -782,9 +782,9 @@ void WindowBaseEcoreX::SetOpaqueState(bool opaque)
 {
 }
 
-bool WindowBaseEcoreX::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+Dali::WindowOperationResult WindowBaseEcoreX::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 WindowScreenOffMode WindowBaseEcoreX::GetScreenOffMode() const
@@ -792,9 +792,9 @@ WindowScreenOffMode WindowBaseEcoreX::GetScreenOffMode() const
   return WindowScreenOffMode::TIMEOUT;
 }
 
-bool WindowBaseEcoreX::SetBrightness(int brightness)
+Dali::WindowOperationResult WindowBaseEcoreX::SetBrightness(int brightness)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 int WindowBaseEcoreX::GetBrightness() const
index 24081d6..2630578 100644 (file)
@@ -267,7 +267,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel()
    */
-  bool SetNotificationLevel(Dali::WindowNotificationLevel level) override;
+  Dali::WindowOperationResult SetNotificationLevel(Dali::WindowNotificationLevel level) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel()
@@ -282,7 +282,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
+  Dali::WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode()
@@ -292,7 +292,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness()
    */
-  bool SetBrightness(int brightness) override;
+  Dali::WindowOperationResult SetBrightness(int brightness) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness()
index 2b2f6bd..6382e43 100644 (file)
@@ -372,9 +372,9 @@ void WindowBaseWin::SetType(Dali::WindowType type)
 {
 }
 
-bool WindowBaseWin::SetNotificationLevel(Dali::WindowNotificationLevel level)
+Dali::WindowOperationResult WindowBaseWin::SetNotificationLevel(Dali::WindowNotificationLevel level)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 Dali::WindowNotificationLevel WindowBaseWin::GetNotificationLevel() const
@@ -386,9 +386,9 @@ void WindowBaseWin::SetOpaqueState(bool opaque)
 {
 }
 
-bool WindowBaseWin::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+Dali::WindowOperationResult WindowBaseWin::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 WindowScreenOffMode WindowBaseWin::GetScreenOffMode() const
@@ -396,9 +396,9 @@ WindowScreenOffMode WindowBaseWin::GetScreenOffMode() const
   return WindowScreenOffMode::TIMEOUT;
 }
 
-bool WindowBaseWin::SetBrightness(int brightness)
+Dali::WindowOperationResult WindowBaseWin::SetBrightness(int brightness)
 {
-  return false;
+  return Dali::WindowOperationResult::NOT_SUPPORTED;
 }
 
 int WindowBaseWin::GetBrightness() const
index dedbccb..57b51c4 100644 (file)
@@ -254,7 +254,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel()
    */
-  bool SetNotificationLevel(Dali::WindowNotificationLevel level) override;
+  Dali::WindowOperationResult SetNotificationLevel(Dali::WindowNotificationLevel level) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel()
@@ -269,7 +269,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode()
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
+  Dali::WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode()
@@ -279,7 +279,7 @@ public:
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness()
    */
-  bool SetBrightness(int brightness) override;
+  Dali::WindowOperationResult SetBrightness(int brightness) override;
 
   /**
    * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness()
index 22895ca..9797af1 100644 (file)
@@ -93,6 +93,18 @@ enum class WindowEffectType
   HIDE,     ///< Window hide effect. @SINCE_2_0.0
 };
 
+/**
+ * @brief An enum of window operation result.
+ */
+enum class WindowOperationResult
+{
+  UNKNOWN_ERROR = 0, ///< Failed for unknown reason.
+  SUCCEED,           ///< Succeed.
+  PERMISSION_DENIED, ///< Permission denied.
+  NOT_SUPPORTED,     ///< The operation is not supported.
+  INVALID_OPERATION, ///< The operation is invalid. (e.g. Try to operate to the wrong window)
+};
+
 } // namespace Dali
 
 #endif // DALI_WINDOW_ENUMERATIONS_H
index f1b67fe..0000add 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 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.
@@ -248,7 +248,7 @@ WindowType Window::GetType() const
   return GetImplementation(*this).GetType();
 }
 
-bool Window::SetNotificationLevel(WindowNotificationLevel level)
+WindowOperationResult Window::SetNotificationLevel(WindowNotificationLevel level)
 {
   return GetImplementation(*this).SetNotificationLevel(level);
 }
@@ -268,7 +268,7 @@ bool Window::IsOpaqueState() const
   return GetImplementation(*this).IsOpaqueState();
 }
 
-bool Window::SetScreenOffMode(WindowScreenOffMode screenMode)
+WindowOperationResult Window::SetScreenOffMode(WindowScreenOffMode screenMode)
 {
   return GetImplementation(*this).SetScreenOffMode(screenMode);
 }
@@ -278,7 +278,7 @@ WindowScreenOffMode Window::GetScreenOffMode() const
   return GetImplementation(*this).GetScreenOffMode();
 }
 
-bool Window::SetBrightness(int brightness)
+WindowOperationResult Window::SetBrightness(int brightness)
 {
   return GetImplementation(*this).SetBrightness(brightness);
 }
index 759dfcd..e0c8d34 100644 (file)
@@ -420,12 +420,12 @@ public:
    * @brief Sets a priority level for the specified notification window.
    * @@SINCE_2_0.0
    * @param[in] level The notification window level.
-   * @return True if no error occurred, false otherwise.
+   * @return The result of the window operation.
    * @PRIVLEVEL_PUBLIC
    * @PRIVILEGE_WINDOW_PRIORITY
    * @remarks This can be used for a notification type window only. The default level is NotificationLevel::NONE.
    */
-  bool SetNotificationLevel(WindowNotificationLevel level);
+  WindowOperationResult SetNotificationLevel(WindowNotificationLevel level);
 
   /**
    * @brief Gets a priority level for the specified notification window.
@@ -462,11 +462,11 @@ public:
    * If the window is no longer shown, then the window manager requests the display system to go back to normal operation.
    * @@SINCE_2_0.0
    * @param[in] screenOffMode The screen mode.
-   * @return True if no error occurred, false otherwise.
+   * @return The result of the window operation.
    * @PRIVLEVEL_PUBLIC
    * @PRIVILEGE_DISPLAY
    */
-  bool SetScreenOffMode(WindowScreenOffMode screenOffMode);
+  WindowOperationResult SetScreenOffMode(WindowScreenOffMode screenOffMode);
 
   /**
    * @brief Gets a screen off mode of the window.
@@ -483,11 +483,11 @@ public:
    * A value less than 0 results in default brightness and a value greater than 100 results in maximum brightness.
    * @SINCE_1_2.60
    * @param[in] brightness The preferred brightness (0 to 100).
-   * @return True if no error occurred, false otherwise.
+   * @return The result of the window operation.
    * @PRIVLEVEL_PUBLIC
    * @PRIVILEGE_DISPLAY
    */
-  bool SetBrightness(int brightness);
+  WindowOperationResult SetBrightness(int brightness);
 
   /**
    * @brief Gets preferred brightness of the window.
index d51362c..d5752f3 100644 (file)
@@ -27,7 +27,7 @@ namespace Dali
 {
 const unsigned int ADAPTOR_MAJOR_VERSION = 2;
 const unsigned int ADAPTOR_MINOR_VERSION = 0;
-const unsigned int ADAPTOR_MICRO_VERSION = 24;
+const unsigned int ADAPTOR_MICRO_VERSION = 27;
 const char* const  ADAPTOR_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index f77e6b3..aa335e2 100644 (file)
@@ -17,7 +17,7 @@
 
 Name:       dali2-adaptor
 Summary:    The DALi Tizen Adaptor
-Version:    2.0.24
+Version:    2.0.27
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT
@@ -61,6 +61,7 @@ BuildRequires:  pkgconfig(libpng)
 BuildRequires:  pkgconfig(egl)
 BuildRequires:  libcurl-devel
 BuildRequires:  pkgconfig(harfbuzz)
+BuildRequires:  hyphen-devel
 BuildRequires:  fribidi-devel
 
 BuildRequires:  pkgconfig(capi-system-info)