Revert "[Tizen] Revert "Support screen rotation""
[platform/core/uifw/dali-adaptor.git] / adaptors / ecore / wayland / window-render-surface-ecore-wl.cpp
index 1df0faa..db97cd5 100644 (file)
@@ -27,7 +27,6 @@
 // INTERNAL INCLUDES
 #include <wl-types.h>
 #include <gl/egl-implementation.h>
 // INTERNAL INCLUDES
 #include <wl-types.h>
 #include <gl/egl-implementation.h>
-#include <base/display-connection.h>
 #include <adaptors/common/adaptor-impl.h>
 #include <integration-api/trigger-event-factory-interface.h>
 
 #include <adaptors/common/adaptor-impl.h>
 #include <integration-api/trigger-event-factory-interface.h>
 
@@ -45,7 +44,6 @@ namespace
 {
 
 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
 {
 
 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
-const char* WAYLAND_EGL_SO( "libwayland-egl.so" );
 
 } // unnamed namespace
 
 
 } // unnamed namespace
 
@@ -54,16 +52,17 @@ WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize,
                                           const std::string& name,
                                           bool isTransparent)
 : EcoreWlRenderSurface( positionSize, surface, name, isTransparent ),
                                           const std::string& name,
                                           bool isTransparent)
 : EcoreWlRenderSurface( positionSize, surface, name, isTransparent ),
-  mEglWinGetCapabilitiesPtr( NULL ),
-  mEglWinSetRotationPtr( NULL ),
-  mLibHandle( NULL ),
   mWlWindow( NULL ),
   mWlSurface( NULL ),
   mEglWindow( NULL ),
   mThreadSynchronization( NULL ),
   mRotationTrigger( NULL ),
   mWlWindow( NULL ),
   mWlSurface( NULL ),
   mEglWindow( NULL ),
   mThreadSynchronization( NULL ),
   mRotationTrigger( NULL ),
+  mRotationAngle( 0 ),
+  mScreenRotationAngle( 0 ),
   mRotationSupported( false ),
   mRotationSupported( false ),
-  mRotated( false )
+  mRotationFinished( true ),
+  mScreenRotationFinished( true ),
+  mResizeFinished( true )
 {
   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
   Init( surface );
 {
   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
   Init( surface );
@@ -87,10 +86,6 @@ WindowRenderSurface::~WindowRenderSurface()
     delete mRotationTrigger;
   }
 
     delete mRotationTrigger;
   }
 
-  if( mLibHandle != NULL )
-  {
-    dlclose( mLibHandle );
-  }
 }
 
 Ecore_Wl_Window* WindowRenderSurface::GetDrawable()
 }
 
 Ecore_Wl_Window* WindowRenderSurface::GetDrawable()
@@ -110,7 +105,7 @@ Ecore_Wl_Window* WindowRenderSurface::GetWlWindow()
   return mWlWindow;
 }
 
   return mWlWindow;
 }
 
