[Tizen] Add GlWindow
authorDaekwang Ryu <dkdk.ryu@samsung.com>
Tue, 15 Sep 2020 02:49:11 +0000 (11:49 +0900)
committerSeoyeon Kim <seoyeon2.kim@samsung.com>
Wed, 16 Sep 2020 02:46:49 +0000 (11:46 +0900)
Add GlWindow to support the native GLES Application.

Change-Id: I0737eda18fd42caf1cac58e588a05f978479598f

dali/devel-api/adaptor-framework/gl-window.cpp [new file with mode: 0644]
dali/devel-api/adaptor-framework/gl-window.h [new file with mode: 0644]
dali/devel-api/file.list
dali/internal/graphics/gles/egl-graphics.cpp
dali/internal/graphics/gles/egl-graphics.h
dali/internal/window-system/common/event-handler.cpp
dali/internal/window-system/common/event-handler.h
dali/internal/window-system/common/gl-window-impl.cpp [new file with mode: 0644]
dali/internal/window-system/common/gl-window-impl.h [new file with mode: 0644]
dali/internal/window-system/common/window-impl.cpp
dali/internal/window-system/file.list

diff --git a/dali/devel-api/adaptor-framework/gl-window.cpp b/dali/devel-api/adaptor-framework/gl-window.cpp
new file mode 100644 (file)
index 0000000..b801233
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2020 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/adaptor-framework/gl-window.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/adaptor-framework/window.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/window-system/common/gl-window-impl.h>
+#include <dali/internal/window-system/common/orientation-impl.h>
+
+namespace Dali
+{
+GlWindow GlWindow::New()
+{
+  PositionSize positionSize( 0, 0, 0, 0 );
+  return Dali::GlWindow::New( positionSize, "", "", false );
+}
+GlWindow GlWindow::New(PositionSize positionSize, const std::string& name, const std::string& className, bool isTransparent )
+{
+  GlWindow newWindow;
+  Internal::Adaptor::GlWindow* window = Internal::Adaptor::GlWindow::New( positionSize, name, className, isTransparent );
+  if( window == nullptr )
+  {
+    DALI_LOG_ERROR("Fail to create gl-window-impl\n");
+  }
+  else
+  {
+    newWindow = GlWindow(window);
+  }
+  const bool isAdaptorAvailable = Dali::Adaptor::IsAvailable();
+  if( isAdaptorAvailable )
+  {
+    Dali::Adaptor& adaptor = Internal::Adaptor::Adaptor::Get();
+    Dali::WindowContainer windows = adaptor.GetWindows();
+    if( !windows.empty() )
+    {
+      window->SetChild( windows[0] );
+    }
+  }
+  return newWindow;
+}
+GlWindow::GlWindow()
+{
+}
+GlWindow::~GlWindow()
+{
+}
+GlWindow::GlWindow(const GlWindow& handle)
+: BaseHandle(handle)
+{
+}
+GlWindow& GlWindow::operator=(const GlWindow& rhs)
+{
+  BaseHandle::operator=(rhs);
+  return *this;
+}
+void GlWindow::SetEglConfig( bool depth, bool stencil, int msaa, GlesVersion version )
+{
+  GetImplementation(*this).SetEglConfig( depth, stencil, msaa, version );
+}
+void GlWindow::Raise()
+{
+  GetImplementation(*this).Raise();
+}
+void GlWindow::Lower()
+{
+  GetImplementation(*this).Lower();
+}
+void GlWindow::Activate()
+{
+  GetImplementation(*this).Activate();
+}
+void GlWindow::Show()
+{
+  GetImplementation(*this).Show();
+}
+void GlWindow::Hide()
+{
+  GetImplementation(*this).Hide();
+}
+unsigned int GlWindow::GetSupportedAuxiliaryHintCount() const
+{
+  return GetImplementation(*this).GetSupportedAuxiliaryHintCount();
+}
+std::string GlWindow::GetSupportedAuxiliaryHint( unsigned int index ) const
+{
+  return GetImplementation(*this).GetSupportedAuxiliaryHint( index );
+}
+unsigned int GlWindow::AddAuxiliaryHint( const std::string& hint, const std::string& value )
+{
+  return GetImplementation(*this).AddAuxiliaryHint( hint, value );
+}
+bool GlWindow::RemoveAuxiliaryHint( unsigned int id )
+{
+  return GetImplementation(*this).RemoveAuxiliaryHint( id );
+}
+bool GlWindow::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
+{
+  return GetImplementation(*this).SetAuxiliaryHintValue( id, value );
+}
+std::string GlWindow::GetAuxiliaryHintValue( unsigned int id ) const
+{
+  return GetImplementation(*this).GetAuxiliaryHintValue( id );
+}
+unsigned int GlWindow::GetAuxiliaryHintId( const std::string& hint ) const
+{
+  return GetImplementation(*this).GetAuxiliaryHintId( hint );
+}
+void GlWindow::SetInputRegion( const Rect< int >& inputRegion )
+{
+  GetImplementation(*this).SetInputRegion( inputRegion );
+}
+void GlWindow::SetOpaqueState( bool opaque )
+{
+  GetImplementation(*this).SetOpaqueState( opaque );
+}
+bool GlWindow::IsOpaqueState() const
+{
+  return GetImplementation(*this).IsOpaqueState();
+}
+void GlWindow::SetPositionSize( PositionSize positionSize )
+{
+  GetImplementation(*this).SetPositionSize( positionSize );
+}
+PositionSize GlWindow::GetPositionSize() const
+{
+  return GetImplementation(*this).GetPositionSize();
+}
+Dali::GlWindow::GlWindowOrientation GlWindow::GetCurrentOrientation() const
+{
+  return GetImplementation( *this ).GetCurrentOrientation();
+}
+void GlWindow::SetAvailableOrientations( const Dali::Vector< Dali::GlWindow::GlWindowOrientation >& orientations )
+{
+  GetImplementation( *this ).SetAvailableOrientations( orientations );
+}
+void GlWindow::SetPreferredOrientation( Dali::GlWindow::GlWindowOrientation orientation )
+{
+  GetImplementation(*this).SetPreferredOrientation( orientation );
+}
+void GlWindow::RegisterGlCallback( GlInitialize glInit, GlRenderFrame glRenderFrame, GlTerminate glTerminate )
+{
+  GetImplementation(*this).RegisterGlCallback( glInit, glRenderFrame, glTerminate );
+}
+void GlWindow::RenderOnce()
+{
+  GetImplementation(*this).RenderOnce();
+}
+GlWindow::FocusChangeSignalType& GlWindow::FocusChangeSignal()
+{
+  return GetImplementation(*this).FocusChangeSignal();
+}
+GlWindow::ResizedSignalType& GlWindow::ResizedSignal()
+{
+  return GetImplementation(*this).ResizedSignal();
+}
+GlWindow::KeyEventSignalType& GlWindow::KeyEventSignal()
+{
+  return GetImplementation(*this).KeyEventSignal();
+}
+GlWindow::TouchSignalType& GlWindow::TouchSignal()
+{
+  return GetImplementation(*this).TouchSignal();
+}
+GlWindow::VisibilityChangedSignalType& GlWindow::VisibilityChangedSignal()
+{
+  return GetImplementation(*this).VisibilityChangedSignal();
+}
+GlWindow::GlWindow( Internal::Adaptor::GlWindow* window )
+: BaseHandle( window )
+{
+}
+
+}// Dali
diff --git a/dali/devel-api/adaptor-framework/gl-window.h b/dali/devel-api/adaptor-framework/gl-window.h
new file mode 100644 (file)
index 0000000..e654048
--- /dev/null
@@ -0,0 +1,439 @@
+#ifndef DALI_GL_WINDOW_H
+#define DALI_GL_WINDOW_H
+
+/*
+ * Copyright (c) 2020 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 <string>
+#include <dali/public-api/math/rect.h>
+#include <dali/public-api/math/uint-16-pair.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/object/base-handle.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>
+
+namespace Dali
+{
+/**
+ * @addtogroup dali_adaptor_framework
+ * @{
+ */
+
+typedef Dali::Rect<int> PositionSize;
+
+namespace Internal DALI_INTERNAL
+{
+namespace Adaptor
+{
+class GlWindow;
+}
+}
+
+namespace
+{
+typedef void  (*GlInitialize)();
+typedef void  (*GlRenderFrame)();
+typedef void  (*GlTerminate)();
+}
+
+class TouchEvent;
+struct KeyEvent;
+
+/**
+ * @brief The GlWindow class is to draw with native GLES.
+ *
+ * This class is the special window. It is for native GLES application.
+ * So, some special funtions and type are supported.
+ * In addition, basic window's functions are supported, too.
+ *
+ */
+class DALI_ADAPTOR_API GlWindow : public BaseHandle
+{
+public:
+
+  using WindowSize = Uint16Pair ;
+
+  typedef Signal< void ( const KeyEvent& ) >        KeyEventSignalType;           ///< GlWindow Key Event signal type
+  typedef Signal< void ( const TouchEvent& ) >      TouchSignalType;              ///< GlWindow Touch Event signal type
+  typedef Signal< void ( GlWindow, bool ) >         FocusChangeSignalType;        ///< GlWindow Focus signal type
+  typedef Signal< void ( WindowSize ) >             ResizedSignalType;             ///< GlWindow resized signal type
+  typedef Signal< void ( GlWindow, bool ) >         VisibilityChangedSignalType;  ///< GlWindow visibility change signal type
+
+public:
+
+  // Enumerations
+
+  /**
+   * @brief Enumeration for orientation of the window is the way in which a rectangular page is oriented for normal viewing.
+   *
+   * This Enumeration is used the available orientation APIs and the preferred orientation.
+   *
+   */
+  enum class GlWindowOrientation
+  {
+    PORTRAIT = 0,                       ///< Portrait orientation. The height of the display area is greater than the width.
+    LANDSCAPE = 1,                      ///< Landscape orientation. A wide view area is needed.
+    PORTRAIT_INVERSE = 2,               ///< Portrait inverse orientation
+    LANDSCAPE_INVERSE = 3,              ///< Landscape inverse orientation
+    NO_ORIENTATION_PREFERENCE = -1      ///< Invalid angle value. It is used to initialize or unset the preferred orientation.
+  };
+
+    /**
+   * @brief Enumeration for GLES verion
+   *
+   * This Enumeration is used the GLES version for EGL configuration.
+   * If the device can not support GLES version 3.0 over, the version will be chosen with GLES version 2.0
+   *
+   */
+  enum class GlesVersion
+  {
+    VERSION_2_0 = 0,                    ///< GLES version 2.0
+    VERSION_3_0,                        ///< GLES version 3.0
+  };
+
+  /**
+   * @brief Creates an initialized handle to a new GlWindow.
+   *
+   * @return A new GlWindow
+   * @note This creates an extra GlWindow in addition to the default main GlWindow
+   */
+  static GlWindow New();
+
+  /**
+   * @brief Creates an initialized handle to a new GlWindow.
+   *
+   * @param[in] positionSize The position and size of the GlWindow
+   * @param[in] name The GlWindow title
+   * @param[in] className The GlWindow class name
+   * @param[in] isTransparent Whether GlWindow is transparent
+   * @note This creates an extra GlWindow in addition to the default main GlWindow
+   * @return A new GlWindow
+   */
+  static GlWindow New( PositionSize positionSize, const std::string& name, const std::string& className, bool isTransparent = false );
+
+  /**
+   * @brief Creates an uninitialized handle.
+   *
+   * This can be initialized using Dali::Application::GetGlWindow() or
+   * Dali::GlWindow::New().
+   *
+   */
+  GlWindow();
+
+  /**
+   * @brief Destructor.
+   *
+   * This is non-virtual since derived Handle types must not contain data or virtual methods.
+   *
+   */
+  ~GlWindow();
+
+  /**
+   * @brief This copy constructor is required for (smart) pointer semantics.
+   *
+   * @param[in] handle A reference to the copied handle
+   */
+  GlWindow(const GlWindow& handle);
+
+  /**
+   * @brief This assignment operator is required for (smart) pointer semantics.
+   *
+   * @param[in] rhs A reference to the copied handle
+   * @return A reference to this
+   */
+  GlWindow& operator=(const GlWindow& rhs);
+
+  /**
+   * @brief Sets egl configuration for GlWindow
+   *
+   * @param[in] depth the flag of depth buffer. If true is set, 24bit depth buffer is enabled.
+   * @param[in] stencil the flag of stencil. it true is set, 8bit stencil buffer is enabled.
+   * @param[in] msaa the bit of msaa.
+   * @param[in] version the GLES version
+   *
+   */
+  void SetEglConfig( bool depth, bool stencil, int msaa, GlesVersion version );
+
+  /**
+   * @brief Raises GlWindow to the top of GlWindow stack.
+   *
+   */
+  void Raise();
+
+  /**
+   * @brief Lowers GlWindow to the bottom of GlWindow stack.
+   *
+   */
+  void Lower();
+
+  /**
+   * @brief Activates GlWindow to the top of GlWindow stack even it is iconified.
+   *
+   */
+  void Activate();
+
+  /**
+   * @brief Shows the GlWindow if it is hidden.
+   *
+   */
+  void Show();
+
+  /**
+   * @brief Hides the GlWindow if it is showing.
+   *
+   */
+  void Hide();
+
+  /**
+   * @brief Sets a position of the GlWindow.
+   *
+   * @param[in] positionSize The new GlWindow position
+   */
+  void SetPositionSize( PositionSize positionSize );
+
+  /**
+   * @brief Gets a position of the GlWindow.
+   *
+   * @return The position of the GlWindow
+   */
+  PositionSize GetPositionSize() const;
+
+  /**
+   * @brief Gets the count of supported auxiliary hints of the window.
+   *
+   * @return The number of supported auxiliary hints.
+   *
+   * @note The window auxiliary hint is the value which is used to decide which actions should be made available to the user by the window manager.
+   * If you want to set specific hint to your window, then you should check whether it exists in the supported auxiliary hints.
+   */
+  unsigned int GetSupportedAuxiliaryHintCount() const;
+
+  /**
+   * @brief Gets the supported auxiliary hint string of the window.
+   *
+   * @param[in] index The index of the supported auxiliary hint lists
+   * @return The auxiliary hint string of the index.
+   *
+   * @note The window auxiliary hint is the value which is used to decide which actions should be made available to the user by the window manager.
+   * If you want to set specific hint to your window, then you should check whether it exists in the supported auxiliary hints.
+   */
+  std::string GetSupportedAuxiliaryHint( unsigned int index ) const;
+
+  /**
+   * @brief Creates an auxiliary hint of the window.
+   *
+   * @param[in] hint The auxiliary hint string.
+   * @param[in] value The value string.
+   * @return The ID of created auxiliary hint, or @c 0 on failure.
+   */
+  unsigned int AddAuxiliaryHint( const std::string& hint, const std::string& value );
+
+  /**
+   * @brief Removes an auxiliary hint of the window.
+   *
+   * @param[in] id The ID of the auxiliary hint.
+   * @return True if no error occurred, false otherwise.
+   */
+  bool RemoveAuxiliaryHint( unsigned int id );
+
+  /**
+   * @brief Changes a value of the auxiliary hint.
+   *
+   * @param[in] id The auxiliary hint ID.
+   * @param[in] value The value string to be set.
+   * @return True if no error occurred, false otherwise.
+   */
+  bool SetAuxiliaryHintValue( unsigned int id, const std::string& value );
+
+  /**
+   * @brief Gets a value of the auxiliary hint.
+   *
+   * @param[in] id The auxiliary hint ID.
+   * @return The string value of the auxiliary hint ID, or an empty string if none exists.
+   */
+  std::string GetAuxiliaryHintValue( unsigned int id ) const;
+
+  /**
+   * @brief Gets a ID of the auxiliary hint string.
+   *
+   * @param[in] hint The auxiliary hint string.
+   * @return The ID of the auxiliary hint string, or @c 0 if none exists.
+   */
+  unsigned int GetAuxiliaryHintId( const std::string& hint ) const;
+
+  /**
+   * @brief Sets a region to accept input events.
+   *
+   * @param[in] inputRegion The region to accept input events.
+   */
+  void SetInputRegion( const Rect< int >& inputRegion );
+
+  /**
+   * @brief Sets a transparent window's visual state to opaque.
+   * @details If a visual state of a transparent window is opaque,
+   * then the window manager could handle it as an opaque window when calculating visibility.
+   *
+   * @param[in] opaque Whether the window's visual state is opaque.
+   * @remarks This will have no effect on an opaque window.
+   * It doesn't change transparent window to opaque window but lets the window manager know the visual state of the window.
+   */
+  void SetOpaqueState( bool opaque );
+
+  /**
+   * @brief Returns whether a transparent window's visual state is opaque or not.
+   *
+   * @return True if the window's visual state is opaque, false otherwise.
+   * @remarks The return value has no meaning on an opaque window.
+   */
+  bool IsOpaqueState() const;
+
+  /**
+   * @brief Gets current rotation angle of the window.
+   *
+   * @return The current GlWindow rotation angle if previously set, or none
+   */
+   Dali::GlWindow::GlWindowOrientation GetCurrentOrientation() const;
+
+   /**
+    * @brief Sets available orientations of the window.
+    *
+    * This API is for setting several orientations one time.
+    *
+    * @param[in] orientations The available orientations list to add
+    */
+   void SetAvailableOrientations( const Dali::Vector<Dali::GlWindow::GlWindowOrientation>& orientations );
+
+  /**
+   * @brief Sets a preferred orientation.
+   *
+   * @param[in] orientation The preferred orientation
+   * @pre angle is in the list of available orientation.
+   *
+   * @note To unset the preferred orientation, angle should be set NO_ORIENTATION_PREFERENCE.
+   */
+  void SetPreferredOrientation( Dali::GlWindow::GlWindowOrientation orientation );
+
+  /**
+   * @brief Registers a GL callback function for application.
+   *
+   * @param[in] glInit  the callback function for application initialize
+   * @param[in] glRenderFrame the callback function to render to the frame.
+   * @param[in] glTerminate the callback function to clean-up application GL resource.
+   *
+   */
+  void RegisterGlCallback( GlInitialize glInit, GlRenderFrame glRenderFrame, GlTerminate glTerminate );
+
+  /**
+   * @brief Renders once more even if GL render functions are not added to idler.
+   * @note Will not work if the window is hidden or GL render functions are added to idler
+   *
+   */
+  void RenderOnce();
+
+public: // Signals
+
+  /**
+   * @brief The user should connect to this signal to get a timing when GlWindow gains focus or loses focus.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName( GlWindow GlWindow, bool focusIn );
+   * @endcode
+   * The parameter is true if GlWindow gains focus, otherwise false.
+   * and GlWindow means this signal was called from what GlWindow
+   *
+   * @return The signal to connect to
+   */
+  FocusChangeSignalType& FocusChangeSignal();
+
+  /**
+   * @brief This signal is emitted when the GlWindow is resized.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName( GlWindow GlWindow, int width, int height );
+   * @endcode
+   * The parameters are the resized width and height.
+   * and GlWindow means this signal was called from what GlWindow
+   *
+   * @return The signal to connect to
+   */
+  ResizedSignalType& ResizedSignal();
+
+  /**
+   * @brief This signal is emitted when key event is received.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName(const KeyEvent& event);
+   * @endcode
+   *
+   * @return The signal to connect to
+   */
+  KeyEventSignalType& KeyEventSignal();
+
+  /**
+   * @brief This signal is emitted when the screen is touched and when the touch ends
+   * (i.e. the down & up touch events only).
+   *
+   * If there are multiple touch points, then this will be emitted when the first touch occurs and
+   * then when the last finger is lifted.
+   * An interrupted event will also be emitted (if it occurs).
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName(const TouchEvent& event);
+   * @endcode
+   *
+   * @return The touch signal to connect to
+   *
+   * @note Motion events are not emitted.
+   */
+  TouchSignalType& TouchSignal();
+
+  /**
+   * @brief This signal is emitted when the window is shown or hidden.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   void YourCallbackName( Window window, bool visible );
+   * @endcode
+   *
+   * @return The signal to connect to
+   */
+  VisibilityChangedSignalType& VisibilityChangedSignal();
+
+public: // Not intended for application developers
+  /// @cond internal
+  /**
+   * @brief This constructor is used by Dali::Application::GetGlWindow().
+   * @param[in] GlWindow A pointer to the GlWindow
+   */
+  explicit DALI_INTERNAL GlWindow( Internal::Adaptor::GlWindow* GlWindow );
+  /// @endcond
+};
+
+/**
+ * @}
+ */
+} // namespace Dali
+
+#endif // DALI_GL_WINDOW_H
index 717cba9..e8cd60b 100755 (executable)
@@ -39,6 +39,7 @@ SET( devel_api_src_files
   ${adaptor_devel_api_dir}/adaptor-framework/window-devel.cpp
   ${adaptor_devel_api_dir}/adaptor-framework/offscreen-application.cpp
   ${adaptor_devel_api_dir}/adaptor-framework/offscreen-window.cpp
+  ${adaptor_devel_api_dir}/adaptor-framework/gl-window.cpp
 )
 
 