-void WindowRenderSurface::RequestRotation( Dali::Window::WindowOrientation orientation, int width, int height )
+void WindowRenderSurface::RequestRotation( int angle, int width, int height )
 {
   if( !mRotationSupported )
   {
 {
   if( !mRotationSupported )
   {
@@ -118,62 +113,42 @@ void WindowRenderSurface::RequestRotation( Dali::Window::WindowOrientation orien
     return;
   }
 
     return;
   }
 
-  DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: orientation = %d\n", orientation );
-
   if( !mRotationTrigger )
   {
     TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
     mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
   }
 
   if( !mRotationTrigger )
   {
     TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface();
     mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
   }
 
-  mPosition.width = width;
-  mPosition.height = height;
+  mPositionSize.width = width;
+  mPositionSize.height = height;
 
 
-  mRotated = true;
+  mRotationAngle = angle;
+  mRotationFinished = false;
 
 
-  int angle;
-  wl_egl_window_rotation rotation;
+  ecore_wl_window_rotation_set( mWlWindow, mRotationAngle );
 
 
-  switch( orientation )
-  {
-    case Dali::Window::PORTRAIT:
-    {
-      angle = 0;
-      rotation = ROTATION_0;
-      break;
-    }
-    case Dali::Window::LANDSCAPE:
-    {
-      angle = 90;
-      rotation = ROTATION_270;
-      break;
-    }
-    case Dali::Window::PORTRAIT_INVERSE:
-    {
-      angle = 180;
-      rotation = ROTATION_180;
-      break;
-    }
-    case Dali::Window::LANDSCAPE_INVERSE:
-    {
-      angle = 270;
-      rotation = ROTATION_90;
-      break;
-    }
-    default:
-    {
-      angle = 0;
-      rotation = ROTATION_0;
-      break;
-    }
-  }
+  DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
+}
 
 
-  ecore_wl_window_rotation_set( mWlWindow, angle );
+void WindowRenderSurface::OutputTransformed()
+{
+  int transform;
 
 
-  if( mEglWinSetRotationPtr )
+  if( ecore_wl_window_ignore_output_transform_get( mWlWindow ) )
   {
   {
-    mEglWinSetRotationPtr( mEglWindow, rotation );
+    transform = 0;
   }
   }
+  else
+  {
+    transform = ecore_wl_output_transform_get( ecore_wl_window_output_find( mWlWindow ) );
+  }
+
+  ecore_wl_window_buffer_transform_set( mWlWindow, transform );
+
+  mScreenRotationAngle = transform * 90;
+  mScreenRotationFinished = false;
+
+  DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle );
 }
 
 void WindowRenderSurface::SetTransparency( bool transparent )
 }
 
 void WindowRenderSurface::SetTransparency( bool transparent )
@@ -196,57 +171,28 @@ void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf )
 
   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
 
 
   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
 
-  // Temporary code for opaque window. We have to modify it after wayland team finish the work.
-  if( mColorDepth == COLOR_DEPTH_32 )
+  // create the EGL window
+  if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
   {
   {
-    ecore_wl_window_alpha_set( mWlWindow, true );
+    mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height );
   }
   else
   {
   }
   else
   {
-    ecore_wl_window_alpha_set( mWlWindow, false );
+    mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width );
   }
 
   }
 
-  // create the EGL window
-  mEglWindow = wl_egl_window_create( mWlSurface, mPosition.width, mPosition.height );
   EGLNativeWindowType windowType( mEglWindow );
   eglImpl.CreateSurfaceWindow( windowType, mColorDepth );
 
   // Check capability
   EGLNativeWindowType windowType( mEglWindow );
   eglImpl.CreateSurfaceWindow( windowType, mColorDepth );
 
   // Check capability
-  if( !mLibHandle )
+  wl_egl_window_capability capability = static_cast< wl_egl_window_capability >( wl_egl_window_get_capabilities( mEglWindow ) );
+  if( capability == WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED )
   {
   {
-    mLibHandle = dlopen( WAYLAND_EGL_SO, RTLD_LAZY );
-
-    char* error = dlerror();
-    if( mLibHandle == NULL || error != NULL )
-    {
-      DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: dlopen error: %s\n", error );
-      return;
-    }
-
-    mEglWinGetCapabilitiesPtr = reinterpret_cast< EglWinGetCapabilitiesFunction >( dlsym( mLibHandle, "wl_egl_window_get_capabilities" ) );
-    if( !mEglWinGetCapabilitiesPtr )
-    {
-      DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: Can't load wl_egl_window_get_capabilities\n" );
-      return;
-    }
-
-    mEglWinSetRotationPtr = reinterpret_cast< EglWinSetRotationFunction >( dlsym( mLibHandle, "wl_egl_window_set_rotation" ) );
-    if( !mEglWinSetRotationPtr )
-    {
-      DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: Can't load wl_egl_window_set_rotation\n" );
-      return;
-    }
+    DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: capability = %d\n", capability );
+    mRotationSupported = true;
   }
 
   }
 
-  if( mEglWinGetCapabilitiesPtr )
-  {
-    wl_egl_window_capability capability = static_cast< wl_egl_window_capability >( mEglWinGetCapabilitiesPtr( mEglWindow ) );
-    if( capability == WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED )
-    {
-      DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: capability = %d\n", capability );
-      mRotationSupported = true;
-    }
-  }
+  DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle );
 }
 
 void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf )
 }
 
 void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf )
@@ -273,17 +219,17 @@ bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl )
     mEglWindow = NULL;
   }
 
     mEglWindow = NULL;
   }
 
-  // Temporary code for opaque window. We have to modify it after wayland team finish the work.
-  if( mColorDepth == COLOR_DEPTH_32 )
+  if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 )
   {
   {
-    ecore_wl_window_alpha_set( mWlWindow, true );
+    mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height );
   }
   else
   {
   }
   else
   {
-    ecore_wl_window_alpha_set( mWlWindow, false );
+    mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width );
   }
 
   }
 
-  mEglWindow = wl_egl_window_create( mWlSurface, mPosition.width, mPosition.height );
+  // Set screen rotation
+  mScreenRotationFinished = false;
 
   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
   EGLNativeWindowType windowType( mEglWindow );
 
   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
   EGLNativeWindowType windowType( mEglWindow );
@@ -296,33 +242,32 @@ void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize )
   bool needToResize = false;
 
   // check moving
   bool needToResize = false;
 
   // check moving
-  if( (fabs(positionSize.x - mPosition.x) > MINIMUM_DIMENSION_CHANGE) ||
-      (fabs(positionSize.y - mPosition.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
   {
     needToMove = true;
   }
 
   // check resizing
-  if( (fabs(positionSize.width - mPosition.width) > MINIMUM_DIMENSION_CHANGE) ||
-      (fabs(positionSize.height - mPosition.height) > MINIMUM_DIMENSION_CHANGE) )
+  if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) ||
+      (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) )
   {
     needToResize = true;
   }
 
   {
     needToResize = true;
   }
 
-  if(needToMove)
+  if( needToMove )
   {
     ecore_wl_window_position_set( mWlWindow, positionSize.x, positionSize.y );
   }
   {
     ecore_wl_window_position_set( mWlWindow, positionSize.x, positionSize.y );
   }
-  if (needToResize)
+  if( needToResize )
   {
     ecore_wl_window_update_size( mWlWindow, positionSize.width, positionSize.height );
   {
     ecore_wl_window_update_size( mWlWindow, positionSize.width, positionSize.height );
+    mResizeFinished = false;
   }
 
   }
 
-  mPosition = positionSize;
-
-  wl_egl_window_resize( mEglWindow, mPosition.width, mPosition.height, mPosition.x, mPosition.y );
+  mPositionSize = positionSize;
 
 
-  DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPosition.x, mPosition.y, mPosition.width, mPosition.height );
+  DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height );
 }
 
 void WindowRenderSurface::Map()
 }
 
 void WindowRenderSurface::Map()
@@ -334,23 +279,118 @@ void WindowRenderSurface::StartRender()
 {
 }
 
 {
 }
 
-bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
+bool WindowRenderSurface::PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface )
 {
 {
-  // nothing to do for windows
+  if( resizingSurface )
+  {
+#ifdef OVER_TIZEN_VERSION_4
+    // Window rotate or screen rotate
+    if( !mRotationFinished || !mScreenRotationFinished )
+    {
+      wl_egl_window_rotation rotation;
+      wl_output_transform bufferTransform;
+      int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360;
+
+      switch( totalAngle )
+      {
+        case 0:
+        {
+          rotation = ROTATION_0;
+          bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL;
+          break;
+        }
+        case 90:
+        {
+          rotation = ROTATION_270;
+          bufferTransform = WL_OUTPUT_TRANSFORM_90;
+          break;
+        }
+        case 180:
+        {
+          rotation = ROTATION_180;
+          bufferTransform = WL_OUTPUT_TRANSFORM_180;
+          break;
+        }
+        case 270:
+        {
+          rotation = ROTATION_90;
+          bufferTransform = WL_OUTPUT_TRANSFORM_270;
+          break;
+        }
+        default:
+        {
+          rotation = ROTATION_0;
+          bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL;
+          break;
+        }
+      }
+
+      wl_egl_window_set_rotation( mEglWindow, rotation );
+
+      wl_egl_window_set_buffer_transform( mEglWindow, bufferTransform );
+
+      // Reset only screen rotation flag
+      mScreenRotationFinished = true;
+
+      DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set rotation [%d] [%d]\n", mRotationAngle, mScreenRotationAngle );
+    }
+
+    // Only window rotate
+    if( !mRotationFinished )
+    {
+      wl_output_transform windowTransform;
+
+      switch( mRotationAngle )
+      {
+        case 0:
+        {
+          windowTransform = WL_OUTPUT_TRANSFORM_NORMAL;
+          break;
+        }
+        case 90:
+        {
+          windowTransform = WL_OUTPUT_TRANSFORM_90;
+          break;
+        }
+        case 180:
+        {
+          windowTransform = WL_OUTPUT_TRANSFORM_180;
+          break;
+        }
+        case 270:
+        {
+          windowTransform = WL_OUTPUT_TRANSFORM_270;
+          break;
+        }
+        default:
+        {
+          windowTransform = WL_OUTPUT_TRANSFORM_NORMAL;
+          break;
+        }
+      }
+
+      wl_egl_window_set_window_transform( mEglWindow, windowTransform );
+    }
+#endif
+
+    // Resize case
+    if( !mResizeFinished )
+    {
+      wl_egl_window_resize( mEglWindow, mPositionSize.width, mPositionSize.height, mPositionSize.x, mPositionSize.y );
+      mResizeFinished = true;
+
+      DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set resize\n" );
+    }
+  }
+
   return true;
 }
 
   return true;
 }
 