@@ -96,6 +97,7 @@ SET( devel_api_adaptor_framework_header_files
   ${adaptor_devel_api_dir}/adaptor-framework/video-sync-mode.h
   ${adaptor_devel_api_dir}/adaptor-framework/offscreen-application.h
   ${adaptor_devel_api_dir}/adaptor-framework/offscreen-window.h
+  ${adaptor_devel_api_dir}/adaptor-framework/gl-window.h
 )
 
 
index dcbf055..ce3c353 100644 (file)
@@ -71,6 +71,18 @@ void EglGraphics::Initialize( EnvironmentOptions* environmentOptions )
   mEglContextHelper = Utils::MakeUnique< EglContextHelperImplementation >();
 }
 
+void EglGraphics::Initialize( bool depth, bool stencil, int msaa )
+{
+  mDepthBufferRequired = static_cast< Integration::DepthBufferAvailable >( depth );
+  mStencilBufferRequired = static_cast< Integration::StencilBufferAvailable >( stencil );
+
+  mMultiSamplingLevel = msaa;
+
+  mEglSync = Utils::MakeUnique< EglSyncImplementation >();
+
+  mEglContextHelper = Utils::MakeUnique< EglContextHelperImplementation >();
+}
+
 EglInterface* EglGraphics::Create()
 {
   mEglImplementation = Utils::MakeUnique< EglImplementation >( mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired );
index 8ee45bc..7476f94 100644 (file)
@@ -57,6 +57,14 @@ public:
   void Initialize( EnvironmentOptions* environmentOptions ) override;
 
   /**
+   * Initialize the graphics interface with specific input parameters
+   * @param[in]  depth  The flag to enable depth buffer
+   * @param[in]  stencil  The flag to enable stencil buffer
+   * @param[in]  msaa  The value of multi sampleing bit
+   */
+  void Initialize( bool depth, bool stencil, int msaa );
+
+  /**
    * Creates the graphics interface for EGL
    * @return The graphics interface for EGL
    */
index 7a1d02b..25fc86f 100755 (executable)
@@ -95,7 +95,7 @@ static uint32_t GetCurrentMilliSeconds(void)
 } // unnamed namespace
 #endif
 