-void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface )
+void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
 {
 {
-  if( mRotated )
+  if( resizingSurface )
   {
   {
-    // Check viewport size
-    Dali::Vector< GLint > viewportSize;
-    viewportSize.Resize( 4 );
-
-    glAbstraction.GetIntegerv( GL_VIEWPORT, &viewportSize[0] );
-
-    if( viewportSize[2] == mPosition.width && viewportSize[3] == mPosition.height )
+    if( !mRotationFinished )
     {
       DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PostRender: Trigger rotation event\n" );
 
     {
       DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PostRender: Trigger rotation event\n" );
 
@@ -385,16 +425,16 @@ void WindowRenderSurface::SetViewMode( ViewMode viewMode )
 void WindowRenderSurface::CreateWlRenderable()
 {
    // if width or height are zero, go full screen.
 void WindowRenderSurface::CreateWlRenderable()
 {
    // if width or height are zero, go full screen.
-  if ( (mPosition.width == 0) || (mPosition.height == 0) )
+  if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) )
   {
     // Default window size == screen size
   {
     // Default window size == screen size
-    mPosition.x = 0;
-    mPosition.y = 0;
+    mPositionSize.x = 0;
+    mPositionSize.y = 0;
 
 
-    ecore_wl_screen_size_get( &mPosition.width, &mPosition.height );
+    ecore_wl_screen_size_get( &mPositionSize.width, &mPositionSize.height );
   }
 
   }
 
-  mWlWindow = ecore_wl_window_new( 0, mPosition.x, mPosition.y, mPosition.width, mPosition.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW );
+  mWlWindow = ecore_wl_window_new( 0, mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW );
 
   if ( mWlWindow == 0 )
   {
 
   if ( mWlWindow == 0 )
   {
@@ -402,6 +442,27 @@ void WindowRenderSurface::CreateWlRenderable()
   }
 
   mWlSurface = ecore_wl_window_surface_create( mWlWindow );
   }
 
   mWlSurface = ecore_wl_window_surface_create( mWlWindow );
+
+  if( mColorDepth == COLOR_DEPTH_32 )
+  {
+    ecore_wl_window_alpha_set( mWlWindow, true );
+  }
+  else
+  {
+    ecore_wl_window_alpha_set( mWlWindow, false );
+  }
+
+  // Get output transform
+  if( !ecore_wl_window_ignore_output_transform_get( mWlWindow ) )
+  {
+    Ecore_Wl_Output* output = ecore_wl_window_output_find( mWlWindow );
+
+    int transform = ecore_wl_output_transform_get( output );
+    ecore_wl_window_buffer_transform_set( mWlWindow, transform );
+
+    mScreenRotationAngle = transform * 90;
+    mScreenRotationFinished = false;
+  }
 }
 
 void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
 }
 
 void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
@@ -423,7 +484,7 @@ void WindowRenderSurface::ReleaseLock()
 
 void WindowRenderSurface::ProcessRotationRequest()
 {
 
 void WindowRenderSurface::ProcessRotationRequest()
 {
-  mRotated = false;
+  mRotationFinished = true;
 
   ecore_wl_window_rotation_change_done_send( mWlWindow );
 
 
   ecore_wl_window_rotation_change_done_send( mWlWindow );