-EventHandler::EventHandler( WindowRenderSurface* surface, DamageObserver& damageObserver )
+EventHandler::EventHandler( WindowBase* windowBase, DamageObserver& damageObserver )
 : mStyleMonitor( StyleMonitor::Get() ),
   mDamageObserver( damageObserver ),
   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
@@ -103,22 +103,17 @@ EventHandler::EventHandler( WindowRenderSurface* surface, DamageObserver& damage
   mClipboard( Clipboard::Get() ),
   mPaused( false )
 {
-  if( surface )
-  {
-    WindowBase* windowBase = surface->GetWindowBase();
-
-    // Connect signals
-    windowBase->WindowDamagedSignal().Connect( this, &EventHandler::OnWindowDamaged );
-    windowBase->FocusChangedSignal().Connect( this, &EventHandler::OnFocusChanged );
-    windowBase->RotationSignal().Connect( this, &EventHandler::OnRotation );
-    windowBase->TouchEventSignal().Connect( this, &EventHandler::OnTouchEvent );
-    windowBase->WheelEventSignal().Connect( this, &EventHandler::OnWheelEvent );
-    windowBase->KeyEventSignal().Connect( this, &EventHandler::OnKeyEvent );
-    windowBase->SelectionDataSendSignal().Connect( this, &EventHandler::OnSelectionDataSend );
-    windowBase->SelectionDataReceivedSignal().Connect( this, &EventHandler::OnSelectionDataReceived );
-    windowBase->StyleChangedSignal().Connect( this, &EventHandler::OnStyleChanged );
-    windowBase->AccessibilitySignal().Connect( this, &EventHandler::OnAccessibilityNotification );
-  }
+  // Connect signals
+  windowBase->WindowDamagedSignal().Connect( this, &EventHandler::OnWindowDamaged );
+  windowBase->FocusChangedSignal().Connect( this, &EventHandler::OnFocusChanged );
+  windowBase->RotationSignal().Connect( this, &EventHandler::OnRotation );
+  windowBase->TouchEventSignal().Connect( this, &EventHandler::OnTouchEvent );
+  windowBase->WheelEventSignal().Connect( this, &EventHandler::OnWheelEvent );
+  windowBase->KeyEventSignal().Connect( this, &EventHandler::OnKeyEvent );
+  windowBase->SelectionDataSendSignal().Connect( this, &EventHandler::OnSelectionDataSend );
+  windowBase->SelectionDataReceivedSignal().Connect( this, &EventHandler::OnSelectionDataReceived );
+  windowBase->StyleChangedSignal().Connect( this, &EventHandler::OnStyleChanged );
+  windowBase->AccessibilitySignal().Connect( this, &EventHandler::OnAccessibilityNotification );
 }
 
 EventHandler::~EventHandler()
index 71f4ca5..ba23ce3 100644 (file)
@@ -111,10 +111,10 @@ public:
 
   /**
    * Constructor.
-   * @param[in]  surface                  The render surface of the window.
+   * @param[in]  windowBase               The window base to be handled
    * @param[in]  damageObserver           The damage observer (to pass damage events to).
    */
-  EventHandler( WindowRenderSurface* surface, DamageObserver& damageObserver );
+  EventHandler( WindowBase* windowBase, DamageObserver& damageObserver );
 
   /**
    * Destructor.
diff --git a/dali/internal/window-system/common/gl-window-impl.cpp b/dali/internal/window-system/common/gl-window-impl.cpp
new file mode 100644 (file)
index 0000000..648feeb
--- /dev/null
@@ -0,0 +1,878 @@
+/*
+ * Copyright (c) 2020 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/window-system/common/gl-window-impl.h>
+
+// EXTERNAL HEADERS
+#include <thread>
+#include <dali/integration-api/core.h>
+#include <dali/devel-api/adaptor-framework/orientation.h>
+#include <dali/devel-api/adaptor-framework/gl-window.h>
+#include <dali/integration-api/events/touch-integ.h>
+#include <dali/integration-api/events/key-event-integ.h>
+#include <dali/devel-api/events/key-event-devel.h>
+
+// INTERNAL HEADERS
+//#include <dali/internal/graphics/gles/egl-graphics.h>
+#include <dali/internal/window-system/common/event-handler.h>
+#include <dali/internal/window-system/common/orientation-impl.h>
+#include <dali/internal/window-system/common/window-factory.h>
+#include <dali/internal/window-system/common/window-base.h>
+#include <dali/internal/window-system/common/window-system.h>
+#include <dali/internal/window-system/common/window-impl.h>
+#include <dali/internal/window-system/common/window-render-surface.h>
+#include <dali/internal/window-system/common/window-visibility-observer.h>
+#include <dali/internal/graphics/gles/egl-graphics-factory.h>
+#include <dali/internal/window-system/common/display-utils.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+
+namespace
+{
+const int MINIMUM_DIMENSION_CHANGE( 1 );
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
+#endif
+
+} // unnamed namespace
+
+GlWindow* GlWindow::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
+{
+  GlWindow* window = new GlWindow();
+  window->mIsTransparent = isTransparent;
+  window->Initialize( positionSize, name, className );
+  return window;
+}
+
+GlWindow::GlWindow()
+: mWindowBase(),
+  mGraphics(),
+  mDisplayConnection( nullptr ),
+  mEventHandler( nullptr ),
+  mPositionSize(),
+  mColorDepth( COLOR_DEPTH_24 ),
+  mIsTransparent( false ),
+  mIsFocusAcceptable( false ),
+  mIconified( false ),
+  mOpaqueState( false ),
+  mResizedEnabled( false ),
+  mVisible( false ),
+  mIsRotated( false ),
+  mIsWindowRotated( false ),
+  mIsTouched( false ),
+  mAvailableAngles(),
+  mPreferredAngle( 0 ),
+  mTotalRotationAngle( 0 ),
+  mWindowRotationAngle( 0 ),
+  mScreenRotationAngle( 0 ),
+  mOrientationMode( 0 ),
+  mWindowWidth( 0 ),
+  mWindowHeight( 0 ),
+  mNativeWindowId( -1 ),
+  mKeyEventSignal(),
+  mTouchSignal(),
+  mFocusChangeSignal(),
+  mResizedSignal(),
+  mVisibilityChangedSignal(),
+  mGLInitCallback( 0 ),
+  mGLRenderFrameCallback( 0 ),
+  mGLTerminateCallback( 0 ),
+  mGLRenderCallback( nullptr ),
+  mEGLSurface( nullptr ),
+  mEGLContext( nullptr ),
+  mGLESVersion( Dali::GlWindow::GlesVersion::VERSION_3_0 ),
+  mInitCallback( false ),
+  mDepth( false ),
+  mStencil( false ),
+  mIsEGLInitialize( false ),
+  mMSAA( 0 )
+{
+}
+
+GlWindow::~GlWindow()
+{
+  if ( mEventHandler )
+  {
+    mEventHandler->RemoveObserver( *this );
+  }
+
+  if( mGLTerminateCallback )
+  {
+    mGLTerminateCallback();
+  }
+
+  if( mIsEGLInitialize )
+  {
+    GraphicsInterface* graphics = mGraphics.get();
+    EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
+    Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+
+    if( mEGLSurface )
+    {
+      eglImpl.DestroySurface( mEGLSurface );
+      mEGLSurface = nullptr;
+    }
+
+    if( mEGLContext )
+    {
+      eglImpl.DestroyContext( mEGLContext );
+      mEGLContext = nullptr;
+    }
+
+    eglImpl.TerminateGles();
+
+    mGraphics->Destroy();
+  }
+
+  delete mDisplayConnection;
+}
+
+void GlWindow::Initialize( const PositionSize& positionSize, const std::string& name, const std::string& className )
+{
+  int screenWidth, screenHeight;
+
+  mPositionSize = positionSize;
+  WindowSystem::GetScreenSize( screenWidth, screenHeight );
+  if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
+  {
+    mPositionSize.x = 0;
+    mPositionSize.y = 0;
+    mPositionSize.width = screenWidth;
+    mPositionSize.height = screenHeight;
+  }
+
+  if( screenWidth > screenHeight )
+  {
+    mOrientationMode = 1; // Default mode is landscape
+  }
+  else
+  {
+    mOrientationMode = 0; // Default mode is portrate
+  }
+
+  // Create a window base
+  auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
+  Any surface;
+  mWindowBase = windowFactory->CreateWindowBase( mPositionSize, surface, ( mIsTransparent ? true : false ) );
+  mWindowBase->IconifyChangedSignal().Connect( this, &GlWindow::OnIconifyChanged );
+  mWindowBase->FocusChangedSignal().Connect( this, &GlWindow::OnFocusChanged );
+
+  SetEventHandler();
+
+  if( !mPositionSize.IsEmpty() )
+  {
+    AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
+    mResizedEnabled = true;
+  }
+
+  mWindowBase->Show();
+
+  if( mIsTransparent )
+  {
+    mColorDepth = COLOR_DEPTH_32;
+  }
+  else
+  {
+    mColorDepth = COLOR_DEPTH_24;
+  }
+
+  SetClass( name, className );
+
+  // For Debugging
+  mNativeWindowId = mWindowBase->GetNativeWindowId();
+}
+
+void GlWindow::SetEventHandler()
+{
+  mEventHandler = EventHandlerPtr( new EventHandler( mWindowBase.get(), *this ) );
+  mEventHandler->AddObserver( *this );
+}
+
+void GlWindow::SetClass( const std::string name, const std::string className )
+{
+  mName = name;
+  mClassName = className;
+  mWindowBase->SetClass( name, className );
+}
+
+void GlWindow::SetEglConfig( bool depth, bool stencil, int msaa, Dali::GlWindow::GlesVersion version )
+{
+  // Init Graphics
+  mDepth = depth;
+  mStencil = stencil;
+  mMSAA = msaa;
+  mGLESVersion = version;
+
+  InitializeGraphics();
+}
+
+void GlWindow::Raise()
+{
+  mWindowBase->Raise();
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Raise() \n", this, mNativeWindowId );
+}
+
+void GlWindow::Lower()
+{
+  mWindowBase->Lower();
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Lower() \n", this, mNativeWindowId );
+}
+
+void GlWindow::Activate()
+{
+  mWindowBase->Activate();
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Activate() \n", this, mNativeWindowId );
+}
+
+void GlWindow::Show()
+{
+  mVisible = true;
+
+  mWindowBase->Show();
+
+  if( !mIconified )
+  {
+    Dali::GlWindow handle( this );
+    mVisibilityChangedSignal.Emit( handle, true );
+  }
+
+  if( mEventHandler )
+  {
+    mEventHandler->Resume();
+  }
+
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Show(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible );
+}
+
+void GlWindow::Hide()
+{
+  mVisible = false;
+
+  mWindowBase->Hide();
+
+  if( !mIconified )
+  {
+    Dali::GlWindow handle( this );
+    mVisibilityChangedSignal.Emit( handle, false );
+  }
+
+  if( mEventHandler )
+  {
+    mEventHandler->Pause();
+  }
+
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Hide(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible );
+}
+
+unsigned int GlWindow::GetSupportedAuxiliaryHintCount() const
+{
+  return mWindowBase->GetSupportedAuxiliaryHintCount();
+}
+
+std::string GlWindow::GetSupportedAuxiliaryHint( unsigned int index ) const
+{
+  return mWindowBase->GetSupportedAuxiliaryHint( index );
+}
+
+unsigned int GlWindow::AddAuxiliaryHint( const std::string& hint, const std::string& value )
+{
+  return mWindowBase->AddAuxiliaryHint( hint, value );
+}
+
+bool GlWindow::RemoveAuxiliaryHint( unsigned int id )
+{
+  return mWindowBase->RemoveAuxiliaryHint( id );
+}
+
+bool GlWindow::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
+{
+  return mWindowBase->SetAuxiliaryHintValue( id, value );
+}
+
+std::string GlWindow::GetAuxiliaryHintValue( unsigned int id ) const
+{
+  return mWindowBase->GetAuxiliaryHintValue( id );
+}
+
+unsigned int GlWindow::GetAuxiliaryHintId( const std::string& hint ) const
+{
+  return mWindowBase->GetAuxiliaryHintId( hint );
+}
+
+void GlWindow::SetInputRegion( const Rect< int >& inputRegion )
+{
+  mWindowBase->SetInputRegion( inputRegion );
+
+  DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "GlWindow::SetInputRegion: x = %d, y = %d, w = %d, h = %d\n", inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height );
+}
+
+void GlWindow::SetOpaqueState( bool opaque )
+{
+  mOpaqueState = opaque;
+
+  mWindowBase->SetOpaqueState( opaque );
+
+  DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "GlWindow::SetOpaqueState: opaque = %d\n", opaque );
+}
+
+bool GlWindow::IsOpaqueState() const
+{
+  return mOpaqueState;
+}
+
+void GlWindow::SetPositionSize( PositionSize positionSize )
+{
+  if( !mResizedEnabled )
+  {
+    AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
+    mResizedEnabled = true;
+  }
+
+  bool needToMove = false;
+  bool needToResize = false;
+
+  // Check moving
+  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) )
+  {
+    needToResize = true;
+  }
+
+  if( needToResize )
+  {
+    if( needToMove )
+    {
+      mWindowBase->MoveResize( positionSize );
+    }
+    else
+    {
+      mWindowBase->Resize( positionSize );
+    }
+    mPositionSize = positionSize;
+  }
+  else
+  {
+    if( needToMove )
+    {
+      mWindowBase->Move( positionSize );
+      mPositionSize = positionSize;
+    }
+  }
+
+  // If window's size or position is changed, the signal will be emitted to user.
+  if( ( needToMove ) || ( needToResize ) )
+  {
+    Uint16Pair newSize( mPositionSize.width, mPositionSize.height );
+    mResizedSignal.Emit( newSize );
+  }
+}
+
+PositionSize GlWindow::GetPositionSize() const
+{
+  PositionSize positionSize( mPositionSize );
+  if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
+  {
+    positionSize.height = mPositionSize.width;
+    positionSize.width = mPositionSize.height;
+  }
+
+  return positionSize;
+}
+
+void GlWindow::OnIconifyChanged( bool iconified )
+{
+  if( iconified )
+  {
+    mIconified = true;
+
+    if( mVisible )
+    {
+      Dali::GlWindow handle( this );
+      mVisibilityChangedSignal.Emit( handle, false );
+    }
+
+    if( mEventHandler )
+    {
+      mEventHandler->Pause();
+    }
+
+    DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Iconified: visible = %d\n", this, mNativeWindowId, mVisible );
+  }
+  else
+  {
+    mIconified = false;
+
+    if( mVisible )
+    {
+      Dali::GlWindow handle( this );
+      mVisibilityChangedSignal.Emit( handle, true );
+    }
+
+    if( mEventHandler )
+    {
+      mEventHandler->Resume();
+    }
+
+    DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible );
+  }
+}
+
+void GlWindow::OnFocusChanged( bool focusIn )
+{
+  Dali::GlWindow handle( this );
+  mFocusChangeSignal.Emit( handle, 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;
+    }
+
+    // Emit Resized signal
+    mResizedSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
+  }
+}
+
+void GlWindow::OnTouchPoint( Dali::Integration::Point& point, int timeStamp )
+{
+  PointState::Type state = point.GetState();
+
+  if( state == PointState::DOWN )
+  {
+    mIsTouched = true;
+  }
+
+  if( state == PointState::UP )
+  {
+    mIsTouched = false;
+  }
+
+  if( !mIsTouched && state == PointState::MOTION )
+  {
+    return;
+  }
+
+  RecalculateTouchPosition( point );
+  Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent( timeStamp, point );
+  mTouchSignal.Emit( touchEvent );
+}
+
+void GlWindow::OnWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
+{
+  // TODO:
+  //FeedWheelEvent( wheelEvent );
+}
+
+void GlWindow::OnKeyEvent( Dali::Integration::KeyEvent& keyEvent )
+{
+  Dali::KeyEvent event = Dali::DevelKeyEvent::New( keyEvent.keyName, keyEvent.logicalKey, keyEvent.keyString, keyEvent.keyCode,
+                                                   keyEvent.keyModifier, keyEvent.time, static_cast<Dali::KeyEvent::State>(keyEvent.state),
+                                                   keyEvent.compose, keyEvent.deviceName, keyEvent.deviceClass, keyEvent.deviceSubclass );
+  mKeyEventSignal.Emit( event );
+}
+
+void GlWindow::OnRotation( const RotationEvent& rotation )
+{
+  mWindowRotationAngle = rotation.angle;
+  mTotalRotationAngle = ( mWindowRotationAngle + mScreenRotationAngle ) % 360;
+  if( mTotalRotationAngle == 90 || mTotalRotationAngle == 270 )
+  {
+    mWindowWidth = mPositionSize.height;
+    mWindowHeight = mPositionSize.width;
+  }
+  else
+  {
+    mWindowWidth = mPositionSize.width;
+    mWindowHeight = mPositionSize.height;
+  }
+
+  mIsRotated = true;
+  mIsWindowRotated = true;
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), OnRotation(): resized signal emit [%d x %d]\n", this, mNativeWindowId, mWindowWidth, mWindowHeight );
+
+  // Emit Resized signal
+  mResizedSignal.Emit( Dali::Uint16Pair( mWindowWidth, mWindowHeight ) );
+}
+
+void GlWindow::RecalculateTouchPosition( Integration::Point& point )
+{
+  Vector2 position = point.GetScreenPosition();
+  Vector2 convertedPosition;
+
+  switch( mTotalRotationAngle )
+  {
+    case 90:
+    {
+      convertedPosition.x = static_cast<float>( mWindowWidth ) - position.y;
+      convertedPosition.y = position.x;
+      break;
+    }
+    case 180:
+    {
+      convertedPosition.x = static_cast<float>( mWindowWidth ) - position.x;
+      convertedPosition.y = static_cast<float>( mWindowHeight ) - position.y;
+      break;
+    }
+    case 270:
+    {
+      convertedPosition.x = position.y;
+      convertedPosition.y = static_cast<float>( mWindowHeight ) - position.x;
+      break;
+    }
+    default:
+    {
+      convertedPosition = position;
+      break;
+    }
+  }
+
+  point.SetScreenPosition( convertedPosition );
+}
+
+void GlWindow::SetAvailableAnlges( const std::vector< int >& angles )
+{
+  if( angles.size() > 4 )
+  {
+    DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableAnlges: Invalid vector size! [%d]\n", angles.size() );
+    return;
+  }
+
+  mWindowBase->SetAvailableAnlges( angles );
+}
+
+bool GlWindow::IsOrientationAvailable( Dali::GlWindow::GlWindowOrientation orientation ) const
+{
+  if( orientation <= Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE
+      || orientation > Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE )
+  {
+    DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::IsOrientationAvailable: Invalid input orientation [%d]\n", orientation );
+    return false;
+  }
+  return true;
+}
+
+int GlWindow::ConvertToAngle(  Dali::GlWindow::GlWindowOrientation  orientation )
+{
+  int convertAngle = 0;
+  if ( mOrientationMode == 0 )
+  {
+    convertAngle = ( static_cast< int >( orientation ) ) * 90;
+  }
+  else if( mOrientationMode == 1)
+  {
+    switch( orientation )
+    {
+      case Dali::GlWindow::GlWindowOrientation::LANDSCAPE:
+      {
+        convertAngle = 0;
+        break;
+      }
+      case Dali::GlWindow::GlWindowOrientation::PORTRAIT:
+      {
+        convertAngle = 90;
+        break;
+      }
+      case Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE:
+      {
+        convertAngle = 180;
+        break;
+      }
+      case Dali::GlWindow::GlWindowOrientation::PORTRAIT_INVERSE:
+      {
+        convertAngle = 270;
+        break;
+      }
+      case Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE:
+      {
+        convertAngle = -1;
+        break;
+      }
+    }
+  }
+  return convertAngle;
+}
+
+Dali::GlWindow::GlWindowOrientation GlWindow::ConvertToOrientation( int angle ) const
+{
+  Dali::GlWindow::GlWindowOrientation orientation = Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE;
+  if ( mOrientationMode == 0 ) // Portrate mode
+  {
+    orientation = static_cast< Dali::GlWindow::GlWindowOrientation >( angle / 90 );
+  }
+  else if( mOrientationMode == 1 ) // Landscape mode
+  {
+    switch( angle )
+    {
+      case 0:
+      {
+        orientation = Dali::GlWindow::GlWindowOrientation::LANDSCAPE;
+        break;
+      }
+      case 90:
+      {
+        orientation = Dali::GlWindow::GlWindowOrientation::PORTRAIT;
+        break;
+      }
+      case 180:
+      {
+        orientation = Dali::GlWindow::GlWindowOrientation::LANDSCAPE_INVERSE;
+        break;
+      }
+      case 270:
+      {
+        orientation = Dali::GlWindow::GlWindowOrientation::PORTRAIT_INVERSE;
+        break;
+      }
+      case -1:
+      {
+        orientation = Dali::GlWindow::GlWindowOrientation::NO_ORIENTATION_PREFERENCE;
+        break;
+      }
+    }
+  }
+  return orientation;
+}
+
+Dali::GlWindow::GlWindowOrientation GlWindow::GetCurrentOrientation() const
+{
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), GetCurrentOrientation(): %d\n", this, mNativeWindowId, mTotalRotationAngle );
+  return ConvertToOrientation( mTotalRotationAngle );
+}
+
+void GlWindow::SetAvailableOrientations( const Dali::Vector< Dali::GlWindow::GlWindowOrientation >& orientations )
+{
+  Dali::Vector<float>::SizeType count = orientations.Count();
+  for( Dali::Vector<float>::SizeType index = 0; index < count; ++index )
+  {
+    if( IsOrientationAvailable( orientations[index] ) == false )
+    {
+      DALI_LOG_ERROR("Window::SetAvailableRotationAngles, invalid angle: %d\n", orientations[index]);
+      continue;
+    }
+
+    bool found = false;
+    int angle = ConvertToAngle( orientations[index] );
+
+    for( std::size_t i = 0; i < mAvailableAngles.size(); i++ )
+    {
+      if( mAvailableAngles[i] == angle )
+      {
+        found = true;
+        break;
+      }
+    }
+
+    if( !found )
+    {
+      DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, angle );
+      mAvailableAngles.push_back( angle );
+    }
+  }
+  SetAvailableAnlges( mAvailableAngles );
+}
+
+void GlWindow::SetPreferredOrientation( Dali::GlWindow::GlWindowOrientation orientation  )
+{
+  if( IsOrientationAvailable( orientation ) == false )
+  {
+    DALI_LOG_ERROR( "Window::SetPreferredOrientation, invalid orientation: %d\n", orientation );
+    return;
+  }
+  mPreferredAngle = ConvertToAngle( orientation );
+  DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), SetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle );
+  mWindowBase->SetPreferredAngle( mPreferredAngle );
+}
+
+void GlWindow::SetChild( Dali::Window& child )
+{
+  if( DALI_UNLIKELY( child ) )
+  {
+    mChildWindow = child;
+    Internal::Adaptor::Window& windowImpl = Dali::GetImplementation( mChildWindow );
+    WindowRenderSurface* renderSurface = static_cast<WindowRenderSurface*>( windowImpl.GetSurface() );
+    WindowBase* childWindowBase = renderSurface->GetWindowBase();
+    childWindowBase->SetParent( mWindowBase.get() );
+  }
+}
+
+void GlWindow::RegisterGlCallback( GlInitialize glInit, GlRenderFrame glRenderFrame, GlTerminate glTerminate )
+{
+  if( mIsEGLInitialize == false )
+  {
+    InitializeGraphics();
+  }
+  mGLInitCallback = glInit;
+  mGLRenderFrameCallback = glRenderFrame;
+  mGLTerminateCallback = glTerminate;
+
+  mInitCallback = false;
+
+  if( !mGLRenderCallback )
+  {
+    mGLRenderCallback = MakeCallback( this, &GlWindow::RunCallback );
+
+    Dali::Adaptor::Get().AddIdle( mGLRenderCallback, true );
+  }
+}
+
+bool GlWindow::RunCallback()
+{
+  GraphicsInterface* graphics = mGraphics.get();
+  EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
+  Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+
+  eglImpl.MakeContextCurrent( mEGLSurface, mEGLContext );
+
+  if( mIsRotated )
+  {
+    mWindowBase->SetEglWindowBufferTransform( mTotalRotationAngle );
+    if( mIsWindowRotated )
+    {
+      mWindowBase->SetEglWindowTransform( mWindowRotationAngle );
+    }
+    mIsRotated = false;
+  }
+
+  if( !mInitCallback )
+  {
+    if( mGLInitCallback )
+    {
+      mGLInitCallback();
+    }
+    mInitCallback = true;
+  }
+
+  if( mGLRenderFrameCallback )
+  {
+    mGLRenderFrameCallback();
+  }
+
+  if( mIsWindowRotated )
+  {
+    mWindowBase->WindowRotationCompleted( mWindowRotationAngle, mPositionSize.width, mPositionSize.height );
+    mIsWindowRotated = false;
+  }
+
+  eglImpl.SwapBuffers( mEGLSurface );
+
+  return true;
+}
+
+void GlWindow::RenderOnce()
+{
+  RunCallback();
+}
+
+int32_t GlWindow::GetNativeId() const
+{
+  return mWindowBase->GetNativeWindowId();
+}
+
+void GlWindow::InitializeGraphics()
+{
+  if( !mIsEGLInitialize )
+  {
+    // Init Graphics
+    std::unique_ptr< GraphicsFactory > graphicsFactoryPtr = Utils::MakeUnique< GraphicsFactory >();
+    auto graphicsFactory = *graphicsFactoryPtr.get();
+
+    mGraphics = std::unique_ptr< GraphicsInterface >( &graphicsFactory.Create() );
+    GraphicsInterface* graphics = mGraphics.get();
+    EglGraphics *eglGraphics = static_cast<EglGraphics*>( graphics );
+    eglGraphics->Initialize( mDepth, mStencil, mMSAA );
+    eglGraphics->Create();
+
+    mDisplayConnection = Dali::DisplayConnection::New( *graphics, Dali::RenderSurfaceInterface::Type::WINDOW_RENDER_SURFACE );
+    mDisplayConnection->Initialize();
+
+    Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
+    if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_2_0 )
+    {
+      eglImpl.SetGlesVersion( 20 );
+    }
+    else if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
+    {
+      eglImpl.SetGlesVersion( 30 );
+    }
+
+    if( eglImpl.ChooseConfig(true, mColorDepth) == false )
+    {
+      if( mGLESVersion == Dali::GlWindow::GlesVersion::VERSION_3_0 )
+      {
+        DALI_LOG_RELEASE_INFO( "InitializeGraphics: Fail to choose config with GLES30, retry with GLES20\n" );
+        eglImpl.SetGlesVersion( 20 );
+        mGLESVersion = Dali::GlWindow::GlesVersion::VERSION_2_0;
+        if( eglImpl.ChooseConfig(true, mColorDepth) == false )
+        {
+          DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
+          return;
+        }
+      }
+      else
+      {
+        DALI_LOG_ERROR("InitializeGraphics: Fail to choose config with GLES20");
+        return;
+      }
+    }
+    eglImpl.CreateWindowContext( mEGLContext );
+
+   // Create the EGL window
+    EGLNativeWindowType window = mWindowBase->CreateEglWindow( mPositionSize.width, mPositionSize.height );
+    mEGLSurface = eglImpl.CreateSurfaceWindow( window, mColorDepth );
+
+    mIsEGLInitialize = true;
+  }
+}
+
+void GlWindow::OnDamaged(  const DamageArea& area )
+{
+
+}
+
+} // Adaptor
+
+} // Internal
+
+} // Dali
diff --git a/dali/internal/window-system/common/gl-window-impl.h b/dali/internal/window-system/common/gl-window-impl.h
new file mode 100644 (file)
index 0000000..4dbe7f8
--- /dev/null
@@ -0,0 +1,418 @@
+#ifndef DALI_INTERNAL_WINDOWSYSTEM_COMMON_GL_WINDOW_IMPL_H
+#define DALI_INTERNAL_WINDOWSYSTEM_COMMON_GL_WINDOW_IMPL_H
+
+/*
+ * Copyright (c) 2020 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/ref-object.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/adaptor-framework/window.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/egl-graphics.h>
+#include <dali/public-api/adaptor-framework/key-grab.h>
+#include <dali/devel-api/adaptor-framework/gl-window.h>
+#include <dali/internal/adaptor/common/adaptor-impl.h>
+#include <dali/internal/window-system/common/event-handler.h>
+
+namespace Dali
+{
+class Adaptor;
+
+namespace Internal
+{
+namespace Adaptor
+{
+class WindowBase;
+
+class GlWindow;
+using GlWindowPtr = IntrusivePtr< GlWindow >;
+using EventHandlerPtr = IntrusivePtr< EventHandler >;
+
+/**
+ * Window provides a surface to render onto with orientation.
+ */
+class GlWindow : public BaseObject, public EventHandler::Observer, public DamageObserver, public ConnectionTracker
+{
+public:
+
+  using KeyEventSignalType = Dali::GlWindow::KeyEventSignalType;
+  using TouchSignalType = Dali::GlWindow::TouchSignalType;
+  using FocusChangeSignalType = Dali::GlWindow::FocusChangeSignalType;
+  using ResizedSignalType = Dali::GlWindow::ResizedSignalType;
+  using VisibilityChangedSignalType = Dali::GlWindow::VisibilityChangedSignalType;
+  using SignalType = Signal< void () >;
+
+  /**
+   * @brief Create a new GlWindow. This should only be called once by the Application class
+   * @param[in] surface The surface used to render on.
+   * @param[in] positionSize The position and size of the window
+   * @param[in] name The window title
+   * @param[in] className The window class name
+   * @param[in] isTransparent Whether window is transparent
+   * @return A newly allocated Window
+   */
+  static GlWindow* New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent = false );
+
+  /**
+   * @copydoc Dali::GlWindow::SetEglConfig()
+   */
+  void SetEglConfig( bool depth, bool stencil, int msaa, Dali::GlWindow::GlesVersion version );
+
+  /**
+   * @copydoc Dali::GlWindow::Raise()
+   */
+  void Raise();
+
+  /**
+   * @copydoc Dali::GlWindow::Lower()
+   */
+  void Lower();
+
+  /**
+   * @copydoc Dali::GlWindow::Activate()
+   */
+  void Activate();
+
+  /**
+   * @copydoc Dali::GlWindow::Show()
+   */
+  void Show();
+
+  /**
+   * @copydoc Dali::GlWindow::Hide()
+   */
+  void Hide();
+
+  /**
+   * @copydoc Dali::GlWindow::GetSupportedAuxiliaryHintCount()
+   */
+  unsigned int GetSupportedAuxiliaryHintCount() const;
+
+  /**
+   * @copydoc Dali::GlWindow::GetSupportedAuxiliaryHint()
+   */
+  std::string GetSupportedAuxiliaryHint( unsigned int index ) const;
+
+  /**
+   * @copydoc Dali::GlWindow::AddAuxiliaryHint()
+   */
+  unsigned int AddAuxiliaryHint( const std::string& hint, const std::string& value );
+
+  /**
+   * @copydoc Dali::GlWindow::RemoveAuxiliaryHint()
+   */
+  bool RemoveAuxiliaryHint( unsigned int id );
+
+  /**
+   * @copydoc Dali::GlWindow::SetAuxiliaryHintValue()
+   */
+  bool SetAuxiliaryHintValue( unsigned int id, const std::string& value );
+
+  /**
+   * @copydoc Dali::GlWindow::GetAuxiliaryHintValue()
+   */
+  std::string GetAuxiliaryHintValue( unsigned int id ) const;
+
+  /**
+   * @copydoc Dali::GlWindow::GetAuxiliaryHintId()
+   */
+  unsigned int GetAuxiliaryHintId( const std::string& hint ) const;
+
+  /**
+   * @copydoc Dali::GlWindow::SetInputRegion()
+   */
+  void SetInputRegion( const Rect< int >& inputRegion );
+
+  /**
+   * @copydoc Dali::GlWindow::SetOpaqueState()
+   */
+  void SetOpaqueState( bool opaque );
+
+  /**
+   * @copydoc Dali::GlWindow::IsOpaqueState()
+   */
+  bool IsOpaqueState() const;
+
+  /**
+   * @copydoc Dali::GlWindow::SetPositionSize()
+   */
+  void SetPositionSize( PositionSize positionSize );
+
+  /**
+   * @copydoc Dali::GlWindow::GetPositionSize()
+   */
+  PositionSize GetPositionSize() const;
+
+  /**
+   * @copydoc Dali::GlWindow::GetCurrentOrientation() const
+   */
+  Dali::GlWindow::GlWindowOrientation GetCurrentOrientation() const;
+
+  /**
+   * @copydoc Dali::GlWindow::SetAvailableOrientations()
+   */
+  void SetAvailableOrientations( const Dali::Vector< Dali::GlWindow::GlWindowOrientation >& orientations );
+
+  /**
+   * @copydoc Dali::GlWindow::SetPreferredOrientation()
+   */
+  void SetPreferredOrientation( Dali::GlWindow::GlWindowOrientation orientation );
+
+  /**
+   * @copydoc Dali::GlWindow::RegisterGlCallback()
+   */
+  void RegisterGlCallback( GlInitialize glInit, GlRenderFrame glRenderFrame, GlTerminate glTerminate );
+
+  /**
+   * @copydoc Dali::GlWindow::RenderOnce()
+   */
+  void RenderOnce();
+
+public: // For implementation
+  /**
+   * @brief Sets child window with Dali::Window
+   *
+   * Currently the child window is default window.
+   */
+  void SetChild( Dali::Window& child );
+
+private:
+
+  /**
+   * Private constructor.
+   * @sa Window::New()
+   */
+  GlWindow();
+
+  /**
+   * Destructor
+   */
+  virtual ~GlWindow();
+
+  /**
+   * Second stage initialization
+   */
+  void Initialize( const PositionSize& positionSize, const std::string& name, const std::string& className );
+
+  /**
+   * Called when the window becomes iconified or deiconified.
+   */
+  void OnIconifyChanged( bool iconified );
+
+  /**
+   * Called when the window focus is changed.
+   */
+  void OnFocusChanged( bool focusIn );
+
+  /**
+   * Called when the output is transformed.
+   */
+  void OnOutputTransformed();
+
+  /**
+   * Called when the window receives a delete request.
+   */
+  void OnDeleteRequest();
+
+  /**
+   * @brief Set available rotation angle to window base.
+   */
+  void SetAvailableAnlges( const std::vector< int >& angles );
+
+  /**
+   * @brief Check available window rotation angle for Available angle.
+   */
+  bool IsOrientationAvailable( Dali::GlWindow::GlWindowOrientation orientation ) const;
+
+  /**
+   * @brief Convert from window orientation to angle using orientation mode value.
+   */
+  int ConvertToAngle( Dali::GlWindow::GlWindowOrientation orientation );
+
+  /**
+   * @brief Convert from angle to window orientation using orientation mode value.
+   */
+  Dali::GlWindow::GlWindowOrientation ConvertToOrientation( int angle ) const;
+
+  /**
+   * @brief Run Ui GL callback function.
+   */
+  bool RunCallback();
+
+  /**
+   * @brief Initialize and create EGL resource
+   */
+  void InitializeGraphics();
+
+  /**
+   * @brief Sets event handler for window's events.
+   */
+  void SetEventHandler() ;
+
+  /**
+   * @brief Gets the native window handle
+   */
+  Dali::Any GetNativeHandle() const;
+
+  /**
+   * @brief Gets the native window handle ID
+   */
+  int32_t GetNativeId() const;
+
+  /**
+   * @brief calculate touch position for rotation.
+   */
+  void RecalculateTouchPosition( Integration::Point& point ) ;
+
+  /**
+   * @brief Sets window and class name.
+   */
+  void SetClass( const std::string name, const std::string className );
+
+private:
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::EventHandler::Observer::OnTouchPoint
+   */
+  void OnTouchPoint( Dali::Integration::Point& point, int timeStamp ) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::EventHandler::Observer::OnWheelEvent
+   */
+  void OnWheelEvent( Dali::Integration::WheelEvent& wheelEvent ) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::EventHandler::Observer::OnKeyEvent
+   */
+  void OnKeyEvent( Dali::Integration::KeyEvent& keyEvent ) override;
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::EventHandler::Observer::OnRotation
+   */
+  void OnRotation( const RotationEvent& rotation ) override;
+
+private: // From Dali::Internal::Adaptor::DamageObserver
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::DamageObserver::OnDamaged()
+   */
+  void OnDamaged( const DamageArea& area );
+
+public: // Signals
+
+  /**
+   * @copydoc Dali::GlWindow::FocusChangeSignal()
+   */
+  FocusChangeSignalType& FocusChangeSignal() { return mFocusChangeSignal; }
+
+  /**
+   * @copydoc Dali::GlWindow::ResizedSignal()
+   */
+  ResizedSignalType& ResizedSignal() { return mResizedSignal; }
+
+  /**
+   * @copydoc Dali::GlWindow::KeyEventSignal()
+   */
+  KeyEventSignalType& KeyEventSignal() { return mKeyEventSignal; }
+
+  /**
+   * @copydoc Dali::GlWindow::TouchSignal()
+   */
+  TouchSignalType& TouchSignal() { return mTouchSignal; }
+
+  /**
+   * @copydoc Dali::GlWindow::VisibilityChangedSignal()
+   */
+  VisibilityChangedSignalType& VisibilityChangedSignal() { return mVisibilityChangedSignal; }
+
+private:
+
+  std::unique_ptr< WindowBase >         mWindowBase;
+  std::unique_ptr< GraphicsInterface >  mGraphics;                    ///< Graphics interface
+  Dali::DisplayConnection*              mDisplayConnection;
+  std::string                           mName;
+  std::string                           mClassName;
+  EventHandlerPtr                       mEventHandler;         ///< The window events handler
+  PositionSize                          mPositionSize;
+  ColorDepth                            mColorDepth;
+  Dali::Window                          mChildWindow;
+  bool                                  mIsTransparent:1;
+  bool                                  mIsFocusAcceptable:1;
+  bool                                  mIconified:1;
+  bool                                  mOpaqueState:1;
+  bool                                  mResizedEnabled:1;
+  bool                                  mVisible:1;
+  bool                                  mIsRotated:1;
+  bool                                  mIsWindowRotated:1;
+  bool                                  mIsTouched:1;
+
+  std::vector< int >                    mAvailableAngles;
+  int                                   mPreferredAngle;
+  int                                   mTotalRotationAngle;   ///< The angle of window + screen rotation angle % 360
+  int                                   mWindowRotationAngle;  ///< The angle of window rotation angle
+  int                                   mScreenRotationAngle;  ///< The angle of screen rotation angle
+  int                                   mOrientationMode;      ///< 0: Default portrati, 1:Default landscape
+  int                                   mWindowWidth;          ///< The width of the window
+  int                                   mWindowHeight;         ///< The height of the window
+  int                                   mNativeWindowId;       ///< The Native Window Id
+
+  // Signals
+  KeyEventSignalType                    mKeyEventSignal;
+  TouchSignalType                       mTouchSignal;
+  FocusChangeSignalType                 mFocusChangeSignal;
+  ResizedSignalType                     mResizedSignal;
+  VisibilityChangedSignalType           mVisibilityChangedSignal;
+
+  // EGL, GL Resource
+  GlInitialize                          mGLInitCallback;
+  GlRenderFrame                         mGLRenderFrameCallback;
+  GlTerminate                           mGLTerminateCallback;
+  CallbackBase*                         mGLRenderCallback;
+  EGLSurface                            mEGLSurface;
+  EGLContext                            mEGLContext;
+  Dali::GlWindow::GlesVersion           mGLESVersion;
+  bool                                  mInitCallback:1;
+  bool                                  mDepth:1;
+  bool                                  mStencil:1;
+  bool                                  mIsEGLInitialize:1;
+  int                                   mMSAA;
+};
+
+} // namespace Adaptor
+} // namepsace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::Adaptor::GlWindow& GetImplementation(Dali::GlWindow& window)
+{
+  DALI_ASSERT_ALWAYS( window && "Window handle is empty" );
+  BaseObject& object = window.GetBaseObject();
+  return static_cast<Internal::Adaptor::GlWindow&>(object);
+}
+
+inline const Internal::Adaptor::GlWindow& GetImplementation(const Dali::GlWindow& window)
+{
+  DALI_ASSERT_ALWAYS( window && "Window handle is empty" );
+  const BaseObject& object = window.GetBaseObject();
+  return static_cast<const Internal::Adaptor::GlWindow&>(object);
+}
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_WINDOWSYSTEM_COMMON_GL_WINDOW_IMPL_H
index a214144..1031461 100755 (executable)
@@ -154,7 +154,7 @@ void Window::Initialize(Any surface, const PositionSize& positionSize, const std
 
 void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
 {
-  mEventHandler = EventHandlerPtr(new EventHandler( mWindowSurface, *mAdaptor ) );
+  mEventHandler = EventHandlerPtr(new EventHandler( mWindowSurface->GetWindowBase(), *mAdaptor ) );
   mEventHandler->AddObserver( *this );
 }
 
index 7dffb60..a04299b 100644 (file)
@@ -8,6 +8,7 @@ SET( adaptor_window_system_common_src_files
     ${adaptor_window_system_dir}/common/window-base.cpp 
     ${adaptor_window_system_dir}/common/window-impl.cpp 
     ${adaptor_window_system_dir}/common/window-render-surface.cpp
+    ${adaptor_window_system_dir}/common/gl-window-impl.cpp
 )
 
 # module: window-system, backend: tizen-wayland